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
11 changes: 9 additions & 2 deletions bin/generate-spec
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ included_tests_from_toml = (path) ->

included


export indent, quote -- mark as global so spec_generators can see them
-- ----------------------------------------------------------
-- functions marked as global so spec_generators can see them
export indent, quote, is_json_null

indent = (text, level) -> string.rep(' ', level) .. text

Expand All @@ -57,6 +58,11 @@ quote = (str) ->
else
"'#{str}'"

-- the dkjson `json.null` value is an empty table
is_json_null = (value) -> type(value) == 'table' and #value == 0

-- ----------------------------------------------------------


test_cmd = 'it'

Expand Down Expand Up @@ -104,6 +110,7 @@ canonical_data_path = "canonical-data/#{exercise_name}.json"
assert os.execute('mkdir -p "$(dirname "' .. canonical_data_path .. '")"')
assert os.execute('curl "' .. canonical_data_url .. '" -s -o "' .. canonical_data_path .. '"')

-- "json.null" ref: https://dkolf.de/dkjson-lua/documentation
canonical_data = json.decode read_file(canonical_data_path), 1, json.null

tests_toml_path = exercise_directory .. '/.meta/tests.toml'
Expand Down
8 changes: 7 additions & 1 deletion bin/verify-exercises
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,24 @@ verify_exercise() {

verify_exercises() {
local exercise_slug
local start=$SECONDS
local errs=0

exercise_slug="${1}"

shopt -s nullglob
count=0
for exercise_dir in ./exercises/{concept,practice}/${exercise_slug}/; do
if [[ -d "${exercise_dir}" ]]; then
verify_exercise "${exercise_dir}"
verify_exercise "${exercise_dir}" || ((++errs))
((++count))
fi
done
((count > 0)) || die 'no matching exercises found!'

echo
echo "$count exercises tested in $((SECONDS - start)) seconds with $errs failures"
return $errs
}

required_tool jq
Expand Down
3 changes: 3 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ description = "Seven-digit number that is not an Armstrong number"

[5ee2fdf8-334e-4a46-bb8d-e5c19c02c148]
description = "Armstrong number containing seven zeroes"
include=false
comment="Lua cannot handle large numbers precisely"

[12ffbf10-307a-434e-b4ad-c925680e1dd4]
description = "The largest and last Armstrong number"
include=false
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DifferenceOfSquares = require 'difference_of_squares'

describe 'difference-of-squares', ->
describe 'square the sum of the numbers up to the given number', ->
describe 'Square the sum of the numbers up to the given number', ->
it 'square of sum 1', ->
result = DifferenceOfSquares.square_of_sum 1
assert.are.equal 1, result
Expand All @@ -14,7 +14,7 @@ describe 'difference-of-squares', ->
result = DifferenceOfSquares.square_of_sum 100
assert.are.equal 25502500, result

describe 'sum the squares of the numbers up to the given number', ->
describe 'Sum the squares of the numbers up to the given number', ->
pending 'sum of squares 1', ->
result = DifferenceOfSquares.sum_of_squares 1
assert.are.equal 1, result
Expand All @@ -27,7 +27,7 @@ describe 'difference-of-squares', ->
result = DifferenceOfSquares.sum_of_squares 100
assert.are.equal 338350, result

describe 'subtract sum of squares from square of sums', ->
describe 'Subtract sum of squares from square of sums', ->
pending 'difference of squares 1', ->
result = DifferenceOfSquares.difference_of_squares 1
assert.are.equal 0, result
Expand Down
12 changes: 8 additions & 4 deletions exercises/practice/etl/.meta/spec_generator.moon
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ string_list = (list) -> "{#{table.concat [quote(v) for v in *list], ', '}}"
lines = {}

table.insert lines, "legacy = {"
for k, v in pairs case.input.legacy
table.insert lines, " #{quote k}: #{string_list v}"
keys = [k for k, _ in pairs case.input.legacy]
table.sort keys
for k in *keys
table.insert lines, " #{quote k}: #{string_list case.input.legacy[k]}"
table.insert lines, "}"

table.insert lines, "expected = {"
for k, v in pairs case.expected
table.insert lines, " #{quote k}: #{v}"
keys = [k for k, _ in pairs case.expected]
table.sort keys
for k in *keys
table.insert lines, " #{quote k}: #{case.expected[k]}"
table.insert lines, "}"

table.insert lines, "result = Etl.#{case.property} legacy"
Expand Down
38 changes: 19 additions & 19 deletions exercises/practice/etl/etl_spec.moon
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ describe 'etl', ->
expected = {
'a': 1
'e': 1
'u': 1
'o': 1
'i': 1
'o': 1
'u': 1
}
result = Etl.transform legacy
assert.are.same expected, result
Expand All @@ -33,48 +33,48 @@ describe 'etl', ->
expected = {
'a': 1
'd': 2
'g': 2
'e': 1
'g': 2
}
result = Etl.transform legacy
assert.are.same expected, result

pending 'multiple scores with differing numbers of letters', ->
legacy = {
'1': {'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'}
'8': {'J', 'X'}
'3': {'B', 'C', 'M', 'P'}
'10': {'Q', 'Z'}
'2': {'D', 'G'}
'5': {'K'}
'3': {'B', 'C', 'M', 'P'}
'4': {'F', 'H', 'V', 'W', 'Y'}
'10': {'Q', 'Z'}
'5': {'K'}
'8': {'J', 'X'}
}
expected = {
'a': 1
'c': 3
'b': 3
'e': 1
'c': 3
'd': 2
'g': 2
'e': 1
'f': 4
'i': 1
'g': 2
'h': 4
'k': 5
'i': 1
'j': 8
'm': 3
'k': 5
'l': 1
'o': 1
'm': 3
'n': 1
'q': 10
'o': 1
'p': 3
's': 1
'q': 10
'r': 1
'u': 1
's': 1
't': 1
'w': 4
'u': 1
'v': 4
'y': 4
'w': 4
'x': 8
'y': 4
'z': 10
}
result = Etl.transform legacy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ int_list = (list) -> "{#{table.concat list, ', '}}"
int_lists = (lists) ->
"{#{table.concat [int_list list for list in *lists], ', '}}"

value = (val) ->
if is_json_null val
nil
else
val

{
module_name: 'PalindromeProducts',
Expand All @@ -17,7 +22,7 @@ int_lists = (lists) ->
else
lines = {
"palindrome, factors = PalindromeProducts.#{case.property} #{case.input.min}, #{case.input.max}",
"expected_palindrome = #{case.expected.value}",
"expected_palindrome = #{value case.expected.value}",
"expected_factors = #{int_lists case.expected.factors}",
"assert.are.equal expected_palindrome, palindrome",
"assert.are.same expected_factors, factors",
Expand Down
88 changes: 44 additions & 44 deletions exercises/practice/prism/prism_spec.moon
Original file line number Diff line number Diff line change
Expand Up @@ -128,38 +128,38 @@ describe 'prism', ->
{id: 24, x: 36.2, y: 65.2, angle: -0.304}
{id: 20, x: 20.4, y: 82.8, angle: 45.17}
{id: 31, x: -20.2, y: 48.8, angle: 30.615}
{id: 30, x: 24, y: 0.6, angle: 28.771}
{id: 30, x: 24.0, y: 0.6, angle: 28.771}
{id: 29, x: 31.4, y: 79.4, angle: 61.327}
{id: 28, x: 36.4, y: 31.4, angle: -18.157}
{id: 22, x: 47, y: 57.8, angle: 54.745}
{id: 22, x: 47.0, y: 57.8, angle: 54.745}
{id: 38, x: 36.4, y: 79.2, angle: 49.05}
{id: 10, x: 37.8, y: 55.2, angle: 11.978}
{id: 18, x: -26, y: 42.6, angle: 22.661}
{id: 18, x: -26.0, y: 42.6, angle: 22.661}
{id: 25, x: 38.8, y: 76.2, angle: 51.958}
{id: 2, x: 0, y: 42.4, angle: -21.817}
{id: 2, x: 0.0, y: 42.4, angle: -21.817}
{id: 35, x: 21.4, y: 44.8, angle: -171.579}
{id: 7, x: 14.2, y: -1.6, angle: 19.081}
{id: 33, x: 11.2, y: 44.4, angle: -165.941}
{id: 11, x: 15.4, y: 82.6, angle: 66.262}
{id: 16, x: 30.8, y: 6.6, angle: 35.852}
{id: 15, x: -3, y: 79.2, angle: 53.782}
{id: 4, x: 29, y: 75.4, angle: 17.016}
{id: 15, x: -3.0, y: 79.2, angle: 53.782}
{id: 4, x: 29.0, y: 75.4, angle: 17.016}
{id: 23, x: 41.6, y: 59.8, angle: 70.763}
{id: 8, x: -10, y: 15.8, angle: -9.24}
{id: 8, x: -10.0, y: 15.8, angle: -9.24}
{id: 13, x: 48.6, y: 51.8, angle: 45.812}
{id: 1, x: 13.2, y: 77, angle: 17.937}
{id: 1, x: 13.2, y: 77.0, angle: 17.937}
{id: 34, x: -8.8, y: 36.8, angle: -4.199}
{id: 21, x: 24.4, y: 75.8, angle: 20.783}
{id: 17, x: -4.4, y: 74.6, angle: 24.709}
{id: 9, x: 30.8, y: 41.8, angle: -165.413}
{id: 32, x: 4.2, y: 78.6, angle: 40.892}
{id: 37, x: -15.8, y: 47, angle: 33.29}
{id: 6, x: 1, y: 80.6, angle: 51.295}
{id: 36, x: -27, y: 47.8, angle: 92.52}
{id: 14, x: -2, y: 34.4, angle: -52.001}
{id: 37, x: -15.8, y: 47.0, angle: 33.29}
{id: 6, x: 1.0, y: 80.6, angle: 51.295}
{id: 36, x: -27.0, y: 47.8, angle: 92.52}
{id: 14, x: -2.0, y: 34.4, angle: -52.001}
{id: 5, x: 23.2, y: 80.2, angle: 31.866}
{id: 27, x: -5.6, y: 32.8, angle: -75.303}
{id: 12, x: -1, y: 0.2, angle: 0}
{id: 12, x: -1.0, y: 0.2, angle: 0.0}
{id: 3, x: -6.6, y: 3.2, angle: 46.72}
{id: 19, x: -13.8, y: 24.2, angle: -9.205}
}
Expand All @@ -168,79 +168,79 @@ describe 'prism', ->
assert.are.same expected, result

pending 'complex path with multiple prisms floating point precision', ->
start = {x: 0, y: 0, angle: 0}
start = {x: 0, y: 0, angle: 0.0}
prisms = {
{id: 46, x: 37.4, y: 20.6, angle: -88.332}
{id: 72, x: -24.2, y: 23.4, angle: -90.774}
{id: 25, x: 78.6, y: 7.8, angle: 98.562}
{id: 60, x: -58.8, y: 31.6, angle: 115.56}
{id: 22, x: 75.2, y: 28, angle: 63.515}
{id: 22, x: 75.2, y: 28.0, angle: 63.515}
{id: 2, x: 89.8, y: 27.8, angle: 91.176}
{id: 23, x: 9.8, y: 30.8, angle: 30.829}
{id: 69, x: 22.8, y: 20.6, angle: -88.315}
{id: 44, x: -0.8, y: 15.6, angle: -116.565}
{id: 36, x: -24.2, y: 8.2, angle: -90}
{id: 53, x: -1.2, y: 0, angle: 0}
{id: 52, x: 14.2, y: 24, angle: -143.896}
{id: 36, x: -24.2, y: 8.2, angle: -90.0}
{id: 53, x: -1.2, y: 0.0, angle: 0.0}
{id: 52, x: 14.2, y: 24.0, angle: -143.896}
{id: 5, x: -65.2, y: 21.6, angle: 93.128}
{id: 66, x: 5.4, y: 15.6, angle: 31.608}
{id: 51, x: -72.6, y: 21, angle: -100.976}
{id: 65, x: 48, y: 10.2, angle: 87.455}
{id: 21, x: -41.8, y: 0, angle: 68.352}
{id: 51, x: -72.6, y: 21.0, angle: -100.976}
{id: 65, x: 48.0, y: 10.2, angle: 87.455}
{id: 21, x: -41.8, y: 0.0, angle: 68.352}
{id: 18, x: -46.2, y: 19.2, angle: -128.362}
{id: 10, x: 74.4, y: 0.4, angle: 90.939}
{id: 15, x: 67.6, y: 0.4, angle: 84.958}
{id: 35, x: 14.8, y: -0.4, angle: 89.176}
{id: 1, x: 83, y: 0.2, angle: 89.105}
{id: 68, x: 14.6, y: 28, angle: -29.867}
{id: 1, x: 83.0, y: 0.2, angle: 89.105}
{id: 68, x: 14.6, y: 28.0, angle: -29.867}
{id: 67, x: 79.8, y: 18.6, angle: -136.643}
{id: 38, x: 53, y: 14.6, angle: -90.848}
{id: 31, x: -58, y: 6.6, angle: -61.837}
{id: 38, x: 53.0, y: 14.6, angle: -90.848}
{id: 31, x: -58.0, y: 6.6, angle: -61.837}
{id: 74, x: -30.8, y: 0.4, angle: 85.966}
{id: 48, x: -4.6, y: 10, angle: -161.222}
{id: 12, x: 59, y: 5, angle: -91.164}
{id: 48, x: -4.6, y: 10.0, angle: -161.222}
{id: 12, x: 59.0, y: 5.0, angle: -91.164}
{id: 33, x: -16.4, y: 18.4, angle: 90.734}
{id: 4, x: 82.6, y: 27.6, angle: 71.127}
{id: 75, x: -10.2, y: 30.6, angle: -1.108}
{id: 28, x: 38, y: 0, angle: 86.863}
{id: 28, x: 38.0, y: 0.0, angle: 86.863}
{id: 11, x: 64.4, y: -0.2, angle: 92.353}
{id: 9, x: -51.4, y: 31.6, angle: 67.249}
{id: 26, x: -39.8, y: 30.8, angle: 61.113}
{id: 30, x: -34.2, y: 0.6, angle: 111.33}
{id: 56, x: -51, y: 0.2, angle: 70.445}
{id: 41, x: -12, y: 0, angle: 91.219}
{id: 56, x: -51.0, y: 0.2, angle: 70.445}
{id: 41, x: -12.0, y: 0.0, angle: 91.219}
{id: 24, x: 63.8, y: 14.4, angle: 86.586}
{id: 70, x: -72.8, y: 13.4, angle: -87.238}
{id: 3, x: 22.4, y: 7, angle: -91.685}
{id: 13, x: 34.4, y: 7, angle: 90}
{id: 3, x: 22.4, y: 7.0, angle: -91.685}
{id: 13, x: 34.4, y: 7.0, angle: 90.0}
{id: 16, x: -47.4, y: 11.4, angle: -136.02}
{id: 6, x: 90, y: 0.2, angle: 90.415}
{id: 54, x: 44, y: 27.8, angle: 85.969}
{id: 32, x: -9, y: 0, angle: 91.615}
{id: 6, x: 90.0, y: 0.2, angle: 90.415}
{id: 54, x: 44.0, y: 27.8, angle: 85.969}
{id: 32, x: -9.0, y: 0.0, angle: 91.615}
{id: 8, x: -31.6, y: 30.8, angle: 0.535}
{id: 39, x: -12, y: 8.2, angle: 90}
{id: 39, x: -12.0, y: 8.2, angle: 90.0}
{id: 14, x: -79.6, y: 32.4, angle: 92.342}
{id: 42, x: 65.8, y: 20.8, angle: -85.867}
{id: 40, x: -65, y: 14, angle: 87.109}
{id: 40, x: -65.0, y: 14.0, angle: 87.109}
{id: 45, x: 10.6, y: 18.8, angle: 23.697}
{id: 71, x: -24.2, y: 18.6, angle: -88.531}
{id: 7, x: -72.6, y: 6.4, angle: -89.148}
{id: 62, x: -32, y: 24.8, angle: -140.8}
{id: 62, x: -32.0, y: 24.8, angle: -140.8}
{id: 49, x: 34.4, y: -0.2, angle: 89.415}
{id: 63, x: 74.2, y: 12.6, angle: -138.429}
{id: 59, x: 82.8, y: 13, angle: -140.177}
{id: 59, x: 82.8, y: 13.0, angle: -140.177}
{id: 34, x: -9.4, y: 23.2, angle: -88.238}
{id: 76, x: -57.6, y: 0, angle: 1.2}
{id: 43, x: 7, y: 0, angle: 116.565}
{id: 76, x: -57.6, y: 0.0, angle: 1.2}
{id: 43, x: 7.0, y: 0.0, angle: 116.565}
{id: 20, x: 45.8, y: -0.2, angle: 1.469}
{id: 37, x: -16.6, y: 13.2, angle: 84.785}
{id: 58, x: -79, y: -0.2, angle: 89.481}
{id: 58, x: -79.0, y: -0.2, angle: 89.481}
{id: 50, x: -24.2, y: 12.8, angle: -86.987}
{id: 64, x: 59.2, y: 10.2, angle: -92.203}
{id: 61, x: -72, y: 26.4, angle: -83.66}
{id: 61, x: -72.0, y: 26.4, angle: -83.66}
{id: 47, x: 45.4, y: 5.8, angle: -82.992}
{id: 17, x: -52.2, y: 17.8, angle: -52.938}
{id: 57, x: -61.8, y: 32, angle: 84.627}
{id: 57, x: -61.8, y: 32.0, angle: 84.627}
{id: 29, x: 47.2, y: 28.2, angle: 92.954}
{id: 27, x: -4.6, y: 0.2, angle: 87.397}
{id: 55, x: -61.4, y: 26.4, angle: 94.086}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/resistor-color/resistor_color_spec.moon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ResistorColor = require 'resistor_color'

describe 'resistor-color', ->
describe 'color codes', ->
describe 'Color codes', ->
it 'Black', ->
result = ResistorColor.color_code 'black'
assert.are.equal 0, result
Expand Down
2 changes: 2 additions & 0 deletions exercises/practice/space-age/.meta/spec_generator.moon
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

test_helpers: [[
-- ----------------------------------------
-- Why do we need to test "approximately equal"?
-- See https://0.30000000000000004.com
epsilon = 1e-2
is_close_to = (state, arguments) ->
{a, b} = arguments
Expand Down
Loading
Loading