Everyone on the Web I found who states that quote I was looking for says “I don’t know who said it, but be ‘Generous on input, strict on output'” (or some variation on this). While I am unsure about the first proposition, I wholeheartedly agree with the second.
Edit 3/8: the quote is known in a different wording as Postel’s Law, which shows up as the Robustness Principle in RFC 793, the specification of TCP. Thanks for the hint, Austin!
Unfortunately, the closest a Rubyist typically gets to the implementation of an interface specification is his tests. This provides a pretty good, but somewhat disconnected specification that can sometimes cover up imprecisions in the interface’s implementation.
On top of that, sometimes our frameworks make it easy to forget what our tests are asserting or spec’ing.
Take rspec’s predicate matchers and this example:
require 'rspec/core'
class VeryImportantQuestions
def self.really?(answer)
answer == 'Yes. I am telling you.'
end
def self.really_really?(answer)
answer == 'Yes. I am telling you.' ? 42 : nil
end
end
describe "really?" do
context "using rspec predicate matchers" do
context "if someone is telling you" do
it "should be really really the case and return true" do
VeryImportantQuestions.really?('Yes. I am telling you.').should be_true
end
end
context "if someone is not sure" do
it "should return false" do
VeryImportantQuestions.really?('I am not sure.').should be_false
end
end
end
end
describe "really_really?" do
context "using rspec predicate matchers" do
context "if someone is telling you" do
it "should be really really the case and return true" do
VeryImportantQuestions.really_really?('Yes. I am telling you.').should be_true
end
end
context "if someone is not sure" do
it "should return false" do
VeryImportantQuestions.really_really?('I am not sure.').should be_false
end
end
end
end
be_true
and be_false
effectively hide the fact that what’s actually spec’ed is truthiness and falsiness. Only when the following context is added is this imprecision revealed:
context "spec'ing the actual output of the method fails" do
context "if someone is telling you" do
it "should be really really the case and return true" do
VeryImportantQuestions.really_really?('Yes. I am telling you.').should == true
end
end
context "if someone is not sure" do
it "should return false" do
VeryImportantQuestions.really_really?('I am not sure.').should == false
end
end
end
With regard to rspec, I suggest to consider twice whether the benefits of using specific matchers to not outweigh their benefits in your situation. You might get nicer test output, but you might lose the ability to immediately tell what you’re spec’ing.
With regard to tests in general: be specific about what you output – aka be specific about what you test.
Here is the gist: https://gist.github.com/1998462
About the Author