rom-http 0.0.1

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.
@@ -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