cross-stub 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +12 -0
- data/README.rdoc +85 -29
- data/Rakefile +8 -1
- data/VERSION +1 -1
- data/cross-stub.gemspec +37 -19
- data/lib/cross-stub.rb +63 -24
- data/lib/cross-stub/arguments.rb +21 -0
- data/lib/cross-stub/arguments/array.rb +16 -0
- data/lib/cross-stub/arguments/hash.rb +17 -0
- data/lib/cross-stub/arguments/proc.rb +73 -0
- data/lib/cross-stub/cache.rb +36 -0
- data/lib/cross-stub/stores.rb +4 -0
- data/lib/cross-stub/stores/base.rb +38 -0
- data/lib/cross-stub/stores/file.rb +39 -0
- data/lib/cross-stub/stores/memcache.rb +40 -0
- data/lib/cross-stub/stores/redis.rb +41 -0
- data/lib/cross-stub/stubber.rb +132 -0
- data/rails_generators/cross_stub/cross_stub_generator.rb +1 -1
- data/rails_generators/cross_stub/templates/config/initializers/cross-stub.rb +9 -1
- data/rails_generators/cross_stub/templates/features/support/cross-stub.rb +16 -2
- data/spec/arguments/proc_spec.rb +689 -0
- data/spec/includes.rb +103 -0
- data/spec/integration/clearing_instance_stubs_spec.rb +119 -0
- data/spec/integration/clearing_stubs_spec.rb +118 -0
- data/spec/integration/creating_instance_stubs_spec.rb +91 -0
- data/spec/integration/creating_stubs_spec.rb +95 -0
- data/spec/integration/shared_spec.rb +35 -0
- data/spec/integration/stubbing_error_spec.rb +69 -0
- data/spec/service.rb +114 -0
- data/spec/spec_helper.rb +1 -41
- metadata +58 -26
- data/lib/cross-stub/cache_helpers.rb +0 -48
- data/lib/cross-stub/pseudo_class.rb +0 -82
- data/lib/cross-stub/setup_helpers.rb +0 -13
- data/lib/cross-stub/stub_helpers.rb +0 -64
- data/spec/cross-stub/clearing_stubs_spec.rb +0 -112
- data/spec/cross-stub/creating_stubs_spec.rb +0 -110
- data/spec/cross-stub/stubbing_error_spec.rb +0 -38
- data/spec/helpers.rb +0 -125
data/spec/includes.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
unless Object.const_defined?(:RUBY_VM)
|
2
|
+
|
3
|
+
# ///////////////////////////////////////////////////////////////////////
|
4
|
+
# Constants
|
5
|
+
# ///////////////////////////////////////////////////////////////////////
|
6
|
+
|
7
|
+
RUBY_VM = [
|
8
|
+
RUBY_VERSION.gsub(/[^\d]/,''),
|
9
|
+
RUBY_PLATFORM =~ /java/i ? 'j' : '',
|
10
|
+
RUBY_DESCRIPTION =~ /enterprise/i ? 'e' : ''
|
11
|
+
].join
|
12
|
+
|
13
|
+
PROJECT_ROOT = File.join(File.dirname(__FILE__), '..')
|
14
|
+
PROJECT_FILE = lambda{|*args| File.join(*[PROJECT_ROOT, *args]) }
|
15
|
+
|
16
|
+
CACHE_STORES = {
|
17
|
+
:file => PROJECT_FILE['tmp', "stubbing-#{RUBY_VM}.cache"],
|
18
|
+
:memcache => "localhost:11211/stubbing-#{RUBY_VM}.cache",
|
19
|
+
:redis => "localhost:6379/stubbing-#{RUBY_VM}.cache",
|
20
|
+
}
|
21
|
+
|
22
|
+
ECHO_SERVER_INIT_WAIT_TIME = RUBY_VM.end_with?('j') ? 10 : 2
|
23
|
+
ECHO_SERVER_LOG = PROJECT_FILE['tmp', "echoserver-#{RUBY_VM}.log"]
|
24
|
+
ECHO_SERVER_HOST = '127.0.0.1'
|
25
|
+
ECHO_SERVER_PORT = 10000 + RUBY_VM[/(\d+)/,1].to_i + ({'j' => 7, 'e' => 17}[RUBY_VM[-1..-1]] || 0)
|
26
|
+
|
27
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
28
|
+
# Useful methods
|
29
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
30
|
+
|
31
|
+
def cache_store(id)
|
32
|
+
{(id = :"#{id}") => CACHE_STORES[id]}
|
33
|
+
end
|
34
|
+
|
35
|
+
def each_cache_store(&block)
|
36
|
+
CACHE_STORES.keys.each do |store_type|
|
37
|
+
yield(store_type)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def do_local_method_call(klass_and_method_and_args)
|
42
|
+
klass, is_instance, method, args = parse_call_args(klass_and_method_and_args)
|
43
|
+
receiver = is_instance ? klass.new : klass
|
44
|
+
args.empty? ? receiver.send(method) : receiver.send(method, *args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_call_args(klass_and_method_and_args)
|
48
|
+
klass_descriptor, method, *args = klass_and_method_and_args.split('.')
|
49
|
+
is_instance = klass_descriptor.end_with?(suffix = '#new')
|
50
|
+
[klassify(klass_descriptor), is_instance, method, args]
|
51
|
+
end
|
52
|
+
|
53
|
+
def do_remote_method_call(store_type_and_klass_and_method_and_args)
|
54
|
+
(value = EchoClient.get(store_type_and_klass_and_method_and_args)) !~ /^undefined method/ ?
|
55
|
+
value : Object.we_just_wanna_trigger_no_method_error_with_this_weird_method!
|
56
|
+
end
|
57
|
+
|
58
|
+
def klassify(descriptor)
|
59
|
+
descriptor.sub('#new','').split(/::/).inject(Object){|k,c| k.const_get(c) }
|
60
|
+
end
|
61
|
+
|
62
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
63
|
+
# Loading of files
|
64
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
65
|
+
|
66
|
+
$LOAD_PATH.unshift(PROJECT_FILE['lib'])
|
67
|
+
require 'cross-stub'
|
68
|
+
|
69
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
70
|
+
# Class definitions for specs
|
71
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
72
|
+
|
73
|
+
class AnyClass
|
74
|
+
|
75
|
+
def self.say ; 'hello' ; end
|
76
|
+
|
77
|
+
class Inner
|
78
|
+
def self.say ; 'hello' ; end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class AnyInstance
|
84
|
+
|
85
|
+
def say ; 'hello' ; end
|
86
|
+
|
87
|
+
class Inner
|
88
|
+
def say ; 'hello' ; end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
module AnyModule
|
94
|
+
|
95
|
+
def self.say ; 'hello' ; end
|
96
|
+
|
97
|
+
module Inner
|
98
|
+
def self.say ; 'hello' ; end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'shared_spec')
|
2
|
+
|
3
|
+
describe 'Clearing Instance Stubs' do
|
4
|
+
|
5
|
+
each_cache_store do |store_type|
|
6
|
+
%w{current other}.each do |mode|
|
7
|
+
%w{AnyInstance#new AnyInstance::Inner#new}.each do |descriptor|
|
8
|
+
|
9
|
+
describe '>> %s process using :%s store (%s instance)' % [mode, store_type, descriptor] do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@descriptor = descriptor
|
13
|
+
@klass = klassify(descriptor)
|
14
|
+
@instance = @klass.new
|
15
|
+
@store_type = store_type
|
16
|
+
end
|
17
|
+
|
18
|
+
behaves_like "has #{mode} process setup"
|
19
|
+
|
20
|
+
should "clear hash generated stub and return original value" do
|
21
|
+
original_value = @instance.say
|
22
|
+
@klass.xstub({:say => 'HELLO'}, :instance => true)
|
23
|
+
CrossStub.clear
|
24
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
25
|
+
end
|
26
|
+
|
27
|
+
should "clear hash generated stub and raise NoMethodError" do
|
28
|
+
should.raise(NoMethodError) do
|
29
|
+
@klass.xstub({:blurb => 'blah blah'}, :instance => true)
|
30
|
+
CrossStub.clear
|
31
|
+
@call["#{@descriptor}.blurb"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
should "clear symbol generated stub and return original value" do
|
36
|
+
original_value = @instance.say
|
37
|
+
@klass.xstub(:say, :instance => true)
|
38
|
+
CrossStub.clear
|
39
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
40
|
+
end
|
41
|
+
|
42
|
+
should "clear symbol generated stub and raise NoMethodError" do
|
43
|
+
should.raise(NoMethodError) do
|
44
|
+
@klass.xstub(:blurb, :instance => true)
|
45
|
+
CrossStub.clear
|
46
|
+
@call["#{@descriptor}.blurb"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
should "clear block generated stub and return original value" do
|
51
|
+
original_value = @instance.say
|
52
|
+
@klass.xstub(:instance => true) do
|
53
|
+
def say ; 'HELLO' ; end
|
54
|
+
end
|
55
|
+
CrossStub.clear
|
56
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
57
|
+
end
|
58
|
+
|
59
|
+
should "clear block generated stub and raise NoMethodError" do
|
60
|
+
should.raise(NoMethodError) do
|
61
|
+
@klass.xstub(:instance => true) do
|
62
|
+
def blurb ; 'blah blah' ; end
|
63
|
+
end
|
64
|
+
CrossStub.clear
|
65
|
+
@call["#{@descriptor}.blurb"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
should "always clear previously generated stub" do
|
70
|
+
original_value = @instance.say
|
71
|
+
|
72
|
+
# Stub an existing method
|
73
|
+
@klass.xstub({:say => 'HELLO'}, :instance => true)
|
74
|
+
@call["#{@descriptor}.say"]
|
75
|
+
|
76
|
+
# Clear stubs without refreshing another process
|
77
|
+
CrossStub.clear
|
78
|
+
CrossStub.setup(cache_store(@store_type))
|
79
|
+
|
80
|
+
# Stub a non-existing method
|
81
|
+
@klass.xstub({:blurb => 'blah blah'}, :instance => true)
|
82
|
+
@call["#{@descriptor}.blurb"]
|
83
|
+
|
84
|
+
# Make sure existing method returns to original method
|
85
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
86
|
+
end
|
87
|
+
|
88
|
+
should "always clear previously generated stub and raise NoMethodError" do
|
89
|
+
# Stub a non-existing method
|
90
|
+
@klass.xstub({:blurb => 'blah blah'}, :instance => true)
|
91
|
+
@call["#{@descriptor}.blurb"]
|
92
|
+
|
93
|
+
# Clear stubs without refreshing another process
|
94
|
+
CrossStub.clear
|
95
|
+
CrossStub.setup(cache_store(@store_type))
|
96
|
+
|
97
|
+
# Stub an existing method
|
98
|
+
@klass.xstub({:say => 'HELLO'}, :instance => true)
|
99
|
+
@call["#{@descriptor}.say"]
|
100
|
+
|
101
|
+
# Make sure accessing non-existing method throws error
|
102
|
+
should.raise(NoMethodError) { @call["#{@descriptor}.blurb"] }
|
103
|
+
end
|
104
|
+
|
105
|
+
should "clear for method not implemented in ruby and return original value" do
|
106
|
+
Time.xstub(:day => 99, :instance => true)
|
107
|
+
CrossStub.clear
|
108
|
+
value = nil
|
109
|
+
should.not.raise(NoMethodError) { value = @call['Time#new.day'] }
|
110
|
+
value.should.not.equal 99
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'shared_spec')
|
2
|
+
|
3
|
+
describe 'Clearing Stubs' do
|
4
|
+
|
5
|
+
each_cache_store do |store_type|
|
6
|
+
%w{current other}.each do |mode|
|
7
|
+
%w{AnyClass AnyClass::Inner AnyModule AnyModule::Inner}.each do |descriptor|
|
8
|
+
|
9
|
+
describe '>> %s process using :%s store (%s)' % [mode, store_type, descriptor] do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@descriptor = descriptor
|
13
|
+
@klass = klassify(descriptor)
|
14
|
+
@store_type = store_type
|
15
|
+
end
|
16
|
+
|
17
|
+
behaves_like "has #{mode} process setup"
|
18
|
+
|
19
|
+
should "clear hash generated stub and return original value" do
|
20
|
+
original_value = @klass.say
|
21
|
+
@klass.xstub(:say => 'HELLO')
|
22
|
+
CrossStub.clear
|
23
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
24
|
+
end
|
25
|
+
|
26
|
+
should "clear hash generated stub and raise NoMethodError" do
|
27
|
+
should.raise(NoMethodError) do
|
28
|
+
@klass.xstub(:bang => 'OOPS')
|
29
|
+
CrossStub.clear
|
30
|
+
@call["#{@descriptor}.bang"]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
should "clear symbol generated stub and return original value" do
|
35
|
+
original_value = @klass.say
|
36
|
+
@klass.xstub(:say)
|
37
|
+
CrossStub.clear
|
38
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
39
|
+
end
|
40
|
+
|
41
|
+
should "clear symbol generated stub and raise NoMethodError" do
|
42
|
+
should.raise(NoMethodError) do
|
43
|
+
@klass.xstub(:bang)
|
44
|
+
CrossStub.clear
|
45
|
+
@call["#{@descriptor}.bang"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
should "clear block generated stub and return original value" do
|
50
|
+
original_value = @klass.say
|
51
|
+
@klass.xstub do
|
52
|
+
def say ; 'HELLO' ; end
|
53
|
+
end
|
54
|
+
CrossStub.clear
|
55
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
56
|
+
end
|
57
|
+
|
58
|
+
should "clear block generated stub and raise NoMethodError" do
|
59
|
+
should.raise(NoMethodError) do
|
60
|
+
@klass.xstub do
|
61
|
+
def bang ; 'OOPS' ; end
|
62
|
+
end
|
63
|
+
CrossStub.clear
|
64
|
+
@call["#{@descriptor}.bang"]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
should "always clear previously generated stub" do
|
69
|
+
original_value = @klass.say
|
70
|
+
|
71
|
+
# Stub an existing method
|
72
|
+
@klass.xstub(:say => 'HELLO')
|
73
|
+
@call["#{@descriptor}.say"]
|
74
|
+
|
75
|
+
# Clear stubs without refreshing another process
|
76
|
+
CrossStub.clear
|
77
|
+
CrossStub.setup(cache_store(@store_type))
|
78
|
+
|
79
|
+
# Stub a non-existing method
|
80
|
+
@klass.xstub(:bang => 'OOPS')
|
81
|
+
@call["#{@descriptor}.bang"]
|
82
|
+
|
83
|
+
# Make sure existing method returns to original method
|
84
|
+
@call["#{@descriptor}.say"].should.equal original_value
|
85
|
+
end
|
86
|
+
|
87
|
+
should "always clear previously generated stub and raise NoMethodError" do
|
88
|
+
# Stub a non-existing method
|
89
|
+
@klass.xstub(:bang => 'OOPS')
|
90
|
+
@call["#{@descriptor}.bang"]
|
91
|
+
|
92
|
+
# Clear stubs without refreshing another process
|
93
|
+
CrossStub.clear
|
94
|
+
CrossStub.setup(cache_store(@store_type))
|
95
|
+
|
96
|
+
# Stub an existing method
|
97
|
+
@klass.xstub(:say => 'HELLO')
|
98
|
+
@call["#{@descriptor}.say"]
|
99
|
+
|
100
|
+
# Make sure accessing non-existing method throws error
|
101
|
+
should.raise(NoMethodError) { @call["#{@descriptor}.bang"] }
|
102
|
+
end
|
103
|
+
|
104
|
+
should "clear for method not implemented in ruby and return original value" do
|
105
|
+
Time.xstub(:now => 'abc')
|
106
|
+
CrossStub.clear
|
107
|
+
value = nil
|
108
|
+
should.not.raise(NoMethodError) { value = @call['Time.now'] }
|
109
|
+
value.should.not.equal 'abc'
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'shared_spec')
|
2
|
+
|
3
|
+
describe 'Creating Instance Stubs' do
|
4
|
+
|
5
|
+
each_cache_store do |store_type|
|
6
|
+
%w{current other}.each do |mode|
|
7
|
+
%w{AnyInstance#new AnyInstance::Inner#new}.each do |descriptor|
|
8
|
+
|
9
|
+
describe '>> %s process using :%s store (%s)' % [mode, store_type, descriptor] do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@descriptor = descriptor
|
13
|
+
@klass = klassify(descriptor)
|
14
|
+
@store_type = store_type
|
15
|
+
end
|
16
|
+
|
17
|
+
behaves_like "has #{mode} process setup"
|
18
|
+
|
19
|
+
should "create with hash argument(s)" do
|
20
|
+
@klass.xstub({:bang => 'OOPS', :say => 'HELLO'}, :instance => true)
|
21
|
+
@call["#{@descriptor}.bang"].should.equal 'OOPS'
|
22
|
+
@call["#{@descriptor}.say"].should.equal 'HELLO'
|
23
|
+
end
|
24
|
+
|
25
|
+
should "create with symbol argument(s)" do
|
26
|
+
@klass.xstub(:bang, :instance => true)
|
27
|
+
@call["#{@descriptor}.bang"].should.equal nil
|
28
|
+
end
|
29
|
+
|
30
|
+
should "create with block with no argument" do
|
31
|
+
@klass.xstub(:instance => true) do
|
32
|
+
def bang ; 'OOPS' ; end
|
33
|
+
end
|
34
|
+
@call["#{@descriptor}.bang"].should.equal 'OOPS'
|
35
|
+
end
|
36
|
+
|
37
|
+
should "create with symbol & block with no argument" do
|
38
|
+
@klass.xstub(:bang, :instance => true) do
|
39
|
+
def say ; 'HELLO' ; end
|
40
|
+
end
|
41
|
+
@call["#{@descriptor}.bang"].should.equal nil
|
42
|
+
@call["#{@descriptor}.say"].should.equal 'HELLO'
|
43
|
+
end
|
44
|
+
|
45
|
+
should "create with hash & block with no argument" do
|
46
|
+
@klass.xstub({:bang => 'OOPS'}, :instance => true) do
|
47
|
+
def say ; 'HELLO' ; end
|
48
|
+
end
|
49
|
+
@call["#{@descriptor}.bang"].should.equal 'OOPS'
|
50
|
+
@call["#{@descriptor}.say"].should.equal 'HELLO'
|
51
|
+
end
|
52
|
+
|
53
|
+
should "always create the most recent" do
|
54
|
+
found, expected = [], ['OOPS', 'OOOPS', 'OOOOPS']
|
55
|
+
stub_and_get_value = lambda do |value|
|
56
|
+
@klass.xstub({:bang => value}, :instance => true)
|
57
|
+
@call["#{@descriptor}.bang"]
|
58
|
+
end
|
59
|
+
|
60
|
+
found << stub_and_get_value[expected[0]]
|
61
|
+
found << stub_and_get_value[expected[1]]
|
62
|
+
|
63
|
+
CrossStub.clear
|
64
|
+
CrossStub.setup(cache_store(@store_type))
|
65
|
+
|
66
|
+
found << stub_and_get_value[expected[2]]
|
67
|
+
found.should.equal expected
|
68
|
+
end
|
69
|
+
|
70
|
+
should "create stub with dependency on other stub" do
|
71
|
+
@klass.xstub({:something => 'HELLO'}, :instance => true) do
|
72
|
+
def do_action(who, action)
|
73
|
+
%\#{who} #{action} #{something}\
|
74
|
+
end
|
75
|
+
end
|
76
|
+
@call["#{@descriptor}.do_action.i.say"].should.equal 'i say HELLO'
|
77
|
+
end
|
78
|
+
|
79
|
+
should "create for method not implemented in ruby" do
|
80
|
+
day = 99
|
81
|
+
Time.xstub({:day => day}, :instance => true)
|
82
|
+
@call['Time#new.day'].should.equal day
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'shared_spec')
|
2
|
+
|
3
|
+
describe 'Creating Stubs' do
|
4
|
+
|
5
|
+
each_cache_store do |store_type|
|
6
|
+
%w{current other}.each do |mode|
|
7
|
+
%w{AnyClass AnyModule AnyClass::Inner AnyModule::Inner}.each do |descriptor|
|
8
|
+
|
9
|
+
describe '>> %s process using :%s store (%s)' % [mode, store_type, descriptor] do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@descriptor = descriptor
|
13
|
+
@klass = klassify(descriptor)
|
14
|
+
@store_type = store_type
|
15
|
+
end
|
16
|
+
|
17
|
+
behaves_like "has #{mode} process setup"
|
18
|
+
|
19
|
+
should "create with hash argument(s)" do
|
20
|
+
@klass.xstub(:bang => 'OOPS', :say => 'HELLO')
|
21
|
+
@call["#{@descriptor}.bang"].should.equal 'OOPS'
|
22
|
+
@call["#{@descriptor}.say"].should.equal 'HELLO'
|
23
|
+
end
|
24
|
+
|
25
|
+
should "create with symbol argument(s)" do
|
26
|
+
@klass.xstub(:bang)
|
27
|
+
@call["#{@descriptor}.bang"].should.equal nil
|
28
|
+
end
|
29
|
+
|
30
|
+
should "create with block with no argument" do
|
31
|
+
@klass.xstub do
|
32
|
+
def bang ; 'OOPS' ; end
|
33
|
+
end
|
34
|
+
@call["#{@descriptor}.bang"].should.equal 'OOPS'
|
35
|
+
end
|
36
|
+
|
37
|
+
should "create with symbol & block with no argument" do
|
38
|
+
@klass.xstub(:bang) do
|
39
|
+
def say
|
40
|
+
'HELLO'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@call["#{@descriptor}.bang"].should.equal nil
|
44
|
+
@call["#{@descriptor}.say"].should.equal 'HELLO'
|
45
|
+
end
|
46
|
+
|
47
|
+
should "create with hash & block with no argument" do
|
48
|
+
@klass.xstub(:bang => 'OOPS') do
|
49
|
+
def say
|
50
|
+
'HELLO'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@call["#{@descriptor}.bang"].should.equal 'OOPS'
|
54
|
+
@call["#{@descriptor}.say"].should.equal 'HELLO'
|
55
|
+
end
|
56
|
+
|
57
|
+
should "always create the most recent" do
|
58
|
+
found, expected = [], ['OOPS', 'OOOPS', 'OOOOPS']
|
59
|
+
stub_and_get_value = lambda do |value|
|
60
|
+
@klass.xstub(:bang => value)
|
61
|
+
@call["#{@descriptor}.bang"]
|
62
|
+
end
|
63
|
+
|
64
|
+
found << stub_and_get_value[expected[0]]
|
65
|
+
found << stub_and_get_value[expected[1]]
|
66
|
+
|
67
|
+
CrossStub.clear
|
68
|
+
CrossStub.setup(cache_store(@store_type))
|
69
|
+
|
70
|
+
found << stub_and_get_value[expected[2]]
|
71
|
+
found.should.equal expected
|
72
|
+
end
|
73
|
+
|
74
|
+
should "create stub with dependency on other stub" do
|
75
|
+
@klass.xstub(:something => 'HELLO') do
|
76
|
+
def do_action(who, action)
|
77
|
+
%\#{who} #{action} #{something}\
|
78
|
+
end
|
79
|
+
end
|
80
|
+
@call["#{@descriptor}.do_action.i.say"].should.equal 'i say HELLO'
|
81
|
+
end
|
82
|
+
|
83
|
+
should "create for method not implemented in ruby" do
|
84
|
+
now = Time.now - 365*60*60*24
|
85
|
+
Time.xstub(:now => now)
|
86
|
+
@call['Time.now'].should.equal now
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|