• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

brozeph / node-chess / 17656510336

11 Sep 2025 08:28PM UTC coverage: 95.659% (+0.4%) from 95.286%
17656510336

push

github

web-flow
Merge pull request #102 from brozeph/v1.3.1

V1.3.1

462 of 491 branches covered (94.09%)

52 of 54 new or added lines in 2 files covered. (96.3%)

2 existing lines in 2 files now uncovered.

1939 of 2027 relevant lines covered (95.66%)

42655.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
/src/gameValidation.js
1
/**
6✔
2
        GameValidation is the 3rd phase of validation for the game
6✔
3
        and is intended to support Game level events. Examples of Game
6✔
4
        scope validation include Check, Checkmate, 3-fold position
6✔
5
        repetition and pawn promotion.
6✔
6
*/
6✔
7
import { BoardValidation } from './boardValidation.js';
3✔
8
import { PieceType } from './piece.js';
3✔
9

3✔
10
export class GameValidation {
6✔
11
        constructor (game) {
6✔
12
                this.game = game;
324✔
13
        }
324✔
14

3✔
15
        static create (game) {
6✔
16
                return new GameValidation(game);
324✔
17
        }
324✔
18

3✔
19
        findKingSquare (side) {
6✔
20
                let
2,076✔
21
                        i = 0,
2,076✔
22
                        squares = this.game.board.getSquares(side);
2,076✔
23

1,038✔
24
                for (i = 0; i < squares.length; i++) {
2,076✔
25
                        if (squares[i].piece.type === PieceType.King) {
16,158✔
26
                                return squares[i];
2,076✔
27
                        }
2,076✔
28
                }
16,158✔
29
        }
2,076✔
30

3✔
31
        isRepetition () {
6✔
32
                let
2,076✔
33
                        hash = '',
2,076✔
34
                        hashCount = [],
2,076✔
35
                        i = 0;
2,076✔
36

1,038✔
37
                // analyze 3-fold repetition (draw)
2,076✔
38
                for (i = 0; i < this.game.moveHistory.length; i++) {
2,076✔
39
                        hash = this.game.moveHistory[i].hashCode;
30,786✔
40
                        hashCount[hash] = hashCount[hash] ? hashCount[hash] + 1 : 1;
30,786✔
41

15,393✔
42
                        /* eslint no-magic-numbers: 0 */
30,786✔
43
                        if (hashCount[hash] === 3) {
30,786✔
44
                                return true;
6✔
45
                        }
6✔
46
                }
30,786✔
47

1,035✔
48
                return false;
2,070✔
49
        }
2,070✔
50

3✔
51
        start (callback) {
6✔
52
                // ensure callback is set
2,076✔
53
                callback = callback || ((err, result) => new Promise((resolve, reject) => {
2,076!
54
                        if (err) {
×
55
                                return reject(err);
×
56
                        }
×
57

58
                        return resolve(result);
×
59
                }));
2,076✔
60

1,038✔
61
                let
2,076✔
62
                        kingSquare = null,
2,076✔
63
                        result = {
2,076✔
64
                                isCheck : false,
2,076✔
65
                                isCheckmate : false,
2,076✔
66
                                isFiftyMoveDraw : false,
2,076✔
67
                                isRepetition : false,
2,076✔
68
                                isStalemate : false,
2,076✔
69
                                validMoves : []
2,076✔
70
                        },
2,076✔
71
                        setResult = (v, result, isKingAttacked) => {
2,076✔
72
                                return (err, validMoves) => {
2,076✔
73
                                        if (err) {
2,076!
74
                                                return callback(err);
×
75
                                        }
×
76

1,038✔
77
                                        result.isCheck = isKingAttacked && validMoves.length > 0;
2,076✔
78
                                        result.isCheckmate = isKingAttacked && validMoves.length === 0;
2,076✔
79
                                        result.isStalemate = !isKingAttacked && validMoves.length === 0;
2,076✔
80
                                        result.isRepetition = v.isRepetition();
2,076✔
81
                                        result.validMoves = validMoves;
2,076✔
82

1,038✔
83
                                        return callback(null, result);
2,076✔
84
                                };
2,076✔
85
                        },
2,076✔
86
                        v = BoardValidation.create(this.game);
2,076✔
87

1,038✔
88
                if (this.game) {
2,076✔
89
                        // find current side king square
2,076✔
90
                        kingSquare = this.findKingSquare(this.game.getCurrentSide());
2,076✔
91

1,038✔
92
                        // find valid moves
2,076✔
93
                        return v.start(setResult(this, result, v.isSquareAttacked(kingSquare)));
2,076✔
94
                }
2,076!
95
                
×
96
                return callback(new Error('game is invalid'));
×
UNCOV
97
        }
×
98
}
6✔
99

3✔
100
export default { GameValidation };
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc