We often write our own custom matchers and I wanna show how is easy to write
custom expectation.
Desired DSL
Usually when I do things like this I start with DSL. I think it’s important since
it must be convenient to use and easy to read.
So turn on your imagination and spend some time on it.
In my example I’m gonna create an expectation to test text written to standard output
and standard error.
There are samples how I wanna use it(desired DSL):
12345
# Test text written to standard outputexpect{puts"Hello!"}.towrite("Hello!")# Test text written to standard errorexpect{warn"Stop it!"}.towrite("Stop it!").to(:error)
Expectation
I bet you’ve already created number of custom matchers. What about custom expectations?
They are usual custom matches which test blocks of code!
I’m gonna locate the expectation in spec/support/custom_expectations/write_expectation.rb file.
I think spec/support/custom_expectations/ directory is the right place for it since
custom matchers usually are located in spec/support/custom_matchers/.
RSpec::Matchers.define:writedo|message|chain(:to)do|io|@io=ioendmatchdo|block|output=caseiowhen:outputthenfake_stdout(&block)when:errorthenfake_stderr(&block)elseraise("Allowed values for `to` are :output and :error, got `#{io.inspect}`")endoutput.include?messageenddescriptiondo"write \"#{message}\"#{io_name}"endfailure_message_for_shoulddo"expected to #{description}"endfailure_message_for_should_notdo"expected to not #{description}"end# Fake STDERR and return a string written to it.deffake_stderroriginal_stderr=$stderr$stderr=StringIO.newyield$stderr.stringensure$stderr=original_stderrend# Fake STDOUT and return a string written to it.deffake_stdoutoriginal_stdout=$stdout$stdout=StringIO.newyield$stdout.stringensure$stdout=original_stdoutend# default IO is standard outputdefio@io||=:outputend# IO name is used for description messagedefio_name{:output=>"standard output",:error=>"standard error"}[io]endend
And that’s it. You can try it against the examples from “Desired DSL” section.
Hope that’s was useful. I look forward for your comments and suggestions. You know I do! =)