From 9a734dbc21380899308b6e47021a22e5e5cdc0c1 Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Mon, 4 May 2026 15:17:45 -0400 Subject: [PATCH] Refactor the spec_generator helper functions --- CONTRIBUTING.md | 52 ++++--- bin/generate-spec | 95 ++++--------- exercises/practice/.keep | 0 .../acronym/.meta/spec_generator.moon | 2 + .../affine-cipher/.meta/spec_generator.moon | 2 + .../all-your-base/.meta/spec_generator.moon | 2 +- .../allergies/.meta/spec_generator.moon | 2 +- .../alphametics/.meta/spec_generator.moon | 25 +--- .../alphametics/alphametics_spec.moon | 108 +++----------- .../anagram/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 + .../atbash-cipher/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 17 +-- .../baffling_birthdays_spec.moon | 20 +-- .../bank-account/.meta/spec_generator.moon | 1 - .../.meta/spec_generator.moon | 2 +- .../binary_search_tree_spec.moon | 42 +++--- .../binary-search/.meta/spec_generator.moon | 2 + .../practice/bob/.meta/spec_generator.moon | 1 + .../book-store/.meta/spec_generator.moon | 2 +- .../camicia/.meta/spec_generator.moon | 2 +- .../practice/change/.meta/spec_generator.moon | 2 +- .../circular-buffer/.meta/spec_generator.moon | 2 + .../practice/clock/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 + .../complex-numbers/.meta/spec_generator.moon | 2 + .../connect/.meta/spec_generator.moon | 2 +- .../crypto-square/.meta/spec_generator.moon | 2 + .../custom-set/.meta/spec_generator.moon | 2 +- .../practice/darts/.meta/spec_generator.moon | 2 + .../diamond/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 + .../dnd-character/.meta/spec_generator.moon | 31 ++-- .../dnd-character/dnd_character_spec.moon | 16 +-- .../dominoes/.meta/spec_generator.moon | 2 +- .../eliuds-eggs/.meta/spec_generator.moon | 2 + .../practice/etl/.meta/spec_generator.moon | 2 +- .../flatten-array/.meta/spec_generator.moon | 4 +- .../flower-field/.meta/spec_generator.moon | 3 +- .../food-chain/.meta/spec_generator.moon | 2 +- .../practice/forth/.meta/spec_generator.moon | 7 +- .../game-of-life/.meta/spec_generator.moon | 2 +- .../gigasecond/.meta/spec_generator.moon | 2 + .../grade-school/.meta/spec_generator.moon | 2 +- .../practice/grains/.meta/spec_generator.moon | 11 +- .../hamming/.meta/spec_generator.moon | 2 + .../hello-world/.meta/spec_generator.moon | 1 - .../high-scores/.meta/spec_generator.moon | 2 +- .../practice/house/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 +- .../isbn-verifier/.meta/spec_generator.moon | 5 +- .../isogram/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 1 - .../knapsack/.meta/spec_generator.moon | 2 +- .../practice/knapsack/knapsack_spec.moon | 76 +++++----- .../.meta/spec_generator.moon | 2 + .../practice/leap/.meta/spec_generator.moon | 2 + .../line-up/.meta/spec_generator.moon | 2 + .../linked-list/.meta/spec_generator.moon | 2 + .../practice/luhn/.meta/spec_generator.moon | 2 + .../markdown/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 + .../practice/matrix/.meta/spec_generator.moon | 2 +- .../practice/meetup/.meta/spec_generator.moon | 2 +- .../micro-blog/.meta/spec_generator.moon | 6 +- .../nth-prime/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 8 +- .../pangram/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 +- .../perfect-numbers/.meta/spec_generator.moon | 2 + .../phone-number/.meta/spec_generator.moon | 2 + .../pig-latin/.meta/spec_generator.moon | 9 +- .../practice/pig-latin/pig_latin_spec.moon | 69 ++++++--- .../prime-factors/.meta/spec_generator.moon | 4 +- .../prime-factors/prime_factors_spec.moon | 24 ++-- .../practice/prism/.meta/spec_generator.moon | 20 ++- .../.meta/spec_generator.moon | 2 +- .../proverb/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 +- .../queen-attack/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 + .../raindrops/.meta/spec_generator.moon | 6 +- .../.meta/spec_generator.moon | 20 +-- .../rational_numbers_spec.moon | 20 +-- .../practice/react/.meta/spec_generator.moon | 1 - .../rectangles/.meta/spec_generator.moon | 3 +- .../.meta/spec_generator.moon | 4 +- .../.meta/spec_generator.moon | 8 +- .../resistor-color/.meta/spec_generator.moon | 6 +- .../rest-api/.meta/spec_generator.moon | 2 +- .../practice/rest-api/rest_api_spec.moon | 132 +++++++++--------- .../reverse-string/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 + .../robot-name/.meta/spec_generator.moon | 1 - .../practice/robot-name/robot_name_spec.moon | 9 +- .../practice/robot-name/test_helpers.moon | 21 --- .../robot-simulator/.meta/spec_generator.moon | 2 + .../roman-numerals/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 + .../saddle-points/.meta/spec_generator.moon | 8 +- .../saddle-points/saddle_points_spec.moon | 38 ++--- .../satellite/.meta/spec_generator.moon | 1 - .../practice/say/.meta/spec_generator.moon | 26 ++-- .../scrabble-score/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 +- .../practice/series/.meta/spec_generator.moon | 2 +- .../sgf-parsing/.meta/spec_generator.moon | 4 +- .../sgf-parsing/sgf_parsing_spec.moon | 72 +++++----- .../practice/sieve/.meta/spec_generator.moon | 2 +- .../simple-cipher/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 +- .../space-age/.meta/spec_generator.moon | 20 +-- .../practice/space-age/space_age_spec.moon | 30 ++-- .../spiral-matrix/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 +- .../square-root/.meta/spec_generator.moon | 2 + .../.meta/spec_generator.moon | 2 +- .../practice/strain/.meta/spec_generator.moon | 26 ++-- .../sublist/.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 +- .../.meta/spec_generator.moon | 2 + .../tournament/.meta/spec_generator.moon | 2 + .../transpose/.meta/spec_generator.moon | 2 +- .../triangle/.meta/spec_generator.moon | 5 +- .../twelve-days/.meta/spec_generator.moon | 2 +- .../two-bucket/.meta/spec_generator.moon | 2 +- .../two-fer/.meta/spec_generator.moon | 1 - .../.meta/spec_generator.moon | 2 +- .../word-count/.meta/spec_generator.moon | 23 +-- .../practice/word-count/word_count_spec.moon | 91 +++++------- .../practice/wordy/.meta/spec_generator.moon | 2 + .../practice/yacht/.meta/spec_generator.moon | 2 + .../zebra-puzzle/.meta/spec_generator.moon | 2 + lib/{test_helpers.moon => spec_helpers.moon} | 56 ++++++-- lib/spec_helpers/assertions.moon | 30 ++++ 137 files changed, 710 insertions(+), 774 deletions(-) delete mode 100644 exercises/practice/.keep delete mode 100644 exercises/practice/bank-account/.meta/spec_generator.moon mode change 100755 => 100644 exercises/practice/flower-field/.meta/spec_generator.moon delete mode 100644 exercises/practice/hello-world/.meta/spec_generator.moon delete mode 100644 exercises/practice/kindergarten-garden/.meta/spec_generator.moon delete mode 100644 exercises/practice/react/.meta/spec_generator.moon delete mode 100644 exercises/practice/robot-name/.meta/spec_generator.moon delete mode 100644 exercises/practice/robot-name/test_helpers.moon delete mode 100644 exercises/practice/satellite/.meta/spec_generator.moon delete mode 100644 exercises/practice/two-fer/.meta/spec_generator.moon rename lib/{test_helpers.moon => spec_helpers.moon} (83%) create mode 100644 lib/spec_helpers/assertions.moon diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4da0a0e..f282563 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -125,45 +125,47 @@ It's a module that returns a table. These tests are not executed by the test runner. - Examples: [`robot-name`][robot-name], [`custom-set`][custom-set] -##### Examples of custom assertions - -- [`dnd-character`][dnd-character] -- `assert.between value, min, max` -- [`space-age`][space-age] -- `assert.approx_equal #{case.expected}, result` -- [`alphametics`][alphametics] -- `assert.has.same_kv result, expected` - -#### Helper functions for formatting test cases - -##### Functions in bin/generate-spec - -These functions are exported from [`bin/generate-spec`][generate-spec-exported] for use in spec_generator modules - -- `indent(text, level)` -- provide leading whitespace to the appropriate level. -- `quote(str)` -- add quotation marks to the string, single or double as appropriate. -- `is_empty(tbl)` -- predicate: is the table empty -- `is_json_null(value)` -- predicate: is the value `json.null` from dkjson -- `contains(tbl, value)` -- predicate: does the table contain the value (uses `==`) - ##### Helper functions We have a library of helper functions, useful for generating pretty tables mostly. -For example, to nicely format a list of words, or a list of strings over multiple lines, or to recursively format nested tables. +- to safely quote a word, +- to nicely format a list of words, or a list of strings over multiple lines, +- to recursively format nested tables. -**Look in [`lib/test_helpers.moon`][test-helpers].** +**Look in [`lib/spec_helpers.moon`][spec-helpers].** Example: ```moonscript -import int_list, string_list from require 'test_helpers' +import indent, int_list, string_list from require 'spec_helpers' ... { generate_test: (case, level) -> lines = { "input = #{int_list case.input.numbers}" "expected = #{string_list case.expected, level}" - ... + "assert.are.same expected, someFunc input" + } + table.concat [indent line for line in *lines], "\n" ``` +##### Custom Assertions + +Custom assertions are stored in [`lib/spec_handlers/assertions.moon][assertions]. +Currently there is only one: + +- [`dnd-character`][dnd-character] -- `assert.is.between value, min, max` + +I used to have some more, but the [luassert][luassert] library is quite complete: + +- `assert.are.equal expected, actual` -- compare with `==` +- `assert.are.same expected, actual` -- deeply compare tables for same keys and values +- `assert.is.near expected, actual, epsilon` -- floats are approximately equal +- `assert.matches pattern, string [, init [, plain]]` -- pattern matching (with lua patterns) + - see the lua [string.find][string-find] and [string.match][string-match] docs. + - luassert uses string.match, or string.find if "plain" is true. + ##### Comparing tables deeply The `assert.are.same t1, t2` assertion is used to compare tables deeply. @@ -242,9 +244,13 @@ Here, the value `4` was chosen to reflect the max depth of the expected value: [exercise-list]: https://github.com/exercism/moonscript/issues/102 [gh-issues]: https://github.com/exercism/moonscript/issues [gh-pulls]: https://github.com/exercism/moonscript/pulls +[luassert]: https://github.com/lunarmodules/luassert/blob/master/src/assertions.lua +[string-find]: https://www.lua.org/manual/5.4/manual.html#pdf-string.find +[string-match]: https://www.lua.org/manual/5.4/manual.html#pdf-string.match [style]: ./STYLE.md [generate-spec-exported]: ./bin/generate-spec#L51 -[test-helpers]: ./lib/test_helpers.moon +[spec-helpers]: ./lib/spec_helpers.moon +[assertions]: ./lib/spec_helpers/assertions.moon [space-age]: ./exercises/practice/space-age/.meta/spec_generator.moon [alphametics]: ./exercises/practice/alphametics/.meta/spec_generator.moon [dnd-character]: ./exercises/practice/dnd-character/.meta/spec_generator.moon diff --git a/bin/generate-spec b/bin/generate-spec index 21bab13..fbe042d 100755 --- a/bin/generate-spec +++ b/bin/generate-spec @@ -3,76 +3,35 @@ require 'moonscript' json = (require 'dkjson').use_lpeg! +path = require 'pl.path' +file = require 'pl.file' -- import p from require 'moon' -local exercise_name, exercise_directory, spec_generator, included_tests -- forward declarations - - -file_exists = (path) -> - f = io.open path, 'r' - if f - f\close! - true - else - false - - -read_file = (path) -> - f = assert io.open path, 'r' - contents = f\read '*a' - f\close! - contents - - -write_file = (path, contents) -> - f = assert io.open path, 'w' - f\write contents - f\close! +package.moonpath = "./lib/?.moon;#{package.moonpath}" +import indent, quote, table_contains from require 'spec_helpers' +die = (msg) -> + io.stderr\write msg + os.exit 1 +-- ---------------------------------------------------------- included_tests_from_toml = (path) -> included = {} - local uuid, last_uuid - line_no = 0 + local last_uuid - for line in io.lines(path) - line_no += 1 - for uuid in line\gmatch('%[([%x%-]+)%]') + for line in io.lines path + for uuid in line\gmatch '%[([%x%-]+)%]' last_uuid = uuid included[uuid] = true - if line\match('^include%s*=%s*false') + if line\match '^include%s*=%s*false' included[last_uuid] = nil included -- ---------------------------------------------------------- --- functions marked as global so spec_generators can see them -export indent, quote, is_json_null, is_empty, contains - -indent = (text, level) -> - error 'Provide a level for `indent`', 2 if not level - string.rep(' ', level) .. text - -quote = (str) -> - if str\find "'" - "\"#{str\gsub '"', '\\"'}\"" - else - "'#{str}'" - -is_empty = (t) -> not next t - --- the dkjson `json.null` value is an empty table -is_json_null = (value) -> type(value) == 'table' and is_empty(value) - --- a table contains a value -contains = (t, v) -> - for elem in *t - return true if elem == v - false - --- ---------------------------------------------------------- - +-- forward declarations +local exercise_name, exercise_directory, spec_generator, included_tests test_cmd = 'it' @@ -81,18 +40,21 @@ process = (node, level=0) -> for exclusion in *(spec_generator.exclusions or {}) if node[exclusion.key] if exclusion.op == 'contains' - return '' if contains node[exclusion.key], exclusion.value + return '' if table_contains node[exclusion.key], exclusion.value else return '' if node[exclusion.key] == exclusion.value - if node.cases + if not node.cases + test = "#{test_cmd} #{quote node.description}, ->\n#{spec_generator.generate_test(node, level + 1)}\n" + test_cmd = 'pending' + return indent test, level + else output = {} if node.description table.insert output, indent("describe #{quote(node.description .. ':')}, ->", level) else table.insert output, indent("describe '#{exercise_name}:', ->", level) - if spec_generator.test_helpers table.insert output, spec_generator.test_helpers @@ -105,11 +67,6 @@ process = (node, level=0) -> return table.concat output, '\n' - else -- no "cases" member - test = "#{test_cmd} #{quote node.description}, ->\n#{spec_generator.generate_test(node, level + 1)}\n" - test_cmd = 'pending' - return indent test, level - -- ---------------------------------------------------------- -- "main" -- ---------------------------------------------------------- @@ -121,6 +78,12 @@ if snake_name == 'say' snake_name = './say' exercise_directory = 'exercises/practice/' .. exercise_name +if not path.exists(exercise_directory) + die "no such directory: #{exercise_directory}\n" + +-- can't generate what's not there +if not path.exists("#{exercise_directory}/.meta/spec_generator.moon") + die "#{exercise_name} does not have a spec_generator module.\n" canonical_data_url = "https://raw.githubusercontent.com/exercism/problem-specifications/main/exercises/#{exercise_name}/canonical-data.json" canonical_data_path = "canonical-data/#{exercise_name}.json" @@ -129,7 +92,7 @@ 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 +canonical_data = json.decode file.read(canonical_data_path, false), 1, json.null tests_toml_path = exercise_directory .. '/.meta/tests.toml' included_tests = included_tests_from_toml tests_toml_path @@ -143,7 +106,7 @@ if spec_generator.module_name elseif spec_generator.module_imports spec = "import #{table.concat spec_generator.module_imports, ', '} from require '#{snake_name}'" else - error 'spec_generator is missing both "module_name" and "module_imports"' + die 'spec_generator is missing both "module_name" and "module_imports"' spec ..= "\n\n" .. process(canonical_data) @@ -161,6 +124,6 @@ if spec_generator.bonus spec ..= spec_generator.bonus spec_path = exercise_directory .. '/' .. snake_name .. '_spec.moon' -write_file spec_path, spec +file.write spec_path, spec, false print "Created #{spec_path}" diff --git a/exercises/practice/.keep b/exercises/practice/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/exercises/practice/acronym/.meta/spec_generator.moon b/exercises/practice/acronym/.meta/spec_generator.moon index 23d5de5..70e0173 100644 --- a/exercises/practice/acronym/.meta/spec_generator.moon +++ b/exercises/practice/acronym/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'abbreviate'}, generate_test: (case, level) -> diff --git a/exercises/practice/affine-cipher/.meta/spec_generator.moon b/exercises/practice/affine-cipher/.meta/spec_generator.moon index 2ecfb8a..ac5aa09 100644 --- a/exercises/practice/affine-cipher/.meta/spec_generator.moon +++ b/exercises/practice/affine-cipher/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'encode', 'decode'}, diff --git a/exercises/practice/all-your-base/.meta/spec_generator.moon b/exercises/practice/all-your-base/.meta/spec_generator.moon index f0667da..f8613b7 100644 --- a/exercises/practice/all-your-base/.meta/spec_generator.moon +++ b/exercises/practice/all-your-base/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, quote, int_list from require 'spec_helpers' { module_imports: {'rebase'}, diff --git a/exercises/practice/allergies/.meta/spec_generator.moon b/exercises/practice/allergies/.meta/spec_generator.moon index 2dd9afe..93740ea 100644 --- a/exercises/practice/allergies/.meta/spec_generator.moon +++ b/exercises/practice/allergies/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' { module_name: 'Allergies', diff --git a/exercises/practice/alphametics/.meta/spec_generator.moon b/exercises/practice/alphametics/.meta/spec_generator.moon index a6b996f..ff82df0 100644 --- a/exercises/practice/alphametics/.meta/spec_generator.moon +++ b/exercises/practice/alphametics/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import kv_table from require 'test_helpers' +import indent, quote, is_json_null, table_tostring_sortby_keys from require 'spec_helpers' { module_imports: {'solve'}, @@ -13,27 +13,8 @@ import kv_table from require 'test_helpers' { "puzzle = #{quote case.input.puzzle}", "result = solve puzzle", - "expected = #{kv_table case.expected, level}", - "assert.is.same_kv result, expected" + "expected = #{table_tostring_sortby_keys case.expected, level}", + "assert.are.same result, expected" } table.concat [indent line, level for line in *lines], '\n' - - test_helpers: [[ - -- ---------------------------------------------------------- - same_kv = (state, arguments) -> - actual = arguments[1] - return false if type(actual) != 'table' - expected = arguments[2] - size = (t) -> #[k for k, _ in pairs t] - return false if size(expected) != size(actual) - for k, v in pairs expected - return false if actual[k] != v - true - - say = require 'say' - say\set 'assertion.same_kv.positive', 'Actual result\n%s\ndoes not have the same keys and values as expected\n%s' - say\set 'assertion.same_kv.negative', 'Actual result\n%s\nwas not supposed to be the same as expected\n%s' - assert\register 'assertion', 'same_kv', same_kv, 'assertion.same_kv.positive', 'assertion.same_kv.negative' - -- ---------------------------------------------------------- -]] } diff --git a/exercises/practice/alphametics/alphametics_spec.moon b/exercises/practice/alphametics/alphametics_spec.moon index 22ef061..93be850 100644 --- a/exercises/practice/alphametics/alphametics_spec.moon +++ b/exercises/practice/alphametics/alphametics_spec.moon @@ -1,32 +1,11 @@ import solve from require 'alphametics' describe 'alphametics:', -> - -- ---------------------------------------------------------- - same_kv = (state, arguments) -> - actual = arguments[1] - return false if type(actual) != 'table' - expected = arguments[2] - size = (t) -> #[k for k, _ in pairs t] - return false if size(expected) != size(actual) - for k, v in pairs expected - return false if actual[k] != v - true - - say = require 'say' - say\set 'assertion.same_kv.positive', 'Actual result\n%s\ndoes not have the same keys and values as expected\n%s' - say\set 'assertion.same_kv.negative', 'Actual result\n%s\nwas not supposed to be the same as expected\n%s' - assert\register 'assertion', 'same_kv', same_kv, 'assertion.same_kv.positive', 'assertion.same_kv.negative' - -- ---------------------------------------------------------- - it 'puzzle with three letters', -> puzzle = 'I + BB == ILL' result = solve puzzle - expected = { - I: 1, - B: 9, - L: 0, - } - assert.is.same_kv result, expected + expected = {B: 9, I: 1, L: 0} + assert.are.same result, expected pending 'solution must have unique value for each letter', -> puzzle = 'A == B' @@ -39,96 +18,41 @@ describe 'alphametics:', -> pending 'puzzle with two digits final carry', -> puzzle = 'A + A + A + A + A + A + A + A + A + A + A + B == BCC' result = solve puzzle - expected = { - A: 9, - B: 1, - C: 0, - } - assert.is.same_kv result, expected + expected = {A: 9, B: 1, C: 0} + assert.are.same result, expected pending 'puzzle with four letters', -> puzzle = 'AS + A == MOM' result = solve puzzle - expected = { - A: 9, - O: 0, - S: 2, - M: 1, - } - assert.is.same_kv result, expected + expected = {A: 9, M: 1, O: 0, S: 2} + assert.are.same result, expected pending 'puzzle with six letters', -> puzzle = 'NO + NO + TOO == LATE' result = solve puzzle - expected = { - E: 2, - N: 7, - O: 4, - A: 0, - T: 9, - L: 1, - } - assert.is.same_kv result, expected + expected = {A: 0, E: 2, L: 1, N: 7, O: 4, T: 9} + assert.are.same result, expected pending 'puzzle with seven letters', -> puzzle = 'HE + SEES + THE == LIGHT' result = solve puzzle - expected = { - E: 4, - G: 2, - H: 5, - I: 0, - T: 7, - S: 9, - L: 1, - } - assert.is.same_kv result, expected + expected = {E: 4, G: 2, H: 5, I: 0, L: 1, S: 9, T: 7} + assert.are.same result, expected pending 'puzzle with eight letters', -> puzzle = 'SEND + MORE == MONEY' result = solve puzzle - expected = { - E: 5, - N: 6, - O: 0, - M: 1, - Y: 2, - R: 8, - S: 9, - D: 7, - } - assert.is.same_kv result, expected + expected = {D: 7, E: 5, M: 1, N: 6, O: 0, R: 8, S: 9, Y: 2} + assert.are.same result, expected pending 'puzzle with ten letters', -> puzzle = 'AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE' result = solve puzzle - expected = { - N: 0, - O: 2, - E: 4, - F: 7, - G: 8, - T: 9, - A: 5, - R: 1, - S: 6, - D: 3, - } - assert.is.same_kv result, expected + expected = {A: 5, D: 3, E: 4, F: 7, G: 8, N: 0, O: 2, R: 1, S: 6, T: 9} + assert.are.same result, expected pending 'puzzle with ten letters and 199 addends', -> puzzle = 'THIS + A + FIRE + THEREFORE + FOR + ALL + HISTORIES + I + TELL + A + TALE + THAT + FALSIFIES + ITS + TITLE + TIS + A + LIE + THE + TALE + OF + THE + LAST + FIRE + HORSES + LATE + AFTER + THE + FIRST + FATHERS + FORESEE + THE + HORRORS + THE + LAST + FREE + TROLL + TERRIFIES + THE + HORSES + OF + FIRE + THE + TROLL + RESTS + AT + THE + HOLE + OF + LOSSES + IT + IS + THERE + THAT + SHE + STORES + ROLES + OF + LEATHERS + AFTER + SHE + SATISFIES + HER + HATE + OFF + THOSE + FEARS + A + TASTE + RISES + AS + SHE + HEARS + THE + LEAST + FAR + HORSE + THOSE + FAST + HORSES + THAT + FIRST + HEAR + THE + TROLL + FLEE + OFF + TO + THE + FOREST + THE + HORSES + THAT + ALERTS + RAISE + THE + STARES + OF + THE + OTHERS + AS + THE + TROLL + ASSAILS + AT + THE + TOTAL + SHIFT + HER + TEETH + TEAR + HOOF + OFF + TORSO + AS + THE + LAST + HORSE + FORFEITS + ITS + LIFE + THE + FIRST + FATHERS + HEAR + OF + THE + HORRORS + THEIR + FEARS + THAT + THE + FIRES + FOR + THEIR + FEASTS + ARREST + AS + THE + FIRST + FATHERS + RESETTLE + THE + LAST + OF + THE + FIRE + HORSES + THE + LAST + TROLL + HARASSES + THE + FOREST + HEART + FREE + AT + LAST + OF + THE + LAST + TROLL + ALL + OFFER + THEIR + FIRE + HEAT + TO + THE + ASSISTERS + FAR + OFF + THE + TROLL + FASTS + ITS + LIFE + SHORTER + AS + STARS + RISE + THE + HORSES + REST + SAFE + AFTER + ALL + SHARE + HOT + FISH + AS + THEIR + AFFILIATES + TAILOR + A + ROOFS + FOR + THEIR + SAFE == FORTRESSES' result = solve puzzle - expected = { - O: 6, - I: 7, - L: 2, - E: 0, - F: 5, - H: 8, - A: 1, - R: 3, - S: 4, - T: 9, - } - assert.is.same_kv result, expected + expected = {A: 1, E: 0, F: 5, H: 8, I: 7, L: 2, O: 6, R: 3, S: 4, T: 9} + assert.are.same result, expected diff --git a/exercises/practice/anagram/.meta/spec_generator.moon b/exercises/practice/anagram/.meta/spec_generator.moon index dfb197d..1144b77 100644 --- a/exercises/practice/anagram/.meta/spec_generator.moon +++ b/exercises/practice/anagram/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' { module_name: 'find_anagrams', diff --git a/exercises/practice/armstrong-numbers/.meta/spec_generator.moon b/exercises/practice/armstrong-numbers/.meta/spec_generator.moon index 2e46233..e497734 100644 --- a/exercises/practice/armstrong-numbers/.meta/spec_generator.moon +++ b/exercises/practice/armstrong-numbers/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'ArmstrongNumbers', generate_test: (case, level) -> diff --git a/exercises/practice/atbash-cipher/.meta/spec_generator.moon b/exercises/practice/atbash-cipher/.meta/spec_generator.moon index 1a53d8d..557b039 100644 --- a/exercises/practice/atbash-cipher/.meta/spec_generator.moon +++ b/exercises/practice/atbash-cipher/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'AtbashCipher', diff --git a/exercises/practice/baffling-birthdays/.meta/spec_generator.moon b/exercises/practice/baffling-birthdays/.meta/spec_generator.moon index 2a7e68f..dc92def 100644 --- a/exercises/practice/baffling-birthdays/.meta/spec_generator.moon +++ b/exercises/practice/baffling-birthdays/.meta/spec_generator.moon @@ -1,5 +1,4 @@ -tablex = require 'pl.tablex' -import int_list, word_list from require 'test_helpers' +import indent, int_list, word_list from require 'spec_helpers' { module_name: 'BafflingBirthdays', @@ -15,7 +14,7 @@ import int_list, word_list from require 'test_helpers' when 'estimatedProbabilityOfSharedBirthday' lines = { "result = BafflingBirthdays.#{case.property} #{case.input.groupSize}", - "assert.is.approx_equal #{case.expected}, result" + "assert.is.near #{case.expected}, result, 1.0" } when 'randomBirthdates' switch case.description @@ -63,18 +62,6 @@ import int_list, word_list from require 'test_helpers' -- https://lunarmodules.github.io/Penlight/libraries/pl.tablex.html tablex = require 'pl.tablex' - -- - epsilon = 1.0 - is_close_to = (state, arguments) -> - {a, b} = arguments - math.abs(a - b) <= epsilon - - say = require 'say' - say\set 'assertion.approx_equal.positive', "Expected %s and %s to be within #{epsilon}" - say\set 'assertion.approx_equal.negative', "Expected %s and %s not to be within #{epsilon}" - assert\register 'assertion', 'approx_equal', is_close_to, 'assertion.approx_equal.positive', 'assertion.approx_equal.negative' - - -- isLeapYear = (year) -> year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) -- ---------------------------------------- ]] diff --git a/exercises/practice/baffling-birthdays/baffling_birthdays_spec.moon b/exercises/practice/baffling-birthdays/baffling_birthdays_spec.moon index 5993114..c9f1750 100644 --- a/exercises/practice/baffling-birthdays/baffling_birthdays_spec.moon +++ b/exercises/practice/baffling-birthdays/baffling_birthdays_spec.moon @@ -5,18 +5,6 @@ describe 'baffling-birthdays:', -> -- https://lunarmodules.github.io/Penlight/libraries/pl.tablex.html tablex = require 'pl.tablex' - -- - epsilon = 1.0 - is_close_to = (state, arguments) -> - {a, b} = arguments - math.abs(a - b) <= epsilon - - say = require 'say' - say\set 'assertion.approx_equal.positive', "Expected %s and %s to be within #{epsilon}" - say\set 'assertion.approx_equal.negative', "Expected %s and %s not to be within #{epsilon}" - assert\register 'assertion', 'approx_equal', is_close_to, 'assertion.approx_equal.positive', 'assertion.approx_equal.negative' - - -- isLeapYear = (year) -> year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) -- ---------------------------------------- @@ -93,16 +81,16 @@ describe 'baffling-birthdays:', -> describe 'estimated probability of at least one shared birthday:', -> pending 'for one person', -> result = BafflingBirthdays.estimatedProbabilityOfSharedBirthday 1 - assert.is.approx_equal 0.0, result + assert.is.near 0.0, result, 1.0 pending 'among ten people', -> result = BafflingBirthdays.estimatedProbabilityOfSharedBirthday 10 - assert.is.approx_equal 11.694818, result + assert.is.near 11.694818, result, 1.0 pending 'among twenty-three people', -> result = BafflingBirthdays.estimatedProbabilityOfSharedBirthday 23 - assert.is.approx_equal 50.729723, result + assert.is.near 50.729723, result, 1.0 pending 'among seventy people', -> result = BafflingBirthdays.estimatedProbabilityOfSharedBirthday 70 - assert.is.approx_equal 99.915958, result + assert.is.near 99.915958, result, 1.0 diff --git a/exercises/practice/bank-account/.meta/spec_generator.moon b/exercises/practice/bank-account/.meta/spec_generator.moon deleted file mode 100644 index 6efb5e1..0000000 --- a/exercises/practice/bank-account/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'bank-account does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/binary-search-tree/.meta/spec_generator.moon b/exercises/practice/binary-search-tree/.meta/spec_generator.moon index 42a666a..0f305d1 100644 --- a/exercises/practice/binary-search-tree/.meta/spec_generator.moon +++ b/exercises/practice/binary-search-tree/.meta/spec_generator.moon @@ -1,6 +1,6 @@ stringx = require 'pl.stringx' import dump from require 'moon' -import word_list from require 'test_helpers' +import indent, word_list from require 'spec_helpers' bst = (t, level) -> dumped = dump t diff --git a/exercises/practice/binary-search-tree/binary_search_tree_spec.moon b/exercises/practice/binary-search-tree/binary_search_tree_spec.moon index f3995c3..5343150 100644 --- a/exercises/practice/binary-search-tree/binary_search_tree_spec.moon +++ b/exercises/practice/binary-search-tree/binary_search_tree_spec.moon @@ -6,8 +6,8 @@ describe 'binary-search-tree:', -> result = tree\data! expected = { data: "4" - right: nil left: nil + right: nil } assert.are.same expected, result @@ -17,12 +17,12 @@ describe 'binary-search-tree:', -> result = tree\data! expected = { data: "4" - right: nil left: { data: "2" - right: nil left: nil + right: nil } + right: nil } assert.are.same expected, result @@ -31,12 +31,12 @@ describe 'binary-search-tree:', -> result = tree\data! expected = { data: "4" - right: nil left: { data: "4" - right: nil left: nil + right: nil } + right: nil } assert.are.same expected, result @@ -45,12 +45,12 @@ describe 'binary-search-tree:', -> result = tree\data! expected = { data: "4" + left: nil right: { data: "5" - right: nil left: nil + right: nil } - left: nil } assert.are.same expected, result @@ -59,30 +59,30 @@ describe 'binary-search-tree:', -> result = tree\data! expected = { data: "4" - right: { - data: "6" - right: { - data: "7" - right: nil - left: nil - } + left: { + data: "2" left: { - data: "5" - right: nil + data: "1" left: nil + right: nil } - } - left: { - data: "2" right: { data: "3" - right: nil left: nil + right: nil } + } + right: { + data: "6" left: { - data: "1" + data: "5" + left: nil right: nil + } + right: { + data: "7" left: nil + right: nil } } } diff --git a/exercises/practice/binary-search/.meta/spec_generator.moon b/exercises/practice/binary-search/.meta/spec_generator.moon index 900746b..8d1c1cb 100644 --- a/exercises/practice/binary-search/.meta/spec_generator.moon +++ b/exercises/practice/binary-search/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'BinarySearch', test_helpers: [[ diff --git a/exercises/practice/bob/.meta/spec_generator.moon b/exercises/practice/bob/.meta/spec_generator.moon index 03c4844..3953ea4 100644 --- a/exercises/practice/bob/.meta/spec_generator.moon +++ b/exercises/practice/bob/.meta/spec_generator.moon @@ -1,3 +1,4 @@ +import indent, quote from require 'spec_helpers' json = require 'dkjson' { diff --git a/exercises/practice/book-store/.meta/spec_generator.moon b/exercises/practice/book-store/.meta/spec_generator.moon index 72547e8..f12dbd9 100644 --- a/exercises/practice/book-store/.meta/spec_generator.moon +++ b/exercises/practice/book-store/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, int_list from require 'spec_helpers' { module_name: 'BookStore', diff --git a/exercises/practice/camicia/.meta/spec_generator.moon b/exercises/practice/camicia/.meta/spec_generator.moon index 76cfb03..8809e67 100644 --- a/exercises/practice/camicia/.meta/spec_generator.moon +++ b/exercises/practice/camicia/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' { module_name: 'Camicia' diff --git a/exercises/practice/change/.meta/spec_generator.moon b/exercises/practice/change/.meta/spec_generator.moon index 4f12a36..8202263 100644 --- a/exercises/practice/change/.meta/spec_generator.moon +++ b/exercises/practice/change/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -int_list = (list) -> "{#{table.concat list, ', '}}" +import indent, quote, int_list from require 'spec_helpers' { module_imports: {'make_change'}, diff --git a/exercises/practice/circular-buffer/.meta/spec_generator.moon b/exercises/practice/circular-buffer/.meta/spec_generator.moon index bf0c3d0..444d97f 100644 --- a/exercises/practice/circular-buffer/.meta/spec_generator.moon +++ b/exercises/practice/circular-buffer/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'CircularBuffer', diff --git a/exercises/practice/clock/.meta/spec_generator.moon b/exercises/practice/clock/.meta/spec_generator.moon index 1473f19..22831e1 100644 --- a/exercises/practice/clock/.meta/spec_generator.moon +++ b/exercises/practice/clock/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Clock', generate_test: (case, level) -> diff --git a/exercises/practice/collatz-conjecture/.meta/spec_generator.moon b/exercises/practice/collatz-conjecture/.meta/spec_generator.moon index d090fb1..d5a799e 100644 --- a/exercises/practice/collatz-conjecture/.meta/spec_generator.moon +++ b/exercises/practice/collatz-conjecture/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'CollatzConjecture', generate_test: (case, level) -> diff --git a/exercises/practice/complex-numbers/.meta/spec_generator.moon b/exercises/practice/complex-numbers/.meta/spec_generator.moon index 6ef3d3e..75024ee 100644 --- a/exercises/practice/complex-numbers/.meta/spec_generator.moon +++ b/exercises/practice/complex-numbers/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + op = add: '+', sub: '-', mul: '*', div: '/' cn = (z) -> diff --git a/exercises/practice/connect/.meta/spec_generator.moon b/exercises/practice/connect/.meta/spec_generator.moon index c09df51..3b1870d 100644 --- a/exercises/practice/connect/.meta/spec_generator.moon +++ b/exercises/practice/connect/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, quote, string_list from require 'spec_helpers' { -- one of: diff --git a/exercises/practice/crypto-square/.meta/spec_generator.moon b/exercises/practice/crypto-square/.meta/spec_generator.moon index 19216ef..e88ea4b 100644 --- a/exercises/practice/crypto-square/.meta/spec_generator.moon +++ b/exercises/practice/crypto-square/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'encode'}, diff --git a/exercises/practice/custom-set/.meta/spec_generator.moon b/exercises/practice/custom-set/.meta/spec_generator.moon index 270ee00..7e80745 100644 --- a/exercises/practice/custom-set/.meta/spec_generator.moon +++ b/exercises/practice/custom-set/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, int_list from require 'spec_helpers' { module_name: 'CustomSet', diff --git a/exercises/practice/darts/.meta/spec_generator.moon b/exercises/practice/darts/.meta/spec_generator.moon index 8c02c0a..22c3dd7 100644 --- a/exercises/practice/darts/.meta/spec_generator.moon +++ b/exercises/practice/darts/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'darts', generate_test: (case, level) -> diff --git a/exercises/practice/diamond/.meta/spec_generator.moon b/exercises/practice/diamond/.meta/spec_generator.moon index 6d46f78..ab74512 100644 --- a/exercises/practice/diamond/.meta/spec_generator.moon +++ b/exercises/practice/diamond/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, quote, string_list from require 'spec_helpers' { module_name: 'Diamond' diff --git a/exercises/practice/difference-of-squares/.meta/spec_generator.moon b/exercises/practice/difference-of-squares/.meta/spec_generator.moon index 182f4f9..cb18c96 100644 --- a/exercises/practice/difference-of-squares/.meta/spec_generator.moon +++ b/exercises/practice/difference-of-squares/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'DifferenceOfSquares', generate_test: (case, level=2) -> diff --git a/exercises/practice/dnd-character/.meta/spec_generator.moon b/exercises/practice/dnd-character/.meta/spec_generator.moon index b244922..87904ca 100644 --- a/exercises/practice/dnd-character/.meta/spec_generator.moon +++ b/exercises/practice/dnd-character/.meta/spec_generator.moon @@ -1,19 +1,10 @@ +import indent from require 'spec_helpers' +assertions = require 'spec_helpers.assertions' + { module_imports: {'modifier', 'ability', 'character'}, - test_helpers: [[ - -- ---------------------------------------------------------- - between = (state, arguments) -> - assert #arguments == 3, 'expected three arguments to assert.between: value, min, max' - { val, min, max } = arguments - val and min <= val and val <= max - - say = require 'say' - say\set 'assertion.between.positive', 'Expected %s to be in the range [%s, %s]' - say\set 'assertion.between.negative', 'Expected %s not to be in the range [%s, %s]' - assert\register 'assertion', 'between', between, 'assertion.between.positive', 'assertion.between.negative' - -- ---------------------------------------------------------- - ]] + test_helpers: assertions.between generate_test: (case, level) -> local lines @@ -27,18 +18,18 @@ lines = { "for i = 1, 50", " score = ability!", - " assert.between score, 3, 18" + " assert.is.between score, 3, 18" } when 'character' if case.description == "random character is valid" lines = { "player = character!", - "assert.between player.strength, 3, 18", - "assert.between player.dexterity, 3, 18", - "assert.between player.constitution, 3, 18", - "assert.between player.intelligence, 3, 18", - "assert.between player.wisdom, 3, 18", - "assert.between player.charisma, 3, 18", + "assert.is.between player.strength, 3, 18", + "assert.is.between player.dexterity, 3, 18", + "assert.is.between player.constitution, 3, 18", + "assert.is.between player.intelligence, 3, 18", + "assert.is.between player.wisdom, 3, 18", + "assert.is.between player.charisma, 3, 18", "assert.are.equal (10 + modifier player.constitution), player.hitpoints" } else diff --git a/exercises/practice/dnd-character/dnd_character_spec.moon b/exercises/practice/dnd-character/dnd_character_spec.moon index cfb98cb..1eec724 100644 --- a/exercises/practice/dnd-character/dnd_character_spec.moon +++ b/exercises/practice/dnd-character/dnd_character_spec.moon @@ -12,7 +12,7 @@ describe 'dnd-character:', -> say\set 'assertion.between.negative', 'Expected %s not to be in the range [%s, %s]' assert\register 'assertion', 'between', between, 'assertion.between.positive', 'assertion.between.negative' -- ---------------------------------------------------------- - + describe 'ability modifier:', -> it 'ability modifier for score 3 is -4', -> assert.are.equal -4, modifier 3 @@ -65,16 +65,16 @@ describe 'dnd-character:', -> pending 'random ability is within range', -> for i = 1, 50 score = ability! - assert.between score, 3, 18 + assert.is.between score, 3, 18 pending 'random character is valid', -> player = character! - assert.between player.strength, 3, 18 - assert.between player.dexterity, 3, 18 - assert.between player.constitution, 3, 18 - assert.between player.intelligence, 3, 18 - assert.between player.wisdom, 3, 18 - assert.between player.charisma, 3, 18 + assert.is.between player.strength, 3, 18 + assert.is.between player.dexterity, 3, 18 + assert.is.between player.constitution, 3, 18 + assert.is.between player.intelligence, 3, 18 + assert.is.between player.wisdom, 3, 18 + assert.is.between player.charisma, 3, 18 assert.are.equal (10 + modifier player.constitution), player.hitpoints pending 'each ability is only calculated once', -> diff --git a/exercises/practice/dominoes/.meta/spec_generator.moon b/exercises/practice/dominoes/.meta/spec_generator.moon index 40f08fd..7543094 100644 --- a/exercises/practice/dominoes/.meta/spec_generator.moon +++ b/exercises/practice/dominoes/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_lists from require 'test_helpers' +import indent, int_lists from require 'spec_helpers' { module_imports: {'canChain'}, diff --git a/exercises/practice/eliuds-eggs/.meta/spec_generator.moon b/exercises/practice/eliuds-eggs/.meta/spec_generator.moon index 5414e99..3ac8f6f 100644 --- a/exercises/practice/eliuds-eggs/.meta/spec_generator.moon +++ b/exercises/practice/eliuds-eggs/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'count_eggs', generate_test: (case, level) -> diff --git a/exercises/practice/etl/.meta/spec_generator.moon b/exercises/practice/etl/.meta/spec_generator.moon index 0d881b2..2cbca6d 100644 --- a/exercises/practice/etl/.meta/spec_generator.moon +++ b/exercises/practice/etl/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' { module_name: 'Etl', diff --git a/exercises/practice/flatten-array/.meta/spec_generator.moon b/exercises/practice/flatten-array/.meta/spec_generator.moon index 329e686..f72304f 100644 --- a/exercises/practice/flatten-array/.meta/spec_generator.moon +++ b/exercises/practice/flatten-array/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, int_list from require 'spec_helpers' + -- A simple way to render an arbitrary list of lists is to stringify it -- and then munge the string into a Lua table literal. json = (require 'dkjson').use_lpeg! @@ -9,8 +11,6 @@ nested_lists = (list) -> a = a\gsub 'null', '"null"' a -import int_list from require 'test_helpers' - { module_imports: {'flatten'}, diff --git a/exercises/practice/flower-field/.meta/spec_generator.moon b/exercises/practice/flower-field/.meta/spec_generator.moon old mode 100755 new mode 100644 index 283995e..566e1a9 --- a/exercises/practice/flower-field/.meta/spec_generator.moon +++ b/exercises/practice/flower-field/.meta/spec_generator.moon @@ -1,4 +1,5 @@ -import string_list from require 'test_helpers' +import indent, string_list from require 'spec_helpers' + { module_name: 'FlowerField' diff --git a/exercises/practice/food-chain/.meta/spec_generator.moon b/exercises/practice/food-chain/.meta/spec_generator.moon index af4b134..4ec8fc8 100644 --- a/exercises/practice/food-chain/.meta/spec_generator.moon +++ b/exercises/practice/food-chain/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, string_list from require 'spec_helpers' { module_name: 'FoodChain', diff --git a/exercises/practice/forth/.meta/spec_generator.moon b/exercises/practice/forth/.meta/spec_generator.moon index 0c921af..8d97f17 100644 --- a/exercises/practice/forth/.meta/spec_generator.moon +++ b/exercises/practice/forth/.meta/spec_generator.moon @@ -1,4 +1,9 @@ -import int_list, string_list, table_contains from require 'test_helpers' +import indent + quote + int_list + string_list + table_contains + from require 'spec_helpers' { module_name: 'Forth', diff --git a/exercises/practice/game-of-life/.meta/spec_generator.moon b/exercises/practice/game-of-life/.meta/spec_generator.moon index b99a872..71ef8c3 100644 --- a/exercises/practice/game-of-life/.meta/spec_generator.moon +++ b/exercises/practice/game-of-life/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_lists, word_list from require 'test_helpers' +import indent, int_lists, word_list from require 'spec_helpers' { module_name: 'GameOfLife', diff --git a/exercises/practice/gigasecond/.meta/spec_generator.moon b/exercises/practice/gigasecond/.meta/spec_generator.moon index 03df107..701585a 100644 --- a/exercises/practice/gigasecond/.meta/spec_generator.moon +++ b/exercises/practice/gigasecond/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Gigasecond', diff --git a/exercises/practice/grade-school/.meta/spec_generator.moon b/exercises/practice/grade-school/.meta/spec_generator.moon index fa3dd34..917b856 100644 --- a/exercises/practice/grade-school/.meta/spec_generator.moon +++ b/exercises/practice/grade-school/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import bool_list, word_list from require 'test_helpers' +import indent, quote, bool_list, word_list from require 'spec_helpers' student_grade = (t) -> "{#{quote t[1]}, #{t[2]}}" diff --git a/exercises/practice/grains/.meta/spec_generator.moon b/exercises/practice/grains/.meta/spec_generator.moon index 499e5a5..6bf9ce4 100644 --- a/exercises/practice/grains/.meta/spec_generator.moon +++ b/exercises/practice/grains/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + format = (number) -> string.format '%.0f', number @@ -5,18 +7,17 @@ format = (number) -> module_name: 'Grains' generate_test: (case, level) -> - lines = {} - if type(case.expected) == 'table' and case.expected.error - table.insert lines, "assert.has.errors -> Grains.#{case.property} #{case.input.square}, #{quote case.expected.error}" + lines = if type(case.expected) == 'table' and case.expected.error + {"assert.has.errors -> Grains.#{case.property} #{case.input.square}, #{quote case.expected.error}"} else if case.property == 'square' - table.insert lines, "assert.are.equal #{format case.expected}, Grains.#{case.property} #{case.input.square}" + {"assert.are.equal #{format case.expected}, Grains.#{case.property} #{case.input.square}"} else -- apparently Lua can't represent this number exactly, so hardcode it. -- > string.format('%.0f', 18446744073709551615) -- 18446744073709551616 -- > 18446744073709551615 == 18446744073709551616 -- true - table.insert lines, "assert.are.equal 18446744073709551615, Grains.#{case.property}!" + {"assert.are.equal 18446744073709551615, Grains.#{case.property}!"} table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/hamming/.meta/spec_generator.moon b/exercises/practice/hamming/.meta/spec_generator.moon index 239d03a..27a58b4 100644 --- a/exercises/practice/hamming/.meta/spec_generator.moon +++ b/exercises/practice/hamming/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: "hamming", generate_test: (case, level) -> diff --git a/exercises/practice/hello-world/.meta/spec_generator.moon b/exercises/practice/hello-world/.meta/spec_generator.moon deleted file mode 100644 index 23f6bee..0000000 --- a/exercises/practice/hello-world/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'hello-world does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/high-scores/.meta/spec_generator.moon b/exercises/practice/high-scores/.meta/spec_generator.moon index 65386bb..162a87d 100644 --- a/exercises/practice/high-scores/.meta/spec_generator.moon +++ b/exercises/practice/high-scores/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, int_list from require 'spec_helpers' { module_name: 'HighScores', diff --git a/exercises/practice/house/.meta/spec_generator.moon b/exercises/practice/house/.meta/spec_generator.moon index c8d308d..ec4fec1 100644 --- a/exercises/practice/house/.meta/spec_generator.moon +++ b/exercises/practice/house/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, string_list from require 'spec_helpers' { module_name: 'House', diff --git a/exercises/practice/intergalactic-transmission/.meta/spec_generator.moon b/exercises/practice/intergalactic-transmission/.meta/spec_generator.moon index 8649640..0a5870e 100644 --- a/exercises/practice/intergalactic-transmission/.meta/spec_generator.moon +++ b/exercises/practice/intergalactic-transmission/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, quote, string_list from require 'spec_helpers' { module_imports: {'transmitSequence', 'decodeMessage'}, diff --git a/exercises/practice/isbn-verifier/.meta/spec_generator.moon b/exercises/practice/isbn-verifier/.meta/spec_generator.moon index f925e05..b2dae0c 100644 --- a/exercises/practice/isbn-verifier/.meta/spec_generator.moon +++ b/exercises/practice/isbn-verifier/.meta/spec_generator.moon @@ -1,5 +1,8 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Isbn10', generate_test: (case, level) -> - indent "assert.is_#{case.expected} Isbn10.is_valid #{quote case.input.isbn}", level + line = "assert.is_#{case.expected} Isbn10.is_valid #{quote case.input.isbn}" + indent line, level } diff --git a/exercises/practice/isogram/.meta/spec_generator.moon b/exercises/practice/isogram/.meta/spec_generator.moon index 8fd7011..f9bbf48 100644 --- a/exercises/practice/isogram/.meta/spec_generator.moon +++ b/exercises/practice/isogram/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'is_isogram'}, generate_test: (case, level) -> diff --git a/exercises/practice/kindergarten-garden/.meta/spec_generator.moon b/exercises/practice/kindergarten-garden/.meta/spec_generator.moon deleted file mode 100644 index 87d399e..0000000 --- a/exercises/practice/kindergarten-garden/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'kindergarten-garden does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/knapsack/.meta/spec_generator.moon b/exercises/practice/knapsack/.meta/spec_generator.moon index d688204..ca824b6 100644 --- a/exercises/practice/knapsack/.meta/spec_generator.moon +++ b/exercises/practice/knapsack/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import table_list from require 'test_helpers' +import indent, table_list from require 'spec_helpers' { module_imports: {'maximumValue'}, diff --git a/exercises/practice/knapsack/knapsack_spec.moon b/exercises/practice/knapsack/knapsack_spec.moon index 3f92024..a4e4060 100644 --- a/exercises/practice/knapsack/knapsack_spec.moon +++ b/exercises/practice/knapsack/knapsack_spec.moon @@ -8,18 +8,18 @@ describe 'knapsack:', -> assert.are.equal 0, result pending 'one item, too heavy', -> - items = {{weight: 100, value: 1}} + items = {{value: 1, weight: 100}} maxWeight = 10 result = maximumValue maxWeight, items assert.are.equal 0, result pending 'five items (cannot be greedy by weight)', -> items = { - {weight: 2, value: 5}, - {weight: 2, value: 5}, - {weight: 2, value: 5}, - {weight: 2, value: 5}, - {weight: 10, value: 21}, + {value: 5, weight: 2}, + {value: 5, weight: 2}, + {value: 5, weight: 2}, + {value: 5, weight: 2}, + {value: 21, weight: 10}, } maxWeight = 10 result = maximumValue maxWeight, items @@ -27,11 +27,11 @@ describe 'knapsack:', -> pending 'five items (cannot be greedy by value)', -> items = { - {weight: 2, value: 20}, - {weight: 2, value: 20}, - {weight: 2, value: 20}, - {weight: 2, value: 20}, - {weight: 10, value: 50}, + {value: 20, weight: 2}, + {value: 20, weight: 2}, + {value: 20, weight: 2}, + {value: 20, weight: 2}, + {value: 50, weight: 10}, } maxWeight = 10 result = maximumValue maxWeight, items @@ -39,10 +39,10 @@ describe 'knapsack:', -> pending 'example knapsack', -> items = { - {weight: 5, value: 10}, - {weight: 4, value: 40}, - {weight: 6, value: 30}, - {weight: 4, value: 50}, + {value: 10, weight: 5}, + {value: 40, weight: 4}, + {value: 30, weight: 6}, + {value: 50, weight: 4}, } maxWeight = 10 result = maximumValue maxWeight, items @@ -50,14 +50,14 @@ describe 'knapsack:', -> pending '8 items', -> items = { - {weight: 25, value: 350}, - {weight: 35, value: 400}, - {weight: 45, value: 450}, - {weight: 5, value: 20}, - {weight: 25, value: 70}, - {weight: 3, value: 8}, - {weight: 2, value: 5}, - {weight: 2, value: 5}, + {value: 350, weight: 25}, + {value: 400, weight: 35}, + {value: 450, weight: 45}, + {value: 20, weight: 5}, + {value: 70, weight: 25}, + {value: 8, weight: 3}, + {value: 5, weight: 2}, + {value: 5, weight: 2}, } maxWeight = 104 result = maximumValue maxWeight, items @@ -65,21 +65,21 @@ describe 'knapsack:', -> pending '15 items', -> items = { - {weight: 70, value: 135}, - {weight: 73, value: 139}, - {weight: 77, value: 149}, - {weight: 80, value: 150}, - {weight: 82, value: 156}, - {weight: 87, value: 163}, - {weight: 90, value: 173}, - {weight: 94, value: 184}, - {weight: 98, value: 192}, - {weight: 106, value: 201}, - {weight: 110, value: 210}, - {weight: 113, value: 214}, - {weight: 115, value: 221}, - {weight: 118, value: 229}, - {weight: 120, value: 240}, + {value: 135, weight: 70}, + {value: 139, weight: 73}, + {value: 149, weight: 77}, + {value: 150, weight: 80}, + {value: 156, weight: 82}, + {value: 163, weight: 87}, + {value: 173, weight: 90}, + {value: 184, weight: 94}, + {value: 192, weight: 98}, + {value: 201, weight: 106}, + {value: 210, weight: 110}, + {value: 214, weight: 113}, + {value: 221, weight: 115}, + {value: 229, weight: 118}, + {value: 240, weight: 120}, } maxWeight = 750 result = maximumValue maxWeight, items diff --git a/exercises/practice/largest-series-product/.meta/spec_generator.moon b/exercises/practice/largest-series-product/.meta/spec_generator.moon index f07afb0..70ed8d1 100644 --- a/exercises/practice/largest-series-product/.meta/spec_generator.moon +++ b/exercises/practice/largest-series-product/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'largest_product'}, diff --git a/exercises/practice/leap/.meta/spec_generator.moon b/exercises/practice/leap/.meta/spec_generator.moon index 10bdd86..215ab4f 100644 --- a/exercises/practice/leap/.meta/spec_generator.moon +++ b/exercises/practice/leap/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'is_leap_year', generate_test: (case, level) -> diff --git a/exercises/practice/line-up/.meta/spec_generator.moon b/exercises/practice/line-up/.meta/spec_generator.moon index 021f5f8..f3e1f70 100644 --- a/exercises/practice/line-up/.meta/spec_generator.moon +++ b/exercises/practice/line-up/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'LineUp', diff --git a/exercises/practice/linked-list/.meta/spec_generator.moon b/exercises/practice/linked-list/.meta/spec_generator.moon index f82bb6e..c1dc0a5 100644 --- a/exercises/practice/linked-list/.meta/spec_generator.moon +++ b/exercises/practice/linked-list/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'LinkedList', diff --git a/exercises/practice/luhn/.meta/spec_generator.moon b/exercises/practice/luhn/.meta/spec_generator.moon index 56bc522..f583dad 100644 --- a/exercises/practice/luhn/.meta/spec_generator.moon +++ b/exercises/practice/luhn/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Luhn', diff --git a/exercises/practice/markdown/.meta/spec_generator.moon b/exercises/practice/markdown/.meta/spec_generator.moon index 5c5f6e1..88147b1 100644 --- a/exercises/practice/markdown/.meta/spec_generator.moon +++ b/exercises/practice/markdown/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import json_string from require 'test_helpers' +import indent, quote, json_string from require 'spec_helpers' { module_name: 'Markdown', diff --git a/exercises/practice/matching-brackets/.meta/spec_generator.moon b/exercises/practice/matching-brackets/.meta/spec_generator.moon index 46052d3..c101852 100644 --- a/exercises/practice/matching-brackets/.meta/spec_generator.moon +++ b/exercises/practice/matching-brackets/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'is_paired'}, generate_test: (case, level) -> diff --git a/exercises/practice/matrix/.meta/spec_generator.moon b/exercises/practice/matrix/.meta/spec_generator.moon index 467ed8f..77a8940 100644 --- a/exercises/practice/matrix/.meta/spec_generator.moon +++ b/exercises/practice/matrix/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import json_string, int_list from require 'test_helpers' +import indent, json_string, int_list from require 'spec_helpers' { module_name: 'Matrix', diff --git a/exercises/practice/meetup/.meta/spec_generator.moon b/exercises/practice/meetup/.meta/spec_generator.moon index f2acca7..0575d20 100644 --- a/exercises/practice/meetup/.meta/spec_generator.moon +++ b/exercises/practice/meetup/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import table_tostring_ordered from require 'test_helpers' +import indent, quote, table_tostring_ordered from require 'spec_helpers' keys = {'year', 'month', 'week', 'dayofweek'} { diff --git a/exercises/practice/micro-blog/.meta/spec_generator.moon b/exercises/practice/micro-blog/.meta/spec_generator.moon index 12f5c00..d7a1416 100644 --- a/exercises/practice/micro-blog/.meta/spec_generator.moon +++ b/exercises/practice/micro-blog/.meta/spec_generator.moon @@ -1,9 +1,11 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'MicroBlog', generate_test: (case, level) -> lines = { - "result = MicroBlog.#{case.property} '#{case.input.phrase}'", - "assert.are.equal '#{case.expected}', result" + "result = MicroBlog.#{case.property} #{quote case.input.phrase}", + "assert.are.equal #{quote case.expected}, result" } table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/nth-prime/.meta/spec_generator.moon b/exercises/practice/nth-prime/.meta/spec_generator.moon index d9dfd56..dc5ad84 100644 --- a/exercises/practice/nth-prime/.meta/spec_generator.moon +++ b/exercises/practice/nth-prime/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'prime'}, diff --git a/exercises/practice/nucleotide-count/.meta/spec_generator.moon b/exercises/practice/nucleotide-count/.meta/spec_generator.moon index 2b89cc2..26be50a 100644 --- a/exercises/practice/nucleotide-count/.meta/spec_generator.moon +++ b/exercises/practice/nucleotide-count/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import table_tostring_ordered from require 'test_helpers' +import indent, table_tostring_ordered from require 'spec_helpers' { module_name: 'nucleotide_count', diff --git a/exercises/practice/palindrome-products/.meta/spec_generator.moon b/exercises/practice/palindrome-products/.meta/spec_generator.moon index 6fdb38a..ccdd4e3 100644 --- a/exercises/practice/palindrome-products/.meta/spec_generator.moon +++ b/exercises/practice/palindrome-products/.meta/spec_generator.moon @@ -1,6 +1,10 @@ -import int_list, int_lists from require 'test_helpers' +import indent + quote + is_json_null + int_lists + from require 'spec_helpers' -value = (val) -> +value = (val) -> if is_json_null val nil else diff --git a/exercises/practice/pangram/.meta/spec_generator.moon b/exercises/practice/pangram/.meta/spec_generator.moon index b71fdea..44f0f68 100644 --- a/exercises/practice/pangram/.meta/spec_generator.moon +++ b/exercises/practice/pangram/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'is_pangram', generate_test: (case, level) -> diff --git a/exercises/practice/pascals-triangle/.meta/spec_generator.moon b/exercises/practice/pascals-triangle/.meta/spec_generator.moon index 7d7095e..0b5e341 100644 --- a/exercises/practice/pascals-triangle/.meta/spec_generator.moon +++ b/exercises/practice/pascals-triangle/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_lists from require 'test_helpers' +import indent, int_lists from require 'spec_helpers' { module_name: 'PascalsTriangle', diff --git a/exercises/practice/perfect-numbers/.meta/spec_generator.moon b/exercises/practice/perfect-numbers/.meta/spec_generator.moon index ef2f14c..c25cac7 100644 --- a/exercises/practice/perfect-numbers/.meta/spec_generator.moon +++ b/exercises/practice/perfect-numbers/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'classify'}, diff --git a/exercises/practice/phone-number/.meta/spec_generator.moon b/exercises/practice/phone-number/.meta/spec_generator.moon index 6c369e0..07ce7ef 100644 --- a/exercises/practice/phone-number/.meta/spec_generator.moon +++ b/exercises/practice/phone-number/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'clean'}, diff --git a/exercises/practice/pig-latin/.meta/spec_generator.moon b/exercises/practice/pig-latin/.meta/spec_generator.moon index 03e3332..4a23d01 100644 --- a/exercises/practice/pig-latin/.meta/spec_generator.moon +++ b/exercises/practice/pig-latin/.meta/spec_generator.moon @@ -1,6 +1,11 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'translate'}, generate_test: (case, level) -> - body = "assert.are.equal #{quote case.expected}, translate #{quote case.input.phrase}" - indent body, level + lines = { + "result = translate #{quote case.input.phrase}" + "assert.are.equal #{quote case.expected}, result" + } + table.concat [indent line, level for line in *lines], "\n" } diff --git a/exercises/practice/pig-latin/pig_latin_spec.moon b/exercises/practice/pig-latin/pig_latin_spec.moon index dd8e8ab..a90b65d 100644 --- a/exercises/practice/pig-latin/pig_latin_spec.moon +++ b/exercises/practice/pig-latin/pig_latin_spec.moon @@ -3,75 +3,98 @@ import translate from require 'pig_latin' describe 'pig-latin:', -> describe 'ay is added to words that start with vowels:', -> it 'word beginning with a', -> - assert.are.equal 'appleay', translate 'apple' + result = translate 'apple' + assert.are.equal 'appleay', result pending 'word beginning with e', -> - assert.are.equal 'earay', translate 'ear' + result = translate 'ear' + assert.are.equal 'earay', result pending 'word beginning with i', -> - assert.are.equal 'iglooay', translate 'igloo' + result = translate 'igloo' + assert.are.equal 'iglooay', result pending 'word beginning with o', -> - assert.are.equal 'objectay', translate 'object' + result = translate 'object' + assert.are.equal 'objectay', result pending 'word beginning with u', -> - assert.are.equal 'underay', translate 'under' + result = translate 'under' + assert.are.equal 'underay', result pending 'word beginning with a vowel and followed by a qu', -> - assert.are.equal 'equalay', translate 'equal' + result = translate 'equal' + assert.are.equal 'equalay', result describe 'first letter and ay are moved to the end of words that start with consonants:', -> pending 'word beginning with p', -> - assert.are.equal 'igpay', translate 'pig' + result = translate 'pig' + assert.are.equal 'igpay', result pending 'word beginning with k', -> - assert.are.equal 'oalakay', translate 'koala' + result = translate 'koala' + assert.are.equal 'oalakay', result pending 'word beginning with x', -> - assert.are.equal 'enonxay', translate 'xenon' + result = translate 'xenon' + assert.are.equal 'enonxay', result pending 'word beginning with q without a following u', -> - assert.are.equal 'atqay', translate 'qat' + result = translate 'qat' + assert.are.equal 'atqay', result pending 'word beginning with consonant and vowel containing qu', -> - assert.are.equal 'iquidlay', translate 'liquid' + result = translate 'liquid' + assert.are.equal 'iquidlay', result describe 'some letter clusters are treated like a single consonant:', -> pending 'word beginning with ch', -> - assert.are.equal 'airchay', translate 'chair' + result = translate 'chair' + assert.are.equal 'airchay', result pending 'word beginning with qu', -> - assert.are.equal 'eenquay', translate 'queen' + result = translate 'queen' + assert.are.equal 'eenquay', result pending 'word beginning with qu and a preceding consonant', -> - assert.are.equal 'aresquay', translate 'square' + result = translate 'square' + assert.are.equal 'aresquay', result pending 'word beginning with th', -> - assert.are.equal 'erapythay', translate 'therapy' + result = translate 'therapy' + assert.are.equal 'erapythay', result pending 'word beginning with thr', -> - assert.are.equal 'ushthray', translate 'thrush' + result = translate 'thrush' + assert.are.equal 'ushthray', result pending 'word beginning with sch', -> - assert.are.equal 'oolschay', translate 'school' + result = translate 'school' + assert.are.equal 'oolschay', result describe 'some letter clusters are treated like a single vowel:', -> pending 'word beginning with yt', -> - assert.are.equal 'yttriaay', translate 'yttria' + result = translate 'yttria' + assert.are.equal 'yttriaay', result pending 'word beginning with xr', -> - assert.are.equal 'xrayay', translate 'xray' + result = translate 'xray' + assert.are.equal 'xrayay', result describe 'position of y in a word determines if it is a consonant or a vowel:', -> pending 'y is treated like a consonant at the beginning of a word', -> - assert.are.equal 'ellowyay', translate 'yellow' + result = translate 'yellow' + assert.are.equal 'ellowyay', result pending 'y is treated like a vowel at the end of a consonant cluster', -> - assert.are.equal 'ythmrhay', translate 'rhythm' + result = translate 'rhythm' + assert.are.equal 'ythmrhay', result pending 'y as second letter in two letter word', -> - assert.are.equal 'ymay', translate 'my' + result = translate 'my' + assert.are.equal 'ymay', result describe 'phrases are translated:', -> pending 'a whole phrase', -> - assert.are.equal 'ickquay astfay unray', translate 'quick fast run' + result = translate 'quick fast run' + assert.are.equal 'ickquay astfay unray', result diff --git a/exercises/practice/prime-factors/.meta/spec_generator.moon b/exercises/practice/prime-factors/.meta/spec_generator.moon index 1432edc..6c03462 100644 --- a/exercises/practice/prime-factors/.meta/spec_generator.moon +++ b/exercises/practice/prime-factors/.meta/spec_generator.moon @@ -1,9 +1,11 @@ +import indent, int_list from require 'spec_helpers' + { module_imports: {'factors'}, generate_test: (case, level) -> lines = { - "expected = {#{table.concat case.expected, ', '}}", "result = factors #{case.input.value}", + "expected = #{int_list case.expected}", "assert.are.same expected, result" } table.concat [indent line, level for line in *lines], '\n' diff --git a/exercises/practice/prime-factors/prime_factors_spec.moon b/exercises/practice/prime-factors/prime_factors_spec.moon index e7189d6..4aab619 100644 --- a/exercises/practice/prime-factors/prime_factors_spec.moon +++ b/exercises/practice/prime-factors/prime_factors_spec.moon @@ -2,61 +2,61 @@ import factors from require 'prime_factors' describe 'prime-factors:', -> it 'no factors', -> - expected = {} result = factors 1 + expected = {} assert.are.same expected, result pending 'prime number', -> - expected = {2} result = factors 2 + expected = {2} assert.are.same expected, result pending 'another prime number', -> - expected = {3} result = factors 3 + expected = {3} assert.are.same expected, result pending 'square of a prime', -> - expected = {3, 3} result = factors 9 + expected = {3, 3} assert.are.same expected, result pending 'product of first prime', -> - expected = {2, 2} result = factors 4 + expected = {2, 2} assert.are.same expected, result pending 'cube of a prime', -> - expected = {2, 2, 2} result = factors 8 + expected = {2, 2, 2} assert.are.same expected, result pending 'product of second prime', -> - expected = {3, 3, 3} result = factors 27 + expected = {3, 3, 3} assert.are.same expected, result pending 'product of third prime', -> - expected = {5, 5, 5, 5} result = factors 625 + expected = {5, 5, 5, 5} assert.are.same expected, result pending 'product of first and second prime', -> - expected = {2, 3} result = factors 6 + expected = {2, 3} assert.are.same expected, result pending 'product of primes and non-primes', -> - expected = {2, 2, 3} result = factors 12 + expected = {2, 2, 3} assert.are.same expected, result pending 'product of primes', -> - expected = {5, 17, 23, 461} result = factors 901255 + expected = {5, 17, 23, 461} assert.are.same expected, result pending 'factors include a large prime', -> - expected = {11, 9539, 894119} result = factors 93819012551 + expected = {11, 9539, 894119} assert.are.same expected, result diff --git a/exercises/practice/prism/.meta/spec_generator.moon b/exercises/practice/prism/.meta/spec_generator.moon index 7da422f..90b7b34 100644 --- a/exercises/practice/prism/.meta/spec_generator.moon +++ b/exercises/practice/prism/.meta/spec_generator.moon @@ -1,3 +1,12 @@ +import indent from require 'spec_helpers' + +prism = (p) -> "{id: #{p.id}, x: #{p.x}, y: #{p.y}, angle: #{p.angle}}" +prism_list = (ps, level) -> + lines = {"{"} + table.insert lines, indent "#{prism p}", level + 1 for p in *ps + table.insert lines, indent "}", level + table.concat lines, "\n" + { module_name: 'Prism' @@ -9,14 +18,11 @@ if #case.input.prisms == 0 table.insert lines, "prisms = {}" else - table.insert(lines, "prisms = {") - for p in *case.input.prisms - table.insert(lines, " {id: #{p.id}, x: #{p.x}, y: #{p.y}, angle: #{p.angle}}") - table.insert(lines, "}") + table.insert lines, "prisms = #{prism_list case.input.prisms, level}" - table.insert(lines, "expected = {#{table.concat(case.expected.sequence, ', ')}}") - table.insert(lines, "result = Prism.#{case.property} start, prisms") - table.insert(lines, "assert.are.same expected, result") + table.insert lines, "expected = {#{table.concat(case.expected.sequence, ', ')}}" + table.insert lines, "result = Prism.#{case.property} start, prisms" + table.insert lines, "assert.are.same expected, result" table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/protein-translation/.meta/spec_generator.moon b/exercises/practice/protein-translation/.meta/spec_generator.moon index 46d1907..aaef739 100644 --- a/exercises/practice/protein-translation/.meta/spec_generator.moon +++ b/exercises/practice/protein-translation/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' { module_imports: {'proteins'}, diff --git a/exercises/practice/proverb/.meta/spec_generator.moon b/exercises/practice/proverb/.meta/spec_generator.moon index 12a41ab..5c2023e 100644 --- a/exercises/practice/proverb/.meta/spec_generator.moon +++ b/exercises/practice/proverb/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, is_empty, word_list from require 'spec_helpers' { module_name: 'recite', diff --git a/exercises/practice/pythagorean-triplet/.meta/spec_generator.moon b/exercises/practice/pythagorean-triplet/.meta/spec_generator.moon index aebd1d8..2cb1af0 100644 --- a/exercises/practice/pythagorean-triplet/.meta/spec_generator.moon +++ b/exercises/practice/pythagorean-triplet/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_lists from require 'test_helpers' +import indent, int_lists from require 'spec_helpers' { module_imports: {'triplets_with_sum'}, diff --git a/exercises/practice/queen-attack/.meta/spec_generator.moon b/exercises/practice/queen-attack/.meta/spec_generator.moon index 3f9f7b6..d625eef 100644 --- a/exercises/practice/queen-attack/.meta/spec_generator.moon +++ b/exercises/practice/queen-attack/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'Queen', test_helpers: [[ diff --git a/exercises/practice/rail-fence-cipher/.meta/spec_generator.moon b/exercises/practice/rail-fence-cipher/.meta/spec_generator.moon index ea760a6..5057b78 100644 --- a/exercises/practice/rail-fence-cipher/.meta/spec_generator.moon +++ b/exercises/practice/rail-fence-cipher/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'RailFenceCipher', diff --git a/exercises/practice/raindrops/.meta/spec_generator.moon b/exercises/practice/raindrops/.meta/spec_generator.moon index 7668071..c31b045 100644 --- a/exercises/practice/raindrops/.meta/spec_generator.moon +++ b/exercises/practice/raindrops/.meta/spec_generator.moon @@ -1,9 +1,11 @@ +import indent, quote from require 'spec_helpers' + { module_name: "raindrops", generate_test: (case, level) -> lines = { "result = raindrops #{case.input.number}" - "assert.are.equal '#{case.expected}', result" + "assert.are.equal #{quote case.expected}, result" } - table.concat [string.rep(' ', level) .. line for line in *lines], '\n' + table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/rational-numbers/.meta/spec_generator.moon b/exercises/practice/rational-numbers/.meta/spec_generator.moon index 080c9e7..cf62ff9 100644 --- a/exercises/practice/rational-numbers/.meta/spec_generator.moon +++ b/exercises/practice/rational-numbers/.meta/spec_generator.moon @@ -1,24 +1,8 @@ -import int_list from require 'test_helpers' +import indent, int_list from require 'spec_helpers' { module_name: 'rational', - test_helpers: [[ - -- ---------------------------------------- - -- Why do we need to test "approximately equal"? - -- See https://0.30000000000000004.com - epsilon = 1e-9 - is_close_to = (state, arguments) -> - {a, b} = arguments - math.abs(a - b) <= epsilon - - say = require 'say' - say\set 'assertion.approx_equal.positive', "Expected %s and %s to be within #{epsilon}" - say\set 'assertion.approx_equal.negative', "Expected %s and %s not to be within #{epsilon}" - assert\register 'assertion', 'approx_equal', is_close_to, 'assertion.approx_equal.positive', 'assertion.approx_equal.negative' - -- ---------------------------------------- -]] - generate_test: (case, level) -> local lines @@ -42,7 +26,7 @@ import int_list from require 'test_helpers' when 'expreal' lines = { "result = rational.#{case.property} #{case.input.x}, #{int_list case.input.r}", - "assert.approx_equal #{case.expected}, result" + "assert.is.near #{case.expected}, result, 1e-6" } table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/rational-numbers/rational_numbers_spec.moon b/exercises/practice/rational-numbers/rational_numbers_spec.moon index d45f231..48592a1 100644 --- a/exercises/practice/rational-numbers/rational_numbers_spec.moon +++ b/exercises/practice/rational-numbers/rational_numbers_spec.moon @@ -1,20 +1,6 @@ rational = require 'rational_numbers' describe 'rational-numbers:', -> - -- ---------------------------------------- - -- Why do we need to test "approximately equal"? - -- See https://0.30000000000000004.com - epsilon = 1e-9 - is_close_to = (state, arguments) -> - {a, b} = arguments - math.abs(a - b) <= epsilon - - say = require 'say' - say\set 'assertion.approx_equal.positive', "Expected %s and %s to be within #{epsilon}" - say\set 'assertion.approx_equal.negative', "Expected %s and %s not to be within #{epsilon}" - assert\register 'assertion', 'approx_equal', is_close_to, 'assertion.approx_equal.positive', 'assertion.approx_equal.negative' - -- ---------------------------------------- - describe 'Arithmetic:', -> describe 'Addition:', -> it 'Add two positive rational numbers', -> @@ -175,15 +161,15 @@ describe 'rational-numbers:', -> describe 'Exponentiation of a real number to a rational number:', -> pending 'Raise a real number to a positive rational number', -> result = rational.expreal 8, {4, 3} - assert.approx_equal 16.0, result + assert.is.near 16.0, result, 1e-6 pending 'Raise a real number to a negative rational number', -> result = rational.expreal 9, {-1, 2} - assert.approx_equal 0.33333333333333, result + assert.is.near 0.33333333333333, result, 1e-6 pending 'Raise a real number to a zero rational number', -> result = rational.expreal 2, {0, 1} - assert.approx_equal 1.0, result + assert.is.near 1.0, result, 1e-6 describe 'Reduction to lowest terms:', -> pending 'Reduce a positive rational number to lowest terms', -> diff --git a/exercises/practice/react/.meta/spec_generator.moon b/exercises/practice/react/.meta/spec_generator.moon deleted file mode 100644 index d477f33..0000000 --- a/exercises/practice/react/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'react does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/rectangles/.meta/spec_generator.moon b/exercises/practice/rectangles/.meta/spec_generator.moon index ab9a797..5dfbdd1 100644 --- a/exercises/practice/rectangles/.meta/spec_generator.moon +++ b/exercises/practice/rectangles/.meta/spec_generator.moon @@ -1,5 +1,4 @@ -test_helpers = require 'test_helpers' -import string_list from test_helpers +import indent, string_list from require 'spec_helpers' { module_imports: {'rectangles'}, diff --git a/exercises/practice/resistor-color-duo/.meta/spec_generator.moon b/exercises/practice/resistor-color-duo/.meta/spec_generator.moon index 8b8b106..29345fb 100644 --- a/exercises/practice/resistor-color-duo/.meta/spec_generator.moon +++ b/exercises/practice/resistor-color-duo/.meta/spec_generator.moon @@ -1,7 +1,9 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'ResistorColorDuo', generate_test: (case, level) -> - input = ["'#{color}'" for color in *case.input.colors] + input = [quote color for color in *case.input.colors] lines = { "result = ResistorColorDuo.value #{table.concat input, ', '}", "assert.are.equal #{case.expected}, result" diff --git a/exercises/practice/resistor-color-trio/.meta/spec_generator.moon b/exercises/practice/resistor-color-trio/.meta/spec_generator.moon index e4f5a67..6ed7bca 100644 --- a/exercises/practice/resistor-color-trio/.meta/spec_generator.moon +++ b/exercises/practice/resistor-color-trio/.meta/spec_generator.moon @@ -1,10 +1,14 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'ResistorColorTrio', generate_test: (case, level) -> + colors = table.concat [quote color for color in *case.input.colors], ', ' + expected = quote "#{case.expected.value} #{case.expected.unit}" lines = { - "result = ResistorColorTrio.#{case.property} #{table.concat [quote color for color in *case.input.colors], ', '}", - "assert.are.equal '#{case.expected.value} #{case.expected.unit}', result" + "result = ResistorColorTrio.#{case.property} #{colors}", + "assert.are.equal #{expected}, result" } table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/resistor-color/.meta/spec_generator.moon b/exercises/practice/resistor-color/.meta/spec_generator.moon index 87c7966..9ba12e2 100644 --- a/exercises/practice/resistor-color/.meta/spec_generator.moon +++ b/exercises/practice/resistor-color/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'ResistorColor', @@ -5,7 +7,7 @@ local lines if case.property == "colorCode" lines = { - "result = ResistorColor.color_code '#{case.input.color}'", + "result = ResistorColor.color_code #{quote case.input.color}", "assert.are.equal #{case.expected}, result" } else @@ -15,7 +17,7 @@ "assert.are.same expected, result" } - table.concat [indent(line, level) for line in *lines], '\n' + table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/rest-api/.meta/spec_generator.moon b/exercises/practice/rest-api/.meta/spec_generator.moon index 048ef0b..46d6519 100644 --- a/exercises/practice/rest-api/.meta/spec_generator.moon +++ b/exercises/practice/rest-api/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import table_dump from require 'test_helpers' +import indent, quote, table_dump from require 'spec_helpers' { module_name: 'RestApi', diff --git a/exercises/practice/rest-api/rest_api_spec.moon b/exercises/practice/rest-api/rest_api_spec.moon index e6eed4f..f5813ca 100644 --- a/exercises/practice/rest-api/rest_api_spec.moon +++ b/exercises/practice/rest-api/rest_api_spec.moon @@ -25,25 +25,25 @@ describe 'rest-api:', -> } result = api\POST '/add', payload expected = { - balance: 0.0 + name: "Adam" owes: {} owed_by: {} - name: "Adam" + balance: 0.0 } assert.are.same expected, result pending 'get single user', -> database = { users: {{ - balance: 0.0 + name: "Adam" owes: {} owed_by: {} - name: "Adam" - }, { balance: 0.0 + }, { + name: "Bob" owes: {} owed_by: {} - name: "Bob" + balance: 0.0 }} } api = RestApi database @@ -53,10 +53,10 @@ describe 'rest-api:', -> result = api\GET '/users', payload expected = { users: {{ - balance: 0.0 + name: "Bob" owes: {} owed_by: {} - name: "Bob" + balance: 0.0 }} } assert.are.same expected, result @@ -65,39 +65,39 @@ describe 'rest-api:', -> pending 'both users have 0 balance', -> database = { users: {{ - balance: 0.0 + name: "Adam" owes: {} owed_by: {} - name: "Adam" - }, { balance: 0.0 + }, { + name: "Bob" owes: {} owed_by: {} - name: "Bob" + balance: 0.0 }} } api = RestApi database payload = { - amount: 3.0 borrower: "Bob" lender: "Adam" + amount: 3.0 } result = api\POST '/iou', payload expected = { users: {{ - balance: 3.0 + name: "Adam" owes: {} owed_by: { Bob: 3.0 } - name: "Adam" + balance: 3.0 }, { - balance: -3.0 + name: "Bob" owes: { Adam: 3.0 } owed_by: {} - name: "Bob" + balance: -3.0 }} } assert.are.same expected, result @@ -105,49 +105,49 @@ describe 'rest-api:', -> pending 'borrower has negative balance', -> database = { users: {{ - balance: 0.0 + name: "Adam" owes: {} owed_by: {} - name: "Adam" + balance: 0.0 }, { - balance: -3.0 + name: "Bob" owes: { Chuck: 3.0 } owed_by: {} - name: "Bob" + balance: -3.0 }, { - balance: 3.0 + name: "Chuck" owes: {} owed_by: { Bob: 3.0 } - name: "Chuck" + balance: 3.0 }} } api = RestApi database payload = { - amount: 3.0 borrower: "Bob" lender: "Adam" + amount: 3.0 } result = api\POST '/iou', payload expected = { users: {{ - balance: 3.0 + name: "Adam" owes: {} owed_by: { Bob: 3.0 } - name: "Adam" + balance: 3.0 }, { - balance: -6.0 + name: "Bob" owes: { Chuck: 3.0 Adam: 3.0 } owed_by: {} - name: "Bob" + balance: -6.0 }} } assert.are.same expected, result @@ -155,50 +155,50 @@ describe 'rest-api:', -> pending 'lender has negative balance', -> database = { users: {{ - balance: 0.0 + name: "Adam" owes: {} owed_by: {} - name: "Adam" + balance: 0.0 }, { - balance: -3.0 + name: "Bob" owes: { Chuck: 3.0 } owed_by: {} - name: "Bob" + balance: -3.0 }, { - balance: 3.0 + name: "Chuck" owes: {} owed_by: { Bob: 3.0 } - name: "Chuck" + balance: 3.0 }} } api = RestApi database payload = { - amount: 3.0 borrower: "Adam" lender: "Bob" + amount: 3.0 } result = api\POST '/iou', payload expected = { users: {{ - balance: -3.0 + name: "Adam" owes: { Bob: 3.0 } owed_by: {} - name: "Adam" + balance: -3.0 }, { - balance: 0.0 + name: "Bob" owes: { Chuck: 3.0 } owed_by: { Adam: 3.0 } - name: "Bob" + balance: 0.0 }} } assert.are.same expected, result @@ -206,43 +206,43 @@ describe 'rest-api:', -> pending 'lender owes borrower', -> database = { users: {{ - balance: -3.0 + name: "Adam" owes: { Bob: 3.0 } owed_by: {} - name: "Adam" + balance: -3.0 }, { - balance: 3.0 + name: "Bob" owes: {} owed_by: { Adam: 3.0 } - name: "Bob" + balance: 3.0 }} } api = RestApi database payload = { - amount: 2.0 borrower: "Bob" lender: "Adam" + amount: 2.0 } result = api\POST '/iou', payload expected = { users: {{ - balance: -1.0 + name: "Adam" owes: { Bob: 1.0 } owed_by: {} - name: "Adam" + balance: -1.0 }, { - balance: 1.0 + name: "Bob" owes: {} owed_by: { Adam: 1.0 } - name: "Bob" + balance: 1.0 }} } assert.are.same expected, result @@ -250,43 +250,43 @@ describe 'rest-api:', -> pending 'lender owes borrower less than new loan', -> database = { users: {{ - balance: -3.0 + name: "Adam" owes: { Bob: 3.0 } owed_by: {} - name: "Adam" + balance: -3.0 }, { - balance: 3.0 + name: "Bob" owes: {} owed_by: { Adam: 3.0 } - name: "Bob" + balance: 3.0 }} } api = RestApi database payload = { - amount: 4.0 borrower: "Bob" lender: "Adam" + amount: 4.0 } result = api\POST '/iou', payload expected = { users: {{ - balance: 1.0 + name: "Adam" owes: {} owed_by: { Bob: 1.0 } - name: "Adam" + balance: 1.0 }, { - balance: -1.0 + name: "Bob" owes: { Adam: 1.0 } owed_by: {} - name: "Bob" + balance: -1.0 }} } assert.are.same expected, result @@ -294,39 +294,39 @@ describe 'rest-api:', -> pending 'lender owes borrower same as new loan', -> database = { users: {{ - balance: -3.0 + name: "Adam" owes: { Bob: 3.0 } owed_by: {} - name: "Adam" + balance: -3.0 }, { - balance: 3.0 + name: "Bob" owes: {} owed_by: { Adam: 3.0 } - name: "Bob" + balance: 3.0 }} } api = RestApi database payload = { - amount: 3.0 borrower: "Bob" lender: "Adam" + amount: 3.0 } result = api\POST '/iou', payload expected = { users: {{ - balance: 0.0 + name: "Adam" owes: {} owed_by: {} - name: "Adam" - }, { balance: 0.0 + }, { + name: "Bob" owes: {} owed_by: {} - name: "Bob" + balance: 0.0 }} } assert.are.same expected, result diff --git a/exercises/practice/reverse-string/.meta/spec_generator.moon b/exercises/practice/reverse-string/.meta/spec_generator.moon index 34df15e..ff43e05 100644 --- a/exercises/practice/reverse-string/.meta/spec_generator.moon +++ b/exercises/practice/reverse-string/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'reverse', generate_test: (case, level) -> diff --git a/exercises/practice/rna-transcription/.meta/spec_generator.moon b/exercises/practice/rna-transcription/.meta/spec_generator.moon index 479e68b..eadfe35 100644 --- a/exercises/practice/rna-transcription/.meta/spec_generator.moon +++ b/exercises/practice/rna-transcription/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'to_rna', generate_test: (case, level) -> diff --git a/exercises/practice/robot-name/.meta/spec_generator.moon b/exercises/practice/robot-name/.meta/spec_generator.moon deleted file mode 100644 index ee2d191..0000000 --- a/exercises/practice/robot-name/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'robot-name does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/robot-name/robot_name_spec.moon b/exercises/practice/robot-name/robot_name_spec.moon index df686f2..1258e05 100644 --- a/exercises/practice/robot-name/robot_name_spec.moon +++ b/exercises/practice/robot-name/robot_name_spec.moon @@ -1,4 +1,9 @@ -import table_size from require './test_helpers' +-- because `#t` is insufficient for non-sequence tables +table_size = (t) -> + count = 0 + count += 1 for _ in pairs t + count + Robot = require 'robot_name' @@ -7,7 +12,7 @@ describe 'robot-name', -> it 'a robot has a name', -> robot = Robot! name = robot\name! - assert.is.match name, '^[A-Z][A-Z][0-9][0-9][0-9]$' + assert.matches '^[A-Z][A-Z][0-9][0-9][0-9]$', name pending 'name does not change', -> robot = Robot! diff --git a/exercises/practice/robot-name/test_helpers.moon b/exercises/practice/robot-name/test_helpers.moon deleted file mode 100644 index b2e0a0e..0000000 --- a/exercises/practice/robot-name/test_helpers.moon +++ /dev/null @@ -1,21 +0,0 @@ --- create a custom assertion: does a string match a pattern -assert = require 'luassert' -say = require 'say' - -match = (state, arguments) -> - {str, patt} = arguments - string.match str, patt - -say\set 'assertion.match.positive', 'Expected %s to match pattern %s.' -say\set 'assertion.match.negative', 'Expected %s not to match pattern %s.' -assert\register 'assertion', 'match', match, 'assertion.match.positive', 'assertion.match.negative' - - --- return the helper functions -{ - table_size: (t) -> - -- because `#t` is insufficient for non-sequence tables - count = 0 - count += 1 for _ in pairs t - count -} diff --git a/exercises/practice/robot-simulator/.meta/spec_generator.moon b/exercises/practice/robot-simulator/.meta/spec_generator.moon index 138919a..54e8b66 100644 --- a/exercises/practice/robot-simulator/.meta/spec_generator.moon +++ b/exercises/practice/robot-simulator/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Robot', diff --git a/exercises/practice/roman-numerals/.meta/spec_generator.moon b/exercises/practice/roman-numerals/.meta/spec_generator.moon index 06b46b0..3f64a5f 100644 --- a/exercises/practice/roman-numerals/.meta/spec_generator.moon +++ b/exercises/practice/roman-numerals/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'RomanNumerals', diff --git a/exercises/practice/rotational-cipher/.meta/spec_generator.moon b/exercises/practice/rotational-cipher/.meta/spec_generator.moon index 5c53ae0..c781542 100644 --- a/exercises/practice/rotational-cipher/.meta/spec_generator.moon +++ b/exercises/practice/rotational-cipher/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'RotationalCipher', diff --git a/exercises/practice/run-length-encoding/.meta/spec_generator.moon b/exercises/practice/run-length-encoding/.meta/spec_generator.moon index ccb83bf..37f1853 100644 --- a/exercises/practice/run-length-encoding/.meta/spec_generator.moon +++ b/exercises/practice/run-length-encoding/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'encode', 'decode'}, diff --git a/exercises/practice/saddle-points/.meta/spec_generator.moon b/exercises/practice/saddle-points/.meta/spec_generator.moon index 330f7b9..80d6a6a 100644 --- a/exercises/practice/saddle-points/.meta/spec_generator.moon +++ b/exercises/practice/saddle-points/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_lists, table_tostring_ordered from require 'test_helpers' +import indent, int_lists from require 'spec_helpers' result_obj = (obj) -> "{row: #{obj.row}, column: #{obj.column}}" result_list = (list) -> "{#{table.concat [result_obj obj for obj in *list], ', '}}" @@ -7,7 +7,7 @@ result_list = (list) -> "{#{table.concat [result_obj obj for obj in *list], ', ' module_imports: {'saddle_points'}, test_helpers: [[ - cmp_saddle_points = (a, b) -> + compare_saddle_points = (a, b) -> a.row < b.row or (a.row == b.row and a.column < b.column) ]] @@ -16,8 +16,8 @@ result_list = (list) -> "{#{table.concat [result_obj obj for obj in *list], ', ' "matrix = #{int_lists case.input.matrix, level}", "result = saddle_points matrix" "expected = #{result_list case.expected}", - "table.sort result, cmp_saddle_points", - "table.sort expected, cmp_saddle_points", + "table.sort result, compare_saddle_points", + "table.sort expected, compare_saddle_points", "assert.are.same expected, result" } table.concat [indent line, level for line in *lines], '\n' diff --git a/exercises/practice/saddle-points/saddle_points_spec.moon b/exercises/practice/saddle-points/saddle_points_spec.moon index 5b9d907..d474d1e 100644 --- a/exercises/practice/saddle-points/saddle_points_spec.moon +++ b/exercises/practice/saddle-points/saddle_points_spec.moon @@ -1,7 +1,7 @@ import saddle_points from require 'saddle_points' describe 'saddle-points:', -> - cmp_saddle_points = (a, b) -> + compare_saddle_points = (a, b) -> a.row < b.row or (a.row == b.row and a.column < b.column) it 'Can identify single saddle point', -> @@ -12,16 +12,16 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {{row: 2, column: 1}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify that empty matrix has no saddle points', -> matrix = {{}} result = saddle_points matrix expected = {} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify lack of saddle points when there are none', -> @@ -32,8 +32,8 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify multiple saddle points in a column', -> @@ -44,8 +44,8 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {{row: 1, column: 2}, {row: 2, column: 2}, {row: 3, column: 2}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify multiple saddle points in a row', -> @@ -56,8 +56,8 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {{row: 2, column: 1}, {row: 2, column: 2}, {row: 2, column: 3}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify saddle point in bottom right corner', -> @@ -68,8 +68,8 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {{row: 3, column: 3}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify saddle points in a non square matrix', -> @@ -79,8 +79,8 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {{row: 1, column: 3}, {row: 1, column: 1}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify that saddle points in a single column matrix are those with the minimum value', -> @@ -92,14 +92,14 @@ describe 'saddle-points:', -> } result = saddle_points matrix expected = {{row: 2, column: 1}, {row: 4, column: 1}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result pending 'Can identify that saddle points in a single row matrix are those with the maximum value', -> matrix = {{2, 5, 3, 5}} result = saddle_points matrix expected = {{row: 1, column: 2}, {row: 1, column: 4}} - table.sort result, cmp_saddle_points - table.sort expected, cmp_saddle_points + table.sort result, compare_saddle_points + table.sort expected, compare_saddle_points assert.are.same expected, result diff --git a/exercises/practice/satellite/.meta/spec_generator.moon b/exercises/practice/satellite/.meta/spec_generator.moon deleted file mode 100644 index 3e675ed..0000000 --- a/exercises/practice/satellite/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'satellite does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/say/.meta/spec_generator.moon b/exercises/practice/say/.meta/spec_generator.moon index 878afcd..f971248 100644 --- a/exercises/practice/say/.meta/spec_generator.moon +++ b/exercises/practice/say/.meta/spec_generator.moon @@ -1,19 +1,19 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Say', generate_test: (case, level) -> - local lines - switch type(case.expected) - when 'table' - lines = { - "f = -> Say.in_english #{case.input.number}", - "assert.has.error f,#{quote case.expected.error}" - } - else - lines = { - "result = Say.in_english #{case.input.number}", - "expected = #{quote case.expected}", - "assert.are.equal expected, result" - } + lines = if case.expected.error + { + "f = -> Say.in_english #{case.input.number}", + "assert.has.error f,#{quote case.expected.error}" + } + else + { + "result = Say.in_english #{case.input.number}", + "expected = #{quote case.expected}", + "assert.are.equal expected, result" + } table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/scrabble-score/.meta/spec_generator.moon b/exercises/practice/scrabble-score/.meta/spec_generator.moon index 56c044c..bcca4d5 100644 --- a/exercises/practice/scrabble-score/.meta/spec_generator.moon +++ b/exercises/practice/scrabble-score/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Scrabble', generate_test: (case, level) -> diff --git a/exercises/practice/secret-handshake/.meta/spec_generator.moon b/exercises/practice/secret-handshake/.meta/spec_generator.moon index 532ce86..11b45bb 100644 --- a/exercises/practice/secret-handshake/.meta/spec_generator.moon +++ b/exercises/practice/secret-handshake/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, word_list from require 'spec_helpers' { module_name: 'SecretHandshake', diff --git a/exercises/practice/series/.meta/spec_generator.moon b/exercises/practice/series/.meta/spec_generator.moon index 1b9f70e..b86ce8c 100644 --- a/exercises/practice/series/.meta/spec_generator.moon +++ b/exercises/practice/series/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' { module_imports: {'slices'}, diff --git a/exercises/practice/sgf-parsing/.meta/spec_generator.moon b/exercises/practice/sgf-parsing/.meta/spec_generator.moon index e976760..7bcba06 100644 --- a/exercises/practice/sgf-parsing/.meta/spec_generator.moon +++ b/exercises/practice/sgf-parsing/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import json_string, table_dump from require 'test_helpers' +import indent, quote, json_string, table_dump from require 'spec_helpers' { module_name: 'SGFParser', @@ -15,7 +15,7 @@ import json_string, table_dump from require 'test_helpers' } else { - "result = SGFParser.#{case.property} #{json_string case.input.encoded}", + "result = SGFParser.parse #{json_string case.input.encoded}", "expected = #{table_dump case.expected, level}", "assert.are.same expected, result" } diff --git a/exercises/practice/sgf-parsing/sgf_parsing_spec.moon b/exercises/practice/sgf-parsing/sgf_parsing_spec.moon index 5f7f00c..25bd84f 100644 --- a/exercises/practice/sgf-parsing/sgf_parsing_spec.moon +++ b/exercises/practice/sgf-parsing/sgf_parsing_spec.moon @@ -18,29 +18,29 @@ describe 'sgf-parsing:', -> pending 'node without properties', -> result = SGFParser.parse "(;)" expected = { - children: {} properties: {} + children: {} } assert.are.same expected, result pending 'single node tree', -> result = SGFParser.parse "(;A[B])" expected = { - children: {} properties: { A: {"B"} } + children: {} } assert.are.same expected, result pending 'multiple properties', -> result = SGFParser.parse "(;A[b]C[d])" expected = { - children: {} properties: { A: {"b"} C: {"d"} } + children: {} } assert.are.same expected, result @@ -59,172 +59,172 @@ describe 'sgf-parsing:', -> pending 'two nodes', -> result = SGFParser.parse "(;A[B];B[C])" expected = { + properties: { + A: {"B"} + } children: {{ - children: {} properties: { B: {"C"} } + children: {} }} - properties: { - A: {"B"} - } } assert.are.same expected, result pending 'two child trees', -> result = SGFParser.parse "(;A[B](;B[C])(;C[D]))" expected = { + properties: { + A: {"B"} + } children: {{ - children: {} properties: { B: {"C"} } - }, { children: {} + }, { properties: { C: {"D"} } + children: {} }} - properties: { - A: {"B"} - } } assert.are.same expected, result pending 'multiple property values', -> result = SGFParser.parse "(;A[b][c][d])" expected = { - children: {} properties: { A: {"b", "c", "d"} } + children: {} } assert.are.same expected, result pending 'within property values, whitespace characters such as tab are converted to spaces', -> result = SGFParser.parse "(;A[hello\t\tworld])" expected = { - children: {} properties: { A: {"hello world"} } + children: {} } assert.are.same expected, result pending 'within property values, newlines remain as newlines', -> result = SGFParser.parse "(;A[hello\n\nworld])" expected = { - children: {} properties: { A: {"hello\n\nworld"} } + children: {} } assert.are.same expected, result pending 'escaped closing bracket within property value becomes just a closing bracket', -> result = SGFParser.parse "(;A[\\]])" expected = { - children: {} properties: { A: {"]"} } + children: {} } assert.are.same expected, result pending 'escaped backslash in property value becomes just a backslash', -> result = SGFParser.parse "(;A[\\\\])" expected = { - children: {} properties: { A: {"\\"} } + children: {} } assert.are.same expected, result pending "opening bracket within property value doesn't need to be escaped", -> result = SGFParser.parse "(;A[x[y\\]z][foo]B[bar];C[baz])" expected = { + properties: { + A: {"x[y]z", "foo"} + B: {"bar"} + } children: {{ - children: {} properties: { C: {"baz"} } + children: {} }} - properties: { - A: {"x[y]z", "foo"} - B: {"bar"} - } } assert.are.same expected, result pending "semicolon in property value doesn't need to be escaped", -> result = SGFParser.parse "(;A[a;b][foo]B[bar];C[baz])" expected = { + properties: { + A: {"a;b", "foo"} + B: {"bar"} + } children: {{ - children: {} properties: { C: {"baz"} } + children: {} }} - properties: { - A: {"a;b", "foo"} - B: {"bar"} - } } assert.are.same expected, result pending "parentheses in property value don't need to be escaped", -> result = SGFParser.parse "(;A[x(y)z][foo]B[bar];C[baz])" expected = { + properties: { + A: {"x(y)z", "foo"} + B: {"bar"} + } children: {{ - children: {} properties: { C: {"baz"} } + children: {} }} - properties: { - A: {"x(y)z", "foo"} - B: {"bar"} - } } assert.are.same expected, result pending 'escaped tab in property value is converted to space', -> result = SGFParser.parse "(;A[hello\\\tworld])" expected = { - children: {} properties: { A: {"hello world"} } + children: {} } assert.are.same expected, result pending 'escaped newline in property value is converted to nothing at all', -> result = SGFParser.parse "(;A[hello\\\nworld])" expected = { - children: {} properties: { A: {"helloworld"} } + children: {} } assert.are.same expected, result pending 'escaped t and n in property value are just letters, not whitespace', -> result = SGFParser.parse "(;A[\\t = t and \\n = n])" expected = { - children: {} properties: { A: {"t = t and n = n"} } + children: {} } assert.are.same expected, result pending 'mixing various kinds of whitespace and escaped characters in property value', -> result = SGFParser.parse "(;A[\\]b\nc\\\nd\t\te\\\\ \\\n\\]])" expected = { - children: {} properties: { A: {"]b\ncd e\\ ]"} } + children: {} } assert.are.same expected, result diff --git a/exercises/practice/sieve/.meta/spec_generator.moon b/exercises/practice/sieve/.meta/spec_generator.moon index 606c001..ba45478 100644 --- a/exercises/practice/sieve/.meta/spec_generator.moon +++ b/exercises/practice/sieve/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list_wrapped from require 'test_helpers' +import indent, int_list_wrapped from require 'spec_helpers' { module_name: 'Sieve', diff --git a/exercises/practice/simple-cipher/.meta/spec_generator.moon b/exercises/practice/simple-cipher/.meta/spec_generator.moon index 5bbc7f5..7e6ccc4 100644 --- a/exercises/practice/simple-cipher/.meta/spec_generator.moon +++ b/exercises/practice/simple-cipher/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'SimpleCipher', diff --git a/exercises/practice/simple-linked-list/.meta/spec_generator.moon b/exercises/practice/simple-linked-list/.meta/spec_generator.moon index 5179d7b..a4f8736 100644 --- a/exercises/practice/simple-linked-list/.meta/spec_generator.moon +++ b/exercises/practice/simple-linked-list/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, quote, int_list from require 'spec_helpers' { module_name: 'SimpleLinkedList', diff --git a/exercises/practice/space-age/.meta/spec_generator.moon b/exercises/practice/space-age/.meta/spec_generator.moon index 9107bab..85081da 100644 --- a/exercises/practice/space-age/.meta/spec_generator.moon +++ b/exercises/practice/space-age/.meta/spec_generator.moon @@ -1,22 +1,8 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'SpaceAge', - 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 - math.abs(a - b) <= epsilon - - say = require 'say' - say\set 'assertion.approx_equal.positive', "Expected %s and %s to be within #{epsilon}" - say\set 'assertion.approx_equal.negative', "Expected %s and %s not to be within #{epsilon}" - assert\register 'assertion', 'approx_equal', is_close_to, 'assertion.approx_equal.positive', 'assertion.approx_equal.negative' - -- ---------------------------------------- -]] - generate_test: (case, level) -> local lines @@ -28,7 +14,7 @@ else lines = { "result = SpaceAge.age #{quote case.input.planet}, #{case.input.seconds}", - "assert.approx_equal #{case.expected}, result" + "assert.is.near #{case.expected}, result, 0.01" } table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/space-age/space_age_spec.moon b/exercises/practice/space-age/space_age_spec.moon index ffeb300..bf1a09b 100644 --- a/exercises/practice/space-age/space_age_spec.moon +++ b/exercises/practice/space-age/space_age_spec.moon @@ -1,51 +1,37 @@ SpaceAge = require 'space_age' describe 'space-age:', -> - -- ---------------------------------------- - -- Why do we need to test "approximately equal"? - -- See https://0.30000000000000004.com - epsilon = 1e-2 - is_close_to = (state, arguments) -> - {a, b} = arguments - math.abs(a - b) <= epsilon - - say = require 'say' - say\set 'assertion.approx_equal.positive', "Expected %s and %s to be within #{epsilon}" - say\set 'assertion.approx_equal.negative', "Expected %s and %s not to be within #{epsilon}" - assert\register 'assertion', 'approx_equal', is_close_to, 'assertion.approx_equal.positive', 'assertion.approx_equal.negative' - -- ---------------------------------------- - it 'age on Earth', -> result = SpaceAge.age 'Earth', 1000000000 - assert.approx_equal 31.69, result + assert.is.near 31.69, result, 0.01 pending 'age on Mercury', -> result = SpaceAge.age 'Mercury', 2134835688 - assert.approx_equal 280.88, result + assert.is.near 280.88, result, 0.01 pending 'age on Venus', -> result = SpaceAge.age 'Venus', 189839836 - assert.approx_equal 9.78, result + assert.is.near 9.78, result, 0.01 pending 'age on Mars', -> result = SpaceAge.age 'Mars', 2129871239 - assert.approx_equal 35.88, result + assert.is.near 35.88, result, 0.01 pending 'age on Jupiter', -> result = SpaceAge.age 'Jupiter', 901876382 - assert.approx_equal 2.41, result + assert.is.near 2.41, result, 0.01 pending 'age on Saturn', -> result = SpaceAge.age 'Saturn', 2000000000 - assert.approx_equal 2.15, result + assert.is.near 2.15, result, 0.01 pending 'age on Uranus', -> result = SpaceAge.age 'Uranus', 1210123456 - assert.approx_equal 0.46, result + assert.is.near 0.46, result, 0.01 pending 'age on Neptune', -> result = SpaceAge.age 'Neptune', 1821023456 - assert.approx_equal 0.35, result + assert.is.near 0.35, result, 0.01 pending 'invalid planet causes error', -> f = -> SpaceAge.age 'Sun', 680804807 diff --git a/exercises/practice/spiral-matrix/.meta/spec_generator.moon b/exercises/practice/spiral-matrix/.meta/spec_generator.moon index b40a67c..d3d682c 100644 --- a/exercises/practice/spiral-matrix/.meta/spec_generator.moon +++ b/exercises/practice/spiral-matrix/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_lists from require 'test_helpers' +import indent, int_lists from require 'spec_helpers' { module_imports: {'spiral_matrix'}, diff --git a/exercises/practice/split-second-stopwatch/.meta/spec_generator.moon b/exercises/practice/split-second-stopwatch/.meta/spec_generator.moon index dcf7187..fa17027 100644 --- a/exercises/practice/split-second-stopwatch/.meta/spec_generator.moon +++ b/exercises/practice/split-second-stopwatch/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import word_list from require 'test_helpers' +import indent, quote, word_list from require 'spec_helpers' format_expected = (val) -> type(val) == 'table' and word_list(val) or quote(val) diff --git a/exercises/practice/square-root/.meta/spec_generator.moon b/exercises/practice/square-root/.meta/spec_generator.moon index cf3a0a3..3119d20 100644 --- a/exercises/practice/square-root/.meta/spec_generator.moon +++ b/exercises/practice/square-root/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent from require 'spec_helpers' + { module_name: 'SquareRoot', generate_test: (case, level) -> diff --git a/exercises/practice/state-of-tic-tac-toe/.meta/spec_generator.moon b/exercises/practice/state-of-tic-tac-toe/.meta/spec_generator.moon index 033c5fa..1334f0d 100644 --- a/exercises/practice/state-of-tic-tac-toe/.meta/spec_generator.moon +++ b/exercises/practice/state-of-tic-tac-toe/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, quote, string_list from require 'spec_helpers' { module_imports: {'gamestate'}, diff --git a/exercises/practice/strain/.meta/spec_generator.moon b/exercises/practice/strain/.meta/spec_generator.moon index d9bd89b..9311566 100644 --- a/exercises/practice/strain/.meta/spec_generator.moon +++ b/exercises/practice/strain/.meta/spec_generator.moon @@ -1,32 +1,26 @@ -import int_list, word_list from require 'test_helpers' +import indent, is_empty, int_list, word_list from require 'spec_helpers' format_predicate = (pred) -> switch pred - when "fn(x) -> true" - "(_) -> true" - when "fn(x) -> false" - "(_) -> false" - when "fn(x) -> x % 2 == 1" - "(num) -> num % 2 == 1" - when "fn(x) -> x % 2 == 0" - "(num) -> num % 2 == 0" - when "fn(x) -> contains(x, 5)" - "(list) -> contains list, 5" - when "fn(x) -> starts_with(x, 'z')" - "(str) -> starts_with str, 'z'" + when "fn(x) -> true" then "(_) -> true" + when "fn(x) -> false" then "(_) -> false" + when "fn(x) -> x % 2 == 1" then "(num) -> num % 2 == 1" + when "fn(x) -> x % 2 == 0" then "(num) -> num % 2 == 0" + when "fn(x) -> contains(x, 5)" then "(list) -> contains list, 5" + when "fn(x) -> starts_with(x, 'z')" then "(str) -> starts_with str, 'z'" else pred format_list = (list) -> - if #list == 0 - "{}" + if is_empty list + '{}' elseif type(list[1]) == 'string' word_list list else int_list list format_value = (val, level) -> - if #val == 0 + if is_empty val '{}' elseif type(val[1]) == 'table' -- list of lists rows = [indent format_list(row), level + 1 for row in *val] diff --git a/exercises/practice/sublist/.meta/spec_generator.moon b/exercises/practice/sublist/.meta/spec_generator.moon index 38b81cf..413f9a8 100644 --- a/exercises/practice/sublist/.meta/spec_generator.moon +++ b/exercises/practice/sublist/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, quote, int_list from require 'spec_helpers' { module_imports: {'sublist'}, diff --git a/exercises/practice/sum-of-multiples/.meta/spec_generator.moon b/exercises/practice/sum-of-multiples/.meta/spec_generator.moon index 0383f4c..c187634 100644 --- a/exercises/practice/sum-of-multiples/.meta/spec_generator.moon +++ b/exercises/practice/sum-of-multiples/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, int_list from require 'spec_helpers' { module_name: 'SumOfMultiples', diff --git a/exercises/practice/swift-scheduling/.meta/spec_generator.moon b/exercises/practice/swift-scheduling/.meta/spec_generator.moon index 8d6376a..1fbc3fd 100644 --- a/exercises/practice/swift-scheduling/.meta/spec_generator.moon +++ b/exercises/practice/swift-scheduling/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'delivery_date'}, diff --git a/exercises/practice/tournament/.meta/spec_generator.moon b/exercises/practice/tournament/.meta/spec_generator.moon index bbfad4b..e44f54b 100644 --- a/exercises/practice/tournament/.meta/spec_generator.moon +++ b/exercises/practice/tournament/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + string_list = (list, level) -> lines = [indent quote(elem) .. ',', level + 1 for elem in *list] table.insert lines, 1, '{' diff --git a/exercises/practice/transpose/.meta/spec_generator.moon b/exercises/practice/transpose/.meta/spec_generator.moon index 8dbbf8e..cb37ac2 100644 --- a/exercises/practice/transpose/.meta/spec_generator.moon +++ b/exercises/practice/transpose/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, string_list from require 'spec_helpers' { module_imports: {'transpose'}, diff --git a/exercises/practice/triangle/.meta/spec_generator.moon b/exercises/practice/triangle/.meta/spec_generator.moon index e2d075a..0bef7e9 100644 --- a/exercises/practice/triangle/.meta/spec_generator.moon +++ b/exercises/practice/triangle/.meta/spec_generator.moon @@ -1,5 +1,8 @@ +import indent from require 'spec_helpers' + { module_imports: {'is_equilateral', 'is_isosceles', 'is_scalene'}, generate_test: (case, level) -> - indent "assert.is_#{case.expected} is_#{case.property}(#{table.concat case.input.sides, ', '})", level + func = "is_#{case.property}(#{table.concat case.input.sides, ', '})" + indent "assert.is_#{case.expected} #{func}", level } diff --git a/exercises/practice/twelve-days/.meta/spec_generator.moon b/exercises/practice/twelve-days/.meta/spec_generator.moon index 24362e1..f94b373 100644 --- a/exercises/practice/twelve-days/.meta/spec_generator.moon +++ b/exercises/practice/twelve-days/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import string_list from require 'test_helpers' +import indent, string_list from require 'spec_helpers' { module_name: 'TwelveDays', diff --git a/exercises/practice/two-bucket/.meta/spec_generator.moon b/exercises/practice/two-bucket/.meta/spec_generator.moon index 8b9746d..77ee583 100644 --- a/exercises/practice/two-bucket/.meta/spec_generator.moon +++ b/exercises/practice/two-bucket/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import table_tostring_ordered from require 'test_helpers' +import indent, table_tostring_ordered from require 'spec_helpers' { module_imports: {'measure'}, diff --git a/exercises/practice/two-fer/.meta/spec_generator.moon b/exercises/practice/two-fer/.meta/spec_generator.moon deleted file mode 100644 index 17602f6..0000000 --- a/exercises/practice/two-fer/.meta/spec_generator.moon +++ /dev/null @@ -1 +0,0 @@ -error 'two-fer does not use a generator. Please update spec by hand.' diff --git a/exercises/practice/variable-length-quantity/.meta/spec_generator.moon b/exercises/practice/variable-length-quantity/.meta/spec_generator.moon index 03fb8b5..d626818 100644 --- a/exercises/practice/variable-length-quantity/.meta/spec_generator.moon +++ b/exercises/practice/variable-length-quantity/.meta/spec_generator.moon @@ -1,4 +1,4 @@ -import int_list from require 'test_helpers' +import indent, quote, int_list from require 'spec_helpers' { module_name: 'VariableLengthQuantity', diff --git a/exercises/practice/word-count/.meta/spec_generator.moon b/exercises/practice/word-count/.meta/spec_generator.moon index d0387d9..21db5b6 100644 --- a/exercises/practice/word-count/.meta/spec_generator.moon +++ b/exercises/practice/word-count/.meta/spec_generator.moon @@ -1,32 +1,13 @@ -import json_string, kv_table from require 'test_helpers' +import indent, json_string, kv_table from require 'spec_helpers' { module_imports: {'count_words'}, - test_helpers: [[ - -- ---------------------------------------------------------- - same_kv = (state, arguments) -> - actual = arguments[1] - return false if type(actual) != 'table' - expected = arguments[2] - size = (t) -> #[k for k, _ in pairs t] - return false if size(expected) != size(actual) - for k, v in pairs expected - return false if actual[k] != v - true - - say = require 'say' - say\set 'assertion.same_kv.positive', 'Actual result\n%s\ndoes not have the same keys and values as expected\n%s' - say\set 'assertion.same_kv.negative', 'Actual result\n%s\nwas not supposed to be the same as expected\n%s' - assert\register 'assertion', 'same_kv', same_kv, 'assertion.same_kv.positive', 'assertion.same_kv.negative' - -- ---------------------------------------------------------- -]] - generate_test: (case, level) -> lines = { "result = count_words #{json_string case.input.sentence}", "expected = #{kv_table case.expected, level}", - "assert.has.same_kv result, expected" + "assert.are.same result, expected" } table.concat [indent line, level for line in *lines], '\n' } diff --git a/exercises/practice/word-count/word_count_spec.moon b/exercises/practice/word-count/word_count_spec.moon index 8dcda0f..ab89e6a 100644 --- a/exercises/practice/word-count/word_count_spec.moon +++ b/exercises/practice/word-count/word_count_spec.moon @@ -1,87 +1,70 @@ import count_words from require 'word_count' describe 'word-count:', -> - -- ---------------------------------------------------------- - same_kv = (state, arguments) -> - actual = arguments[1] - return false if type(actual) != 'table' - expected = arguments[2] - size = (t) -> #[k for k, _ in pairs t] - return false if size(expected) != size(actual) - for k, v in pairs expected - return false if actual[k] != v - true - - say = require 'say' - say\set 'assertion.same_kv.positive', 'Actual result\n%s\ndoes not have the same keys and values as expected\n%s' - say\set 'assertion.same_kv.negative', 'Actual result\n%s\nwas not supposed to be the same as expected\n%s' - assert\register 'assertion', 'same_kv', same_kv, 'assertion.same_kv.positive', 'assertion.same_kv.negative' - -- ---------------------------------------------------------- - it 'count one word', -> result = count_words "word" expected = { word: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'count one of each word', -> result = count_words "one of each" expected = { + of: 1, one: 1, each: 1, - of: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'multiple occurrences of a word', -> result = count_words "one fish two fish red fish blue fish" expected = { - blue: 1, - one: 1, - red: 1, fish: 4, + red: 1, + one: 1, two: 1, + blue: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'handles cramped lists', -> result = count_words "one,two,three" expected = { - two: 1, three: 1, one: 1, + two: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'handles expanded lists', -> result = count_words "one,\ntwo,\nthree" expected = { - two: 1, three: 1, one: 1, + two: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'ignore punctuation', -> result = count_words "car: carpet as java: javascript!!&@$%^&" expected = { java: 1, - carpet: 1, javascript: 1, + carpet: 1, car: 1, as: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'include numbers', -> result = count_words "testing, 1, 2 testing" expected = { - testing: 2, - '2': 1, '1': 1, + '2': 1, + testing: 2, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'normalize case', -> result = count_words "go Go GO Stop stop" @@ -89,64 +72,64 @@ describe 'word-count:', -> stop: 2, go: 3, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'with apostrophes', -> result = count_words "'First: don't laugh. Then: don't cry. You're getting it.'" expected = { - laugh: 1, + first: 1, getting: 1, it: 1, - first: 1, - "you're": 1, - then: 1, + laugh: 1, "don't": 2, + then: 1, + "you're": 1, cry: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'with quotations', -> result = count_words "Joe can't tell between 'large' and large." expected = { - and: 1, - "can't": 1, - joe: 1, tell: 1, - large: 2, + "can't": 1, between: 1, + large: 2, + and: 1, + joe: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'substrings from the beginning', -> result = count_words "Joe can't tell between app, apple and a." expected = { - and: 1, + tell: 1, "can't": 1, - a: 1, apple: 1, + between: 1, + a: 1, app: 1, - tell: 1, + and: 1, joe: 1, - between: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'multiple spaces not detected as a word', -> result = count_words " multiple whitespaces" expected = { - whitespaces: 1, multiple: 1, + whitespaces: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'alternating word separators not detected as a word', -> result = count_words ",\n,one,\n ,two \n 'three'" expected = { - two: 1, three: 1, one: 1, + two: 1, } - assert.has.same_kv result, expected + assert.are.same result, expected pending 'quotation for word with apostrophe', -> result = count_words "can, can't, 'can't'" @@ -154,4 +137,4 @@ describe 'word-count:', -> can: 1, "can't": 2, } - assert.has.same_kv result, expected + assert.are.same result, expected diff --git a/exercises/practice/wordy/.meta/spec_generator.moon b/exercises/practice/wordy/.meta/spec_generator.moon index 6afbaca..94e690d 100644 --- a/exercises/practice/wordy/.meta/spec_generator.moon +++ b/exercises/practice/wordy/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Wordy', diff --git a/exercises/practice/yacht/.meta/spec_generator.moon b/exercises/practice/yacht/.meta/spec_generator.moon index 1cbce4b..2801018 100644 --- a/exercises/practice/yacht/.meta/spec_generator.moon +++ b/exercises/practice/yacht/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_name: 'Yacht', generate_test: (case, level) -> diff --git a/exercises/practice/zebra-puzzle/.meta/spec_generator.moon b/exercises/practice/zebra-puzzle/.meta/spec_generator.moon index 19278c5..7fc30d5 100644 --- a/exercises/practice/zebra-puzzle/.meta/spec_generator.moon +++ b/exercises/practice/zebra-puzzle/.meta/spec_generator.moon @@ -1,3 +1,5 @@ +import indent, quote from require 'spec_helpers' + { module_imports: {'drinksWater', 'ownsZebra'}, diff --git a/lib/test_helpers.moon b/lib/spec_helpers.moon similarity index 83% rename from lib/test_helpers.moon rename to lib/spec_helpers.moon index bd5c054..c9479bd 100644 --- a/lib/test_helpers.moon +++ b/lib/spec_helpers.moon @@ -1,7 +1,20 @@ json = require 'dkjson' -- example usage in a spec_generator: --- import int_list, word_list from require 'test_helpers' +-- import indent, quote, int_list, word_list from require 'test_helpers' +-- or +-- import +-- indent +-- quote +-- int_list +-- word_list +-- from require 'test_helpers' + +--- ----------------------------------------------------------------------- +-- Since moonscript is a conten +indent = (text, level) -> + error 'Provide a level for `indent`', 2 if not level + string.rep(' ', level) .. text --- ----------------------------------------------------------------------- --- Lists of booleans @@ -46,6 +59,13 @@ int_list_wrapped = (list, level) -> table.concat lines, '\n' --- ----------------------------------------------------------------------- +-- Safely quote a string +quote = (str) -> + if str\find "'" + "\"#{str\gsub '"', '\\"'}\"" + else + "'#{str}'" + --- List of strings word_list = (list) -> "{#{table.concat [quote word for word in *list], ', '}}" @@ -68,6 +88,15 @@ string_list = (list, level, opts) -> --- Show strings with escapes, when you want to keep the `\t`, `\n` in the test case. json_string = (s) -> json.encode s +-- comparing against the dkjson `json.null` value +local is_empty +is_json_null = (value) -> + return false unless type(value) == 'table' + return false unless is_empty(value) + return false unless getmetatable(value) + return false unless type(getmetatable(value).__tojson) == 'function' + true + --- ----------------------------------------------------------------------- --- Key-Value list kv_table = (tbl, level) -> @@ -95,6 +124,12 @@ table_tostring_ordered = (t, keys) -> s = [string.format '%s: %q', k, t[k] for k in *keys] "{#{table.concat s, ', '}}" +table_tostring_sortby_keys = (t) -> + keys = [k for k, _ in pairs t] + table.sort keys + s = [string.format '%s: %q', k, t[k] for k in *keys] + "{#{table.concat s, ', '}}" + --- list of one-line key-value tables table_list = (list, level) -> error 'Provide a level for `table_list`', 2 if not level @@ -157,16 +192,21 @@ table_dump = (what, level = 0) -> --- ----------------------------------------------------------------------- { :bool_list + :indent :int_list - :int_lists :int_list_wrapped - :word_list - :string_list - :kv_table - :table_tostring - :table_tostring_ordered - :table_list + :int_lists + :is_empty + :is_json_null :json_string + :kv_table + :quote + :string_list :table_contains :table_dump + :table_list + :table_tostring + :table_tostring_ordered + :table_tostring_sortby_keys + :word_list } diff --git a/lib/spec_helpers/assertions.moon b/lib/spec_helpers/assertions.moon new file mode 100644 index 0000000..c9222bf --- /dev/null +++ b/lib/spec_helpers/assertions.moon @@ -0,0 +1,30 @@ +-- Custom assertions +-- +-- pull them into the spec_generator like this: (see `dnd-character`) +-- +-- import ident, ... from require 'spec_helpers' +-- assertions = require 'spec_helpers/assertions' +-- ... +-- generate_test = (case, level) -> +-- ... +-- test_helpers = assertions.between +-- ... + +assertions = { + between: [[ + -- ---------------------------------------------------------- + between = (state, arguments) -> + assert #arguments == 3, 'expected three arguments to assert.between: value, min, max' + { val, min, max } = arguments + val and min <= val and val <= max + + say = require 'say' + say\set 'assertion.between.positive', 'Expected %s to be in the range [%s, %s]' + say\set 'assertion.between.negative', 'Expected %s not to be in the range [%s, %s]' + assert\register 'assertion', 'between', between, 'assertion.between.positive', 'assertion.between.negative' + -- ---------------------------------------------------------- +]] + +} + +assertions