leadlight 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +9 -0
- data/Gemfile.lock +79 -0
- data/Guardfile +19 -0
- data/Rakefile +133 -0
- data/leadlight.gemspec +125 -0
- data/lib/leadlight.rb +92 -0
- data/lib/leadlight/blank.rb +15 -0
- data/lib/leadlight/codec.rb +63 -0
- data/lib/leadlight/enumerable_representation.rb +24 -0
- data/lib/leadlight/errors.rb +14 -0
- data/lib/leadlight/hyperlinkable.rb +126 -0
- data/lib/leadlight/link.rb +35 -0
- data/lib/leadlight/link_template.rb +47 -0
- data/lib/leadlight/representation.rb +30 -0
- data/lib/leadlight/request.rb +91 -0
- data/lib/leadlight/service.rb +73 -0
- data/lib/leadlight/service_middleware.rb +50 -0
- data/lib/leadlight/tint.rb +26 -0
- data/lib/leadlight/tint_helper.rb +67 -0
- data/lib/leadlight/type.rb +71 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/has_the_expected_content.yml +75 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml +75 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml +384 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members/.yml +309 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml +159 -0
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml +32 -0
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml +32 -0
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/should_be_a_204_no_content.yml +32 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/.yml +32 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/__location__/.yml +32 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/should_be_a_204_no_content.yml +32 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_user/has_the_expected_content.yml +65 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/.yml +100 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_able_to_follow_next_link.yml +135 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable.yml +275 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable_over_page_boundaries.yml +170 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_have_next_and_last_links.yml +100 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/exists.yml +32 -0
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/links_to_the_expected_URL.yml +32 -0
- data/spec/leadlight/codec_spec.rb +93 -0
- data/spec/leadlight/hyperlinkable_spec.rb +136 -0
- data/spec/leadlight/link_spec.rb +53 -0
- data/spec/leadlight/link_template_spec.rb +45 -0
- data/spec/leadlight/representation_spec.rb +62 -0
- data/spec/leadlight/request_spec.rb +236 -0
- data/spec/leadlight/service_middleware_spec.rb +81 -0
- data/spec/leadlight/service_spec.rb +127 -0
- data/spec/leadlight/tint_helper_spec.rb +132 -0
- data/spec/leadlight/type_spec.rb +137 -0
- data/spec/leadlight_spec.rb +237 -0
- data/spec/spec_helper_lite.rb +6 -0
- data/spec/support/credentials.rb +16 -0
- data/spec/support/vcr.rb +18 -0
- metadata +229 -0
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'spec_helper_lite'
|
2
|
+
require 'leadlight/request'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
module Leadlight
|
6
|
+
describe Request do
|
7
|
+
include Timeout
|
8
|
+
|
9
|
+
|
10
|
+
# The Faraday connection API works like this:
|
11
|
+
#
|
12
|
+
# connection.run_request(:get, ...).on_complete do |env|
|
13
|
+
# ...
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# TODO stick a facade over Faraday instead of stubbing stuff I
|
17
|
+
# don't own
|
18
|
+
class FakeFaradayResponse
|
19
|
+
fattr(:completion_handlers) { Queue.new }
|
20
|
+
attr_reader :env
|
21
|
+
|
22
|
+
def initialize(env)
|
23
|
+
@env = env
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_complete(&block)
|
27
|
+
completion_handlers << block
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_completion_handlers(n=1)
|
31
|
+
n.times do
|
32
|
+
completion_handlers.pop.call(@env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
subject { Request.new(connection, url, http_method, params, body) }
|
38
|
+
let(:connection) { stub(:connection, :run_request => faraday_response) }
|
39
|
+
let(:url) { stub(:url) }
|
40
|
+
let(:http_method){ :get }
|
41
|
+
let(:body) { stub(:body) }
|
42
|
+
let(:params) { {} }
|
43
|
+
let(:faraday_request) {stub(:faraday_request)}
|
44
|
+
let(:on_complete_handlers) { [] }
|
45
|
+
let(:faraday_response) { FakeFaradayResponse.new(faraday_env) }
|
46
|
+
let(:faraday_env) { {:leadlight_representation => representation} }
|
47
|
+
let(:representation) { stub(:representation) }
|
48
|
+
|
49
|
+
def run_completion_handlers
|
50
|
+
faraday_response.run_completion_handlers
|
51
|
+
end
|
52
|
+
|
53
|
+
def do_it_and_complete(&block)
|
54
|
+
t = Thread.new do
|
55
|
+
do_it(&block)
|
56
|
+
end
|
57
|
+
run_completion_handlers
|
58
|
+
t.join.value
|
59
|
+
end
|
60
|
+
|
61
|
+
context "for GET" do
|
62
|
+
let(:http_method) { :get }
|
63
|
+
|
64
|
+
its(:http_method) { should eq(:get) }
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
context "for POST" do
|
69
|
+
let(:http_method) { :post }
|
70
|
+
|
71
|
+
its(:http_method) { should eq(:post) }
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#submit" do
|
75
|
+
it "starts a request runnning" do
|
76
|
+
connection.should_receive(:run_request).
|
77
|
+
with(http_method, url, body, {}).
|
78
|
+
and_return(faraday_response)
|
79
|
+
subject.submit
|
80
|
+
end
|
81
|
+
|
82
|
+
it "triggers the on_prepare_request hook in the block passed to #run_request" do
|
83
|
+
yielded = :nothing
|
84
|
+
faraday_request = stub
|
85
|
+
connection.stub(:run_request).
|
86
|
+
and_yield(faraday_request).
|
87
|
+
and_return(faraday_response)
|
88
|
+
subject.on_prepare_request do |request|
|
89
|
+
yielded = request
|
90
|
+
end
|
91
|
+
subject.submit
|
92
|
+
yielded.should equal(faraday_request)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
shared_examples_for "synchronous methods" do
|
98
|
+
it "returns once the request has completed" do
|
99
|
+
timeout(1) do
|
100
|
+
trace = Queue.new
|
101
|
+
thread = Thread.new do
|
102
|
+
do_it
|
103
|
+
trace << "wait finished"
|
104
|
+
end
|
105
|
+
trace << "completing request"
|
106
|
+
faraday_response.run_completion_handlers
|
107
|
+
thread.join
|
108
|
+
trace << "request completed"
|
109
|
+
trace.pop.should eq("completing request")
|
110
|
+
trace.pop.should eq("wait finished")
|
111
|
+
trace.pop.should eq("request completed")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#wait" do
|
117
|
+
context "before a submit" do
|
118
|
+
it "doesn't return until after the submit" do
|
119
|
+
timeout(1) do
|
120
|
+
trace = Queue.new
|
121
|
+
thread = Thread.new do
|
122
|
+
subject.wait
|
123
|
+
trace << "wait finished"
|
124
|
+
end
|
125
|
+
trace << "submit"
|
126
|
+
subject.submit
|
127
|
+
trace << "completing request"
|
128
|
+
faraday_response.run_completion_handlers
|
129
|
+
thread.join
|
130
|
+
trace << "request completed"
|
131
|
+
trace.pop.should eq("submit")
|
132
|
+
trace.pop.should eq("completing request")
|
133
|
+
trace.pop.should eq("wait finished")
|
134
|
+
trace.pop.should eq("request completed")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "after a submit" do
|
140
|
+
before do
|
141
|
+
subject.submit
|
142
|
+
end
|
143
|
+
|
144
|
+
def do_it
|
145
|
+
subject.wait
|
146
|
+
end
|
147
|
+
|
148
|
+
it_should_behave_like "synchronous methods"
|
149
|
+
|
150
|
+
it "returns self" do
|
151
|
+
do_it_and_complete.should equal(subject)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#submit_and_wait" do
|
158
|
+
def do_it(&block)
|
159
|
+
subject.submit_and_wait(&block)
|
160
|
+
end
|
161
|
+
|
162
|
+
it_should_behave_like "synchronous methods"
|
163
|
+
|
164
|
+
it "returns self" do
|
165
|
+
do_it_and_complete.should equal(subject)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "yields the response representation" do
|
169
|
+
yielded = :nothing
|
170
|
+
do_it_and_complete do |rep|
|
171
|
+
yielded = rep
|
172
|
+
end
|
173
|
+
yielded.should equal(representation)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#on_complete" do
|
178
|
+
def submit_and_complete
|
179
|
+
t = Thread.new do
|
180
|
+
subject.submit
|
181
|
+
subject.wait
|
182
|
+
end
|
183
|
+
run_completion_handlers
|
184
|
+
t.join
|
185
|
+
end
|
186
|
+
|
187
|
+
it "queues hooks to be run on completion" do
|
188
|
+
run_hooks = []
|
189
|
+
subject.on_complete do |response|
|
190
|
+
run_hooks << "hook 1"
|
191
|
+
end
|
192
|
+
subject.on_complete do |response|
|
193
|
+
run_hooks << "hook 2"
|
194
|
+
end
|
195
|
+
submit_and_complete
|
196
|
+
run_hooks.should eq(["hook 1", "hook 2"])
|
197
|
+
end
|
198
|
+
|
199
|
+
it "calls hooks with the faraday response" do
|
200
|
+
Faraday::Response.should_receive(:new).with(faraday_env).
|
201
|
+
and_return(faraday_response)
|
202
|
+
yielded = :nothing
|
203
|
+
subject.on_complete do |response|
|
204
|
+
yielded = response
|
205
|
+
end
|
206
|
+
submit_and_complete
|
207
|
+
yielded.should equal(faraday_response)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
describe "#raise_on_error" do
|
213
|
+
def submit_and_complete
|
214
|
+
t = Thread.new do
|
215
|
+
subject.submit
|
216
|
+
subject.wait
|
217
|
+
end
|
218
|
+
run_completion_handlers
|
219
|
+
t.join
|
220
|
+
subject
|
221
|
+
end
|
222
|
+
|
223
|
+
it "raises an error when the response is a client error" do
|
224
|
+
faraday_env[:status] = 404
|
225
|
+
expect { submit_and_complete.raise_on_error }.to raise_error(ResourceNotFound)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "raises after completion when called before completion" do
|
229
|
+
faraday_env[:status] = 500
|
230
|
+
subject.raise_on_error
|
231
|
+
expect { submit_and_complete }.to raise_error(ServerError)
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper_lite'
|
2
|
+
require 'leadlight/service_middleware'
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module Leadlight
|
6
|
+
describe ServiceMiddleware do
|
7
|
+
let(:test_stack) {
|
8
|
+
Faraday.new(url: 'http://example.com') do |b|
|
9
|
+
b.use described_class, service: service
|
10
|
+
b.adapter :test, faraday_stubs
|
11
|
+
end
|
12
|
+
}
|
13
|
+
|
14
|
+
subject { described_class.new(app, service: service) }
|
15
|
+
let(:service) { stub(url: 'http://example.com', tints: []) }
|
16
|
+
let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new }
|
17
|
+
let(:app) { ->(env){stub(on_complete: nil)} }
|
18
|
+
let(:response) { [200, {}, ''] }
|
19
|
+
let(:result_env) {
|
20
|
+
test_stack.get('/').env
|
21
|
+
}
|
22
|
+
let(:representation) { result_env[:leadlight_representation] }
|
23
|
+
|
24
|
+
before do
|
25
|
+
faraday_stubs.get('/') {response}
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'adds :leadlight_service to env before app' do
|
29
|
+
test_stack.get('/').env[:leadlight_service].should equal(service)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'extends the representation with Representation' do
|
33
|
+
representation.should be_a(Representation)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'makes the representation hyperlinkable' do
|
37
|
+
representation.should be_a(Hyperlinkable)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'requests JSON, then YAML, then XML, then HTML' do
|
41
|
+
result_env[:request_headers]['Accept'].
|
42
|
+
should eq('application/json, text/x-yaml, application/xml, application/xhtml+xml, text/html, text/plain')
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with a no-content response' do
|
46
|
+
let(:response) { [204, {}, ''] }
|
47
|
+
let(:result_env) {
|
48
|
+
test_stack.get('/').env
|
49
|
+
}
|
50
|
+
|
51
|
+
it 'sets :leadlight_representation to a Blank' do
|
52
|
+
result_env[:leadlight_representation].should be_a(Blank)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with a blank JSON response' do
|
57
|
+
let(:response) {
|
58
|
+
[200, {'Content-Type' => 'application/json', 'Content-Length' => '0'}, '']
|
59
|
+
}
|
60
|
+
let(:result_env) {
|
61
|
+
test_stack.get('/').env
|
62
|
+
}
|
63
|
+
|
64
|
+
it 'sets :leadlight_representation to a Blank' do
|
65
|
+
result_env[:leadlight_representation].should be_a(Blank)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with a non-blank JSON response' do
|
70
|
+
let(:response) {
|
71
|
+
[200, {'Content-Type' => 'application/json', 'Content-Length' => '7'}, '[1,2,3]']
|
72
|
+
}
|
73
|
+
let(:result_env) {
|
74
|
+
test_stack.get('/').env
|
75
|
+
}
|
76
|
+
it 'sets :leadlight_representation to the result of parsing the JSON' do
|
77
|
+
result_env[:leadlight_representation].should eq([1,2,3])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'spec_helper_lite'
|
2
|
+
require 'leadlight/service'
|
3
|
+
|
4
|
+
module Leadlight
|
5
|
+
describe Service do
|
6
|
+
subject { klass.new(service_options) }
|
7
|
+
let(:klass) { Class.new do include Service end }
|
8
|
+
let(:connection) { stub(:connection, get: response) }
|
9
|
+
let(:representation) { stub(:representation) }
|
10
|
+
let(:response) { stub(:response, env: env) }
|
11
|
+
let(:env) { {leadlight_representation: representation} }
|
12
|
+
let(:service_options) { {codec: codec} }
|
13
|
+
let(:codec) { stub(:codec) }
|
14
|
+
let(:request) { stub(:request).as_null_object }
|
15
|
+
|
16
|
+
before do
|
17
|
+
subject.stub(connection: connection, url: nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples_for "an HTTP client" do |http_method|
|
21
|
+
describe "##{http_method}" do
|
22
|
+
before do
|
23
|
+
Request.stub(:new).and_return(request)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns a new request object' do
|
27
|
+
Request.should_receive(:new).and_return(request)
|
28
|
+
subject.public_send(http_method, '/').should equal(request)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'passes the connection to the request' do
|
32
|
+
Request.should_receive(:new).
|
33
|
+
with(connection, anything, anything, anything, anything).
|
34
|
+
and_return(request)
|
35
|
+
subject.public_send(http_method, '/somepath')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'passes the path to the request' do
|
39
|
+
Request.should_receive(:new).
|
40
|
+
with(anything, '/somepath', anything, anything, anything).
|
41
|
+
and_return(request)
|
42
|
+
subject.public_send(http_method, '/somepath')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'passes the method to the request' do
|
46
|
+
Request.should_receive(:new).
|
47
|
+
with(anything, anything, http_method, anything, anything).
|
48
|
+
and_return(request)
|
49
|
+
subject.public_send(http_method, '/somepath')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'passes the params to the request' do
|
53
|
+
params = stub
|
54
|
+
Request.should_receive(:new).
|
55
|
+
with(anything, anything, anything, params, anything).
|
56
|
+
and_return(request)
|
57
|
+
subject.public_send(http_method, '/somepath', params)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'passes the body to the request' do
|
61
|
+
body = stub
|
62
|
+
Request.should_receive(:new).
|
63
|
+
with(anything, anything, anything, anything, body).
|
64
|
+
and_return(request)
|
65
|
+
subject.public_send(http_method, '/somepath', {}, body)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'adds a prepare_request callback' do
|
69
|
+
faraday_request = stub(:faraday_request)
|
70
|
+
request.stub(:on_prepare_request).and_yield(faraday_request)
|
71
|
+
subject.should_receive(:prepare_request).with(faraday_request)
|
72
|
+
subject.public_send(http_method, '/')
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'given a block' do
|
76
|
+
define_method(:do_it) do
|
77
|
+
subject.public_send(http_method, '/') do |yielded|
|
78
|
+
return yielded
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'submits and waits for completion' do
|
83
|
+
request.should_receive(:submit_and_wait).and_yield(representation)
|
84
|
+
do_it
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it_behaves_like "an HTTP client", :head
|
91
|
+
it_behaves_like "an HTTP client", :get
|
92
|
+
it_behaves_like "an HTTP client", :post
|
93
|
+
it_behaves_like "an HTTP client", :put
|
94
|
+
it_behaves_like "an HTTP client", :delete
|
95
|
+
it_behaves_like "an HTTP client", :patch
|
96
|
+
it_behaves_like "an HTTP client", :options
|
97
|
+
|
98
|
+
describe '#service_options' do
|
99
|
+
it 'returns option values passed to the initializer' do
|
100
|
+
it = klass.new(foo: 42, bar: 'baz')
|
101
|
+
it.service_options.should eq(foo: 42, bar: 'baz')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#encode' do
|
106
|
+
it 'delegates to the codec' do
|
107
|
+
entity = stub
|
108
|
+
codec.should_receive(:encode).
|
109
|
+
with('CONTENT_TYPE', representation, {foo: 'bar'}).
|
110
|
+
and_return(entity)
|
111
|
+
subject.encode('CONTENT_TYPE', representation, {foo: 'bar'}).
|
112
|
+
should equal(entity)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#decode' do
|
117
|
+
it 'delegates to the codec' do
|
118
|
+
entity = stub
|
119
|
+
codec.should_receive(:decode).
|
120
|
+
with('CONTENT_TYPE', entity, {foo: 'bar'}).
|
121
|
+
and_return(representation)
|
122
|
+
subject.decode('CONTENT_TYPE', entity, {foo: 'bar'}).
|
123
|
+
should equal(representation)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper_lite'
|
2
|
+
require 'leadlight/tint_helper'
|
3
|
+
|
4
|
+
module Leadlight
|
5
|
+
describe TintHelper do
|
6
|
+
subject{ TintHelper.new(object, tint) }
|
7
|
+
let(:object) {
|
8
|
+
stub(__location__: stub(path: '/the/path'),
|
9
|
+
__response__: response)
|
10
|
+
}
|
11
|
+
let(:response) {
|
12
|
+
stub(:response,
|
13
|
+
env: env)
|
14
|
+
}
|
15
|
+
let(:env) { {response_headers: headers} }
|
16
|
+
let(:headers) {
|
17
|
+
{ 'Content-Type' => 'text/html; charset=UTF-8'}
|
18
|
+
}
|
19
|
+
let(:tint) { Module.new }
|
20
|
+
|
21
|
+
it 'forwards unknown calls to the wrapped object' do
|
22
|
+
object.should_receive(:foo).with('bar')
|
23
|
+
subject.foo('bar')
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#match_path' do
|
27
|
+
it 'allows execution to proceed on match' do
|
28
|
+
object.should_receive(:baz)
|
29
|
+
subject.exec_tint do
|
30
|
+
match_path('/the/path')
|
31
|
+
baz
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can match on a Regexp' do
|
36
|
+
object.should_receive(:baz)
|
37
|
+
subject.exec_tint do
|
38
|
+
match_path(/path/)
|
39
|
+
baz
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not allow execution to proceed on no match' do
|
44
|
+
object.should_not_receive(:baz)
|
45
|
+
subject.exec_tint do
|
46
|
+
match_path('/the/wrong/path')
|
47
|
+
baz
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#match_content_type' do
|
53
|
+
it 'allows execution to proceed on match' do
|
54
|
+
object.should_receive(:baz)
|
55
|
+
subject.exec_tint do
|
56
|
+
match_content_type('text/html')
|
57
|
+
baz
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can match on a regex' do
|
62
|
+
object.should_receive(:baz)
|
63
|
+
subject.exec_tint do
|
64
|
+
match_content_type(/text/)
|
65
|
+
baz
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'does not allow execution to proceed on no match' do
|
70
|
+
object.should_not_receive(:baz)
|
71
|
+
subject.exec_tint do
|
72
|
+
match_content_type('text/plain')
|
73
|
+
baz
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#match' do
|
79
|
+
it 'allows execution to proceed on true return' do
|
80
|
+
object.should_receive(:baz)
|
81
|
+
subject.exec_tint do
|
82
|
+
match{ (2 + 2) == 4 }
|
83
|
+
baz
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'does not allow execution to proceed on false return' do
|
88
|
+
object.should_not_receive(:baz)
|
89
|
+
subject.exec_tint do
|
90
|
+
match{ (2 + 2) == 5 }
|
91
|
+
baz
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#exec_tint' do
|
97
|
+
it 'returns self' do
|
98
|
+
subject.exec_tint{}.should equal(subject)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#add_header' do
|
103
|
+
it 'adds a header' do
|
104
|
+
subject.add_header('MyHeader', 'Hello world')
|
105
|
+
headers['MyHeader'].should eq('Hello world')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#extend' do
|
110
|
+
context 'given a module' do
|
111
|
+
let(:mod) { Module.new }
|
112
|
+
|
113
|
+
it 'extends the object with the given module' do
|
114
|
+
subject.extend(mod)
|
115
|
+
object.should be_a(mod)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'given a block' do
|
120
|
+
it 'extends the tint module with the given definitions' do
|
121
|
+
subject.extend do
|
122
|
+
def magic_word
|
123
|
+
'xyzzy'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
object.magic_word.should eq('xyzzy')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|