rom-http 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ shared_examples_for 'a command' do
2
+ describe '#method_missing' do
3
+ it 'forwards to relation and wraps response if it returned another relation' do
4
+ new_command = command.with_params(1)
5
+
6
+ expect(new_command).to be_instance_of(command.class)
7
+ expect(new_command.relation).to eq(command.with_params(1).relation)
8
+ end
9
+
10
+ it 'returns original response if it was not a relation' do
11
+ expect(command.name).to eq(command.relation.name)
12
+ end
13
+
14
+ it 'raises error when message is not known' do
15
+ expect { command.not_here }.to raise_error(NoMethodError, /not_here/)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ RSpec.shared_context 'setup' do
2
+ let(:env) { ROM::Environment.new }
3
+ let(:setup) do
4
+ env.setup(
5
+ :http,
6
+ uri: 'http://localhost:3000',
7
+ request_handler: request_handler,
8
+ response_handler: response_handler
9
+ )
10
+ end
11
+ let(:rom) { setup.finalize }
12
+ let(:request_handler) { double(Proc) }
13
+ let(:response_handler) { double(Proc) }
14
+ end
@@ -0,0 +1,10 @@
1
+ RSpec.shared_context 'users and tasks' do
2
+ include_context 'setup'
3
+
4
+ before do
5
+ gateway = setup.default
6
+
7
+ gateway.dataset(:users)
8
+ gateway.dataset(:tasks)
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ Bundler.setup
5
+
6
+ require 'rom-http'
7
+
8
+ root = Pathname(__FILE__).dirname
9
+
10
+ Dir[root.join('support/**/*.rb').to_s].each { |file| require file }
11
+ Dir[root.join('shared/**/*.rb').to_s].each { |file| require file }
@@ -0,0 +1,10 @@
1
+ module Mutant
2
+ class Selector
3
+ # Expression based test selector
4
+ class Expression < self
5
+ def call(_subject)
6
+ integration.all_tests
7
+ end
8
+ end # Expression
9
+ end # Selector
10
+ end # Mutant
@@ -0,0 +1,22 @@
1
+ describe ROM::HTTP::Commands::Create do
2
+ include_context 'users and tasks'
3
+
4
+ subject(:command) { ROM::HTTP::Commands::Create.build(users) }
5
+
6
+ let(:users_relation_klass) do
7
+ Class.new(ROM::HTTP::Relation) do
8
+ dataset :users
9
+
10
+ def by_id(id)
11
+ with_params(id: id)
12
+ end
13
+ end
14
+ end
15
+ let(:users) { rom.relations[:users] }
16
+
17
+ before do
18
+ setup.register_relation(users_relation_klass)
19
+ end
20
+
21
+ it_behaves_like 'a command'
22
+ end
@@ -0,0 +1,22 @@
1
+ describe ROM::HTTP::Commands::Delete do
2
+ include_context 'users and tasks'
3
+
4
+ subject(:command) { ROM::HTTP::Commands::Delete.build(users) }
5
+
6
+ let(:users_relation_klass) do
7
+ Class.new(ROM::HTTP::Relation) do
8
+ dataset :users
9
+
10
+ def by_id(id)
11
+ with_params(id: id)
12
+ end
13
+ end
14
+ end
15
+ let(:users) { rom.relations[:users] }
16
+
17
+ before do
18
+ setup.register_relation(users_relation_klass)
19
+ end
20
+
21
+ it_behaves_like 'a command'
22
+ end
@@ -0,0 +1,22 @@
1
+ describe ROM::HTTP::Commands::Update do
2
+ include_context 'users and tasks'
3
+
4
+ subject(:command) { ROM::HTTP::Commands::Update.build(users) }
5
+
6
+ let(:users_relation_klass) do
7
+ Class.new(ROM::HTTP::Relation) do
8
+ dataset :users
9
+
10
+ def by_id(id)
11
+ with_params(id: id)
12
+ end
13
+ end
14
+ end
15
+ let(:users) { rom.relations[:users] }
16
+
17
+ before do
18
+ setup.register_relation(users_relation_klass)
19
+ end
20
+
21
+ it_behaves_like 'a command'
22
+ end
@@ -0,0 +1,472 @@
1
+ RSpec.describe ROM::HTTP::Dataset do
2
+ let(:dataset) { ROM::HTTP::Dataset.new(config, options) }
3
+ let(:config) do
4
+ {
5
+ uri: uri,
6
+ request_handler: request_handler,
7
+ response_handler: response_handler
8
+ }
9
+ end
10
+ let(:options) { {} }
11
+ let(:uri) { 'http://localhost:3000' }
12
+ let(:request_handler) { double(Proc) }
13
+ let(:response_handler) { double(Proc) }
14
+
15
+ it { expect(dataset).to be_kind_of(Enumerable) }
16
+
17
+ describe 'defaults' do
18
+ describe '#config' do
19
+ subject { dataset.config }
20
+
21
+ it { is_expected.to eq(config) }
22
+ end
23
+
24
+ describe '#options' do
25
+ subject { dataset.options }
26
+
27
+ context 'with options passed' do
28
+ let(:options) do
29
+ {
30
+ request_method: :put,
31
+ headers: {
32
+ 'Accept' => 'application/json'
33
+ }
34
+ }
35
+ end
36
+
37
+ it do
38
+ is_expected.to eq(
39
+ request_method: :put,
40
+ path: '',
41
+ params: {},
42
+ headers: {
43
+ 'Accept' => 'application/json'
44
+ }
45
+ )
46
+ end
47
+ end
48
+
49
+ context 'with no options passed' do
50
+ it do
51
+ is_expected.to eq(
52
+ request_method: :get,
53
+ path: '',
54
+ params: {}
55
+ )
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#==' do
62
+ subject { dataset == other }
63
+
64
+ context 'with config and options equal' do
65
+ let(:other) { ROM::HTTP::Dataset.new(dataset.config, dataset.options) }
66
+
67
+ it { is_expected.to be true }
68
+ end
69
+
70
+ context 'with config and options equal' do
71
+ let(:other) do
72
+ ROM::HTTP::Dataset.new(dataset.config, dataset.options.merge(path: Random.new_seed))
73
+ end
74
+
75
+ it { is_expected.to be false }
76
+ end
77
+ end
78
+
79
+ describe '#uri' do
80
+ it { expect(dataset.uri).to eq(uri) }
81
+ end
82
+
83
+ describe '#headers' do
84
+ subject { dataset.headers }
85
+
86
+ context 'with no headers configured' do
87
+ context 'with no headers option' do
88
+ it { is_expected.to eq({}) }
89
+ end
90
+
91
+ context 'with headers option' do
92
+ let(:headers) { { 'Accept' => 'application/json' } }
93
+ let(:options) { { headers: headers } }
94
+
95
+ it { is_expected.to eq(headers) }
96
+ end
97
+ end
98
+
99
+ context 'with headers configured' do
100
+ context 'with no headers option' do
101
+ let(:headers) { { 'Accept' => 'application/json' } }
102
+ let(:config) do
103
+ super().merge(headers: headers)
104
+ end
105
+
106
+ it { is_expected.to eq(headers) }
107
+ end
108
+
109
+ context 'with headers option' do
110
+ let(:config_headers) { { 'Content-Type' => 'application/json' } }
111
+ let(:config) do
112
+ super().merge(headers: config_headers)
113
+ end
114
+ let(:option_headers) { { 'Accept' => 'application/json' } }
115
+ let(:options) { { headers: option_headers } }
116
+
117
+ it do
118
+ is_expected.to eq(
119
+ 'Content-Type' => 'application/json',
120
+ 'Accept' => 'application/json'
121
+ )
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ describe '#name' do
128
+ subject { dataset.name }
129
+
130
+ context 'with no name configured' do
131
+ it { is_expected.to eq('') }
132
+ end
133
+
134
+ context 'with name configured' do
135
+ let(:name) { 'users' }
136
+ let(:config) do
137
+ super().merge(name: name)
138
+ end
139
+
140
+ it { is_expected.to eq(name) }
141
+ end
142
+ end
143
+
144
+ describe '#path' do
145
+ subject { dataset.path }
146
+
147
+ context 'with no path option' do
148
+ it { is_expected.to eq('') }
149
+ end
150
+
151
+ context 'with path option' do
152
+ context 'when path is absolute' do
153
+ let(:path) { '/users' }
154
+ let(:options) { { path: path } }
155
+
156
+ it 'removes the leading /' do
157
+ is_expected.to eq('users')
158
+ end
159
+ end
160
+
161
+ context 'when path is not absolute' do
162
+ let(:path) { 'users' }
163
+ let(:options) { { path: path } }
164
+
165
+ it { is_expected.to eq(path) }
166
+ end
167
+ end
168
+ end
169
+
170
+ describe '#absolute_path' do
171
+ subject { dataset.absolute_path }
172
+
173
+ context 'with no path option' do
174
+ it { is_expected.to eq('/') }
175
+ end
176
+
177
+ context 'with path option' do
178
+ context 'when path is absolute' do
179
+ let(:path) { '/users' }
180
+ let(:options) { { path: path } }
181
+
182
+ it { is_expected.to eq(path) }
183
+ end
184
+
185
+ context 'when path is not absolute' do
186
+ let(:path) { 'users' }
187
+ let(:options) { { path: path } }
188
+
189
+ it { is_expected.to eq("/#{path}") }
190
+ end
191
+ end
192
+ end
193
+
194
+ describe '#request_method' do
195
+ subject { dataset.request_method }
196
+
197
+ context 'with no request_method option' do
198
+ it { is_expected.to eq(:get) }
199
+ end
200
+
201
+ context 'with request_method option' do
202
+ let(:request_method) { :put }
203
+ let(:options) { { request_method: request_method } }
204
+
205
+ it { is_expected.to eq(request_method) }
206
+ end
207
+ end
208
+
209
+ describe '#params' do
210
+ subject { dataset.params }
211
+
212
+ context 'with no params option' do
213
+ it { is_expected.to eq({}) }
214
+ end
215
+
216
+ context 'with params option' do
217
+ let(:params) { { name: 'Jack' } }
218
+ let(:options) { { params: params } }
219
+
220
+ it { is_expected.to eq(params) }
221
+ end
222
+ end
223
+
224
+ describe '#with_headers' do
225
+ let(:headers) { { 'Accept' => 'application/json' } }
226
+ let(:new_dataset) { dataset.with_headers(headers) }
227
+
228
+ subject! { new_dataset }
229
+
230
+ it { expect(new_dataset.config).to eq(config) }
231
+ it do
232
+ expect(new_dataset.options).to eq(
233
+ request_method: :get,
234
+ path: '',
235
+ params: {},
236
+ headers: headers
237
+ )
238
+ end
239
+ it { is_expected.to_not be(dataset) }
240
+ it { is_expected.to be_a(ROM::HTTP::Dataset) }
241
+ end
242
+
243
+ describe '#add_header' do
244
+ let(:header_key) { 'Accept' }
245
+ let(:header_value) { 'application/json' }
246
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
247
+
248
+ before do
249
+ allow(dataset).to receive(:with_headers).and_return(new_dataset)
250
+ end
251
+
252
+ subject! { dataset.add_header(header_key, header_value) }
253
+
254
+ context 'with existing headers configured' do
255
+ let(:config_headers) { { 'Content-Type' => 'application/json', 'Accept' => 'text/html' } }
256
+ let(:config) { super().merge(headers: config_headers) }
257
+
258
+ it do
259
+ expect(dataset).to have_received(:with_headers).with(
260
+ 'Content-Type' => 'application/json',
261
+ header_key => header_value
262
+ )
263
+ end
264
+ it { is_expected.to eq(new_dataset) }
265
+ end
266
+
267
+ context 'without existing headers configured' do
268
+ it do
269
+ expect(dataset).to have_received(:with_headers).with(
270
+ header_key => header_value
271
+ )
272
+ end
273
+ it { is_expected.to eq(new_dataset) }
274
+ end
275
+ end
276
+
277
+ describe '#with_options' do
278
+ let(:name) { 'Jill' }
279
+ let(:options) { { params: { name: name } } }
280
+ let(:new_dataset) { dataset.with_options(options) }
281
+
282
+ subject! { new_dataset }
283
+
284
+ it { expect(new_dataset.config).to eq(config) }
285
+ it do
286
+ expect(new_dataset.options).to eq(
287
+ request_method: :get,
288
+ path: '',
289
+ params: {
290
+ name: name
291
+ }
292
+ )
293
+ end
294
+ it { is_expected.to_not be(dataset) }
295
+ it { is_expected.to be_a(ROM::HTTP::Dataset) }
296
+ end
297
+
298
+ describe '#with_path' do
299
+ let(:path) { '/users/tasks' }
300
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
301
+
302
+ before do
303
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
304
+ end
305
+
306
+ subject! { dataset.with_path(path) }
307
+
308
+ it { expect(dataset).to have_received(:with_options).with(path: path) }
309
+ it { is_expected.to eq(new_dataset) }
310
+ end
311
+
312
+ describe '#append_path' do
313
+ let(:path) { 'tasks' }
314
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
315
+
316
+ before do
317
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
318
+ end
319
+
320
+ subject! { dataset.append_path(path) }
321
+
322
+ context 'without existing path' do
323
+ it { expect(dataset).to have_received(:with_options).with(path: '/tasks') }
324
+ it { is_expected.to eq(new_dataset) }
325
+ end
326
+
327
+ context 'with existing path' do
328
+ let(:options) { { path: '/users' } }
329
+
330
+ it { expect(dataset).to have_received(:with_options).with(path: '/users/tasks') }
331
+ it { is_expected.to eq(new_dataset) }
332
+ end
333
+ end
334
+
335
+ describe '#with_request_method' do
336
+ let(:request_method) { :put }
337
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
338
+
339
+ before do
340
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
341
+ end
342
+
343
+ subject! { dataset.with_request_method(request_method) }
344
+
345
+ it { expect(dataset).to have_received(:with_options).with(request_method: request_method) }
346
+ it { is_expected.to eq(new_dataset) }
347
+ end
348
+
349
+ describe '#with_params' do
350
+ let(:name) { 'Jack' }
351
+ let(:params) { { user: { name: name } } }
352
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
353
+
354
+ before do
355
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
356
+ end
357
+
358
+ subject! { dataset.with_params(params) }
359
+
360
+ it { expect(dataset).to have_received(:with_options).with(params: params) }
361
+ it { is_expected.to eq(new_dataset) }
362
+ end
363
+
364
+ describe '#each' do
365
+ let(:response) { double(Array) }
366
+ let(:block) { proc {} }
367
+ let(:result) { double }
368
+
369
+ before do
370
+ allow(dataset).to receive(:response).and_return(response)
371
+ allow(response).to receive(:each).and_yield.and_return(result)
372
+ end
373
+
374
+ context 'with no block given' do
375
+ subject! { dataset.each }
376
+
377
+ it { expect(dataset).to_not have_received(:response) }
378
+ it { expect(response).to_not have_received(:each) }
379
+ it { is_expected.to be_kind_of(Enumerable) }
380
+ end
381
+
382
+ context 'with block given' do
383
+ subject! { dataset.each(&block) }
384
+
385
+ it { expect(dataset).to have_received(:response).once }
386
+ it { expect(response).to have_received(:each) }
387
+ it { is_expected.to eq(result) }
388
+ end
389
+ end
390
+
391
+ describe '#insert' do
392
+ let(:name) { 'Jill' }
393
+ let(:params) { { user: { name: name } } }
394
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
395
+ let(:response) { double }
396
+
397
+ before do
398
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
399
+ allow(new_dataset).to receive(:response).and_return(response)
400
+ end
401
+
402
+ subject! { dataset.insert(params) }
403
+
404
+ it do
405
+ expect(dataset).to have_received(:with_options).with(
406
+ request_method: :post,
407
+ params: params
408
+ )
409
+ end
410
+ it { expect(new_dataset).to have_received(:response) }
411
+ it { is_expected.to eq(response) }
412
+ end
413
+
414
+ describe '#update' do
415
+ let(:name) { 'Jill' }
416
+ let(:params) { { user: { name: name } } }
417
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
418
+ let(:response) { double }
419
+
420
+ before do
421
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
422
+ allow(new_dataset).to receive(:response).and_return(response)
423
+ end
424
+
425
+ subject! { dataset.update(params) }
426
+
427
+ it do
428
+ expect(dataset).to have_received(:with_options).with(
429
+ request_method: :put,
430
+ params: params
431
+ )
432
+ end
433
+ it { expect(new_dataset).to have_received(:response) }
434
+ it { is_expected.to eq(response) }
435
+ end
436
+
437
+ describe '#delete' do
438
+ let(:new_dataset) { double(ROM::HTTP::Dataset) }
439
+ let(:response) { double }
440
+
441
+ before do
442
+ allow(dataset).to receive(:with_options).and_return(new_dataset)
443
+ allow(new_dataset).to receive(:response).and_return(response)
444
+ end
445
+
446
+ subject! { dataset.delete }
447
+
448
+ it do
449
+ expect(dataset).to have_received(:with_options).with(
450
+ request_method: :delete
451
+ )
452
+ end
453
+ it { expect(new_dataset).to have_received(:response) }
454
+ it { is_expected.to eq(response) }
455
+ end
456
+
457
+ describe '#response' do
458
+ let(:response) { double }
459
+ let(:result) { double }
460
+
461
+ before do
462
+ allow(request_handler).to receive(:call).and_return(response)
463
+ allow(response_handler).to receive(:call).and_return(result)
464
+ end
465
+
466
+ subject! { dataset.response }
467
+
468
+ it { expect(request_handler).to have_received(:call).with(dataset) }
469
+ it { expect(response_handler).to have_received(:call).with(response, dataset) }
470
+ it { is_expected.to eq(result) }
471
+ end
472
+ end