lib/pork.rb in pork-0.9.2 vs lib/pork.rb in pork-1.0.0
- old
+ new
@@ -1,247 +1,30 @@
-require 'thread'
+require 'pork/executor'
-module Kernel
- def should message=nil, message_lazy=nil, &checker
- Pork::Should.new(self, message, message_lazy, &checker)
- end
-end
-
module Pork
- Error = Class.new(StandardError)
- Failure = Class.new(Error)
- Skip = Class.new(Error)
-
- def self.stats ; @stats ||= Stats.new; end
- def self.reset ; @stats = nil ; end
- def self.report; stats.report; reset ; end
- def self.report_at_exit
- Pork.stats.start
- @report_at_exit ||= at_exit do
- stats.report
- exit stats.failures.size + stats.errors.size + ($! && 1).to_i
- end
- end
- # default to :auto while eliminating warnings for uninitialized ivar
- def self.inspect_failure_mode mode=nil; @mode = mode || @mode ||= :auto; end
- def self.inspect_failure *args
- lambda{ public_send("inspect_failure_#{inspect_failure_mode}", *args) }
- end
-
- def self.inspect_failure_auto object, msg, args, negate
- if args.size > 1
- inspect_failure_inline(object, msg, args, negate)
- elsif object.kind_of?(Hash) && args.first.kind_of?(Hash)
- inspect_failure_inline(Hash[object.sort], msg,
- [Hash[args.first.sort]], negate)
- elsif object.kind_of?(String) && object.size > 400 &&
- object.count("\n") > 4 && !`which diff`.empty?
- inspect_failure_diff(object, msg, args, negate)
- else
- ins = object.inspect
- if ins.size > 78
- inspect_failure_newline(object, msg, args, negate)
- else
- inspect_failure_inline( object, msg, args, negate)
- end
- end
- end
-
- def self.inspect_failure_inline object, msg, args, negate
- a = args.map(&:inspect).join(', ')
- "#{object.inspect}.#{msg}(#{a}) to return #{!negate}"
- end
-
- def self.inspect_failure_newline object, msg, args, negate
- a = args.map(&:inspect).join(",\n")
- "\n#{object.inspect}.#{msg}(\n#{a}) to return #{!negate}"
- end
-
- def self.inspect_failure_diff object, msg, args, negate
- require 'tempfile'
- Tempfile.open('pork-expect') do |expect|
- Tempfile.open('pork-was') do |was|
- expect.puts(object.to_s)
- expect.close
- was.puts(args.map(&:to_s).join(",\n"))
- was.close
- name = "#{object.class}##{msg}(\n"
- "#{name}#{`diff #{expect.path} #{was.path}`}) to return #{!negate}"
- end
- end
- end
-
module API
module_function
def before █ Executor.before(&block); end
def after █ Executor.after( &block); end
- def describe desc=:default, &suite; Executor.describe(desc, &suite); end
- def copy desc=:default, &suite; Executor.copy( desc, &suite); end
+ def copy desc=:default, █ Executor.copy( desc, &block); end
def paste desc=:default, *args ; Executor.paste( desc, *args ); end
+ def describe desc=:default, &suite; Executor.describe(desc, &suite); end
def would desc=:default, &test ; Executor.would( desc, &test ); end
end
- module Imp
- attr_reader :stash, :desc
- def before &block
- if block_given? then @before << block else @before end
- end
- def after &block
- if block_given? then @after << block else @after end
- end
- def describe desc=:default, &suite
- Class.new(self){ init("#{desc}: ") }.module_eval(&suite)
- end
- def copy desc=:default, &suite; stash[desc] = suite; end
- def paste desc=:default, *args
- module_exec(*args, &search_stash(desc))
- end
- def would desc=:default, &test
- assertions = Pork.stats.assertions
- context = new(desc)
- run_before(context)
- context.instance_eval(&test)
- if assertions == Pork.stats.assertions
- raise Error.new('Missing assertions')
- end
- rescue Error, StandardError => e
- case e
- when Skip
- Pork.stats.incr_skips
- when Failure
- Pork.stats.add_failure(e, description_for("would #{desc}"))
- when Error, StandardError
- Pork.stats.add_error( e, description_for("would #{desc}"))
- end
- else
- print '.'
- ensure
- Pork.stats.incr_tests
- run_after(context)
- end
-
- protected
- def init desc=''; @desc, @before, @after, @stash = desc, [], [], {}; end
- def super_executor
- @super_executor ||= ancestors[1..-1].find{ |a| a <= Executor }
- end
- def search_stash desc
- stash[desc] or super_executor && super_executor.search_stash(desc)
- end
- def description_for name=''
- "#{desc}#{super_executor && super_executor.description_for}#{name}"
- end
- def run_before context
- super_executor && super_executor.run_before(context)
- before.each{ |b| context.instance_eval(&b) }
- end
- def run_after context
- super_executor && super_executor.run_after(context)
- after.each{ |b| context.instance_eval(&b) }
- end
+ # default to :execute while eliminating warnings for uninitialized ivar
+ def self.execute_mode execute=nil
+ @execute = execute || @execute ||= :execute
end
- class Executor < Struct.new(:desc)
- extend Pork::Imp, Pork::API
- init
- def skip ; raise Skip.new("Skipping #{desc}"); end
- def flunk reason='Flunked'; raise Error.new(reason) ; end
- def ok ; Pork.stats.incr_assertions ; end
- end
-
- class Should < BasicObject
- instance_methods.each{ |m| undef_method(m) unless m =~ /^__|^object_id$/ }
- def initialize object, message=nil, message_lazy=nil, &checker
- @object, @negate = object, false
- @message, @message_lazy = message, message_lazy
- satisfy(&checker) if checker
- end
-
- def method_missing msg, *args, &block
- satisfy(nil, ::Pork.inspect_failure(@object, msg, args, @negate)) do
- @object.public_send(msg, *args, &block)
- end
- end
-
- def satisfy desc=@object, desc_lazy=nil
- result = yield(@object)
- if !!result == @negate
- d = desc_lazy && desc_lazy.call || desc
- m = @message_lazy && @message_lazy.call || @message
- ::Kernel.raise Failure.new("Expect #{d}\n#{m}".chomp)
- else
- ::Pork.stats.incr_assertions
- end
- result
- end
-
- def not &checker
- @negate = !@negate
- satisfy(&checker) if checker
- self
- end
-
- def eq rhs; self == rhs; end
- def lt rhs; self < rhs; end
- def gt rhs; self > rhs; end
- def lte rhs; self <= rhs; end
- def gte rhs; self >= rhs; end
-
- def raise exception=::RuntimeError
- satisfy("#{__not__}raising #{exception}") do
- begin
- if ::Kernel.block_given? then yield else @object.call end
- rescue exception => e
- e
- else
- false
- end
- end
- end
-
- def throw msg
- satisfy("#{__not__}throwing #{msg}") do
- flag = true
- data = ::Kernel.catch(msg) do
- if ::Kernel.block_given? then yield else @object.call end
- flag = false
- end
- flag && [msg, data]
- end
- end
-
- private
- def __not__; if @negate == true then 'not ' else '' end; end
- end
-
- class Stats < Struct.new(:tests, :assertions, :skips, :failures, :errors)
- def initialize
- @mutex = Mutex.new
- super(0, 0, 0, [], [])
- end
- def incr_assertions; @mutex.synchronize{ self.assertions += 1 }; end
- def incr_tests ; @mutex.synchronize{ self.tests += 1 }; end
- def incr_skips ; @mutex.synchronize{ self.skips += 1; print('s')}; end
- def add_failure *e ; @mutex.synchronize{ failures << e; print('F')}; end
- def add_error *e ; @mutex.synchronize{ errors << e; print('E')}; end
- def numbers; [tests, assertions, failures.size, errors.size, skips]; end
- def start ; @start ||= Time.now ; end
- def report
- puts
- puts (failures + errors).map{ |(e, m)|
- "\n#{m}\n#{e.class}: #{e.message}\n #{backtrace(e)}"
- }
- printf("\nFinished in %f seconds.\n", Time.now - @start)
- printf("%d tests, %d assertions, %d failures, %d errors, %d skips\n",
- *numbers)
- end
- private
- def backtrace e
- if $VERBOSE
- e.backtrace
- else
- e.backtrace.reject{ |line| line =~ %r{/pork\.rb:\d+} }
- end.join("\n ")
+ def self.autorun auto=true
+ @auto = auto
+ @autorun ||= at_exit do
+ next unless @auto
+ require "pork/mode/#{execute_mode}" unless execute_mode == :execute
+ stat = Executor.public_send(execute_mode)
+ stat.report
+ exit stat.failures.size + stat.errors.size + ($! && 1).to_i
end
end
end