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.
- 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
@@ -1,82 +0,0 @@
|
|
1
|
-
module CrossStub
|
2
|
-
|
3
|
-
private
|
4
|
-
|
5
|
-
class PseudoClass
|
6
|
-
|
7
|
-
@@translator ||= lambda do |metaclass, method|
|
8
|
-
@@convertor ||= lambda {|sexp| Ruby2Ruby.new.process(Unifier.new.process(sexp)) }
|
9
|
-
@@convertor[ParseTree.translate(metaclass, method)] rescue nil
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(klass)
|
13
|
-
@klass = get_class(klass)
|
14
|
-
@metaclass = (class << @klass ; self ; end)
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_class(klass)
|
18
|
-
if klass.is_a?(String)
|
19
|
-
klass.split(/::/).inject(Object) { |const_train, const| const_train.const_get(const) }
|
20
|
-
else
|
21
|
-
klass
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def id
|
26
|
-
@klass.to_s
|
27
|
-
end
|
28
|
-
|
29
|
-
def method_code(method)
|
30
|
-
@@translator[@metaclass, method]
|
31
|
-
end
|
32
|
-
|
33
|
-
def replace_method(method, value_or_code)
|
34
|
-
status = backup_method(method)
|
35
|
-
@klass.instance_eval "#{value_or_code}" =~ /^def / ? value_or_code :
|
36
|
-
%\def #{method}; Marshal.load(%|#{Marshal.dump(value_or_code)}|) ; end\
|
37
|
-
status
|
38
|
-
end
|
39
|
-
|
40
|
-
def revert_method(method)
|
41
|
-
new_name = before_stubbing_method_name(method)
|
42
|
-
@metaclass.instance_eval("alias_method :#{method}, :#{new_name}") rescue nil
|
43
|
-
remove_method(new_name)
|
44
|
-
end
|
45
|
-
|
46
|
-
def backup_method(method)
|
47
|
-
if @klass.respond_to?(method)
|
48
|
-
!@klass.respond_to?(new_name = before_stubbing_method_name(method)) &&
|
49
|
-
@metaclass.instance_eval("alias_method :#{new_name}, :#{method}")
|
50
|
-
true
|
51
|
-
else
|
52
|
-
false
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def remove_method(method)
|
57
|
-
@metaclass.send(:remove_method, method) rescue nil
|
58
|
-
end
|
59
|
-
|
60
|
-
def replace_methods(&blk)
|
61
|
-
(tmp = BlankObject.new).__instance_eval__(&blk)
|
62
|
-
methods_in_block = tmp.__methods__ - BlankObject.new.__methods__
|
63
|
-
is_method_implemented_flags = methods_in_block.inject({}) do |memo, method|
|
64
|
-
memo.merge(method => backup_method(method))
|
65
|
-
end
|
66
|
-
@klass.instance_eval(&blk)
|
67
|
-
is_method_implemented_flags
|
68
|
-
end
|
69
|
-
|
70
|
-
def before_stubbing_method_name(method)
|
71
|
-
:"__#{method}_before_xstubbing"
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
class BlankObject
|
77
|
-
alias_method :__instance_eval__, :instance_eval
|
78
|
-
alias_method :__methods__, :methods
|
79
|
-
instance_methods.each {|m| undef_method m unless m =~ /^__.*__$/ }
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module CrossStub
|
2
|
-
|
3
|
-
private
|
4
|
-
|
5
|
-
module StubHelpers
|
6
|
-
|
7
|
-
def clear_stubs_for_current_process
|
8
|
-
if File.exists?(options[:file])
|
9
|
-
unapply_stubs ; delete_cache
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def apply_stubs_for_current_process(*args, &blk)
|
14
|
-
pk, args = PseudoClass.new(args[0]), args[1]
|
15
|
-
update_cache do |entire_cache|
|
16
|
-
hash = (args[0].is_a?(Hash) ? args[0] : args.inject({}){|h, k| h.merge(k => nil) })
|
17
|
-
cache = entire_cache[pk.id] || {}
|
18
|
-
cache = create_stub_from_hash(pk, cache, hash)
|
19
|
-
cache = create_stub_from_block(pk, cache, &blk) if block_given?
|
20
|
-
entire_cache.merge(pk.id => cache)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def apply_or_unapply_stubs_for_other_process
|
25
|
-
lambda {
|
26
|
-
unapply_stubs(load_backup_cache)
|
27
|
-
load_cache.each do |klass, hash|
|
28
|
-
pk = PseudoClass.new(klass)
|
29
|
-
hash.each {|method, codes| pk.replace_method(method, codes[:after]) }
|
30
|
-
end
|
31
|
-
}[] rescue nil
|
32
|
-
end
|
33
|
-
|
34
|
-
def unapply_stubs(cache=nil)
|
35
|
-
cache ||= load_cache
|
36
|
-
cache.each do |klass, hash|
|
37
|
-
pk = PseudoClass.new(klass)
|
38
|
-
hash.each do |method, codes|
|
39
|
-
codes[:before] ? pk.revert_method(method) : pk.remove_method(method)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def create_stub_from_hash(pk, cache, hash)
|
45
|
-
hash.inject(cache) do |cache, args|
|
46
|
-
method, value = args
|
47
|
-
is_method_implemented = pk.replace_method(method, value)
|
48
|
-
cache[method] ||= {:before => is_method_implemented}
|
49
|
-
cache[method][:after] = pk.method_code(method)
|
50
|
-
cache
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def create_stub_from_block(pk, cache, &blk)
|
55
|
-
pk.replace_methods(&blk).inject(cache) do |cache, args|
|
56
|
-
method, is_method_implemented = args
|
57
|
-
cache[method] ||= {:before => is_method_implemented}
|
58
|
-
cache[method][:after] = pk.method_code(method)
|
59
|
-
cache
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
-
|
3
|
-
describe 'Clearing Stubs' do
|
4
|
-
|
5
|
-
behaves_like 'has standard setup'
|
6
|
-
|
7
|
-
%w{current other}.each do |mode|
|
8
|
-
|
9
|
-
behaves_like "has #{mode} process setup"
|
10
|
-
|
11
|
-
%w{AnyClass AnyClass::Inner AnyModule AnyModule::Inner}.each do |klass_or_module|
|
12
|
-
|
13
|
-
before do
|
14
|
-
@context = @get_context[klass_or_module]
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should clear hash generated stub and return original value for #{klass_or_module} in #{mode} process" do
|
18
|
-
original_value = @context.say_world
|
19
|
-
@context.xstub(:say_world => 'i say world')
|
20
|
-
CrossStub.clear
|
21
|
-
@get_value["#{@context}.say_world"].should.equal original_value
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should clear hash generated stub and raise NoMethodError for #{klass_or_module} in #{mode} process" do
|
25
|
-
should.raise(NoMethodError) do
|
26
|
-
@context.xstub(:say_hello => 'i say hello')
|
27
|
-
CrossStub.clear
|
28
|
-
@get_value["#{@context}.say_hello"]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should clear symbol generated stub and return original value for #{klass_or_module} in #{mode} process" do
|
33
|
-
original_value = @context.say_world
|
34
|
-
@context.xstub(:say_world)
|
35
|
-
CrossStub.clear
|
36
|
-
@get_value["#{@context}.say_world"].should.equal original_value
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should clear symbol generated stub and raise NoMethodError for #{klass_or_module} in #{mode} process" do
|
40
|
-
should.raise(NoMethodError) do
|
41
|
-
@context.xstub(:say_hello)
|
42
|
-
CrossStub.clear
|
43
|
-
@get_value["#{@context}.say_hello"]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should clear block generated stub and return original value for #{klass_or_module} in #{mode} process" do
|
48
|
-
original_value = @context.say_world
|
49
|
-
@context.xstub do
|
50
|
-
def say_world ; 'i say world' ; end
|
51
|
-
end
|
52
|
-
CrossStub.clear
|
53
|
-
@get_value["#{@context}.say_world"].should.equal original_value
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should clear block generated stub and raise NoMethodError for #{klass_or_module} in #{mode} process" do
|
57
|
-
should.raise(NoMethodError) do
|
58
|
-
@context.xstub do
|
59
|
-
def say_hello ; 'i say hello' ; end
|
60
|
-
end
|
61
|
-
CrossStub.clear
|
62
|
-
@get_value["#{@context}.say_hello"]
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should always clear previously generated stub for #{klass_or_module} in #{mode} process" do
|
67
|
-
original_value = @context.say_world
|
68
|
-
|
69
|
-
# Stub an existing method
|
70
|
-
@context.xstub(:say_world => 'i say world')
|
71
|
-
@get_value["#{@context}.say_world"]
|
72
|
-
|
73
|
-
# Clear stubs without refreshing another process
|
74
|
-
CrossStub.clear
|
75
|
-
CrossStub.setup(:file => $cache_file)
|
76
|
-
|
77
|
-
# Stub a non-existing method
|
78
|
-
@context.xstub(:say_hello => 'i say hello')
|
79
|
-
@get_value["#{@context}.say_hello"]
|
80
|
-
|
81
|
-
# Make sure existing method returns to original method
|
82
|
-
@get_value["#{@context}.say_world"].should.equal original_value
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should always clear previously generated stub and raise NoMethodError for #{klass_or_module} in #{mode} process" do
|
86
|
-
# Stub a non-existing method
|
87
|
-
@context.xstub(:say_hello => 'i say hello')
|
88
|
-
@get_value["#{@context}.say_hello"]
|
89
|
-
|
90
|
-
# Clear stubs without refreshing another process
|
91
|
-
CrossStub.clear
|
92
|
-
CrossStub.setup(:file => $cache_file)
|
93
|
-
|
94
|
-
# Stub an existing method
|
95
|
-
@context.xstub(:say_world => 'i say world')
|
96
|
-
@get_value["#{@context}.say_world"]
|
97
|
-
|
98
|
-
# Make sure accessing non-existing method throws error
|
99
|
-
should.raise(NoMethodError) { @get_value["#{@context}.say_hello"] }
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should clear for method not implemented in ruby and return original value for #{klass_or_module} in #{mode} process" do
|
103
|
-
Time.xstub(:now => 'abc')
|
104
|
-
CrossStub.clear
|
105
|
-
value = nil
|
106
|
-
should.not.raise(NoMethodError) { value = @get_value['Time.now'] }
|
107
|
-
value.should.not.equal 'abc'
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
-
|
3
|
-
describe 'Creating Stubs' do
|
4
|
-
|
5
|
-
behaves_like 'has standard setup'
|
6
|
-
|
7
|
-
%w{current other}.each do |mode|
|
8
|
-
|
9
|
-
behaves_like "has #{mode} process setup"
|
10
|
-
|
11
|
-
%w{AnyClass AnyClass::Inner AnyModule AnyModule::Inner}.each do |klass_or_module|
|
12
|
-
|
13
|
-
before do
|
14
|
-
@context = @get_context[klass_or_module]
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should create with hash argument(s) for #{klass_or_module} class in #{mode} process" do
|
18
|
-
@context.xstub(:say_hello => 'i say hello', :say_world => 'i say world')
|
19
|
-
@get_value["#{@context}.say_hello"].should.equal 'i say hello'
|
20
|
-
@get_value["#{@context}.say_world"].should.equal 'i say world'
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should create with symbol argument(s) for #{klass_or_module} class in #{mode} process" do
|
24
|
-
@context.xstub(:say_hello)
|
25
|
-
@get_value["#{@context}.say_hello"].should.equal nil
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should create with block with no argument for #{klass_or_module} class in #{mode} process" do
|
29
|
-
@context.xstub do
|
30
|
-
def say_hello ; 'i say hello' ; end
|
31
|
-
end
|
32
|
-
@get_value["#{@context}.say_hello"].should.equal 'i say hello'
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should create with symbol & block with no argument for #{klass_or_module} class in #{mode} process" do
|
36
|
-
@context.xstub(:say_hello) do
|
37
|
-
def say_world
|
38
|
-
'i say world'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
@get_value["#{@context}.say_hello"].should.equal nil
|
42
|
-
@get_value["#{@context}.say_world"].should.equal 'i say world'
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should create with hash & block with no argument for #{klass_or_module} class in #{mode} process" do
|
46
|
-
@context.xstub(:say_hello => 'i say hello') do
|
47
|
-
def say_world
|
48
|
-
'i say world'
|
49
|
-
end
|
50
|
-
end
|
51
|
-
@get_value["#{@context}.say_hello"].should.equal 'i say hello'
|
52
|
-
@get_value["#{@context}.say_world"].should.equal 'i say world'
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should always create the most recent for #{klass_or_module} class in #{mode} process" do
|
56
|
-
found, expected = [], ['i say hello', 'i say something else', 'i say something else again']
|
57
|
-
stub_and_get_value = lambda do |value|
|
58
|
-
@context.xstub(:say_hello => value)
|
59
|
-
@get_value["#{@context}.say_hello"]
|
60
|
-
end
|
61
|
-
|
62
|
-
found << stub_and_get_value[expected[0]]
|
63
|
-
found << stub_and_get_value[expected[1]]
|
64
|
-
|
65
|
-
CrossStub.clear
|
66
|
-
CrossStub.setup(:file => $cache_file)
|
67
|
-
|
68
|
-
found << stub_and_get_value[expected[2]]
|
69
|
-
found.should.equal expected
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should create stub with dependency on other stub for #{klass_or_module} class in #{mode} process" do
|
73
|
-
@context.xstub(:something => 'hello') do
|
74
|
-
def do_action(who, action)
|
75
|
-
%\#{who} #{action} #{something}\
|
76
|
-
end
|
77
|
-
end
|
78
|
-
@get_value["#{@context}.do_action.i.say"].should.equal 'i say hello'
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should create for method not implemented in ruby for #{klass_or_module} class in #{mode} process" do
|
82
|
-
now = Time.now - 365*60*60*24
|
83
|
-
Time.xstub(:now => now)
|
84
|
-
@get_value['Time.now'].should.equal now
|
85
|
-
end
|
86
|
-
|
87
|
-
# it "should create with block that takes argument(s) for #{mode} process" do
|
88
|
-
# # a, b = 1, 2
|
89
|
-
# # AnyClass.xstub do |a, b|
|
90
|
-
# # def say_hello
|
91
|
-
# # "i say #{a+b} hellos"
|
92
|
-
# # end
|
93
|
-
# # end
|
94
|
-
# # AnyClass.say_hello.should.equal 'i say 3 hellos'
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# it "should create with hash & block that takes argument(s) for #{mode} process" do
|
98
|
-
# # a, b = 1, 2
|
99
|
-
# # AnyClass.xstub(:say_world => 'i say world') do |a, b|
|
100
|
-
# # def say_hello
|
101
|
-
# # "i say #{a+b} hellos"
|
102
|
-
# # end
|
103
|
-
# # end
|
104
|
-
# # AnyClass.say_hello.should.equal 'i say 3 hellos'
|
105
|
-
# # AnyClass.say_world.should.equal 'i say world'
|
106
|
-
# end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
-
|
3
|
-
describe 'Stubbing Error' do
|
4
|
-
|
5
|
-
behaves_like 'has standard setup'
|
6
|
-
|
7
|
-
it 'should not be raised when stubbing module' do
|
8
|
-
should.not.raise(CrossStub::Error) {
|
9
|
-
AnyModule.xstub(:say_hello => 'i say hello')
|
10
|
-
}
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should not be raised when stubbing class' do
|
14
|
-
should.not.raise(CrossStub::Error) {
|
15
|
-
AnyClass.xstub(:say_hello => 'i say hello')
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should not be raised when stubbing nested class' do
|
20
|
-
should.not.raise(CrossStub::Error) {
|
21
|
-
AnyClass::Inner.xstub(:say_hello => 'i say hello')
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should not be raised when stubbing nested module' do
|
26
|
-
should.not.raise(CrossStub::Error) {
|
27
|
-
AnyModule::Inner.xstub(:say_hello => 'i say hello')
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'should be raised when stubbing instance' do
|
32
|
-
should.raise(CrossStub::CannotStubInstanceError) do
|
33
|
-
o = AnyClass.new
|
34
|
-
o.xstub(:say_hello => 'i say hello')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
data/spec/helpers.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'eventmachine'
|
3
|
-
|
4
|
-
$cache_file = File.join(File.dirname(__FILE__), '..', 'tmp', 'stubbing.cache')
|
5
|
-
$log_file = File.join(File.dirname(__FILE__), '..', 'tmp', 'echoserver.log')
|
6
|
-
$sleep_time = 1.5 # may need to increase this depending on ur machine's prowess
|
7
|
-
|
8
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
|
-
require 'cross-stub'
|
10
|
-
|
11
|
-
class AnyClass
|
12
|
-
def self.say_world
|
13
|
-
'u say world'
|
14
|
-
end
|
15
|
-
class Inner
|
16
|
-
def self.say_world
|
17
|
-
'u say world'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module AnyModule
|
23
|
-
def self.say_world
|
24
|
-
'u say world'
|
25
|
-
end
|
26
|
-
module Inner
|
27
|
-
def self.say_world
|
28
|
-
'u say world'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
module EchoClient
|
34
|
-
|
35
|
-
class << self
|
36
|
-
|
37
|
-
attr_accessor :result
|
38
|
-
|
39
|
-
def get(klass_and_method)
|
40
|
-
address, port = EchoServer::ADDRESS, EchoServer::PORT
|
41
|
-
EventMachine::run do
|
42
|
-
(EventMachine::connect(address, port, EM)).
|
43
|
-
execute(klass_and_method) {|data| self.result = Marshal.load(data) }
|
44
|
-
end
|
45
|
-
self.result
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
module EM
|
53
|
-
def receive_data(data)
|
54
|
-
@callback[data]
|
55
|
-
EventMachine::stop_event_loop
|
56
|
-
end
|
57
|
-
def execute(method, &blk)
|
58
|
-
@callback = blk
|
59
|
-
send_data method
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
module EchoServer
|
66
|
-
|
67
|
-
ADDRESS, PORT = '127.0.0.1', 8081
|
68
|
-
|
69
|
-
class << self
|
70
|
-
|
71
|
-
def pid
|
72
|
-
@process.pid
|
73
|
-
end
|
74
|
-
|
75
|
-
def start(other_process=false)
|
76
|
-
unless other_process
|
77
|
-
@process = IO.popen("ruby #{__FILE__}")
|
78
|
-
sleep $sleep_time
|
79
|
-
else
|
80
|
-
EventMachine::run { EventMachine::start_server(ADDRESS, PORT, EM) }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def stop
|
85
|
-
Process.kill('SIGHUP', pid)
|
86
|
-
end
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
module EM
|
93
|
-
def receive_data(klass_and_method)
|
94
|
-
log "(1) EchoServer::EM#receive_data ... receives: #{klass_and_method}"
|
95
|
-
CrossStub.refresh(:file => $cache_file)
|
96
|
-
log "(2) EchoServer::EM#receive_data ... completes stubs refresh"
|
97
|
-
klass, method, *args = klass_and_method.split('.')
|
98
|
-
konst = klass.split(/::/).inject(Object) { |const_train, const| const_train.const_get(const) }
|
99
|
-
log "(3) EchoServer::EM#receive_data ... parses arguments to:",
|
100
|
-
" * klass ... #{klass}",
|
101
|
-
" * method ... #{method}",
|
102
|
-
" * args ... #{args.inspect}"
|
103
|
-
value = args.empty? ? konst.send(method) :
|
104
|
-
konst.send(method, *args) rescue $!.message
|
105
|
-
log "(4) EchoServer::EM#receive_data ... returns: #{value.inspect}"
|
106
|
-
send_data(Marshal.dump(value))
|
107
|
-
log "(5) EchoServer::EM#receive_data ... end"
|
108
|
-
end
|
109
|
-
|
110
|
-
def log(*msg)
|
111
|
-
$logger << [msg, ""].flatten.join("\n")
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
if $0 == __FILE__
|
118
|
-
begin
|
119
|
-
require 'logger'
|
120
|
-
$logger = Logger.new($log_file)
|
121
|
-
EchoServer.start(true)
|
122
|
-
ensure
|
123
|
-
$logger.close
|
124
|
-
end
|
125
|
-
end
|