Permalink
Browse files

Merge branch 'master' into development

Conflicts:
	test/matcher_test.rb
  • Loading branch information...
2 parents b9e0c60 + 67b25e2 commit daacbabe042181618816eb24285bdf530c221461 @michaeldv committed Jan 6, 2012
Showing with 54 additions and 80 deletions.
  1. +4 −0 CHANGELOG
  2. +1 −1 Gemfile.lock
  3. +22 −9 lib/quickie/matcher.rb
  4. +6 −2 lib/quickie/runner.rb
  5. +1 −1 lib/quickie/version.rb
  6. +20 −67 test/matcher_test.rb
View
@@ -1,2 +1,6 @@
+0.2.0
+ - Improved actual vs. expected reporting.
+ - Improved user experience when running within IRB or Pry.
+
0.1.0
- Initial Release.
View
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- quickie (0.1.0)
+ quickie (0.2.0)
GEM
remote: http://rubygems.org/
View
@@ -6,21 +6,19 @@
module Quickie
class Hell < RuntimeError
def oops
- puts "\n#{message.chomp} in #{backtrace[2].sub(':', ', line ').sub(':', ' ')}"
+ "#{message.chomp} in #{backtrace[2].sub(':', ', line ').sub(':', ' ')}"
end
end
class Matcher
def initialize(object, verb)
@object = object
@should = (verb == :should)
- %w[ == === =~ > >= < <= => ].each do |operator|
- self.class.override operator
- end
end
private
+ # Override an operator to be able to tell whether it succeeded or not.
#--------------------------------------------------------------------------
def self.override(operator)
define_method(operator) do |expected|
@@ -40,6 +38,8 @@ def self.override(operator)
end
end
+ # Note that we always evaluate positive operators, and then flip the actual
+ # result based on should/should_not request.
#--------------------------------------------------------------------------
def evaluate(operator, negative_operator, expected)
actual = !!@object.__send__(operator, expected)
@@ -48,25 +48,38 @@ def evaluate(operator, negative_operator, expected)
if actual
report :success
else
- report :failure
raise Hell, lyrics(negative_operator || operator, expected)
end
rescue Hell => e
- e.oops
+ report :failure, e.oops
end
+ # Format actual vs. expected message.
#--------------------------------------------------------------------------
def lyrics(operator, expected)
format = "expected: %s %s\n actual: %s %s"
format.sub!(":", " not:").sub!("\n", "\n ") unless @should
format % [ operator, expected.inspect, ' ' * operator.size, @object.inspect ]
end
+ # Report test success and/or failure. When running within IRB or Pry the
+ # message gets displayed immediately, otherwise all the messages are shown
+ # by the Runner in at_exit block.
+ #--------------------------------------------------------------------------
+ def report(status, message = nil)
+ print(status == :success ? '.' : 'F')
+ if !defined?(::IRB) && !defined?(::Pry)
+ Runner.update(status, message)
+ else
+ puts "\n\n#{message}"
+ end
+ end
+
+ # The matcher magic starts here ;-)
#--------------------------------------------------------------------------
- def report(status)
- print '.' if status == :success
- Runner.update(status)
+ %w[ == === =~ > >= < <= => ].each do |operator|
+ override operator
end
end
end
View
@@ -5,14 +5,18 @@
#------------------------------------------------------------------------------
module Quickie
class Runner
+ @@trace = []
@@stats = Hash.new(0)
- def self.update(status)
+ def self.update(status, message = nil)
at_exit {
- puts "\n\nPassed: #{@@stats[:success]}, not quite: #{@@stats[:failure]}, total tests: #{@@stats.values.inject(:+)}."
+ puts
+ puts "\n" << @@trace.join("\n\n") unless @@trace.empty?
+ puts "\nPassed: #{@@stats[:success]}, not quite: #{@@stats[:failure]}, total tests: #{@@stats.values.inject(:+)}."
} if @@stats.empty?
@@stats[status] += 1
+ @@trace << message if message
end
end
end
View
@@ -5,6 +5,6 @@
#------------------------------------------------------------------------------
module Quickie
def self.version
- '0.1.0'
+ '0.2.0'
end
end
View
87 test/matcher_test.rb 100644 → 100755
@@ -12,33 +12,24 @@
# 2. Capture the output of the test.
# 3. Make sure captured output matches the expectation.
#
-# In addition, we hack the Quickie stats so that captured tests are not
-# counted in the actual results.
+# In addition, we hack the Quickie trace/stats so that failed captured
+# tests are not shown/counted in the actual results.
#--------------------------------------------------------------------------
def capture
- stats = Quickie::Runner.class_variable_get('@@stats')
- captured = StringIO.new
- standard, $stdout = $stdout, captured
+ stats = Quickie::Runner.class_variable_get(:@@stats)
+ trace = Quickie::Runner.class_variable_get(:@@trace)
+
+ standard, $stdout = $stdout, StringIO.new
yield
- captured.string
+ $stdout.string
ensure
- $stdout = standard
- if captured.string == '.'
+ if $stdout.string == '.'
stats[:success] -= 1
else
stats[:failure] -= 1
+ trace.pop
end
- Quickie::Runner.class_variable_set('@@stats', stats)
-end
-
-#--------------------------------------------------------------------------
-class String
- def fix(line)
- self.sub!(/^/, "\n") # Insert newline.
- self.sub!("?", line.to_s) # Insert actual line number.
- self.sub!(/\n+Passed.+$/, "") # Ignore the stats.
- self
- end
+ $stdout = standard
end
# Should - passing specs.
@@ -59,54 +50,16 @@ def fix(line)
# Should - failing specs.
#--------------------------------------------------------------------------
-capture { "abc".should != "abc" }.should == <<-EOS.fix(__LINE__)
-expected: != "abc"
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { "abc".should == "xyz" }.should == <<-EOS.fix(__LINE__)
-expected: == "xyz"
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { "abc".should !~ /AB/i }.should == <<-EOS.fix(__LINE__)
-expected: !~ /AB/i
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { "abc".should =~ /XY/i }.should == <<-EOS.fix(__LINE__)
-expected: =~ /XY/i
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { 1234567.should_be < 0 }.should == <<-EOS.fix(__LINE__)
-expected: < 0
- actual: 1234567 in #{__FILE__}, line ? in `block in <main>'
-EOS
+capture { "abc".should != "abc" }.should == "F"
+capture { "abc".should == "xyz" }.should == "F"
+capture { "abc".should !~ /AB/i }.should == "F"
+capture { "abc".should =~ /XY/i }.should == "F"
+capture { 1234567.should_be < 0 }.should == "F"
# Should Not - failing specs.
#--------------------------------------------------------------------------
-capture { "abc".should_not == "abc" }.should == <<-EOS.fix(__LINE__)
-expected not: == "abc"
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { "abc".should_not != "xyz" }.should == <<-EOS.fix(__LINE__)
-expected not: != "xyz"
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { "abc".should_not =~ /AB/i }.should == <<-EOS.fix(__LINE__)
-expected not: =~ /AB/i
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { "abc".should_not !~ /XY/i }.should == <<-EOS.fix(__LINE__)
-expected not: !~ /XY/i
- actual: "abc" in #{__FILE__}, line ? in `block in <main>'
-EOS
-
-capture { 1234567.should_not_be > 0 }.should == <<-EOS.fix(__LINE__)
-expected not: > 0
- actual: 1234567 in #{__FILE__}, line ? in `block in <main>'
-EOS
+capture { "abc".should_not == "abc" }.should == "F"
+capture { "abc".should_not != "xyz" }.should == "F"
+capture { "abc".should_not =~ /AB/i }.should == "F"
+capture { "abc".should_not !~ /XY/i }.should == "F"
+capture { 1234567.should_not_be > 0 }.should == "F"

0 comments on commit daacbab

Please sign in to comment.