From af734a798c5839064e1a1283ad95f58bb5a2ef58 Mon Sep 17 00:00:00 2001 From: Frederico Bittencourt Date: Tue, 18 Oct 2016 00:35:25 -0200 Subject: [PATCH] Add anagram test generator --- exercises/anagram/.version | 1 + exercises/anagram/anagram_test.rb | 132 +++++++++++++++++++++++------- exercises/anagram/example.rb | 4 + exercises/anagram/example.tt | 19 +++++ lib/anagram_cases.rb | 42 ++++++++++ 5 files changed, 167 insertions(+), 31 deletions(-) create mode 100644 exercises/anagram/.version create mode 100644 exercises/anagram/example.tt create mode 100644 lib/anagram_cases.rb diff --git a/exercises/anagram/.version b/exercises/anagram/.version new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/exercises/anagram/.version @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/exercises/anagram/anagram_test.rb b/exercises/anagram/anagram_test.rb index 0ba4e5e394..cc106de0b1 100755 --- a/exercises/anagram/anagram_test.rb +++ b/exercises/anagram/anagram_test.rb @@ -3,70 +3,140 @@ require 'minitest/autorun' require_relative 'anagram' +# Test data version: +# 6a886e0 class AnagramTest < Minitest::Test def test_no_matches + # skip detector = Anagram.new('diaper') - assert_equal [], detector.match(%w(hello world zombies pants)) + anagrams = detector.match(["hello", "world", "zombies", "pants"]) + assert_equal [], anagrams end - def test_detect_simple_anagram + def test_detects_simple_anagram skip detector = Anagram.new('ant') - anagrams = detector.match(%w(tan stand at)) - assert_equal ['tan'], anagrams + anagrams = detector.match(["tan", "stand", "at"]) + assert_equal ["tan"], anagrams end - def test_detect_multiple_anagrams + def test_does_not_detect_false_positives + skip + detector = Anagram.new('galea') + anagrams = detector.match(["eagle"]) + assert_equal [], anagrams + end + + def test_detects_multiple_anagrams skip detector = Anagram.new('master') - anagrams = detector.match(%w(stream pigeon maters)) - assert_equal %w(maters stream), anagrams.sort + anagrams = detector.match(["stream", "pigeon", "maters"]) + assert_equal ["maters", "stream"], anagrams.sort end - def test_does_not_confuse_different_duplicates + def test_does_not_detect_anagram_subsets skip - detector = Anagram.new('galea') - assert_equal [], detector.match(['eagle']) + detector = Anagram.new('good') + anagrams = detector.match(["dog", "goody"]) + assert_equal [], anagrams end - def test_identical_word_is_not_anagram + def test_detects_anagram + skip + detector = Anagram.new('listen') + anagrams = detector.match(["enlists", "google", "inlets", "banana"]) + assert_equal ["inlets"], anagrams + end + + def test_detects_multiple_anagrams + skip + detector = Anagram.new('allergy') + anagrams = detector.match(["gallery", "ballerina", "regally", "clergy", "largely", "leading"]) + assert_equal ["gallery", "largely", "regally"], anagrams.sort + end + + def test_does_not_detect_identical_words skip detector = Anagram.new('corn') - anagrams = detector.match %w(corn dark Corn rank CORN cron park) - assert_equal ['cron'], anagrams + anagrams = detector.match(["corn", "dark", "Corn", "rank", "CORN", "cron", "park"]) + assert_equal ["cron"], anagrams end - def test_eliminate_anagrams_with_same_checksum + def test_does_not_detect_non_anagrams_with_identical_checksum skip detector = Anagram.new('mass') - assert_equal [], detector.match(['last']) + anagrams = detector.match(["last"]) + assert_equal [], anagrams end - def test_eliminate_anagram_subsets + def test_detects_anagrams_case_insensitively skip - detector = Anagram.new('good') - assert_equal [], detector.match(%w(dog goody)) + detector = Anagram.new('Orchestra') + anagrams = detector.match(["cashregister", "Carthorse", "radishes"]) + assert_equal ["Carthorse"], anagrams end - def test_detect_anagram + def test_detects_anagrams_using_case_insensitive_subject skip - detector = Anagram.new('listen') - anagrams = detector.match %w(enlists google inlets banana) - assert_equal ['inlets'], anagrams + detector = Anagram.new('Orchestra') + anagrams = detector.match(["cashregister", "carthorse", "radishes"]) + assert_equal ["carthorse"], anagrams end - def test_multiple_anagrams + def test_detects_anagrams_using_case_insensitive_possible_matches skip - detector = Anagram.new('allergy') - anagrams = - detector.match %w(gallery ballerina regally clergy largely leading) - assert_equal %w(gallery largely regally), anagrams.sort + detector = Anagram.new('orchestra') + anagrams = detector.match(["cashregister", "Carthorse", "radishes"]) + assert_equal ["Carthorse"], anagrams end - def test_anagrams_are_case_insensitive + def test_does_not_detect_a_word_as_its_own_anagram skip - detector = Anagram.new('Orchestra') - anagrams = detector.match %w(cashregister Carthorse radishes) - assert_equal ['Carthorse'], anagrams + detector = Anagram.new('banana') + anagrams = detector.match(["Banana"]) + assert_equal [], anagrams + end + + def test_does_not_detect_a_anagram_if_the_original_word_is_repeated + skip + detector = Anagram.new('go') + anagrams = detector.match(["go Go GO"]) + assert_equal [], anagrams + end + + def test_anagrams_must_use_all_letters_exactly_once + skip + detector = Anagram.new('tapper') + anagrams = detector.match(["patter"]) + assert_equal [], anagrams + end + + def test_capital_word_is_not_own_anagram + skip + detector = Anagram.new('BANANA') + anagrams = detector.match(["Banana"]) + assert_equal [], anagrams + end + + # Problems in exercism evolve over time, as we find better ways to ask + # questions. + # The version number refers to the version of the problem you solved, + # not your solution. + # + # Define a constant named VERSION inside of the top level BookKeeping + # module, which may be placed near the end of your file. + # + # In your file, it will look like this: + # + # module BookKeeping + # VERSION = 1 # Where the version number matches the one in the test. + # end + # + # If you are curious, read more about constants on RubyDoc: + # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html + + def test_bookkeeping + skip + assert_equal 2, BookKeeping::VERSION end end diff --git a/exercises/anagram/example.rb b/exercises/anagram/example.rb index 57507ce6c1..c6ba632cff 100644 --- a/exercises/anagram/example.rb +++ b/exercises/anagram/example.rb @@ -1,3 +1,7 @@ +module BookKeeping + VERSION=2 +end + class Anagram attr_reader :subject def initialize(word) diff --git a/exercises/anagram/example.tt b/exercises/anagram/example.tt new file mode 100644 index 0000000000..26b66ba78c --- /dev/null +++ b/exercises/anagram/example.tt @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby +gem 'minitest', '>= 5.0.0' +require 'minitest/autorun' +require_relative 'anagram' + +# Test data version: +# <%= sha1 %> +class AnagramTest < Minitest::Test<% test_cases.each do |test_case| %> + def <%= test_case.test_name %> + <%= test_case.skipped %> + <%= test_case.work_load %> + end +<% end %> +<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %> + def test_bookkeeping + skip + assert_equal <%= version.next %>, BookKeeping::VERSION + end +end diff --git a/lib/anagram_cases.rb b/lib/anagram_cases.rb new file mode 100644 index 0000000000..d21cb62cba --- /dev/null +++ b/lib/anagram_cases.rb @@ -0,0 +1,42 @@ +class AnagramCase < OpenStruct + def test_name + 'test_%s' % description.gsub(/[ -]/, '_') + end + + def work_load + indent_lines([show_comment, detector, anagram, assert].compact) + end + + def skipped + index.zero? ? '# skip' : 'skip' + end + + private + + def indent_lines(code, indent = 2) + code.join("\n" + ' '*2*indent) + end + + def show_comment + "# #{comment}" unless comment.nil? + end + + def detector + "detector = Anagram.new('#{subject}')" + end + + def anagram + "anagrams = detector.match(#{candidates})" + end + + def assert + actual = expected.size > 1 ? 'anagrams.sort' : 'anagrams' + "assert_equal #{expected.sort}, #{actual}" + end +end + +AnagramCases = proc do |data| + JSON.parse(data)['cases'].map.with_index do |row, i| + AnagramCase.new(row.merge('index' => i)) + end +end