File: //usr/local/rvm/src/ruby-3.0.2/spec/mspec/spec/runner/mspec_spec.rb
require 'spec_helper'
require 'mspec/expectations/expectations'
require 'mspec/helpers/tmp'
require 'mspec/helpers/fs'
require 'mspec/matchers/base'
require 'mspec/runner/mspec'
require 'mspec/runner/example'
describe MSpec, ".register_files" do
it "records which spec files to run" do
MSpec.register_files [:one, :two, :three]
MSpec.files_array.should == [:one, :two, :three]
end
end
describe MSpec, ".register_mode" do
before :each do
MSpec.clear_modes
end
it "sets execution mode flags" do
MSpec.register_mode :verify
MSpec.retrieve(:modes).should == [:verify]
end
end
describe MSpec, ".register_tags_patterns" do
it "records the patterns for generating a tag file from a spec file" do
MSpec.register_tags_patterns [[/spec\/ruby/, "spec/tags"], [/frozen/, "ruby"]]
MSpec.retrieve(:tags_patterns).should == [[/spec\/ruby/, "spec/tags"], [/frozen/, "ruby"]]
end
end
describe MSpec, ".register_exit" do
before :each do
MSpec.store :exit, 0
end
it "records the exit code" do
MSpec.exit_code.should == 0
MSpec.register_exit 1
MSpec.exit_code.should == 1
end
end
describe MSpec, ".exit_code" do
it "retrieves the code set with .register_exit" do
MSpec.register_exit 99
MSpec.exit_code.should == 99
end
end
describe MSpec, ".store" do
it "records data for MSpec settings" do
MSpec.store :anything, :value
MSpec.retrieve(:anything).should == :value
end
end
describe MSpec, ".retrieve" do
it "accesses .store'd data" do
MSpec.register :retrieve, :first
MSpec.retrieve(:retrieve).should == [:first]
end
end
describe MSpec, ".randomize" do
it "sets the flag to randomize spec execution order" do
MSpec.randomize?.should == false
MSpec.randomize = true
MSpec.randomize?.should == true
MSpec.randomize = false
MSpec.randomize?.should == false
end
end
describe MSpec, ".register" do
it "is the gateway behind the register(symbol, action) facility" do
MSpec.register :bonus, :first
MSpec.register :bonus, :second
MSpec.register :bonus, :second
MSpec.retrieve(:bonus).should == [:first, :second]
end
end
describe MSpec, ".unregister" do
it "is the gateway behind the unregister(symbol, actions) facility" do
MSpec.register :unregister, :first
MSpec.register :unregister, :second
MSpec.unregister :unregister, :second
MSpec.retrieve(:unregister).should == [:first]
end
end
describe MSpec, ".protect" do
before :each do
MSpec.clear_current
@cs = ContextState.new "C#m"
@cs.parent = MSpec.current
@es = ExampleState.new @cs, "runs"
ScratchPad.record Exception.new("Sharp!")
end
it "returns true if no exception is raised" do
MSpec.protect("passed") { 1 }.should be_true
end
it "returns false if an exception is raised" do
MSpec.protect("testing") { raise ScratchPad.recorded }.should be_false
end
it "rescues any exceptions raised when evaluating the block argument" do
MSpec.protect("") { raise Exception, "Now you see me..." }
end
it "does not rescue SystemExit" do
begin
MSpec.protect("") { exit 1 }
rescue SystemExit
ScratchPad.record :system_exit
end
ScratchPad.recorded.should == :system_exit
end
it "calls all the exception actions" do
exc = ExceptionState.new @es, "testing", ScratchPad.recorded
ExceptionState.stub(:new).and_return(exc)
action = double("exception")
action.should_receive(:exception).with(exc)
MSpec.register :exception, action
MSpec.protect("testing") { raise ScratchPad.recorded }
MSpec.unregister :exception, action
end
it "registers a non-zero exit code when an exception is raised" do
MSpec.should_receive(:register_exit).with(1)
MSpec.protect("testing") { raise ScratchPad.recorded }
end
end
describe MSpec, ".register_current" do
before :each do
MSpec.clear_current
end
it "sets the value returned by MSpec.current" do
MSpec.current.should be_nil
MSpec.register_current :a
MSpec.current.should == :a
end
end
describe MSpec, ".clear_current" do
it "sets the value returned by MSpec.current to nil" do
MSpec.register_current :a
MSpec.current.should_not be_nil
MSpec.clear_current
MSpec.current.should be_nil
end
end
describe MSpec, ".current" do
before :each do
MSpec.clear_current
end
it "returns nil if no ContextState has been registered" do
MSpec.current.should be_nil
end
it "returns the most recently registered ContextState" do
first = ContextState.new ""
second = ContextState.new ""
MSpec.register_current first
MSpec.current.should == first
MSpec.register_current second
MSpec.current.should == second
end
end
describe MSpec, ".actions" do
before :each do
MSpec.store :start, []
ScratchPad.record []
start_one = double("one")
start_one.stub(:start).and_return { ScratchPad << :one }
start_two = double("two")
start_two.stub(:start).and_return { ScratchPad << :two }
MSpec.register :start, start_one
MSpec.register :start, start_two
end
it "does not attempt to run any actions if none have been registered" do
MSpec.store :finish, nil
lambda { MSpec.actions :finish }.should_not raise_error
end
it "runs each action registered as a start action" do
MSpec.actions :start
ScratchPad.recorded.should == [:one, :two]
end
end
describe MSpec, ".mode?" do
before :each do
MSpec.clear_modes
end
it "returns true if the mode has been set" do
MSpec.mode?(:verify).should == false
MSpec.register_mode :verify
MSpec.mode?(:verify).should == true
end
end
describe MSpec, ".clear_modes" do
it "clears all registered modes" do
MSpec.register_mode(:pretend)
MSpec.register_mode(:verify)
MSpec.mode?(:pretend).should == true
MSpec.mode?(:verify).should == true
MSpec.clear_modes
MSpec.mode?(:pretend).should == false
MSpec.mode?(:verify).should == false
end
end
describe MSpec, ".guarded?" do
before :each do
MSpec.instance_variable_set :@guarded, []
end
it "returns false if no guard has run" do
MSpec.guarded?.should == false
end
it "returns true if a single guard has run" do
MSpec.guard
MSpec.guarded?.should == true
end
it "returns true if more than one guard has run" do
MSpec.guard
MSpec.guard
MSpec.guarded?.should == true
end
it "returns true until all guards have finished" do
MSpec.guard
MSpec.guard
MSpec.guarded?.should == true
MSpec.unguard
MSpec.guarded?.should == true
MSpec.unguard
MSpec.guarded?.should == false
end
end
describe MSpec, ".describe" do
before :each do
MSpec.clear_current
@cs = ContextState.new ""
ContextState.stub(:new).and_return(@cs)
MSpec.stub(:current).and_return(nil)
MSpec.stub(:register_current)
end
it "creates a new ContextState for the block" do
ContextState.should_receive(:new).and_return(@cs)
MSpec.describe(Object) { }
end
it "accepts an optional second argument" do
ContextState.should_receive(:new).and_return(@cs)
MSpec.describe(Object, "msg") { }
end
it "registers the newly created ContextState" do
MSpec.should_receive(:register_current).with(@cs).twice
MSpec.describe(Object) { }
end
it "invokes the ContextState#describe method" do
prc = lambda { }
@cs.should_receive(:describe).with(&prc)
MSpec.describe(Object, "msg", &prc)
end
end
describe MSpec, ".process" do
before :each do
MSpec.stub(:files)
MSpec.store :start, []
MSpec.store :finish, []
STDOUT.stub(:puts)
end
it "prints the RUBY_DESCRIPTION" do
STDOUT.should_receive(:puts).with(RUBY_DESCRIPTION)
MSpec.process
end
it "calls all start actions" do
start = double("start")
start.stub(:start).and_return { ScratchPad.record :start }
MSpec.register :start, start
MSpec.process
ScratchPad.recorded.should == :start
end
it "calls all finish actions" do
finish = double("finish")
finish.stub(:finish).and_return { ScratchPad.record :finish }
MSpec.register :finish, finish
MSpec.process
ScratchPad.recorded.should == :finish
end
it "calls the files method" do
MSpec.should_receive(:files)
MSpec.process
end
end
describe MSpec, ".files" do
before :each do
MSpec.store :load, []
MSpec.store :unload, []
MSpec.register_files [:one, :two, :three]
Kernel.stub(:load)
end
it "calls load actions before each file" do
load = double("load")
load.stub(:load).and_return { ScratchPad.record :load }
MSpec.register :load, load
MSpec.files
ScratchPad.recorded.should == :load
end
it "shuffles the file list if .randomize? is true" do
MSpec.randomize = true
MSpec.should_receive(:shuffle)
MSpec.files
MSpec.randomize = false
end
it "registers the current file" do
load = double("load")
files = []
load.stub(:load).and_return { files << MSpec.file }
MSpec.register :load, load
MSpec.files
files.should == [:one, :two, :three]
end
end
describe MSpec, ".shuffle" do
before :each do
@base = (0..100).to_a
@list = @base.clone
MSpec.shuffle @list
end
it "does not alter the elements in the list" do
@base.each do |elt|
@list.should include(elt)
end
end
it "changes the order of the list" do
# obviously, this spec has a certain probability
# of failing. If it fails, run it again.
@list.should_not == @base
end
end
describe MSpec, ".tags_file" do
before :each do
MSpec.store :file, "path/to/spec/something/some_spec.rb"
MSpec.store :tags_patterns, nil
end
it "returns the default tags file for the current spec file" do
MSpec.tags_file.should == "path/to/spec/tags/something/some_tags.txt"
end
it "returns the tags file for the current spec file with custom tags_patterns" do
MSpec.register_tags_patterns [[/^(.*)\/spec/, '\1/tags'], [/_spec.rb/, "_tags.txt"]]
MSpec.tags_file.should == "path/to/tags/something/some_tags.txt"
end
it "performs multiple substitutions" do
MSpec.register_tags_patterns [
[%r(/spec/something/), "/spec/other/"],
[%r(/spec/), "/spec/tags/"],
[/_spec.rb/, "_tags.txt"]
]
MSpec.tags_file.should == "path/to/spec/tags/other/some_tags.txt"
end
it "handles cases where no substitution is performed" do
MSpec.register_tags_patterns [[/nothing/, "something"]]
MSpec.tags_file.should == "path/to/spec/something/some_spec.rb"
end
end
describe MSpec, ".read_tags" do
before :each do
MSpec.stub(:tags_file).and_return(File.dirname(__FILE__) + '/tags.txt')
end
it "returns a list of tag instances for matching tag names found" do
one = SpecTag.new "fail(broken):Some#method? works"
MSpec.read_tags(["fail", "pass"]).should == [one]
end
it "returns [] if no tags names match" do
MSpec.read_tags("super").should == []
end
end
describe MSpec, ".read_tags" do
before :each do
@tag = SpecTag.new "fails:Some#method"
File.open(tmp("tags.txt", false), "w") do |f|
f.puts ""
f.puts @tag
f.puts ""
end
MSpec.stub(:tags_file).and_return(tmp("tags.txt", false))
end
it "does not return a tag object for empty lines" do
MSpec.read_tags(["fails"]).should == [@tag]
end
end
describe MSpec, ".write_tags" do
before :each do
FileUtils.cp File.dirname(__FILE__) + "/tags.txt", tmp("tags.txt", false)
MSpec.stub(:tags_file).and_return(tmp("tags.txt", false))
@tag1 = SpecTag.new "check(broken):Tag#rewrite works"
@tag2 = SpecTag.new "broken:Tag#write_tags fails"
end
after :all do
rm_r tmp("tags.txt", false)
end
it "overwrites the tags in the tag file" do
IO.read(tmp("tags.txt", false)).should == %[fail(broken):Some#method? works
incomplete(20%):The#best method ever
benchmark(0.01825):The#fastest method today
extended():\"Multi-line\\ntext\\ntag\"
]
MSpec.write_tags [@tag1, @tag2]
IO.read(tmp("tags.txt", false)).should == %[check(broken):Tag#rewrite works
broken:Tag#write_tags fails
]
end
end
describe MSpec, ".write_tag" do
before :each do
FileUtils.stub(:mkdir_p)
MSpec.stub(:tags_file).and_return(tmp("tags.txt", false))
@tag = SpecTag.new "fail(broken):Some#method works"
end
after :all do
rm_r tmp("tags.txt", false)
end
it "writes a tag to the tags file for the current spec file" do
MSpec.write_tag @tag
IO.read(tmp("tags.txt", false)).should == "fail(broken):Some#method works\n"
end
it "does not write a duplicate tag" do
File.open(tmp("tags.txt", false), "w") { |f| f.puts @tag }
MSpec.write_tag @tag
IO.read(tmp("tags.txt", false)).should == "fail(broken):Some#method works\n"
end
end
describe MSpec, ".delete_tag" do
before :each do
FileUtils.cp File.dirname(__FILE__) + "/tags.txt", tmp("tags.txt", false)
MSpec.stub(:tags_file).and_return(tmp("tags.txt", false))
@tag = SpecTag.new "fail(Comments don't matter):Some#method? works"
end
after :each do
rm_r tmp("tags.txt", false)
end
it "deletes the tag if it exists" do
MSpec.delete_tag(@tag).should == true
IO.read(tmp("tags.txt", false)).should == %[incomplete(20%):The#best method ever
benchmark(0.01825):The#fastest method today
extended():\"Multi-line\\ntext\\ntag\"
]
end
it "deletes a tag with escaped newlines" do
MSpec.delete_tag(SpecTag.new('extended:"Multi-line\ntext\ntag"')).should == true
IO.read(tmp("tags.txt", false)).should == %[fail(broken):Some#method? works
incomplete(20%):The#best method ever
benchmark(0.01825):The#fastest method today
]
end
it "does not change the tags file contents if the tag doesn't exist" do
@tag.tag = "failed"
MSpec.delete_tag(@tag).should == false
IO.read(tmp("tags.txt", false)).should == %[fail(broken):Some#method? works
incomplete(20%):The#best method ever
benchmark(0.01825):The#fastest method today
extended():\"Multi-line\\ntext\\ntag\"
]
end
it "deletes the tag file if it is empty" do
MSpec.delete_tag(@tag).should == true
MSpec.delete_tag(SpecTag.new("incomplete:The#best method ever")).should == true
MSpec.delete_tag(SpecTag.new("benchmark:The#fastest method today")).should == true
MSpec.delete_tag(SpecTag.new('extended:"Multi-line\ntext\ntag"')).should == true
File.exist?(tmp("tags.txt", false)).should == false
end
end
describe MSpec, ".delete_tags" do
before :each do
@tags = tmp("tags.txt", false)
FileUtils.cp File.dirname(__FILE__) + "/tags.txt", @tags
MSpec.stub(:tags_file).and_return(@tags)
end
it "deletes the tag file" do
MSpec.delete_tags
File.exist?(@tags).should be_false
end
end
describe MSpec, ".expectation" do
it "sets the flag that an expectation has been reported" do
MSpec.clear_expectations
MSpec.expectation?.should be_false
MSpec.expectation
MSpec.expectation?.should be_true
end
end
describe MSpec, ".expectation?" do
it "returns true if an expectation has been reported" do
MSpec.expectation
MSpec.expectation?.should be_true
end
it "returns false if an expectation has not been reported" do
MSpec.clear_expectations
MSpec.expectation?.should be_false
end
end
describe MSpec, ".clear_expectations" do
it "clears the flag that an expectation has been reported" do
MSpec.expectation
MSpec.expectation?.should be_true
MSpec.clear_expectations
MSpec.expectation?.should be_false
end
end
describe MSpec, ".register_shared" do
it "stores a shared ContextState by description" do
parent = ContextState.new "container"
state = ContextState.new "shared"
state.parent = parent
prc = lambda { }
state.describe(&prc)
MSpec.register_shared(state)
MSpec.retrieve(:shared)["shared"].should == state
end
end
describe MSpec, ".retrieve_shared" do
it "retrieves the shared ContextState matching description" do
state = ContextState.new ""
MSpec.retrieve(:shared)["shared"] = state
MSpec.retrieve_shared(:shared).should == state
end
end