Skip to content

Commit d8fdd93

Browse files
authored
Update anagram tests (#578)
1 parent 9a8b0d5 commit d8fdd93

File tree

4 files changed

+166
-27
lines changed

4 files changed

+166
-27
lines changed

exercises/practice/anagram/.meta/example.lua

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ local function alphagram(a_word)
99
local str = a_word
1010
local t = {}
1111
for i = 1, #str do
12-
t[i] = str:sub(i, i) -- string library sets metatable so can be accessed in object oriented style
12+
t[i] = str:sub(i, i) -- string library sets metatable so can be accessed in object oriented style
1313
end
1414
table.sort(t) -- sorts in place, no return value
1515
return table.concat(t, '')
@@ -19,9 +19,7 @@ function Anagram:match(list)
1919
local result = {}
2020
local t = list
2121
for i = 1, #t do
22-
if (t[i]:lower() == self.word) then
23-
table.insert(result, t[i])
24-
elseif (alphagram(t[i]:lower()) == alphagram(self.word)) then
22+
if (t[i]:lower() ~= self.word:lower()) and (alphagram(t[i]:lower()) == alphagram(self.word)) then
2523
table.insert(result, t[i])
2624
end
2725
end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
local function map(t, f)
2+
local mapped = {}
3+
for i, v in ipairs(t) do
4+
mapped[i] = f(v)
5+
end
6+
return mapped
7+
end
8+
9+
local function render_list(list)
10+
return '{ ' .. table.concat(map(list, function(v)
11+
return "'" .. v .. "'"
12+
end), ', ') .. ' }'
13+
end
14+
15+
return {
16+
module_name = 'Anagram',
17+
18+
test_helpers = [[
19+
local function sorted_clone(t)
20+
local clone = {}
21+
for k, v in pairs(t) do
22+
clone[k] = v
23+
end
24+
table.sort(clone)
25+
return clone
26+
end
27+
28+
local function assert_lists_are_same(expected, actual)
29+
assert.are.same(sorted_clone(expected), sorted_clone(actual))
30+
end
31+
]],
32+
33+
generate_test = function(case)
34+
local template = [[
35+
local detector = Anagram:new('%s')
36+
local result = detector:match(%s)
37+
local expected = %s
38+
assert_lists_are_same(expected, result)]]
39+
40+
return template:format(case.input.subject, render_list(case.input.candidates), render_list(case.expected))
41+
end
42+
}

exercises/practice/anagram/.meta/tests.toml

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1-
# This is an auto-generated file. Regular comments will be removed when this
2-
# file is regenerated. Regenerating will not touch any manually added keys,
3-
# so comments can be added in a "comment" key.
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
411

512
[dd40c4d2-3c8b-44e5-992a-f42b393ec373]
613
description = "no matches"
714

815
[b3cca662-f50a-489e-ae10-ab8290a09bdc]
916
description = "detects two anagrams"
17+
include = false
18+
19+
[03eb9bbe-8906-4ea0-84fa-ffe711b52c8b]
20+
description = "detects two anagrams"
21+
reimplements = "b3cca662-f50a-489e-ae10-ab8290a09bdc"
1022

1123
[a27558ee-9ba0-4552-96b1-ecf665b06556]
1224
description = "does not detect anagram subsets"
@@ -34,12 +46,43 @@ description = "detects anagrams using case-insensitive possible matches"
3446

3547
[7cc195ad-e3c7-44ee-9fd2-d3c344806a2c]
3648
description = "does not detect an anagram if the original word is repeated"
49+
include = false
50+
51+
[630abb71-a94e-4715-8395-179ec1df9f91]
52+
description = "does not detect an anagram if the original word is repeated"
53+
reimplements = "7cc195ad-e3c7-44ee-9fd2-d3c344806a2c"
3754

3855
[9878a1c9-d6ea-4235-ae51-3ea2befd6842]
3956
description = "anagrams must use all letters exactly once"
4057

4158
[85757361-4535-45fd-ac0e-3810d40debc1]
4259
description = "words are not anagrams of themselves (case-insensitive)"
60+
include = false
61+
62+
[68934ed0-010b-4ef9-857a-20c9012d1ebf]
63+
description = "words are not anagrams of themselves"
64+
reimplements = "85757361-4535-45fd-ac0e-3810d40debc1"
65+
66+
[589384f3-4c8a-4e7d-9edc-51c3e5f0c90e]
67+
description = "words are not anagrams of themselves even if letter case is partially different"
68+
reimplements = "85757361-4535-45fd-ac0e-3810d40debc1"
69+
70+
[ba53e423-7e02-41ee-9ae2-71f91e6d18e6]
71+
description = "words are not anagrams of themselves even if letter case is completely different"
72+
reimplements = "85757361-4535-45fd-ac0e-3810d40debc1"
4373

4474
[a0705568-628c-4b55-9798-82e4acde51ca]
4575
description = "words other than themselves can be anagrams"
76+
include = false
77+
78+
[33d3f67e-fbb9-49d3-a90e-0beb00861da7]
79+
description = "words other than themselves can be anagrams"
80+
reimplements = "a0705568-628c-4b55-9798-82e4acde51ca"
81+
82+
[a6854f66-eec1-4afd-a137-62ef2870c051]
83+
description = "handles case of greek letters"
84+
include = false
85+
86+
[fd3509e5-e3ba-409d-ac3d-a9ac84d13296]
87+
description = "different characters may have the same bytes"
88+
include = false

exercises/practice/anagram/anagram_spec.lua

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,17 @@ describe('anagram', function()
1414
assert.are.same(sorted_clone(expected), sorted_clone(actual))
1515
end
1616

17-
it('no result', function()
17+
it('no matches', function()
1818
local detector = Anagram:new('diaper')
1919
local result = detector:match({ 'hello', 'world', 'zombies', 'pants' })
2020
local expected = {}
2121
assert_lists_are_same(expected, result)
2222
end)
2323

24-
it('detects simple anagram', function()
25-
local detector = Anagram:new('ant')
26-
local result = detector:match({ 'tan', 'stand', 'at' })
27-
local expected = { 'tan' }
28-
assert_lists_are_same(expected, result)
29-
end)
30-
31-
it('does not detect false positives', function()
32-
local detector = Anagram:new('galea')
33-
local result = detector:match({ 'eagle' })
34-
local expected = {}
35-
assert_lists_are_same(expected, result)
36-
end)
37-
38-
it('detects multiple anagrams', function()
39-
local detector = Anagram:new('master')
40-
local result = detector:match({ 'stream', 'pigeon', 'maters' })
41-
local expected = { 'stream', 'maters' }
24+
it('detects two anagrams', function()
25+
local detector = Anagram:new('solemn')
26+
local result = detector:match({ 'lemons', 'cherry', 'melons' })
27+
local expected = { 'lemons', 'melons' }
4228
assert_lists_are_same(expected, result)
4329
end)
4430

@@ -56,17 +42,87 @@ describe('anagram', function()
5642
assert_lists_are_same(expected, result)
5743
end)
5844

59-
it('detects multiple anagrams', function()
45+
it('detects three anagrams', function()
6046
local detector = Anagram:new('allergy')
6147
local result = detector:match({ 'gallery', 'ballerina', 'regally', 'clergy', 'largely', 'leading' })
6248
local expected = { 'gallery', 'regally', 'largely' }
6349
assert_lists_are_same(expected, result)
6450
end)
6551

52+
it('detects multiple anagrams with different case', function()
53+
local detector = Anagram:new('nose')
54+
local result = detector:match({ 'Eons', 'ONES' })
55+
local expected = { 'Eons', 'ONES' }
56+
assert_lists_are_same(expected, result)
57+
end)
58+
59+
it('does not detect non-anagrams with identical checksum', function()
60+
local detector = Anagram:new('mass')
61+
local result = detector:match({ 'last' })
62+
local expected = {}
63+
assert_lists_are_same(expected, result)
64+
end)
65+
6666
it('detects anagrams case-insensitively', function()
6767
local detector = Anagram:new('Orchestra')
6868
local result = detector:match({ 'cashregister', 'Carthorse', 'radishes' })
6969
local expected = { 'Carthorse' }
7070
assert_lists_are_same(expected, result)
7171
end)
72+
73+
it('detects anagrams using case-insensitive subject', function()
74+
local detector = Anagram:new('Orchestra')
75+
local result = detector:match({ 'cashregister', 'carthorse', 'radishes' })
76+
local expected = { 'carthorse' }
77+
assert_lists_are_same(expected, result)
78+
end)
79+
80+
it('detects anagrams using case-insensitive possible matches', function()
81+
local detector = Anagram:new('orchestra')
82+
local result = detector:match({ 'cashregister', 'Carthorse', 'radishes' })
83+
local expected = { 'Carthorse' }
84+
assert_lists_are_same(expected, result)
85+
end)
86+
87+
it('does not detect an anagram if the original word is repeated', function()
88+
local detector = Anagram:new('go')
89+
local result = detector:match({ 'goGoGO' })
90+
local expected = {}
91+
assert_lists_are_same(expected, result)
92+
end)
93+
94+
it('anagrams must use all letters exactly once', function()
95+
local detector = Anagram:new('tapper')
96+
local result = detector:match({ 'patter' })
97+
local expected = {}
98+
assert_lists_are_same(expected, result)
99+
end)
100+
101+
it('words are not anagrams of themselves', function()
102+
local detector = Anagram:new('BANANA')
103+
local result = detector:match({ 'BANANA' })
104+
local expected = {}
105+
assert_lists_are_same(expected, result)
106+
end)
107+
108+
it('words are not anagrams of themselves even if letter case is partially different', function()
109+
local detector = Anagram:new('BANANA')
110+
local result = detector:match({ 'Banana' })
111+
local expected = {}
112+
assert_lists_are_same(expected, result)
113+
end)
114+
115+
it('words are not anagrams of themselves even if letter case is completely different', function()
116+
local detector = Anagram:new('BANANA')
117+
local result = detector:match({ 'banana' })
118+
local expected = {}
119+
assert_lists_are_same(expected, result)
120+
end)
121+
122+
it('words other than themselves can be anagrams', function()
123+
local detector = Anagram:new('LISTEN')
124+
local result = detector:match({ 'LISTEN', 'Silent' })
125+
local expected = { 'Silent' }
126+
assert_lists_are_same(expected, result)
127+
end)
72128
end)

0 commit comments

Comments
 (0)