From 0b99a72cbf514cb82d5d1b43bf8ac3937c75755b Mon Sep 17 00:00:00 2001 From: meatball Date: Sun, 31 Aug 2025 23:04:35 +0200 Subject: [PATCH 1/5] Add templates to exercises batch 4 --- .../practice/dominoes/.meta/test_template.erb | 12 +++++++++ exercises/practice/dominoes/dominoes_test.rb | 10 +++---- .../eliuds-eggs/.meta/test_template.erb | 11 ++++++++ .../practice/etl/.meta/test_template.erb | 21 +++++++++++++++ exercises/practice/etl/etl_test.rb | 2 +- .../flatten-array/.meta/test_template.erb | 12 +++++++++ .../practice/flatten-array/.meta/tests.toml | 18 +++++++++++++ .../flatten-array/flatten_array_test.rb | 25 ++++++++++++++---- .../flower-field/.meta/test_template.erb | 13 ++++++++++ .../flower-field/flower_field_test.rb | 1 + .../gigasecond/.meta/test_template.erb | 12 +++++++++ .../practice/gigasecond/.meta/tests.toml | 3 --- .../practice/gigasecond/gigasecond_test.rb | 22 +++++++++++++--- .../practice/grains/.meta/test_template.erb | 26 +++++++++++++++++++ exercises/practice/grains/grains_test.rb | 20 +++++++------- 15 files changed, 181 insertions(+), 27 deletions(-) create mode 100644 exercises/practice/dominoes/.meta/test_template.erb create mode 100644 exercises/practice/eliuds-eggs/.meta/test_template.erb create mode 100644 exercises/practice/etl/.meta/test_template.erb create mode 100644 exercises/practice/flatten-array/.meta/test_template.erb create mode 100644 exercises/practice/flower-field/.meta/test_template.erb create mode 100644 exercises/practice/gigasecond/.meta/test_template.erb create mode 100644 exercises/practice/grains/.meta/test_template.erb diff --git a/exercises/practice/dominoes/.meta/test_template.erb b/exercises/practice/dominoes/.meta/test_template.erb new file mode 100644 index 0000000000..1882c94bed --- /dev/null +++ b/exercises/practice/dominoes/.meta/test_template.erb @@ -0,0 +1,12 @@ +require 'minitest/autorun' +require_relative 'dominoes' + +class DominoesTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + dominoes = <%= cases["input"]["dominoes"] %> + <%= cases["expected"] ? "assert" : "refute" %> Dominoes.chain?(dominoes) + end + <% end %> +end \ No newline at end of file diff --git a/exercises/practice/dominoes/dominoes_test.rb b/exercises/practice/dominoes/dominoes_test.rb index 6f994466a8..23c95f6aec 100644 --- a/exercises/practice/dominoes/dominoes_test.rb +++ b/exercises/practice/dominoes/dominoes_test.rb @@ -2,13 +2,13 @@ require_relative 'dominoes' class DominoesTest < Minitest::Test - def test_empty_input_empty_output + def test_empty_input__empty_output # skip dominoes = [] assert Dominoes.chain?(dominoes) end - def test_singleton_input_singleton_output + def test_singleton_input__singleton_output skip dominoes = [[1, 1]] assert Dominoes.chain?(dominoes) @@ -38,19 +38,19 @@ def test_cant_be_chained refute Dominoes.chain?(dominoes) end - def test_disconnected_simple + def test_disconnected___simple skip dominoes = [[1, 1], [2, 2]] refute Dominoes.chain?(dominoes) end - def test_disconnected_double_loop + def test_disconnected___double_loop skip dominoes = [[1, 2], [2, 1], [3, 4], [4, 3]] refute Dominoes.chain?(dominoes) end - def test_disconnected_single_isolated + def test_disconnected___single_isolated skip dominoes = [[1, 2], [2, 3], [3, 1], [4, 4]] refute Dominoes.chain?(dominoes) diff --git a/exercises/practice/eliuds-eggs/.meta/test_template.erb b/exercises/practice/eliuds-eggs/.meta/test_template.erb new file mode 100644 index 0000000000..eac36876f8 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.meta/test_template.erb @@ -0,0 +1,11 @@ +require 'minitest/autorun' +require_relative 'eliuds_eggs' + +class EliudsEggsTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + assert_equal <%= cases["expected"] %>, EliudsEggs.egg_count(<%= cases["input"]["number"] %>) + end + <% end %> +end \ No newline at end of file diff --git a/exercises/practice/etl/.meta/test_template.erb b/exercises/practice/etl/.meta/test_template.erb new file mode 100644 index 0000000000..c8341f253f --- /dev/null +++ b/exercises/practice/etl/.meta/test_template.erb @@ -0,0 +1,21 @@ +require 'minitest/autorun' +require_relative 'etl' + +class EtlTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + old = { + <% cases["input"]["legacy"].each do |key, value| -%> + <%= key %> => <%= value %>, + <%- end -%> + } + expected = { + <% cases["expected"].each do |key, value| -%> + '<%= key %>' => <%= value %>, + <%- end -%> + } + assert_equal expected, ETL.transform(old) + end + <% end %> +end \ No newline at end of file diff --git a/exercises/practice/etl/etl_test.rb b/exercises/practice/etl/etl_test.rb index 09a8c1a91b..c101d16bc8 100644 --- a/exercises/practice/etl/etl_test.rb +++ b/exercises/practice/etl/etl_test.rb @@ -2,7 +2,7 @@ require_relative 'etl' class EtlTest < Minitest::Test - def test_a_single_letter + def test_single_letter # skip old = { 1 => ["A"] diff --git a/exercises/practice/flatten-array/.meta/test_template.erb b/exercises/practice/flatten-array/.meta/test_template.erb new file mode 100644 index 0000000000..a1fd861761 --- /dev/null +++ b/exercises/practice/flatten-array/.meta/test_template.erb @@ -0,0 +1,12 @@ +require 'minitest/autorun' +require_relative 'flatten_array' + +class FlattenArrayTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + flat_array = FlattenArray.flatten(<%= cases["input"]["array"] %>) + assert_equal <%= cases["expected"] %>, flat_array + end + <% end %> +end \ No newline at end of file diff --git a/exercises/practice/flatten-array/.meta/tests.toml b/exercises/practice/flatten-array/.meta/tests.toml index 1c0c79136a..309aae8404 100644 --- a/exercises/practice/flatten-array/.meta/tests.toml +++ b/exercises/practice/flatten-array/.meta/tests.toml @@ -35,12 +35,30 @@ include = false description = "consecutive null values at the front of the list are omitted from the final result" include = false +[bc72da10-5f55-4ada-baf3-50e4da02ec8e] +description = "consecutive null values at the front of the array are omitted from the final result" +reimplements = "c6cf26de-8ccd-4410-84bd-b9efd88fd2bc" + [382c5242-587e-4577-b8ce-a5fb51e385a1] description = "consecutive null values in the middle of the list are omitted from the final result" include = false +[6991836d-0d9b-4703-80a0-3f1f23eb5981] +description = "consecutive null values in the middle of the array are omitted from the final result" +reimplements = "382c5242-587e-4577-b8ce-a5fb51e385a1" + [ef1d4790-1b1e-4939-a179-51ace0829dbd] description = "6 level nest list with null values" +include = false + +[dc90a09c-5376-449c-a7b3-c2d20d540069] +description = "6 level nested array with null values" +reimplements = "ef1d4790-1b1e-4939-a179-51ace0829dbd" [85721643-705a-4150-93ab-7ae398e2942d] description = "all values in nested list are null" +include = false + +[51f5d9af-8f7f-4fb5-a156-69e8282cb275] +description = "all values in nested array are null" +reimplements = "85721643-705a-4150-93ab-7ae398e2942d" diff --git a/exercises/practice/flatten-array/flatten_array_test.rb b/exercises/practice/flatten-array/flatten_array_test.rb index 46fb7592f4..4d27e5fe2e 100644 --- a/exercises/practice/flatten-array/flatten_array_test.rb +++ b/exercises/practice/flatten-array/flatten_array_test.rb @@ -4,7 +4,8 @@ class FlattenArrayTest < Minitest::Test def test_empty # skip - assert_empty FlattenArray.flatten([]) + flat_array = FlattenArray.flatten([]) + assert_empty flat_array end def test_no_nesting @@ -15,7 +16,8 @@ def test_no_nesting def test_flattens_a_nested_array skip - assert_empty FlattenArray.flatten([[[]]]) + flat_array = FlattenArray.flatten([[[]]]) + assert_empty flat_array end def test_flattens_array_with_just_integers_present @@ -36,14 +38,27 @@ def test_6_level_nesting assert_equal [1, 2, 3, 4, 5, 6, 7, 8], flat_array end - def test_6_level_nest_list_with_null_values + def test_consecutive_null_values_at_the_front_of_the_array_are_omitted_from_the_final_result + skip + flat_array = FlattenArray.flatten([nil, nil, 3]) + assert_equal [3], flat_array + end + + def test_consecutive_null_values_in_the_middle_of_the_array_are_omitted_from_the_final_result + skip + flat_array = FlattenArray.flatten([1, nil, nil, 4]) + assert_equal [1, 4], flat_array + end + + def test_6_level_nested_array_with_null_values skip flat_array = FlattenArray.flatten([0, 2, [[2, 3], 8, [[100]], nil, [[nil]]], -2]) assert_equal [0, 2, 2, 3, 8, 100, -2], flat_array end - def test_all_values_in_nested_list_are_null + def test_all_values_in_nested_array_are_null skip - assert_empty FlattenArray.flatten([nil, [[[nil]]], nil, nil, [[nil, nil], nil], nil]) + flat_array = FlattenArray.flatten([nil, [[[nil]]], nil, nil, [[nil, nil], nil], nil]) + assert_empty flat_array end end diff --git a/exercises/practice/flower-field/.meta/test_template.erb b/exercises/practice/flower-field/.meta/test_template.erb new file mode 100644 index 0000000000..9aa654e1df --- /dev/null +++ b/exercises/practice/flower-field/.meta/test_template.erb @@ -0,0 +1,13 @@ +require 'minitest/autorun' +require_relative 'flower_field' + +class FlowerFieldTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + input = <%= cases["input"]["garden"] %> + expected = <%= cases["expected"] %> + assert_equal expected, FlowerField.annotate(input) + end + <% end %> +end \ No newline at end of file diff --git a/exercises/practice/flower-field/flower_field_test.rb b/exercises/practice/flower-field/flower_field_test.rb index e9bde59618..23e1783030 100644 --- a/exercises/practice/flower-field/flower_field_test.rb +++ b/exercises/practice/flower-field/flower_field_test.rb @@ -3,6 +3,7 @@ class FlowerFieldTest < Minitest::Test def test_no_rows + # skip input = [] expected = [] assert_equal expected, FlowerField.annotate(input) diff --git a/exercises/practice/gigasecond/.meta/test_template.erb b/exercises/practice/gigasecond/.meta/test_template.erb new file mode 100644 index 0000000000..814b548f49 --- /dev/null +++ b/exercises/practice/gigasecond/.meta/test_template.erb @@ -0,0 +1,12 @@ +require 'minitest/autorun' +require_relative 'gigasecond' +require 'time' + +class GigasecondTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + assert_equal Time.parse('<%= cases["expected"] %> UTC'), Gigasecond.from(Time.parse('<%= cases["input"]["moment"] %><%= cases["input"]["moment"].include?('T') ? '' : 'T00:00:00' %> UTC')) + end + <% end %> +end \ No newline at end of file diff --git a/exercises/practice/gigasecond/.meta/tests.toml b/exercises/practice/gigasecond/.meta/tests.toml index 64fd072a04..7f75cf5e6f 100644 --- a/exercises/practice/gigasecond/.meta/tests.toml +++ b/exercises/practice/gigasecond/.meta/tests.toml @@ -11,15 +11,12 @@ [92fbe71c-ea52-4fac-bd77-be38023cacf7] description = "date only specification of time" -include = false [6d86dd16-6f7a-47be-9e58-bb9fb2ae1433] description = "second test for date only specification of time" -include = false [77eb8502-2bca-4d92-89d9-7b39ace28dd5] description = "third test for date only specification of time" -include = false [c9d89a7d-06f8-4e28-a305-64f1b2abc693] description = "full time specified" diff --git a/exercises/practice/gigasecond/gigasecond_test.rb b/exercises/practice/gigasecond/gigasecond_test.rb index ad000cf3d5..b30d7eb79e 100644 --- a/exercises/practice/gigasecond/gigasecond_test.rb +++ b/exercises/practice/gigasecond/gigasecond_test.rb @@ -1,14 +1,30 @@ require 'minitest/autorun' require_relative 'gigasecond' +require 'time' class GigasecondTest < Minitest::Test - def test_full_time_specified + def test_date_only_specification_of_time # skip - assert_equal Time.utc(2046, 10, 2, 23, 46, 40), Gigasecond.from(Time.utc(2015, 1, 24, 22, 0, 0)) + assert_equal Time.parse('2043-01-01T01:46:40 UTC'), Gigasecond.from(Time.parse('2011-04-25T00:00:00 UTC')) + end + + def test_second_test_for_date_only_specification_of_time + skip + assert_equal Time.parse('2009-02-19T01:46:40 UTC'), Gigasecond.from(Time.parse('1977-06-13T00:00:00 UTC')) + end + + def test_third_test_for_date_only_specification_of_time + skip + assert_equal Time.parse('1991-03-27T01:46:40 UTC'), Gigasecond.from(Time.parse('1959-07-19T00:00:00 UTC')) + end + + def test_full_time_specified + skip + assert_equal Time.parse('2046-10-02T23:46:40 UTC'), Gigasecond.from(Time.parse('2015-01-24T22:00:00 UTC')) end def test_full_time_with_day_roll_over skip - assert_equal Time.utc(2046, 10, 3, 1, 46, 39), Gigasecond.from(Time.utc(2015, 1, 24, 23, 59, 59)) + assert_equal Time.parse('2046-10-03T01:46:39 UTC'), Gigasecond.from(Time.parse('2015-01-24T23:59:59 UTC')) end end diff --git a/exercises/practice/grains/.meta/test_template.erb b/exercises/practice/grains/.meta/test_template.erb new file mode 100644 index 0000000000..b6340168e9 --- /dev/null +++ b/exercises/practice/grains/.meta/test_template.erb @@ -0,0 +1,26 @@ +require 'minitest/autorun' +require_relative 'grains' + +class GrainsTest < Minitest::Test +<% json["cases"].each do |cases| %> + <%- if cases["cases"] -%> + <% cases["cases"].each do |sub_case| %> + def test_<%= underscore(sub_case["description"]) %> + <%= skip? %> + <%- if sub_case["expected"].is_a?(Hash) && sub_case["expected"].key?("error") -%> + assert_raises(ArgumentError) do + Grains.square(<%= sub_case["input"]["square"] %>) + end + <%- else -%> + assert_equal <%= sub_case["expected"] %>, Grains.square(<%= sub_case["input"]["square"] %>) + <%- end -%> + end + <% end %> + <%- else -%> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + assert_equal <%= cases["expected"] %>, Grains.total + end + <%- end -%> +<% end %> +end \ No newline at end of file diff --git a/exercises/practice/grains/grains_test.rb b/exercises/practice/grains/grains_test.rb index 8351663201..bf5ab14c62 100644 --- a/exercises/practice/grains/grains_test.rb +++ b/exercises/practice/grains/grains_test.rb @@ -2,56 +2,56 @@ require_relative 'grains' class GrainsTest < Minitest::Test - def test_1 + def test_grains_on_square_1 # skip assert_equal 1, Grains.square(1) end - def test_2 + def test_grains_on_square_2 skip assert_equal 2, Grains.square(2) end - def test_3 + def test_grains_on_square_3 skip assert_equal 4, Grains.square(3) end - def test_4 + def test_grains_on_square_4 skip assert_equal 8, Grains.square(4) end - def test_16 + def test_grains_on_square_16 skip assert_equal 32_768, Grains.square(16) end - def test_32 + def test_grains_on_square_32 skip assert_equal 2_147_483_648, Grains.square(32) end - def test_64 + def test_grains_on_square_64 skip assert_equal 9_223_372_036_854_775_808, Grains.square(64) end - def test_square_0_raises_an_exception + def test_square_0_is_invalid skip assert_raises(ArgumentError) do Grains.square(0) end end - def test_negative_square_raises_an_exception + def test_negative_square_is_invalid skip assert_raises(ArgumentError) do Grains.square(-1) end end - def test_square_greater_than_64_raises_an_exception + def test_square_greater_than_64_is_invalid skip assert_raises(ArgumentError) do Grains.square(65) From 470834d232d54e69573743df122bba6e6afc33b6 Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Sun, 31 Aug 2025 23:14:46 +0200 Subject: [PATCH 2/5] Sync (#1778) * Fix exercise naming in generator (#1770) * Enhance underscore method to filter invalid characters and update test file naming convention * Add test case which test underscore for special characters * Use character classes in regex. Also expose description for nested test cases. * Underscore must not create multiple underscores around special characters * Add templates to exercises batch 1 (#1771) * Make test name unique in allergies * Changed exercises to use single quotes. Changed template for allergies so it should match the old version. * Update acronym solution to work on the new test * Fix import and class in atbash test * Fix exercise naming in generator (#1770) (#1774) * Enhance underscore method to filter invalid characters and update test file naming convention * Add test case which test underscore for special characters * Use character classes in regex. Also expose description for nested test cases. * Underscore must not create multiple underscores around special characters --------- Co-authored-by: Victor Goff --------- Co-authored-by: Victor Goff --- bin/generate | 6 +- exercises/practice/acronym/.meta/example.rb | 6 +- .../practice/acronym/.meta/test_template.erb | 2 +- exercises/practice/acronym/acronym_test.rb | 10 ++ .../affine-cipher/.meta/test_template.erb | 26 ++++ .../all-your-base/.meta/test_template.erb | 26 ++++ .../all-your-base/all_your_base_test.rb | 57 +++++---- .../allergies/.meta/test_template.erb | 19 +++ .../practice/allergies/allergies_test.rb | 120 ++++++++++-------- .../practice/anagram/.meta/test_template.erb | 15 +++ exercises/practice/anagram/.meta/tests.toml | 2 + exercises/practice/anagram/anagram_test.rb | 86 ++++++++----- .../armstrong-numbers/.meta/test_template.erb | 11 ++ .../atbash-cipher/.meta/test_template.erb | 21 +++ .../bank-account/.meta/test_template.erb | 43 +++++++ .../practice/bank-account/.meta/tests.toml | 2 +- .../bank-account/bank_account_test.rb | 2 +- .../binary-search/.meta/test_template.erb | 16 +++ .../binary-search/binary_search_test.rb | 4 +- generatorv2/lib/generator.rb | 6 +- generatorv2/lib/utils.rb | 2 +- generatorv2/test/utils_test.rb | 10 ++ 22 files changed, 364 insertions(+), 128 deletions(-) create mode 100644 exercises/practice/affine-cipher/.meta/test_template.erb create mode 100644 exercises/practice/all-your-base/.meta/test_template.erb create mode 100644 exercises/practice/allergies/.meta/test_template.erb create mode 100644 exercises/practice/anagram/.meta/test_template.erb create mode 100644 exercises/practice/armstrong-numbers/.meta/test_template.erb create mode 100644 exercises/practice/atbash-cipher/.meta/test_template.erb create mode 100644 exercises/practice/bank-account/.meta/test_template.erb create mode 100644 exercises/practice/binary-search/.meta/test_template.erb diff --git a/bin/generate b/bin/generate index fd6f32f277..4966be4299 100755 --- a/bin/generate +++ b/bin/generate @@ -9,6 +9,10 @@ def exercises .select { |file| File.directory? File.join('./exercises/practice', file) } end +def underscore(str) + str.gsub(/[^\w\s-]/, '').gsub(/[-\s]/, '_').downcase +end + class VerificationError < StandardError MESSAGE = 'The result generated for %s, does not match the current file' @@ -39,7 +43,7 @@ end parser.on('--verify', 'Verify all exercises') do exercises.each do |exercise| if File.exist?("./exercises/practice/#{exercise}/.meta/test_template.erb") - current_code = File.read("./exercises/practice/#{exercise}/#{exercise}_test.rb") + current_code = File.read("./exercises/practice/#{exercise}/#{underscore(exercise)}_test.rb") f = File.new("./exercises/practice/#{exercise}/temp_test.rb", 'w+') Generator.new(exercise).generate(f.path) generated_code = f.read diff --git a/exercises/practice/acronym/.meta/example.rb b/exercises/practice/acronym/.meta/example.rb index d0230dd623..7ff6892849 100644 --- a/exercises/practice/acronym/.meta/example.rb +++ b/exercises/practice/acronym/.meta/example.rb @@ -7,9 +7,7 @@ def self.abbreviate(phrase) end.join end - def self.each_word(phrase) - phrase.scan(/[A-Z]+[a-z]*|[a-z]+/) do |word| - yield word - end + def self.each_word(phrase, &block) + phrase.scan(/[A-Za-z]+(?:'[A-Za-z]+)*/, &block) end end diff --git a/exercises/practice/acronym/.meta/test_template.erb b/exercises/practice/acronym/.meta/test_template.erb index 66c45804f7..c2b235f152 100644 --- a/exercises/practice/acronym/.meta/test_template.erb +++ b/exercises/practice/acronym/.meta/test_template.erb @@ -5,7 +5,7 @@ class AcronymTest < Minitest::Test <% json["cases"].each do |cases| %> def test_<%= underscore(cases["description"]) %> <%= skip? %> - assert_equal '<%= cases["expected"] %>', <%= camel_case(json["exercise"]) %>.<%= underscore(cases["property"]) %>('<%= cases["input"]["phrase"] %>') + assert_equal '<%= cases["expected"] %>', <%= camel_case(json["exercise"]) %>.<%= underscore(cases["property"]) %>('<%= cases["input"]["phrase"].gsub("'", "\\\\'") %>') end <% end %> end diff --git a/exercises/practice/acronym/acronym_test.rb b/exercises/practice/acronym/acronym_test.rb index 7dde064850..0716d5b5b8 100644 --- a/exercises/practice/acronym/acronym_test.rb +++ b/exercises/practice/acronym/acronym_test.rb @@ -36,4 +36,14 @@ def test_consecutive_delimiters skip assert_equal 'SIMUFTA', Acronym.abbreviate('Something - I made up from thin air') end + + def test_apostrophes + skip + assert_equal 'HC', Acronym.abbreviate('Halley\'s Comet') + end + + def test_underscore_emphasis + skip + assert_equal 'TRNT', Acronym.abbreviate('The Road _Not_ Taken') + end end diff --git a/exercises/practice/affine-cipher/.meta/test_template.erb b/exercises/practice/affine-cipher/.meta/test_template.erb new file mode 100644 index 0000000000..0a62fdb4e3 --- /dev/null +++ b/exercises/practice/affine-cipher/.meta/test_template.erb @@ -0,0 +1,26 @@ +require 'minitest/autorun' +require_relative 'affine_cipher' + +class AffineCipherTest < Minitest::Test +<% json["cases"].each do |group| %> + <% group["cases"].each do |sub_case| %> + def test_<%= underscore(sub_case["description"]) %> + <%= skip? %> + <%- if sub_case["expected"].is_a?(Hash) && sub_case["expected"].key?("error") -%> + assert_raises(ArgumentError) { Affine.new(<%= sub_case["input"]["key"]["a"] %>, <%= sub_case["input"]["key"]["b"] %>) } + <%- else -%> + cipher = Affine.new(<%= sub_case["input"]["key"]["a"] %>, <%= sub_case["input"]["key"]["b"] %>) + <%- if sub_case["property"] == "encode" -%> + plaintext = '<%= sub_case["input"]["phrase"] %>' + ciphertext = '<%= sub_case["expected"] %>' + assert_equal ciphertext, cipher.encode(plaintext) + <%- elsif sub_case["property"] == "decode" -%> + ciphertext = '<%= sub_case["input"]["phrase"] %>' + plaintext = '<%= sub_case["expected"] %>' + assert_equal plaintext, cipher.decode(ciphertext) + <%- end -%> + <%- end -%> + end + <% end %> +<% end %> +end diff --git a/exercises/practice/all-your-base/.meta/test_template.erb b/exercises/practice/all-your-base/.meta/test_template.erb new file mode 100644 index 0000000000..b1260006f0 --- /dev/null +++ b/exercises/practice/all-your-base/.meta/test_template.erb @@ -0,0 +1,26 @@ +require 'minitest/autorun' +require_relative 'all_your_base' + +class AllYourBaseTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + digits = <%= cases["input"]["digits"] %> + input_base = <%= cases["input"]["inputBase"] %> + output_base = <%= cases["input"]["outputBase"] %> + <% if cases["expected"].is_a?(Hash) && cases["expected"].key?("error") %> + assert_raises(ArgumentError) do + BaseConverter.convert(input_base, digits, output_base) + end + <% else %>expected = <%= cases["expected"] %> + + converted = BaseConverter.convert(input_base, digits, output_base) + + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." + + assert_equal expected, converted, hint + <% end %> + end + <% end %> +end diff --git a/exercises/practice/all-your-base/all_your_base_test.rb b/exercises/practice/all-your-base/all_your_base_test.rb index 3ef5f434e5..c565a75aec 100644 --- a/exercises/practice/all-your-base/all_your_base_test.rb +++ b/exercises/practice/all-your-base/all_your_base_test.rb @@ -11,8 +11,8 @@ def test_single_bit_one_to_decimal converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 2, output base 10. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -26,8 +26,8 @@ def test_binary_to_single_decimal converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 2, output base 10. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -41,8 +41,8 @@ def test_single_decimal_to_binary converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 10, output base 2. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -56,8 +56,8 @@ def test_binary_to_multiple_decimal converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 2, output base 10. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -71,8 +71,8 @@ def test_decimal_to_binary converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 10, output base 2. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -86,8 +86,8 @@ def test_trinary_to_hexadecimal converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 3, output base 16. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -101,8 +101,8 @@ def test_hexadecimal_to_trinary converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 16, output base 3. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -116,8 +116,8 @@ def test_15_bit_integer converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 97, output base 73. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -131,8 +131,8 @@ def test_empty_list converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 2, output base 10. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -146,8 +146,8 @@ def test_single_zero converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 10, output base 2. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -161,8 +161,8 @@ def test_multiple_zeros converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 10, output base 2. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -176,8 +176,8 @@ def test_leading_zeros converted = BaseConverter.convert(input_base, digits, output_base) - hint = "Input base: 7, output base 10. " \ - "Expected #{expected} but got #{converted}." + hint = "Input base: #{input_base}, output base #{output_base}. " \ + "Expected #{expected} but got #{converted}." assert_equal expected, converted, hint end @@ -187,6 +187,7 @@ def test_input_base_is_one digits = [0] input_base = 1 output_base = 10 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -197,6 +198,7 @@ def test_input_base_is_zero digits = [] input_base = 0 output_base = 10 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -207,6 +209,7 @@ def test_input_base_is_negative digits = [1] input_base = -2 output_base = 10 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -217,6 +220,7 @@ def test_negative_digit digits = [1, -1, 1, 0, 1, 0] input_base = 2 output_base = 10 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -227,6 +231,7 @@ def test_invalid_positive_digit digits = [1, 2, 1, 0, 1, 0] input_base = 2 output_base = 10 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -237,6 +242,7 @@ def test_output_base_is_one digits = [1, 0, 1, 0, 1, 0] input_base = 2 output_base = 1 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -247,6 +253,7 @@ def test_output_base_is_zero digits = [7] input_base = 10 output_base = 0 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -257,6 +264,7 @@ def test_output_base_is_negative digits = [1] input_base = 2 output_base = -7 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end @@ -267,6 +275,7 @@ def test_both_bases_are_negative digits = [1] input_base = -2 output_base = -7 + assert_raises(ArgumentError) do BaseConverter.convert(input_base, digits, output_base) end diff --git a/exercises/practice/allergies/.meta/test_template.erb b/exercises/practice/allergies/.meta/test_template.erb new file mode 100644 index 0000000000..70ddced656 --- /dev/null +++ b/exercises/practice/allergies/.meta/test_template.erb @@ -0,0 +1,19 @@ +require 'minitest/autorun' +require_relative 'allergies' + +class AllergiesTest < Minitest::Test +<% json["cases"].each do |group| %> + <% group["cases"].each do |sub_case| %> + def test_<%= underscore(group["description"]) %>_<%= underscore(sub_case["description"]) %> + <%= skip? %> + allergies = Allergies.new(<%= sub_case["input"]["score"] %>) + <%- if sub_case["property"] == "allergicTo" -%> + <%= sub_case["expected"] ? "assert" : "refute" %> allergies.allergic_to?('<%= sub_case["input"]["item"] %>'), 'Tom is<%= sub_case["expected"] ? "" : " not" %> allergic, but it says he is<%= sub_case["expected"] ? " not" : "" %>.' + <%- else -%> + expected = %w[<%= sub_case["expected"].join(" ") %>] + assert_equal expected, allergies.list + <% end %> + end + <% end %> + <% end %> +end diff --git a/exercises/practice/allergies/allergies_test.rb b/exercises/practice/allergies/allergies_test.rb index d5d244968f..f9e6e27c7c 100644 --- a/exercises/practice/allergies/allergies_test.rb +++ b/exercises/practice/allergies/allergies_test.rb @@ -5,300 +5,310 @@ class AllergiesTest < Minitest::Test def test_testing_for_eggs_allergy_not_allergic_to_anything # skip allergies = Allergies.new(0) - refute allergies.allergic_to?("eggs"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('eggs'), 'Tom is not allergic, but it says he is.' end def test_testing_for_eggs_allergy_allergic_only_to_eggs skip allergies = Allergies.new(1) - assert allergies.allergic_to?("eggs"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('eggs'), 'Tom is allergic, but it says he is not.' end def test_testing_for_eggs_allergy_allergic_to_eggs_and_something_else skip allergies = Allergies.new(3) - assert allergies.allergic_to?("eggs"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('eggs'), 'Tom is allergic, but it says he is not.' end def test_testing_for_eggs_allergy_allergic_to_something_but_not_eggs skip allergies = Allergies.new(2) - refute allergies.allergic_to?("eggs"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('eggs'), 'Tom is not allergic, but it says he is.' end def test_testing_for_eggs_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("eggs"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('eggs'), 'Tom is allergic, but it says he is not.' end def test_testing_for_peanuts_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("peanuts"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('peanuts'), 'Tom is not allergic, but it says he is.' end def test_testing_for_peanuts_allergy_allergic_only_to_peanuts skip allergies = Allergies.new(2) - assert allergies.allergic_to?("peanuts"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('peanuts'), 'Tom is allergic, but it says he is not.' end def test_testing_for_peanuts_allergy_allergic_to_peanuts_and_something_else skip allergies = Allergies.new(7) - assert allergies.allergic_to?("peanuts"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('peanuts'), 'Tom is allergic, but it says he is not.' end def test_testing_for_peanuts_allergy_allergic_to_something_but_not_peanuts skip allergies = Allergies.new(5) - refute allergies.allergic_to?("peanuts"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('peanuts'), 'Tom is not allergic, but it says he is.' end def test_testing_for_peanuts_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("peanuts"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('peanuts'), 'Tom is allergic, but it says he is not.' end def test_testing_for_shellfish_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("shellfish"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('shellfish'), 'Tom is not allergic, but it says he is.' end def test_testing_for_shellfish_allergy_allergic_only_to_shellfish skip allergies = Allergies.new(4) - assert allergies.allergic_to?("shellfish"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('shellfish'), 'Tom is allergic, but it says he is not.' end def test_testing_for_shellfish_allergy_allergic_to_shellfish_and_something_else skip allergies = Allergies.new(14) - assert allergies.allergic_to?("shellfish"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('shellfish'), 'Tom is allergic, but it says he is not.' end def test_testing_for_shellfish_allergy_allergic_to_something_but_not_shellfish skip allergies = Allergies.new(10) - refute allergies.allergic_to?("shellfish"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('shellfish'), 'Tom is not allergic, but it says he is.' end def test_testing_for_shellfish_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("shellfish"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('shellfish'), 'Tom is allergic, but it says he is not.' end def test_testing_for_strawberries_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("strawberries"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('strawberries'), 'Tom is not allergic, but it says he is.' end def test_testing_for_strawberries_allergy_allergic_only_to_strawberries skip allergies = Allergies.new(8) - assert allergies.allergic_to?("strawberries"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('strawberries'), 'Tom is allergic, but it says he is not.' end def test_testing_for_strawberries_allergy_allergic_to_strawberries_and_something_else skip allergies = Allergies.new(28) - assert allergies.allergic_to?("strawberries"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('strawberries'), 'Tom is allergic, but it says he is not.' end def test_testing_for_strawberries_allergy_allergic_to_something_but_not_strawberries skip allergies = Allergies.new(20) - refute allergies.allergic_to?("strawberries"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('strawberries'), 'Tom is not allergic, but it says he is.' end def test_testing_for_strawberries_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("strawberries"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('strawberries'), 'Tom is allergic, but it says he is not.' end def test_testing_for_tomatoes_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("tomatoes"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('tomatoes'), 'Tom is not allergic, but it says he is.' end def test_testing_for_tomatoes_allergy_allergic_only_to_tomatoes skip allergies = Allergies.new(16) - assert allergies.allergic_to?("tomatoes"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('tomatoes'), 'Tom is allergic, but it says he is not.' end def test_testing_for_tomatoes_allergy_allergic_to_tomatoes_and_something_else skip allergies = Allergies.new(56) - assert allergies.allergic_to?("tomatoes"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('tomatoes'), 'Tom is allergic, but it says he is not.' end def test_testing_for_tomatoes_allergy_allergic_to_something_but_not_tomatoes skip allergies = Allergies.new(40) - refute allergies.allergic_to?("tomatoes"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('tomatoes'), 'Tom is not allergic, but it says he is.' end def test_testing_for_tomatoes_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("tomatoes"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('tomatoes'), 'Tom is allergic, but it says he is not.' end def test_testing_for_chocolate_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("chocolate"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('chocolate'), 'Tom is not allergic, but it says he is.' end def test_testing_for_chocolate_allergy_allergic_only_to_chocolate skip allergies = Allergies.new(32) - assert allergies.allergic_to?("chocolate"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('chocolate'), 'Tom is allergic, but it says he is not.' end def test_testing_for_chocolate_allergy_allergic_to_chocolate_and_something_else skip allergies = Allergies.new(112) - assert allergies.allergic_to?("chocolate"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('chocolate'), 'Tom is allergic, but it says he is not.' end def test_testing_for_chocolate_allergy_allergic_to_something_but_not_chocolate skip allergies = Allergies.new(80) - refute allergies.allergic_to?("chocolate"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('chocolate'), 'Tom is not allergic, but it says he is.' end def test_testing_for_chocolate_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("chocolate"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('chocolate'), 'Tom is allergic, but it says he is not.' end def test_testing_for_pollen_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("pollen"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('pollen'), 'Tom is not allergic, but it says he is.' end def test_testing_for_pollen_allergy_allergic_only_to_pollen skip allergies = Allergies.new(64) - assert allergies.allergic_to?("pollen"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('pollen'), 'Tom is allergic, but it says he is not.' end def test_testing_for_pollen_allergy_allergic_to_pollen_and_something_else skip allergies = Allergies.new(224) - assert allergies.allergic_to?("pollen"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('pollen'), 'Tom is allergic, but it says he is not.' end def test_testing_for_pollen_allergy_allergic_to_something_but_not_pollen skip allergies = Allergies.new(160) - refute allergies.allergic_to?("pollen"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('pollen'), 'Tom is not allergic, but it says he is.' end def test_testing_for_pollen_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("pollen"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('pollen'), 'Tom is allergic, but it says he is not.' end def test_testing_for_cats_allergy_not_allergic_to_anything skip allergies = Allergies.new(0) - refute allergies.allergic_to?("cats"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('cats'), 'Tom is not allergic, but it says he is.' end def test_testing_for_cats_allergy_allergic_only_to_cats skip allergies = Allergies.new(128) - assert allergies.allergic_to?("cats"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('cats'), 'Tom is allergic, but it says he is not.' end def test_testing_for_cats_allergy_allergic_to_cats_and_something_else skip allergies = Allergies.new(192) - assert allergies.allergic_to?("cats"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('cats'), 'Tom is allergic, but it says he is not.' end def test_testing_for_cats_allergy_allergic_to_something_but_not_cats skip allergies = Allergies.new(64) - refute allergies.allergic_to?("cats"), "Tom is not allergic, but it says he is." + refute allergies.allergic_to?('cats'), 'Tom is not allergic, but it says he is.' end def test_testing_for_cats_allergy_allergic_to_everything skip allergies = Allergies.new(255) - assert allergies.allergic_to?("cats"), "Tom is allergic, but it says he is not." + assert allergies.allergic_to?('cats'), 'Tom is allergic, but it says he is not.' end def test_list_when_no_allergies skip - expected = [] - assert_equal expected, Allergies.new(0).list + allergies = Allergies.new(0) + expected = %w[] + assert_equal expected, allergies.list end def test_list_when_just_eggs skip - expected = ["eggs"] - assert_equal expected, Allergies.new(1).list + allergies = Allergies.new(1) + expected = %w[eggs] + assert_equal expected, allergies.list end def test_list_when_just_peanuts skip - expected = ["peanuts"] - assert_equal expected, Allergies.new(2).list + allergies = Allergies.new(2) + expected = %w[peanuts] + assert_equal expected, allergies.list end def test_list_when_just_strawberries skip - expected = ["strawberries"] - assert_equal expected, Allergies.new(8).list + allergies = Allergies.new(8) + expected = %w[strawberries] + assert_equal expected, allergies.list end def test_list_when_eggs_and_peanuts skip + allergies = Allergies.new(3) expected = %w[eggs peanuts] - assert_equal expected, Allergies.new(3).list + assert_equal expected, allergies.list end def test_list_when_more_than_eggs_but_not_peanuts skip + allergies = Allergies.new(5) expected = %w[eggs shellfish] - assert_equal expected, Allergies.new(5).list + assert_equal expected, allergies.list end def test_list_when_lots_of_stuff skip + allergies = Allergies.new(248) expected = %w[strawberries tomatoes chocolate pollen cats] - assert_equal expected, Allergies.new(248).list + assert_equal expected, allergies.list end def test_list_when_everything skip + allergies = Allergies.new(255) expected = %w[eggs peanuts shellfish strawberries tomatoes chocolate pollen cats] - assert_equal expected, Allergies.new(255).list + assert_equal expected, allergies.list end def test_list_when_no_allergen_score_parts skip + allergies = Allergies.new(509) expected = %w[eggs shellfish strawberries tomatoes chocolate pollen cats] - assert_equal expected, Allergies.new(509).list + assert_equal expected, allergies.list end def test_list_when_no_allergen_score_parts_without_highest_valid_score skip - expected = ["eggs"] - assert_equal expected, Allergies.new(257).list + allergies = Allergies.new(257) + expected = %w[eggs] + assert_equal expected, allergies.list end end diff --git a/exercises/practice/anagram/.meta/test_template.erb b/exercises/practice/anagram/.meta/test_template.erb new file mode 100644 index 0000000000..003e246495 --- /dev/null +++ b/exercises/practice/anagram/.meta/test_template.erb @@ -0,0 +1,15 @@ +require 'minitest/autorun' +require_relative 'anagram' + +class AnagramTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + detector = Anagram.new('<%= cases["input"]["subject"] %>') + anagrams = detector.match(%w[<%= cases["input"]["candidates"].join(" ") %>]) + expected = %w[<%= cases["expected"].join(" ") %>] + + assert_equal expected, anagrams + end + <% end %> +end diff --git a/exercises/practice/anagram/.meta/tests.toml b/exercises/practice/anagram/.meta/tests.toml index 4d90562705..8b680daca3 100644 --- a/exercises/practice/anagram/.meta/tests.toml +++ b/exercises/practice/anagram/.meta/tests.toml @@ -81,6 +81,8 @@ reimplements = "a0705568-628c-4b55-9798-82e4acde51ca" [a6854f66-eec1-4afd-a137-62ef2870c051] description = "handles case of greek letters" +include = false [fd3509e5-e3ba-409d-ac3d-a9ac84d13296] description = "different characters may have the same bytes" +include = false diff --git a/exercises/practice/anagram/anagram_test.rb b/exercises/practice/anagram/anagram_test.rb index cd5f4fc98c..93bbdd3a9a 100644 --- a/exercises/practice/anagram/anagram_test.rb +++ b/exercises/practice/anagram/anagram_test.rb @@ -4,129 +4,145 @@ class AnagramTest < Minitest::Test def test_no_matches # skip - detector = Anagram.new("diaper") + detector = Anagram.new('diaper') anagrams = detector.match(%w[hello world zombies pants]) - expected = [] + expected = %w[] + assert_equal expected, anagrams end def test_detects_two_anagrams skip - detector = Anagram.new("solemn") + detector = Anagram.new('solemn') anagrams = detector.match(%w[lemons cherry melons]) expected = %w[lemons melons] + assert_equal expected, anagrams end def test_does_not_detect_anagram_subsets skip - detector = Anagram.new("good") + detector = Anagram.new('good') anagrams = detector.match(%w[dog goody]) - expected = [] + expected = %w[] + assert_equal expected, anagrams end def test_detects_anagram skip - detector = Anagram.new("listen") + detector = Anagram.new('listen') anagrams = detector.match(%w[enlists google inlets banana]) - expected = ["inlets"] + expected = %w[inlets] + assert_equal expected, anagrams end def test_detects_three_anagrams skip - detector = Anagram.new("allergy") + detector = Anagram.new('allergy') anagrams = detector.match(%w[gallery ballerina regally clergy largely leading]) expected = %w[gallery regally largely] + assert_equal expected, anagrams end def test_detects_multiple_anagrams_with_different_case skip - detector = Anagram.new("nose") + detector = Anagram.new('nose') anagrams = detector.match(%w[Eons ONES]) expected = %w[Eons ONES] + assert_equal expected, anagrams end def test_does_not_detect_non_anagrams_with_identical_checksum skip - detector = Anagram.new("mass") - anagrams = detector.match(["last"]) - expected = [] + detector = Anagram.new('mass') + anagrams = detector.match(%w[last]) + expected = %w[] + assert_equal expected, anagrams end def test_detects_anagrams_case_insensitively skip - detector = Anagram.new("Orchestra") + detector = Anagram.new('Orchestra') anagrams = detector.match(%w[cashregister Carthorse radishes]) - expected = ["Carthorse"] + expected = %w[Carthorse] + assert_equal expected, anagrams end def test_detects_anagrams_using_case_insensitive_subject skip - detector = Anagram.new("Orchestra") + detector = Anagram.new('Orchestra') anagrams = detector.match(%w[cashregister carthorse radishes]) - expected = ["carthorse"] + expected = %w[carthorse] + assert_equal expected, anagrams end def test_detects_anagrams_using_case_insensitive_possible_matches skip - detector = Anagram.new("orchestra") + detector = Anagram.new('orchestra') anagrams = detector.match(%w[cashregister Carthorse radishes]) - expected = ["Carthorse"] + expected = %w[Carthorse] + assert_equal expected, anagrams end def test_does_not_detect_an_anagram_if_the_original_word_is_repeated skip - detector = Anagram.new("go") - anagrams = detector.match(["go Go GO"]) - expected = [] + detector = Anagram.new('go') + anagrams = detector.match(%w[goGoGO]) + expected = %w[] + assert_equal expected, anagrams end def test_anagrams_must_use_all_letters_exactly_once skip - detector = Anagram.new("tapper") - anagrams = detector.match(["patter"]) - expected = [] + detector = Anagram.new('tapper') + anagrams = detector.match(%w[patter]) + expected = %w[] + assert_equal expected, anagrams end def test_words_are_not_anagrams_of_themselves skip - detector = Anagram.new("BANANA") - anagrams = detector.match(["BANANA"]) - expected = [] + detector = Anagram.new('BANANA') + anagrams = detector.match(%w[BANANA]) + expected = %w[] + assert_equal expected, anagrams end def test_words_are_not_anagrams_of_themselves_even_if_letter_case_is_partially_different skip - detector = Anagram.new("BANANA") - anagrams = detector.match(["Banana"]) - expected = [] + detector = Anagram.new('BANANA') + anagrams = detector.match(%w[Banana]) + expected = %w[] + assert_equal expected, anagrams end def test_words_are_not_anagrams_of_themselves_even_if_letter_case_is_completely_different skip - detector = Anagram.new("BANANA") - anagrams = detector.match(["banana"]) - expected = [] + detector = Anagram.new('BANANA') + anagrams = detector.match(%w[banana]) + expected = %w[] + assert_equal expected, anagrams end def test_words_other_than_themselves_can_be_anagrams skip - detector = Anagram.new("LISTEN") + detector = Anagram.new('LISTEN') anagrams = detector.match(%w[LISTEN Silent]) - expected = ["Silent"] + expected = %w[Silent] + assert_equal expected, anagrams end end diff --git a/exercises/practice/armstrong-numbers/.meta/test_template.erb b/exercises/practice/armstrong-numbers/.meta/test_template.erb new file mode 100644 index 0000000000..a39a63b2a7 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/test_template.erb @@ -0,0 +1,11 @@ +require 'minitest/autorun' +require_relative 'armstrong_numbers' + +class ArmstrongNumbersTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + <%= cases["expected"] ? "assert_includes" : "refute_includes" %> ArmstrongNumbers, <%= cases["input"]["number"] %> + end + <% end %> +end diff --git a/exercises/practice/atbash-cipher/.meta/test_template.erb b/exercises/practice/atbash-cipher/.meta/test_template.erb new file mode 100644 index 0000000000..f0f0ac9e1e --- /dev/null +++ b/exercises/practice/atbash-cipher/.meta/test_template.erb @@ -0,0 +1,21 @@ +require 'minitest/autorun' +require_relative 'armstrong_numbers' + +class ArmstrongNumbersTest < Minitest::Test +<% json["cases"].each do |cases| %> + <% cases["cases"].each do |sub_case| %> + def test_<%= underscore(sub_case["description"]) %> + <%= skip? %> + <%- if sub_case["property"] == "encode" -%> + plaintext = '<%= sub_case["input"]["phrase"] %>' + ciphertext = '<%= sub_case["expected"] %>' + assert_equal ciphertext, Atbash.encode(plaintext) + <%- else -%> + ciphertext = '<%= sub_case["input"]["phrase"] %>' + plaintext = '<%= sub_case["expected"] %>' + assert_equal plaintext, Atbash.decode(ciphertext) + <% end %> + end + <% end %> +<% end %> +end diff --git a/exercises/practice/bank-account/.meta/test_template.erb b/exercises/practice/bank-account/.meta/test_template.erb new file mode 100644 index 0000000000..7bda18768f --- /dev/null +++ b/exercises/practice/bank-account/.meta/test_template.erb @@ -0,0 +1,43 @@ +require 'minitest/autorun' +require_relative 'bank_account' + +class BankAccountTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + bank_account = BankAccount.new + <%- cases["input"]["operations"][...-1].each do |operation| -%> + <%- if operation["operation"] == "open" -%> + bank_account.open + <%- elsif operation["operation"] == "close" -%> + bank_account.close + <%- elsif operation["operation"] == "deposit" -%> + bank_account.deposit(<%= operation["amount"] %>) + <%- elsif operation["operation"] == "withdraw" -%> + bank_account.withdraw(<%= operation["amount"] %>) + <%- end -%> + <%- end -%> + <%- if cases["expected"].is_a?(Hash) && cases["expected"].key?("error") -%> + assert_raises(ArgumentError, <%- if cases["expected"]["error"] == "account not open" && cases["input"]["operations"][-1]["operation"] == "balance" -%> + "You can't check the balance of a closed account" + <%- elsif cases["expected"]["error"] == "account not open" && cases["input"]["operations"][-1]["operation"] == "withdraw" -%> + "You can't withdraw money into a closed account" + <%- elsif cases["expected"]["error"] == "account not open" && cases["input"]["operations"][-1]["operation"] == "deposit" -%> + "You can't deposit money into a closed account" + <%- elsif cases["expected"]["error"] == "account not open" -%> + "You can't close an already closed account" + <%- elsif cases["expected"]["error"] == "account already open" -%> + "You can't open an already open account" + <%- elsif cases["expected"]["error"] == "amount must be less than balance" -%> + "You can't withdraw more than you have" + <%- elsif cases["expected"]["error"] == "amount must be greater than 0" && cases["input"]["operations"][-1]["operation"] == "withdraw" -%> + "You can't withdraw a negative amount" + <%- elsif cases["expected"]["error"] == "amount must be greater than 0" -%> + "You can't deposit a negative amount" + <%- end -%> ) { bank_account.<%= cases["input"]["operations"][-1]["operation"]%>(<%= cases["input"]["operations"][-1]["amount"] %>) } + <%- else -%> + assert_equal <%= cases["expected"] %>, bank_account.balance + <%- end -%> + end +<% end %> +end diff --git a/exercises/practice/bank-account/.meta/tests.toml b/exercises/practice/bank-account/.meta/tests.toml index 655ea7ae5a..1704a08c5a 100644 --- a/exercises/practice/bank-account/.meta/tests.toml +++ b/exercises/practice/bank-account/.meta/tests.toml @@ -59,4 +59,4 @@ description = "Cannot deposit negative" [ba0c1e0b-0f00-416f-8097-a7dfc97871ff] description = "Can handle concurrent transactions" -include = false \ No newline at end of file +include = false diff --git a/exercises/practice/bank-account/bank_account_test.rb b/exercises/practice/bank-account/bank_account_test.rb index edc44b4559..926b987c6d 100644 --- a/exercises/practice/bank-account/bank_account_test.rb +++ b/exercises/practice/bank-account/bank_account_test.rb @@ -6,7 +6,7 @@ def test_newly_opened_account_has_zero_balance # skip bank_account = BankAccount.new bank_account.open - assert_equal bank_account.balance, 0 + assert_equal 0, bank_account.balance end def test_single_deposit diff --git a/exercises/practice/binary-search/.meta/test_template.erb b/exercises/practice/binary-search/.meta/test_template.erb new file mode 100644 index 0000000000..27b55b5a33 --- /dev/null +++ b/exercises/practice/binary-search/.meta/test_template.erb @@ -0,0 +1,16 @@ +require 'minitest/autorun' +require_relative 'binary_search' + +class BinarySearchTest < Minitest::Test +<% json["cases"].each do |cases| %> + def test_<%= underscore(cases["description"]) %> + <%= skip? %> + binary = BinarySearch.new(<%= cases["input"]["array"] %>) + <%- if cases["expected"].is_a?(Hash) && cases["expected"].key?("error") -%> + assert_nil binary.search_for(<%= cases["input"]["value"] %>) + <%- else -%> + assert_equal <%= cases["expected"] %>, binary.search_for(<%= cases["input"]["value"] %>) + <%- end -%> + end + <% end %> +end diff --git a/exercises/practice/binary-search/binary_search_test.rb b/exercises/practice/binary-search/binary_search_test.rb index bc928a666c..6f9c9ebd4b 100644 --- a/exercises/practice/binary-search/binary_search_test.rb +++ b/exercises/practice/binary-search/binary_search_test.rb @@ -44,13 +44,13 @@ def test_identifies_that_a_value_is_not_included_in_the_array assert_nil binary.search_for(7) end - def test_a_value_smaller_than_the_array_s_smallest_value_is_not_found + def test_a_value_smaller_than_the_arrays_smallest_value_is_not_found skip binary = BinarySearch.new([1, 3, 4, 6, 8, 9, 11]) assert_nil binary.search_for(0) end - def test_a_value_larger_than_the_array_s_largest_value_is_not_found + def test_a_value_larger_than_the_arrays_largest_value_is_not_found skip binary = BinarySearch.new([1, 3, 4, 6, 8, 9, 11]) assert_nil binary.search_for(13) diff --git a/generatorv2/lib/generator.rb b/generatorv2/lib/generator.rb index a0d669e929..5f15b0b43c 100644 --- a/generatorv2/lib/generator.rb +++ b/generatorv2/lib/generator.rb @@ -21,17 +21,17 @@ def generate(result_path = "./exercises/practice/#{@exercise}/#{underscore(@exer additional_json(json) json["cases"] = remove_tests(uuid, json) status = proc { status } - template = ERB.new File.read("./exercises/practice/#{@exercise}/.meta/test_template.erb") + template = ERB.new(File.read("./exercises/practice/#{@exercise}/.meta/test_template.erb"), trim_mode: '-') result = template.result(binding) File.write(result_path, result) RuboCop::CLI.new. - run(['-x', '-c', '.rubocop.yml', '-o', NullDevice.path, result_path]) + run(['-a', '-c', '.rubocop.yml', '-o', NullDevice.path, result_path]) end def underscore(str) - str.gsub(/[-\s]/, '_').downcase + str.gsub(/[^\w\s-]/, '').gsub(' ', ' ').gsub(/[-\s]/, '_').downcase end def camel_case(str) diff --git a/generatorv2/lib/utils.rb b/generatorv2/lib/utils.rb index d6b80971e6..a728848e8c 100644 --- a/generatorv2/lib/utils.rb +++ b/generatorv2/lib/utils.rb @@ -47,7 +47,7 @@ def additional_json(json) def remove_tests(uuid, json) json["cases"].each_with_object([]) do |x, acc| if x["cases"] - acc << { "cases" => remove_tests(uuid, x) } + acc << { "cases" => remove_tests(uuid, x), "description" => x["description"] } elsif uuid.include?(x["uuid"]) acc << x end diff --git a/generatorv2/test/utils_test.rb b/generatorv2/test/utils_test.rb index 235021882c..944e0b66b8 100644 --- a/generatorv2/test/utils_test.rb +++ b/generatorv2/test/utils_test.rb @@ -22,6 +22,16 @@ def test_underscore_with_two_words Generator.new("two-fer").underscore("two-fer") end + def test_underscore_with_special_characters + assert_equal "two_fer", + Generator.new("two-fer").underscore("two,!@#$%^&*()-fer") + end + + def test_underscore_with_special_characters_should_not_create_multiple_spaces + assert_equal "two_fer", + Generator.new("two-fer").underscore("two = fer") + end + def test_first_time_includes_hastag assert_equal "# skip", Generator.new("acronym").skip? From 2f59845a5ec458ac801eccf0f0ed550ece95c1a9 Mon Sep 17 00:00:00 2001 From: meatball Date: Sun, 31 Aug 2025 23:16:20 +0200 Subject: [PATCH 3/5] Fix formatting in dominoes --- exercises/practice/dominoes/dominoes_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/dominoes/dominoes_test.rb b/exercises/practice/dominoes/dominoes_test.rb index 23c95f6aec..61bd05ef35 100644 --- a/exercises/practice/dominoes/dominoes_test.rb +++ b/exercises/practice/dominoes/dominoes_test.rb @@ -2,13 +2,13 @@ require_relative 'dominoes' class DominoesTest < Minitest::Test - def test_empty_input__empty_output + def test_empty_input_empty_output # skip dominoes = [] assert Dominoes.chain?(dominoes) end - def test_singleton_input__singleton_output + def test_singleton_input_singleton_output skip dominoes = [[1, 1]] assert Dominoes.chain?(dominoes) From 0629588da425c9994542b0345f4d8e917236e68c Mon Sep 17 00:00:00 2001 From: meatball Date: Tue, 2 Sep 2025 20:13:06 +0200 Subject: [PATCH 4/5] Add EOL --- exercises/practice/dominoes/.meta/test_template.erb | 2 +- exercises/practice/eliuds-eggs/.meta/test_template.erb | 2 +- exercises/practice/etl/.meta/test_template.erb | 2 +- exercises/practice/flatten-array/.meta/test_template.erb | 2 +- exercises/practice/flower-field/.meta/test_template.erb | 2 +- exercises/practice/gigasecond/.meta/test_template.erb | 2 +- exercises/practice/grains/.meta/test_template.erb | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/practice/dominoes/.meta/test_template.erb b/exercises/practice/dominoes/.meta/test_template.erb index 1882c94bed..a7e57e72db 100644 --- a/exercises/practice/dominoes/.meta/test_template.erb +++ b/exercises/practice/dominoes/.meta/test_template.erb @@ -9,4 +9,4 @@ class DominoesTest < Minitest::Test <%= cases["expected"] ? "assert" : "refute" %> Dominoes.chain?(dominoes) end <% end %> -end \ No newline at end of file +end diff --git a/exercises/practice/eliuds-eggs/.meta/test_template.erb b/exercises/practice/eliuds-eggs/.meta/test_template.erb index eac36876f8..4cc351712b 100644 --- a/exercises/practice/eliuds-eggs/.meta/test_template.erb +++ b/exercises/practice/eliuds-eggs/.meta/test_template.erb @@ -8,4 +8,4 @@ class EliudsEggsTest < Minitest::Test assert_equal <%= cases["expected"] %>, EliudsEggs.egg_count(<%= cases["input"]["number"] %>) end <% end %> -end \ No newline at end of file +end diff --git a/exercises/practice/etl/.meta/test_template.erb b/exercises/practice/etl/.meta/test_template.erb index c8341f253f..ec6e1fb882 100644 --- a/exercises/practice/etl/.meta/test_template.erb +++ b/exercises/practice/etl/.meta/test_template.erb @@ -18,4 +18,4 @@ class EtlTest < Minitest::Test assert_equal expected, ETL.transform(old) end <% end %> -end \ No newline at end of file +end diff --git a/exercises/practice/flatten-array/.meta/test_template.erb b/exercises/practice/flatten-array/.meta/test_template.erb index a1fd861761..4fb0031b9b 100644 --- a/exercises/practice/flatten-array/.meta/test_template.erb +++ b/exercises/practice/flatten-array/.meta/test_template.erb @@ -9,4 +9,4 @@ class FlattenArrayTest < Minitest::Test assert_equal <%= cases["expected"] %>, flat_array end <% end %> -end \ No newline at end of file +end diff --git a/exercises/practice/flower-field/.meta/test_template.erb b/exercises/practice/flower-field/.meta/test_template.erb index 9aa654e1df..cfbbf02955 100644 --- a/exercises/practice/flower-field/.meta/test_template.erb +++ b/exercises/practice/flower-field/.meta/test_template.erb @@ -10,4 +10,4 @@ class FlowerFieldTest < Minitest::Test assert_equal expected, FlowerField.annotate(input) end <% end %> -end \ No newline at end of file +end diff --git a/exercises/practice/gigasecond/.meta/test_template.erb b/exercises/practice/gigasecond/.meta/test_template.erb index 814b548f49..fdb716f417 100644 --- a/exercises/practice/gigasecond/.meta/test_template.erb +++ b/exercises/practice/gigasecond/.meta/test_template.erb @@ -9,4 +9,4 @@ class GigasecondTest < Minitest::Test assert_equal Time.parse('<%= cases["expected"] %> UTC'), Gigasecond.from(Time.parse('<%= cases["input"]["moment"] %><%= cases["input"]["moment"].include?('T') ? '' : 'T00:00:00' %> UTC')) end <% end %> -end \ No newline at end of file +end diff --git a/exercises/practice/grains/.meta/test_template.erb b/exercises/practice/grains/.meta/test_template.erb index b6340168e9..b9c5ade6dd 100644 --- a/exercises/practice/grains/.meta/test_template.erb +++ b/exercises/practice/grains/.meta/test_template.erb @@ -23,4 +23,4 @@ class GrainsTest < Minitest::Test end <%- end -%> <% end %> -end \ No newline at end of file +end From e5b37889be99575c50941aeb1d0a89021786e37c Mon Sep 17 00:00:00 2001 From: meatball Date: Sun, 7 Sep 2025 13:13:13 +0200 Subject: [PATCH 5/5] remove trailing spaces --- exercises/practice/eliuds-eggs/.meta/test_template.erb | 2 +- exercises/practice/etl/.meta/test_template.erb | 2 +- exercises/practice/flatten-array/.meta/test_template.erb | 2 +- exercises/practice/flower-field/.meta/test_template.erb | 2 +- exercises/practice/gigasecond/.meta/test_template.erb | 2 +- exercises/practice/grains/.meta/test_template.erb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/practice/eliuds-eggs/.meta/test_template.erb b/exercises/practice/eliuds-eggs/.meta/test_template.erb index 4cc351712b..99186c907c 100644 --- a/exercises/practice/eliuds-eggs/.meta/test_template.erb +++ b/exercises/practice/eliuds-eggs/.meta/test_template.erb @@ -4,7 +4,7 @@ require_relative 'eliuds_eggs' class EliudsEggsTest < Minitest::Test <% json["cases"].each do |cases| %> def test_<%= underscore(cases["description"]) %> - <%= skip? %> + <%= skip? %> assert_equal <%= cases["expected"] %>, EliudsEggs.egg_count(<%= cases["input"]["number"] %>) end <% end %> diff --git a/exercises/practice/etl/.meta/test_template.erb b/exercises/practice/etl/.meta/test_template.erb index ec6e1fb882..91eaefbbfc 100644 --- a/exercises/practice/etl/.meta/test_template.erb +++ b/exercises/practice/etl/.meta/test_template.erb @@ -4,7 +4,7 @@ require_relative 'etl' class EtlTest < Minitest::Test <% json["cases"].each do |cases| %> def test_<%= underscore(cases["description"]) %> - <%= skip? %> + <%= skip? %> old = { <% cases["input"]["legacy"].each do |key, value| -%> <%= key %> => <%= value %>, diff --git a/exercises/practice/flatten-array/.meta/test_template.erb b/exercises/practice/flatten-array/.meta/test_template.erb index 4fb0031b9b..3ceef0c430 100644 --- a/exercises/practice/flatten-array/.meta/test_template.erb +++ b/exercises/practice/flatten-array/.meta/test_template.erb @@ -4,7 +4,7 @@ require_relative 'flatten_array' class FlattenArrayTest < Minitest::Test <% json["cases"].each do |cases| %> def test_<%= underscore(cases["description"]) %> - <%= skip? %> + <%= skip? %> flat_array = FlattenArray.flatten(<%= cases["input"]["array"] %>) assert_equal <%= cases["expected"] %>, flat_array end diff --git a/exercises/practice/flower-field/.meta/test_template.erb b/exercises/practice/flower-field/.meta/test_template.erb index cfbbf02955..0157e35a41 100644 --- a/exercises/practice/flower-field/.meta/test_template.erb +++ b/exercises/practice/flower-field/.meta/test_template.erb @@ -4,7 +4,7 @@ require_relative 'flower_field' class FlowerFieldTest < Minitest::Test <% json["cases"].each do |cases| %> def test_<%= underscore(cases["description"]) %> - <%= skip? %> + <%= skip? %> input = <%= cases["input"]["garden"] %> expected = <%= cases["expected"] %> assert_equal expected, FlowerField.annotate(input) diff --git a/exercises/practice/gigasecond/.meta/test_template.erb b/exercises/practice/gigasecond/.meta/test_template.erb index fdb716f417..0715771f7c 100644 --- a/exercises/practice/gigasecond/.meta/test_template.erb +++ b/exercises/practice/gigasecond/.meta/test_template.erb @@ -5,7 +5,7 @@ require 'time' class GigasecondTest < Minitest::Test <% json["cases"].each do |cases| %> def test_<%= underscore(cases["description"]) %> - <%= skip? %> + <%= skip? %> assert_equal Time.parse('<%= cases["expected"] %> UTC'), Gigasecond.from(Time.parse('<%= cases["input"]["moment"] %><%= cases["input"]["moment"].include?('T') ? '' : 'T00:00:00' %> UTC')) end <% end %> diff --git a/exercises/practice/grains/.meta/test_template.erb b/exercises/practice/grains/.meta/test_template.erb index b9c5ade6dd..ffb764c893 100644 --- a/exercises/practice/grains/.meta/test_template.erb +++ b/exercises/practice/grains/.meta/test_template.erb @@ -6,7 +6,7 @@ class GrainsTest < Minitest::Test <%- if cases["cases"] -%> <% cases["cases"].each do |sub_case| %> def test_<%= underscore(sub_case["description"]) %> - <%= skip? %> + <%= skip? %> <%- if sub_case["expected"].is_a?(Hash) && sub_case["expected"].key?("error") -%> assert_raises(ArgumentError) do Grains.square(<%= sub_case["input"]["square"] %>)