commute 0.2.0.rc.2 → 0.3.0.pre
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/.todo +28 -12
- data/README.md +0 -1
- data/commute.gemspec +4 -5
- data/lib/commute/common/basic_auth.rb +10 -9
- data/lib/commute/common/caching.rb +208 -0
- data/lib/commute/common/chemicals.rb +47 -24
- data/lib/commute/common/eventmachine.rb +68 -0
- data/lib/commute/common/synchrony.rb +42 -0
- data/lib/commute/common/typhoeus.rb +64 -0
- data/lib/commute/core/api.rb +42 -29
- data/lib/commute/core/builder.rb +4 -15
- data/lib/commute/core/context.rb +156 -15
- data/lib/commute/core/http.rb +124 -0
- data/lib/commute/core/layer.rb +187 -0
- data/lib/commute/core/sequence.rb +83 -132
- data/lib/commute/core/stack.rb +63 -72
- data/lib/commute/core/status.rb +45 -0
- data/lib/commute/core/util/event_emitter.rb +58 -0
- data/lib/commute/core/util/path.rb +37 -0
- data/lib/commute/core/util/stream.rb +141 -0
- data/lib/commute/extensions/crud.rb +88 -0
- data/lib/commute/extensions/param.rb +20 -0
- data/lib/commute/extensions/url.rb +53 -0
- data/lib/commute/version.rb +1 -1
- data/spec/commute/common/caching_spec.rb +158 -0
- data/spec/commute/common/eventmachine_spec.rb +74 -0
- data/spec/commute/common/typhoeus_spec.rb +67 -0
- data/spec/commute/core/api_spec.rb +3 -1
- data/spec/commute/core/builder_spec.rb +8 -8
- data/spec/commute/core/http_spec.rb +39 -0
- data/spec/commute/core/layer_spec.rb +81 -0
- data/spec/commute/core/sequence_spec.rb +36 -150
- data/spec/commute/core/stack_spec.rb +33 -83
- data/spec/commute/core/util/event_emitter_spec.rb +35 -0
- data/spec/commute/core/util/path_spec.rb +29 -0
- data/spec/commute/core/util/stream_spec.rb +90 -0
- data/spec/commute/extensions/url_spec.rb +76 -0
- data/spec/spec_helper.rb +3 -1
- metadata +61 -48
- data/examples/gist_api.rb +0 -71
- data/examples/highrise_task_api.rb +0 -59
- data/examples/pastie_api.rb +0 -18
- data/lib/commute/aspects/caching.rb +0 -37
- data/lib/commute/aspects/crud.rb +0 -41
- data/lib/commute/aspects/pagination.rb +0 -16
- data/lib/commute/aspects/url.rb +0 -57
- data/lib/commute/common/cache.rb +0 -43
- data/lib/commute/common/conditional.rb +0 -27
- data/lib/commute/common/em-synchrony_adapter.rb +0 -29
- data/lib/commute/common/em_http_request_adapter.rb +0 -57
- data/lib/commute/common/typhoeus_adapter.rb +0 -40
- data/lib/commute/common/xml.rb +0 -7
- data/lib/commute/core/commuter.rb +0 -116
- data/lib/commute/core/processors/code_status_processor.rb +0 -40
- data/lib/commute/core/processors/hook.rb +0 -14
- data/lib/commute/core/processors/request_builder.rb +0 -26
- data/lib/commute/core/processors/sequencer.rb +0 -46
- data/lib/commute/core/request.rb +0 -58
- data/lib/commute/core/response.rb +0 -18
- data/spec/commute/aspects/caching_spec.rb +0 -12
- data/spec/commute/aspects/url_spec.rb +0 -61
- data/spec/commute/core/commuter_spec.rb +0 -64
- data/spec/commute/core/processors/code_status_processor_spec.rb +0 -5
- data/spec/commute/core/processors/hook_spec.rb +0 -25
- data/spec/commute/core/processors/request_builder_spec.rb +0 -25
- data/spec/commute/core/processors/sequencer_spec.rb +0 -33
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'commute/core/http'
|
4
|
+
|
5
|
+
describe Commute::Http::Status do
|
6
|
+
|
7
|
+
Status = Commute::Http::Status
|
8
|
+
|
9
|
+
it 'should be a failure for 4xx and 5xx status codes' do
|
10
|
+
Status.new(420).fail?.must_equal true
|
11
|
+
Status.new(501).fail?.must_equal true
|
12
|
+
Status.new(501).success?.must_equal false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should be a success otherwise' do
|
16
|
+
Status.new(200).success?.must_equal true
|
17
|
+
Status.new(200).fail?.must_equal false
|
18
|
+
Status.new(301).success?.must_equal true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Commute::Http::Request do
|
23
|
+
|
24
|
+
it 'should have some default values' do
|
25
|
+
request = Commute::Http::Request.new nil
|
26
|
+
request.uri.path.must_equal '/'
|
27
|
+
request.headers.must_be_empty
|
28
|
+
request.query.must_be_empty
|
29
|
+
request.method.must_equal :get
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should keep uri#query consistent' do
|
33
|
+
request = Commute::Http::Request.new nil
|
34
|
+
request.query[:limit] = 10
|
35
|
+
request.uri.query.must_equal 'limit%3D10'
|
36
|
+
request.query[:index] = 20
|
37
|
+
request.uri.query.must_equal 'limit%3D10%26index%3D20'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'commute/core/builder'
|
4
|
+
require 'commute/core/http'
|
5
|
+
require 'commute/core/util/path'
|
6
|
+
require 'commute/core/layer'
|
7
|
+
|
8
|
+
describe Commute::Layer do
|
9
|
+
|
10
|
+
it 'should have a name' do
|
11
|
+
layer = Commute::Layer.new proc {}, :test
|
12
|
+
layer.name.must_equal :test
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should figure out the name is none was given' do
|
16
|
+
# With an instance var.
|
17
|
+
klass = Class.new do
|
18
|
+
@name = :test
|
19
|
+
end
|
20
|
+
layer = Commute::Layer.new klass.new
|
21
|
+
layer.name.must_equal :test
|
22
|
+
# With a method.
|
23
|
+
klass = Class.new do
|
24
|
+
def name; :test; end
|
25
|
+
end
|
26
|
+
layer = Commute::Layer.new klass.new
|
27
|
+
layer.name.must_equal :test
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#call' do
|
31
|
+
|
32
|
+
it 'should auto-add context options to the options hash' do
|
33
|
+
context = Commute::Context.new(nil).with auth: { key: 'secret' }
|
34
|
+
request = Commute::Layer::Request.new Commute::Http::Request.new(context)
|
35
|
+
callable = mock
|
36
|
+
router = mock
|
37
|
+
callable.expects(:call).with(router, request, key: 'secret')
|
38
|
+
Commute::Layer.new(callable, :auth).call router, request
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#callable' do
|
43
|
+
let(:context) { Commute::Context.new(nil) }
|
44
|
+
|
45
|
+
it 'should return false if the layer is disabled' do
|
46
|
+
Commute::Layer.new(proc {}, :test).callable?(context.disable(:test).context).must_equal false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should return false if the layer has no callable' do
|
50
|
+
Commute::Layer.new(nil, :test).callable?(context).must_equal false
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return true otherwise' do
|
54
|
+
Commute::Layer.new(proc {}, :test).callable?(context).must_equal true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Commute::Layer::Communication do
|
60
|
+
|
61
|
+
it 'should hold an underlaying http request/response' do
|
62
|
+
http = Commute::Http::Request.new(nil)
|
63
|
+
Commute::Layer::Request.new(http).http.must_equal http
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Commute::Layer::Request do
|
68
|
+
|
69
|
+
it 'should be respondable' do
|
70
|
+
receiver = proc {}
|
71
|
+
http_request = Commute::Http::Request.new(nil)
|
72
|
+
request = Commute::Layer::Request.new(http_request)
|
73
|
+
http_response = Commute::Http::Response.new(request)
|
74
|
+
status = Commute::Status.ok
|
75
|
+
request.on(:response, &receiver)
|
76
|
+
receiver.expects(:call).with do |response, _status|
|
77
|
+
response.http == http_response && _status == status
|
78
|
+
end
|
79
|
+
request.respond http_response, status
|
80
|
+
end
|
81
|
+
end
|
@@ -3,188 +3,74 @@ require 'commute/core/sequence'
|
|
3
3
|
|
4
4
|
describe Commute::Sequence do
|
5
5
|
|
6
|
-
let(:sequence) { Commute::Sequence.new }
|
6
|
+
let(:sequence) { Commute::Sequence.new(:test) }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
let(:processor2) {
|
13
|
-
lambda { |result, subject, options = {}| result * 2 }
|
14
|
-
}
|
15
|
-
|
16
|
-
let(:processor3) {
|
17
|
-
Class.new {
|
18
|
-
@id = :test
|
19
|
-
|
20
|
-
def call result, subject, options = {}
|
21
|
-
result ** options[:power]
|
22
|
-
end
|
23
|
-
}.new
|
24
|
-
}
|
8
|
+
it 'should have a name' do
|
9
|
+
sequence.name.must_equal :test
|
10
|
+
end
|
25
11
|
|
26
12
|
describe '#new' do
|
13
|
+
it 'should be empty' do
|
14
|
+
sequence.size.must_equal 0
|
15
|
+
end
|
16
|
+
|
27
17
|
it 'should alter the sequence when a block is provided' do
|
28
|
-
|
29
|
-
s.append
|
30
|
-
|
31
|
-
|
18
|
+
Commute::Sequence.new(:test) { |s|
|
19
|
+
s.append proc {}
|
20
|
+
}.size.must_equal 1
|
21
|
+
Commute::Sequence.new(:test) {
|
22
|
+
append proc {}
|
23
|
+
append proc {}
|
24
|
+
}.size.must_equal 2
|
32
25
|
end
|
33
26
|
end
|
34
27
|
|
35
28
|
describe '#alter' do
|
36
29
|
it 'should alter the sequence in a block when the arity is 1' do
|
37
|
-
sequence.alter
|
38
|
-
s.append
|
39
|
-
|
40
|
-
sequence.processors.size.must_equal 1
|
30
|
+
sequence.alter { |s|
|
31
|
+
s.append proc {}
|
32
|
+
}.size.must_equal 1
|
41
33
|
end
|
42
34
|
|
43
35
|
it 'should evaluate the block when the arity is 0' do
|
44
|
-
sequence.alter
|
45
|
-
append
|
46
|
-
|
47
|
-
sequence.processors.size.must_equal 1
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe '#processors' do
|
52
|
-
it 'should return an empty array when there are no processors' do
|
53
|
-
sequence.processors.must_equal []
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'should not return a modifiable array' do
|
57
|
-
sequence.processors << 'test'
|
58
|
-
sequence.processors.must_be_empty
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '#processors=' do
|
63
|
-
|
64
|
-
it 'should not exist' do
|
65
|
-
Proc.new { sequence.processors = nil }.must_raise NoMethodError
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe '#call' do
|
70
|
-
let(:processor1) do
|
71
|
-
Proc.new do |commuter|
|
72
|
-
commuter.change { |n| n+1 }
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
let(:processor2) do
|
77
|
-
Proc.new do |commuter, operation|
|
78
|
-
commuter.change { |n| n.send operation, n }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
let(:commuter) { Commute::Commuter.new mock, 1 }
|
83
|
-
|
84
|
-
it 'should call all processors' do
|
85
|
-
commuter.expects(:parameters).with(nil).never
|
86
|
-
commuter.expects(:parameters).with(:operator).returns(:**)
|
87
|
-
sequence.append(processor1)
|
88
|
-
sequence.append(processor2, as: :operator)
|
89
|
-
sequence.call commuter
|
90
|
-
commuter.get.must_equal 4
|
91
|
-
end
|
92
|
-
|
93
|
-
# This is not tested implicitely due to the Proc usage.
|
94
|
-
it 'should call processors with the correct number of arguments' do
|
95
|
-
commuter.expects(:parameters).with(:operator).returns(:+)
|
96
|
-
processor1 = mock
|
97
|
-
processor1.expects(:call).with(commuter)
|
98
|
-
processor2 = mock
|
99
|
-
processor2.expects(:call).with(commuter, :+)
|
100
|
-
sequence.append processor1
|
101
|
-
sequence.append processor2, as: :operator
|
102
|
-
sequence.call commuter
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'should be a processor itself' do
|
106
|
-
commuter.expects(:parameters).with(:operator).returns(:**)
|
107
|
-
|
108
|
-
subsequence = Commute::Sequence.new do |s|
|
109
|
-
s.append processor1
|
110
|
-
end
|
111
|
-
|
112
|
-
sequence = Commute::Sequence.new do |s|
|
113
|
-
s.append subsequence
|
114
|
-
s.append processor2, as: :operator
|
115
|
-
end
|
116
|
-
|
117
|
-
sequence.call commuter
|
118
|
-
commuter.get.must_equal 4
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'should return nothing' do
|
122
|
-
Commute::Sequence.new { |s|
|
123
|
-
s.append processor1
|
124
|
-
}.call(commuter).must_equal nil
|
36
|
+
sequence.alter {
|
37
|
+
append proc {}
|
38
|
+
}.size.must_equal 1
|
125
39
|
end
|
126
40
|
end
|
127
41
|
|
128
42
|
describe '#append' do
|
129
43
|
it 'should append the processor to the tail' do
|
130
|
-
sequence.append
|
131
|
-
sequence.
|
132
|
-
|
133
|
-
sequence.
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'should be able to override the default processor id' do
|
137
|
-
sequence.append processor1, as: :increment
|
138
|
-
sequence.at(:increment).call(1, nil).must_equal 2
|
139
|
-
|
140
|
-
sequence.append processor3, as: :power
|
141
|
-
sequence.at(:power).must_equal processor3
|
44
|
+
layer1 = sequence.append proc {}
|
45
|
+
sequence.must_equal [layer1]
|
46
|
+
layer2 = sequence.append proc {}
|
47
|
+
sequence.must_equal [layer1, layer2]
|
142
48
|
end
|
143
49
|
|
144
50
|
it 'should be able to append after a specified processor' do
|
145
|
-
sequence.append
|
146
|
-
sequence.append
|
51
|
+
layer1 = sequence.append proc {}, as: :action1
|
52
|
+
layer3 = sequence.append proc {}
|
147
53
|
|
148
|
-
sequence.append
|
149
|
-
sequence.
|
54
|
+
layer2 = sequence.append proc {}, as: :action2, after: :action1
|
55
|
+
sequence.must_equal [layer1, layer2, layer3]
|
150
56
|
end
|
151
57
|
end
|
152
58
|
|
153
59
|
describe '#remove' do
|
154
60
|
before do
|
155
|
-
sequence.append
|
156
|
-
sequence.append
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'should remove the processor if the processor itself is given' do
|
160
|
-
processor = sequence.remove processor1
|
161
|
-
(processor == processor1).must_equal true
|
162
|
-
sequence.processors.must_equal [processor2]
|
163
|
-
assert_equal sequence.at(:multiplier), processor2
|
61
|
+
@layer1 = sequence.append proc {}
|
62
|
+
@layer2 = sequence.append proc {}, as: :action
|
164
63
|
end
|
165
64
|
|
166
65
|
it 'should remove the processor if its id is given' do
|
167
|
-
|
168
|
-
|
169
|
-
sequence.processors.must_equal [processor1]
|
170
|
-
sequence.at(:multiplier).must_be_nil
|
66
|
+
sequence.remove(:action).must_equal @layer2
|
67
|
+
sequence.must_equal [@layer1]
|
171
68
|
end
|
172
69
|
end
|
173
70
|
|
174
|
-
describe '#
|
175
|
-
it 'should
|
176
|
-
|
177
|
-
sequence.at(:test).must_equal processor3
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
describe '#dup' do
|
182
|
-
it 'should duplicate the sequence' do
|
183
|
-
sequence.append processor1
|
184
|
-
cloned = sequence.dup
|
185
|
-
cloned.append processor2
|
186
|
-
sequence.processors.size.must_equal 1
|
187
|
-
cloned.processors.size.must_equal 2
|
71
|
+
describe '#call' do
|
72
|
+
it 'should lazily push the sequence on the path' do
|
73
|
+
skip
|
188
74
|
end
|
189
75
|
end
|
190
76
|
end
|
@@ -4,93 +4,43 @@ require 'commute/core/stack'
|
|
4
4
|
|
5
5
|
describe Commute::Stack do
|
6
6
|
|
7
|
-
let(:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
7
|
+
let(:stack) { Commute::Stack.new }
|
8
|
+
|
9
|
+
# A Layer that forwards to the next.
|
10
|
+
let(:forward_layer) { proc { |router, request, options = {}|
|
11
|
+
request.pipe router.call(request.http) { |response, status|
|
12
|
+
response.pipe request.respond(response.http, status)
|
13
|
+
}
|
14
|
+
}}
|
15
|
+
|
16
|
+
# A layer that echoes all data.
|
17
|
+
let(:echo_layer) { proc { |router, request, options = {}|
|
18
|
+
request.pipe request.respond(Commute::Http::Response.new(request), Commute::Status.ok)
|
19
|
+
}}
|
20
|
+
|
21
|
+
describe '#call' do
|
22
|
+
describe 'with a forward and echo layer' do
|
23
|
+
it 'should echo all data' do
|
24
|
+
# Append a forward and echo layer to the main sequence.
|
25
|
+
stack.sequence do |s|
|
26
|
+
s.append forward_layer
|
27
|
+
s.append forward_layer
|
28
|
+
s.append stack.sequence(:echo)
|
23
29
|
end
|
24
|
-
stack.sequence
|
25
|
-
|
26
|
-
|
27
|
-
it 'should yield the stack and the main sequence when the arity is 2' do
|
28
|
-
stack = Commute::Stack.new do |stack, sequence|
|
29
|
-
sequence.append Proc.new {}
|
30
|
+
stack.sequence(:echo) do |s|
|
31
|
+
s.append echo_layer
|
30
32
|
end
|
31
|
-
stack.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
sequence = Commute::Sequence.new do
|
38
|
-
append Proc.new {}
|
39
|
-
end
|
40
|
-
stack = Commute::Stack.new sequence
|
41
|
-
stack.sequence.processors.size.must_equal 1
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe '#add' do
|
47
|
-
it 'should add a sequence to the stack by name' do
|
48
|
-
stack.add sequence, :calculation
|
49
|
-
stack.sequence(:calculation).must_equal sequence
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe '#sequence' do
|
54
|
-
it 'should add the sequence when it was not found' do
|
55
|
-
stack.sequence(:calculation) do
|
56
|
-
append Proc.new { |c| c.set(c.get + 1) }
|
57
|
-
end
|
58
|
-
|
59
|
-
stack.sequence(:calculation).processors.size.must_equal 1
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#sequencer' do
|
64
|
-
it 'should allow us to embed a sequence in a sequence' do
|
65
|
-
stack = Commute::Stack.new do |stack, sequence|
|
66
|
-
sequence.append Commute::Sequencer.new(:calculation)
|
67
|
-
sequence.append Proc.new { |c|
|
68
|
-
c.change { |n| "The result is #{n}" }
|
69
|
-
}
|
70
|
-
|
71
|
-
stack.sequence(:calculation) do
|
72
|
-
append Proc.new { |c| c.set(c.get + 1) }
|
73
|
-
append Proc.new { |c| c.set(c.get + 2) }
|
33
|
+
# Call the stack.
|
34
|
+
context = Commute::Context.new stack
|
35
|
+
request = stack.call Commute::Http::Request.new(context) do |response, status|
|
36
|
+
puts 'response!'
|
37
|
+
response.on(:data) { |chunk| puts chunk }
|
38
|
+
response.on(:end) { puts 'end!'}
|
74
39
|
end
|
40
|
+
request.write 1
|
41
|
+
request.write 2
|
42
|
+
request.end
|
75
43
|
end
|
76
|
-
commuter = Commute::Commuter.new(Commute::Context.new(stack), 1)
|
77
|
-
stack.call(commuter)
|
78
|
-
commuter.get.must_equal 'The result is 4'
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
describe '#dup' do
|
83
|
-
it 'should duplicate the stack and all its sequences' do
|
84
|
-
stack.add sequence, :calculation
|
85
|
-
cloned = stack.dup.alter do
|
86
|
-
sequence.append Proc.new {}
|
87
|
-
|
88
|
-
sequence(:calculation).append Proc.new {}
|
89
|
-
end
|
90
|
-
stack.sequence.processors.size.must_equal 0
|
91
|
-
stack.sequence(:calculation).processors.size.must_equal 1
|
92
|
-
cloned.sequence.processors.size.must_equal 1
|
93
|
-
cloned.sequence(:calculation).processors.size.must_equal 2
|
94
44
|
end
|
95
45
|
end
|
96
46
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'commute/core/util/event_emitter'
|
4
|
+
|
5
|
+
describe Commute::EventEmitter do
|
6
|
+
|
7
|
+
let(:emitter) {
|
8
|
+
Class.new { include Commute::EventEmitter }.new
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:handler1) { proc {} }
|
12
|
+
let(:handler2) { proc {} }
|
13
|
+
let(:handler3) { proc {} }
|
14
|
+
|
15
|
+
it 'should notify event handlers for one event' do
|
16
|
+
[handler1, handler2].each do |handler|
|
17
|
+
handler.expects(:call).with :test, 1
|
18
|
+
end
|
19
|
+
emitter.on :data, &handler1
|
20
|
+
emitter.on :data, &handler2
|
21
|
+
emitter.send :emit, :data, :test, 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should notify event handlers for multiple events' do
|
25
|
+
[handler1, handler2].each do |handler|
|
26
|
+
handler.expects(:call).with(:test, 1).once
|
27
|
+
end
|
28
|
+
handler3.expects(:call).once
|
29
|
+
emitter.on :data, &handler1
|
30
|
+
emitter.on :data, &handler2
|
31
|
+
emitter.on :end, &handler3
|
32
|
+
emitter.send :emit, :data, :test, 1
|
33
|
+
emitter.send :emit, :end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'commute/core/util/path'
|
3
|
+
|
4
|
+
describe Commute::Path do
|
5
|
+
|
6
|
+
Path = Commute::Path
|
7
|
+
|
8
|
+
describe 'with a single route' do
|
9
|
+
|
10
|
+
it 'should walk the entire route' do
|
11
|
+
path = Path.new([1,2,3].each)
|
12
|
+
[path.succ, path.succ, path.succ].must_equal [1,2,3]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'with one detour' do
|
17
|
+
|
18
|
+
it 'should walk the main route, the detour and the rest of the main route' do
|
19
|
+
router = Path.new([1,2,3].each)
|
20
|
+
router.succ.must_equal 1
|
21
|
+
router.succ.must_equal 2
|
22
|
+
router << ['a', 'b'].each
|
23
|
+
router.succ.must_equal 'a'
|
24
|
+
router.succ.must_equal 'b'
|
25
|
+
router.succ.must_equal 3
|
26
|
+
router.succ.must_equal nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'commute/core/util/stream'
|
4
|
+
|
5
|
+
describe Commute::Stream do
|
6
|
+
|
7
|
+
let(:stream) {
|
8
|
+
Class.new { include Commute::Stream }.new
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:handler) { proc {} }
|
12
|
+
|
13
|
+
describe '#new' do
|
14
|
+
it 'should be writeable' do
|
15
|
+
stream.writeable?.must_equal true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#write' do
|
20
|
+
it 'should write data to the stream' do
|
21
|
+
handler.expects(:call).twice
|
22
|
+
stream.on :data, &handler
|
23
|
+
stream.write 1
|
24
|
+
stream.write 2
|
25
|
+
stream.writeable?.must_equal true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#end' do
|
30
|
+
it 'should end the stream' do
|
31
|
+
data_handler = proc {}
|
32
|
+
end_handler = proc {}
|
33
|
+
stream.on :data, &data_handler
|
34
|
+
stream.on :end, &end_handler
|
35
|
+
data_handler.expects(:call).twice
|
36
|
+
end_handler.expects(:call).once
|
37
|
+
stream.write 1
|
38
|
+
stream.write 2
|
39
|
+
stream.end
|
40
|
+
stream.write(3).must_equal nil
|
41
|
+
stream.writeable?.must_equal false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#buffer' do
|
46
|
+
it 'should buffer all stream data when a buffer is given' do
|
47
|
+
buffer = []
|
48
|
+
stream >> buffer
|
49
|
+
0.upto(3) { |i| stream.write i }
|
50
|
+
stream.end
|
51
|
+
buffer.must_equal [0,1,2,3]
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should buffer all stream data when no buffer is given' do
|
55
|
+
stream.buffer do |buffer|
|
56
|
+
buffer.must_equal [0,1,2,3]
|
57
|
+
end
|
58
|
+
0.upto(3) { |i| stream.write i }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#pipe' do
|
63
|
+
it 'should pipe the stream to an other stream' do
|
64
|
+
destination = mock
|
65
|
+
streaming = sequence 'streaming'
|
66
|
+
destination.expects(:write).with(1).in_sequence streaming
|
67
|
+
destination.expects(:write).with(2).in_sequence streaming
|
68
|
+
destination.expects(:end).in_sequence streaming
|
69
|
+
stream.pipe destination
|
70
|
+
stream.write 1
|
71
|
+
stream.write 2
|
72
|
+
stream.end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#map' do
|
77
|
+
it 'should map all data in a stream' do
|
78
|
+
buffer = []
|
79
|
+
output = stream.
|
80
|
+
map { |i| i*2 }.
|
81
|
+
reject { |i| i % 3 == 0 }.
|
82
|
+
inject(0, &:+) >> buffer
|
83
|
+
1.upto(5) do |i|
|
84
|
+
stream.write i
|
85
|
+
end
|
86
|
+
stream.end
|
87
|
+
buffer.must_equal [24]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|