From fe7cf39e5a1330973ac75b205350b66e3a417b42 Mon Sep 17 00:00:00 2001 From: Hilary Holz Date: Wed, 3 May 2017 11:57:32 -0700 Subject: [PATCH 1/4] add new example solution loc to exercise task --- lib/tasks/exercise.rb | 10 +++++++++- test/tasks/exercise_test.rb | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/tasks/exercise.rb b/lib/tasks/exercise.rb index bcc61cd1fb..d0ab5e2817 100644 --- a/lib/tasks/exercise.rb +++ b/lib/tasks/exercise.rb @@ -23,7 +23,7 @@ def directory end def example_file - 'example.rb' + File.exist?(example_filename) ? example_filename : legacy_example_filename end def testable_example_file @@ -36,6 +36,14 @@ def test_file private + def example_filename + File.join('.meta', 'solutions', "#{name}.rb") + end + + def legacy_example_filename + 'example.rb' + end + def base_file_name @_base_file_name ||= name.tr('-', '_') end diff --git a/test/tasks/exercise_test.rb b/test/tasks/exercise_test.rb index 8a5838141a..d3cde01d29 100644 --- a/test/tasks/exercise_test.rb +++ b/test/tasks/exercise_test.rb @@ -31,6 +31,12 @@ def test_directory end def test_example_file + File.stub(:exist?, true) do + assert_equal '.meta/solutions/name.rb', Exercise.new('name').example_file + end + end + + def test_legacy_example_file assert_equal 'example.rb', Exercise.new('').example_file end From 19c059fed434aca9e58c3bf3bce990e30d619f45 Mon Sep 17 00:00:00 2001 From: Hilary Holz Date: Wed, 3 May 2017 11:58:12 -0700 Subject: [PATCH 2/4] test old and new locs in tests_runner --- .../exercise_tests_runner_legacy_test.rb | 64 +++++++++++++++++++ test/tasks/exercise_tests_runner_test.rb | 4 +- 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/tasks/exercise_tests_runner_legacy_test.rb diff --git a/test/tasks/exercise_tests_runner_legacy_test.rb b/test/tasks/exercise_tests_runner_legacy_test.rb new file mode 100644 index 0000000000..d21820e100 --- /dev/null +++ b/test/tasks/exercise_tests_runner_legacy_test.rb @@ -0,0 +1,64 @@ +require_relative '../test_helper' + +class FakeLegacyExercise + def name + 'test' + end + + alias :to_s :name + + def directory + 'test/.' + end + + def example_file + 'example.rb' + end + + def testable_example_file + 'test.rb' + end + + def test_file + 'test_test.rb' + end +end + +class ExerciseTestsRunnerLegacyTest < Minitest::Test + def test_run + Dir.stub :mktmpdir, nil, 'dir' do + cp_mock = Minitest::Mock.new.expect(:call, nil, ['test/.', 'dir']) + + mv_mock = Minitest::Mock.new.expect( + :call, + nil, + ['dir/example.rb', 'dir/test.rb'], + ) + + ruby_mock = Minitest::Mock.new.expect( + :call, + nil, + ['-I lib -r disable_skip.rb dir/test_test.rb -p'], + ) + + FileUtils.stub :cp_r, cp_mock do + FileUtils.stub :mv, mv_mock do + runner = ExerciseTestsRunner.new( + exercise: FakeLegacyExercise.new, + test_options: '-p', + ) + + runner.stub :ruby, ruby_mock do + assert_output "\n\n#{'-'*64}\nrunning tests for: test\n" do + runner.run + end + end + + cp_mock.verify + mv_mock.verify + ruby_mock.verify + end + end + end + end +end diff --git a/test/tasks/exercise_tests_runner_test.rb b/test/tasks/exercise_tests_runner_test.rb index b0b013b037..d789bcc078 100644 --- a/test/tasks/exercise_tests_runner_test.rb +++ b/test/tasks/exercise_tests_runner_test.rb @@ -12,7 +12,7 @@ def directory end def example_file - 'example.rb' + '.meta/solutions/test.rb' end def testable_example_file @@ -32,7 +32,7 @@ def test_run mv_mock = Minitest::Mock.new.expect( :call, nil, - ['dir/example.rb', 'dir/test.rb'], + ['dir/.meta/solutions/test.rb', 'dir/test.rb'], ) ruby_mock = Minitest::Mock.new.expect( From a9686995193da592be6acd9da91eff78ea003df1 Mon Sep 17 00:00:00 2001 From: Hilary Holz Date: Wed, 3 May 2017 12:31:55 -0700 Subject: [PATCH 3/4] support example solutions in .meta/solutions in lib --- lib/generator/files/track_files.rb | 14 +++++++++++++- .../{example.rb => .meta/solutions/alpha.rb} | 0 test/generator/files/track_files_test.rb | 17 ++++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) rename test/fixtures/xruby/exercises/alpha/{example.rb => .meta/solutions/alpha.rb} (100%) diff --git a/lib/generator/files/track_files.rb b/lib/generator/files/track_files.rb index 09cf239744..e2f012f4c1 100644 --- a/lib/generator/files/track_files.rb +++ b/lib/generator/files/track_files.rb @@ -10,7 +10,7 @@ def tests_version end def example_solution - ExampleSolutionFile.new(filename: File.join(exercise_path, 'example.rb')) + ExampleSolutionFile.new(filename: File.join(exercise_path, example_file)) end def minitest_tests @@ -48,6 +48,18 @@ def tests_template_filename 'test_template.erb' end + def example_file + File.exist?(File.join(exercise_path, example_filename)) ? example_filename : legacy_example_filename + end + + def example_filename + File.join('.meta', 'solutions', "#{exercise_name}.rb") + end + + def legacy_example_filename + 'example.rb' + end + def minitest_tests_filename "#{exercise_name.gsub(/[ -]/, '_')}_test.rb" end diff --git a/test/fixtures/xruby/exercises/alpha/example.rb b/test/fixtures/xruby/exercises/alpha/.meta/solutions/alpha.rb similarity index 100% rename from test/fixtures/xruby/exercises/alpha/example.rb rename to test/fixtures/xruby/exercises/alpha/.meta/solutions/alpha.rb diff --git a/test/generator/files/track_files_test.rb b/test/generator/files/track_files_test.rb index ea583f3911..482b103262 100644 --- a/test/generator/files/track_files_test.rb +++ b/test/generator/files/track_files_test.rb @@ -13,7 +13,7 @@ def initialize @paths = FixturePaths @exercise_name = 'alpha' end - attr_reader :paths, :exercise_name + attr_accessor :paths, :exercise_name include TrackFiles end @@ -24,7 +24,15 @@ def test_tests_version def test_example_solution subject = TestTrackFiles.new - assert_instance_of ExampleSolutionFile, subject.example_solution + expected_filename = FixturePaths.track + '/exercises/alpha/.meta/solutions/alpha.rb' + assert_equal expected_filename, subject.example_solution.filename + end + + def test_legacy_example_solution + subject = TestTrackFiles.new + subject.exercise_name = 'beta' + expected_filename = FixturePaths.track + '/exercises/beta/example.rb' + assert_equal expected_filename, subject.example_solution.filename end def test_minitest_tests @@ -38,6 +46,7 @@ def test_tests_template assert_equal expected_filename, subject.tests_template.filename end + class TestTrackFilesUseDefault def initialize @paths = FixturePaths @@ -75,7 +84,9 @@ def save(content) end def test_update_version - subject = TestExampleSolutionFile.new(filename: 'test/fixtures/xruby/exercises/alpha/example.rb') + subject = TestExampleSolutionFile.new( + filename: 'test/fixtures/xruby/exercises/alpha/.meta/solutions/alpha.rb' + ) assert_match(/VERSION = 2/, subject.update_version(2)) end end From 76e52396d9bcfa86dc0474835dee51d05bb9b56a Mon Sep 17 00:00:00 2001 From: Hilary Holz Date: Wed, 3 May 2017 12:43:22 -0700 Subject: [PATCH 4/4] update README --- README.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fc945c47b8..01e0f382f9 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,19 @@ the language, so you're all set. The files for an exercise live in `exercises/` (where `` is the slug for the exercise, e.g. `clock` or -`atbash-cipher`). An exercise has a test suite -(`exercises//_test.rb`) and an example solution -(`exercises//example.rb`). +`atbash-cipher`). All exercises have: + +* a test suite, `_test.rb` +* an example solution, `.rb`, in `.meta/solutions` + +Tests with a test generator will also have: + +* a `.version` +* the test generator, `_cases.rb`, in `.meta/generator` + +A few tests have other custom files which are discussed below. + +### Canonical Data **Most exercises can be generated from shared inputs/outputs, called canonical data (see [Generated Test Suites](#generated-test-suites) below).** To find out @@ -25,9 +35,9 @@ the [x-common repo](https://github.com/exercism/x-common/tree/master/exercises). ## Running the Tests -Run the tests using `rake`, rather than `ruby path/to/the_test.rb`. `rake` -knows to look for `example.rb` and to disable skips. Just tell `rake` the -name of your problem and you are set: +Run the tests using `rake`, rather than `ruby path/to/the_test.rb`. `rake` knows +to look for the example solution and to disable skips. Just tell `rake` the name +of your problem and you are set: ```sh rake test:clock @@ -211,7 +221,7 @@ We have created a minimal set of guidelines for the testing files, which you can take advantage of by installing the `rubocop` gem. It will use the configuration file located in the root folder, `.rubocop.yml`. When you edit your code, you can simply run `rubocop -D`. It will ignore -your `example.rb`, but will gently suggest style for your test code. +your example solution, but will gently suggest style for your test code. The `-D` option that is suggested is provided to give you the ability to easily ignore the Cops that you think should be ignored. This is easily