tokyo 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +335 -0
- data/Rakefile +11 -0
- data/bin/tokyo +4 -0
- data/lib/tokyo/assert.rb +148 -0
- data/lib/tokyo/core_ext.rb +103 -0
- data/lib/tokyo/expectations/raise.rb +32 -0
- data/lib/tokyo/expectations/return.rb +32 -0
- data/lib/tokyo/expectations/throw.rb +24 -0
- data/lib/tokyo/expectations/with.rb +36 -0
- data/lib/tokyo/expectations.rb +103 -0
- data/lib/tokyo/pretty_print.rb +55 -0
- data/lib/tokyo/run.rb +126 -0
- data/lib/tokyo/unit.rb +185 -0
- data/lib/tokyo/util/assert_raise.rb +54 -0
- data/lib/tokyo/util/assert_throw.rb +40 -0
- data/lib/tokyo/util/refute_raise.rb +48 -0
- data/lib/tokyo/util/refute_throw.rb +34 -0
- data/lib/tokyo/util.rb +91 -0
- data/lib/tokyo.rb +121 -0
- data/test/assert_test.rb +98 -0
- data/test/context_inheritance_test.rb +52 -0
- data/test/hooks_test.rb +35 -0
- data/test/raise_test.rb +66 -0
- data/test/receive_and_raise_test.rb +83 -0
- data/test/receive_and_return_test.rb +46 -0
- data/test/receive_and_throw_test.rb +74 -0
- data/test/receive_test.rb +71 -0
- data/test/receive_with_test.rb +57 -0
- data/test/refute_raise_test.rb +90 -0
- data/test/refute_throw_test.rb +42 -0
- data/test/setup.rb +25 -0
- data/test/skip_test.rb +35 -0
- data/test/throw_test.rb +58 -0
- data/tokyo.gemspec +27 -0
- metadata +195 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module Tokyo
|
2
|
+
|
3
|
+
def refute_thrown_as_expected object, expected_symbol, block = nil
|
4
|
+
f = refute_thrown(object, expected_symbol)
|
5
|
+
return f if f
|
6
|
+
|
7
|
+
if expected_symbol
|
8
|
+
f = refute_expected_symbol_thrown(object, expected_symbol)
|
9
|
+
return f if f
|
10
|
+
end
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def refute_thrown object, should_throw = false
|
15
|
+
if should_throw
|
16
|
+
return [
|
17
|
+
'Expected a symbol to be thrown at %s' % object[:caller]
|
18
|
+
] unless object[:thrown]
|
19
|
+
else
|
20
|
+
return [
|
21
|
+
'Not expected a symbol to be thrown at %s' % object[:caller]
|
22
|
+
] if object[:thrown]
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def refute_expected_symbol_thrown object, expected_symbol
|
28
|
+
return [
|
29
|
+
'Not expected :%s to be thrown' % expected_symbol,
|
30
|
+
'at %s' % object[:caller]
|
31
|
+
] if expected_symbol == object[:thrown]
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
data/lib/tokyo/util.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module Tokyo
|
2
|
+
|
3
|
+
def call_block block
|
4
|
+
{returned: block.call, caller: relative_source_location(block)}.freeze
|
5
|
+
rescue UncaughtThrowError => e
|
6
|
+
{raised: e, thrown: extract_thrown_symbol(e), caller: relative_source_location(block)}.freeze
|
7
|
+
rescue Exception => e
|
8
|
+
{raised: e, caller: relative_source_location(block)}.freeze
|
9
|
+
end
|
10
|
+
|
11
|
+
# extract thrown symbol from given exception
|
12
|
+
#
|
13
|
+
# @param exception
|
14
|
+
#
|
15
|
+
def extract_thrown_symbol exception
|
16
|
+
return unless exception.is_a?(Exception)
|
17
|
+
return unless s = exception.message.scan(/uncaught throw\W+(\w+)/).flatten[0]
|
18
|
+
s.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def identity_string type, label, block
|
22
|
+
'%s %s (%s:%s)' % [
|
23
|
+
blue(type),
|
24
|
+
label.inspect,
|
25
|
+
*relative_source_location(block)
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
def relative_source_location block
|
30
|
+
return unless block
|
31
|
+
[
|
32
|
+
relative_location(block.source_location[0]),
|
33
|
+
block.source_location[1]
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
def relative_location line
|
38
|
+
line.sub(/\A#{pwd}\/+/, '')
|
39
|
+
end
|
40
|
+
|
41
|
+
def pretty_backtrace e
|
42
|
+
Array(e.backtrace).map {|l| relative_location(l)}
|
43
|
+
end
|
44
|
+
|
45
|
+
def readline caller
|
46
|
+
file, line = caller_to_source_location(caller)
|
47
|
+
return unless file && line
|
48
|
+
lines = ((@__readlinecache__ ||= {})[file] ||= File.readlines(file))
|
49
|
+
return unless line = lines[line.to_i - 1]
|
50
|
+
line.sub(/(do|\{)\Z/, '').strip
|
51
|
+
end
|
52
|
+
|
53
|
+
def caller_to_source_location caller
|
54
|
+
file, line = caller.split(/:(\d+):in.+/)
|
55
|
+
[relative_location(file), line]
|
56
|
+
end
|
57
|
+
|
58
|
+
def find_files pattern_or_files
|
59
|
+
return pattern_or_files if pattern_or_files.is_a?(Array)
|
60
|
+
Dir[pwd(pattern_or_files)]
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_file file
|
64
|
+
augment_load_path(file)
|
65
|
+
require(file)
|
66
|
+
end
|
67
|
+
|
68
|
+
def augment_load_path file
|
69
|
+
# adding ./
|
70
|
+
$:.unshift(pwd) unless $:.include?(pwd)
|
71
|
+
|
72
|
+
# adding ./lib/
|
73
|
+
lib = pwd('lib')
|
74
|
+
unless $:.include?(lib)
|
75
|
+
$:.unshift(lib) if File.directory?(lib)
|
76
|
+
end
|
77
|
+
|
78
|
+
# adding file's dirname
|
79
|
+
dir = File.dirname(file)
|
80
|
+
$:.unshift(dir) unless $:.include?(dir)
|
81
|
+
end
|
82
|
+
|
83
|
+
def pwd *args
|
84
|
+
File.join(Dir.pwd, *args.map!(&:to_s))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
require 'tokyo/util/assert_raise'
|
89
|
+
require 'tokyo/util/refute_raise'
|
90
|
+
require 'tokyo/util/assert_throw'
|
91
|
+
require 'tokyo/util/refute_throw'
|
data/lib/tokyo.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'tty-progressbar'
|
2
|
+
require 'tty-screen'
|
3
|
+
require 'pastel'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Tokyo
|
7
|
+
extend self
|
8
|
+
|
9
|
+
DEFAULT_PATTERN = '{spec,test}/**/{*_spec.rb,*_test.rb}'.freeze
|
10
|
+
GLOBAL_SETUPS = []
|
11
|
+
|
12
|
+
GenericFailure = Struct.new(:reason, :caller)
|
13
|
+
AssertionFailure = Struct.new(:object, :arguments, :caller)
|
14
|
+
|
15
|
+
Skip = Struct.new(:reason, :caller)
|
16
|
+
|
17
|
+
INDENT = ' '.freeze
|
18
|
+
PASTEL = Pastel.new
|
19
|
+
%w[
|
20
|
+
red
|
21
|
+
bright_red
|
22
|
+
green
|
23
|
+
blue
|
24
|
+
cyan
|
25
|
+
magenta
|
26
|
+
bold
|
27
|
+
underline
|
28
|
+
].each {|m| define_method(m) {|*a| PASTEL.__send__(m, *a)}}
|
29
|
+
|
30
|
+
def units
|
31
|
+
@units ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
def assertions
|
35
|
+
@assertions ||= {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def total_assertions
|
39
|
+
@total_assertions ||= []
|
40
|
+
end
|
41
|
+
|
42
|
+
def skips
|
43
|
+
@skips ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def define_spec label, block
|
47
|
+
define_unit_class(:spec, label, block, [].freeze)
|
48
|
+
end
|
49
|
+
|
50
|
+
def define_and_register_a_spec label, block
|
51
|
+
units << define_spec(label, block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def define_context label, block, parent
|
55
|
+
define_unit_class(:context, label, block, [*parent.__ancestors__, parent].freeze)
|
56
|
+
end
|
57
|
+
|
58
|
+
def define_and_register_a_context label, block, parent
|
59
|
+
units << define_context(label, block, parent)
|
60
|
+
end
|
61
|
+
|
62
|
+
# define a class that will hold contexts and tests
|
63
|
+
#
|
64
|
+
# @param [String, Symbol] type
|
65
|
+
# @param [String, Symbol] label
|
66
|
+
# @param [Proc] block
|
67
|
+
# @param [Array] ancestors
|
68
|
+
# @return [Unit]
|
69
|
+
#
|
70
|
+
def define_unit_class type, label, block, ancestors
|
71
|
+
identity = identity_string(type, label, block).freeze
|
72
|
+
Class.new ancestors.last || Unit do
|
73
|
+
define_singleton_method(:__ancestors__) {ancestors}
|
74
|
+
define_singleton_method(:__identity__) {identity}
|
75
|
+
Tokyo::GLOBAL_SETUPS.each {|b| class_exec(&b)}
|
76
|
+
# execute given block only after global setups executed and all utility methods defined
|
77
|
+
result = catch(:__tokyo_skip__) {class_exec(&block)}
|
78
|
+
Tokyo.skips << result if result.is_a?(Skip)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# define a module that when included will execute the given block on base
|
83
|
+
#
|
84
|
+
# @param [Proc] block
|
85
|
+
# @return [Module]
|
86
|
+
#
|
87
|
+
def define_unit_module block
|
88
|
+
block || raise(ArgumentError, 'missing block')
|
89
|
+
Module.new do
|
90
|
+
# any spec/context that will include this module will "inherit" it's logic
|
91
|
+
#
|
92
|
+
# @example
|
93
|
+
# EnumeratorSpec = spec 'Enumerator tests' do
|
94
|
+
# # some tests here
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# spec Array do
|
98
|
+
# include EnumeratorSpec
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# spec Hash do
|
102
|
+
# include EnumeratorSpec
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
define_singleton_method(:included) {|b| b.class_exec(&block)}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# stop any code and report a failure
|
110
|
+
def fail reason, caller
|
111
|
+
throw(:__tokyo_status__, GenericFailure.new(Array(reason), caller))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
require 'tokyo/core_ext'
|
116
|
+
require 'tokyo/pretty_print'
|
117
|
+
require 'tokyo/expectations'
|
118
|
+
require 'tokyo/util'
|
119
|
+
require 'tokyo/unit'
|
120
|
+
require 'tokyo/assert'
|
121
|
+
require 'tokyo/run'
|
data/test/assert_test.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
describe :assert do
|
2
|
+
|
3
|
+
it 'pass ==' do
|
4
|
+
x = mock(:==, :x)
|
5
|
+
x == :x
|
6
|
+
x.verify
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'pass ===' do
|
10
|
+
x = mock(:===, :x)
|
11
|
+
x === :x
|
12
|
+
x.verify
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'pass !=' do
|
16
|
+
x = mock(:!=, :x)
|
17
|
+
x != :x
|
18
|
+
x.verify
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'pass >' do
|
22
|
+
x = mock(:>, :x)
|
23
|
+
x > :x
|
24
|
+
x.verify
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'pass >=' do
|
28
|
+
x = mock(:>=, :x)
|
29
|
+
x >= :x
|
30
|
+
x.verify
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'pass <' do
|
34
|
+
x = mock(:<, :x)
|
35
|
+
x < :x
|
36
|
+
x.verify
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'pass <=' do
|
40
|
+
x = mock(:<=, :x)
|
41
|
+
x <= :x
|
42
|
+
x.verify
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'pass eql?' do
|
46
|
+
x = mock(:eql?, :x)
|
47
|
+
x.eql? :x
|
48
|
+
x.verify
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'pass equal?' do
|
52
|
+
x = mock(:equal?, :x)
|
53
|
+
x.equal? :x
|
54
|
+
x.verify
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'pass =~' do
|
58
|
+
x = mock(:=~, :x)
|
59
|
+
x =~ :x
|
60
|
+
x.verify
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'pass match' do
|
64
|
+
x = mock(:match, :x)
|
65
|
+
x.match :x
|
66
|
+
x.verify
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'pass any?' do
|
70
|
+
m = mock(:any?)
|
71
|
+
m.any?
|
72
|
+
m.verify
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'pass all?' do
|
76
|
+
x = mock(:all?, :x)
|
77
|
+
x.all? :x
|
78
|
+
x.verify
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'pass start_with?' do
|
82
|
+
x = mock(:start_with?, :x)
|
83
|
+
x.start_with? :x
|
84
|
+
x.verify
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'pass end_with?' do
|
88
|
+
x = mock(:end_with?, :x)
|
89
|
+
x.end_with? :x
|
90
|
+
x.verify
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'pass respond_to?' do
|
94
|
+
x = mock(:respond_to?, :__id__, true)
|
95
|
+
x.respond_to? :__id__, true
|
96
|
+
x.verify
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
describe :context_inheritance_test do
|
2
|
+
|
3
|
+
it 'inherits from parent spec' do
|
4
|
+
x = nil
|
5
|
+
spec rand do
|
6
|
+
define_method(:set_x) {x = true}
|
7
|
+
context rand do
|
8
|
+
allocate.send(:set_x)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
assert_equal true, x
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'inherits from parent context' do
|
15
|
+
x = nil
|
16
|
+
spec rand do
|
17
|
+
context rand do
|
18
|
+
define_method(:set_x) {x = true}
|
19
|
+
context rand do
|
20
|
+
allocate.send(:set_x)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
assert_equal true, x
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'inherits from parent spec through parent context' do
|
28
|
+
x = nil
|
29
|
+
spec rand do
|
30
|
+
define_method(:set_x) {x = true}
|
31
|
+
context rand do
|
32
|
+
context rand do
|
33
|
+
allocate.send(:set_x)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
assert_equal true, x
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'does not inherit tests' do
|
41
|
+
spec_tests, context_tests = nil
|
42
|
+
spec rand do
|
43
|
+
test(:x) {}
|
44
|
+
context rand do
|
45
|
+
context_tests = tests.size
|
46
|
+
end
|
47
|
+
spec_tests = tests.size
|
48
|
+
end
|
49
|
+
assert_equal 1, spec_tests
|
50
|
+
assert_equal 0, context_tests
|
51
|
+
end
|
52
|
+
end
|
data/test/hooks_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
describe :hooks do
|
2
|
+
|
3
|
+
it 'calls before and after hooks' do
|
4
|
+
called = 0
|
5
|
+
spec rand do
|
6
|
+
before {called += 1}
|
7
|
+
after {called += 1}
|
8
|
+
test(:x) {}
|
9
|
+
run(:x)
|
10
|
+
end
|
11
|
+
assert_equal 2, called
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'calls around hooks' do
|
15
|
+
called = false
|
16
|
+
spec rand do
|
17
|
+
around {|test| test.call}
|
18
|
+
test(:x) {called = true}
|
19
|
+
run(:x)
|
20
|
+
end
|
21
|
+
assert_equal true, called
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'inherits hooks' do
|
25
|
+
spec_hooks, context_hooks = nil
|
26
|
+
spec rand do
|
27
|
+
before {}
|
28
|
+
context rand do
|
29
|
+
context_hooks = hooks
|
30
|
+
end
|
31
|
+
spec_hooks = hooks
|
32
|
+
end
|
33
|
+
assert_equal context_hooks, spec_hooks
|
34
|
+
end
|
35
|
+
end
|
data/test/raise_test.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
describe :raise do
|
2
|
+
|
3
|
+
it 'should pass if any exception raised' do
|
4
|
+
this = self
|
5
|
+
spec rand do
|
6
|
+
test(:test) {assert {x}.raise}
|
7
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should fail if nothing raised' do
|
12
|
+
this = self
|
13
|
+
spec rand do
|
14
|
+
test(:test) {assert {}.raise}
|
15
|
+
this.assert_equal Tokyo::GenericFailure, run(:test).class
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should pass if type matching' do
|
20
|
+
this = self
|
21
|
+
spec rand do
|
22
|
+
test(:test) {assert {x}.raise(NameError)}
|
23
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should fail if wrong exception raised' do
|
28
|
+
this = self
|
29
|
+
spec rand do
|
30
|
+
test(:test) {assert {}.raise(ArgumentError)}
|
31
|
+
this.assert_equal Tokyo::GenericFailure, run(:test).class
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should pass if both type and message matches' do
|
36
|
+
this = self
|
37
|
+
spec rand do
|
38
|
+
test(:test) {assert {x}.raise NameError, /undefined local variable or method/}
|
39
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should fail if message does not match' do
|
44
|
+
this = self
|
45
|
+
spec rand do
|
46
|
+
test(:test) {assert {x}.raise(NameError, /blah/)}
|
47
|
+
this.assert_equal Tokyo::GenericFailure, run(:test).class
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should pass if given block validates the raised error' do
|
52
|
+
this = self
|
53
|
+
spec rand do
|
54
|
+
test(:test) {assert {x}.raise {|e| e.class == NameError && e.message =~ /undefined local variable or method/}}
|
55
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should fail if given block invalidates raised error' do
|
60
|
+
this = self
|
61
|
+
spec rand do
|
62
|
+
test(:test) {assert {x}.raise {false}}
|
63
|
+
this.assert_equal Tokyo::GenericFailure, run(:test).class
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
describe :receive_and_raise do
|
2
|
+
|
3
|
+
it 'should pass when received message raises as expected' do
|
4
|
+
this = self
|
5
|
+
spec rand do
|
6
|
+
test :test do
|
7
|
+
expect(x = 'x').to_receive(:y).and_raise(NoMethodError)
|
8
|
+
x.y
|
9
|
+
end
|
10
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should pass when received message raises whatever error' do
|
15
|
+
this = self
|
16
|
+
spec rand do
|
17
|
+
test :test do
|
18
|
+
expect(x = 'x').to_receive(:y).and_raise
|
19
|
+
x.y
|
20
|
+
end
|
21
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should fail when received message does not raise' do
|
26
|
+
this = self
|
27
|
+
spec rand do
|
28
|
+
test :test do
|
29
|
+
expect(x = 'x').to_receive(:to_s).and_raise
|
30
|
+
x.to_s
|
31
|
+
end
|
32
|
+
this.assert_match /Expected a exception to be raised/, run(:test).reason*' '
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should fail when received message raises a unexpected error type' do
|
37
|
+
this = self
|
38
|
+
spec rand do
|
39
|
+
test :test do
|
40
|
+
expect(x = 'x').to_receive(:y).and_raise(NameError)
|
41
|
+
x.y
|
42
|
+
end
|
43
|
+
this.assert_match /Expected a NameError to be raised/, run(:test).reason*' '
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should fail when error raised by received message is of expected type but error message does not match' do
|
48
|
+
this = self
|
49
|
+
spec rand do
|
50
|
+
test :test do
|
51
|
+
expect(x = 'x').to_receive(:y).and_raise(NoMethodError, /blah/)
|
52
|
+
x.y
|
53
|
+
end
|
54
|
+
this.assert_match /to match "blah"/, run(:test).reason*' '
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should pass if received message raises a error that match by type and message' do
|
59
|
+
this = self
|
60
|
+
spec rand do
|
61
|
+
test :test do
|
62
|
+
expect(x = 'x').to_receive(:y).and_raise(NoMethodError, /undefined method `y' for "x":String/)
|
63
|
+
x.y
|
64
|
+
end
|
65
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should pass if error raised by received message are validated by block' do
|
70
|
+
this, t, m = self, nil, nil
|
71
|
+
spec rand do
|
72
|
+
test :test do
|
73
|
+
expect(x = 'x').to_receive(:y).and_raise {|e|
|
74
|
+
t, m = e.class, e.message
|
75
|
+
}
|
76
|
+
x.y
|
77
|
+
end
|
78
|
+
run(:test)
|
79
|
+
this.assert_equal NoMethodError, t
|
80
|
+
this.assert_match /undefined method .y. for "x":String/, m
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
describe :receive_and_return do
|
2
|
+
|
3
|
+
it 'should pass when expected message returns expected value' do
|
4
|
+
this = self
|
5
|
+
spec rand do
|
6
|
+
test :test do
|
7
|
+
expect(x = 'x').to_receive(:+).with('y').and_return('xy')
|
8
|
+
x + 'y'
|
9
|
+
end
|
10
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should fail when expected message returns wrong value' do
|
15
|
+
this = self
|
16
|
+
spec rand do
|
17
|
+
test :test do
|
18
|
+
expect(x = 'x').to_receive(:to_s).and_return(:y)
|
19
|
+
x.to_s
|
20
|
+
end
|
21
|
+
this.assert_match /Looks like :to_s message never returned expected value/, run(:test).reason*' '
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should pass when block validates returned value' do
|
26
|
+
this = self
|
27
|
+
spec rand do
|
28
|
+
test :test do
|
29
|
+
expect(x = 'x').to_receive(:+).with('y').and_return {|v| v == 'xy'}
|
30
|
+
x + 'y'
|
31
|
+
end
|
32
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should fail when block does not validate returned value' do
|
37
|
+
this = self
|
38
|
+
spec rand do
|
39
|
+
test :test do
|
40
|
+
expect(x = 'x').to_receive(:+).with('y').and_return {false}
|
41
|
+
x + 'y'
|
42
|
+
end
|
43
|
+
this.assert_match /Looks like :\+ message never returned expected value/, run(:test).reason*' '
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
describe :receive_and_throw do
|
2
|
+
|
3
|
+
it 'should pass when received message throws whatever' do
|
4
|
+
this = self
|
5
|
+
spec rand do
|
6
|
+
test :test do
|
7
|
+
x = Class.new {define_singleton_method(:y) {throw :z}}
|
8
|
+
expect(x).to_receive(:y).and_throw
|
9
|
+
x.y
|
10
|
+
end
|
11
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should pass when received message throws expected symbol' do
|
16
|
+
this = self
|
17
|
+
spec rand do
|
18
|
+
test :test do
|
19
|
+
x = Class.new {define_singleton_method(:y) {throw :z}}
|
20
|
+
expect(x).to_receive(:y).and_throw(:z)
|
21
|
+
x.y
|
22
|
+
end
|
23
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should fail when received message throws nothing' do
|
28
|
+
this = self
|
29
|
+
spec rand do
|
30
|
+
test :test do
|
31
|
+
x = Class.new {define_singleton_method(:y) {}}
|
32
|
+
expect(x).to_receive(:y).and_throw
|
33
|
+
x.y
|
34
|
+
end
|
35
|
+
this.assert_match /Expected a symbol to be thrown/, run(:test).reason*' '
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should fail when received message throws wrong symbol' do
|
40
|
+
this = self
|
41
|
+
spec rand do
|
42
|
+
test :test do
|
43
|
+
x = Class.new {define_singleton_method(:y) {throw :z}}
|
44
|
+
expect(x).to_receive(:y).and_throw(:a)
|
45
|
+
x.y
|
46
|
+
end
|
47
|
+
this.assert_match /Expected :a to be thrown/, run(:test).reason*' '
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should pass when given block validates thrown symbol' do
|
52
|
+
this = self
|
53
|
+
spec rand do
|
54
|
+
test :test do
|
55
|
+
x = Class.new {define_singleton_method(:y) {throw :z}}
|
56
|
+
expect(x).to_receive(:y).and_throw {|s| s == :z}
|
57
|
+
x.y
|
58
|
+
end
|
59
|
+
this.assert_equal :__tokyo_passed__, run(:test)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should fail when block does not validate thrown symbol' do
|
64
|
+
this = self
|
65
|
+
spec rand do
|
66
|
+
test :test do
|
67
|
+
x = Class.new {define_singleton_method(:y) {throw :z}}
|
68
|
+
expect(x).to_receive(:y).and_throw {false}
|
69
|
+
x.y
|
70
|
+
end
|
71
|
+
this.assert_match /Looks like wrong or no symbol thrown/, run(:test).reason*' '
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|