diff --git a/bin/generate-spec b/bin/generate-spec index ad8f13c9..7abaa666 100755 --- a/bin/generate-spec +++ b/bin/generate-spec @@ -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') if s:match("'") and not s:match('"') then return '"' .. s .. '"' else diff --git a/exercises/practice/crypto-square/.meta/spec_generator.lua b/exercises/practice/crypto-square/.meta/spec_generator.lua new file mode 100644 index 00000000..03255c5d --- /dev/null +++ b/exercises/practice/crypto-square/.meta/spec_generator.lua @@ -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 +} diff --git a/exercises/practice/crypto-square/crypto-square_spec.lua b/exercises/practice/crypto-square/crypto-square_spec.lua index 38486198..a3d8f348 100644 --- a/exercises/practice/crypto-square/crypto-square_spec.lua +++ b/exercises/practice/crypto-square/crypto-square_spec.lua @@ -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) diff --git a/exercises/practice/knapsack/.meta/spec_generator.lua b/exercises/practice/knapsack/.meta/spec_generator.lua new file mode 100644 index 00000000..c459e001 --- /dev/null +++ b/exercises/practice/knapsack/.meta/spec_generator.lua @@ -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 +} diff --git a/exercises/practice/knapsack/knapsack_spec.lua b/exercises/practice/knapsack/knapsack_spec.lua index f75b22ab..ec711df3 100644 --- a/exercises/practice/knapsack/knapsack_spec.lua +++ b/exercises/practice/knapsack/knapsack_spec.lua @@ -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 }, @@ -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 }, @@ -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 }, @@ -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 }, diff --git a/exercises/practice/matching-brackets/.meta/spec_generator.lua b/exercises/practice/matching-brackets/.meta/spec_generator.lua new file mode 100644 index 00000000..defa56bc --- /dev/null +++ b/exercises/practice/matching-brackets/.meta/spec_generator.lua @@ -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 +} diff --git a/exercises/practice/matching-brackets/matching-brackets_spec.lua b/exercises/practice/matching-brackets/matching-brackets_spec.lua index 5c0ea93b..c32740e8 100644 --- a/exercises/practice/matching-brackets/matching-brackets_spec.lua +++ b/exercises/practice/matching-brackets/matching-brackets_spec.lua @@ -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) diff --git a/exercises/practice/pythagorean-triplet/.meta/spec_generator.lua b/exercises/practice/pythagorean-triplet/.meta/spec_generator.lua new file mode 100644 index 00000000..08db2058 --- /dev/null +++ b/exercises/practice/pythagorean-triplet/.meta/spec_generator.lua @@ -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 +} diff --git a/exercises/practice/pythagorean-triplet/pythagorean-triplet_spec.lua b/exercises/practice/pythagorean-triplet/pythagorean-triplet_spec.lua index 761de728..9edbe3ee 100644 --- a/exercises/practice/pythagorean-triplet/pythagorean-triplet_spec.lua +++ b/exercises/practice/pythagorean-triplet/pythagorean-triplet_spec.lua @@ -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) diff --git a/exercises/practice/queen-attack/.meta/spec_generator.lua b/exercises/practice/queen-attack/.meta/spec_generator.lua new file mode 100644 index 00000000..895be2ee --- /dev/null +++ b/exercises/practice/queen-attack/.meta/spec_generator.lua @@ -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 +} diff --git a/exercises/practice/queen-attack/queen-attack_spec.lua b/exercises/practice/queen-attack/queen-attack_spec.lua index cf13beeb..5d156b00 100644 --- a/exercises/practice/queen-attack/queen-attack_spec.lua +++ b/exercises/practice/queen-attack/queen-attack_spec.lua @@ -1,82 +1,86 @@ local Queen = require('queen-attack') describe('queen-attack', function() - it('queen with a valid position', function() - assert.has_no_error(function() - Queen({ row = 2, column = 2 }) + describe('test creation of queens with valid and invalid positions', function() + it('queen with a valid position', function() + assert.has_no_error(function() + Queen({ row = 2, column = 2 }) + end) end) - end) - it('queen must have a positive row', function() - assert.has_error(function() - Queen({ row = -2, column = 2 }) + it('queen must have positive row', function() + assert.has_error(function() + Queen({ row = -2, column = 2 }) + end) end) - end) - it('queen must have row on board', function() - assert.has_error(function() - Queen({ row = 8, column = 4 }) + it('queen must have row on board', function() + assert.has_error(function() + Queen({ row = 8, column = 4 }) + end) end) - end) - it('queen must have positive column', function() - assert.has_error(function() - Queen({ row = 2, column = -2 }) + it('queen must have positive column', function() + assert.has_error(function() + Queen({ row = 2, column = -2 }) + end) end) - end) - it('queen must have column on board', function() - assert.has_error(function() - Queen({ row = 4, column = 8 }) + it('queen must have column on board', function() + assert.has_error(function() + Queen({ row = 4, column = 8 }) + end) end) end) - it('can not attack', function() - local q1 = Queen({ row = 2, column = 4 }) - local q2 = Queen({ row = 6, column = 6 }) - assert.is_false(q1.can_attack(q2)) - end) + describe('test the ability of one queen to attack another', function() + it('cannot attack', function() + local q1 = Queen({ row = 2, column = 4 }) + local q2 = Queen({ row = 6, column = 6 }) + assert.is_false(q1.can_attack(q2)) + end) - it('can attack on same row', function() - local q1 = Queen({ row = 2, column = 4 }) - local q2 = Queen({ row = 2, column = 6 }) - assert.is_true(q1.can_attack(q2)) - end) + it('can attack on same row', function() + local q1 = Queen({ row = 2, column = 4 }) + local q2 = Queen({ row = 2, column = 6 }) + assert.is_true(q1.can_attack(q2)) + end) - it('can attack on same column', function() - local q1 = Queen({ row = 4, column = 5 }) - local q2 = Queen({ row = 2, column = 5 }) - assert.is_true(q1.can_attack(q2)) - end) + it('can attack on same column', function() + local q1 = Queen({ row = 4, column = 5 }) + local q2 = Queen({ row = 2, column = 5 }) + assert.is_true(q1.can_attack(q2)) + end) - it('can attack on first diagonal', function() - local q1 = Queen({ row = 2, column = 2 }) - local q2 = Queen({ row = 0, column = 4 }) - assert.is_true(q1.can_attack(q2)) - end) + it('can attack on first diagonal', function() + local q1 = Queen({ row = 2, column = 2 }) + local q2 = Queen({ row = 0, column = 4 }) + assert.is_true(q1.can_attack(q2)) + end) - it('can attack on second diagonal', function() - local q1 = Queen({ row = 2, column = 2 }) - local q2 = Queen({ row = 3, column = 1 }) - assert.is_true(q1.can_attack(q2)) - end) + it('can attack on second diagonal', function() + local q1 = Queen({ row = 2, column = 2 }) + local q2 = Queen({ row = 3, column = 1 }) + assert.is_true(q1.can_attack(q2)) + end) - it('can attack on third diagonal', function() - local q1 = Queen({ row = 2, column = 2 }) - local q2 = Queen({ row = 1, column = 1 }) - assert.is_true(q1.can_attack(q2)) - end) + it('can attack on third diagonal', function() + local q1 = Queen({ row = 2, column = 2 }) + local q2 = Queen({ row = 1, column = 1 }) + assert.is_true(q1.can_attack(q2)) + end) - it('can attack on fourth diagonal', function() - local q1 = Queen({ row = 1, column = 7 }) - local q2 = Queen({ row = 0, column = 6 }) - assert.is_true(q1.can_attack(q2)) - end) + it('can attack on fourth diagonal', function() + local q1 = Queen({ row = 1, column = 7 }) + local q2 = Queen({ row = 0, column = 6 }) + assert.is_true(q1.can_attack(q2)) + end) - it('cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal', - function() - local q1 = Queen({ row = 4, column = 1 }) - local q2 = Queen({ row = 2, column = 5 }) - assert.is_false(q1.can_attack(q2)) + it('cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal', + function() + local q1 = Queen({ row = 4, column = 1 }) + local q2 = Queen({ row = 2, column = 5 }) + assert.is_false(q1.can_attack(q2)) + end) end) end) diff --git a/exercises/practice/run-length-encoding/.meta/spec_generator.lua b/exercises/practice/run-length-encoding/.meta/spec_generator.lua new file mode 100644 index 00000000..f375735a --- /dev/null +++ b/exercises/practice/run-length-encoding/.meta/spec_generator.lua @@ -0,0 +1,17 @@ +local utils = require 'utils' + +return { + module_name = 'rle', + + generate_test = function(case) + if case.property == 'consistency' then + local template = [[ + assert.equal(%s, rle.decode(rle.encode(%s)))]] + return template:format(utils.stringify(case.expected), utils.stringify(case.input.string)) + else + local template = [[ + assert.equal(%s, rle.%s(%s))]] + return template:format(utils.stringify(case.expected), case.property, utils.stringify(case.input.string)) + end + end +} diff --git a/exercises/practice/run-length-encoding/run-length-encoding_spec.lua b/exercises/practice/run-length-encoding/run-length-encoding_spec.lua index 6b2d1dcc..f6a83bf9 100644 --- a/exercises/practice/run-length-encoding/run-length-encoding_spec.lua +++ b/exercises/practice/run-length-encoding/run-length-encoding_spec.lua @@ -1,31 +1,61 @@ local rle = require('run-length-encoding') describe('run-length-encoding', function() - it('should encode simple strings', function() - assert.equal('2A3B4C', rle.encode('AABBBCCCC')) - end) + describe('run-length encode a string', function() + it('empty string', function() + assert.equal('', rle.encode('')) + end) - it('should encode strings with multi-digit run lengths', function() - assert.equal('2A10B4C', rle.encode('AABBBBBBBBBBCCCC')) - end) + it('single characters only are encoded without count', function() + assert.equal('XYZ', rle.encode('XYZ')) + end) - it('should decode simple strings', function() - assert.equal('AABBBCCCC', rle.decode('2A3B4C')) - end) + it('string with no single characters', function() + assert.equal('2A3B4C', rle.encode('AABBBCCCC')) + end) - it('should decode strings with multi-digit run lengths', function() - assert.equal('AABBBBBBBBBBCCCC', rle.decode('2A10B4C')) - end) + it('single characters mixed with repeated characters', function() + assert.equal('12WB12W3B24WB', rle.encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB')) + end) + + it('multiple whitespace mixed in string', function() + assert.equal('2 hs2q q2w2 ', rle.encode(' hsqq qww ')) + end) - it('should not encode characters with a run length of 1', function() - assert.equal('2AB4CD', rle.encode('AABCCCCD')) + it('lowercase characters', function() + assert.equal('2a3b4c', rle.encode('aabbbcccc')) + end) end) - it('should successfully decode characters with a run length of 1', function() - assert.equal('AABCCCCD', rle.decode('2AB4CD')) + describe('run-length decode a string', function() + it('empty string', function() + assert.equal('', rle.decode('')) + end) + + it('single characters only', function() + assert.equal('XYZ', rle.decode('XYZ')) + end) + + it('string with no single characters', function() + assert.equal('AABBBCCCC', rle.decode('2A3B4C')) + end) + + it('single characters with repeated characters', function() + assert.equal('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB', rle.decode('12WB12W3B24WB')) + end) + + it('multiple whitespace mixed in string', function() + assert.equal(' hsqq qww ', rle.decode('2 hs2q q2w2 ')) + end) + + it('lowercase string', function() + assert.equal('aabbbcccc', rle.decode('2a3b4c')) + end) end) - it('should decode an encoded string back to the original string', function() - assert.equal('zzz ZZ zZ', rle.decode(rle.encode('zzz ZZ zZ'))) + describe('encode and then decode', function() + it('encode followed by decode gives original string', function() + assert.equal('zzz ZZ zZ', rle.decode(rle.encode('zzz ZZ zZ'))) + end) end) end) diff --git a/exercises/practice/secret-handshake/.meta/spec_generator.lua b/exercises/practice/secret-handshake/.meta/spec_generator.lua new file mode 100644 index 00000000..166b9126 --- /dev/null +++ b/exercises/practice/secret-handshake/.meta/spec_generator.lua @@ -0,0 +1,11 @@ +local utils = require 'utils' + +return { + module_name = 'secret_handshake', + + generate_test = function(case) + local template = [[ + assert.are.same({ %s }, secret_handshake(%d))]] + return template:format(table.concat(utils.map(case.expected, utils.stringify), ', '), case.input.number) + end +} diff --git a/exercises/practice/secret-handshake/secret-handshake_spec.lua b/exercises/practice/secret-handshake/secret-handshake_spec.lua index 3831b37e..84445d23 100644 --- a/exercises/practice/secret-handshake/secret-handshake_spec.lua +++ b/exercises/practice/secret-handshake/secret-handshake_spec.lua @@ -1,35 +1,47 @@ -local secret_handshake = require 'secret-handshake' +local secret_handshake = require('secret-handshake') describe('secret-handshake', function() - it('should allow empty handshakes', function() - assert.are.same({}, secret_handshake(0)) + it('wink for 1', function() + assert.are.same({ 'wink' }, secret_handshake(1)) + end) + + it('double blink for 10', function() + assert.are.same({ 'double blink' }, secret_handshake(2)) + end) + + it('close your eyes for 100', function() + assert.are.same({ 'close your eyes' }, secret_handshake(4)) + end) + + it('jump for 1000', function() + assert.are.same({ 'jump' }, secret_handshake(8)) end) - it('should interpret 0b1 as wink', function() - assert.are.same({ 'wink' }, secret_handshake(tonumber('1', 2))) + it('combine two actions', function() + assert.are.same({ 'wink', 'double blink' }, secret_handshake(3)) end) - it('should interpret 0b10 as double blink', function() - assert.are.same({ 'double blink' }, secret_handshake(tonumber('10', 2))) + it('reverse two actions', function() + assert.are.same({ 'double blink', 'wink' }, secret_handshake(19)) end) - it('should interpret 0b100 as close your eyes', function() - assert.are.same({ 'close your eyes' }, secret_handshake(tonumber('100', 2))) + it('reversing one action gives the same action', function() + assert.are.same({ 'jump' }, secret_handshake(24)) end) - it('should interpret 0b1000 as jump', function() - assert.are.same({ 'jump' }, secret_handshake(tonumber('1000', 2))) + it('reversing no actions still gives no actions', function() + assert.are.same({}, secret_handshake(16)) end) - it('should allow multiple handshake primitives to be used together', function() - assert.are.same({ 'wink', 'double blink' }, secret_handshake(tonumber('11', 2))) + it('all possible actions', function() + assert.are.same({ 'wink', 'double blink', 'close your eyes', 'jump' }, secret_handshake(15)) end) - it('should reverse the order of the primitives when 0b10000 is used', function() - assert.are.same({ 'double blink', 'wink' }, secret_handshake(tonumber('10011', 2))) + it('reverse all possible actions', function() + assert.are.same({ 'jump', 'close your eyes', 'double blink', 'wink' }, secret_handshake(31)) end) - it('should allow all primitives to be used together', function() - assert.are.same({ 'jump', 'close your eyes', 'double blink', 'wink' }, secret_handshake(tonumber('11111', 2))) + it('do nothing for zero', function() + assert.are.same({}, secret_handshake(0)) end) end) diff --git a/exercises/practice/yacht/.meta/spec_generator.lua b/exercises/practice/yacht/.meta/spec_generator.lua new file mode 100644 index 00000000..cf2c0d0d --- /dev/null +++ b/exercises/practice/yacht/.meta/spec_generator.lua @@ -0,0 +1,11 @@ +local utils = require 'utils' + +return { + module_name = 'yacht', + + generate_test = function(case) + local template = [[ + assert.are.equal(%d, yacht.score({ %s }, %s))]] + return template:format(case.expected, table.concat(case.input.dice, ', '), utils.stringify(case.input.category)) + end +}