Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/generate-spec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ utils.map = function(t, f)
end

utils.stringify = function(s)
s = s:gsub('\n', '\\n')
s = s:gsub('\\', '\\\\'):gsub('\n', '\\n')

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if s:match("'") and not s:match('"') then
return '"' .. s .. '"'
else
Expand Down
11 changes: 11 additions & 0 deletions exercises/practice/crypto-square/.meta/spec_generator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
local utils = require 'utils'

return {
module_name = 'crypto_square',

generate_test = function(case)
local template = [[
assert.are.equal(%s, crypto_square.ciphertext(%s))]]
return template:format(utils.stringify(case.expected), utils.stringify(case.input.plaintext))
end
}
6 changes: 3 additions & 3 deletions exercises/practice/crypto-square/crypto-square_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ describe('crypto-square', function()
assert.are.equal('', crypto_square.ciphertext('... --- ...'))
end)

it('Lowercase', function()
it('lowercase', function()
assert.are.equal('a', crypto_square.ciphertext('A'))
end)

it('Remove spaces', function()
it('remove spaces', function()
assert.are.equal('b', crypto_square.ciphertext(' b '))
end)

it('Remove punctuation', function()
it('remove punctuation', function()
assert.are.equal('1', crypto_square.ciphertext('@1,%!'))
end)

Expand Down
20 changes: 20 additions & 0 deletions exercises/practice/knapsack/.meta/spec_generator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
local utils = require 'utils'

local function render_items(items)
return table.concat(utils.map(items, function(item)
return ('{ weight = %d, value = %d }'):format(item.weight, item.value)
end), ', ')
end

return {
module_name = 'knapsack',

generate_test = function(case)
local template = [[
local items = { %s }
local maximum_weight = %d

assert.are.equal(%d, knapsack.maximum_value(maximum_weight, items))]]
return template:format(render_items(case.input.items), case.input.maximumWeight, case.expected)
end
}
14 changes: 7 additions & 7 deletions exercises/practice/knapsack/knapsack_spec.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
local knapsack = require 'knapsack'
local knapsack = require('knapsack')

describe('knapsack', function()
it('no items', function()
local items = {}
local maximum_weight = 100

assert.are.equal(0, knapsack.maximum_value(maximum_weight, items))
end)

it('one item too heavy', function()
it('one item, too heavy', function()
local items = { { weight = 100, value = 1 } }
local maximum_weight = 10

assert.are.equal(0, knapsack.maximum_value(maximum_weight, items))
end)

it('five items cannot be greedy by weight', function()
it('five items (cannot be greedy by weight)', function()
local items = {
{ weight = 2, value = 5 },
{ weight = 2, value = 5 },
Expand All @@ -27,7 +28,7 @@ describe('knapsack', function()
assert.are.equal(21, knapsack.maximum_value(maximum_weight, items))
end)

it('five items cannot be greedy by value', function()
it('five items (cannot be greedy by value)', function()
local items = {
{ weight = 2, value = 20 },
{ weight = 2, value = 20 },
Expand All @@ -52,9 +53,8 @@ describe('knapsack', function()
assert.are.equal(90, knapsack.maximum_value(maximum_weight, items))
end)

it('eight items', function()
it('8 items', function()
local items = {
{ weight = 5, value = 10 },
{ weight = 25, value = 350 },
{ weight = 35, value = 400 },
{ weight = 45, value = 450 },
Expand All @@ -69,7 +69,7 @@ describe('knapsack', function()
assert.are.equal(900, knapsack.maximum_value(maximum_weight, items))
end)

it('fifteen items', function()
it('15 items', function()
local items = {
{ weight = 70, value = 135 },
{ weight = 73, value = 139 },
Expand Down
11 changes: 11 additions & 0 deletions exercises/practice/matching-brackets/.meta/spec_generator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
local utils = require 'utils'

return {
module_name = 'brackets',

generate_test = function(case)
local template = [[
assert.is_%s(brackets.valid(%s))]]
return template:format(case.expected, utils.stringify(case.input.value))
end
}
43 changes: 21 additions & 22 deletions exercises/practice/matching-brackets/matching-brackets_spec.lua
Original file line number Diff line number Diff line change
@@ -1,85 +1,84 @@
-- canonical test data 2.0.0
local brackets = require('matching-brackets')

describe('matching-brackets', function()
it('should accept paired square brackets', function()
it('paired square brackets', function()
assert.is_true(brackets.valid('[]'))
end)

it('should accept empty string', function()
it('empty string', function()
assert.is_true(brackets.valid(''))
end)

it('should reject unpaired brackets', function()
it('unpaired brackets', function()
assert.is_false(brackets.valid('[['))
end)

it('should reject wrong ordered brackets', function()
it('wrong ordered brackets', function()
assert.is_false(brackets.valid('}{'))
end)

it('should reject wrong closing bracket', function()
it('wrong closing bracket', function()
assert.is_false(brackets.valid('{]'))
end)

it('should accept paired with whitespace', function()
it('paired with whitespace', function()
assert.is_true(brackets.valid('{ }'))
end)

it('should reject partially paired brackets', function()
it('partially paired brackets', function()
assert.is_false(brackets.valid('{[])'))
end)

it('should accept simple nested brackets', function()
it('simple nested brackets', function()
assert.is_true(brackets.valid('{[]}'))
end)

it('should accept several paired brackets', function()
it('several paired brackets', function()
assert.is_true(brackets.valid('{}[]'))
end)

it('should accept paired and nested brackets', function()
it('paired and nested brackets', function()
assert.is_true(brackets.valid('([{}({}[])])'))
end)

it('should reject unopened closing brackets', function()
it('unopened closing brackets', function()
assert.is_false(brackets.valid('{[)][]}'))
end)

it('should reject unpaired and nested brackets', function()
it('unpaired and nested brackets', function()
assert.is_false(brackets.valid('([{])'))
end)

it('should reject paired and wrong nested brackets', function()
it('paired and wrong nested brackets', function()
assert.is_false(brackets.valid('[({]})'))
end)

it('should reject paired and wrong nested brackets but innermost are correct', function()
it('paired and wrong nested brackets but innermost are correct', function()
assert.is_false(brackets.valid('[({}])'))
end)

it('should reject paired and incomplete brackets', function()
it('paired and incomplete brackets', function()
assert.is_false(brackets.valid('{}['))
end)

it('should reject too many closing brackets', function()
it('too many closing brackets', function()
assert.is_false(brackets.valid('[]]'))
end)

it('should reject early unexpected brackets', function()
it('early unexpected brackets', function()
assert.is_false(brackets.valid(')()'))
end)

it('should reject early mismatched brackets', function()
it('early mismatched brackets', function()
assert.is_false(brackets.valid('{)()'))
end)

it('should accept math expression', function()
it('math expression', function()
assert.is_true(brackets.valid('(((185 + 223.85) * 15) - 543)/2'))
end)

it('should accept complex latex expression', function()
it('complex latex expression', function()
assert.is_true(brackets.valid(
[[\left(\begin{array}{cc} \frac{1}{3} & x\\ \mathrm{e}^{x} &... x^2 \end{array}\right)]]))
'\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)'))
end)
end)
26 changes: 26 additions & 0 deletions exercises/practice/pythagorean-triplet/.meta/spec_generator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
local utils = require 'utils'

local function render_triplets(triplets)
return '{ ' .. table.concat(utils.map(triplets, function(triplet)
return '{ ' .. table.concat(triplet, ', ') .. ' }'
end), ', ') .. ' }'
end

return {
module_name = 'triplets_with_sum',

test_helpers = [[
local function sort(triplets)
table.sort(triplets, function(a, b)
return a[1] < b[1]
end)
return triplets
end
]],

generate_test = function(case)
local template = [[
assert.same(%s, sort(triplets_with_sum(%d)))]]
return template:format(render_triplets(case.expected), case.input.n)
end
}
72 changes: 35 additions & 37 deletions exercises/practice/pythagorean-triplet/pythagorean-triplet_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,46 @@ describe('pythagorean-triplet', function()
return triplets
end

describe('triplets_with_sum', function()
it('finds triplets whose sum is 12', function()
assert.same({ { 3, 4, 5 } }, sort(triplets_with_sum(12)))
end)
it('triplets whose sum is 12', function()
assert.same({ { 3, 4, 5 } }, sort(triplets_with_sum(12)))
end)

it('finds triplets whose sum is 108', function()
assert.same({ { 27, 36, 45 } }, sort(triplets_with_sum(108)))
end)
it('triplets whose sum is 108', function()
assert.same({ { 27, 36, 45 } }, sort(triplets_with_sum(108)))
end)

it('finds triplets whose sum is 1000', function()
assert.same({ { 200, 375, 425 } }, sort(triplets_with_sum(1000)))
end)
it('triplets whose sum is 1000', function()
assert.same({ { 200, 375, 425 } }, sort(triplets_with_sum(1000)))
end)

it('finds no triplets whose sum is 1001', function()
assert.same({}, triplets_with_sum(1001))
end)
it('no matching triplets for 1001', function()
assert.same({}, sort(triplets_with_sum(1001)))
end)

it('finds triplets whose sum is 90', function()
assert.same({ { 9, 40, 41 }, { 15, 36, 39 } }, sort(triplets_with_sum(90)))
end)
it('returns all matching triplets', function()
assert.same({ { 9, 40, 41 }, { 15, 36, 39 } }, sort(triplets_with_sum(90)))
end)

it('finds triplets whose sum is 840', function()
assert.same({
{ 40, 399, 401 },
{ 56, 390, 394 },
{ 105, 360, 375 },
{ 120, 350, 370 },
{ 140, 336, 364 },
{ 168, 315, 357 },
{ 210, 280, 350 },
{ 240, 252, 348 }
}, sort(triplets_with_sum(840)))
end)
it('several matching triplets', function()
assert.same({
{ 40, 399, 401 },
{ 56, 390, 394 },
{ 105, 360, 375 },
{ 120, 350, 370 },
{ 140, 336, 364 },
{ 168, 315, 357 },
{ 210, 280, 350 },
{ 240, 252, 348 }
}, sort(triplets_with_sum(840)))
end)

it('finds triplets whose sum is a large number (30000)', function()
assert.same({
{ 1200, 14375, 14425 },
{ 1875, 14000, 14125 },
{ 5000, 12000, 13000 },
{ 6000, 11250, 12750 },
{ 7500, 10000, 12500 }
}, sort(triplets_with_sum(30000)))
end)
it('triplets for large number', function()
assert.same({
{ 1200, 14375, 14425 },
{ 1875, 14000, 14125 },
{ 5000, 12000, 13000 },
{ 6000, 11250, 12750 },
{ 7500, 10000, 12500 }
}, sort(triplets_with_sum(30000)))
end)
end)
24 changes: 24 additions & 0 deletions exercises/practice/queen-attack/.meta/spec_generator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
local function render_queen(queen)
return ('Queen({ row = %d, column = %d })'):format(queen.position.row, queen.position.column)
end

return {
module_name = 'Queen',

generate_test = function(case)
if case.property == 'create' then
local template = [[
assert.%s(function()
%s
end)]]
local assertion = type(case.expected) == 'table' and 'has_error' or 'has_no_error'
return template:format(assertion, render_queen(case.input.queen))
else
local template = [[
local q1 = %s
local q2 = %s
assert.is_%s(q1.can_attack(q2))]]
return template:format(render_queen(case.input.white_queen), render_queen(case.input.black_queen), case.expected)
end
end
}
Loading
Loading