Select Git revision
cell.js 8.75 KiB
// Sudoku Solver
// Copyright (C) 2020 Christoph (Sheogorath) Kern
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
const Cell = require("../lib/cell.js");
const assert = require('assert');
const SAMPLE_CELL_VALUE_A = 1;
describe('Cell', function () {
describe('#constructor()', function () {
it('should create a new writable cell with no set value and no id', function () {
const cell = new Cell();
assert.equal(cell.value, undefined);
assert.equal(cell.id, undefined);
assert.equal(cell.readOnly, false);
});
});
describe('#constructor(value)', function () {
it('should create a new read-only cell with a set value but no id', function () {
const cell = new Cell(SAMPLE_CELL_VALUE_A);
assert.equal(cell.value, SAMPLE_CELL_VALUE_A);
assert.equal(cell.id, undefined);
assert.equal(cell.readOnly, true);
});
});
describe('#constructor(value, id)', function () {
it('should create a new read-only cell with a set value and an id', function () {
const cell = new Cell(SAMPLE_CELL_VALUE_A, "test");
assert.equal(cell.value, SAMPLE_CELL_VALUE_A);
assert.equal(cell.id, "test");
assert.equal(cell.readOnly, true);
});
});
describe('#constructor(undefined, id)', function () {
it('should create a new writable cell with no set value but an id', function () {
const cell = new Cell(undefined, "test");
assert.equal(cell.value, undefined);
assert.equal(cell.id, "test");
assert.equal(cell.readOnly, false);
});
});
describe('value attribute', function () {
it('should return the value of a cell', function () {
const cell = new Cell();
cell.value = SAMPLE_CELL_VALUE_A;
const testValue = cell.value;
assert.equal(cell.value, SAMPLE_CELL_VALUE_A);
assert.equal(testValue, SAMPLE_CELL_VALUE_A);
});
it('should be able to be set to a valid number', function () {
const cell = new Cell();
cell.value = SAMPLE_CELL_VALUE_A;
assert.equal(cell.value, SAMPLE_CELL_VALUE_A);
});
it('should return the value that was set', function () {
const cell = new Cell();
const testValue = cell.value = SAMPLE_CELL_VALUE_A;
assert.equal(cell.value, SAMPLE_CELL_VALUE_A);
assert.equal(testValue, SAMPLE_CELL_VALUE_A);
});
it('should fail when set to an invalid number', function () {
const cell = new Cell();
assert.throws(() => {cell.value = 10}, Error);
assert.equal(cell.value, undefined);
});
it('should fail when trying to set a read-only cell', function () {
const cell = new Cell(SAMPLE_CELL_VALUE_A);
assert.throws(() => {cell.value = 2}, Error);
assert.equal(cell.value, SAMPLE_CELL_VALUE_A);
});
it('should emit a "changed" event when set a the value of a cell', function () {
const cell = new Cell();
let count = 0;
cell.on("changed", () => {count++});
cell.value = 2;
assert.equal(count, 1);
});
it('should emit a "value set" event when set a the value of a cell', function () {
const cell = new Cell();
let count = 0;
cell.on("value set", () => {count++});
cell.value = 2;
assert.equal(count, 1);
});
it('should not emit a "changed" event when trying to set the value of a read-only cell', function () {
const cell = new Cell(SAMPLE_CELL_VALUE_A);
let count = 0;
cell.on("changed", () => {count++});
assert.throws(() => {cell.value = 2}, Error);
assert.equal(count, 0);
});
it('should not emit a "value set" event when trying to set the value of a read-only cell', function () {
const cell = new Cell(SAMPLE_CELL_VALUE_A);
let count = 0;
cell.on("value set", () => {count++});
assert.throws(() => {cell.value = 2}, Error);
assert.equal(count, 0);
});
});
describe('#removeDraft(x)', function () {
it('should ignore the input when cell has a value', function () {
const cell = new Cell();
cell.value = 2
cell.removeDraft(3);
assert.deepEqual(cell.draftState, [1,2,3,4,5,6,7,8,9]);
});
it('should emit a "changed" event when draft was modified', function () {
const cell = new Cell();
let count = 0;
cell.on("changed", () => {count++});
cell.removeDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 1);
});
it('should emit a "draft changed" event when draft was modified', function () {
const cell = new Cell();
let count = 0;
cell.on("draft changed", () => {count++});
cell.removeDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 1);
});
it('should not emit a "changed" event when draft did not need to be modified', function () {
const cell = new Cell();
let count = 0;
cell.removeDraft(SAMPLE_CELL_VALUE_A);
cell.on("changed", () => {count++});
cell.removeDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 0);
});
it('should not emit a "draft changed" event when draft did not need to be modified', function () {
const cell = new Cell();
let count = 0;
cell.removeDraft(SAMPLE_CELL_VALUE_A);
cell.on("draft changed", () => {count++});
cell.removeDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 0);
});
it('should set the value when only one possible draft is left', function () {
const cell = new Cell();
cell.removeDraft(1)
cell.removeDraft(2)
cell.removeDraft(3)
cell.removeDraft(4)
cell.removeDraft(5)
cell.removeDraft(6)
cell.removeDraft(7)
cell.removeDraft(8)
assert.equal(cell.value, 9);
});
});
describe('#addDraft(x)', function () {
it('should ignore the input when cell has a value', function () {
const cell = new Cell();
cell.removeDraft(3);
cell.value = 2
cell.addDraft(3);
assert.deepEqual(cell.draftState, [1,2,4,5,6,7,8,9]);
});
it('should emit a "changed" event when draft was modified', function () {
const cell = new Cell();
cell.removeDraft(SAMPLE_CELL_VALUE_A);
let count = 0;
cell.on("changed", () => {count++});
cell.addDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 1);
});
it('should emit a "draft changed" event when draft was modified', function () {
const cell = new Cell();
cell.removeDraft(SAMPLE_CELL_VALUE_A);
let count = 0;
cell.on("draft changed", () => {count++});
cell.addDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 1);
});
it('should not emit a "changed" event when draft did not need to be modified', function () {
const cell = new Cell();
let count = 0;
cell.addDraft(SAMPLE_CELL_VALUE_A);
cell.on("changed", () => {count++});
cell.addDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 0);
});
it('should not emit a "draft changed" event when draft did not need to be modified', function () {
const cell = new Cell();
let count = 0;
cell.addDraft(SAMPLE_CELL_VALUE_A);
cell.on("draft changed", () => {count++});
cell.addDraft(SAMPLE_CELL_VALUE_A);
assert.equal(count, 0);
});
it('should verify that the provided value is a valid sudoku number', function () {
const cell = new Cell();
assert.throws(() => {cell.addDraft(10)}, Error);
});
});
describe('#isDraft(x)', function () {
it('should return true when cell has x in draftState', function () {
const cell = new Cell();
assert.equal(cell.isDraft(SAMPLE_CELL_VALUE_A), true);
});
it('should return false when cell does not have x in draftState', function () {
const cell = new Cell();
cell.removeDraft(SAMPLE_CELL_VALUE_A);
assert.equal(cell.isDraft(SAMPLE_CELL_VALUE_A), false);
});
it('should return false when cell is preset to a value', function () {
const cell = new Cell(SAMPLE_CELL_VALUE_A);
assert.equal(cell.isDraft(SAMPLE_CELL_VALUE_A), false);
});
it('should return false when cell is set to a value', function () {
const cell = new Cell();
cell.value = SAMPLE_CELL_VALUE_A;
assert.equal(cell.isDraft(SAMPLE_CELL_VALUE_A), false);
});
});
});