Sudoku Solver: Add functional tests and fix Unit Tests
This commit is contained in:
parent
70cee77a95
commit
0d2e39e7ba
4 changed files with 237 additions and 76 deletions
|
@ -1,22 +1,41 @@
|
|||
export const puzzlesAndSolutions = [
|
||||
[
|
||||
'1.5..2.84..63.12.7.2..5.....9..1....8.2.3674.3.7.2..9.47...8..1..16....926914.37.',
|
||||
'135762984946381257728459613694517832812936745357824196473298561581673429269145378'
|
||||
"1.5..2.84..63.12.7.2..5.....9..1....8.2.3674.3.7.2..9.47...8..1..16....926914.37.",
|
||||
"135762984946381257728459613694517832812936745357824196473298561581673429269145378",
|
||||
],
|
||||
[
|
||||
'5..91372.3...8.5.9.9.25..8.68.47.23...95..46.7.4.....5.2.......4..8916..85.72...3',
|
||||
'568913724342687519197254386685479231219538467734162895926345178473891652851726943'
|
||||
"5..91372.3...8.5.9.9.25..8.68.47.23...95..46.7.4.....5.2.......4..8916..85.72...3",
|
||||
"568913724342687519197254386685479231219538467734162895926345178473891652851726943",
|
||||
],
|
||||
[
|
||||
'..839.7.575.....964..1.......16.29846.9.312.7..754.....62..5.78.8...3.2...492...1',
|
||||
'218396745753284196496157832531672984649831257827549613962415378185763429374928561'
|
||||
"..839.7.575.....964..1.......16.29846.9.312.7..754.....62..5.78.8...3.2...492...1",
|
||||
"218396745753284196496157832531672984649831257827549613962415378185763429374928561",
|
||||
],
|
||||
[
|
||||
'.7.89.....5....3.4.2..4..1.5689..472...6.....1.7.5.63873.1.2.8.6..47.1..2.9.387.6',
|
||||
'473891265851726394926345817568913472342687951197254638734162589685479123219538746'
|
||||
".7.89.....5....3.4.2..4..1.5689..472...6.....1.7.5.63873.1.2.8.6..47.1..2.9.387.6",
|
||||
"473891265851726394926345817568913472342687951197254638734162589685479123219538746",
|
||||
],
|
||||
[
|
||||
'82..4..6...16..89...98315.749.157.............53..4...96.415..81..7632..3...28.51',
|
||||
'827549163531672894649831527496157382218396475753284916962415738185763249374928651'
|
||||
]
|
||||
"82..4..6...16..89...98315.749.157.............53..4...96.415..81..7632..3...28.51",
|
||||
"827549163531672894649831527496157382218396475753284916962415738185763249374928651",
|
||||
],
|
||||
];
|
||||
|
||||
export const invalidStrings = [
|
||||
"135762984946-8125772845961369451783281293674535B82419647329856158167342926:145378",
|
||||
'56891372434268751"%=7254386685479231219538467734162895926345178473891652851726943',
|
||||
"/////////////////////////////////////////////////////////////////////////////////",
|
||||
"NyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyan.",
|
||||
];
|
||||
|
||||
export const unsolvableStrings = [
|
||||
"115..2.84..63.12.7.2..5.....9..1....8.2.3674.3.7.2..9.420..8..1..16....926969.37.",
|
||||
"4206942069.......................................................................",
|
||||
"111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||
];
|
||||
|
||||
export const wrongLengthStrings = [
|
||||
"123456",
|
||||
"9999999.9999992",
|
||||
"1.5..2.84..63.12.7.2..5.....9..1....8.2.3674.3.7.2..9.47...8..1..16....926914.37.5..91372.3...8.5.9.9.25..8.68.47.23...95..46.7.4.....5.2.......4..8916..85.72...3",
|
||||
];
|
||||
|
|
|
@ -41,7 +41,7 @@ class SudokuSolver {
|
|||
checkRegionPlacement(puzzleString, row, column, value) {}
|
||||
|
||||
solve(puzzleString) {
|
||||
return false;
|
||||
return { error: "test" };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
const chai = require("chai");
|
||||
const assert = chai.assert;
|
||||
import { puzzlesAndSolutions } from "../controllers/puzzle-strings";
|
||||
|
||||
const invalidStrings = [
|
||||
"135762984946-8125772845961369451783281293674535B82419647329856158167342926:145378",
|
||||
'56891372434268751"%=7254386685479231219538467734162895926345178473891652851726943',
|
||||
"/////////////////////////////////////////////////////////////////////////////////",
|
||||
"NyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyanNyan.",
|
||||
];
|
||||
|
||||
const unsolvableStrings = [
|
||||
"115..2.84..63.12.7.2..5.....9..1....8.2.3674.3.7.2..9.420..8..1..16....926969.37.",
|
||||
"4206942069.......................................................................",
|
||||
"111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||
];
|
||||
import {
|
||||
puzzlesAndSolutions,
|
||||
invalidStrings,
|
||||
unsolvableStrings,
|
||||
wrongLengthStrings,
|
||||
} from "../controllers/puzzle-strings";
|
||||
|
||||
const Solver = require("../controllers/sudoku-solver.js");
|
||||
let solver = new Solver();
|
||||
|
@ -35,10 +27,12 @@ suite("Unit Tests", () => {
|
|||
}
|
||||
});
|
||||
test("Logic handles a puzzle string that is not 81 characters in length", () => {
|
||||
assert.equal(
|
||||
solver.validate("135762984946145378").error,
|
||||
"Expected puzzle to be 81 characters long"
|
||||
);
|
||||
for (let i in wrongLengthStrings) {
|
||||
assert.equal(
|
||||
solver.validate(wrongLengthStrings[i]).error,
|
||||
"Expected puzzle to be 81 characters long"
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
suite("Placement Checks", () => {
|
||||
|
@ -106,7 +100,6 @@ suite("Unit Tests", () => {
|
|||
suite("Solver", () => {
|
||||
test("Valid puzzle strings pass the solver", () => {
|
||||
for (let i in puzzlesAndSolutions) {
|
||||
console.log(i);
|
||||
assert.equal(
|
||||
solver.solve(puzzlesAndSolutions[i][1]),
|
||||
puzzlesAndSolutions[i][1]
|
||||
|
@ -116,21 +109,9 @@ suite("Unit Tests", () => {
|
|||
test("Invalid puzzle strings fail the solver", () => {
|
||||
for (let i in invalidStrings) {
|
||||
assert.equal(
|
||||
solver.solve(invalidStrings[i].error),
|
||||
"Invalid characters in puzzle",
|
||||
"invalid characters" + invalidStrings[i]
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
solver.solve("135762984946145378").error,
|
||||
"Expected puzzle to be 81 characters long",
|
||||
"wrong length"
|
||||
);
|
||||
for (let i in unsolvableStrings) {
|
||||
assert.equal(
|
||||
solver.solve().error,
|
||||
"Puzzle cannot be solved",
|
||||
"not solvable" + unsolvableStrings[i]
|
||||
solver.solve(invalidStrings[i]),
|
||||
{ error: "Invalid characters in puzzle" },
|
||||
"invalid characters"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -145,12 +126,3 @@ suite("Unit Tests", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
|
||||
|
||||
|
||||
Valid puzzle strings pass the solver
|
||||
*/
|
||||
|
|
|
@ -2,27 +2,197 @@ const chai = require("chai");
|
|||
const chaiHttp = require("chai-http");
|
||||
const assert = chai.assert;
|
||||
const server = require("../server");
|
||||
import {
|
||||
puzzlesAndSolutions,
|
||||
invalidStrings,
|
||||
unsolvableStrings,
|
||||
wrongLengthStrings,
|
||||
} from "../controllers/puzzle-strings";
|
||||
|
||||
chai.use(chaiHttp);
|
||||
|
||||
suite("Functional Tests", () => {});
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
Solve a puzzle with valid puzzle string: POST request to /api/solve
|
||||
Solve a puzzle with missing puzzle string: POST request to /api/solve
|
||||
Solve a puzzle with invalid characters: POST request to /api/solve
|
||||
Solve a puzzle with incorrect length: POST request to /api/solve
|
||||
Solve a puzzle that cannot be solved: POST request to /api/solve
|
||||
Check a puzzle placement with all fields: POST request to /api/check
|
||||
Check a puzzle placement with single placement conflict: POST request to /api/check
|
||||
Check a puzzle placement with multiple placement conflicts: POST request to /api/check
|
||||
Check a puzzle placement with all placement conflicts: POST request to /api/check
|
||||
Check a puzzle placement with missing required fields: POST request to /api/check
|
||||
Check a puzzle placement with invalid characters: POST request to /api/check
|
||||
Check a puzzle placement with incorrect length: POST request to /api/check
|
||||
Check a puzzle placement with invalid placement coordinate: POST request to /api/check
|
||||
Check a puzzle placement with invalid placement value: POST request to /api/check
|
||||
|
||||
*/
|
||||
suite("Functional Tests", () => {
|
||||
suite("Solving puzzles", () => {
|
||||
test("Solve a puzzle with valid puzzle string: POST request to /api/solve", (done) => {
|
||||
for (let i in puzzlesAndSolutions) {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/solve")
|
||||
.send({ puzzle: puzzlesAndSolutions[i][0] })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.solution, puzzlesAndSolutions[i][1]);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
test("Solve a puzzle with missing puzzle string: POST request to /api/solve", (done) => {
|
||||
for (let i in puzzlesAndSolutions) {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/solve")
|
||||
.send({})
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Required field missing");
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
test("Solve a puzzle with invalid characters: POST request to /api/solve", (done) => {
|
||||
for (let i in invalidStrings) {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/solve")
|
||||
.send({ puzzle: invalidStrings[i] })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Invalid characters in puzzle");
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
test("Solve a puzzle with incorrect length: POST request to /api/solve", (done) => {
|
||||
for (let i in wrongLengthStrings) {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/solve")
|
||||
.send({ puzzle: wrongLengthStrings[i] })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(
|
||||
res.body.error,
|
||||
"Expected puzzle to be 81 charcters long"
|
||||
);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
test("Solve a puzzle that cannot be solved: POST request to /api/solve", (done) => {
|
||||
for (let i in unsolvableStrings) {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/solve")
|
||||
.send({ puzzle: unsolvableStrings[i] })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Puzzle cannot be solved");
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
suite("Placement Checks", () => {
|
||||
test("Check a puzzle placement with all fields: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0][0], coordinate: "A2", value: 3 })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.valid, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with single placement conflict: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0][0], coordinate: "A2", value: 4 })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.valid, false);
|
||||
assert.include(res.body.conflict, "row");
|
||||
assert.notInclude(res.body.conflict, "region");
|
||||
assert.notInclude(res.body.conflict, "column");
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with multiple placement conflicts: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0][0], coordinate: "A2", value: 1 })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.valid, false);
|
||||
assert.include(res.body.conflict, "row");
|
||||
assert.include(res.body.conflict, "region");
|
||||
assert.notInclude(res.body.conflict, "column");
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with all placement conflicts: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0][0], coordinate: "A2", value: 2 })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.valid, false);
|
||||
assert.include(res.body.conflict, "row");
|
||||
assert.include(res.body.conflict, "region");
|
||||
assert.include(res.body.conflict, "column");
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with missing required fields: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0][0], coordinate: "A2" })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Required field(s) missing");
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with invalid characters: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: invalidStrings[0], coordinate: "A2", value: "3" })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Invalid characters in puzzle");
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with incorrect length: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: wrongLengthStrings[0], coordinate: "A2", value: "3" })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(
|
||||
res.body.error,
|
||||
"Expected puzzle to be 81 characters long"
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with invalid placement coordinate: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0], coordinate: "Z11", value: "3" })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Invalid coordinate");
|
||||
done();
|
||||
});
|
||||
});
|
||||
test("Check a puzzle placement with invalid placement value: POST request to /api/check", (done) => {
|
||||
chai
|
||||
.request(server)
|
||||
.post("/api/check")
|
||||
.send({ puzzle: puzzlesAndSolutions[0], coordinate: "A2", value: "22" })
|
||||
.end((err, res) => {
|
||||
assert.equal(res.status, 200);
|
||||
assert.equal(res.body.error, "Invalid value");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Reference in a new issue