Skip to content

Instantly share code, notes, and snippets.

@lgrains
Last active August 29, 2015 14:02
Show Gist options
  • Save lgrains/81b30c98722380121163 to your computer and use it in GitHub Desktop.
Save lgrains/81b30c98722380121163 to your computer and use it in GitHub Desktop.
rspec string_calculator.rb
.....F
Failures:
1) add negative number(s)
Failure/Error: raise "negatives not allowed - " + v.to_s if v
RuntimeError:
negatives not allowed - -3
# ./string_calculator.rb:6:in `add'
# ./string_calculator.rb:53:in `block (3 levels) in <top (required)>'
Finished in 0.00203 seconds
6 examples, 1 failure
Failed examples:
rspec ./string_calculator.rb:53 # add negative number(s)
require 'rspec/autorun'
class StringCalculator
def self.add(numbers="")
v = contains_negatives(numbers)
raise "negatives not allowed - " + v.to_s if v
delimiters = /,|\n/
return add_inject(numbers, delimiters) unless numbers.start_with?('//')
delim,nums = partition_input(numbers)
delimiters = delim[-1]
add_inject(nums,delimiters)
# implement using split, map, reduce
end
def self.partition_input(str)
str.split("\n")
end
def self.add_inject(numbers, delimiters)
numbers.split(delimiters).map{|n| n.to_i}.reduce(0,:+)
end
def self.contains_negatives(numbers)
/-\d/.match(numbers)
end
end
describe "add" do
subject {StringCalculator}
context "empty string" do
it {subject.add.should == 0}
end
context "one number" do
it {subject.add("3").should == 3 }
end
context "unknown amount of numbers" do
it {subject.add("4,6,8,10").should == 28}
end
context "a newline in the numbers" do
it {subject.add("1\n2,3").should == 6 }
end
context "given a delimiter at the beginning of string" do
it {subject.add("//;\n1;2").should == 3}
end
context "negative number(s)" do
it { subject.add("-3,3").to raise_error }
end
end
@thedrewbisset
Copy link

For some reason the line numbers don't match - weird.
Not sure what happened, but now line numbers are showing up properly. The following references loc 52-54:

Anyway, your negative number is failing because anytime you want to test that exceptions are raised in a test, you need to wrap the code that is throwing the exception in a lambda. Otherwise RSpec thinks the exception has to do with the test runtime and interprets it automatically as a failure.

I use RSpec expect syntax so I'm not 100% sure how to do this using should, but it looks like something like the following might work:

it { lambda { subject.add("-3,3") }.to raise_error }

If that doesn't work, this most certainly should:

it 'throws an error' do
  lambda { subject.add("-3,3") }.should raise_error
end

@thedrewbisset
Copy link

One other suggestion I would make is to have your subject capture the method you're testing and pass the param as it's defined with a let under each context. You can dry things up considerably this way:

subject { StringCalculator.add(string_of_numbers) }

context 'with one number' do
  let(:string_of_numbers) { "3" }
  it { should == 3 }
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment