Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #7 - dynamic config #38

Merged
merged 5 commits into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions cypress/e2e/example9001-moves.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ describe('Example 9001: moves', () => {
})

it('test1: e2 - e4', () => {
cy.get('#test1move1Btn').click()
cy.get('#test1StartBtn').click()
.get('#test1Container').should('be.visible')
.get('#test1move1Btn').should('be.visible')
.get('#test1move1Btn').click()
.window().then(win => {
assert.exists(win.test1move)
assert.isTrue(isPromise(win.test1move))
})
.get('#test1results').should('be.visible')
.get('#test1move1finished').should('be.visible')
.window().then(win => {
assert.exists(win.board1)
Expand All @@ -34,7 +38,8 @@ describe('Example 9001: moves', () => {
})

it('test2: multiple moves', () => {
cy.get('#test2move1Btn').click()
cy.get('#test2StartBtn').click()
.get('#test2move1Btn').click()
.window().then(win => {
assert.exists(win.test2move1)
assert.exists(win.test2move2)
Expand All @@ -48,7 +53,8 @@ describe('Example 9001: moves', () => {
})

it('test3: set position callback', () => {
cy.get('#test3step1Btn').click()
cy.get('#test3StartBtn').click()
.get('#test3step1Btn').click()
.window().then(win => {
assert.exists(win.test3step1)
assert.isTrue(isPromise(win.test3step1))
Expand All @@ -61,7 +67,8 @@ describe('Example 9001: moves', () => {
})

it('test4: set position Promise', () => {
cy.get('#test4step1Btn').click()
cy.get('#test4StartBtn').click()
.get('#test4step1Btn').click()
.get('#test4step1finished').should('not.exist')
// wait for animation to finish ...
.get('#test4step1finished').should('be.visible')
Expand All @@ -75,8 +82,10 @@ describe('Example 9001: moves', () => {
})

it('test5: orientation', () => {
cy.get('#test5StartBtn').click()

// step1: add Arrows
cy.get('#test5step1Btn').click()
.get('#test5step1Btn').click()
.get('#myBoard .arrow-bc3c7').should('have.length', 3)
.get('#myBoard .circle-a0266').should('have.length', 0)
.get('#myBoard .item-18a5b').should('have.length', 3)
Expand Down
37 changes: 37 additions & 0 deletions cypress/e2e/example9005-config.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
describe('Example 9005: config', () => {
beforeEach(() => {
cy.visit('http://localhost:3232/examples/9005.html')
.get('#myBoard .piece-349f8').should('have.length', 32)
.window().then((win) => {
assert.exists(win.board1)
// test that a few of the API methods exist
assert.isFunction(win.board1.position)
assert.isFunction(win.board1.move)
assert.isFunction(win.board1.addArrow)

// we should be in the start position
assert.equal(win.board1.position('map').size, 32)
assert.equal(win.board1.fen(), "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")
})
})

it('change config values at runtime', () => {
cy.get('#setConfig1Btn').click()
.window().then(win => {
assert.equal(win.board1.orientation(), 'black')
})
.get('#setKingPawnEndgameBtn').click()
.get('#myBoard .piece-349f8').should('have.length', 3)
.get('#onChangeTarget').then($div => {
const innerText = $div.text()
assert.equal(innerText, 'change1')
})
.get('#setConfig2Btn').click()
.get('#setRuyLopezBtn').click()
.get('#myBoard .piece-349f8').should('have.length', 32)
.get('#onChangeTarget').then($div => {
const innerText = $div.text()
assert.equal(innerText, 'change2')
})
})
})
2 changes: 1 addition & 1 deletion examples/3009-circles.example
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const board = Chessboard2('myBoard', 'start')
let circle1Id = null
let circle2Id = null
let circle3Id = null
let circle4Id = null
const circle4Id = null
let circle5Id = null

attachEvent('addCircle1Btn', 'click', () => {
Expand Down
66 changes: 46 additions & 20 deletions examples/9001-move-test.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,43 @@ Move Pieces Test
This file exists for Cypress testing

===== HTML
<div id="myBoard" style="width: 400px"></div>

<section>
<h1>test1: e2 - e4</h1>
<div id="myBoard" style="width: 300px"></div>

<br />

<button id="test1StartBtn">Start Test 1</button>
<button id="test2StartBtn">Start Test 2</button>
<button id="test3StartBtn">Start Test 3</button>
<button id="test4StartBtn">Start Test 4</button>
<button id="test5StartBtn">Start Test 5</button>

<hr />

<section id="test1Container" style="display:none">
<h1>test1: e2 - e4</h1>
<button id="test1move1Btn">e2-e4</button>
<div id="test1results"></div>
</section>

<hr />

<section>
<section id="test2Container" style="display:none">
<h1>test2: multiple moves</h1>
<button id="test2move1Btn">step1</button>
<div id="test2results"></div>
</section>

<hr />

<section>
<section id="test3Container" style="display:none">
<h1>test3: set position callback</h1>
<button id="test3step1Btn">step1</button>
<div id="test3results"></div>
</section>

<hr />

<section>
<section id="test4Container" style="display:none">
<h1>test4: set position promise</h1>
<button id="test4step1Btn">step1</button>
<div id="test4results"></div>
</section>

<hr />

<section>
<section id="test5Container" style="display:none">
<h1>test5: orientation</h1>
<button id="test5step1Btn">step1: add arrows</button>
<button id="test5step2Btn">step2: add circles</button>
Expand All @@ -51,17 +53,41 @@ This file exists for Cypress testing
<div id="test5results"></div>
</section>

<hr />

===== JS
const board1 = Chessboard2('myBoard', 'start')
const board1 = Chessboard2('myBoard', 'start')
window.board1 = board1

function byId (id) {
return document.getElementById(id)
}

function appendHtml (id, html) {
const el = document.getElementById(id)
const el = byId(id)
el.innerHTML = el.innerHTML + html
}

function hideEl (id) {
byId(id).style.display = 'none'
}

function hideAllSections () {
hideEl('test1Container')
hideEl('test2Container')
hideEl('test3Container')
hideEl('test4Container')
hideEl('test5Container')
}

function showSection (id) {
byId(id).style.display = ''
}

attachEvent('test1StartBtn', 'click', () => { hideAllSections(); showSection('test1Container') })
attachEvent('test2StartBtn', 'click', () => { hideAllSections(); showSection('test2Container') })
attachEvent('test3StartBtn', 'click', () => { hideAllSections(); showSection('test3Container') })
attachEvent('test4StartBtn', 'click', () => { hideAllSections(); showSection('test4Container') })
attachEvent('test5StartBtn', 'click', () => { hideAllSections(); showSection('test5Container') })

// -----------------------------------------------------------------------------
// Test 1

Expand Down
4 changes: 2 additions & 2 deletions examples/9004-draggable-test.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ This file exists for testing
===== JS
const config = {
draggable: true,
position: "start"
position: 'start'
}
const board1 = Chessboard2("myBoard", config)
const board1 = Chessboard2('myBoard', config)
81 changes: 81 additions & 0 deletions examples/9005-config-test.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
===== id
9005

===== Name
Config Test

===== DescriptionMD
This file exists for testing config settings.

===== HTML
<div id="myBoard" style="width: 300px"></div>

<br />

<button id="test1StartBtn">Start Test 1</button>

<hr />

<section id="test1Container">
<button id="setConfig1Btn">set config 1</button>
<button id="setConfig2Btn">set config 2</button>
<button id="setStartBtn">set start position</button>
<button id="setRuyLopezBtn">set ruy lopez</button>
<button id="setKingPawnEndgameBtn">set king and pawn endgame</button>
<pre id="configValues"></pre>
<div id="onChangeTarget"></div>
</section>

===== JS
const board1 = Chessboard2('myBoard', 'start')
window.board1 = board1

const config2 = {
onChange: onChange2
}

function byId (id) {
return document.getElementById(id)
}

function appendHtml (id, html) {
const el = byId(id)
el.innerHTML = el.innerHTML + html
}

// -----------------------------------------------------------------------------
// Test 1

function onChange1 () {
byId('onChangeTarget').innerHTML = 'change1'
}

function onChange2 () {
byId('onChangeTarget').innerHTML = 'change2'
}

attachEvent('setConfig1Btn', 'click', () => {
// should warn that "banana" is not a valid value for "orientation"
board1.config('orientation', 'banana')
// should warn-log that "foo" is not a valid config property
board1.config('foo', 'bar')

board1.config('orientation', 'black')
board1.config('onChange', onChange1)
})

attachEvent('setConfig2Btn', 'click', () => {
board1.setConfig(config2)
})

attachEvent('setStartBtn', 'click', () => {
board1.start()
})

attachEvent('setRuyLopezBtn', 'click', () => {
board1.position('r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R')
})

attachEvent('setKingPawnEndgameBtn', 'click', () => {
board1.position('8/8/8/3pk3/8/4K3/8/8')
})
2 changes: 1 addition & 1 deletion scripts/website.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const cmReader = new commonmark.Parser()
const cmWriter = new commonmark.HtmlRenderer()

// toggle development version
const useLocalDevFiles = false
const useLocalDevFiles = true
const jsCDNScript = '<script src="https://unpkg.com/@chrisoakman/chessboard2@0.3.0/dist/chessboard2.min.js" integrity="sha384-v+CI0A3P1tu1MDM6cJaBosdhRHCfZlJrhHUFWBGtckCzH/ChKw9EhDHEWGmPkp8t" crossorigin="anonymous"></script>'
// const esmCDNScript = '<script src="https://unpkg.com/@chrisoakman/chessboard2@0.3.0/dist/chessboard2.min.mjs" integrity="sha384-1yHocjOlRFtt1hT94ytsOQ/8eylPRk9Gj/DLNca1faolxec6F7k4c+f3S3FS60Rf" crossorigin="anonymous"></script>'
const cssCDNLink = '<link rel="stylesheet" href="https://unpkg.com/@chrisoakman/chessboard2@0.3.0/dist/chessboard2.min.css" integrity="sha384-5cxVYodq78gDJaWQIc5iBCUhFERY+VjHOszl2K7BTbZwBbrzQH2IYhOliWHJy6X3" crossorigin="anonymous">'
Expand Down
42 changes: 40 additions & 2 deletions src-cljs/com/oakmac/chessboard2/api.cljs
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
(ns com.oakmac.chessboard2.api
"Functions that represent the CLJS API for Chessboard2"
(:require
[clojure.string :as str]
[com.oakmac.chessboard2.animations :refer [animation->dom-op calculate-animations]]
[com.oakmac.chessboard2.constants :refer [animate-speed-strings->times]]
[com.oakmac.chessboard2.config :as config]
[com.oakmac.chessboard2.constants :refer [animate-speed-strings->times start-position]]
[com.oakmac.chessboard2.dom-ops :as dom-ops]
[com.oakmac.chessboard2.feature-flags :as flags]
[com.oakmac.chessboard2.html :as html]
[com.oakmac.chessboard2.util.arrows :as arrow-util]
[com.oakmac.chessboard2.util.dom :as dom-util :refer [get-element set-inner-html! set-style-prop!]]
[com.oakmac.chessboard2.util.fen :refer [fen->position valid-fen?]]
[com.oakmac.chessboard2.util.ids :refer [random-id]]
[com.oakmac.chessboard2.util.logging :refer [warn-log]]
[com.oakmac.chessboard2.util.moves :refer [apply-move-to-position]]
[com.oakmac.chessboard2.util.predicates :refer [arrow-item? valid-square? valid-position?]]
[com.oakmac.chessboard2.util.predicates :refer [arrow-item? fen-string? start-string? valid-square? valid-position?]]
[com.oakmac.chessboard2.util.squares :refer [square->dimensions]]
[goog.object :as gobj]))

;; TODO: move this to a util namespace
; (defn coerce-to-position-map
; "Does it's best to coerce p into a position map if possible"
; [p]
; (cond
; (start-string? p) start-position
; (valid-fen? p) (fen->position p)
; (valid-position? p) p
; :else nil))

(defn get-items-by-type
"Returns a map of <type> Items on the board"
[board-state type-str]
Expand Down Expand Up @@ -376,3 +389,28 @@
(reset! board-state nil))
;; return null
nil)

(defn update-config!
"Update the board config with new values."
[board-state new-config]
(let [;; do not allow them to update the position via this method
cfg2 (dissoc new-config :position)
validated-config (reduce
(fn [cfg3 [prop val]]
(if-not (contains? config/valid-config-keys prop)
;; Google Closure adds these keys to Objects for some reason ¯\_(ツ)_/¯
;; do not log and confuse the end user
(do (when-not (str/starts-with? (name prop) "closure_uid")
(warn-log "Invalid config property:" (name prop)))
cfg3)
(let [validation-fn (get-in config/config-props [prop :valid-fn])
valid-value? (validation-fn val)]
(if-not valid-value?
(do (warn-log (str "Invalid value for config property \"" (name prop) "\": "
val))
cfg3)
(assoc cfg3 prop val)))))
{}
cfg2)]
(swap! board-state merge validated-config)
nil))
Loading