tokyo 0.0.5
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.
- 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
|