|
5 | 5 | #include "test/catch.hpp"
|
6 | 6 | #endif
|
7 | 7 |
|
| 8 | +#include <string> |
| 9 | +#include <unordered_set> |
| 10 | + |
8 | 11 | using namespace std;
|
9 | 12 |
|
10 | 13 | // Anagram exercise test case data version 1.5.0
|
11 | 14 |
|
12 |
| -TEST_CASE("no_matches") |
13 |
| -{ |
| 15 | +// This class is a helper to allow the solution to return any container type. It |
| 16 | +// takes an std::unordered_set of expected values and provides a method |
| 17 | +// `is_identical_to` that checks if a given container is as expected. Since the |
| 18 | +// method is a method template, it works for any container. |
| 19 | +class ExpectedSet { |
| 20 | + public: |
| 21 | + explicit ExpectedSet(std::unordered_set<std::string> e) |
| 22 | + : expected{std::move(e)} {} |
| 23 | + |
| 24 | + template <typename Container> |
| 25 | + bool is_identical_to(Container const& container) { |
| 26 | + return std::size(expected) == std::size(container) && |
| 27 | + std::all_of(std::cbegin(container), std::cend(container), |
| 28 | + [this](auto const& elem) { |
| 29 | + return expected.count(elem) == 1; |
| 30 | + }); |
| 31 | + } |
| 32 | + |
| 33 | + private: |
| 34 | + std::unordered_set<std::string> expected{}; |
| 35 | +}; |
| 36 | + |
| 37 | +TEST_CASE("no_matches") { |
14 | 38 | // 'anagram::anagram' defines a class
|
15 | 39 | anagram::anagram subject = anagram::anagram("diaper");
|
16 | 40 | auto matches = subject.matches({"hello", "world", "zombies", "pants"});
|
17 |
| - vector<string> expected; |
18 |
| - |
19 |
| - REQUIRE(expected == matches); |
| 41 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
20 | 42 | }
|
21 | 43 |
|
22 | 44 | #if defined(EXERCISM_RUN_ALL_TESTS)
|
23 |
| -TEST_CASE("detects_two_anagrams", "[findAnagrams][03eb9bbe-8906-4ea0-84fa-ffe711b52c8b]") |
24 |
| -{ |
| 45 | +TEST_CASE("detects_two_anagrams", |
| 46 | + "[findAnagrams][03eb9bbe-8906-4ea0-84fa-ffe711b52c8b]") { |
25 | 47 | auto subject = anagram::anagram("solemn");
|
26 |
| - auto matches = subject.matches({"lemons", "cherry", "melons"}); |
27 |
| - vector<string> expected{"lemons", "melons"}; |
| 48 | + auto matches = subject.matches({"cherry", "melons", "lemons"}); |
28 | 49 |
|
29 |
| - REQUIRE(expected == matches); |
| 50 | + REQUIRE(ExpectedSet({"lemons", "melons"}).is_identical_to(matches)); |
30 | 51 | }
|
31 | 52 |
|
32 |
| -TEST_CASE("does_not_detect_anagram_subsets", "[findAnagrams][a27558ee-9ba0-4552-96b1-ecf665b06556]") |
33 |
| -{ |
| 53 | +TEST_CASE("does_not_detect_anagram_subsets", |
| 54 | + "[findAnagrams][a27558ee-9ba0-4552-96b1-ecf665b06556]") { |
34 | 55 | auto subject = anagram::anagram("good");
|
35 | 56 | auto matches = subject.matches({"dog", "goody"});
|
36 |
| - vector<string> expected; |
37 | 57 |
|
38 |
| - REQUIRE(expected == matches); |
| 58 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
39 | 59 | }
|
40 | 60 |
|
41 |
| -TEST_CASE("detects_anagram", "[findAnagrams][64cd4584-fc15-4781-b633-3d814c4941a4]") |
42 |
| -{ |
| 61 | +TEST_CASE("detects_anagram", |
| 62 | + "[findAnagrams][64cd4584-fc15-4781-b633-3d814c4941a4]") { |
43 | 63 | auto subject = anagram::anagram("listen");
|
44 | 64 | auto matches = subject.matches({"enlists", "google", "inlets", "banana"});
|
45 |
| - vector<string> expected{"inlets"}; |
46 | 65 |
|
47 |
| - REQUIRE(expected == matches); |
| 66 | + REQUIRE(ExpectedSet({"inlets"}).is_identical_to(matches)); |
48 | 67 | }
|
49 | 68 |
|
50 |
| -TEST_CASE("detects_three_anagrams", "[findAnagrams][99c91beb-838f-4ccd-b123-935139917283]") |
51 |
| -{ |
| 69 | +TEST_CASE("detects_three_anagrams", |
| 70 | + "[findAnagrams][99c91beb-838f-4ccd-b123-935139917283]") { |
52 | 71 | auto subject = anagram::anagram("allergy");
|
53 |
| - auto matches = subject.matches({ |
54 |
| - "gallery", |
55 |
| - "ballerina", |
56 |
| - "regally", |
57 |
| - "clergy", |
58 |
| - "largely", |
59 |
| - "leading" |
60 |
| - }); |
61 |
| - vector<string> expected{"gallery", "regally", "largely"}; |
| 72 | + auto matches = subject.matches( |
| 73 | + {"gallery", "ballerina", "regally", "clergy", "largely", "leading"}); |
62 | 74 |
|
63 |
| - REQUIRE(expected == matches); |
| 75 | + REQUIRE(ExpectedSet({"gallery", "regally", "largely"}) |
| 76 | + .is_identical_to(matches)); |
64 | 77 | }
|
65 | 78 |
|
66 |
| -TEST_CASE("detects_multiple_anagrams_with_different_case", "[findAnagrams][78487770-e258-4e1f-a646-8ece10950d90]") |
67 |
| -{ |
| 79 | +TEST_CASE("detects_multiple_anagrams_with_different_case", |
| 80 | + "[findAnagrams][78487770-e258-4e1f-a646-8ece10950d90]") { |
68 | 81 | auto subject = anagram::anagram("nose");
|
69 | 82 | auto matches = subject.matches({"Eons", "ONES"});
|
70 |
| - vector<string> expected{"Eons", "ONES"}; |
71 | 83 |
|
72 |
| - REQUIRE(expected == matches); |
| 84 | + REQUIRE(ExpectedSet({"Eons", "ONES"}).is_identical_to(matches)); |
73 | 85 | }
|
74 | 86 |
|
75 |
| -TEST_CASE("does_not_detect_non_anagrams_with_identical_checksum", "[findAnagrams][1d0ab8aa-362f-49b7-9902-3d0c668d557b]") |
76 |
| -{ |
| 87 | +TEST_CASE("does_not_detect_non_anagrams_with_identical_checksum", |
| 88 | + "[findAnagrams][1d0ab8aa-362f-49b7-9902-3d0c668d557b]") { |
77 | 89 | auto subject = anagram::anagram("mass");
|
78 | 90 | auto matches = subject.matches({"last"});
|
79 |
| - vector<string> expected; |
80 | 91 |
|
81 |
| - REQUIRE(expected == matches); |
| 92 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
82 | 93 | }
|
83 | 94 |
|
84 |
| -TEST_CASE("detects_anagrams_case_insensitively", "[findAnagrams][9e632c0b-c0b1-4804-8cc1-e295dea6d8a8]") |
85 |
| -{ |
| 95 | +TEST_CASE("detects_anagrams_case_insensitively", |
| 96 | + "[findAnagrams][9e632c0b-c0b1-4804-8cc1-e295dea6d8a8]") { |
86 | 97 | auto subject = anagram::anagram("Orchestra");
|
87 | 98 | auto matches = subject.matches({"cashregister", "Carthorse", "radishes"});
|
88 |
| - vector<string> expected{"Carthorse"}; |
89 | 99 |
|
90 |
| - REQUIRE(expected == matches); |
| 100 | + REQUIRE(ExpectedSet({"Carthorse"}).is_identical_to(matches)); |
91 | 101 | }
|
92 | 102 |
|
93 |
| -TEST_CASE("detects_anagrams_using_case_insensitive_subject", "[findAnagrams][b248e49f-0905-48d2-9c8d-bd02d8c3e392]") |
94 |
| -{ |
| 103 | +TEST_CASE("detects_anagrams_using_case_insensitive_subject", |
| 104 | + "[findAnagrams][b248e49f-0905-48d2-9c8d-bd02d8c3e392]") { |
95 | 105 | auto subject = anagram::anagram("Orchestra");
|
96 | 106 | auto matches = subject.matches({"cashregister", "carthorse", "radishes"});
|
97 |
| - vector<string> expected{"carthorse"}; |
98 | 107 |
|
99 |
| - REQUIRE(expected == matches); |
| 108 | + REQUIRE(ExpectedSet({"carthorse"}).is_identical_to(matches)); |
100 | 109 | }
|
101 | 110 |
|
102 |
| -TEST_CASE("detects_anagrams_using_case_insensitive_possible_matches", "[findAnagrams][f367325c-78ec-411c-be76-e79047f4bd54]") |
103 |
| -{ |
| 111 | +TEST_CASE("detects_anagrams_using_case_insensitive_possible_matches", |
| 112 | + "[findAnagrams][f367325c-78ec-411c-be76-e79047f4bd54]") { |
104 | 113 | auto subject = anagram::anagram("orchestra");
|
105 | 114 | auto matches = subject.matches({"cashregister", "Carthorse", "radishes"});
|
106 |
| - vector<string> expected{"Carthorse"}; |
107 | 115 |
|
108 |
| - REQUIRE(expected == matches); |
| 116 | + REQUIRE(ExpectedSet({"Carthorse"}).is_identical_to(matches)); |
109 | 117 | }
|
110 | 118 |
|
111 |
| -TEST_CASE("does_not_detect_an_anagram_if_the_original_word_is_repeated", "[findAnagrams][630abb71-a94e-4715-8395-179ec1df9f91]") |
112 |
| -{ |
| 119 | +TEST_CASE("does_not_detect_an_anagram_if_the_original_word_is_repeated", |
| 120 | + "[findAnagrams][630abb71-a94e-4715-8395-179ec1df9f91]") { |
113 | 121 | auto subject = anagram::anagram("go");
|
114 | 122 | auto matches = subject.matches({"goGoGO"});
|
115 |
| - vector<string> expected; |
116 | 123 |
|
117 |
| - REQUIRE(expected == matches); |
| 124 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
118 | 125 | }
|
119 | 126 |
|
120 |
| -TEST_CASE("anagrams_must_use_all_letters_exactly_once", "[findAnagrams][9878a1c9-d6ea-4235-ae51-3ea2befd6842]") |
121 |
| -{ |
| 127 | +TEST_CASE("anagrams_must_use_all_letters_exactly_once", |
| 128 | + "[findAnagrams][9878a1c9-d6ea-4235-ae51-3ea2befd6842]") { |
122 | 129 | auto subject = anagram::anagram("tapper");
|
123 | 130 | auto matches = subject.matches({"patter"});
|
124 |
| - vector<string> expected; |
125 | 131 |
|
126 |
| - REQUIRE(expected == matches); |
| 132 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
127 | 133 | }
|
128 | 134 |
|
129 |
| -TEST_CASE("words_are_not_anagrams_of_themselves", "[findAnagrams][68934ed0-010b-4ef9-857a-20c9012d1ebf]") |
130 |
| -{ |
| 135 | +TEST_CASE("words_are_not_anagrams_of_themselves", |
| 136 | + "[findAnagrams][68934ed0-010b-4ef9-857a-20c9012d1ebf]") { |
131 | 137 | auto subject = anagram::anagram("BANANA");
|
132 | 138 | auto matches = subject.matches({"BANANA"});
|
133 |
| - vector<string> expected; |
134 | 139 |
|
135 |
| - REQUIRE(expected == matches); |
| 140 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
136 | 141 | }
|
137 | 142 |
|
138 |
| -TEST_CASE("words_are_not_anagrams_of_themselves_even_if_letter_case_is_partially_different", "[findAnagrams][589384f3-4c8a-4e7d-9edc-51c3e5f0c90e]") |
139 |
| -{ |
| 143 | +TEST_CASE( |
| 144 | + // clang-format off |
| 145 | + "words_are_not_anagrams_of_themselves_even_if_letter_case_is_partially_different", |
| 146 | + // clang-format on |
| 147 | + "[findAnagrams][589384f3-4c8a-4e7d-9edc-51c3e5f0c90e]") { |
140 | 148 | auto subject = anagram::anagram("BANANA");
|
141 | 149 | auto matches = subject.matches({"Banana"});
|
142 |
| - vector<string> expected; |
143 | 150 |
|
144 |
| - REQUIRE(expected == matches); |
| 151 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
145 | 152 | }
|
146 | 153 |
|
147 |
| -TEST_CASE("words_are_not_anagrams_of_themselves_even_if_letter_case_is_completely_different", "[findAnagrams][ba53e423-7e02-41ee-9ae2-71f91e6d18e6]") |
148 |
| -{ |
| 154 | +TEST_CASE( |
| 155 | + // clang-format off |
| 156 | + "words_are_not_anagrams_of_themselves_even_if_letter_case_is_completely_different", |
| 157 | + // clang-format on |
| 158 | + "[findAnagrams][ba53e423-7e02-41ee-9ae2-71f91e6d18e6]") { |
149 | 159 | auto subject = anagram::anagram("BANANA");
|
150 | 160 | auto matches = subject.matches({"banana"});
|
151 |
| - vector<string> expected; |
152 | 161 |
|
153 |
| - REQUIRE(expected == matches); |
| 162 | + REQUIRE(ExpectedSet({}).is_identical_to(matches)); |
154 | 163 | }
|
155 | 164 |
|
156 |
| -TEST_CASE("words_other_than_themselves_can_be_anagrams", "[findAnagrams][33d3f67e-fbb9-49d3-a90e-0beb00861da7]") |
157 |
| -{ |
| 165 | +TEST_CASE("words_other_than_themselves_can_be_anagrams", |
| 166 | + "[findAnagrams][33d3f67e-fbb9-49d3-a90e-0beb00861da7]") { |
158 | 167 | auto subject = anagram::anagram("LISTEN");
|
159 | 168 | auto matches = subject.matches({"Silent", "LISTEN"});
|
160 |
| - vector<string> expected{"Silent"}; |
161 | 169 |
|
162 |
| - REQUIRE(expected == matches); |
| 170 | + REQUIRE(ExpectedSet({"Silent"}).is_identical_to(matches)); |
163 | 171 | }
|
164 | 172 | #endif
|
0 commit comments