Skip to content

Commit 8870c07

Browse files
authored
Update word-count tests (#597)
1 parent f9de53a commit 8870c07

File tree

5 files changed

+119
-48
lines changed

5 files changed

+119
-48
lines changed
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
local function word_count(s)
1+
local function count_words(s)
22
local counts = {}
3-
s = s:gsub("'([%w%d']+)'", "%1")
43
for w in s:gmatch('[%w%d\']+') do
5-
local normalized = w:lower()
6-
counts[normalized] = (counts[normalized] or 0) + 1
4+
local w = w:lower():gsub("^'", ''):gsub("'$", '')
5+
if #w > 0 then
6+
counts[w] = (counts[w] or 0) + 1
7+
end
78
end
89
return counts
910
end
1011

11-
return { word_count = word_count }
12+
return { count_words = count_words }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
local function stringify(s)
2+
s = s:gsub('\n', '\\n')
3+
if s:match("'") and not s:match('"') then
4+
return '"' .. s .. '"'
5+
else
6+
return "'" .. s:gsub("'", "\\'") .. "'"
7+
end
8+
end
9+
10+
local function format_hash(t)
11+
local key_value_pairs = {}
12+
for key in pairs(t) do
13+
table.insert(key_value_pairs, "[" .. stringify(key) .. "] = " .. t[key])
14+
end
15+
16+
table.sort(key_value_pairs)
17+
18+
return '{ ' .. table.concat(key_value_pairs, ', ') .. ' }'
19+
end
20+
21+
return {
22+
module_name = 'word_count',
23+
24+
generate_test = function(case)
25+
local template = [[
26+
local result = word_count.count_words(%s)
27+
local expected = %s
28+
assert.are.same(expected, result)]]
29+
30+
return template:format(stringify(case.input.sentence), format_hash(case.expected))
31+
end
32+
}

exercises/practice/word-count/.meta/tests.toml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
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
[61559d5f-2cad-48fb-af53-d3973a9ee9ef]
613
description = "count one word"
@@ -28,6 +35,11 @@ description = "normalize case"
2835

2936
[4185a902-bdb0-4074-864c-f416e42a0f19]
3037
description = "with apostrophes"
38+
include = false
39+
40+
[4ff6c7d7-fcfc-43ef-b8e7-34ff1837a2d3]
41+
description = "with apostrophes"
42+
reimplements = "4185a902-bdb0-4074-864c-f416e42a0f19"
3143

3244
[be72af2b-8afe-4337-b151-b297202e4a7b]
3345
description = "with quotations"
@@ -40,3 +52,6 @@ description = "multiple spaces not detected as a word"
4052

4153
[50176e8a-fe8e-4f4c-b6b6-aa9cf8f20360]
4254
description = "alternating word separators not detected as a word"
55+
56+
[6d00f1db-901c-4bec-9829-d20eb3044557]
57+
description = "quotation for word with apostrophe"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
local function word_count(s)
1+
local function count_words(s)
22
end
33

4-
return { word_count = word_count }
4+
return { count_words = count_words }
Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,105 @@
1-
-- problem specification version 1.4.0
2-
local word_count = require('word-count').word_count
1+
local word_count = require('word-count')
32

43
describe('word-count', function()
5-
it('counts one word', function()
6-
local result = word_count('word')
7-
local expected = { word = 1 }
4+
it('count one word', function()
5+
local result = word_count.count_words('word')
6+
local expected = { ['word'] = 1 }
87
assert.are.same(expected, result)
98
end)
109

11-
it('counts one of each', function()
12-
local result = word_count('one of each')
13-
local expected = { one = 1, of = 1, each = 1 }
10+
it('count one of each word', function()
11+
local result = word_count.count_words('one of each')
12+
local expected = { ['each'] = 1, ['of'] = 1, ['one'] = 1 }
1413
assert.are.same(expected, result)
1514
end)
1615

17-
it('counts multiple occurrences', function()
18-
local result = word_count('one fish two fish red fish blue fish')
19-
local expected = { one = 1, fish = 4, two = 1, red = 1, blue = 1 }
16+
it('multiple occurrences of a word', function()
17+
local result = word_count.count_words('one fish two fish red fish blue fish')
18+
local expected = { ['blue'] = 1, ['fish'] = 4, ['one'] = 1, ['red'] = 1, ['two'] = 1 }
2019
assert.are.same(expected, result)
2120
end)
2221

2322
it('handles cramped lists', function()
24-
local result = word_count('one,two,three')
25-
local expected = { one = 1, two = 1, three = 1 }
23+
local result = word_count.count_words('one,two,three')
24+
local expected = { ['one'] = 1, ['three'] = 1, ['two'] = 1 }
2625
assert.are.same(expected, result)
2726
end)
2827

2928
it('handles expanded lists', function()
30-
local result = word_count('one,\ntwo,\nthree')
31-
local expected = { one = 1, two = 1, three = 1 }
29+
local result = word_count.count_words('one,\ntwo,\nthree')
30+
local expected = { ['one'] = 1, ['three'] = 1, ['two'] = 1 }
3231
assert.are.same(expected, result)
3332
end)
3433

35-
it('ignores punctuation', function()
36-
local result = word_count('car : carpet as java : javascript!!&@$%^&')
37-
local expected = { car = 1, carpet = 1, as = 1, java = 1, javascript = 1 }
34+
it('ignore punctuation', function()
35+
local result = word_count.count_words('car: carpet as java: javascript!!&@$%^&')
36+
local expected = { ['as'] = 1, ['car'] = 1, ['carpet'] = 1, ['java'] = 1, ['javascript'] = 1 }
3837
assert.are.same(expected, result)
3938
end)
4039

41-
it('includes numbers', function()
42-
local result = word_count('testing, 1, 2 testing')
43-
local expected = { testing = 2, ['1'] = 1, ['2'] = 1 }
40+
it('include numbers', function()
41+
local result = word_count.count_words('testing, 1, 2 testing')
42+
local expected = { ['1'] = 1, ['2'] = 1, ['testing'] = 2 }
4443
assert.are.same(expected, result)
4544
end)
4645

47-
it('normalizes case', function()
48-
local result = word_count('go Go GO Stop stop')
49-
local expected = { go = 3, stop = 2 }
46+
it('normalize case', function()
47+
local result = word_count.count_words('go Go GO Stop stop')
48+
local expected = { ['go'] = 3, ['stop'] = 2 }
5049
assert.are.same(expected, result)
5150
end)
5251

53-
it('counts with apostrophes', function()
54-
local result = word_count("First: don't laugh. Then: don't cry.")
55-
local expected = { first = 1, ["don't"] = 2, laugh = 1, ['then'] = 1, cry = 1 }
52+
it('with apostrophes', function()
53+
local result = word_count.count_words("'First: don't laugh. Then: don't cry. You're getting it.'")
54+
local expected = {
55+
["don't"] = 2,
56+
["you're"] = 1,
57+
['cry'] = 1,
58+
['first'] = 1,
59+
['getting'] = 1,
60+
['it'] = 1,
61+
['laugh'] = 1,
62+
['then'] = 1
63+
}
5664
assert.are.same(expected, result)
5765
end)
5866

59-
it('counts with quotation', function()
60-
local result = word_count("Joe can't tell between 'large' and large.")
61-
local expected = { joe = 1, ["can't"] = 1, tell = 1, between = 1, large = 2, ["and"] = 1 }
67+
it('with quotations', function()
68+
local result = word_count.count_words("Joe can't tell between 'large' and large.")
69+
local expected = { ["can't"] = 1, ['and'] = 1, ['between'] = 1, ['joe'] = 1, ['large'] = 2, ['tell'] = 1 }
6270
assert.are.same(expected, result)
6371
end)
6472

65-
it('counts with substrings from the beginning', function()
66-
local result = word_count("Joe can't tell between app, apple and a.")
67-
local expected = { joe = 1, ["can't"] = 1, tell = 1, between = 1, app = 1, apple = 1, ["and"] = 1, a = 1 }
73+
it('substrings from the beginning', function()
74+
local result = word_count.count_words("Joe can't tell between app, apple and a.")
75+
local expected = {
76+
["can't"] = 1,
77+
['a'] = 1,
78+
['and'] = 1,
79+
['app'] = 1,
80+
['apple'] = 1,
81+
['between'] = 1,
82+
['joe'] = 1,
83+
['tell'] = 1
84+
}
6885
assert.are.same(expected, result)
6986
end)
7087

71-
it('does not count multiple spaces as a word', function()
72-
local result = word_count(' multiple whitespaces')
73-
local expected = { multiple = 1, whitespaces = 1 }
88+
it('multiple spaces not detected as a word', function()
89+
local result = word_count.count_words(' multiple whitespaces')
90+
local expected = { ['multiple'] = 1, ['whitespaces'] = 1 }
7491
assert.are.same(expected, result)
7592
end)
7693

7794
it('alternating word separators not detected as a word', function()
78-
local result = word_count(",\n,one,\n ,two \n 'three'")
79-
local expected = { one = 1, two = 1, three = 1 }
95+
local result = word_count.count_words(",\n,one,\n ,two \n 'three'")
96+
local expected = { ['one'] = 1, ['three'] = 1, ['two'] = 1 }
97+
assert.are.same(expected, result)
98+
end)
99+
100+
it('quotation for word with apostrophe', function()
101+
local result = word_count.count_words("can, can't, 'can't'")
102+
local expected = { ["can't"] = 2, ['can'] = 1 }
80103
assert.are.same(expected, result)
81104
end)
82105
end)

0 commit comments

Comments
 (0)