Skip to content

Commit

Permalink
Merge pull request #10 from trongtai37/feat/unit_tests
Browse files Browse the repository at this point in the history
feat: unit tests
  • Loading branch information
trongtai37 authored Jul 29, 2023
2 parents 9cd2c40 + b97da83 commit 85bbeb0
Show file tree
Hide file tree
Showing 7 changed files with 757 additions and 6 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ jobs:
with:
node-version: 16.x
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpx nx format:check --all
- name: Install packages
run: pnpm install --frozen-lockfile
- name: Check code formatting
run: pnpx nx format:check --all
- name: Run unit tests
run: pnpx nx test sudogame
4 changes: 4 additions & 0 deletions packages/solver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsup",
"test": "vitest",
"format:check": "prettier --check",
"format:write": "prettier --write \"**/*.ts\"",
"release": "tsc && changeset publish"
Expand All @@ -29,5 +30,8 @@
"homepage": "https://github.com/trongtai37/sudogame#readme",
"dependencies": {
"logic-solver": "^2.0.1"
},
"devDependencies": {
"vitest": "^0.33.0"
}
}
45 changes: 45 additions & 0 deletions packages/solver/src/generator/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, it } from 'vitest';
import { Generator } from './index';

describe.concurrent('Generator tests', () => {
it('should create an instance with a make method', ({ expect }) => {
const size = 3;
const generator = new Generator(size);

expect(generator).toHaveProperty('make');
expect(generator.make).instanceOf(Function);
});

it('should throw error when initialize with invalid size', ({ expect }) => {
expect(() => new Generator(-1)).toThrowError(
/^Only support size from 2 to 7\.$/,
);
expect(() => new Generator(0)).toThrowError(
/^Only support size from 2 to 7\.$/,
);
expect(() => new Generator(1)).toThrowError(
/^Only support size from 2 to 7\.$/,
);
expect(() => new Generator(8)).toThrowError(
/^Only support size from 2 to 7\.$/,
);
});

it('should create a puzzle with board size is 9 when passing size is 3 to Generator', ({
expect,
}) => {
const generator = new Generator(3);
const puzzle = generator.make();

expect(puzzle.question).toHaveLength(9);
for (const row of puzzle.question) {
expect(row).toHaveLength(9);
}

expect(puzzle.solution).toHaveLength(9);
// @ts-ignore
for (const row of puzzle.solution) {
expect(row).toHaveLength(9);
}
});
});
66 changes: 66 additions & 0 deletions packages/solver/src/solver/lazy-solver.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { describe, it } from 'vitest';
import { LazySolver } from './lazy-solver';

describe.concurrent('LazySolver tests', () => {
it('should generate all valid solutions', ({ expect }) => {
const clues = [
[0, 0, 3, 0, 2, 0, 6, 0, 0],
[9, 0, 0, 3, 0, 5, 0, 0, 1],
[0, 0, 1, 8, 0, 6, 4, 0, 0],
[0, 0, 8, 1, 0, 2, 9, 0, 0],
[7, 0, 0, 0, 0, 0, 0, 0, 8],
[0, 0, 6, 7, 0, 8, 2, 0, 0],
[0, 0, 2, 6, 0, 9, 5, 0, 0],
[8, 0, 0, 2, 0, 3, 0, 0, 9],
[0, 0, 5, 0, 1, 0, 3, 0, 0],
];
const solution = [
[4, 8, 3, 9, 2, 1, 6, 5, 7],
[9, 6, 7, 3, 4, 5, 8, 2, 1],
[2, 5, 1, 8, 7, 6, 4, 9, 3],
[5, 4, 8, 1, 3, 2, 9, 7, 6],
[7, 2, 9, 5, 6, 4, 1, 3, 8],
[1, 3, 6, 7, 9, 8, 2, 4, 5],
[3, 7, 2, 6, 8, 9, 5, 1, 4],
[8, 1, 4, 2, 5, 3, 7, 6, 9],
[6, 9, 5, 4, 1, 7, 3, 8, 2],
];
const solver = new LazySolver({ size: 3, clues });
const generator = solver.generator;
let count = 0;

for (const result of generator) {
expect(result.solution).toEqual(solution);
expect(result.question).toEqual(clues);
count++;
}

expect(count).toEqual(1);
});

it('should throw error if size and clues not match', ({ expect }) => {
const clues = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
];
expect(() => new LazySolver({ size: 4, clues })).toThrowError(
/^Puzzle and size are not match\.$/,
);
});

it('returns null if there is no solution', ({ expect }) => {
const clues = [
[1, 2, 3, 4],
[2, 0, 4, 1],
[3, 4, 0, 2],
[4, 1, 2, 3],
];
const solver = new LazySolver({ size: 2, clues });
const generator = solver.generator;
const solution = generator.next();

expect(solution.value).toBeNull();
});
});
33 changes: 33 additions & 0 deletions packages/solver/src/solver/speed-solver.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, it } from 'vitest';
import { SpeedSolver } from './speed-solver';

describe.concurrent('SpeedSolver tests', () => {
it('solves a Sudoku puzzle', ({ expect }) => {
const puzzle = [
[0, 0, 3, 0, 2, 0, 6, 0, 0],
[9, 0, 0, 3, 0, 5, 0, 0, 1],
[0, 0, 1, 8, 0, 6, 4, 0, 0],
[0, 0, 8, 1, 0, 2, 9, 0, 0],
[7, 0, 0, 0, 0, 0, 0, 0, 8],
[0, 0, 6, 7, 0, 8, 2, 0, 0],
[0, 0, 2, 6, 0, 9, 5, 0, 0],
[8, 0, 0, 2, 0, 3, 0, 0, 9],
[0, 0, 5, 0, 1, 0, 3, 0, 0],
];
const solver = new SpeedSolver({ size: 3 });
const result = solver.solve(puzzle);

expect(result.question).toEqual(puzzle);
expect(result.solution).toEqual([
[4, 8, 3, 9, 2, 1, 6, 5, 7],
[9, 6, 7, 3, 4, 5, 8, 2, 1],
[2, 5, 1, 8, 7, 6, 4, 9, 3],
[5, 4, 8, 1, 3, 2, 9, 7, 6],
[7, 2, 9, 5, 6, 4, 1, 3, 8],
[1, 3, 6, 7, 9, 8, 2, 4, 5],
[3, 7, 2, 6, 8, 9, 5, 1, 4],
[8, 1, 4, 2, 5, 3, 7, 6, 9],
[6, 9, 5, 4, 1, 7, 3, 8, 2],
]);
});
});
7 changes: 7 additions & 0 deletions packages/solver/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
watch: false,
},
});
Loading

0 comments on commit 85bbeb0

Please sign in to comment.