1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00

Make sure the JS works in PhantomJS

PhantomJS does not implement `Object.assign` which is how we were
updating the state immutably. I've switched it over to use the
ImmutableJS library instead.
This commit is contained in:
Daniel Barber 2016-12-22 10:28:33 +00:00
parent 7c847d5c94
commit d888ab8d83
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
10 changed files with 77 additions and 21 deletions

View File

@ -4,7 +4,7 @@ use Mix.Config
# you can enable the server option below.
config :chess, Chess.Endpoint,
http: [port: 4001],
server: false
server: true
# Print only warnings and errors during test
config :logger, level: :warn
@ -15,3 +15,5 @@ config :chess, Chess.Repo,
database: "chess_test",
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox
config :hound, driver: "phantomjs"

View File

@ -30,13 +30,15 @@ defmodule Chess.Mixfile do
#
# Type `mix help deps` for examples and options.
defp deps do
[{:phoenix, "~> 1.2.0"},
[{:credo, "~> 0.5", only: [:dev, :test]},
{:phoenix, "~> 1.2.0"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:hound, "~> 1.0"},
{:cowboy, "~> 1.0"},
{:timex_ecto, "~> 3.0"}]
end

View File

@ -1,14 +1,18 @@
%{"certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []},
%{"bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], []},
"certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []},
"combine": {:hex, :combine, "0.9.3", "192e609b48b3f2210494e26f85db1712657be1a8f15795656710317ea43fc449", [:mix], []},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
"cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [:rebar, :make], [{:cowlib, "~> 1.0.0", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
"credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, optional: false]}]},
"db_connection": {:hex, :db_connection, "1.1.0", "b2b88db6d7d12f99997b584d09fad98e560b817a20dab6a526830e339f54cdb3", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]},
"decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], []},
"ecto": {:hex, :ecto, "2.0.6", "9dcbf819c2a77f67a66b83739b7fcc00b71aaf6c100016db4f798930fa4cfd47", [:mix], [{:db_connection, "~> 1.0", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.1.2 or ~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, optional: true]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.12.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, optional: true]}]},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
"gettext": {:hex, :gettext, "0.12.2", "4f71a0df7b0bf5693419da593b4ddde558cc28e8f56a991fbfc2b51be1d5c848", [:mix], []},
"hackney": {:hex, :hackney, "1.6.3", "d489d7ca2d4323e307bedc4bfe684323a7bf773ecfd77938f3ee8074e488e140", [:mix, :rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
"hound": {:hex, :hound, "1.0.2", "b6dd20142d00c28009fad503a23fa4a76bc11899e0d198f36a9c1448427788b2", [:mix], [{:httpoison, "~> 0.8", [hex: :httpoison, optional: false]}, {:poison, ">= 1.4.0", [hex: :poison, optional: false]}]},
"httpoison": {:hex, :httpoison, "0.10.0", "4727b3a5e57e9a4ff168a3c2883e20f1208103a41bccc4754f15a9366f49b676", [:mix], [{:hackney, "~> 1.6.3", [hex: :hackney, optional: false]}]},
"idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []},

View File

@ -0,0 +1,29 @@
defmodule Chess.GamesTest do
use Chess.FeatureCase
test "visit homepage" do
navigate_to "/"
find_element(:css, "body")
assert title_text == "Chess"
end
test "can create a new game" do
navigate_to "/"
create_game
assert page_has_chess_board
end
defp create_game do
click({:css, "form.create-game button[type='submit']"})
end
defp title_text do
find_element(:css, "header h1") |> visible_text
end
defp page_has_chess_board do
element_displayed?({:css, ".board"})
end
end

View File

@ -0,0 +1,12 @@
defmodule Chess.FeatureCase do
use ExUnit.CaseTemplate
using do
quote do
use Chess.ConnCase
use Hound.Helpers
hound_session
end
end
end

View File

@ -1,4 +1,4 @@
Application.ensure_all_started(:hound)
ExUnit.start
Ecto.Adapters.SQL.Sandbox.mode(Chess.Repo, :manual)

View File

@ -1,4 +1,5 @@
import React from "react";
import _ from "lodash";
import $ from "jquery";
import { connect } from "react-redux";
import { setBoard, setGameId } from "../store/actions";
@ -24,7 +25,7 @@ class ChessBoard extends React.Component {
const { store } = this.props;
const rank = this.getBoard()[rankId];
return Object.keys(rank).sort().map((fileId) => {
return _.map(Object.keys(rank).sort(), (fileId) => {
return (
<ChessBoardSquare
file={fileId}
@ -40,7 +41,7 @@ class ChessBoard extends React.Component {
renderRanks() {
const board = this.getBoard();
return Object.keys(board).reverse().map((rankId) => {
return _.map(Object.keys(board).reverse(), (rankId) => {
return (
<div className="board-rank" key={rankId}>
{this.renderFiles(rankId)}

View File

@ -1,28 +1,32 @@
import Immutable from "immutable";
import { Map } from "immutable";
import defaultState from "../store/default-state";
import movePiece from "./move-piece";
const chessBoardReducer = (state = defaultState, action) => {
switch (action.type) {
case "SET_BOARD":
return Object.assign(
{},
state,
{ board: action.board, selectedSquare: null }
);
return Immutable.fromJS(state)
.set("board", action.board)
.set("selectedSquare", null)
.toJS();
case "SET_GAME_ID":
return Object.assign({}, state, { gameId: action.gameId });
return Immutable.fromJS(state)
.set("gameId", action.gameId)
.toJS();
case "MOVE_PIECE":
const newState = {
board: movePiece(state.board, action.from, action.to),
selectedSquare: null
}
return Object.assign({}, state, newState);
return Immutable.fromJS(state)
.set("board", movePiece(state.board))
.set("selectedSquare", null)
.toJS();
case "SELECT_PIECE":
return Object.assign({}, state, { selectedSquare: action.coords });
return Immutable.fromJS(state)
.set("selectedSquare", action.coords)
.toJS();
default:
return state;

View File

@ -15,7 +15,7 @@
</tbody>
</table>
<%= form_for @changeset, game_path(@conn, :create), fn _f -> %>
<%= form_for @changeset, game_path(@conn, :create), [class: "create-game"], fn _f -> %>
<div class="form-group">
<%= submit "Create game", class: "btn btn-primary" %>
</div>

View File

@ -13,7 +13,9 @@
<body>
<div class="container">
<h1>Chess</h1>
<header role="banner">
<h1>Chess</h1>
</header>
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>