mirror of
https://github.com/danbee/chess
synced 2025-03-04 08:39:06 +00:00
Create new games and display them
This commit is contained in:
parent
1b37e5f38a
commit
f6c38661c7
12
priv/repo/migrations/20161209105511_create_game.exs
Normal file
12
priv/repo/migrations/20161209105511_create_game.exs
Normal file
@ -0,0 +1,12 @@
|
||||
defmodule Chess.Repo.Migrations.CreateGame do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:games) do
|
||||
add :board, :map
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
66
test/controllers/game_controller_test.exs
Normal file
66
test/controllers/game_controller_test.exs
Normal file
@ -0,0 +1,66 @@
|
||||
defmodule Chess.GameControllerTest do
|
||||
use Chess.ConnCase
|
||||
|
||||
alias Chess.Game
|
||||
@valid_attrs %{board: %{}}
|
||||
@invalid_attrs %{}
|
||||
|
||||
test "lists all entries on index", %{conn: conn} do
|
||||
conn = get conn, game_path(conn, :index)
|
||||
assert html_response(conn, 200) =~ "Listing games"
|
||||
end
|
||||
|
||||
test "renders form for new resources", %{conn: conn} do
|
||||
conn = get conn, game_path(conn, :new)
|
||||
assert html_response(conn, 200) =~ "New game"
|
||||
end
|
||||
|
||||
test "creates resource and redirects when data is valid", %{conn: conn} do
|
||||
conn = post conn, game_path(conn, :create), game: @valid_attrs
|
||||
assert redirected_to(conn) == game_path(conn, :index)
|
||||
assert Repo.get_by(Game, @valid_attrs)
|
||||
end
|
||||
|
||||
test "does not create resource and renders errors when data is invalid", %{conn: conn} do
|
||||
conn = post conn, game_path(conn, :create), game: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "New game"
|
||||
end
|
||||
|
||||
test "shows chosen resource", %{conn: conn} do
|
||||
game = Repo.insert! %Game{}
|
||||
conn = get conn, game_path(conn, :show, game)
|
||||
assert html_response(conn, 200) =~ "Show game"
|
||||
end
|
||||
|
||||
test "renders page not found when id is nonexistent", %{conn: conn} do
|
||||
assert_error_sent 404, fn ->
|
||||
get conn, game_path(conn, :show, -1)
|
||||
end
|
||||
end
|
||||
|
||||
test "renders form for editing chosen resource", %{conn: conn} do
|
||||
game = Repo.insert! %Game{}
|
||||
conn = get conn, game_path(conn, :edit, game)
|
||||
assert html_response(conn, 200) =~ "Edit game"
|
||||
end
|
||||
|
||||
test "updates chosen resource and redirects when data is valid", %{conn: conn} do
|
||||
game = Repo.insert! %Game{}
|
||||
conn = put conn, game_path(conn, :update, game), game: @valid_attrs
|
||||
assert redirected_to(conn) == game_path(conn, :show, game)
|
||||
assert Repo.get_by(Game, @valid_attrs)
|
||||
end
|
||||
|
||||
test "does not update chosen resource and renders errors when data is invalid", %{conn: conn} do
|
||||
game = Repo.insert! %Game{}
|
||||
conn = put conn, game_path(conn, :update, game), game: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "Edit game"
|
||||
end
|
||||
|
||||
test "deletes chosen resource", %{conn: conn} do
|
||||
game = Repo.insert! %Game{}
|
||||
conn = delete conn, game_path(conn, :delete, game)
|
||||
assert redirected_to(conn) == game_path(conn, :index)
|
||||
refute Repo.get(Game, game.id)
|
||||
end
|
||||
end
|
||||
18
test/models/game_test.exs
Normal file
18
test/models/game_test.exs
Normal file
@ -0,0 +1,18 @@
|
||||
defmodule Chess.GameTest do
|
||||
use Chess.ModelCase
|
||||
|
||||
alias Chess.Game
|
||||
|
||||
@valid_attrs %{board: %{}}
|
||||
@invalid_attrs %{}
|
||||
|
||||
test "changeset with valid attributes" do
|
||||
changeset = Game.changeset(%Game{}, @valid_attrs)
|
||||
assert changeset.valid?
|
||||
end
|
||||
|
||||
test "changeset with invalid attributes" do
|
||||
changeset = Game.changeset(%Game{}, @invalid_attrs)
|
||||
refute changeset.valid?
|
||||
end
|
||||
end
|
||||
@ -3,7 +3,8 @@ defmodule Chess.Api.GameController do
|
||||
|
||||
alias Chess.Game
|
||||
|
||||
def show(conn, _params) do
|
||||
render conn, "show.json", id: 1
|
||||
def show(conn, %{"id" => id}) do
|
||||
game = Repo.get!(Game, id)
|
||||
render conn, "show.json", game: game
|
||||
end
|
||||
end
|
||||
|
||||
66
web/controllers/game_controller.ex
Normal file
66
web/controllers/game_controller.ex
Normal file
@ -0,0 +1,66 @@
|
||||
defmodule Chess.GameController do
|
||||
use Chess.Web, :controller
|
||||
|
||||
alias Chess.Game
|
||||
|
||||
def index(conn, _params) do
|
||||
changeset = Game.changeset(%Game{})
|
||||
games = Repo.all(Game)
|
||||
render(conn, "index.html", games: games, changeset: changeset)
|
||||
end
|
||||
|
||||
def new(conn, _params) do
|
||||
changeset = Game.changeset(%Game{})
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, _params) do
|
||||
changeset = Game.changeset(%Game{})
|
||||
|
||||
case Repo.insert(changeset) do
|
||||
{:ok, _game} ->
|
||||
conn
|
||||
|> put_flash(:info, "Game created successfully.")
|
||||
|> redirect(to: game_path(conn, :index))
|
||||
{:error, changeset} ->
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
game = Repo.get!(Game, id)
|
||||
render(conn, "show.html", game: game)
|
||||
end
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
game = Repo.get!(Game, id)
|
||||
changeset = Game.changeset(game)
|
||||
render(conn, "edit.html", game: game, changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id, "game" => game_params}) do
|
||||
game = Repo.get!(Game, id)
|
||||
changeset = Game.changeset(game, game_params)
|
||||
|
||||
case Repo.update(changeset) do
|
||||
{:ok, game} ->
|
||||
conn
|
||||
|> put_flash(:info, "Game updated successfully.")
|
||||
|> redirect(to: game_path(conn, :show, game))
|
||||
{:error, changeset} ->
|
||||
render(conn, "edit.html", game: game, changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
game = Repo.get!(Game, id)
|
||||
|
||||
# Here we use delete! (with a bang) because we expect
|
||||
# it to always work (and if it does not, it will raise).
|
||||
Repo.delete!(game)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "Game deleted successfully.")
|
||||
|> redirect(to: game_path(conn, :index))
|
||||
end
|
||||
end
|
||||
73
web/models/game.ex
Normal file
73
web/models/game.ex
Normal file
@ -0,0 +1,73 @@
|
||||
defmodule Chess.Game do
|
||||
use Chess.Web, :model
|
||||
|
||||
schema "games" do
|
||||
field :board, :map
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Builds a changeset based on the `struct` and `params`.
|
||||
"""
|
||||
def changeset(struct, params \\ %{}) do
|
||||
struct
|
||||
|> cast(params, [:board])
|
||||
|> set_default_board
|
||||
|> validate_required([:board])
|
||||
end
|
||||
|
||||
def set_default_board(changeset) do
|
||||
changeset
|
||||
|> put_change(:board, default_board)
|
||||
end
|
||||
|
||||
def default_board do
|
||||
%{
|
||||
"8" => %{
|
||||
a: %{ type: "rook", colour: "black" },
|
||||
b: %{ type: "knight", colour: "black" },
|
||||
c: %{ type: "bishop", colour: "black" },
|
||||
d: %{ type: "queen", colour: "black" },
|
||||
e: %{ type: "king", colour: "black" },
|
||||
f: %{ type: "bishop", colour: "black" },
|
||||
g: %{ type: "knight", colour: "black" },
|
||||
h: %{ type: "rook", colour: "black" }
|
||||
},
|
||||
"7" => %{
|
||||
a: %{ type: "pawn", colour: "black" },
|
||||
b: %{ type: "pawn", colour: "black" },
|
||||
c: %{ type: "pawn", colour: "black" },
|
||||
d: %{ type: "pawn", colour: "black" },
|
||||
e: %{ type: "pawn", colour: "black" },
|
||||
f: %{ type: "pawn", colour: "black" },
|
||||
g: %{ type: "pawn", colour: "black" },
|
||||
h: %{ type: "pawn", colour: "black" }
|
||||
},
|
||||
"6" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"5" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"4" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"3" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"2" => %{
|
||||
a: %{ type: "pawn", colour: "white" },
|
||||
b: %{ type: "pawn", colour: "white" },
|
||||
c: %{ type: "pawn", colour: "white" },
|
||||
d: %{ type: "pawn", colour: "white" },
|
||||
e: %{ type: "pawn", colour: "white" },
|
||||
f: %{ type: "pawn", colour: "white" },
|
||||
g: %{ type: "pawn", colour: "white" },
|
||||
h: %{ type: "pawn", colour: "white" }
|
||||
},
|
||||
"1" => %{
|
||||
a: %{ type: "rook", colour: "white" },
|
||||
b: %{ type: "knight", colour: "white" },
|
||||
c: %{ type: "bishop", colour: "white" },
|
||||
d: %{ type: "queen", colour: "white" },
|
||||
e: %{ type: "king", colour: "white" },
|
||||
f: %{ type: "bishop", colour: "white" },
|
||||
g: %{ type: "knight", colour: "white" },
|
||||
h: %{ type: "rook", colour: "white" }
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
@ -13,15 +13,21 @@ import ChessBoard from "./components/chess-board";
|
||||
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
const { store } = this.props;
|
||||
const { store, gameId } = this.props;
|
||||
|
||||
return (
|
||||
<ChessBoard gameId={1} store={store} />
|
||||
<ChessBoard gameId={gameId} store={store} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<App store={store} />,
|
||||
document.getElementById('app')
|
||||
);
|
||||
const container = document.getElementById("app");
|
||||
|
||||
if (container != undefined) {
|
||||
const gameId = container.getAttribute("data-game-id");
|
||||
|
||||
ReactDOM.render(
|
||||
<App store={store} gameId={gameId} />,
|
||||
container
|
||||
);
|
||||
}
|
||||
|
||||
6
web/templates/game/edit.html.eex
Normal file
6
web/templates/game/edit.html.eex
Normal file
@ -0,0 +1,6 @@
|
||||
<h2>Edit game</h2>
|
||||
|
||||
<%= render "form.html", changeset: @changeset,
|
||||
action: game_path(@conn, :update, @game) %>
|
||||
|
||||
<%= link "Back", to: game_path(@conn, :index) %>
|
||||
17
web/templates/game/form.html.eex
Normal file
17
web/templates/game/form.html.eex
Normal file
@ -0,0 +1,17 @@
|
||||
<%= form_for @changeset, @action, fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="alert alert-danger">
|
||||
<p>Oops, something went wrong! Please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label f, :board, class: "control-label" %>
|
||||
<%= text_input f, :board, class: "form-control" %>
|
||||
<%= error_tag f, :board %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= submit "Submit", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
29
web/templates/game/index.html.eex
Normal file
29
web/templates/game/index.html.eex
Normal file
@ -0,0 +1,29 @@
|
||||
<h2>Listing games</h2>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%= for game <- @games do %>
|
||||
<tr>
|
||||
<td><%= game.id %></td>
|
||||
|
||||
<td class="text-right">
|
||||
<%= link "Show", to: game_path(@conn, :show, game), class: "btn btn-default btn-xs" %>
|
||||
<%= link "Delete", to: game_path(@conn, :delete, game), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= form_for @changeset, game_path(@conn, :create), fn f -> %>
|
||||
<div class="form-group">
|
||||
<%= submit "Create game", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
6
web/templates/game/new.html.eex
Normal file
6
web/templates/game/new.html.eex
Normal file
@ -0,0 +1,6 @@
|
||||
<h2>New game</h2>
|
||||
|
||||
<%= render "form.html", changeset: @changeset,
|
||||
action: game_path(@conn, :create) %>
|
||||
|
||||
<%= link "Back", to: game_path(@conn, :index) %>
|
||||
2
web/templates/game/show.html.eex
Normal file
2
web/templates/game/show.html.eex
Normal file
@ -0,0 +1,2 @@
|
||||
<div id="app" data-game-id="<%= @game.id %>">
|
||||
</div>
|
||||
@ -1,52 +1,7 @@
|
||||
defmodule Chess.Api.GameView do
|
||||
use Chess.Web, :view
|
||||
|
||||
def render("show.json", %{ id: 1 }) do
|
||||
%{
|
||||
"8" => %{
|
||||
a: %{ type: "rook", colour: "black" },
|
||||
b: %{ type: "knight", colour: "black" },
|
||||
c: %{ type: "bishop", colour: "black" },
|
||||
d: %{ type: "queen", colour: "black" },
|
||||
e: %{ type: "king", colour: "black" },
|
||||
f: %{ type: "bishop", colour: "black" },
|
||||
g: %{ type: "knight", colour: "black" },
|
||||
h: %{ type: "rook", colour: "black" }
|
||||
},
|
||||
"7" => %{
|
||||
a: %{ type: "pawn", colour: "black" },
|
||||
b: %{ type: "pawn", colour: "black" },
|
||||
c: %{ type: "pawn", colour: "black" },
|
||||
d: %{ type: "pawn", colour: "black" },
|
||||
e: %{ type: "pawn", colour: "black" },
|
||||
f: %{ type: "pawn", colour: "black" },
|
||||
g: %{ type: "pawn", colour: "black" },
|
||||
h: %{ type: "pawn", colour: "black" }
|
||||
},
|
||||
"6" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"5" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"4" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"3" => %{ a: nil, b: nil, c: nil, d: nil, e: nil, f: nil, g: nil, h: nil },
|
||||
"2" => %{
|
||||
a: %{ type: "pawn", colour: "white" },
|
||||
b: %{ type: "pawn", colour: "white" },
|
||||
c: %{ type: "pawn", colour: "white" },
|
||||
d: %{ type: "pawn", colour: "white" },
|
||||
e: %{ type: "pawn", colour: "white" },
|
||||
f: %{ type: "pawn", colour: "white" },
|
||||
g: %{ type: "pawn", colour: "white" },
|
||||
h: %{ type: "pawn", colour: "white" }
|
||||
},
|
||||
"1" => %{
|
||||
a: %{ type: "rook", colour: "white" },
|
||||
b: %{ type: "knight", colour: "white" },
|
||||
c: %{ type: "bishop", colour: "white" },
|
||||
d: %{ type: "queen", colour: "white" },
|
||||
e: %{ type: "king", colour: "white" },
|
||||
f: %{ type: "bishop", colour: "white" },
|
||||
g: %{ type: "knight", colour: "white" },
|
||||
h: %{ type: "rook", colour: "white" }
|
||||
}
|
||||
}
|
||||
def render("show.json", %{game: game}) do
|
||||
game.board
|
||||
end
|
||||
end
|
||||
|
||||
3
web/views/game_view.ex
Normal file
3
web/views/game_view.ex
Normal file
@ -0,0 +1,3 @@
|
||||
defmodule Chess.GameView do
|
||||
use Chess.Web, :view
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user