diff --git a/spec/mspec/lib/mspec/guards/version.rb b/spec/mspec/lib/mspec/guards/version.rb index 20f8c06d38..f5ea1988ae 100644 --- a/spec/mspec/lib/mspec/guards/version.rb +++ b/spec/mspec/lib/mspec/guards/version.rb @@ -33,6 +33,30 @@ class VersionGuard < SpecGuard @version >= @requirement end end + + @kernel_version = nil + def self.kernel_version + if @kernel_version + @kernel_version + else + if v = RUBY_PLATFORM[/darwin(\d+)/, 1] # build time version + uname = v + else + begin + require 'etc' + etc = true + rescue LoadError + etc = false + end + if etc and Etc.respond_to?(:uname) + uname = Etc.uname.fetch(:release) + else + uname = `uname -r`.chomp + end + end + @kernel_version = uname + end + end end def version_is(base_version, requirement, &block) @@ -42,3 +66,7 @@ end def ruby_version_is(requirement, &block) VersionGuard.new(VersionGuard::FULL_RUBY_VERSION, requirement).run_if(:ruby_version_is, &block) end + +def kernel_version_is(requirement, &block) + VersionGuard.new(VersionGuard.kernel_version, requirement).run_if(:kernel_version_is, &block) +end diff --git a/spec/mspec/lib/mspec/helpers/ruby_exe.rb b/spec/mspec/lib/mspec/helpers/ruby_exe.rb index 922178dab0..7fde001cda 100644 --- a/spec/mspec/lib/mspec/helpers/ruby_exe.rb +++ b/spec/mspec/lib/mspec/helpers/ruby_exe.rb @@ -143,8 +143,17 @@ def ruby_exe(code = :not_given, opts = {}) platform_is_not :opal do command = ruby_cmd(code, opts) output = `#{command}` + status = Process.last_status - exit_status = Process.last_status.exitstatus + exit_status = if status.exited? + status.exitstatus + elsif status.signaled? + signame = Signal.signame status.termsig + raise "No signal name?" unless signame + :"SIG#{signame}" + else + raise SpecExpectationNotMetError, "#{exit_status.inspect} is neither exited? nor signaled?" + end if exit_status != expected_status formatted_output = output.lines.map { |line| " #{line}" }.join raise SpecExpectationNotMetError, diff --git a/spec/mspec/lib/mspec/runner/context.rb b/spec/mspec/lib/mspec/runner/context.rb index 62483590bb..bcd83b2465 100644 --- a/spec/mspec/lib/mspec/runner/context.rb +++ b/spec/mspec/lib/mspec/runner/context.rb @@ -210,6 +210,7 @@ class ContextState MSpec.clear_expectations if example passed = protect nil, example + passed = protect nil, -> { MSpec.actions :passed, state, example } if passed MSpec.actions :example, state, example protect nil, EXPECTATION_MISSING if !MSpec.expectation? and passed end diff --git a/spec/mspec/lib/mspec/runner/formatters/base.rb b/spec/mspec/lib/mspec/runner/formatters/base.rb index c7c50c40d8..54a83c9c32 100644 --- a/spec/mspec/lib/mspec/runner/formatters/base.rb +++ b/spec/mspec/lib/mspec/runner/formatters/base.rb @@ -113,6 +113,14 @@ class BaseFormatter # evaluating the examples. def finish print "\n" + + if MSpecOptions.latest && MSpecOptions.latest.config[:print_skips] + print "\nSkips:\n" unless MSpec.skips.empty? + MSpec.skips.each do |skip, block| + print "#{skip.message} in #{(block.source_location || ['?']).join(':')}\n" + end + end + count = 0 @exceptions.each do |exc| count += 1 diff --git a/spec/mspec/lib/mspec/runner/mspec.rb b/spec/mspec/lib/mspec/runner/mspec.rb index 19cf59b7d2..889e085175 100644 --- a/spec/mspec/lib/mspec/runner/mspec.rb +++ b/spec/mspec/lib/mspec/runner/mspec.rb @@ -26,6 +26,7 @@ module MSpec @unload = nil @tagged = nil @current = nil + @passed = nil @example = nil @modes = [] @shared = {} @@ -36,9 +37,10 @@ module MSpec @repeat = 1 @expectation = nil @expectations = false + @skips = [] class << self - attr_reader :file, :include, :exclude + attr_reader :file, :include, :exclude, :skips attr_writer :repeat, :randomize attr_accessor :formatter end @@ -116,6 +118,7 @@ module MSpec rescue SystemExit => e raise e rescue SkippedSpecError => e + @skips << [e, block] return false rescue Object => exc register_exit 1 @@ -241,6 +244,7 @@ module MSpec # :before before a single spec is run # :add while a describe block is adding examples to run later # :expectation before a 'should', 'should_receive', etc. + # :passed after an example block is run and passes, passed the block, run before :example action # :example after an example block is run, passed the block # :exception after an exception is rescued # :after after a single spec is run diff --git a/spec/mspec/lib/mspec/runner/shared.rb b/spec/mspec/lib/mspec/runner/shared.rb index 1d68365474..283711c1d7 100644 --- a/spec/mspec/lib/mspec/runner/shared.rb +++ b/spec/mspec/lib/mspec/runner/shared.rb @@ -1,10 +1,14 @@ require 'mspec/runner/mspec' def it_behaves_like(desc, meth, obj = nil) - send :before, :all do + before :all do @method = meth @object = obj end + after :all do + @method = nil + @object = nil + end - send :it_should_behave_like, desc.to_s + it_should_behave_like desc.to_s end diff --git a/spec/mspec/lib/mspec/utils/options.rb b/spec/mspec/lib/mspec/utils/options.rb index 23a4c9a2a0..612caf6771 100644 --- a/spec/mspec/lib/mspec/utils/options.rb +++ b/spec/mspec/lib/mspec/utils/options.rb @@ -423,6 +423,10 @@ class MSpecOptions end MSpec.register :load, obj end + + on("--print-skips", "Print skips") do + config[:print_skips] = true + end end def interrupt diff --git a/spec/mspec/spec/helpers/ruby_exe_spec.rb b/spec/mspec/spec/helpers/ruby_exe_spec.rb index 79ce55ca75..61225a2756 100644 --- a/spec/mspec/spec/helpers/ruby_exe_spec.rb +++ b/spec/mspec/spec/helpers/ruby_exe_spec.rb @@ -147,7 +147,7 @@ RSpec.describe Object, "#ruby_exe" do @script = RubyExeSpecs.new allow(@script).to receive(:`).and_return('OUTPUT') - status_successful = double(Process::Status, exitstatus: 0) + status_successful = double(Process::Status, exited?: true, exitstatus: 0) allow(Process).to receive(:last_status).and_return(status_successful) end @@ -176,7 +176,7 @@ RSpec.describe Object, "#ruby_exe" do code = "code" options = {} - status_failed = double(Process::Status, exitstatus: 4) + status_failed = double(Process::Status, exited?: true, exitstatus: 4) allow(Process).to receive(:last_status).and_return(status_failed) expect { @@ -184,16 +184,16 @@ RSpec.describe Object, "#ruby_exe" do }.to raise_error(%r{Expected exit status is 0 but actual is 4 for command ruby_exe\(.+\)}) end - it "shows in the exception message if exitstatus is nil (e.g., signal)" do + it "shows in the exception message if a signal killed the process" do code = "code" options = {} - status_failed = double(Process::Status, exitstatus: nil) + status_failed = double(Process::Status, exited?: false, signaled?: true, termsig: Signal.list.fetch('TERM')) allow(Process).to receive(:last_status).and_return(status_failed) expect { @script.ruby_exe(code, options) - }.to raise_error(%r{Expected exit status is 0 but actual is nil for command ruby_exe\(.+\)}) + }.to raise_error(%r{Expected exit status is 0 but actual is :SIGTERM for command ruby_exe\(.+\)}) end describe "with :dir option" do @@ -236,7 +236,7 @@ RSpec.describe Object, "#ruby_exe" do describe "with :exit_status option" do before do - status_failed = double(Process::Status, exitstatus: 4) + status_failed = double(Process::Status, exited?: true, exitstatus: 4) allow(Process).to receive(:last_status).and_return(status_failed) end