mspec 1.5.10 → 1.5.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|