minispec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.pryrc +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +2140 -0
- data/Rakefile +11 -0
- data/bin/minispec +4 -0
- data/lib/minispec.rb +175 -0
- data/lib/minispec/api.rb +2 -0
- data/lib/minispec/api/class.rb +195 -0
- data/lib/minispec/api/class/after.rb +49 -0
- data/lib/minispec/api/class/around.rb +54 -0
- data/lib/minispec/api/class/before.rb +101 -0
- data/lib/minispec/api/class/helpers.rb +116 -0
- data/lib/minispec/api/class/let.rb +44 -0
- data/lib/minispec/api/class/tests.rb +33 -0
- data/lib/minispec/api/instance.rb +158 -0
- data/lib/minispec/api/instance/mocks/doubles.rb +36 -0
- data/lib/minispec/api/instance/mocks/mocks.rb +319 -0
- data/lib/minispec/api/instance/mocks/spies.rb +17 -0
- data/lib/minispec/api/instance/mocks/stubs.rb +105 -0
- data/lib/minispec/helpers.rb +1 -0
- data/lib/minispec/helpers/array.rb +56 -0
- data/lib/minispec/helpers/booleans.rb +108 -0
- data/lib/minispec/helpers/generic.rb +24 -0
- data/lib/minispec/helpers/mocks/expectations.rb +29 -0
- data/lib/minispec/helpers/mocks/spies.rb +36 -0
- data/lib/minispec/helpers/raise.rb +44 -0
- data/lib/minispec/helpers/throw.rb +29 -0
- data/lib/minispec/mocks.rb +11 -0
- data/lib/minispec/mocks/expectations.rb +77 -0
- data/lib/minispec/mocks/stubs.rb +178 -0
- data/lib/minispec/mocks/validations.rb +80 -0
- data/lib/minispec/mocks/validations/amount.rb +63 -0
- data/lib/minispec/mocks/validations/arguments.rb +161 -0
- data/lib/minispec/mocks/validations/caller.rb +43 -0
- data/lib/minispec/mocks/validations/order.rb +47 -0
- data/lib/minispec/mocks/validations/raise.rb +111 -0
- data/lib/minispec/mocks/validations/return.rb +74 -0
- data/lib/minispec/mocks/validations/throw.rb +91 -0
- data/lib/minispec/mocks/validations/yield.rb +141 -0
- data/lib/minispec/proxy.rb +201 -0
- data/lib/minispec/reporter.rb +185 -0
- data/lib/minispec/utils.rb +139 -0
- data/lib/minispec/utils/differ.rb +325 -0
- data/lib/minispec/utils/pretty_print.rb +51 -0
- data/lib/minispec/utils/raise.rb +123 -0
- data/lib/minispec/utils/throw.rb +140 -0
- data/minispec.gemspec +27 -0
- data/test/mocks/expectations/amount.rb +67 -0
- data/test/mocks/expectations/arguments.rb +126 -0
- data/test/mocks/expectations/caller.rb +55 -0
- data/test/mocks/expectations/generic.rb +35 -0
- data/test/mocks/expectations/order.rb +46 -0
- data/test/mocks/expectations/raise.rb +166 -0
- data/test/mocks/expectations/return.rb +71 -0
- data/test/mocks/expectations/throw.rb +113 -0
- data/test/mocks/expectations/yield.rb +109 -0
- data/test/mocks/spies/amount.rb +68 -0
- data/test/mocks/spies/arguments.rb +57 -0
- data/test/mocks/spies/generic.rb +61 -0
- data/test/mocks/spies/order.rb +38 -0
- data/test/mocks/spies/raise.rb +158 -0
- data/test/mocks/spies/return.rb +71 -0
- data/test/mocks/spies/throw.rb +113 -0
- data/test/mocks/spies/yield.rb +101 -0
- data/test/mocks/test__doubles.rb +98 -0
- data/test/mocks/test__expectations.rb +27 -0
- data/test/mocks/test__mocks.rb +197 -0
- data/test/mocks/test__proxies.rb +61 -0
- data/test/mocks/test__spies.rb +43 -0
- data/test/mocks/test__stubs.rb +427 -0
- data/test/proxified_asserts.rb +34 -0
- data/test/setup.rb +53 -0
- data/test/test__around.rb +58 -0
- data/test/test__assert.rb +510 -0
- data/test/test__before_and_after.rb +117 -0
- data/test/test__before_and_after_all.rb +71 -0
- data/test/test__helpers.rb +197 -0
- data/test/test__raise.rb +104 -0
- data/test/test__skip.rb +41 -0
- data/test/test__throw.rb +103 -0
- metadata +196 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
# Borrowed and adapted from Pry - https://github.com/pry/pry
|
2
|
+
|
3
|
+
# Copyright (c) 2013 John Mair (banisterfiend)
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# 'Software'), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
module MiniSpec
|
25
|
+
module Utils
|
26
|
+
def pp obj
|
27
|
+
out = ''
|
28
|
+
q = MiniSpec::PrettyPrint.new(out)
|
29
|
+
q.guard_inspect_key { q.pp(obj) }
|
30
|
+
q.flush
|
31
|
+
out
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class PrettyPrint < ::PP
|
36
|
+
def text str, width = str.length
|
37
|
+
if str.include?("\e[")
|
38
|
+
super "%s\e[0m" % str, width
|
39
|
+
elsif str.start_with?('#<') || str == '=' || str == '>'
|
40
|
+
super highlight_object_literal(str), width
|
41
|
+
else
|
42
|
+
super CodeRay.scan(str, :ruby).term, width
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def highlight_object_literal object_literal
|
48
|
+
"\e[32m%s\e[0m" % object_literal
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module MiniSpec
|
2
|
+
|
3
|
+
# used when some block does not raise as expected
|
4
|
+
class ExceptionError < StandardError; end
|
5
|
+
|
6
|
+
module Utils
|
7
|
+
|
8
|
+
# checks whether given object is a exception of given class(if any),
|
9
|
+
# and/or match given String/Regexp(if any)
|
10
|
+
#
|
11
|
+
# if no args given any raised exception accepted.
|
12
|
+
# if a class given it checks whether raised exception is of given type.
|
13
|
+
# if a string or regexp given it checks whether raised message matches it.
|
14
|
+
#
|
15
|
+
# @param subject potentially a Exception instance
|
16
|
+
# @param [Hash] context
|
17
|
+
# @param [Array] *args actual expectations. can be a Class, String or Regexp
|
18
|
+
# @return [ExceptionError] if not raised as expected
|
19
|
+
# [true] if raised an exception that meets expectations
|
20
|
+
#
|
21
|
+
def exception_raised? subject, context, *args
|
22
|
+
if context[:right_proc]
|
23
|
+
args.any? && raise(ArgumentError, 'Both arguments and block given. Please use either one.')
|
24
|
+
return MiniSpec::ExceptionInspector.raised_as_expected_by_proc?(subject, context)
|
25
|
+
end
|
26
|
+
|
27
|
+
type, match = nil
|
28
|
+
args.each { |a| a.is_a?(Class) ? type = a : match = a }
|
29
|
+
regexp = match.is_a?(Regexp) ? match : /^#{Regexp.escape(match.to_s)}\z/
|
30
|
+
|
31
|
+
context = {negation: context[:negation]} # it is critical to not alter received context
|
32
|
+
if context[:is_a_exception] = subject.is_a?(Exception)
|
33
|
+
context[:valid_exception_type] = type ? (subject.class == type) : nil
|
34
|
+
context[:valid_exception_message] = match ? (subject.to_s =~ regexp) : nil
|
35
|
+
end
|
36
|
+
|
37
|
+
MiniSpec::ExceptionInspector.raised_as_expected?(subject, type, match, context)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module ExceptionInspector
|
42
|
+
extend MiniSpec::Utils
|
43
|
+
extend self
|
44
|
+
|
45
|
+
def raised_as_expected_by_proc? subject, context
|
46
|
+
x = context[:right_proc].call(*subject) # splat needed on multiple expectations
|
47
|
+
if context[:negation]
|
48
|
+
# return true if block returns false or nil
|
49
|
+
return true if !x
|
50
|
+
return ExceptionError.new('Not expected any error to be raised')
|
51
|
+
end
|
52
|
+
# return true if block returns a positive value
|
53
|
+
return true if x
|
54
|
+
ExceptionError.new('Expected some error to be raised')
|
55
|
+
end
|
56
|
+
|
57
|
+
def raised_as_expected? subject, type, match, context
|
58
|
+
if type && match
|
59
|
+
x = validate_type(subject, type, context)
|
60
|
+
return x if x.is_a?(ExceptionError)
|
61
|
+
validate_message(subject, match, context)
|
62
|
+
elsif type
|
63
|
+
validate_type(subject, type, context)
|
64
|
+
elsif match
|
65
|
+
validate_message(subject, match, context)
|
66
|
+
else
|
67
|
+
validate(context)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate context
|
72
|
+
x = context[:is_a_exception]
|
73
|
+
if context[:negation]
|
74
|
+
# return true if no exception raised
|
75
|
+
return true if !x
|
76
|
+
# return ExceptionError cause a exception raised but not expected
|
77
|
+
return ExceptionError.new('Not expected a error to be raised')
|
78
|
+
end
|
79
|
+
# return true if some exception raised
|
80
|
+
return true if x
|
81
|
+
# return ExceptionError cause no exception raised
|
82
|
+
ExceptionError.new('Expected some error to be raised')
|
83
|
+
end
|
84
|
+
|
85
|
+
def validate_type subject, type, context
|
86
|
+
x = context[:valid_exception_type]
|
87
|
+
if context[:negation]
|
88
|
+
# return true if raised exception is not of expected type OR no exception raised et all
|
89
|
+
return true if !x
|
90
|
+
# return ExceptionError cause exception should NOT be of given type
|
91
|
+
return ExceptionError.new("Not expected a %s error to be raised." % pp(type))
|
92
|
+
end
|
93
|
+
# return true if raised exception is of expected type
|
94
|
+
return true if x
|
95
|
+
# return ExceptionError cause raised exception is NOT of given type OR no exception raised et all
|
96
|
+
ExceptionError.new("Expected a %s error to be raised.\nInstead %s" % [
|
97
|
+
pp(type),
|
98
|
+
context[:is_a_exception] ?
|
99
|
+
'a %s error raised' % pp(subject.class) :
|
100
|
+
'nothing raised'
|
101
|
+
])
|
102
|
+
end
|
103
|
+
|
104
|
+
def validate_message subject, match, context
|
105
|
+
x = context[:valid_exception_message]
|
106
|
+
if context[:negation]
|
107
|
+
# return true if exception message does not match expected value OR no exception raised et all
|
108
|
+
return true if !x
|
109
|
+
# return ExceptionError cause exception message should NOT match given value
|
110
|
+
return ExceptionError.new('Not expected raised error to match %s' % pp(match))
|
111
|
+
end
|
112
|
+
# return true if exception message matched expected value
|
113
|
+
return true if x
|
114
|
+
# return ExceptionError cause exception message does NOT match given value OR no exception raised et all
|
115
|
+
ExceptionError.new("Expected a error that match %s to be raised.\nInstead %s." % [
|
116
|
+
pp(match),
|
117
|
+
context[:is_a_exception] ?
|
118
|
+
'a error with following message raised: %s' % pp(subject) :
|
119
|
+
'nothing raised'
|
120
|
+
])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module MiniSpec
|
2
|
+
|
3
|
+
class ThrowError < StandardError; end
|
4
|
+
|
5
|
+
module Utils
|
6
|
+
|
7
|
+
# checks whether given block throws a symbol
|
8
|
+
# and if yes compare it with expected one.
|
9
|
+
# if a optional value given it will be compared to thrown one.
|
10
|
+
#
|
11
|
+
# @param expected_symbol
|
12
|
+
# @param expected_value
|
13
|
+
# @param [Proc] &proc
|
14
|
+
# @return a failure [ThrowError] if expectation not met.
|
15
|
+
# true if expectations met.
|
16
|
+
#
|
17
|
+
def symbol_thrown? expected_symbol, expected_value, context, &block
|
18
|
+
thrown_symbol, thrown_value = catch_symbol(expected_symbol, &block)
|
19
|
+
|
20
|
+
if context[:right_proc]
|
21
|
+
expected_symbol && raise(ArgumentError, 'Both arguments and block given. Please use either one.')
|
22
|
+
return MiniSpec::ThrowInspector.thrown_as_expected_by_proc?(thrown_symbol, context)
|
23
|
+
end
|
24
|
+
|
25
|
+
MiniSpec::ThrowInspector.thrown_as_expected?(expected_symbol, expected_value, thrown_symbol, thrown_value, context)
|
26
|
+
end
|
27
|
+
|
28
|
+
# calling given block and catching thrown symbol, if any.
|
29
|
+
#
|
30
|
+
# @param expected_symbol
|
31
|
+
# @param [Proc] &block
|
32
|
+
#
|
33
|
+
def catch_symbol expected_symbol, &block
|
34
|
+
thrown_symbol, thrown_value = nil
|
35
|
+
begin
|
36
|
+
if expected_symbol
|
37
|
+
thrown_value = catch :__ms__nothing_thrown do
|
38
|
+
catch expected_symbol do
|
39
|
+
block.call
|
40
|
+
throw :__ms__nothing_thrown, :__ms__nothing_thrown
|
41
|
+
end
|
42
|
+
end
|
43
|
+
thrown_symbol = expected_symbol unless thrown_value == :__ms__nothing_thrown
|
44
|
+
else
|
45
|
+
block.call
|
46
|
+
end
|
47
|
+
rescue => e
|
48
|
+
raise(e) unless thrown_symbol = extract_thrown_symbol(e)
|
49
|
+
end
|
50
|
+
[thrown_symbol, thrown_value]
|
51
|
+
end
|
52
|
+
|
53
|
+
# extract thrown symbol from given exception
|
54
|
+
#
|
55
|
+
# @param exception
|
56
|
+
#
|
57
|
+
def extract_thrown_symbol exception
|
58
|
+
return unless exception.is_a?(Exception)
|
59
|
+
return unless s = exception.message.scan(/uncaught throw\W+(\w+)/).flatten[0]
|
60
|
+
s.to_sym
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module ThrowInspector
|
65
|
+
extend MiniSpec::Utils
|
66
|
+
extend self
|
67
|
+
|
68
|
+
def thrown_as_expected_by_proc? thrown_symbol, context
|
69
|
+
x = context[:right_proc].call(*thrown_symbol) # splat needed on multiple expectations
|
70
|
+
if context[:negation]
|
71
|
+
return true if !x
|
72
|
+
return ThrowError.new('Not expected any symbol to be thrown')
|
73
|
+
end
|
74
|
+
return true if x
|
75
|
+
ThrowError.new('Expected a symbol to be thrown')
|
76
|
+
end
|
77
|
+
|
78
|
+
def thrown_as_expected? expected_symbol, expected_value, thrown_symbol, thrown_value, context
|
79
|
+
if expected_symbol && expected_value
|
80
|
+
x = correct_symbol_thrown?(expected_symbol, thrown_symbol, context)
|
81
|
+
return x if x.is_a?(ThrowError)
|
82
|
+
correct_value_thrown?(expected_symbol, expected_value, thrown_value, context)
|
83
|
+
elsif expected_symbol
|
84
|
+
correct_symbol_thrown?(expected_symbol, thrown_symbol, context)
|
85
|
+
else
|
86
|
+
any_symbol_thrown?(thrown_symbol, context)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def any_symbol_thrown? thrown_symbol, context
|
91
|
+
if context[:negation]
|
92
|
+
return true if !thrown_symbol
|
93
|
+
return ThrowError.new('%s symbol thrown when not expected' % pp(thrown_symbol))
|
94
|
+
end
|
95
|
+
return true if thrown_symbol
|
96
|
+
ThrowError.new('Expected a symbol to be thrown')
|
97
|
+
end
|
98
|
+
|
99
|
+
def correct_symbol_thrown? expected_symbol, thrown_symbol, context
|
100
|
+
# needed here cause this method are invoked directly by mock validators.
|
101
|
+
# and it's not a double check cause Utils.symbol_thrown?
|
102
|
+
# wont arrive here if called with a block
|
103
|
+
if context[:right_proc]
|
104
|
+
return thrown_as_expected_by_proc?(thrown_symbol, context)
|
105
|
+
end
|
106
|
+
|
107
|
+
x = expected_symbol == thrown_symbol
|
108
|
+
if context[:negation]
|
109
|
+
return true if !x
|
110
|
+
return ThrowError.new('Not expected %s symbol to be thrown' % pp(thrown_symbol))
|
111
|
+
end
|
112
|
+
return true if x
|
113
|
+
ThrowError.new('Expected %s symbol to be thrown. Instead %s thrown.' % [
|
114
|
+
pp(expected_symbol),
|
115
|
+
thrown_symbol ?
|
116
|
+
pp(thrown_symbol) :
|
117
|
+
'nothing'
|
118
|
+
])
|
119
|
+
end
|
120
|
+
|
121
|
+
def correct_value_thrown? thrown_symbol, expected_value, thrown_value, context
|
122
|
+
x = expected_value.is_a?(Regexp) ?
|
123
|
+
(thrown_value.to_s =~ expected_value) :
|
124
|
+
(thrown_value == expected_value)
|
125
|
+
if context[:negation]
|
126
|
+
return true if !x
|
127
|
+
return ThrowError.new('Not expected %s symbol\'s value to match %s' % [
|
128
|
+
thrown_symbol,
|
129
|
+
thrown_value,
|
130
|
+
].map(&method(:pp)))
|
131
|
+
end
|
132
|
+
return true if x
|
133
|
+
ThrowError.new("Expected %s symbol's value to match %s\nActual value: %s" % [
|
134
|
+
thrown_symbol,
|
135
|
+
expected_value,
|
136
|
+
thrown_value
|
137
|
+
].map(&method(:pp)))
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/minispec.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
name, version = 'minispec 0.0.1'.split
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = name
|
6
|
+
spec.version = version
|
7
|
+
spec.authors = ['Slee Woo']
|
8
|
+
spec.email = ['mail@sleewoo.com']
|
9
|
+
spec.description = 'Simple, Intuitive, Full-featured Testing Framework'
|
10
|
+
spec.summary = [name, version]*'-'
|
11
|
+
spec.homepage = 'https://github.com/sleewoo/' + name
|
12
|
+
spec.license = 'MIT'
|
13
|
+
|
14
|
+
spec.files = Dir['**/{*,.[a-z]*}'].reject {|e| e =~ /\.(gem|lock)\Z/}
|
15
|
+
spec.require_paths = ['lib']
|
16
|
+
|
17
|
+
spec.executables = Dir['bin/*'].map{|f| File.basename(f)}
|
18
|
+
|
19
|
+
spec.required_ruby_version = '>= 1.9.2'
|
20
|
+
|
21
|
+
spec.add_dependency 'diff-lcs', '~> 1.2'
|
22
|
+
spec.add_dependency 'coderay', '~> 1.1'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'minitest'
|
25
|
+
spec.add_development_dependency 'bundler'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class MinispecTest::Expectations::Unit
|
2
|
+
|
3
|
+
should 'pass when received expected amount' do
|
4
|
+
expect(o).to_receive(:a).count(2)
|
5
|
+
o.a
|
6
|
+
o.a
|
7
|
+
end
|
8
|
+
|
9
|
+
should ':fail when received wrong amount of times' do
|
10
|
+
expect(o).to_receive(:a).count(2)
|
11
|
+
o.a
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'pass when proc validates received amount' do
|
15
|
+
expect(o).to_receive(:a).count {|r| r == 2}
|
16
|
+
o.a
|
17
|
+
o.a
|
18
|
+
end
|
19
|
+
|
20
|
+
should ':fail when proc does not validate received amount' do
|
21
|
+
expect(o).to_receive(:a).count { false }
|
22
|
+
o.a
|
23
|
+
end
|
24
|
+
|
25
|
+
should 'pass when multiple messages uses one expectation' do
|
26
|
+
expect(o).to_receive(:a, :b).count(2)
|
27
|
+
o.a
|
28
|
+
o.b
|
29
|
+
o.b
|
30
|
+
o.a
|
31
|
+
end
|
32
|
+
|
33
|
+
should ':fail when received multiple messages amount are wrong' do
|
34
|
+
expect(o).to_receive(:a, :b).count(2)
|
35
|
+
o.a
|
36
|
+
o.b
|
37
|
+
o.b
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'pass when each of multiple messages uses its own expectation' do
|
41
|
+
expect(o).to_receive(:a, :b).count(1, 2)
|
42
|
+
o.a
|
43
|
+
o.b
|
44
|
+
o.b
|
45
|
+
end
|
46
|
+
|
47
|
+
should ':fail when at least one message does not match its expectation' do
|
48
|
+
expect(o).to_receive(:a, :b).count(1, 1)
|
49
|
+
o.a
|
50
|
+
o.b
|
51
|
+
o.b
|
52
|
+
end
|
53
|
+
|
54
|
+
should 'pass when proc validates received multiple messages amount' do
|
55
|
+
expect(o).to_receive(:a, :b).count {|a, b| a == 2 && b == 2}
|
56
|
+
o.a
|
57
|
+
o.b
|
58
|
+
o.b
|
59
|
+
o.a
|
60
|
+
end
|
61
|
+
|
62
|
+
should ':fail when proc does not validate received multiple messages amount' do
|
63
|
+
expect(o).to_receive(:a, :b).count { false }
|
64
|
+
o.a
|
65
|
+
o.b
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
class MinispecTest::Expectations::Unit
|
2
|
+
|
3
|
+
should 'pass when expected arguments matches given ones' do
|
4
|
+
expect(o).to_receive(:a).with(1, 2)
|
5
|
+
o.a(1, 2)
|
6
|
+
o.a(4, 5)
|
7
|
+
end
|
8
|
+
|
9
|
+
should ':fail when wrong arguments given' do
|
10
|
+
expect(o).to_receive(:a).with(4, 5)
|
11
|
+
o.a(1, 2)
|
12
|
+
o.a(:a, 'b', [:z])
|
13
|
+
o.a([:x], {y: :z})
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'pass when proc validates arguments' do
|
17
|
+
expect(o).to_receive(:a).with {|x| x[0] == [1] && x[1] == [:b]}
|
18
|
+
o.a(1)
|
19
|
+
o.a(:b)
|
20
|
+
expect(o).to_receive(:b).with {|x| x[0] == [:x, [:y]] && x[1] == [9]}
|
21
|
+
o.b(:x, [:y])
|
22
|
+
o.b(9)
|
23
|
+
expect(o).to_receive(:c).with {|x| x[0] == [ [1], {2 => 3} ]}
|
24
|
+
o.c([1], {2 => 3})
|
25
|
+
end
|
26
|
+
|
27
|
+
should ':fail when proc does not validate arguments' do
|
28
|
+
expect(o).to_receive(:a).with {false}
|
29
|
+
o.a(1)
|
30
|
+
o.a(:x)
|
31
|
+
o.a({a: :b}, [:x, [:y]])
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'pass when no arguments expected and no arguments given' do
|
35
|
+
expect(o).to_receive(:a).without_arguments
|
36
|
+
o.a
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'pass when no arguments expected and message called at least once without arguments' do
|
40
|
+
expect(o).to_receive(:a).without_arguments
|
41
|
+
o.a(:x)
|
42
|
+
o.a(:y)
|
43
|
+
o.a
|
44
|
+
end
|
45
|
+
|
46
|
+
should ':fail when no arguments expected and message never called without arguments' do
|
47
|
+
expect(o).to_receive(:a).without_arguments
|
48
|
+
o.a(:x)
|
49
|
+
o.a(:y)
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'pass when given multiple arguments matching expected ones' do
|
53
|
+
expect(o).to_receive(:a, :b, :c).with(1, 2, 3)
|
54
|
+
o.a 1
|
55
|
+
o.b 2
|
56
|
+
o.c 3
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'plays well with Array arguments' do
|
60
|
+
expect(o).to_receive(:a, :b, :c).with([1], [4, 5, [6]], :c)
|
61
|
+
o.a [1]
|
62
|
+
o.a ['1']
|
63
|
+
o.b [4, 5, [6]]
|
64
|
+
o.b ['a', 'b', :c]
|
65
|
+
o.c :c
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'pass when proc validates passed arguments' do
|
69
|
+
expect(o).to_receive(:a, :b, :c).with do |a, b, c|
|
70
|
+
a[0] == [1] &&
|
71
|
+
a[1] == [:z] &&
|
72
|
+
b[0] == [[1], [2, 3]] &&
|
73
|
+
b[1] == [:x] &&
|
74
|
+
c[0] == [3, [:x], {y: :z}] &&
|
75
|
+
c[1] == [:o]
|
76
|
+
end
|
77
|
+
o.a 1
|
78
|
+
o.a :z
|
79
|
+
o.b [1], [2, 3]
|
80
|
+
o.b :x
|
81
|
+
o.c 3, [:x], {y: :z}
|
82
|
+
o.c :o
|
83
|
+
end
|
84
|
+
|
85
|
+
should ':fail when at least one argument does not meet expectations' do
|
86
|
+
expect(o).to_receive(:a, :b, :c).with(1, 2, [:x, "y", [:z]])
|
87
|
+
o.a 1
|
88
|
+
o.b [2]
|
89
|
+
o.c 3
|
90
|
+
o.c :x
|
91
|
+
o.c [:x, :y, {z: 'z'}]
|
92
|
+
end
|
93
|
+
|
94
|
+
should ':fail when proc does not validate passed arguments' do
|
95
|
+
expect(o).to_receive(:a, :b, :c).with { false }
|
96
|
+
o.a 1
|
97
|
+
o.a [1, 2]
|
98
|
+
o.b 2
|
99
|
+
o.b :x, [:y]
|
100
|
+
o.c ['3']
|
101
|
+
end
|
102
|
+
|
103
|
+
should 'pass when no arguments expected and all messages called without arguments' do
|
104
|
+
expect(o).to_receive(:a, :b, :c).without_arguments
|
105
|
+
o.a
|
106
|
+
o.b
|
107
|
+
o.c
|
108
|
+
end
|
109
|
+
|
110
|
+
should 'pass when no arguments expected and each message called at least once without arguments' do
|
111
|
+
expect(o).to_receive(:a, :b, :c).without_arguments
|
112
|
+
o.a
|
113
|
+
o.a(:x)
|
114
|
+
o.b
|
115
|
+
o.b(:y)
|
116
|
+
o.c
|
117
|
+
o.c(:z)
|
118
|
+
end
|
119
|
+
|
120
|
+
should ':fail when no arguments expected and at least one message never called without arguments' do
|
121
|
+
expect(o).to_receive(:a, :b, :c).without_arguments
|
122
|
+
o.a
|
123
|
+
o.b
|
124
|
+
o.c(:x)
|
125
|
+
end
|
126
|
+
end
|