summaryrefslogtreecommitdiff
path: root/spec/mspec/spec/runner/mspec_spec.rb
diff options
context:
space:
mode:
authoreregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-07 12:04:49 +0000
committereregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-07 12:04:49 +0000
commit95e8c48dd3348503a8c7db5d0498894a1b676395 (patch)
tree9eef7f720314ebaff56845a74e203770e62284e4 /spec/mspec/spec/runner/mspec_spec.rb
parented7d803500de38186c74bce94d233e85ef51e503 (diff)
Add in-tree mspec and ruby/spec
* For easier modifications of ruby/spec by MRI developers. * .gitignore: track changes under spec. * spec/mspec, spec/rubyspec: add in-tree mspec and ruby/spec. These files can therefore be updated like any other file in MRI. Instructions are provided in spec/README. [Feature #13156] [ruby-core:79246] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/mspec/spec/runner/mspec_spec.rb')
-rw-r--r--spec/mspec/spec/runner/mspec_spec.rb595
1 files changed, 595 insertions, 0 deletions
diff --git a/spec/mspec/spec/runner/mspec_spec.rb b/spec/mspec/spec/runner/mspec_spec.rb
new file mode 100644
index 0000000000..9b8142414e
--- /dev/null
+++ b/spec/mspec/spec/runner/mspec_spec.rb
@@ -0,0 +1,595 @@
+require 'spec_helper'
+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.retrieve(:files).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 :action, :first
+ MSpec.retrieve(:action).should == [:first]
+ end
+end
+
+describe MSpec, ".randomize" do
+ it "sets the flag to randomize spec execution order" do
+ MSpec.randomize?.should == false
+ MSpec.randomize
+ 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
+ MSpec.should_receive(:shuffle)
+ MSpec.files
+ MSpec.randomize false
+ end
+
+ it "registers the current file" do
+ MSpec.should_receive(:store).with(:file, :one)
+ MSpec.should_receive(:store).with(:file, :two)
+ MSpec.should_receive(:store).with(:file, :three)
+ MSpec.files
+ 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