Skip to content

Commit b9b1ca1

Browse files
committed
Separated tests into their own files
1 parent 41d17ce commit b9b1ca1

File tree

8 files changed

+410
-366
lines changed

8 files changed

+410
-366
lines changed

src/grid.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include<stdexcept>
1010
#include<string>
1111
#include<utility>
12+
#include<vector>
1213

1314
#include"../src/coord.h"
1415

@@ -171,7 +172,7 @@ class Grid {
171172

172173
/*------------------------*/
173174
/* Cell-related Functions */
174-
175+
175176
std::vector<int> get_possible_values_for_cell_at_coord(Coord coord) {
176177
std::vector<int> values = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
177178
std::vector<int> filtered_values(values.size());
@@ -189,7 +190,7 @@ class Grid {
189190
// Shrink vector to remove empty elements.
190191
filtered_values.resize(std::distance(filtered_values.begin(), it));
191192
return filtered_values;
192-
}
193+
}
193194

194195
/*--------------------*/
195196
/* Operator Overloads */

src/sudoku_solver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#define SRC_SUDOKU_SOLVER_H_
44
#endif // SRC_SUDOKU_SOLVER_H_
55

6+
#include<utility>
7+
68
#include"../src/grid.h"
79
#include"../src/coord_utils.h"
810

@@ -41,6 +43,7 @@ bool _solve(
4143
}
4244

4345
void solve(Grid *grid) {
46+
/* Actual function that is used by the user. */
4447
_solve(grid);
4548
}
4649

tests/test_coord_utils.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Copyright 2023 Arjun Aravind */
2+
#ifndef TESTS_TEST_COORD_UTILS_H_
3+
#define TESTS_TEST_COORD_UTILS_H_
4+
5+
#include<utility>
6+
7+
#include"../src/coord_utils.h"
8+
9+
void test_successive_cell_coords_are_generated_correctly() {
10+
/* We test that the get_next_cell_coord() function correctly
11+
* generates the next successive coord value for the sudoku grid. */
12+
assert(
13+
sudoku::get_next_cell_coord(std::make_pair(0, 0))
14+
== std::make_pair(0, 1));
15+
16+
assert(
17+
sudoku::get_next_cell_coord(std::make_pair(0, 8))
18+
== std::make_pair(1, 0));
19+
20+
assert(
21+
sudoku::get_next_cell_coord(std::make_pair(8, 8))
22+
== std::make_pair(8, 8));
23+
}
24+
25+
#endif // TESTS_TEST_COORD_UTILS_H_

tests/test_grid.h

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/* Copyright 2023 Arjun Aravind */
2+
#ifndef TESTS_TEST_GRID_H_
3+
#define TESTS_TEST_GRID_H_
4+
5+
#include<utility>
6+
#include<vector>
7+
8+
#include"../src/grid.h"
9+
10+
void test_puzzle_initial_state_is_set_correctly() {
11+
/* We check if the set_initial_state() function correctly
12+
* adds the non-'0' value coordinates to the list of coords
13+
* that were pre-filled. */
14+
sudoku::Grid grid({{
15+
{{ 0, 0, 3, 0, 0, 0, 0, 0, 0 }},
16+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
17+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
18+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
19+
{{ 1, 0, 0, 0, 0, 0, 0, 0, 0 }},
20+
{{ 0, 0, 0, 0, 0, 7, 0, 0, 0 }},
21+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
22+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
23+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 9 }},
24+
}});
25+
26+
assert(grid.coord_was_pre_filled(std::make_pair(0, 2)));
27+
assert(grid.coord_was_pre_filled(std::make_pair(8, 8)));
28+
assert(grid.coord_was_pre_filled(std::make_pair(4, 0)));
29+
assert(grid.coord_was_pre_filled(std::make_pair(5, 5)));
30+
assert(grid.coord_was_pre_filled(std::make_pair(6, 6)) == false);
31+
}
32+
33+
void test_puzzle_initial_state_is_set_correctly_from_file() {
34+
/* We check if the set_initial_state_from_file() function correctly
35+
* loads the values from a file and sets the initial state. */
36+
37+
sudoku::Grid grid_from_file;
38+
grid_from_file.set_initial_state_from_file("tests/test_data_1.txt");
39+
40+
sudoku::Grid expected_output({{
41+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
42+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
43+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
44+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
45+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
46+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
47+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
48+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
49+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
50+
}});
51+
52+
assert(grid_from_file == expected_output);
53+
}
54+
55+
void test_puzzle_initial_state_isnt_set_due_to_incorrect_values() {
56+
/* We check if the set_initial_state_from_file() function errors out
57+
* when the values in the file are incorrect. */
58+
59+
bool exception_not_thrown = true;
60+
sudoku::Grid grid_from_file;
61+
62+
/*----------*/
63+
/* This file contains values which are >9. It should error out. */
64+
/*----------*/
65+
66+
try {
67+
grid_from_file.set_initial_state_from_file("tests/test_data_2.txt");
68+
} catch (std::invalid_argument ia) {
69+
exception_not_thrown = false;
70+
}
71+
72+
if (exception_not_thrown) assert(false);
73+
74+
/*----------*/
75+
/* This file contains too many values. It should error out. */
76+
/*----------*/
77+
exception_not_thrown = true;
78+
79+
try {
80+
grid_from_file.set_initial_state_from_file("tests/test_data_3.txt");
81+
} catch (std::invalid_argument ia) {
82+
exception_not_thrown = false;
83+
}
84+
85+
if (exception_not_thrown) assert(false);
86+
87+
/*----------*/
88+
/* This file contains too little values. It should error out. */
89+
/*----------*/
90+
exception_not_thrown = true;
91+
92+
try {
93+
grid_from_file.set_initial_state_from_file("tests/test_data_4.txt");
94+
} catch (std::invalid_argument ia) {
95+
exception_not_thrown = false;
96+
}
97+
98+
if (exception_not_thrown) assert(false);
99+
}
100+
101+
void test_exception_is_thrown_if_file_doesnt_exist() {
102+
/* We check if the set_initial_state_from_file() function
103+
* throws an std::invalid_argument exception if the file doesn't exist. */
104+
105+
bool exception_not_thrown = true;
106+
sudoku::Grid grid_from_file;
107+
108+
try {
109+
grid_from_file.set_initial_state_from_file("some_random_thing.txt");
110+
} catch (std::invalid_argument ia) {
111+
exception_not_thrown = false;
112+
}
113+
114+
if (exception_not_thrown) assert(false);
115+
}
116+
117+
void test_value_exists_in_column() {
118+
/* We check functionality of the value_exists_in_column function. */
119+
sudoku::Grid grid({{
120+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
121+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
122+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
123+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
124+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
125+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
126+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
127+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
128+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
129+
}});
130+
131+
assert(grid.value_exists_elsewhere_in_column(std::make_pair(0, 0), 7)
132+
== true);
133+
assert(grid.value_exists_elsewhere_in_column(std::make_pair(1, 5), 1)
134+
== false);
135+
assert(grid.value_exists_elsewhere_in_column(std::make_pair(2, 0), 2)
136+
== false);
137+
assert(grid.value_exists_elsewhere_in_column(std::make_pair(3, 5), 3)
138+
== true);
139+
assert(grid.value_exists_elsewhere_in_column(std::make_pair(4, 8), 1)
140+
== false);
141+
assert(grid.value_exists_elsewhere_in_column(std::make_pair(7, 0), 7)
142+
== false); // The coord itself shouldn't be checked.
143+
}
144+
145+
void test_value_exists_in_row() {
146+
/* We check functionality of the value_exists_in_row function. */
147+
sudoku::Grid grid({{
148+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
149+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
150+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
151+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
152+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
153+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
154+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
155+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
156+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
157+
}});
158+
159+
assert(grid.value_exists_elsewhere_in_row(std::make_pair(0, 0), 8)
160+
== true);
161+
assert(grid.value_exists_elsewhere_in_row(std::make_pair(6, 1), 9)
162+
== true);
163+
assert(grid.value_exists_elsewhere_in_row(std::make_pair(8, 0), 1)
164+
== false);
165+
assert(grid.value_exists_elsewhere_in_row(std::make_pair(1, 8), 9)
166+
== false); // The coord itself shouldn't be checked.
167+
}
168+
169+
void test_value_exists_in_3x3_grid() {
170+
/* We check functionality of the value_exists_in_3x3_grid function. */
171+
sudoku::Grid grid({{
172+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
173+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
174+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
175+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
176+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
177+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
178+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
179+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
180+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
181+
}});
182+
183+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(2, 2), 3)
184+
== true);
185+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(2, 2), 1)
186+
== false);
187+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(5, 4), 5)
188+
== true);
189+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(5, 5), 3)
190+
== false);
191+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(8, 8), 7)
192+
== false);
193+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(6, 6), 7)
194+
== false);
195+
assert(grid.value_exists_elsewhere_in_3x3_grid(std::make_pair(7, 0), 7)
196+
== false); // The coord itself shouldn't be checked.
197+
}
198+
199+
void test_possible_cell_values_generated_correctly() {
200+
/* We check if the get_possible_values_for_cell_at_coord()
201+
* function generates the possible values for each cell correctly. */
202+
sudoku::Grid puzzle({{
203+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
204+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
205+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
206+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
207+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
208+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
209+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
210+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
211+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
212+
}});
213+
214+
auto obtained_value = puzzle.get_possible_values_for_cell_at_coord(
215+
std::make_pair(0, 0));
216+
auto expected_value = std::vector<int>{ 1, 2, 5 };
217+
assert(obtained_value == expected_value);
218+
219+
obtained_value = puzzle.get_possible_values_for_cell_at_coord(
220+
std::make_pair(5, 6));
221+
expected_value = std::vector<int>{ 1, 4, 5, 7, 8 };
222+
assert(obtained_value == expected_value);
223+
224+
obtained_value = puzzle.get_possible_values_for_cell_at_coord(
225+
std::make_pair(8, 8));
226+
expected_value = std::vector<int>{ 1, 4, 7 };
227+
assert(obtained_value == expected_value);
228+
}
229+
230+
#endif // TESTS_TEST_GRID_H_

tests/test_sudoku_generator.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Copyright 2023 Arjun Aravind */
2+
#ifndef TESTS_TEST_SUDOKU_GENERATOR_H_
3+
#define TESTS_TEST_SUDOKU_GENERATOR_H_
4+
5+
#include"../src/sudoku_generator.h"
6+
7+
void test_puzzle_generated_is_solvable() {
8+
/* We test if the generate_puzzle() function generates a puzzle
9+
* that CAN be solved. */
10+
auto generated_puzzle = sudoku::generate_puzzle();
11+
solve(&generated_puzzle);
12+
13+
assert(is_valid_solution(generated_puzzle) == true);
14+
}
15+
16+
void test_no_two_successive_puzzles_generated_are_same() {
17+
/* We test that no two successively generated puzzles, by the
18+
* generate_puzzle() function, are the same. */
19+
auto first_generated_puzzle = sudoku::generate_puzzle();
20+
auto second_generated_puzzle = sudoku::generate_puzzle();
21+
22+
assert((first_generated_puzzle == second_generated_puzzle) == false);
23+
}
24+
25+
#endif // TESTS_TEST_SUDOKU_GENERATOR_H_

tests/test_sudoku_solver.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* Copyright 2023 Arjun Aravind */
2+
#ifndef TESTS_TEST_SUDOKU_SOLVER_H_
3+
#define TESTS_TEST_SUDOKU_SOLVER_H_
4+
5+
#include"../src/sudoku_solver.h"
6+
7+
void test_puzzle_is_solved_correctly() {
8+
/* We check if the solve() function correctly solves the puzzle given. */
9+
sudoku::Grid unsolved_puzzle_grid({{
10+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
11+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
12+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
13+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
14+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
15+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
16+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
17+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
18+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 7 }}
19+
}});
20+
21+
sudoku::solve(&unsolved_puzzle_grid);
22+
23+
sudoku::Grid expected_answer_grid({{
24+
{{ 1, 7, 2, 5, 4, 9, 6, 8, 3 }},
25+
{{ 6, 4, 5, 8, 7, 3, 2, 1, 9 }},
26+
{{ 3, 8, 9, 2, 6, 1, 7, 4, 5 }},
27+
{{ 4, 9, 6, 3, 2, 7, 8, 5, 1 }},
28+
{{ 8, 1, 3, 4, 5, 6, 9, 7, 2 }},
29+
{{ 2, 5, 7, 1, 9, 8, 4, 3, 6 }},
30+
{{ 9, 6, 4, 7, 1, 5, 3, 2, 8 }},
31+
{{ 7, 3, 1, 6, 8, 2, 5, 9, 4 }},
32+
{{ 5, 2, 8, 9, 3, 4, 1, 6, 7 }}
33+
}});
34+
35+
assert(unsolved_puzzle_grid == expected_answer_grid);
36+
37+
/*====TEST 2====*/
38+
39+
unsolved_puzzle_grid.set_initial_state({{
40+
{{ 9, 7, 8, 4, 1, 0, 0, 0, 5 }},
41+
{{ 3, 0, 0, 8, 0, 0, 0, 6, 4 }},
42+
{{ 6, 0, 0, 3, 5, 0, 0, 9, 0 }},
43+
{{ 2, 6, 9, 0, 3, 0, 0, 0, 7 }},
44+
{{ 5, 0, 7, 1, 0, 0, 0, 0, 0 }},
45+
{{ 1, 0, 3, 0, 0, 2, 0, 8, 9 }},
46+
{{ 7, 1, 0, 2, 0, 5, 0, 0, 3 }},
47+
{{ 0, 0, 2, 7, 0, 3, 1, 5, 8 }},
48+
{{ 0, 0, 5, 9, 4, 1, 0, 0, 0 }}
49+
}});
50+
51+
sudoku::solve(&unsolved_puzzle_grid);
52+
53+
expected_answer_grid.set_initial_state({{
54+
{{ 9, 7, 8, 4, 1, 6, 2, 3, 5 }},
55+
{{ 3, 5, 1, 8, 2, 9, 7, 6, 4 }},
56+
{{ 6, 2, 4, 3, 5, 7, 8, 9, 1 }},
57+
{{ 2, 6, 9, 5, 3, 8, 4, 1, 7 }},
58+
{{ 5, 8, 7, 1, 9, 4, 3, 2, 6 }},
59+
{{ 1, 4, 3, 6, 7, 2, 5, 8, 9 }},
60+
{{ 7, 1, 6, 2, 8, 5, 9, 4, 3 }},
61+
{{ 4, 9, 2, 7, 6, 3, 1, 5, 8 }},
62+
{{ 8, 3, 5, 9, 4, 1, 6, 7, 2 }}
63+
}});
64+
65+
assert(unsolved_puzzle_grid == expected_answer_grid);
66+
}
67+
68+
#endif // TESTS_TEST_SUDOKU_SOLVER_H_

0 commit comments

Comments
 (0)