cross-stub 0.1.4 → 0.2.0

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.
Files changed (39) hide show
  1. data/HISTORY.txt +12 -0
  2. data/README.rdoc +85 -29
  3. data/Rakefile +8 -1
  4. data/VERSION +1 -1
  5. data/cross-stub.gemspec +37 -19
  6. data/lib/cross-stub.rb +63 -24
  7. data/lib/cross-stub/arguments.rb +21 -0
  8. data/lib/cross-stub/arguments/array.rb +16 -0
  9. data/lib/cross-stub/arguments/hash.rb +17 -0
  10. data/lib/cross-stub/arguments/proc.rb +73 -0
  11. data/lib/cross-stub/cache.rb +36 -0
  12. data/lib/cross-stub/stores.rb +4 -0
  13. data/lib/cross-stub/stores/base.rb +38 -0
  14. data/lib/cross-stub/stores/file.rb +39 -0
  15. data/lib/cross-stub/stores/memcache.rb +40 -0
  16. data/lib/cross-stub/stores/redis.rb +41 -0
  17. data/lib/cross-stub/stubber.rb +132 -0
  18. data/rails_generators/cross_stub/cross_stub_generator.rb +1 -1
  19. data/rails_generators/cross_stub/templates/config/initializers/cross-stub.rb +9 -1
  20. data/rails_generators/cross_stub/templates/features/support/cross-stub.rb +16 -2
  21. data/spec/arguments/proc_spec.rb +689 -0
  22. data/spec/includes.rb +103 -0
  23. data/spec/integration/clearing_instance_stubs_spec.rb +119 -0
  24. data/spec/integration/clearing_stubs_spec.rb +118 -0
  25. data/spec/integration/creating_instance_stubs_spec.rb +91 -0
  26. data/spec/integration/creating_stubs_spec.rb +95 -0
  27. data/spec/integration/shared_spec.rb +35 -0
  28. data/spec/integration/stubbing_error_spec.rb +69 -0
  29. data/spec/service.rb +114 -0
  30. data/spec/spec_helper.rb +1 -41
  31. metadata +58 -26
  32. data/lib/cross-stub/cache_helpers.rb +0 -48
  33. data/lib/cross-stub/pseudo_class.rb +0 -82
  34. data/lib/cross-stub/setup_helpers.rb +0 -13
  35. data/lib/cross-stub/stub_helpers.rb +0 -64
  36. data/spec/cross-stub/clearing_stubs_spec.rb +0 -112
  37. data/spec/cross-stub/creating_stubs_spec.rb +0 -110
  38. data/spec/cross-stub/stubbing_error_spec.rb +0 -38
  39. data/spec/helpers.rb +0 -125
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'includes')
3
+ require File.join(File.dirname(__FILE__), '..', 'service')
4
+
5
+ shared 'has standard setup' do
6
+ before { CrossStub.setup(cache_store(@store_type)) }
7
+ after { CrossStub.clear }
8
+ end
9
+
10
+ shared 'has current process setup' do
11
+ behaves_like 'has standard setup'
12
+ before { @call = Object.method(:do_local_method_call) }
13
+ end
14
+
15
+ shared 'has other process setup' do
16
+
17
+ behaves_like 'has standard setup'
18
+
19
+ before do
20
+ @call = lambda do |klass_and_method_and_args|
21
+ do_remote_method_call("%s/%s" % [@store_type, klass_and_method_and_args])
22
+ end
23
+ $service_started ||= (
24
+ EchoServer.start if ENV['ECHO_SERVER'] != 'false'
25
+ true
26
+ )
27
+ end
28
+
29
+ end
30
+
31
+ at_exit do
32
+ $service_started && (
33
+ EchoServer.stop unless ENV['ECHO_SERVER'] == 'false'
34
+ )
35
+ end
@@ -0,0 +1,69 @@
1
+ require File.join(File.dirname(__FILE__), 'shared_spec')
2
+
3
+ describe 'Stubbing Error' do
4
+
5
+ describe ">> xstub (class/module)" do
6
+
7
+ before do
8
+ @store_type = :file
9
+ end
10
+
11
+ behaves_like 'has standard setup'
12
+
13
+ should 'not be raised when stubbing module' do
14
+ lambda { AnyModule.send(:xstub, :bang => 'OOPS') }.
15
+ should.not.raise(CrossStub::Error)
16
+ end
17
+
18
+ should 'not be raised when stubbing nested module' do
19
+ lambda { AnyModule::Inner.send(:xstub, :bang => 'OOPS') }.
20
+ should.not.raise(CrossStub::Error)
21
+ end
22
+
23
+ should 'not be raised when stubbing class' do
24
+ lambda { AnyClass.send(:xstub, :bang => 'OOPS') }.
25
+ should.not.raise(CrossStub::Error)
26
+ end
27
+
28
+ should 'not be raised when stubbing nested class' do
29
+ lambda { AnyClass::Inner.send(:xstub, :bang => 'OOPS') }.
30
+ should.not.raise(CrossStub::Error)
31
+ end
32
+
33
+ should 'be raised when stubbing instance' do
34
+ lambda { AnyInstance.new.send(:xstub, :bang => 'OOPS') }.
35
+ should.raise(CrossStub::CannotStubInstanceError)
36
+ end
37
+
38
+ end
39
+
40
+ describe ">> xstub (instance)" do
41
+
42
+ should 'not be raised when stubbing class' do
43
+ lambda { AnyClass.xstub({:bang => 'OOPS'}, :instance => true) }.
44
+ should.not.raise(CrossStub::Error)
45
+ end
46
+
47
+ should 'not be raised when stubbing nested class' do
48
+ lambda { AnyClass::Inner.xstub({:bang => 'OOPS'}, :instance => true) }.
49
+ should.not.raise(CrossStub::Error)
50
+ end
51
+
52
+ should 'be raised when stubbing module' do
53
+ lambda { AnyModule.xstub({:bang => 'OOPS'}, :instance => true) }.
54
+ should.raise(CrossStub::ModuleCannotBeInstantiatedError)
55
+ end
56
+
57
+ should 'be raised when stubbing nested module' do
58
+ lambda { AnyModule::Inner.xstub({:bang => 'OOPS'}, :instance => true) }.
59
+ should.raise(CrossStub::ModuleCannotBeInstantiatedError)
60
+ end
61
+
62
+ should 'be raised when stubbing instance' do
63
+ lambda { AnyInstance.new.xstub({:bang => 'OOPS'}, :instance => true) }.
64
+ should.raise(CrossStub::CannotStubInstanceError)
65
+ end
66
+
67
+ end
68
+
69
+ end
data/spec/service.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+ require File.join(File.dirname(__FILE__), 'includes')
4
+
5
+ module EchoClient
6
+
7
+ ADDRESS = ECHO_SERVER_HOST
8
+ PORT = ECHO_SERVER_PORT
9
+
10
+ class << self
11
+ def get(klass_and_method)
12
+ EventMachine::run do
13
+ (EventMachine::connect(ADDRESS, PORT, EM)).
14
+ execute(klass_and_method){|data| @result = Marshal.load(Base64.decode64(data)) }
15
+ end
16
+ @result
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ module EM
23
+ def receive_data(data)
24
+ @callback.call(data)
25
+ EventMachine::stop_event_loop
26
+ end
27
+ def execute(method, &blk)
28
+ @callback = blk
29
+ send_data(method)
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ module EchoServer
36
+
37
+ ADDRESS = ECHO_SERVER_HOST
38
+ PORT = ECHO_SERVER_PORT
39
+ LOG = ECHO_SERVER_LOG
40
+ WAIT_TIME = ECHO_SERVER_INIT_WAIT_TIME
41
+
42
+ class << self
43
+
44
+ def log(*msg)
45
+ (@logger ||= (
46
+ require 'logger'
47
+ Logger.new(LOG)
48
+ )) << [msg, ""].flatten.join("\n")
49
+ end
50
+
51
+ def cleanup
52
+ @logger.close
53
+ end
54
+
55
+ def start(other_process=false)
56
+ unless other_process
57
+ @process = IO.popen("ruby #{__FILE__}",'r')
58
+ sleep WAIT_TIME
59
+ else
60
+ log 'Starting echo service at %s:%s (#%s)' % [ADDRESS, PORT, Process.pid]
61
+ EventMachine::run { EventMachine::start_server(ADDRESS, PORT, EM) }
62
+ end
63
+ end
64
+
65
+ def stop
66
+ Process.kill('SIGHUP', @process.pid) if @process
67
+ end
68
+
69
+ end
70
+
71
+ private
72
+
73
+ module EM
74
+
75
+ def receive_data(store_type_and_klass_and_method_and_args)
76
+ log "\n"
77
+ log "(1) EchoServer::EM#receive_data ... receives: #{store_type_and_klass_and_method_and_args}"
78
+
79
+ store_type, klass_and_method_and_args =
80
+ store_type_and_klass_and_method_and_args.match(/^(.*?)\/(.*)$/)[1..2]
81
+
82
+ CrossStub.refresh(cache_store($prev_store_type)) if $prev_store_type
83
+ CrossStub.refresh(cache_store($prev_store_type = store_type))
84
+ log "(2) EchoServer::EM#receive_data ... completes stubs refresh"
85
+
86
+ klass, is_instance, method, args = parse_call_args(klass_and_method_and_args)
87
+ log "(3) EchoServer::EM#receive_data ... parses arguments to:",
88
+ " * receiver ... #{klass}%s" % (is_instance ? "#new" : nil),
89
+ " * method ... #{method}",
90
+ " * args ... #{args.inspect}"
91
+ value = do_local_method_call(klass_and_method_and_args) rescue $!.message
92
+
93
+ log "(4) EchoServer::EM#receive_data ... returns: #{value.inspect}"
94
+ send_data(Base64.encode64(Marshal.dump(value)))
95
+ log "(5) EchoServer::EM#receive_data ... end"
96
+ end
97
+
98
+ def log(*msg)
99
+ EchoServer.log(*msg)
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+
106
+ if $0 == __FILE__
107
+ begin
108
+ EchoServer.start(true)
109
+ rescue
110
+ EchoServer.log "#{$!.inspect}\n"
111
+ ensure
112
+ EchoServer.cleanup
113
+ end
114
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,45 +1,5 @@
1
1
  require 'rubygems'
2
2
  require 'bacon'
3
- require 'mocha'
4
-
5
- $LOAD_PATH.unshift(File.dirname(__FILE__))
6
- require 'helpers'
3
+ require File.join(File.dirname(__FILE__), 'includes')
7
4
 
8
5
  Bacon.summary_on_exit
9
-
10
- shared 'has standard setup' do
11
- before do
12
- CrossStub.setup(:file => $cache_file)
13
- @get_context = lambda do |klass_or_module|
14
- klass_or_module.split(/::/).inject(Object) { |context, name| context.const_get(name) }
15
- end
16
- end
17
- after do
18
- CrossStub.clear
19
- end
20
- end
21
-
22
- shared 'has current process setup' do
23
- before do
24
- @get_value = lambda do |klass_and_method_and_args|
25
- klass, method, *args = klass_and_method_and_args.split('.')
26
- konst = klass.split(/::/).inject(Object) { |const_train, const| const_train.const_get(const) }
27
- args.empty? ? konst.send(method) :
28
- konst.send(method, *args)
29
- end
30
- end
31
- end
32
-
33
- shared 'has other process setup' do
34
- before do
35
- EchoServer.start unless ENV['ECHO_SERVER'] == 'false'
36
- @get_value = lambda do |klass_and_method_and_args|
37
- (value = EchoClient.get(klass_and_method_and_args)) !~ /^undefined method/ ? value :
38
- Object.we_just_wanna_trigger_a_no_method_error_with_this_very_long_and_weird_method!
39
- end
40
- end
41
- after do
42
- EchoServer.stop unless ENV['ECHO_SERVER'] == 'false'
43
- end
44
- end
45
-
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cross-stub
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 23
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 1
8
- - 4
9
- version: 0.1.4
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - NgTzeYang
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-03 00:00:00 +08:00
18
+ date: 2010-07-16 00:00:00 +08:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: bacon
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 31
27
30
  segments:
28
31
  - 0
29
32
  - 0
@@ -35,9 +38,11 @@ dependencies:
35
38
  name: eventmachine
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 31
41
46
  segments:
42
47
  - 0
43
48
  - 0
@@ -46,31 +51,35 @@ dependencies:
46
51
  type: :development
47
52
  version_requirements: *id002
48
53
  - !ruby/object:Gem::Dependency
49
- name: ParseTree
54
+ name: ruby2ruby
50
55
  prerelease: false
51
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
52
58
  requirements:
53
59
  - - "="
54
60
  - !ruby/object:Gem::Version
61
+ hash: 23
55
62
  segments:
56
- - 3
57
- - 0
63
+ - 1
64
+ - 2
58
65
  - 4
59
- version: 3.0.4
66
+ version: 1.2.4
60
67
  type: :runtime
61
68
  version_requirements: *id003
62
69
  - !ruby/object:Gem::Dependency
63
- name: ruby2ruby
70
+ name: ruby_parser
64
71
  prerelease: false
65
72
  requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
66
74
  requirements:
67
75
  - - "="
68
76
  - !ruby/object:Gem::Version
77
+ hash: 7
69
78
  segments:
70
- - 1
71
79
  - 2
80
+ - 0
72
81
  - 4
73
- version: 1.2.4
82
+ version: 2.0.4
74
83
  type: :runtime
75
84
  version_requirements: *id004
76
85
  description: ""
@@ -92,18 +101,30 @@ files:
92
101
  - VERSION
93
102
  - cross-stub.gemspec
94
103
  - lib/cross-stub.rb
95
- - lib/cross-stub/cache_helpers.rb
96
- - lib/cross-stub/pseudo_class.rb
97
- - lib/cross-stub/setup_helpers.rb
98
- - lib/cross-stub/stub_helpers.rb
104
+ - lib/cross-stub/arguments.rb
105
+ - lib/cross-stub/arguments/array.rb
106
+ - lib/cross-stub/arguments/hash.rb
107
+ - lib/cross-stub/arguments/proc.rb
108
+ - lib/cross-stub/cache.rb
109
+ - lib/cross-stub/stores.rb
110
+ - lib/cross-stub/stores/base.rb
111
+ - lib/cross-stub/stores/file.rb
112
+ - lib/cross-stub/stores/memcache.rb
113
+ - lib/cross-stub/stores/redis.rb
114
+ - lib/cross-stub/stubber.rb
99
115
  - rails_generators/cross_stub/cross_stub_generator.rb
100
116
  - rails_generators/cross_stub/templates/config/initializers/cross-stub.rb
101
117
  - rails_generators/cross_stub/templates/features/support/cross-stub.rb
102
118
  - spec/.bacon
103
- - spec/cross-stub/clearing_stubs_spec.rb
104
- - spec/cross-stub/creating_stubs_spec.rb
105
- - spec/cross-stub/stubbing_error_spec.rb
106
- - spec/helpers.rb
119
+ - spec/arguments/proc_spec.rb
120
+ - spec/includes.rb
121
+ - spec/integration/clearing_instance_stubs_spec.rb
122
+ - spec/integration/clearing_stubs_spec.rb
123
+ - spec/integration/creating_instance_stubs_spec.rb
124
+ - spec/integration/creating_stubs_spec.rb
125
+ - spec/integration/shared_spec.rb
126
+ - spec/integration/stubbing_error_spec.rb
127
+ - spec/service.rb
107
128
  - spec/spec_helper.rb
108
129
  - tmp/.dummy
109
130
  has_rdoc: true
@@ -116,29 +137,40 @@ rdoc_options:
116
137
  require_paths:
117
138
  - lib
118
139
  required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
119
141
  requirements:
120
142
  - - ">="
121
143
  - !ruby/object:Gem::Version
144
+ hash: 57
122
145
  segments:
123
- - 0
124
- version: "0"
146
+ - 1
147
+ - 8
148
+ - 7
149
+ version: 1.8.7
125
150
  required_rubygems_version: !ruby/object:Gem::Requirement
151
+ none: false
126
152
  requirements:
127
153
  - - ">="
128
154
  - !ruby/object:Gem::Version
155
+ hash: 3
129
156
  segments:
130
157
  - 0
131
158
  version: "0"
132
159
  requirements: []
133
160
 
134
161
  rubyforge_project:
135
- rubygems_version: 1.3.6
162
+ rubygems_version: 1.3.7
136
163
  signing_key:
137
164
  specification_version: 3
138
165
  summary: Simple cross process stubbing
139
166
  test_files:
140
- - spec/helpers.rb
141
- - spec/cross-stub/stubbing_error_spec.rb
142
- - spec/cross-stub/clearing_stubs_spec.rb
143
- - spec/cross-stub/creating_stubs_spec.rb
167
+ - spec/includes.rb
168
+ - spec/arguments/proc_spec.rb
169
+ - spec/service.rb
170
+ - spec/integration/stubbing_error_spec.rb
171
+ - spec/integration/creating_instance_stubs_spec.rb
172
+ - spec/integration/shared_spec.rb
173
+ - spec/integration/clearing_stubs_spec.rb
174
+ - spec/integration/creating_stubs_spec.rb
175
+ - spec/integration/clearing_instance_stubs_spec.rb
144
176
  - spec/spec_helper.rb
@@ -1,48 +0,0 @@
1
- module CrossStub
2
-
3
- private
4
-
5
- module CacheHelpers
6
-
7
- def setup_cache
8
- File.open(cache_file, 'w') {|f| Marshal.dump({}, f) }
9
- end
10
-
11
- def update_cache(&blk)
12
- dump_cache(yield(load_cache))
13
- end
14
-
15
- def delete_cache
16
- if File.exists?(cache_file)
17
- File.exists?(backup_cache_file) ?
18
- File.delete(cache_file) : File.rename(cache_file, backup_cache_file)
19
- end
20
- end
21
-
22
- def load_cache
23
- File.open(cache_file,'r') {|f| Marshal.load(f) }
24
- end
25
-
26
- def load_backup_cache
27
- cache = {}
28
- if File.exists?(backup_cache_file)
29
- cache = File.open(backup_cache_file, 'r') {|f| Marshal.load(f) }
30
- File.delete(backup_cache_file)
31
- end
32
- cache
33
- end
34
-
35
- def dump_cache(data)
36
- File.open(cache_file,'w') {|f| Marshal.dump(data, f) }
37
- end
38
-
39
- def backup_cache_file
40
- %\#{options[:file]}.bak\
41
- end
42
-
43
- def cache_file
44
- options[:file]
45
- end
46
-
47
- end
48
- end