leadlight 0.0.2
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/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
|