mspec 1.5.10 → 1.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/lib/mspec/commands/mkspec.rb +1 -1
- data/lib/mspec/expectations/expectations.rb +4 -4
- data/lib/mspec/expectations/should.rb +4 -4
- data/lib/mspec/guards/endian.rb +5 -8
- data/lib/mspec/guards/guard.rb +1 -1
- data/lib/mspec/helpers/const_lookup.rb +2 -1
- data/lib/mspec/helpers/flunk.rb +1 -1
- data/lib/mspec/helpers/io.rb +2 -2
- data/lib/mspec/helpers/ruby_exe.rb +6 -3
- data/lib/mspec/matchers/base.rb +14 -14
- data/lib/mspec/matchers/be_an_instance_of.rb +26 -0
- data/lib/mspec/mocks/mock.rb +5 -5
- data/lib/mspec/runner/context.rb +1 -1
- data/lib/mspec/runner/exception.rb +3 -3
- data/lib/mspec/runner/formatters/dotted.rb +2 -2
- data/lib/mspec/utils/name_map.rb +2 -1
- data/lib/mspec/utils/options.rb +3 -1
- data/lib/mspec/utils/script.rb +3 -2
- data/lib/mspec/version.rb +1 -1
- data/spec/commands/mkspec_spec.rb +2 -1
- data/spec/expectations/expectations_spec.rb +10 -10
- data/spec/expectations/should.rb +71 -0
- data/spec/expectations/should_spec.rb +58 -126
- data/spec/guards/endian_spec.rb +6 -6
- data/spec/helpers/flunk_spec.rb +3 -3
- data/spec/matchers/base_spec.rb +99 -90
- data/spec/matchers/be_an_instance_of_spec.rb +50 -0
- data/spec/matchers/be_close_spec.rb +2 -2
- data/spec/matchers/be_kind_of_spec.rb +5 -3
- data/spec/matchers/equal_utf16_spec.rb +12 -2
- data/spec/matchers/respond_to_spec.rb +5 -3
- data/spec/mocks/mock_spec.rb +22 -21
- data/spec/runner/actions/tally_spec.rb +2 -2
- data/spec/runner/actions/timer_spec.rb +4 -4
- data/spec/runner/context_spec.rb +4 -4
- data/spec/runner/exception_spec.rb +10 -10
- data/spec/runner/formatters/dotted_spec.rb +6 -6
- data/spec/runner/formatters/file_spec.rb +3 -3
- data/spec/runner/formatters/html_spec.rb +3 -3
- data/spec/runner/formatters/method_spec.rb +2 -2
- data/spec/runner/formatters/specdoc_spec.rb +5 -5
- data/spec/runner/formatters/summary_spec.rb +1 -1
- data/spec/utils/options_spec.rb +10 -9
- data/spec/utils/script_spec.rb +7 -6
- metadata +5 -2
data/Rakefile
CHANGED
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |s|
|
|
18
18
|
|
19
19
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
20
20
|
s.authors = ["Brian Ford"]
|
21
|
-
s.date = %q{2009-3-
|
21
|
+
s.date = %q{2009-3-30}
|
22
22
|
s.email = %q{bford@engineyard.com}
|
23
23
|
s.has_rdoc = true
|
24
24
|
s.extra_rdoc_files = %w[ README LICENSE ]
|
@@ -1,17 +1,17 @@
|
|
1
|
-
class
|
2
|
-
class
|
1
|
+
class SpecExpectationNotMetError < StandardError; end
|
2
|
+
class SpecExpectationNotFoundError < StandardError
|
3
3
|
def message
|
4
4
|
"No behavior expectation was found in the example"
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
-
class
|
8
|
+
class SpecExpectation
|
9
9
|
def self.fail_with(expected, actual)
|
10
10
|
if expected.to_s.size + actual.to_s.size > 80
|
11
11
|
message = expected.to_s.chomp + "\n" + actual.to_s
|
12
12
|
else
|
13
13
|
message = expected.to_s + " " + actual.to_s
|
14
14
|
end
|
15
|
-
Kernel.raise
|
15
|
+
Kernel.raise SpecExpectationNotMetError, message
|
16
16
|
end
|
17
17
|
end
|
@@ -4,10 +4,10 @@ class Object
|
|
4
4
|
MSpec.actions :expectation, MSpec.current.state
|
5
5
|
if matcher
|
6
6
|
unless matcher.matches?(self)
|
7
|
-
|
7
|
+
SpecExpectation.fail_with(*matcher.failure_message)
|
8
8
|
end
|
9
9
|
else
|
10
|
-
|
10
|
+
SpecPositiveOperatorMatcher.new(self)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -16,10 +16,10 @@ class Object
|
|
16
16
|
MSpec.actions :expectation, MSpec.current.state
|
17
17
|
if matcher
|
18
18
|
if matcher.matches?(self)
|
19
|
-
|
19
|
+
SpecExpectation.fail_with(*matcher.negative_failure_message)
|
20
20
|
end
|
21
21
|
else
|
22
|
-
|
22
|
+
SpecNegativeOperatorMatcher.new(self)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
data/lib/mspec/guards/endian.rb
CHANGED
@@ -3,23 +3,20 @@ require 'mspec/guards/guard'
|
|
3
3
|
# Despite that these are inverses, the two classes are
|
4
4
|
# used to simplify MSpec guard reporting modes
|
5
5
|
|
6
|
-
class
|
6
|
+
class EndianGuard < SpecGuard
|
7
7
|
def pattern
|
8
|
-
[1].pack('L')
|
8
|
+
@pattern ||= [1].pack('L')
|
9
9
|
end
|
10
10
|
private :pattern
|
11
|
+
end
|
11
12
|
|
13
|
+
class BigEndianGuard < EndianGuard
|
12
14
|
def match?
|
13
15
|
pattern[-1] == ?\001
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
class LittleEndianGuard <
|
18
|
-
def pattern
|
19
|
-
[1].pack('L')
|
20
|
-
end
|
21
|
-
private :pattern
|
22
|
-
|
19
|
+
class LittleEndianGuard < EndianGuard
|
23
20
|
def match?
|
24
21
|
pattern[-1] == ?\000
|
25
22
|
end
|
data/lib/mspec/guards/guard.rb
CHANGED
@@ -3,7 +3,8 @@ module Kernel
|
|
3
3
|
names = c.split '::'
|
4
4
|
names.shift if names.first.empty?
|
5
5
|
names.inject(Object) do |m, n|
|
6
|
-
|
6
|
+
defined = RUBY_VERSION =~ /^1.9/ ? m.const_defined?(n, false) : m.const_defined?(n)
|
7
|
+
defined ? m.const_get(n) : m.const_missing(n)
|
7
8
|
end
|
8
9
|
end
|
9
10
|
end
|
data/lib/mspec/helpers/flunk.rb
CHANGED
data/lib/mspec/helpers/io.rb
CHANGED
@@ -106,9 +106,12 @@ class Object
|
|
106
106
|
|
107
107
|
def ruby_exe(code, opts = {})
|
108
108
|
body = code
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
working_dir = opts[:dir] || "."
|
110
|
+
Dir.chdir(working_dir) do
|
111
|
+
body = "-e #{code.inspect}" if code and not File.exists?(code)
|
112
|
+
cmd = [RUBY_EXE, ENV['RUBY_FLAGS'], opts[:options], body, opts[:args]]
|
113
|
+
`#{cmd.compact.join(' ')}`
|
114
|
+
end
|
112
115
|
end
|
113
116
|
|
114
117
|
unless Object.const_defined?(:RUBY_EXE) and RUBY_EXE
|
data/lib/mspec/matchers/base.rb
CHANGED
@@ -1,94 +1,94 @@
|
|
1
|
-
class
|
1
|
+
class SpecPositiveOperatorMatcher
|
2
2
|
def initialize(actual)
|
3
3
|
@actual = actual
|
4
4
|
end
|
5
5
|
|
6
6
|
def ==(expected)
|
7
7
|
unless @actual == expected
|
8
|
-
|
8
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
9
9
|
"to equal #{expected.pretty_inspect}")
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def <(expected)
|
14
14
|
unless @actual < expected
|
15
|
-
|
15
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
16
16
|
"to be less than #{expected.pretty_inspect}")
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def <=(expected)
|
21
21
|
unless @actual <= expected
|
22
|
-
|
22
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
23
23
|
"to be less than or equal to #{expected.pretty_inspect}")
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
def >(expected)
|
28
28
|
unless @actual > expected
|
29
|
-
|
29
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
30
30
|
"to be greater than #{expected.pretty_inspect}")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
def >=(expected)
|
35
35
|
unless @actual >= expected
|
36
|
-
|
36
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
37
37
|
"to be greater than or equal to #{expected.pretty_inspect}")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def =~(expected)
|
42
42
|
unless @actual =~ expected
|
43
|
-
|
43
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
44
44
|
"to match #{expected.pretty_inspect}")
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
class
|
49
|
+
class SpecNegativeOperatorMatcher
|
50
50
|
def initialize(actual)
|
51
51
|
@actual = actual
|
52
52
|
end
|
53
53
|
|
54
54
|
def ==(expected)
|
55
55
|
if @actual == expected
|
56
|
-
|
56
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
57
57
|
"not to equal #{expected.pretty_inspect}")
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
def <(expected)
|
62
62
|
if @actual < expected
|
63
|
-
|
63
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
64
64
|
"not to be less than #{expected.pretty_inspect}")
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
def <=(expected)
|
69
69
|
if @actual <= expected
|
70
|
-
|
70
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
71
71
|
"not to be less than or equal to #{expected.pretty_inspect}")
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
75
|
def >(expected)
|
76
76
|
if @actual > expected
|
77
|
-
|
77
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
78
78
|
"not to be greater than #{expected.pretty_inspect}")
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
82
|
def >=(expected)
|
83
83
|
if @actual >= expected
|
84
|
-
|
84
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
85
85
|
"not to be greater than or equal to #{expected.pretty_inspect}")
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
def =~(expected)
|
90
90
|
if @actual =~ expected
|
91
|
-
|
91
|
+
SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
|
92
92
|
"not to match #{expected.pretty_inspect}")
|
93
93
|
end
|
94
94
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class BeAnInstanceOfMatcher
|
2
|
+
def initialize(expected)
|
3
|
+
@expected = expected
|
4
|
+
end
|
5
|
+
|
6
|
+
def matches?(actual)
|
7
|
+
@actual = actual
|
8
|
+
@actual.instance_of?(@expected)
|
9
|
+
end
|
10
|
+
|
11
|
+
def failure_message
|
12
|
+
["Expected #{@actual.inspect} (#{@actual.class})",
|
13
|
+
"to be an instance of #{@expected}"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def negative_failure_message
|
17
|
+
["Expected #{@actual.inspect} (#{@actual.class})",
|
18
|
+
"not to be an instance of #{@expected}"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Object
|
23
|
+
def be_an_instance_of(expected)
|
24
|
+
BeAnInstanceOfMatcher.new(expected)
|
25
|
+
end
|
26
|
+
end
|
data/lib/mspec/mocks/mock.rb
CHANGED
@@ -77,7 +77,7 @@ module Mock
|
|
77
77
|
false
|
78
78
|
end
|
79
79
|
unless pass
|
80
|
-
|
80
|
+
SpecExpectation.fail_with(
|
81
81
|
"Mock '#{name_or_inspect obj}' expected to receive '#{sym}' " \
|
82
82
|
"#{qualifier.to_s.sub('_', ' ')} #{count} times",
|
83
83
|
"but received it #{proxy.calls} times")
|
@@ -110,14 +110,14 @@ module Mock
|
|
110
110
|
if block.arity == -1 || block.arity == args_to_yield.size
|
111
111
|
block.call(*args_to_yield)
|
112
112
|
else
|
113
|
-
|
113
|
+
SpecExpectation.fail_with(
|
114
114
|
"Mock '#{name_or_inspect obj}' asked to yield " \
|
115
115
|
"|#{proxy.yielding.join(', ')}| on #{sym}\n",
|
116
116
|
"but a block with arity #{block.arity} was passed")
|
117
117
|
end
|
118
118
|
end
|
119
119
|
else
|
120
|
-
|
120
|
+
SpecExpectation.fail_with(
|
121
121
|
"Mock '#{name_or_inspect obj}' asked to yield " \
|
122
122
|
"|[#{proxy.yielding.join('], [')}]| on #{sym}\n",
|
123
123
|
"but no block was passed")
|
@@ -133,7 +133,7 @@ module Mock
|
|
133
133
|
if sym.to_sym == :respond_to?
|
134
134
|
return obj.__send__(replaced_name(obj, sym), compare)
|
135
135
|
else
|
136
|
-
|
136
|
+
SpecExpectation.fail_with("Mock '#{name_or_inspect obj}': method #{sym}\n",
|
137
137
|
"called with unexpected arguments (#{Array(compare).join(' ')})")
|
138
138
|
end
|
139
139
|
end
|
@@ -143,7 +143,7 @@ module Mock
|
|
143
143
|
symbols.uniq.each do |replaced, obj, sym|
|
144
144
|
meta = class << obj; self; end
|
145
145
|
|
146
|
-
if meta.instance_methods.include?(replaced.
|
146
|
+
if meta.instance_methods.map { |x| x.to_sym }.include?(replaced.to_sym)
|
147
147
|
meta.__send__ :alias_method, sym.to_sym, replaced
|
148
148
|
meta.__send__ :remove_method, replaced
|
149
149
|
else
|
data/lib/mspec/runner/context.rb
CHANGED
@@ -34,7 +34,7 @@ class ContextState
|
|
34
34
|
|
35
35
|
@mock_verify = lambda { Mock.verify_count }
|
36
36
|
@mock_cleanup = lambda { Mock.cleanup }
|
37
|
-
@expectation_missing = lambda { raise
|
37
|
+
@expectation_missing = lambda { raise SpecExpectationNotFoundError }
|
38
38
|
end
|
39
39
|
|
40
40
|
# Returns true if this is a shared +ContextState+. Essentially, when
|
@@ -18,14 +18,14 @@ class ExceptionState
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def failure?
|
21
|
-
[
|
21
|
+
[SpecExpectationNotMetError, SpecExpectationNotFoundError].any? { |e| @exception.is_a? e }
|
22
22
|
end
|
23
23
|
|
24
24
|
def message
|
25
25
|
if @exception.message.empty?
|
26
26
|
"<No message>"
|
27
|
-
elsif @exception.class ==
|
28
|
-
@exception.class ==
|
27
|
+
elsif @exception.class == SpecExpectationNotMetError ||
|
28
|
+
@exception.class == SpecExpectationNotFoundError
|
29
29
|
@exception.message
|
30
30
|
else
|
31
31
|
"#{@exception.class}: #{@exception.message}"
|
@@ -65,8 +65,8 @@ class DottedFormatter
|
|
65
65
|
# Callback for the MSpec :after event. Prints an indicator
|
66
66
|
# for the result of evaluating this example as follows:
|
67
67
|
# . = No failure or error
|
68
|
-
# F = An
|
69
|
-
# E = Any exception other than
|
68
|
+
# F = An SpecExpectationNotMetError was raised
|
69
|
+
# E = Any exception other than SpecExpectationNotMetError
|
70
70
|
def after(state = nil)
|
71
71
|
unless exception?
|
72
72
|
print "."
|
data/lib/mspec/utils/name_map.rb
CHANGED
@@ -96,11 +96,12 @@ class NameMap
|
|
96
96
|
next unless m and not @seen[m]
|
97
97
|
@seen[m] = true
|
98
98
|
|
99
|
-
ms = m.methods
|
99
|
+
ms = m.methods(false).map { |x| x.to_s }
|
100
100
|
hash["#{name}."] = ms.sort unless ms.empty?
|
101
101
|
|
102
102
|
ms = m.public_instance_methods(false) +
|
103
103
|
m.protected_instance_methods(false)
|
104
|
+
ms.map! { |x| x.to_s }
|
104
105
|
hash["#{name}#"] = ms.sort unless ms.empty?
|
105
106
|
|
106
107
|
map hash, m.constants, name
|
data/lib/mspec/utils/options.rb
CHANGED
@@ -102,8 +102,10 @@ class MSpecOptions
|
|
102
102
|
if option.arg?
|
103
103
|
arg = argv.shift if arg.nil?
|
104
104
|
raise ParseError, "No argument provided for #{opt}" unless arg
|
105
|
+
option.block[arg] if option.block
|
106
|
+
else
|
107
|
+
option.block[] if option.block
|
105
108
|
end
|
106
|
-
option.block[arg] if option.block
|
107
109
|
end
|
108
110
|
option
|
109
111
|
end
|
data/lib/mspec/utils/script.rb
CHANGED
@@ -171,9 +171,10 @@ class MSpecScript
|
|
171
171
|
|
172
172
|
patterns.each do |pattern|
|
173
173
|
expanded = File.expand_path(pattern)
|
174
|
-
return [
|
174
|
+
return [expanded] if File.file?(expanded)
|
175
175
|
|
176
|
-
specs = File.join
|
176
|
+
specs = File.join(pattern, "/**/*_spec.rb")
|
177
|
+
specs = File.expand_path(specs) rescue specs
|
177
178
|
return Dir[specs].sort if File.directory?(expanded)
|
178
179
|
end
|
179
180
|
|
data/lib/mspec/version.rb
CHANGED
@@ -297,7 +297,8 @@ describe MkSpec, "#run" do
|
|
297
297
|
end
|
298
298
|
|
299
299
|
it "calls #create_file for each method on each class/module in the map" do
|
300
|
-
@map.should_receive(:map).with({}, @script.config[:constants]
|
300
|
+
@map.should_receive(:map).with({}, @script.config[:constants]
|
301
|
+
).and_return({"MkSpec#" => ["run"]})
|
301
302
|
@script.should_receive(:create_file).with("spec/mkspec", "MkSpec", "run", "MkSpec#run")
|
302
303
|
@script.run
|
303
304
|
end
|
@@ -1,29 +1,29 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
require 'mspec/expectations/expectations'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe SpecExpectationNotMetError do
|
5
5
|
it "is a subclass of StandardError" do
|
6
|
-
|
6
|
+
SpecExpectationNotMetError.ancestors.should include(StandardError)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
describe
|
10
|
+
describe SpecExpectationNotFoundError do
|
11
11
|
it "is a subclass of StandardError" do
|
12
|
-
|
12
|
+
SpecExpectationNotFoundError.ancestors.should include(StandardError)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
describe
|
16
|
+
describe SpecExpectationNotFoundError, "#message" do
|
17
17
|
it "returns 'No behavior expectation was found in the example'" do
|
18
|
-
m =
|
18
|
+
m = SpecExpectationNotFoundError.new.message
|
19
19
|
m.should == "No behavior expectation was found in the example"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe
|
24
|
-
it "raises an
|
23
|
+
describe SpecExpectation, "#fail_with" do
|
24
|
+
it "raises an SpecExpectationNotMetError" do
|
25
25
|
lambda {
|
26
|
-
|
27
|
-
}.should raise_error(
|
26
|
+
SpecExpectation.fail_with "expected this", "to equal that"
|
27
|
+
}.should raise_error(SpecExpectationNotMetError, "expected this to equal that")
|
28
28
|
end
|
29
29
|
end
|