diff options
Diffstat (limited to 'spec/mspec/spec/matchers')
35 files changed, 1706 insertions, 0 deletions
diff --git a/spec/mspec/spec/matchers/base_spec.rb b/spec/mspec/spec/matchers/base_spec.rb new file mode 100644 index 0000000000..cc13c29d1d --- /dev/null +++ b/spec/mspec/spec/matchers/base_spec.rb @@ -0,0 +1,225 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' +require 'time' + +describe SpecPositiveOperatorMatcher, "== operator" do + it "raises an SpecExpectationNotMetError when expected == actual returns false" do + lambda { + SpecPositiveOperatorMatcher.new(1) == 2 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x to equal y'" do + SpecExpectation.should_receive(:fail_with).with("Expected 1\n", "to equal 2\n") + SpecPositiveOperatorMatcher.new(1) == 2 + end + + it "does not raise an exception when expected == actual returns true" do + SpecPositiveOperatorMatcher.new(1) == 1 + end +end + +describe SpecPositiveOperatorMatcher, "=~ operator" do + it "raises an SpecExpectationNotMetError when expected =~ actual returns false" do + lambda { + SpecPositiveOperatorMatcher.new('real') =~ /fake/ + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected \"x\" to match y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected \"real\"\n", "to match /fake/\n") + SpecPositiveOperatorMatcher.new('real') =~ /fake/ + end + + it "does not raise an exception when expected =~ actual returns true" do + SpecPositiveOperatorMatcher.new('real') =~ /real/ + end +end + +describe SpecPositiveOperatorMatcher, "> operator" do + it "raises an SpecExpectationNotMetError when expected > actual returns false" do + lambda { + SpecPositiveOperatorMatcher.new(4) > 5 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x to be greater than y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 4\n", "to be greater than 5\n") + SpecPositiveOperatorMatcher.new(4) > 5 + end + + it "does not raise an exception when expected > actual returns true" do + SpecPositiveOperatorMatcher.new(5) > 4 + end +end + +describe SpecPositiveOperatorMatcher, ">= operator" do + it "raises an SpecExpectationNotMetError when expected >= actual returns false" do + lambda { + SpecPositiveOperatorMatcher.new(4) >= 5 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x to be greater than or equal to y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 4\n", "to be greater than or equal to 5\n") + SpecPositiveOperatorMatcher.new(4) >= 5 + end + + it "does not raise an exception when expected > actual returns true" do + SpecPositiveOperatorMatcher.new(5) >= 4 + SpecPositiveOperatorMatcher.new(5) >= 5 + end +end + +describe SpecPositiveOperatorMatcher, "< operater" do + it "raises an SpecExpectationNotMetError when expected < actual returns false" do + lambda { + SpecPositiveOperatorMatcher.new(5) < 4 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x to be less than y'" do + SpecExpectation.should_receive(:fail_with).with("Expected 5\n", "to be less than 4\n") + SpecPositiveOperatorMatcher.new(5) < 4 + end + + it "does not raise an exception when expected < actual returns true" do + SpecPositiveOperatorMatcher.new(4) < 5 + end +end + +describe SpecPositiveOperatorMatcher, "<= operater" do + it "raises an SpecExpectationNotMetError when expected < actual returns false" do + lambda { + SpecPositiveOperatorMatcher.new(5) <= 4 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x to be less than or equal to y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 5\n", "to be less than or equal to 4\n") + SpecPositiveOperatorMatcher.new(5) <= 4 + end + + it "does not raise an exception when expected < actual returns true" do + SpecPositiveOperatorMatcher.new(4) <= 5 + SpecPositiveOperatorMatcher.new(4) <= 4 + end +end + +describe SpecNegativeOperatorMatcher, "== operator" do + it "raises an SpecExpectationNotMetError when expected == actual returns true" do + lambda { + SpecNegativeOperatorMatcher.new(1) == 1 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x not to equal y'" do + SpecExpectation.should_receive(:fail_with).with("Expected 1\n", "not to equal 1\n") + SpecNegativeOperatorMatcher.new(1) == 1 + end + + it "does not raise an exception when expected == actual returns false" do + SpecNegativeOperatorMatcher.new(1) == 2 + end +end + +describe SpecNegativeOperatorMatcher, "=~ operator" do + it "raises an SpecExpectationNotMetError when expected =~ actual returns true" do + lambda { + SpecNegativeOperatorMatcher.new('real') =~ /real/ + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected \"x\" not to match /y/'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected \"real\"\n", "not to match /real/\n") + SpecNegativeOperatorMatcher.new('real') =~ /real/ + end + + it "does not raise an exception when expected =~ actual returns false" do + SpecNegativeOperatorMatcher.new('real') =~ /fake/ + end +end + +describe SpecNegativeOperatorMatcher, "< operator" do + it "raises an SpecExpectationNotMetError when expected < actual returns true" do + lambda { + SpecNegativeOperatorMatcher.new(4) < 5 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x not to be less than y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 4\n", "not to be less than 5\n") + SpecNegativeOperatorMatcher.new(4) < 5 + end + + it "does not raise an exception when expected < actual returns false" do + SpecNegativeOperatorMatcher.new(5) < 4 + end +end + +describe SpecNegativeOperatorMatcher, "<= operator" do + it "raises an SpecExpectationNotMetError when expected <= actual returns true" do + lambda { + SpecNegativeOperatorMatcher.new(4) <= 5 + }.should raise_error(SpecExpectationNotMetError) + lambda { + SpecNegativeOperatorMatcher.new(5) <= 5 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x not to be less than or equal to y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 4\n", "not to be less than or equal to 5\n") + SpecNegativeOperatorMatcher.new(4) <= 5 + end + + it "does not raise an exception when expected <= actual returns false" do + SpecNegativeOperatorMatcher.new(5) <= 4 + end +end + +describe SpecNegativeOperatorMatcher, "> operator" do + it "raises an SpecExpectationNotMetError when expected > actual returns true" do + lambda { + SpecNegativeOperatorMatcher.new(5) > 4 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x not to be greater than y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 5\n", "not to be greater than 4\n") + SpecNegativeOperatorMatcher.new(5) > 4 + end + + it "does not raise an exception when expected > actual returns false" do + SpecNegativeOperatorMatcher.new(4) > 5 + end +end + +describe SpecNegativeOperatorMatcher, ">= operator" do + it "raises an SpecExpectationNotMetError when expected >= actual returns true" do + lambda { + SpecNegativeOperatorMatcher.new(5) >= 4 + }.should raise_error(SpecExpectationNotMetError) + lambda { + SpecNegativeOperatorMatcher.new(5) >= 5 + }.should raise_error(SpecExpectationNotMetError) + end + + it "provides a failure message that 'Expected x not to be greater than or equal to y'" do + SpecExpectation.should_receive(:fail_with).with( + "Expected 5\n", "not to be greater than or equal to 4\n") + SpecNegativeOperatorMatcher.new(5) >= 4 + end + + it "does not raise an exception when expected >= actual returns false" do + SpecNegativeOperatorMatcher.new(4) >= 5 + end +end diff --git a/spec/mspec/spec/matchers/be_an_instance_of_spec.rb b/spec/mspec/spec/matchers/be_an_instance_of_spec.rb new file mode 100644 index 0000000000..7f2126df7d --- /dev/null +++ b/spec/mspec/spec/matchers/be_an_instance_of_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +module BeAnInOfSpecs + class A + end + + class B < A + end + + class C < B + end +end + +describe BeAnInstanceOfMatcher do + it "matches when actual is an instance_of? expected" do + a = BeAnInOfSpecs::A.new + BeAnInstanceOfMatcher.new(BeAnInOfSpecs::A).matches?(a).should be_true + + b = BeAnInOfSpecs::B.new + BeAnInstanceOfMatcher.new(BeAnInOfSpecs::B).matches?(b).should be_true + end + + it "does not match when actual is not an instance_of? expected" do + a = BeAnInOfSpecs::A.new + BeAnInstanceOfMatcher.new(BeAnInOfSpecs::B).matches?(a).should be_false + + b = BeAnInOfSpecs::B.new + BeAnInstanceOfMatcher.new(BeAnInOfSpecs::A).matches?(b).should be_false + + c = BeAnInOfSpecs::C.new + BeAnInstanceOfMatcher.new(BeAnInOfSpecs::A).matches?(c).should be_false + BeAnInstanceOfMatcher.new(BeAnInOfSpecs::B).matches?(c).should be_false + end + + it "provides a useful failure message" do + matcher = BeAnInstanceOfMatcher.new(Numeric) + matcher.matches?("string") + matcher.failure_message.should == [ + "Expected \"string\" (String)", "to be an instance of Numeric"] + end + + it "provides a useful negative failure message" do + matcher = BeAnInstanceOfMatcher.new(Numeric) + matcher.matches?(4.0) + matcher.negative_failure_message.should == [ + "Expected 4.0 (Float)", "not to be an instance of Numeric"] + end +end diff --git a/spec/mspec/spec/matchers/be_ancestor_of_spec.rb b/spec/mspec/spec/matchers/be_ancestor_of_spec.rb new file mode 100644 index 0000000000..c6bd1a26c7 --- /dev/null +++ b/spec/mspec/spec/matchers/be_ancestor_of_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class Parent; end +class Child < Parent; end + +describe BeAncestorOfMatcher do + it "matches when actual is an ancestor of expected" do + BeAncestorOfMatcher.new(Child).matches?(Parent).should == true + end + + it "does not match when actual is not an ancestor of expected" do + BeAncestorOfMatcher.new(Parent).matches?(Child).should == false + end + + it "provides a useful failure message" do + matcher = BeAncestorOfMatcher.new(Parent) + matcher.matches?(Child) + matcher.failure_message.should == ["Expected Child", "to be an ancestor of Parent"] + end + + it "provides a useful negative failure message" do + matcher = BeAncestorOfMatcher.new(Child) + matcher.matches?(Parent) + matcher.negative_failure_message.should == ["Expected Parent", "not to be an ancestor of Child"] + end +end diff --git a/spec/mspec/spec/matchers/be_close_spec.rb b/spec/mspec/spec/matchers/be_close_spec.rb new file mode 100644 index 0000000000..3ced61dc7a --- /dev/null +++ b/spec/mspec/spec/matchers/be_close_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +# Adapted from RSpec 1.0.8 +describe BeCloseMatcher do + it "matches when actual == expected" do + BeCloseMatcher.new(5.0, 0.5).matches?(5.0).should == true + end + + it "matches when actual < (expected + tolerance)" do + BeCloseMatcher.new(5.0, 0.5).matches?(5.49).should == true + end + + it "matches when actual > (expected - tolerance)" do + BeCloseMatcher.new(5.0, 0.5).matches?(4.51).should == true + end + + it "does not match when actual == (expected + tolerance)" do + BeCloseMatcher.new(5.0, 0.5).matches?(5.5).should == false + end + + it "does not match when actual == (expected - tolerance)" do + BeCloseMatcher.new(5.0, 0.5).matches?(4.5).should == false + end + + it "does not match when actual < (expected - tolerance)" do + BeCloseMatcher.new(5.0, 0.5).matches?(4.49).should == false + end + + it "does not match when actual > (expected + tolerance)" do + BeCloseMatcher.new(5.0, 0.5).matches?(5.51).should == false + end + + it "provides a useful failure message" do + matcher = BeCloseMatcher.new(5.0, 0.5) + matcher.matches?(5.5) + matcher.failure_message.should == ["Expected 5.0", "to be within +/- 0.5 of 5.5"] + end + + it "provides a useful negative failure message" do + matcher = BeCloseMatcher.new(5.0, 0.5) + matcher.matches?(5.0) + matcher.negative_failure_message.should == ["Expected 5.0", "not to be within +/- 0.5 of 5.0"] + end +end diff --git a/spec/mspec/spec/matchers/be_computed_by_spec.rb b/spec/mspec/spec/matchers/be_computed_by_spec.rb new file mode 100644 index 0000000000..9833e211a4 --- /dev/null +++ b/spec/mspec/spec/matchers/be_computed_by_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' +require 'mspec/matchers' + +describe BeComputedByMatcher do + it "matches when all entries in the Array compute" do + array = [ [65, "A"], + [90, "Z"] ] + BeComputedByMatcher.new(:chr).matches?(array).should be_true + end + + it "matches when all entries in the Array with arguments compute" do + array = [ [1, 2, 3], + [2, 4, 6] ] + BeComputedByMatcher.new(:+).matches?(array).should be_true + end + + it "does not match when any entry in the Array does not compute" do + array = [ [65, "A" ], + [91, "Z" ] ] + BeComputedByMatcher.new(:chr).matches?(array).should be_false + end + + it "accepts an argument list to apply to each method call" do + array = [ [65, "1000001" ], + [90, "1011010" ] ] + BeComputedByMatcher.new(:to_s, 2).matches?(array).should be_true + end + + it "does not match when any entry in the Array with arguments does not compute" do + array = [ [1, 2, 3], + [2, 4, 7] ] + BeComputedByMatcher.new(:+).matches?(array).should be_false + end + + it "provides a useful failure message" do + array = [ [65, "A" ], + [91, "Z" ] ] + matcher = BeComputedByMatcher.new(:chr) + matcher.matches?(array) + matcher.failure_message.should == ["Expected \"Z\"", "to be computed by 91.chr (computed \"[\" instead)"] + end +end diff --git a/spec/mspec/spec/matchers/be_empty_spec.rb b/spec/mspec/spec/matchers/be_empty_spec.rb new file mode 100644 index 0000000000..cb8663f5ee --- /dev/null +++ b/spec/mspec/spec/matchers/be_empty_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BeEmptyMatcher do + it "matches when actual is empty" do + BeEmptyMatcher.new.matches?("").should == true + end + + it "does not match when actual is not empty" do + BeEmptyMatcher.new.matches?([10]).should == false + end + + it "provides a useful failure message" do + matcher = BeEmptyMatcher.new + matcher.matches?("not empty string") + matcher.failure_message.should == ["Expected \"not empty string\"", "to be empty"] + end + + it "provides a useful negative failure message" do + matcher = BeEmptyMatcher.new + matcher.matches?("") + matcher.negative_failure_message.should == ["Expected \"\"", "not to be empty"] + end +end + diff --git a/spec/mspec/spec/matchers/be_false_spec.rb b/spec/mspec/spec/matchers/be_false_spec.rb new file mode 100644 index 0000000000..31afd24ebc --- /dev/null +++ b/spec/mspec/spec/matchers/be_false_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BeFalseMatcher do + it "matches when actual is false" do + BeFalseMatcher.new.matches?(false).should == true + end + + it "does not match when actual is not false" do + BeFalseMatcher.new.matches?("").should == false + BeFalseMatcher.new.matches?(true).should == false + BeFalseMatcher.new.matches?(nil).should == false + BeFalseMatcher.new.matches?(0).should == false + end + + it "provides a useful failure message" do + matcher = BeFalseMatcher.new + matcher.matches?("some string") + matcher.failure_message.should == ["Expected \"some string\"", "to be false"] + end + + it "provides a useful negative failure message" do + matcher = BeFalseMatcher.new + matcher.matches?(false) + matcher.negative_failure_message.should == ["Expected false", "not to be false"] + end +end diff --git a/spec/mspec/spec/matchers/be_kind_of_spec.rb b/spec/mspec/spec/matchers/be_kind_of_spec.rb new file mode 100644 index 0000000000..554ae6aa82 --- /dev/null +++ b/spec/mspec/spec/matchers/be_kind_of_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BeKindOfMatcher do + it "matches when actual is a kind_of? expected" do + BeKindOfMatcher.new(Integer).matches?(1).should == true + BeKindOfMatcher.new(Fixnum).matches?(2).should == true + BeKindOfMatcher.new(Regexp).matches?(/m/).should == true + end + + it "does not match when actual is not a kind_of? expected" do + BeKindOfMatcher.new(Integer).matches?(1.5).should == false + BeKindOfMatcher.new(String).matches?(:a).should == false + BeKindOfMatcher.new(Hash).matches?([]).should == false + end + + it "provides a useful failure message" do + matcher = BeKindOfMatcher.new(Numeric) + matcher.matches?('string') + matcher.failure_message.should == [ + "Expected \"string\" (String)", "to be kind of Numeric"] + end + + it "provides a useful negative failure message" do + matcher = BeKindOfMatcher.new(Numeric) + matcher.matches?(4.0) + matcher.negative_failure_message.should == [ + "Expected 4.0 (Float)", "not to be kind of Numeric"] + end +end diff --git a/spec/mspec/spec/matchers/be_nan_spec.rb b/spec/mspec/spec/matchers/be_nan_spec.rb new file mode 100644 index 0000000000..2062763a92 --- /dev/null +++ b/spec/mspec/spec/matchers/be_nan_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/guards' +require 'mspec/helpers' +require 'mspec/matchers' + +describe BeNaNMatcher do + it "matches when actual is NaN" do + BeNaNMatcher.new.matches?(nan_value).should == true + end + + it "does not match when actual is not NaN" do + BeNaNMatcher.new.matches?(1.0).should == false + BeNaNMatcher.new.matches?(0).should == false + end + + it "provides a useful failure message" do + matcher = BeNaNMatcher.new + matcher.matches?(0) + matcher.failure_message.should == ["Expected 0", "to be NaN"] + end + + it "provides a useful negative failure message" do + matcher = BeNaNMatcher.new + matcher.matches?(nan_value) + matcher.negative_failure_message.should == ["Expected NaN", "not to be NaN"] + end +end diff --git a/spec/mspec/spec/matchers/be_nil_spec.rb b/spec/mspec/spec/matchers/be_nil_spec.rb new file mode 100644 index 0000000000..6551feb5de --- /dev/null +++ b/spec/mspec/spec/matchers/be_nil_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BeNilMatcher do + it "matches when actual is nil" do + BeNilMatcher.new.matches?(nil).should == true + end + + it "does not match when actual is not nil" do + BeNilMatcher.new.matches?("").should == false + BeNilMatcher.new.matches?(false).should == false + BeNilMatcher.new.matches?(0).should == false + end + + it "provides a useful failure message" do + matcher = BeNilMatcher.new + matcher.matches?("some string") + matcher.failure_message.should == ["Expected \"some string\"", "to be nil"] + end + + it "provides a useful negative failure message" do + matcher = BeNilMatcher.new + matcher.matches?(nil) + matcher.negative_failure_message.should == ["Expected nil", "not to be nil"] + end +end diff --git a/spec/mspec/spec/matchers/be_true_or_false_spec.rb b/spec/mspec/spec/matchers/be_true_or_false_spec.rb new file mode 100644 index 0000000000..3edffcb1b1 --- /dev/null +++ b/spec/mspec/spec/matchers/be_true_or_false_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BeTrueOrFalseMatcher do + it "matches when actual is true" do + BeTrueOrFalseMatcher.new.matches?(true).should == true + end + + it "matches when actual is false" do + BeTrueOrFalseMatcher.new.matches?(false).should == true + end + + it "provides a useful failure message" do + matcher = BeTrueOrFalseMatcher.new + matcher.matches?("some string") + matcher.failure_message.should == ["Expected \"some string\"", "to be true or false"] + end +end diff --git a/spec/mspec/spec/matchers/be_true_spec.rb b/spec/mspec/spec/matchers/be_true_spec.rb new file mode 100644 index 0000000000..90c89b3911 --- /dev/null +++ b/spec/mspec/spec/matchers/be_true_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BeTrueMatcher do + it "matches when actual is true" do + BeTrueMatcher.new.matches?(true).should == true + end + + it "does not match when actual is not true" do + BeTrueMatcher.new.matches?("").should == false + BeTrueMatcher.new.matches?(false).should == false + BeTrueMatcher.new.matches?(nil).should == false + BeTrueMatcher.new.matches?(0).should == false + end + + it "provides a useful failure message" do + matcher = BeTrueMatcher.new + matcher.matches?("some string") + matcher.failure_message.should == ["Expected \"some string\"", "to be true"] + end + + it "provides a useful negative failure message" do + matcher = BeTrueMatcher.new + matcher.matches?(true) + matcher.negative_failure_message.should == ["Expected true", "not to be true"] + end +end diff --git a/spec/mspec/spec/matchers/block_caller_spec.rb b/spec/mspec/spec/matchers/block_caller_spec.rb new file mode 100644 index 0000000000..d6793b9779 --- /dev/null +++ b/spec/mspec/spec/matchers/block_caller_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe BlockingMatcher do + it 'matches when a Proc blocks the caller' do + BlockingMatcher.new.matches?(proc { sleep }).should == true + end + + it 'does not match when a Proc does not block the caller' do + BlockingMatcher.new.matches?(proc { 1 }).should == false + end +end diff --git a/spec/mspec/spec/matchers/complain_spec.rb b/spec/mspec/spec/matchers/complain_spec.rb new file mode 100644 index 0000000000..709b57be6c --- /dev/null +++ b/spec/mspec/spec/matchers/complain_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe ComplainMatcher do + it "matches when executing the proc results in output to $stderr" do + proc = lambda { warn "I'm gonna tell yo mama" } + ComplainMatcher.new(nil).matches?(proc).should == true + end + + it "maches when executing the proc results in the expected output to $stderr" do + proc = lambda { warn "Que haces?" } + ComplainMatcher.new("Que haces?\n").matches?(proc).should == true + ComplainMatcher.new("Que pasa?\n").matches?(proc).should == false + ComplainMatcher.new(/Que/).matches?(proc).should == true + ComplainMatcher.new(/Quoi/).matches?(proc).should == false + end + + it "does not match when there is no output to $stderr" do + ComplainMatcher.new(nil).matches?(lambda {}).should == false + end + + it "provides a useful failure message" do + matcher = ComplainMatcher.new(nil) + matcher.matches?(lambda { }) + matcher.failure_message.should == ["Expected a warning", "but received none"] + matcher = ComplainMatcher.new("listen here") + matcher.matches?(lambda { warn "look out" }) + matcher.failure_message.should == + ["Expected warning: \"listen here\"", "but got: \"look out\""] + matcher = ComplainMatcher.new(/talk/) + matcher.matches?(lambda { warn "listen up" }) + matcher.failure_message.should == + ["Expected warning to match: /talk/", "but got: \"listen up\""] + end + + it "provides a useful negative failure message" do + proc = lambda { warn "ouch" } + matcher = ComplainMatcher.new(nil) + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Unexpected warning: ", "\"ouch\""] + matcher = ComplainMatcher.new("ouchy") + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected warning: \"ouchy\"", "but got: \"ouch\""] + matcher = ComplainMatcher.new(/ou/) + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected warning not to match: /ou/", "but got: \"ouch\""] + end +end diff --git a/spec/mspec/spec/matchers/eql_spec.rb b/spec/mspec/spec/matchers/eql_spec.rb new file mode 100644 index 0000000000..711ebdb679 --- /dev/null +++ b/spec/mspec/spec/matchers/eql_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe EqlMatcher do + it "matches when actual is eql? to expected" do + EqlMatcher.new(1).matches?(1).should == true + EqlMatcher.new(1.5).matches?(1.5).should == true + EqlMatcher.new("red").matches?("red").should == true + EqlMatcher.new(:blue).matches?(:blue).should == true + EqlMatcher.new(Object).matches?(Object).should == true + + o = Object.new + EqlMatcher.new(o).matches?(o).should == true + end + + it "does not match when actual is not eql? to expected" do + EqlMatcher.new(1).matches?(1.0).should == false + EqlMatcher.new(Hash).matches?(Object).should == false + end + + it "provides a useful failure message" do + matcher = EqlMatcher.new("red") + matcher.matches?("red") + matcher.failure_message.should == ["Expected \"red\"\n", "to have same value and type as \"red\"\n"] + end + + it "provides a useful negative failure message" do + matcher = EqlMatcher.new(1) + matcher.matches?(1.0) + matcher.negative_failure_message.should == ["Expected 1.0\n", "not to have same value or type as 1\n"] + end +end diff --git a/spec/mspec/spec/matchers/equal_element_spec.rb b/spec/mspec/spec/matchers/equal_element_spec.rb new file mode 100644 index 0000000000..45b8390364 --- /dev/null +++ b/spec/mspec/spec/matchers/equal_element_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe EqualElementMatcher do + it "matches if it finds an element with the passed name, no matter what attributes/content" do + EqualElementMatcher.new("A").matches?('<A></A>').should be_true + EqualElementMatcher.new("A").matches?('<A HREF="http://example.com"></A>').should be_true + EqualElementMatcher.new("A").matches?('<A HREF="http://example.com"></A>').should be_true + + EqualElementMatcher.new("BASE").matches?('<BASE></A>').should be_false + EqualElementMatcher.new("BASE").matches?('<A></BASE>').should be_false + EqualElementMatcher.new("BASE").matches?('<A></A>').should be_false + EqualElementMatcher.new("BASE").matches?('<A HREF="http://example.com"></A>').should be_false + EqualElementMatcher.new("BASE").matches?('<A HREF="http://example.com"></A>').should be_false + end + + it "matches if it finds an element with the passed name and the passed attributes" do + EqualElementMatcher.new("A", {}).matches?('<A></A>').should be_true + EqualElementMatcher.new("A", nil).matches?('<A HREF="http://example.com"></A>').should be_true + EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A HREF="http://example.com"></A>').should be_true + + EqualElementMatcher.new("A", {}).matches?('<A HREF="http://example.com"></A>').should be_false + EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A></A>').should be_false + EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A HREF="http://test.com"></A>').should be_false + EqualElementMatcher.new("A", "HREF" => "http://example.com").matches?('<A HREF="http://example.com" HREF="http://example.com"></A>').should be_false + end + + it "matches if it finds an element with the passed name, the passed attributes and the passed content" do + EqualElementMatcher.new("A", {}, "").matches?('<A></A>').should be_true + EqualElementMatcher.new("A", {"HREF" => "http://example.com"}, "Example").matches?('<A HREF="http://example.com">Example</A>').should be_true + + EqualElementMatcher.new("A", {}, "Test").matches?('<A></A>').should be_false + EqualElementMatcher.new("A", {"HREF" => "http://example.com"}, "Example").matches?('<A HREF="http://example.com"></A>').should be_false + EqualElementMatcher.new("A", {"HREF" => "http://example.com"}, "Example").matches?('<A HREF="http://example.com">Test</A>').should be_false + end + + it "can match unclosed elements" do + EqualElementMatcher.new("BASE", nil, nil, :not_closed => true).matches?('<BASE>').should be_true + EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, nil, :not_closed => true).matches?('<BASE HREF="http://example.com">').should be_true + EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, "Example", :not_closed => true).matches?('<BASE HREF="http://example.com">Example').should be_true + + EqualElementMatcher.new("BASE", {}, nil, :not_closed => true).matches?('<BASE HREF="http://example.com">').should be_false + EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, "", :not_closed => true).matches?('<BASE HREF="http://example.com">Example').should be_false + EqualElementMatcher.new("BASE", {"HREF" => "http://example.com"}, "Test", :not_closed => true).matches?('<BASE HREF="http://example.com">Example').should be_false + end + + it "provides a useful failure message" do + equal_element = EqualElementMatcher.new("A", {}, "Test") + equal_element.matches?('<A></A>').should be_false + equal_element.failure_message.should == [%{Expected "<A></A>"\n}, %{to be a 'A' element with no attributes and "Test" as content}] + + equal_element = EqualElementMatcher.new("A", {}, "") + equal_element.matches?('<A>Test</A>').should be_false + equal_element.failure_message.should == [%{Expected "<A>Test</A>"\n}, %{to be a 'A' element with no attributes and no content}] + + equal_element = EqualElementMatcher.new("A", "HREF" => "http://www.example.com") + equal_element.matches?('<A>Test</A>').should be_false + equal_element.failure_message.should == [%{Expected "<A>Test</A>"\n}, %{to be a 'A' element with HREF="http://www.example.com" and any content}] + end + + it "provides a useful negative failure message" do + equal_element = EqualElementMatcher.new("A", {}, "Test") + equal_element.matches?('<A></A>').should be_false + equal_element.negative_failure_message.should == [%{Expected "<A></A>"\n}, %{not to be a 'A' element with no attributes and "Test" as content}] + + equal_element = EqualElementMatcher.new("A", {}, "") + equal_element.matches?('<A>Test</A>').should be_false + equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"\n}, %{not to be a 'A' element with no attributes and no content}] + + equal_element = EqualElementMatcher.new("A", "HREF" => "http://www.example.com") + equal_element.matches?('<A>Test</A>').should be_false + equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"\n}, %{not to be a 'A' element with HREF="http://www.example.com" and any content}] + end +end diff --git a/spec/mspec/spec/matchers/equal_spec.rb b/spec/mspec/spec/matchers/equal_spec.rb new file mode 100644 index 0000000000..ca7bf83fdd --- /dev/null +++ b/spec/mspec/spec/matchers/equal_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe EqualMatcher do + it "matches when actual is equal? to expected" do + EqualMatcher.new(1).matches?(1).should == true + EqualMatcher.new(:blue).matches?(:blue).should == true + EqualMatcher.new(Object).matches?(Object).should == true + + o = Object.new + EqualMatcher.new(o).matches?(o).should == true + end + + it "does not match when actual is not a equal? to expected" do + EqualMatcher.new(1).matches?(1.0).should == false + EqualMatcher.new("blue").matches?("blue").should == false + EqualMatcher.new(Hash).matches?(Object).should == false + end + + it "provides a useful failure message" do + matcher = EqualMatcher.new("red") + matcher.matches?("red") + matcher.failure_message.should == ["Expected \"red\"\n", "to be identical to \"red\"\n"] + end + + it "provides a useful negative failure message" do + matcher = EqualMatcher.new(1) + matcher.matches?(1) + matcher.negative_failure_message.should == ["Expected 1\n", "not to be identical to 1\n"] + end +end diff --git a/spec/mspec/spec/matchers/have_class_variable_spec.rb b/spec/mspec/spec/matchers/have_class_variable_spec.rb new file mode 100644 index 0000000000..e440050056 --- /dev/null +++ b/spec/mspec/spec/matchers/have_class_variable_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class IVarModMock; end + +shared_examples_for "have_class_variable, on all Ruby versions" do + after :all do + Object.const_set :RUBY_VERSION, @ruby_version + end + + it "matches when mod has the class variable, given as string" do + matcher = HaveClassVariableMatcher.new('@foo') + matcher.matches?(IVarModMock).should be_true + end + + it "matches when mod has the class variable, given as symbol" do + matcher = HaveClassVariableMatcher.new(:@foo) + matcher.matches?(IVarModMock).should be_true + end + + it "does not match when mod hasn't got the class variable, given as string" do + matcher = HaveClassVariableMatcher.new('@bar') + matcher.matches?(IVarModMock).should be_false + end + + it "does not match when mod hasn't got the class variable, given as symbol" do + matcher = HaveClassVariableMatcher.new(:@bar) + matcher.matches?(IVarModMock).should be_false + end + + it "provides a failure message for #should" do + matcher = HaveClassVariableMatcher.new(:@bar) + matcher.matches?(IVarModMock) + matcher.failure_message.should == [ + "Expected IVarModMock to have class variable '@bar'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HaveClassVariableMatcher.new(:@bar) + matcher.matches?(IVarModMock) + matcher.negative_failure_message.should == [ + "Expected IVarModMock NOT to have class variable '@bar'", + "but it does" + ] + end +end + +describe HaveClassVariableMatcher, "on RUBY_VERSION >= 1.9" do + before :all do + @ruby_version = Object.const_get :RUBY_VERSION + Object.const_set :RUBY_VERSION, '1.9.0' + + def IVarModMock.class_variables + [:@foo] + end + end + + it_should_behave_like "have_class_variable, on all Ruby versions" +end diff --git a/spec/mspec/spec/matchers/have_constant_spec.rb b/spec/mspec/spec/matchers/have_constant_spec.rb new file mode 100644 index 0000000000..20c5f161d4 --- /dev/null +++ b/spec/mspec/spec/matchers/have_constant_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HCMSpecs + X = :x +end + +describe HaveConstantMatcher do + it "matches when mod has the constant" do + matcher = HaveConstantMatcher.new :X + matcher.matches?(HCMSpecs).should be_true + end + + it "does not match when mod does not have the constant" do + matcher = HaveConstantMatcher.new :A + matcher.matches?(HCMSpecs).should be_false + end + + it "provides a failure message for #should" do + matcher = HaveConstantMatcher.new :A + matcher.matches?(HCMSpecs) + matcher.failure_message.should == [ + "Expected HCMSpecs to have constant 'A'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HaveConstantMatcher.new :X + matcher.matches?(HCMSpecs) + matcher.negative_failure_message.should == [ + "Expected HCMSpecs NOT to have constant 'X'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_instance_method_spec.rb b/spec/mspec/spec/matchers/have_instance_method_spec.rb new file mode 100644 index 0000000000..738f5f875d --- /dev/null +++ b/spec/mspec/spec/matchers/have_instance_method_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HIMMSpecs + def instance_method + end + + class Subclass < HIMMSpecs + def instance_sub_method + end + end +end + +describe HaveInstanceMethodMatcher do + it "inherits from MethodMatcher" do + HaveInstanceMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when mod has the instance method" do + matcher = HaveInstanceMethodMatcher.new :instance_method + matcher.matches?(HIMMSpecs).should be_true + matcher.matches?(HIMMSpecs::Subclass).should be_true + end + + it "does not match when mod does not have the instance method" do + matcher = HaveInstanceMethodMatcher.new :another_method + matcher.matches?(HIMMSpecs).should be_false + end + + it "does not match if the method is in a superclass and include_super is false" do + matcher = HaveInstanceMethodMatcher.new :instance_method, false + matcher.matches?(HIMMSpecs::Subclass).should be_false + end + + it "provides a failure message for #should" do + matcher = HaveInstanceMethodMatcher.new :some_method + matcher.matches?(HIMMSpecs) + matcher.failure_message.should == [ + "Expected HIMMSpecs to have instance method 'some_method'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HaveInstanceMethodMatcher.new :some_method + matcher.matches?(HIMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HIMMSpecs NOT to have instance method 'some_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_instance_variable_spec.rb b/spec/mspec/spec/matchers/have_instance_variable_spec.rb new file mode 100644 index 0000000000..ababb38bc7 --- /dev/null +++ b/spec/mspec/spec/matchers/have_instance_variable_spec.rb @@ -0,0 +1,61 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +shared_examples_for "have_instance_variable, on all Ruby versions" do + after :all do + Object.const_set :RUBY_VERSION, @ruby_version + end + + it "matches when object has the instance variable, given as string" do + matcher = HaveInstanceVariableMatcher.new('@foo') + matcher.matches?(@object).should be_true + end + + it "matches when object has the instance variable, given as symbol" do + matcher = HaveInstanceVariableMatcher.new(:@foo) + matcher.matches?(@object).should be_true + end + + it "does not match when object hasn't got the instance variable, given as string" do + matcher = HaveInstanceVariableMatcher.new('@bar') + matcher.matches?(@object).should be_false + end + + it "does not match when object hasn't got the instance variable, given as symbol" do + matcher = HaveInstanceVariableMatcher.new(:@bar) + matcher.matches?(@object).should be_false + end + + it "provides a failure message for #should" do + matcher = HaveInstanceVariableMatcher.new(:@bar) + matcher.matches?(@object) + matcher.failure_message.should == [ + "Expected #{@object.inspect} to have instance variable '@bar'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HaveInstanceVariableMatcher.new(:@bar) + matcher.matches?(@object) + matcher.negative_failure_message.should == [ + "Expected #{@object.inspect} NOT to have instance variable '@bar'", + "but it does" + ] + end +end + +describe HaveInstanceVariableMatcher, "on RUBY_VERSION >= 1.9" do + before :all do + @ruby_version = Object.const_get :RUBY_VERSION + Object.const_set :RUBY_VERSION, '1.9.0' + + @object = Object.new + def @object.instance_variables + [:@foo] + end + end + + it_should_behave_like "have_instance_variable, on all Ruby versions" +end diff --git a/spec/mspec/spec/matchers/have_method_spec.rb b/spec/mspec/spec/matchers/have_method_spec.rb new file mode 100644 index 0000000000..41bd485119 --- /dev/null +++ b/spec/mspec/spec/matchers/have_method_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HMMSpecs + def instance_method + end + + class Subclass < HMMSpecs + def instance_sub_method + end + end +end + +describe HaveMethodMatcher do + it "inherits from MethodMatcher" do + HaveMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when mod has the method" do + matcher = HaveMethodMatcher.new :instance_method + matcher.matches?(HMMSpecs).should be_true + matcher.matches?(HMMSpecs.new).should be_true + matcher.matches?(HMMSpecs::Subclass).should be_true + matcher.matches?(HMMSpecs::Subclass.new).should be_true + end + + it "does not match when mod does not have the method" do + matcher = HaveMethodMatcher.new :another_method + matcher.matches?(HMMSpecs).should be_false + end + + it "does not match if the method is in a superclass and include_super is false" do + matcher = HaveMethodMatcher.new :instance_method, false + matcher.matches?(HMMSpecs::Subclass).should be_false + end + + it "provides a failure message for #should" do + matcher = HaveMethodMatcher.new :some_method + matcher.matches?(HMMSpecs) + matcher.failure_message.should == [ + "Expected HMMSpecs to have method 'some_method'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HaveMethodMatcher.new :some_method + matcher.matches?(HMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HMMSpecs NOT to have method 'some_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_private_instance_method_spec.rb b/spec/mspec/spec/matchers/have_private_instance_method_spec.rb new file mode 100644 index 0000000000..827c6b6034 --- /dev/null +++ b/spec/mspec/spec/matchers/have_private_instance_method_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HPIMMSpecs + private + + def private_method + end + + class Subclass < HPIMMSpecs + private + + def private_sub_method + end + end +end + +describe HavePrivateInstanceMethodMatcher do + it "inherits from MethodMatcher" do + HavePrivateInstanceMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when mod has the private instance method" do + matcher = HavePrivateInstanceMethodMatcher.new :private_method + matcher.matches?(HPIMMSpecs).should be_true + matcher.matches?(HPIMMSpecs::Subclass).should be_true + end + + it "does not match when mod does not have the private instance method" do + matcher = HavePrivateInstanceMethodMatcher.new :another_method + matcher.matches?(HPIMMSpecs).should be_false + end + + it "does not match if the method is in a superclass and include_super is false" do + matcher = HavePrivateInstanceMethodMatcher.new :private_method, false + matcher.matches?(HPIMMSpecs::Subclass).should be_false + end + + it "provides a failure message for #should" do + matcher = HavePrivateInstanceMethodMatcher.new :some_method + matcher.matches?(HPIMMSpecs) + matcher.failure_message.should == [ + "Expected HPIMMSpecs to have private instance method 'some_method'", + "but it does not" + ] + end + + it "provides a failure message for #should_not" do + matcher = HavePrivateInstanceMethodMatcher.new :some_method + matcher.matches?(HPIMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HPIMMSpecs NOT to have private instance method 'some_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_private_method_spec.rb b/spec/mspec/spec/matchers/have_private_method_spec.rb new file mode 100644 index 0000000000..e63a9a3c2f --- /dev/null +++ b/spec/mspec/spec/matchers/have_private_method_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HPMMSpecs + def self.private_method + end + + private_class_method :private_method +end + +describe HavePrivateMethodMatcher do + it "inherits from MethodMatcher" do + HavePrivateMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when mod has the private method" do + matcher = HavePrivateMethodMatcher.new :private_method + matcher.matches?(HPMMSpecs).should be_true + end + + it "does not match when mod does not have the private method" do + matcher = HavePrivateMethodMatcher.new :another_method + matcher.matches?(HPMMSpecs).should be_false + end + + it "provides a failure message for #should" do + matcher = HavePrivateMethodMatcher.new :some_method + matcher.matches?(HPMMSpecs) + matcher.failure_message.should == [ + "Expected HPMMSpecs to have private method 'some_method'", + "but it does not" + ] + end + + it "provides a failure message for #should_not" do + matcher = HavePrivateMethodMatcher.new :private_method + matcher.matches?(HPMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HPMMSpecs NOT to have private method 'private_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_protected_instance_method_spec.rb b/spec/mspec/spec/matchers/have_protected_instance_method_spec.rb new file mode 100644 index 0000000000..460d0368fb --- /dev/null +++ b/spec/mspec/spec/matchers/have_protected_instance_method_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HPIMMSpecs + protected + + def protected_method + end + + class Subclass < HPIMMSpecs + protected + + def protected_sub_method + end + end +end + +describe HaveProtectedInstanceMethodMatcher do + it "inherits from MethodMatcher" do + HaveProtectedInstanceMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when mod has the protected instance method" do + matcher = HaveProtectedInstanceMethodMatcher.new :protected_method + matcher.matches?(HPIMMSpecs).should be_true + matcher.matches?(HPIMMSpecs::Subclass).should be_true + end + + it "does not match when mod does not have the protected instance method" do + matcher = HaveProtectedInstanceMethodMatcher.new :another_method + matcher.matches?(HPIMMSpecs).should be_false + end + + it "does not match if the method is in a superclass and include_super is false" do + matcher = HaveProtectedInstanceMethodMatcher.new :protected_method, false + matcher.matches?(HPIMMSpecs::Subclass).should be_false + end + + it "provides a failure message for #should" do + matcher = HaveProtectedInstanceMethodMatcher.new :some_method + matcher.matches?(HPIMMSpecs) + matcher.failure_message.should == [ + "Expected HPIMMSpecs to have protected instance method 'some_method'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HaveProtectedInstanceMethodMatcher.new :some_method + matcher.matches?(HPIMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HPIMMSpecs NOT to have protected instance method 'some_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_public_instance_method_spec.rb b/spec/mspec/spec/matchers/have_public_instance_method_spec.rb new file mode 100644 index 0000000000..bff1046f04 --- /dev/null +++ b/spec/mspec/spec/matchers/have_public_instance_method_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HPIMMSpecs + def public_method + end + + class Subclass < HPIMMSpecs + def public_sub_method + end + end +end + +describe HavePublicInstanceMethodMatcher do + it "inherits from MethodMatcher" do + HavePublicInstanceMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when mod has the public instance method" do + matcher = HavePublicInstanceMethodMatcher.new :public_method + matcher.matches?(HPIMMSpecs).should be_true + matcher.matches?(HPIMMSpecs::Subclass).should be_true + end + + it "does not match when mod does not have the public instance method" do + matcher = HavePublicInstanceMethodMatcher.new :another_method + matcher.matches?(HPIMMSpecs).should be_false + end + + it "does not match if the method is in a superclass and include_super is false" do + matcher = HavePublicInstanceMethodMatcher.new :public_method, false + matcher.matches?(HPIMMSpecs::Subclass).should be_false + end + + it "provides a failure message for #should" do + matcher = HavePublicInstanceMethodMatcher.new :some_method + matcher.matches?(HPIMMSpecs) + matcher.failure_message.should == [ + "Expected HPIMMSpecs to have public instance method 'some_method'", + "but it does not" + ] + end + + it "provides a failure messoge for #should_not" do + matcher = HavePublicInstanceMethodMatcher.new :some_method + matcher.matches?(HPIMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HPIMMSpecs NOT to have public instance method 'some_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/have_singleton_method_spec.rb b/spec/mspec/spec/matchers/have_singleton_method_spec.rb new file mode 100644 index 0000000000..57c37e01d9 --- /dev/null +++ b/spec/mspec/spec/matchers/have_singleton_method_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class HSMMSpecs + def self.singleton_method + end +end + +describe HaveSingletonMethodMatcher do + it "inherits from MethodMatcher" do + HaveSingletonMethodMatcher.new(:m).should be_kind_of(MethodMatcher) + end + + it "matches when the class has a singleton method" do + matcher = HaveSingletonMethodMatcher.new :singleton_method + matcher.matches?(HSMMSpecs).should be_true + end + + it "matches when the object has a singleton method" do + obj = double("HSMMSpecs") + def obj.singleton_method; end + + matcher = HaveSingletonMethodMatcher.new :singleton_method + matcher.matches?(obj).should be_true + end + + it "provides a failure message for #should" do + matcher = HaveSingletonMethodMatcher.new :some_method + matcher.matches?(HSMMSpecs) + matcher.failure_message.should == [ + "Expected HSMMSpecs to have singleton method 'some_method'", + "but it does not" + ] + end + + it "provides a failure message for #should_not" do + matcher = HaveSingletonMethodMatcher.new :singleton_method + matcher.matches?(HSMMSpecs) + matcher.negative_failure_message.should == [ + "Expected HSMMSpecs NOT to have singleton method 'singleton_method'", + "but it does" + ] + end +end diff --git a/spec/mspec/spec/matchers/include_spec.rb b/spec/mspec/spec/matchers/include_spec.rb new file mode 100644 index 0000000000..f045c5e0cb --- /dev/null +++ b/spec/mspec/spec/matchers/include_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe IncludeMatcher do + it "matches when actual includes expected" do + IncludeMatcher.new(2).matches?([1,2,3]).should == true + IncludeMatcher.new("b").matches?("abc").should == true + end + + it "does not match when actual does not include expected" do + IncludeMatcher.new(4).matches?([1,2,3]).should == false + IncludeMatcher.new("d").matches?("abc").should == false + end + + it "matches when actual includes all expected" do + IncludeMatcher.new(3, 2, 1).matches?([1,2,3]).should == true + IncludeMatcher.new("a", "b", "c").matches?("abc").should == true + end + + it "does not match when actual does not include all expected" do + IncludeMatcher.new(3, 2, 4).matches?([1,2,3]).should == false + IncludeMatcher.new("a", "b", "c", "d").matches?("abc").should == false + end + + it "provides a useful failure message" do + matcher = IncludeMatcher.new(5, 2) + matcher.matches?([1,2,3]) + matcher.failure_message.should == ["Expected [1, 2, 3]", "to include 5"] + end + + it "provides a useful negative failure message" do + matcher = IncludeMatcher.new(1, 2, 3) + matcher.matches?([1,2,3]) + matcher.negative_failure_message.should == ["Expected [1, 2, 3]", "not to include 3"] + end +end diff --git a/spec/mspec/spec/matchers/infinity_spec.rb b/spec/mspec/spec/matchers/infinity_spec.rb new file mode 100644 index 0000000000..6eb8ac2940 --- /dev/null +++ b/spec/mspec/spec/matchers/infinity_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/guards' +require 'mspec/helpers' +require 'mspec/matchers' + +describe InfinityMatcher do + it "matches when actual is infinite and has the correct sign" do + InfinityMatcher.new(1).matches?(infinity_value).should == true + InfinityMatcher.new(-1).matches?(-infinity_value).should == true + end + + it "does not match when actual is not infinite" do + InfinityMatcher.new(1).matches?(1.0).should == false + InfinityMatcher.new(-1).matches?(-1.0).should == false + end + + it "does not match when actual is infinite but has the incorrect sign" do + InfinityMatcher.new(1).matches?(-infinity_value).should == false + InfinityMatcher.new(-1).matches?(infinity_value).should == false + end + + it "provides a useful failure message" do + matcher = InfinityMatcher.new(-1) + matcher.matches?(0) + matcher.failure_message.should == ["Expected 0", "to be -Infinity"] + end + + it "provides a useful negative failure message" do + matcher = InfinityMatcher.new(1) + matcher.matches?(infinity_value) + matcher.negative_failure_message.should == ["Expected Infinity", "not to be Infinity"] + end +end diff --git a/spec/mspec/spec/matchers/match_yaml_spec.rb b/spec/mspec/spec/matchers/match_yaml_spec.rb new file mode 100644 index 0000000000..4f16aee0ec --- /dev/null +++ b/spec/mspec/spec/matchers/match_yaml_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe MatchYAMLMatcher do + before :each do + @matcher = MatchYAMLMatcher.new("--- \nfoo: bar\n") + end + + it "compares YAML documents and matches if they're equivalent" do + @matcher.matches?("--- \nfoo: bar\n").should == true + end + + it "compares YAML documents and does not match if they're not equivalent" do + @matcher.matches?("--- \nbar: foo\n").should == false + @matcher.matches?("--- \nfoo: \nbar\n").should == false + end + + it "also receives objects that respond_to to_yaml" do + matcher = MatchYAMLMatcher.new("some string") + matcher.matches?("some string").should == true + + matcher = MatchYAMLMatcher.new(['a', 'b']) + matcher.matches?("--- \n- a\n- b\n").should == true + + matcher = MatchYAMLMatcher.new("foo" => "bar") + matcher.matches?("--- \nfoo: bar\n").should == true + end + + it "matches documents with trailing whitespace" do + @matcher.matches?("--- \nfoo: bar \n").should == true + @matcher.matches?("--- \nfoo: bar \n").should == true + end + + it "fails with a descriptive error message" do + @matcher.matches?("foo").should == false + @matcher.failure_message.should == ["Expected \"foo\"", " to match \"--- \\nfoo: bar\\n\""] + end +end diff --git a/spec/mspec/spec/matchers/output_spec.rb b/spec/mspec/spec/matchers/output_spec.rb new file mode 100644 index 0000000000..264da3b569 --- /dev/null +++ b/spec/mspec/spec/matchers/output_spec.rb @@ -0,0 +1,74 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe OutputMatcher do + it "matches when executing the proc results in the expected output to $stdout" do + proc = Proc.new { puts "bang!" } + OutputMatcher.new("bang!\n", nil).matches?(proc).should == true + OutputMatcher.new("pop", nil).matches?(proc).should == false + OutputMatcher.new(/bang/, nil).matches?(proc).should == true + OutputMatcher.new(/po/, nil).matches?(proc).should == false + end + + it "matches when executing the proc results in the expected output to $stderr" do + proc = Proc.new { $stderr.write "boom!" } + OutputMatcher.new(nil, "boom!").matches?(proc).should == true + OutputMatcher.new(nil, "fizzle").matches?(proc).should == false + OutputMatcher.new(nil, /boom/).matches?(proc).should == true + OutputMatcher.new(nil, /fizzl/).matches?(proc).should == false + end + + it "provides a useful failure message" do + proc = Proc.new { print "unexpected"; $stderr.print "unerror" } + matcher = OutputMatcher.new("expected", "error") + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected:\n $stdout: \"expected\"\n $stderr: \"error\"\n", + " got:\n $stdout: \"unexpected\"\n $stderr: \"unerror\"\n"] + matcher = OutputMatcher.new("expected", nil) + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected:\n $stdout: \"expected\"\n", + " got:\n $stdout: \"unexpected\"\n"] + matcher = OutputMatcher.new(nil, "error") + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected:\n $stderr: \"error\"\n", + " got:\n $stderr: \"unerror\"\n"] + matcher = OutputMatcher.new(/base/, nil) + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected:\n $stdout: /base/\n", + " got:\n $stdout: \"unexpected\"\n"] + matcher = OutputMatcher.new(nil, /octave/) + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected:\n $stderr: /octave/\n", + " got:\n $stderr: \"unerror\"\n"] + end + + it "provides a useful negative failure message" do + proc = Proc.new { puts "expected"; $stderr.puts "error" } + matcher = OutputMatcher.new("expected", "error") + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected output not to be:\n", " $stdout: \"expected\"\n $stderr: \"error\"\n"] + matcher = OutputMatcher.new("expected", nil) + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected output not to be:\n", " $stdout: \"expected\"\n"] + matcher = OutputMatcher.new(nil, "error") + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected output not to be:\n", " $stderr: \"error\"\n"] + matcher = OutputMatcher.new(/expect/, nil) + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected output not to be:\n", " $stdout: \"expected\"\n"] + matcher = OutputMatcher.new(nil, /err/) + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected output not to be:\n", " $stderr: \"error\"\n"] + end +end diff --git a/spec/mspec/spec/matchers/output_to_fd_spec.rb b/spec/mspec/spec/matchers/output_to_fd_spec.rb new file mode 100644 index 0000000000..d35da58829 --- /dev/null +++ b/spec/mspec/spec/matchers/output_to_fd_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe OutputToFDMatcher do + # Figure out how in the hell to achieve this + it "matches when running the block produces the expected output to the given FD" do + output_to_fd("Hi\n", STDERR).matches?(lambda { $stderr.print "Hi\n" }).should == true + end + + it "does not match if running the block does not produce the expected output to the FD" do + output_to_fd("Hi\n", STDERR).matches?(lambda { $stderr.puts("Hello\n") }).should == false + end + + it "propagate the exception if one is thrown while matching" do + exc = RuntimeError.new("propagates") + lambda { + output_to_fd("Hi\n", STDERR).matches?(lambda { + raise exc + }).should == false + }.should raise_error(exc) + end + + it "defaults to matching against STDOUT" do + output_to_fd("Hi\n").matches?(lambda { $stdout.print "Hi\n" }).should == true + end + + it "accepts any IO instance" do + io = IO.new STDOUT.fileno + output_to_fd("Hi\n", io).matches?(lambda { io.print "Hi\n" }).should == true + end + + it "allows matching with a Regexp" do + s = "Hi there\n" + output_to_fd(/Hi/, STDERR).matches?(lambda { $stderr.print s }).should == true + output_to_fd(/Hi?/, STDERR).matches?(lambda { $stderr.print s }).should == true + output_to_fd(/[hH]i?/, STDERR).matches?(lambda { $stderr.print s }).should == true + output_to_fd(/.*/, STDERR).matches?(lambda { $stderr.print s }).should == true + output_to_fd(/H.*?here/, STDERR).matches?(lambda { $stderr.print s }).should == true + output_to_fd(/Ahoy/, STDERR).matches?(lambda { $stderr.print s }).should == false + end +end diff --git a/spec/mspec/spec/matchers/raise_error_spec.rb b/spec/mspec/spec/matchers/raise_error_spec.rb new file mode 100644 index 0000000000..88aab34d53 --- /dev/null +++ b/spec/mspec/spec/matchers/raise_error_spec.rb @@ -0,0 +1,108 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +class ExpectedException < Exception; end +class UnexpectedException < Exception; end + +describe RaiseErrorMatcher do + it "matches when the proc raises the expected exception" do + proc = Proc.new { raise ExpectedException } + matcher = RaiseErrorMatcher.new(ExpectedException, nil) + matcher.matches?(proc).should == true + end + + it "executes it's optional block if matched" do + run = false + proc = Proc.new { raise ExpectedException } + matcher = RaiseErrorMatcher.new(ExpectedException, nil) { |error| + run = true + error.class.should == ExpectedException + } + + matcher.matches?(proc).should == true + run.should == true + end + + it "matches when the proc raises the expected exception with the expected message" do + proc = Proc.new { raise ExpectedException, "message" } + matcher = RaiseErrorMatcher.new(ExpectedException, "message") + matcher.matches?(proc).should == true + end + + it "matches when the proc raises the expected exception with a matching message" do + proc = Proc.new { raise ExpectedException, "some message" } + matcher = RaiseErrorMatcher.new(ExpectedException, /some/) + matcher.matches?(proc).should == true + end + + it "does not match when the proc does not raise the expected exception" do + exc = UnexpectedException.new + matcher = RaiseErrorMatcher.new(ExpectedException, nil) + + matcher.matching_exception?(exc).should == false + lambda { + matcher.matches?(Proc.new { raise exc }) + }.should raise_error(UnexpectedException) + end + + it "does not match when the proc raises the expected exception with an unexpected message" do + exc = ExpectedException.new("unexpected") + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + + matcher.matching_exception?(exc).should == false + lambda { + matcher.matches?(Proc.new { raise exc }) + }.should raise_error(ExpectedException) + end + + it "does not match when the proc does not raise an exception" do + proc = Proc.new {} + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + matcher.matches?(proc).should == false + end + + it "provides a useful failure message" do + exc = UnexpectedException.new("unexpected") + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + + matcher.matching_exception?(exc).should == false + lambda { + matcher.matches?(Proc.new { raise exc }) + }.should raise_error(UnexpectedException) + matcher.failure_message.should == + ["Expected ExpectedException (expected)", "but got UnexpectedException (unexpected)"] + end + + it "provides a useful failure message when no exception is raised" do + proc = Proc.new { 120 } + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected ExpectedException (expected)", "but no exception was raised (120 was returned)"] + end + + it "provides a useful failure message when no exception is raised and nil is returned" do + proc = Proc.new { nil } + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + matcher.matches?(proc) + matcher.failure_message.should == + ["Expected ExpectedException (expected)", "but no exception was raised (nil was returned)"] + end + + it "provides a useful negative failure message" do + proc = Proc.new { raise ExpectedException, "expected" } + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected to not get ExpectedException (expected)", ""] + end + + it "provides a useful negative failure message for strict subclasses of the matched exception class" do + proc = Proc.new { raise UnexpectedException, "unexpected" } + matcher = RaiseErrorMatcher.new(Exception, nil) + matcher.matches?(proc) + matcher.negative_failure_message.should == + ["Expected to not get Exception", "but got UnexpectedException (unexpected)"] + end +end diff --git a/spec/mspec/spec/matchers/respond_to_spec.rb b/spec/mspec/spec/matchers/respond_to_spec.rb new file mode 100644 index 0000000000..988caf4dff --- /dev/null +++ b/spec/mspec/spec/matchers/respond_to_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe RespondToMatcher do + it "matches when actual does respond_to? expected" do + RespondToMatcher.new(:to_s).matches?(Object.new).should == true + RespondToMatcher.new(:inject).matches?([]).should == true + RespondToMatcher.new(:[]).matches?(1).should == true + RespondToMatcher.new(:[]=).matches?("string").should == true + end + + it "does not match when actual does not respond_to? expected" do + RespondToMatcher.new(:to_i).matches?(Object.new).should == false + RespondToMatcher.new(:inject).matches?(1).should == false + RespondToMatcher.new(:non_existent_method).matches?([]).should == false + RespondToMatcher.new(:[]=).matches?(1).should == false + end + + it "provides a useful failure message" do + matcher = RespondToMatcher.new(:non_existent_method) + matcher.matches?('string') + matcher.failure_message.should == [ + "Expected \"string\" (String)", "to respond to non_existent_method"] + end + + it "provides a useful negative failure message" do + matcher = RespondToMatcher.new(:to_i) + matcher.matches?(4.0) + matcher.negative_failure_message.should == [ + "Expected 4.0 (Float)", "not to respond to to_i"] + end +end diff --git a/spec/mspec/spec/matchers/signed_zero_spec.rb b/spec/mspec/spec/matchers/signed_zero_spec.rb new file mode 100644 index 0000000000..9c5c50c602 --- /dev/null +++ b/spec/mspec/spec/matchers/signed_zero_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' +require 'mspec/expectations/expectations' +require 'mspec/matchers' + +describe SignedZeroMatcher do + it "matches when actual is zero and has the correct sign" do + SignedZeroMatcher.new(1).matches?(0.0).should == true + SignedZeroMatcher.new(-1).matches?(-0.0).should == true + end + + it "does not match when actual is non-zero" do + SignedZeroMatcher.new(1).matches?(1.0).should == false + SignedZeroMatcher.new(-1).matches?(-1.0).should == false + end + + it "does not match when actual is zero but has the incorrect sign" do + SignedZeroMatcher.new(1).matches?(-0.0).should == false + SignedZeroMatcher.new(-1).matches?(0.0).should == false + end + + it "provides a useful failure message" do + matcher = SignedZeroMatcher.new(-1) + matcher.matches?(0.0) + matcher.failure_message.should == ["Expected 0.0", "to be -0.0"] + end + + it "provides a useful negative failure message" do + matcher = SignedZeroMatcher.new(-1) + matcher.matches?(-0.0) + matcher.negative_failure_message.should == ["Expected -0.0", "not to be -0.0"] + end +end |