diff --git a/exercises/anagram/.meta/generator/anagram_case.rb b/exercises/anagram/.meta/generator/anagram_case.rb index 1cff0f77ed..161072dbd0 100644 --- a/exercises/anagram/.meta/generator/anagram_case.rb +++ b/exercises/anagram/.meta/generator/anagram_case.rb @@ -13,7 +13,7 @@ def indent_lines(code, indent = 2) end def show_comment - "# #{comment}" unless comment.nil? + "# #{comment}" if respond_to?(:comment) end def detector diff --git a/exercises/beer-song/.meta/generator/beer_song_case.rb b/exercises/beer-song/.meta/generator/beer_song_case.rb index 4b4f2e4649..fa41300405 100644 --- a/exercises/beer-song/.meta/generator/beer_song_case.rb +++ b/exercises/beer-song/.meta/generator/beer_song_case.rb @@ -17,7 +17,7 @@ def beer_song_arguments if property == 'verse' number else - "%s, %s" % [self["beginning"], self["end"]] + "%s, %s" % [self.beginning, self.end] end end end diff --git a/exercises/clock/.meta/generator/clock_case.rb b/exercises/clock/.meta/generator/clock_case.rb index 4d52ea079c..f8aa326074 100644 --- a/exercises/clock/.meta/generator/clock_case.rb +++ b/exercises/clock/.meta/generator/clock_case.rb @@ -29,7 +29,7 @@ def simple_test end def add_to_clock - " + #{add}" if add + " + #{add}" if respond_to?(:add) end end diff --git a/exercises/connect/.meta/generator/connect_case.rb b/exercises/connect/.meta/generator/connect_case.rb index e1b4b8a2fc..0bb766c1b1 100644 --- a/exercises/connect/.meta/generator/connect_case.rb +++ b/exercises/connect/.meta/generator/connect_case.rb @@ -19,7 +19,4 @@ def single_quote(string) string.inspect.tr('"', "'") end - def ignore_method_length - "# rubocop:disable MethodLength\n " if board.length > 8 - end end diff --git a/exercises/connect/.meta/generator/test_template.erb b/exercises/connect/.meta/generator/test_template.erb index 8fb2c0b11e..17ef595630 100644 --- a/exercises/connect/.meta/generator/test_template.erb +++ b/exercises/connect/.meta/generator/test_template.erb @@ -5,7 +5,7 @@ require_relative 'connect' # Common test data version: <%= canonical_data_version %> <%= abbreviated_commit_hash %> class ConnectTest < Minitest::Test <% test_cases.each_with_index do |test_case, idx| %> - <%= test_case.ignore_method_length%>def <%= test_case.name %> + def <%= test_case.name %> <%= test_case.skipped(idx) %><% test_case.test_body.each do |line| %> <%= line %><% end %> end diff --git a/exercises/wordy/.meta/generator/wordy_case.rb b/exercises/wordy/.meta/generator/wordy_case.rb index 18d73ec7c7..2b99daa31d 100644 --- a/exercises/wordy/.meta/generator/wordy_case.rb +++ b/exercises/wordy/.meta/generator/wordy_case.rb @@ -16,7 +16,7 @@ def indent(size, lines) end def assertion - return error_assertion unless expected + return error_assertion if expected == false return message_assertion if message "assert_equal(#{expected}, WordProblem.new(question).answer)" diff --git a/lib/generator/case_values.rb b/lib/generator/case_values.rb index a7e9b6ba78..27ff0a05f6 100644 --- a/lib/generator/case_values.rb +++ b/lib/generator/case_values.rb @@ -7,7 +7,7 @@ def initialize(case_class:) def cases(exercise_data) extract_test_cases(data: JSON.parse(exercise_data)['cases']) - .map { |test| @case_class.new(test) } + .map { |case_properties| @case_class.new(canonical: OpenStruct.new(case_properties)) } end private diff --git a/lib/generator/exercise_case.rb b/lib/generator/exercise_case.rb index edd79b6ce0..6278494adb 100644 --- a/lib/generator/exercise_case.rb +++ b/lib/generator/exercise_case.rb @@ -1,17 +1,31 @@ require 'ostruct' module Generator - class ExerciseCase < OpenStruct + class ExerciseCase using Generator::Underscore include CaseHelpers include Assertion + attr_reader :canonical + def initialize(canonical:) + @canonical = canonical + end + def name - 'test_%s' % description.underscore + 'test_%s' % canonical.description.underscore end def skipped(index) index.zero? ? '# skip' : 'skip' end + + def method_missing(sym, *args, &block) + return canonical.send(sym) if canonical.respond_to?(sym) + super(sym, *args, &block) + end + + def respond_to?(sym, include_private = false) + canonical.respond_to?(sym) || super + end end end diff --git a/lib/generator/exercise_case/assertion.rb b/lib/generator/exercise_case/assertion.rb index fef1a774f5..759764d50f 100644 --- a/lib/generator/exercise_case/assertion.rb +++ b/lib/generator/exercise_case/assertion.rb @@ -14,7 +14,7 @@ module Assertion # "#{assert} Luhn.valid?(#{input.inspect})" # def assert - expected ? 'assert' : 'refute' + canonical.expected ? 'assert' : 'refute' end # generates assertions of the form @@ -29,8 +29,8 @@ def assert # assert_equal { "PigLatin.translate(#{input.inspect})" } # def assert_equal - assertion = expected.nil? ? 'assert_nil' : - "assert_equal #{expected.inspect}," + assertion = canonical.expected.nil? ? 'assert_nil' : + "assert_equal #{canonical.expected.inspect}," "#{assertion} #{yield}" end @@ -43,7 +43,7 @@ def assert_equal # end # def raises_error? - expected.to_i == -1 + canonical.expected.to_i == -1 end # generates assertions of the form diff --git a/test/fixtures/xruby/exercises/alpha/.meta/generator/alpha_case.rb b/test/fixtures/xruby/exercises/alpha/.meta/generator/alpha_case.rb index 709f9d9e64..deacfe3f72 100644 --- a/test/fixtures/xruby/exercises/alpha/.meta/generator/alpha_case.rb +++ b/test/fixtures/xruby/exercises/alpha/.meta/generator/alpha_case.rb @@ -1,6 +1,6 @@ class AlphaCase < Generator::ExerciseCase def name - format('test_%s', description.downcase.gsub(/[ -]/, '_')) + format('test_%s', canonical.description.downcase.gsub(/[ -]/, '_')) end def workload diff --git a/test/generator/case_values_test.rb b/test/generator/case_values_test.rb index a6c2d9f3ba..43b400f77b 100644 --- a/test/generator/case_values_test.rb +++ b/test/generator/case_values_test.rb @@ -16,14 +16,35 @@ def test_multi_level_auto_extraction ).cases(canonical_data) expected = [ - ComplexCase.new(description: 'first generic verse', property: 'verse', number: 99, - expected: '99 bottles of beer on the wall, YAAAR'), - ComplexCase.new(description: 'last generic verse', property: 'verse', number: 3, - expected: '3 bottles of beer on the wall, YAAAR'), - ComplexCase.new(description: 'first two verses', property: 'verses', beginning: 99, end: 98, - expected: "99 bottles of beer on the wall, YAR, PIRATES CAN'T COUNT") + ComplexCase.new( + canonical: { + 'description' => 'first generic verse', + 'property' => 'verse', + 'number' => 99, + 'expected' => '99 bottles of beer on the wall, YAAAR' + } + ), + ComplexCase.new( + canonical: { + 'description' => 'last generic verse', + 'property' => 'verse', + 'number' => 3, + 'expected' => '3 bottles of beer on the wall, YAAAR' + } + ), + ComplexCase.new( + canonical: { + 'description' => 'first two verses', + 'property' => 'verses', + 'beginning' => 99, + 'end' => 98, + 'expected' => "99 bottles of beer on the wall, YAR, PIRATES CAN'T COUNT" + } + ) ] - assert_equal expected, cases + assert expected.zip(cases).all? do |exp, cs| + assert_equal exp.canonical, cs.canonical + end end end end diff --git a/test/generator/exercise_case/assertion_test.rb b/test/generator/exercise_case/assertion_test.rb index ab37778cfa..d1057e6d1c 100644 --- a/test/generator/exercise_case/assertion_test.rb +++ b/test/generator/exercise_case/assertion_test.rb @@ -4,43 +4,43 @@ module Generator class ExerciseCase class AssertionTest < Minitest::Test def test_assert - test_case = OpenStruct.new(expected: true) + test_case = ExerciseCase.new(canonical: OpenStruct.new({'expected' => true})) test_case.extend(Assertion) assert_equal 'assert', test_case.assert end def test_refute - test_case = OpenStruct.new(expected: false) + test_case = ExerciseCase.new(canonical: OpenStruct.new({'expected' => false})) test_case.extend(Assertion) assert_equal 'refute', test_case.assert end def test_assert_equal - test_case = OpenStruct.new(expected: 2) + test_case = ExerciseCase.new(canonical: OpenStruct.new({'expected' => 2})) test_case.extend(Assertion) assert_equal "assert_equal 2, 4", test_case.assert_equal { 1 + 3 } end def test_assert_equal_when_nil - test_case = OpenStruct.new(expected: nil) + test_case = ExerciseCase.new(canonical: OpenStruct.new({'expected' => nil})) test_case.extend(Assertion) assert_equal "assert_nil 4", test_case.assert_equal { 1 + 3 } end def test_raises_error - test_case = OpenStruct.new(expected: -1) + test_case = ExerciseCase.new(canonical: OpenStruct.new({'expected' => -1})) test_case.extend(Assertion) assert test_case.raises_error? end def test_does_not_raise_error - test_case = OpenStruct.new(expected: 'cute kitties') + test_case = ExerciseCase.new(canonical: OpenStruct.new({'expected' => 'cute kitties'})) test_case.extend(Assertion) refute test_case.raises_error? end def test_assert_raises - test_case = OpenStruct.new + test_case = ExerciseCase.new(canonical: OpenStruct.new({})) test_case.extend(Assertion) assert_equal( "assert_raises(ArgumentError) { 4 }", diff --git a/test/generator/exercise_case_test.rb b/test/generator/exercise_case_test.rb index 4c5fd047ea..2b0575f407 100644 --- a/test/generator/exercise_case_test.rb +++ b/test/generator/exercise_case_test.rb @@ -3,45 +3,41 @@ module Generator class ExerciseCaseTest < Minitest::Test def test_name - assert_equal 'test_foo', ExerciseCase.new(description: 'foo').name + subject = ExerciseCase.new(canonical: OpenStruct.new(description: 'foo')) + assert_equal 'test_foo', subject.name end def test_skipped_index_zero - assert_equal '# skip', ExerciseCase.new.skipped(0) + assert_equal '# skip', ExerciseCase.new(canonical: nil).skipped(0) end def test_skipped_index_nonzero - assert_equal 'skip', ExerciseCase.new.skipped(1) + assert_equal 'skip', ExerciseCase.new(canonical: nil).skipped(1) end - class MultiLineCase < ExerciseCase - def workload - indent_lines(['foo', 'bar'], 1) - end - end - def test_indent_multiline_workloads - expected = "foo\n bar" - assert_equal expected, MultiLineCase.new.workload + def test_forwarding_to_canonical + mock_canonical = Minitest::Mock.new + mock_canonical.expect :key, 'fake value' + subject = ExerciseCase.new(canonical: mock_canonical) + subject.key + mock_canonical.verify end - class BlankLineCase < ExerciseCase - def workload - indent_text(2, "foo\n\nbar\n") + def test_method_mising_calls_super + subject = ExerciseCase.new(canonical: nil) + assert_raises NoMethodError do + subject.key end end - def test_indent_multiline_workloads_with_blank_lines - expected = "foo\n\n bar\n" - assert_equal expected, BlankLineCase.new.workload - end - class HeredocCase < ExerciseCase - def workload - indent_heredoc(["foo", "bar"], 'TEXT', 1) - end + def test_true_respond_to? + subject = ExerciseCase.new(canonical: OpenStruct.new(key: 'value')) + assert subject.respond_to?(:key) end - def test_heredoc - expected = "<<-TEXT\n foo\n bar\nTEXT" - assert_equal expected, HeredocCase.new.workload + + def test_false_respond_to? + subject = ExerciseCase.new(canonical: OpenStruct.new()) + refute subject.respond_to?(:key) end end end diff --git a/test/wordy_cases_test.rb b/test/wordy_cases_test.rb index fa5a7c6517..0adfe65aab 100644 --- a/test/wordy_cases_test.rb +++ b/test/wordy_cases_test.rb @@ -4,7 +4,7 @@ class WordyCaseTest < Minitest::Test def test_workload_with_expected_and_no_message - test_case = WordyCase.new(expected: 1, input: 1) + test_case = WordyCase.new(canonical: OpenStruct.new(expected: 1, input: 1)) expected_workload = [ 'question = \'1\'', @@ -15,7 +15,7 @@ def test_workload_with_expected_and_no_message end def test_workload_with_expected_and_message - test_case = WordyCase.new(expected: 1, input: 'What is -3 plus 7 multiplied by -2?') + test_case = WordyCase.new(canonical: OpenStruct.new(expected: 1, input: 'What is -3 plus 7 multiplied by -2?')) message = test_case.send(:message) expected_workload = [ @@ -28,8 +28,8 @@ def test_workload_with_expected_and_message assert_equal expected_workload, test_case.workload end - def test_workload_without_expected - test_case = WordyCase.new(input: 1) + def test_workload_with_expected_false + test_case = WordyCase.new(canonical: OpenStruct.new(input: 1, expected: false)) expected_workload = [ 'question = \'1\'',