-
-
Notifications
You must be signed in to change notification settings - Fork 525
wordy: Generate tests #509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
module BookKeeping | ||
VERSION = 1 | ||
end | ||
|
||
class WordProblem | ||
attr_reader :question | ||
def initialize(question) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
require 'minitest/autorun' | ||
require_relative 'wordy' | ||
|
||
# Test data version: <%= sha1 %> | ||
class WordyTest < Minitest::Test<% test_cases.each do |test_case| %> | ||
def <%= test_case.test_name %> | ||
<%= test_case.skipped %> | ||
<%= test_case.workload %> | ||
end | ||
<% end %> | ||
|
||
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %> | ||
def test_bookkeeping | ||
skip | ||
assert_equal <%= version.next %>, BookKeeping::VERSION | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,128 @@ | ||
#!/usr/bin/env ruby | ||
gem 'minitest', '>= 5.0.0' | ||
require 'minitest/autorun' | ||
require_relative 'wordy' | ||
|
||
class WordProblemTest < Minitest::Test | ||
def test_add_1 | ||
assert_equal 2, WordProblem.new('What is 1 plus 1?').answer | ||
# Test data version: aa12f2e | ||
class WordyTest < Minitest::Test | ||
def test_addition | ||
# skip | ||
question = 'What is 1 plus 1?' | ||
assert_equal(2, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_add_2 | ||
def test_more_addition | ||
skip | ||
assert_equal 55, WordProblem.new('What is 53 plus 2?').answer | ||
question = 'What is 53 plus 2?' | ||
assert_equal(55, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_add_negative_numbers | ||
def test_addition_with_negative_numbers | ||
skip | ||
assert_equal(-11, WordProblem.new('What is -1 plus -10?').answer) | ||
question = 'What is -1 plus -10?' | ||
assert_equal(-11, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_add_more_digits | ||
def test_large_addition | ||
skip | ||
assert_equal 45_801, WordProblem.new('What is 123 plus 45678?').answer | ||
question = 'What is 123 plus 45678?' | ||
assert_equal(45801, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_subtract | ||
def test_subtraction | ||
skip | ||
assert_equal 16, WordProblem.new('What is 4 minus -12?').answer | ||
question = 'What is 4 minus -12?' | ||
assert_equal(16, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_multiply | ||
def test_multiplication | ||
skip | ||
assert_equal(-75, WordProblem.new('What is -3 multiplied by 25?').answer) | ||
question = 'What is -3 multiplied by 25?' | ||
assert_equal(-75, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_divide | ||
def test_division | ||
skip | ||
assert_equal(-11, WordProblem.new('What is 33 divided by -3?').answer) | ||
question = 'What is 33 divided by -3?' | ||
assert_equal(-11, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_add_twice | ||
def test_multiple_additions | ||
skip | ||
question = 'What is 1 plus 1 plus 1?' | ||
assert_equal 3, WordProblem.new(question).answer | ||
assert_equal(3, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_add_then_subtract | ||
def test_addition_and_subtraction | ||
skip | ||
question = 'What is 1 plus 5 minus -2?' | ||
assert_equal 8, WordProblem.new(question).answer | ||
assert_equal(8, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_subtract_twice | ||
def test_multiple_subtraction | ||
skip | ||
question = 'What is 20 minus 4 minus 13?' | ||
assert_equal 3, WordProblem.new(question).answer | ||
assert_equal(3, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_subtract_then_add | ||
def test_subtraction_then_addition | ||
skip | ||
question = 'What is 17 minus 6 plus 3?' | ||
assert_equal 14, WordProblem.new(question).answer | ||
assert_equal(14, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_multiply_twice | ||
def test_multiple_multiplication | ||
skip | ||
question = 'What is 2 multiplied by -2 multiplied by 3?' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the custom message that isn't currently generated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you work out how to make the generator add this message yourself, or would you like some hints? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hints would be perfect, actually 😄 ! I can't quite work out how I would implement this without modifying the shared test data There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See my latest comments. |
||
assert_equal(-12, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_add_then_multiply | ||
def test_addition_and_multiplication | ||
skip | ||
question = 'What is -3 plus 7 multiplied by -2?' | ||
message = 'You should ignore order of precedence. -3 + 7 * -2 = -8, not -17' | ||
assert_equal(-8, WordProblem.new(question).answer, message) | ||
answer = WordProblem.new(question).answer | ||
message = "You should ignore order of precedence. -3 + 7 * -2 = -8, not #{answer}" | ||
assert_equal(-8, answer, message) | ||
end | ||
|
||
def test_divide_twice | ||
def test_multiple_division | ||
skip | ||
question = 'What is -12 divided by 2 divided by -3?' | ||
assert_equal 2, WordProblem.new(question).answer | ||
assert_equal(2, WordProblem.new(question).answer) | ||
end | ||
|
||
def test_too_advanced | ||
def test_unknown_operation | ||
skip | ||
question = 'What is 52 cubed?' | ||
assert_raises ArgumentError do | ||
WordProblem.new('What is 53 cubed?').answer | ||
WordProblem.new(question).answer | ||
end | ||
end | ||
|
||
def test_irrelevant | ||
def test_non_math_question | ||
skip | ||
question = 'Who is the President of the United States?' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This question doesn't start with 'What is' but that's probably an issue for the common metadata. |
||
assert_raises ArgumentError do | ||
WordProblem.new('Who is the president of the United States?').answer | ||
WordProblem.new(question).answer | ||
end | ||
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 1, BookKeeping::VERSION | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
class WordyCase < OpenStruct | ||
def test_name | ||
'test_%s' % description.downcase.tr(' ', '_') | ||
end | ||
|
||
def workload | ||
[ | ||
"question = '#{input}'", | ||
indent(4, assertion), | ||
].join("\n") | ||
end | ||
|
||
def skipped | ||
index.zero? ? '# skip' : 'skip' | ||
end | ||
|
||
private | ||
|
||
def indent(size, lines) | ||
lines.lines.each_with_object('') { |line, obj| obj << ' ' * size + line } | ||
end | ||
|
||
def assertion | ||
return error_assertion unless expected | ||
return message_assertion if message | ||
|
||
"assert_equal(#{expected}, WordProblem.new(question).answer)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then you can add your custom failure message here.
(This code will not work as-is) |
||
end | ||
|
||
def error_assertion | ||
[ | ||
'assert_raises ArgumentError do', | ||
indent(2, 'WordProblem.new(question).answer'), | ||
'end', | ||
].join("\n") | ||
end | ||
|
||
def message_assertion | ||
[ | ||
'answer = WordProblem.new(question).answer', | ||
"message = \"#{message % '#{answer}'}\"", | ||
"assert_equal(#{expected}, answer, message)", | ||
].join("\n") | ||
end | ||
end | ||
|
||
class WordyCase::PreProcessor | ||
class << self | ||
def call(row) | ||
row.merge('message' => message_for(row)) | ||
end | ||
|
||
private | ||
|
||
def message_for(row) | ||
return unless row['input'] == 'What is -3 plus 7 multiplied by -2?' | ||
|
||
'You should ignore order of precedence. -3 + 7 * -2 = -8, not %s' | ||
end | ||
end | ||
end | ||
|
||
WordyCases = proc do |data| | ||
JSON.parse(data)['cases'].map.with_index do |row, i| | ||
WordyCase.new(WordyCase::PreProcessor.call(row).merge(index: i)) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
require_relative 'test_helper' | ||
|
||
class WordyCaseTest < Minitest::Test | ||
def test_test_name | ||
test_case = WordyCase.new(description: 'description') | ||
|
||
assert_equal 'test_description', test_case.test_name | ||
end | ||
|
||
def test_test_name_with_description_with_spaces | ||
test_case = WordyCase.new(description: 'description with spaces') | ||
|
||
assert_equal 'test_description_with_spaces', test_case.test_name | ||
end | ||
|
||
def test_skipped_with_zero_index | ||
test_case = WordyCase.new(index: 0) | ||
|
||
assert_equal '# skip', test_case.skipped | ||
end | ||
|
||
def test_skipped_with_non_zero_index | ||
test_case = WordyCase.new(index: 1) | ||
|
||
assert_equal 'skip', test_case.skipped | ||
end | ||
|
||
def test_workload_with_expected_and_no_message | ||
test_case = WordyCase.new(expected: 1, input: 1) | ||
|
||
expected_workload = [ | ||
'question = \'1\'', | ||
' assert_equal(1, WordProblem.new(question).answer)', | ||
].join("\n") | ||
|
||
assert_equal expected_workload, test_case.workload | ||
end | ||
|
||
def test_workload_with_expected_and_message | ||
test_case = WordyCase.new(expected: 1, input: 1, message: 'test %s') | ||
|
||
expected_workload = [ | ||
'question = \'1\'', | ||
' answer = WordProblem.new(question).answer', | ||
' message = "test #{answer}"', | ||
' assert_equal(1, answer, message)', | ||
].join("\n") | ||
|
||
assert_equal expected_workload, test_case.workload | ||
end | ||
|
||
def test_workload_without_expected | ||
test_case = WordyCase.new(input: 1) | ||
|
||
expected_workload = [ | ||
'question = \'1\'', | ||
' assert_raises ArgumentError do', | ||
' WordProblem.new(question).answer', | ||
' end', | ||
].join("\n") | ||
|
||
assert_equal expected_workload, test_case.workload | ||
end | ||
end | ||
|
||
class WordyCasePrProcessorTest < Minitest::Test | ||
def test_call_as_non_special_case | ||
row = { 'input' => '' } | ||
processed_row = WordyCase::PreProcessor.call(row) | ||
|
||
assert_equal({ 'input' => '', 'message' => nil }, processed_row) | ||
end | ||
|
||
def test_call_as_special_case | ||
row = { 'input' => 'What is -3 plus 7 multiplied by -2?' } | ||
processed_row = WordyCase::PreProcessor.call(row) | ||
expected_row = { | ||
'input' => 'What is -3 plus 7 multiplied by -2?', | ||
'message' => 'You should ignore order of precedence. -3 + 7 * -2 = -8, not %s', | ||
} | ||
|
||
assert_equal expected_row, processed_row | ||
end | ||
end | ||
|
||
class WordyCasesTest < Minitest::Test | ||
def test_call | ||
json = { | ||
cases: [ | ||
{ description: 'test 1' }, | ||
{ description: 'test 2' }, | ||
] | ||
}.to_json | ||
|
||
expected_cases = [ | ||
WordyCase.new(description: 'test 1', message: nil, index: 0), | ||
WordyCase.new(description: 'test 2', message: nil, index: 1), | ||
] | ||
|
||
assert_equal expected_cases, WordyCases.call(json) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this one have brackets around the arguments?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi there!
I originally thought that it was something enforced by rubocop, but I'm not sure now. Whenever I save the file without the parentheses, I get a warning in Vim
ambiguous first argument; put parentheses or a space even after '-' operator
(only for cases with a negative number).I'm assuming that's maybe why the original cases also had parens around negative cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's a Rubocop warning, it's not particularly important, but it's better to make all the cases consistent so in this case I'd wrap them all in parentheses. This has the pleasant side effect of making your
value_assertion
method much simpler.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes. That sounds great to me!