guacamole 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/.hound.yml +3 -0
- data/{config/reek.yml → .reek.yml} +5 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +19 -0
- data/GOALS.md +20 -0
- data/Gemfile +1 -11
- data/Guardfile +0 -4
- data/README.md +147 -11
- data/Rakefile +33 -3
- data/guacamole.gemspec +12 -1
- data/lib/guacamole.rb +1 -0
- data/lib/guacamole/callbacks.rb +259 -0
- data/lib/guacamole/collection.rb +50 -32
- data/lib/guacamole/configuration.rb +92 -15
- data/lib/guacamole/model.rb +39 -1
- data/lib/guacamole/railtie.rb +9 -3
- data/lib/guacamole/version.rb +1 -1
- data/lib/rails/generators/guacamole/callbacks/callbacks_generator.rb +26 -0
- data/lib/rails/generators/guacamole/callbacks/templates/callbacks.rb.tt +13 -0
- data/lib/rails/generators/rspec/callbacks/callbacks_generator.rb +14 -0
- data/lib/rails/generators/rspec/callbacks/templates/callbacks_spec.rb.tt +7 -0
- data/lib/rails/generators/test_unit/callbacks/callbacks_generator.rb +13 -0
- data/lib/rails/generators/test_unit/callbacks/templates/callbacks_test.rb.tt +9 -0
- data/lib/rails/generators/test_unit/collection/collection_generator.rb +13 -0
- data/lib/rails/generators/test_unit/collection/templates/collection_test.rb.tt +10 -0
- data/spec/acceptance/aql_spec.rb +0 -12
- data/spec/acceptance/basic_spec.rb +16 -25
- data/spec/acceptance/callbacks_spec.rb +181 -0
- data/spec/acceptance/config/guacamole.yml +1 -1
- data/spec/acceptance/spec_helper.rb +24 -6
- data/spec/fabricators/article.rb +12 -0
- data/spec/fabricators/comment.rb +7 -0
- data/spec/fabricators/pony.rb +6 -4
- data/spec/fabricators/pony_fabricator.rb +7 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/guacamole.yml.erb +5 -0
- data/spec/unit/callbacks_spec.rb +139 -0
- data/spec/unit/collection_spec.rb +85 -66
- data/spec/unit/configuration_spec.rb +165 -21
- data/spec/unit/identiy_map_spec.rb +2 -2
- data/spec/unit/model_spec.rb +36 -3
- metadata +181 -12
- data/Gemfile.devtools +0 -67
- data/config/devtools.yml +0 -4
- data/config/flay.yml +0 -3
- data/config/flog.yml +0 -2
- data/config/mutant.yml +0 -3
- data/config/yardstick.yml +0 -2
- data/tasks/adjustments.rake +0 -34
@@ -0,0 +1,139 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'guacamole/callbacks'
|
5
|
+
|
6
|
+
class FakeModel
|
7
|
+
end
|
8
|
+
|
9
|
+
class FakeCallback
|
10
|
+
include Guacamole::Callbacks
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Guacamole::Callbacks do
|
14
|
+
describe 'registering callbacks' do
|
15
|
+
let(:model) { FakeModel.new }
|
16
|
+
let(:callback_class) { double('CallbackClass') }
|
17
|
+
let(:callback_instance) { double('CallbackInstance') }
|
18
|
+
|
19
|
+
before do
|
20
|
+
subject.register_callback model.class, callback_class
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should register a callback class to be used with a model class' do
|
24
|
+
expect(subject.registry[model.class]).to eq callback_class
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should retrieve the callback class for a given model class' do
|
28
|
+
allow(callback_class).to receive(:new).with(model).and_return(callback_instance)
|
29
|
+
|
30
|
+
expect(subject.callbacks_for(model).callbacks).to eq callback_instance
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should wrap the callback class in a proxy' do
|
34
|
+
allow(callback_class).to receive(:new).with(model).and_return(callback_instance)
|
35
|
+
|
36
|
+
expect(subject.callbacks_for(model)).to be_instance_of Guacamole::Callbacks::CallbackProxy
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'no callback defined for model class' do
|
40
|
+
it 'should return the DefaultCallback' do
|
41
|
+
any_model = double('ModelWithoutCallbacks')
|
42
|
+
expect(subject.callbacks_for(any_model).callbacks).to be_instance_of Guacamole::Callbacks::DefaultCallback
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'time stamp related callbacks' do
|
48
|
+
let(:model) { double('Model') }
|
49
|
+
let(:now) { double('Time') }
|
50
|
+
subject { FakeCallback.new model }
|
51
|
+
|
52
|
+
before do
|
53
|
+
allow(Time).to receive(:now).twice.and_return(now)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should set created_at / updated_at before_create' do
|
57
|
+
expect(model).to receive(:created_at=).with(now)
|
58
|
+
expect(model).to receive(:updated_at=).with(now)
|
59
|
+
|
60
|
+
subject.run_callbacks :create
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should set updated_at before_update' do
|
64
|
+
expect(model).to_not receive(:created_at=)
|
65
|
+
expect(model).to receive(:updated_at=).with(now)
|
66
|
+
|
67
|
+
subject.run_callbacks :update
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'building callbacks' do
|
72
|
+
subject { FakeCallback }
|
73
|
+
|
74
|
+
it 'should include ActiveModel::Callbacks' do
|
75
|
+
expect(subject.ancestors).to include ActiveModel::Callbacks
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'callback instances' do
|
80
|
+
let(:model) { double('Model').as_null_object }
|
81
|
+
subject { FakeCallback.new model }
|
82
|
+
|
83
|
+
it 'should provide access to the concrete model instance' do
|
84
|
+
expect(subject.object).to eq model
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should run :validate callbacks' do
|
88
|
+
expect { subject.run_callbacks :validate }.not_to raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should run :save callbacks' do
|
92
|
+
expect { subject.run_callbacks :save }.not_to raise_error
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should run :create callbacks' do
|
96
|
+
expect { subject.run_callbacks :create }.not_to raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should run :update callbacks' do
|
100
|
+
expect { subject.run_callbacks :update }.not_to raise_error
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should run :delete callbacks' do
|
104
|
+
expect { subject.run_callbacks :delete }.not_to raise_error
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe Guacamole::Callbacks::DefaultCallback do
|
109
|
+
subject { Guacamole::Callbacks::DefaultCallback }
|
110
|
+
|
111
|
+
it 'should include Guacamole::Callbacks' do
|
112
|
+
expect(subject.ancestors).to include Guacamole::Callbacks
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe Guacamole::Callbacks::CallbackProxy do
|
117
|
+
let(:model) { double('Model').as_null_object }
|
118
|
+
let(:something) { double('Something') }
|
119
|
+
let(:callbacks) { FakeCallback.new(model) }
|
120
|
+
subject { Guacamole::Callbacks::CallbackProxy.new callbacks }
|
121
|
+
|
122
|
+
before do
|
123
|
+
allow(something).to receive(:do_it).once
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should proxy a single kind of callback to the underlying callback class' do
|
127
|
+
expect(callbacks).to receive(:run_callbacks).with(:update).and_yield
|
128
|
+
|
129
|
+
subject.run_callbacks(:update) { something.do_it }
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should execute multiple kinds of callbacks on the underlying callback class' do
|
133
|
+
expect(callbacks).to receive(:run_callbacks).with(:save).ordered.and_yield
|
134
|
+
expect(callbacks).to receive(:run_callbacks).with(:create).ordered.and_yield
|
135
|
+
|
136
|
+
subject.run_callbacks(:save, :create) { something.do_it }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -11,8 +11,19 @@ class TestCollection
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe Guacamole::Collection do
|
14
|
+
let(:callbacks) { double('Callback') }
|
15
|
+
let(:callbacks_module) { double('CallbacksModule') }
|
16
|
+
|
14
17
|
subject { TestCollection }
|
15
18
|
|
19
|
+
before do
|
20
|
+
allow(callbacks_module).to receive(:callbacks_for).and_return(callbacks)
|
21
|
+
allow(callbacks).to receive(:run_callbacks).with(:save, :create).and_yield
|
22
|
+
allow(callbacks).to receive(:run_callbacks).with(:save, :update).and_yield
|
23
|
+
allow(callbacks).to receive(:run_callbacks).with(:delete).and_yield
|
24
|
+
stub_const('Guacamole::Callbacks', callbacks_module)
|
25
|
+
end
|
26
|
+
|
16
27
|
describe 'Configuration' do
|
17
28
|
it 'should set the connection to the ArangoDB collection' do
|
18
29
|
mock_collection_connection = double('ConnectionToCollection')
|
@@ -131,32 +142,21 @@ describe Guacamole::Collection do
|
|
131
142
|
|
132
143
|
before do
|
133
144
|
allow(model).to receive(:valid?).and_return(true)
|
145
|
+
allow(connection).to receive(:create_document).with(document).and_return(document)
|
146
|
+
allow(model).to receive(:persisted?).and_return(false)
|
134
147
|
end
|
135
148
|
|
136
|
-
|
149
|
+
it 'should run the save callbacks for the given model' do
|
150
|
+
expect(subject).to receive(:callbacks).with(model).and_return(callbacks)
|
137
151
|
|
138
|
-
|
139
|
-
|
140
|
-
allow(model).to receive(:persisted?).and_return(false)
|
141
|
-
end
|
152
|
+
subject.save model
|
153
|
+
end
|
142
154
|
|
155
|
+
context 'which is not persisted' do
|
143
156
|
it 'should return the model after calling save' do
|
144
157
|
expect(subject.save(model)).to eq model
|
145
158
|
end
|
146
159
|
|
147
|
-
it 'should set timestamps before creating the document' do
|
148
|
-
now = double('Time.now')
|
149
|
-
|
150
|
-
allow(Time).to receive(:now).once.and_return(now)
|
151
|
-
|
152
|
-
expect(model).to receive(:created_at=).with(now).ordered
|
153
|
-
expect(model).to receive(:updated_at=).with(now).ordered
|
154
|
-
|
155
|
-
allow(connection).to receive(:create_document).with(document).and_return(document).ordered
|
156
|
-
|
157
|
-
subject.save model
|
158
|
-
end
|
159
|
-
|
160
160
|
it 'should add key to model' do
|
161
161
|
expect(model).to receive(:key=).with(key)
|
162
162
|
|
@@ -180,16 +180,7 @@ describe Guacamole::Collection do
|
|
180
180
|
|
181
181
|
let(:model) { double('Model', key: key).as_null_object }
|
182
182
|
|
183
|
-
it 'should
|
184
|
-
now = double('Time.now')
|
185
|
-
|
186
|
-
allow(Time).to receive(:now).once.and_return(now)
|
187
|
-
expect(model).to receive(:updated_at=).with(now)
|
188
|
-
|
189
|
-
subject.save model
|
190
|
-
end
|
191
|
-
|
192
|
-
it 'should replace the document by key via the connection' do
|
183
|
+
it 'should update the document by key via the connection' do
|
193
184
|
expect(connection).to receive(:replace).with(key, document)
|
194
185
|
|
195
186
|
subject.save model
|
@@ -234,8 +225,6 @@ describe Guacamole::Collection do
|
|
234
225
|
end
|
235
226
|
|
236
227
|
it 'should not be changed' do
|
237
|
-
expect(model).not_to receive(:created_at=)
|
238
|
-
expect(model).not_to receive(:updated_at=)
|
239
228
|
expect(model).not_to receive(:key=)
|
240
229
|
expect(model).not_to receive(:rev=)
|
241
230
|
|
@@ -256,7 +245,7 @@ describe Guacamole::Collection do
|
|
256
245
|
|
257
246
|
let(:model) { double('Model', key: key).as_null_object }
|
258
247
|
|
259
|
-
it 'should not be used to
|
248
|
+
it 'should not be used to update the document' do
|
260
249
|
expect(connection).not_to receive(:replace)
|
261
250
|
|
262
251
|
subject.save model
|
@@ -306,27 +295,27 @@ describe Guacamole::Collection do
|
|
306
295
|
expect(subject.create(model)).to eq model
|
307
296
|
end
|
308
297
|
|
309
|
-
it 'should
|
310
|
-
|
311
|
-
|
312
|
-
allow(Time).to receive(:now).once.and_return(now)
|
298
|
+
it 'should add key to model' do
|
299
|
+
expect(model).to receive(:key=).with(key)
|
313
300
|
|
314
|
-
|
315
|
-
|
301
|
+
subject.create model
|
302
|
+
end
|
316
303
|
|
317
|
-
|
304
|
+
it 'should add rev to model' do
|
305
|
+
expect(model).to receive(:rev=).with(rev)
|
318
306
|
|
319
307
|
subject.create model
|
320
308
|
end
|
321
309
|
|
322
|
-
it 'should
|
323
|
-
expect(
|
310
|
+
it 'should run the create callbacks for the given model' do
|
311
|
+
expect(callbacks).to receive(:run_callbacks).with(:save, :create).and_yield
|
324
312
|
|
325
313
|
subject.create model
|
326
314
|
end
|
327
315
|
|
328
|
-
it 'should
|
329
|
-
expect(model).to receive(:
|
316
|
+
it 'should run first the validation and then the create callbacks' do
|
317
|
+
expect(model).to receive(:valid?).ordered.and_return(true)
|
318
|
+
expect(callbacks).to receive(:run_callbacks).ordered.with(:save, :create).and_yield
|
330
319
|
|
331
320
|
subject.create model
|
332
321
|
end
|
@@ -427,8 +416,6 @@ describe Guacamole::Collection do
|
|
427
416
|
end
|
428
417
|
|
429
418
|
it 'should not be changed' do
|
430
|
-
expect(model).not_to receive(:created_at=)
|
431
|
-
expect(model).not_to receive(:updated_at=)
|
432
419
|
expect(model).not_to receive(:key=)
|
433
420
|
expect(model).not_to receive(:rev=)
|
434
421
|
|
@@ -448,10 +435,21 @@ describe Guacamole::Collection do
|
|
448
435
|
|
449
436
|
before do
|
450
437
|
allow(connection).to receive(:fetch).with(key).and_return(document)
|
438
|
+
allow(subject).to receive(:by_key)
|
451
439
|
allow(document).to receive(:delete)
|
452
440
|
end
|
453
441
|
|
454
442
|
context 'a key was provided' do
|
443
|
+
before do
|
444
|
+
allow(mapper).to receive(:document_to_model).with(document).and_return(model)
|
445
|
+
end
|
446
|
+
|
447
|
+
it 'should load the document and instantiate the model' do
|
448
|
+
expect(mapper).to receive(:document_to_model).with(document).and_return(model)
|
449
|
+
|
450
|
+
subject.delete key
|
451
|
+
end
|
452
|
+
|
455
453
|
it 'should delete the according document' do
|
456
454
|
expect(document).to receive(:delete)
|
457
455
|
|
@@ -461,6 +459,13 @@ describe Guacamole::Collection do
|
|
461
459
|
it 'should return the according key' do
|
462
460
|
expect(subject.delete(key)).to eq key
|
463
461
|
end
|
462
|
+
|
463
|
+
it 'should run the delete callbacks for the given model' do
|
464
|
+
expect(subject).to receive(:callbacks).with(model).and_return(callbacks)
|
465
|
+
expect(callbacks).to receive(:run_callbacks).with(:delete).and_yield
|
466
|
+
|
467
|
+
subject.delete model
|
468
|
+
end
|
464
469
|
end
|
465
470
|
|
466
471
|
context 'a model was provided' do
|
@@ -473,10 +478,17 @@ describe Guacamole::Collection do
|
|
473
478
|
it 'should return the according key' do
|
474
479
|
expect(subject.delete(model)).to eq key
|
475
480
|
end
|
481
|
+
|
482
|
+
it 'should run the delete callbacks for the given model' do
|
483
|
+
expect(subject).to receive(:callbacks).with(model).and_return(callbacks)
|
484
|
+
expect(callbacks).to receive(:run_callbacks).with(:delete).and_yield
|
485
|
+
|
486
|
+
subject.delete model
|
487
|
+
end
|
476
488
|
end
|
477
489
|
end
|
478
490
|
|
479
|
-
describe '
|
491
|
+
describe 'update' do
|
480
492
|
let(:key) { double('Key') }
|
481
493
|
let(:rev) { double('Rev') }
|
482
494
|
let(:model) { double('Model', key: key).as_null_object }
|
@@ -494,36 +506,34 @@ describe Guacamole::Collection do
|
|
494
506
|
allow(model).to receive(:valid?).and_return(true)
|
495
507
|
end
|
496
508
|
|
497
|
-
it 'should
|
498
|
-
now = double('Time.now')
|
499
|
-
|
500
|
-
allow(Time).to receive(:now).once.and_return(now)
|
501
|
-
expect(model).to receive(:updated_at=).with(now)
|
502
|
-
|
503
|
-
subject.replace model
|
504
|
-
end
|
505
|
-
|
506
|
-
it 'should replace the document by key via the connection' do
|
509
|
+
it 'should update the document by key via the connection' do
|
507
510
|
expect(connection).to receive(:replace).with(key, document)
|
508
511
|
|
509
|
-
subject.
|
512
|
+
subject.update model
|
510
513
|
end
|
511
514
|
|
512
515
|
it 'should update the revision after replacing the document' do
|
513
516
|
allow(connection).to receive(:replace).and_return(response).ordered
|
514
517
|
expect(model).to receive(:rev=).with(rev).ordered
|
515
518
|
|
516
|
-
subject.
|
519
|
+
subject.update model
|
517
520
|
end
|
518
521
|
|
519
522
|
it 'should return the model' do
|
520
|
-
expect(subject.
|
523
|
+
expect(subject.update(model)).to eq model
|
521
524
|
end
|
522
525
|
|
523
|
-
it 'should
|
524
|
-
expect(
|
526
|
+
it 'should run the update callbacks for the given model' do
|
527
|
+
expect(callbacks).to receive(:run_callbacks).with(:save, :update).and_yield
|
525
528
|
|
526
|
-
subject.
|
529
|
+
subject.update model
|
530
|
+
end
|
531
|
+
|
532
|
+
it 'should run first the validation and then the update callbacks' do
|
533
|
+
expect(model).to receive(:valid?).ordered.and_return(true)
|
534
|
+
expect(callbacks).to receive(:run_callbacks).ordered.with(:save, :update).and_yield
|
535
|
+
|
536
|
+
subject.update model
|
527
537
|
end
|
528
538
|
end
|
529
539
|
|
@@ -532,21 +542,20 @@ describe Guacamole::Collection do
|
|
532
542
|
allow(model).to receive(:valid?).and_return(false)
|
533
543
|
end
|
534
544
|
|
535
|
-
it 'should not be used to
|
545
|
+
it 'should not be used to update the document' do
|
536
546
|
expect(connection).not_to receive(:replace)
|
537
547
|
|
538
|
-
subject.
|
548
|
+
subject.update model
|
539
549
|
end
|
540
550
|
|
541
551
|
it 'should not be changed' do
|
542
552
|
expect(model).not_to receive(:rev=)
|
543
|
-
expect(model).not_to receive(:updated_at=)
|
544
553
|
|
545
|
-
subject.
|
554
|
+
subject.update model
|
546
555
|
end
|
547
556
|
|
548
557
|
it 'should return false' do
|
549
|
-
expect(subject.
|
558
|
+
expect(subject.update(model)).to be false
|
550
559
|
end
|
551
560
|
end
|
552
561
|
end
|
@@ -624,4 +633,14 @@ describe Guacamole::Collection do
|
|
624
633
|
end
|
625
634
|
end
|
626
635
|
end
|
636
|
+
|
637
|
+
describe 'callbacks' do
|
638
|
+
let(:model) { double('Model') }
|
639
|
+
|
640
|
+
it 'should get the callback instance for the given model' do
|
641
|
+
expect(callbacks_module).to receive(:callbacks_for).with(model)
|
642
|
+
|
643
|
+
subject.callbacks model
|
644
|
+
end
|
645
|
+
end
|
627
646
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'guacamole/configuration'
|
5
|
+
require 'tempfile'
|
5
6
|
|
6
7
|
describe 'Guacamole.configure' do
|
7
8
|
subject { Guacamole }
|
@@ -80,20 +81,109 @@ describe Guacamole::Configuration do
|
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
84
|
+
describe 'build_config' do
|
85
|
+
context 'from a hash' do
|
86
|
+
let(:config_hash) do
|
87
|
+
{
|
88
|
+
'protocol' => 'http',
|
89
|
+
'host' => 'localhost',
|
90
|
+
'port' => 8529,
|
91
|
+
'username' => 'username',
|
92
|
+
'password' => 'password',
|
93
|
+
'database' => 'awesome_db'
|
94
|
+
}
|
95
|
+
end
|
96
|
+
let(:config_struct) { subject.build_config(config_hash) }
|
97
|
+
|
98
|
+
it 'should create a struct with a database URL' do
|
99
|
+
expect(config_struct.url).to eq 'http://localhost:8529'
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should create a struct with a username' do
|
103
|
+
expect(config_struct.username).to eq 'username'
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should create a struct with password' do
|
107
|
+
expect(config_struct.password).to eq 'password'
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should create a struct with database' do
|
111
|
+
expect(config_struct.database).to eq 'awesome_db'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'from a URL' do
|
116
|
+
let(:database_url) { 'http://username:password@localhost:8529/_db/awesome_db' }
|
117
|
+
let(:config_struct) { subject.build_config(database_url) }
|
118
|
+
|
119
|
+
it 'should create a struct with a database URL' do
|
120
|
+
expect(config_struct.url).to eq 'http://localhost:8529'
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should create a struct with a username' do
|
124
|
+
expect(config_struct.username).to eq 'username'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should create a struct with password' do
|
128
|
+
expect(config_struct.password).to eq 'password'
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should create a struct with database' do
|
132
|
+
expect(config_struct.database).to eq 'awesome_db'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe 'create_database_connection' do
|
138
|
+
let(:config_struct) { double('ConfigStruct', url: 'http://localhost', username: 'user', password: 'pass', database: 'pony_db') }
|
139
|
+
let(:arango_config) { double('ArangoConfig').as_null_object }
|
140
|
+
let(:database) { double('Ashikawa::Core::Database') }
|
141
|
+
let(:guacamole_logger) { double('logger') }
|
142
|
+
|
143
|
+
before do
|
144
|
+
allow(Ashikawa::Core::Database).to receive(:new).and_yield(arango_config).and_return(database)
|
145
|
+
allow(subject).to receive(:logger).and_return(guacamole_logger)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should create the actual Ashikawa::Core::Database instance' do
|
149
|
+
expect(arango_config).to receive(:url=).with('http://localhost')
|
150
|
+
expect(arango_config).to receive(:username=).with('user')
|
151
|
+
expect(arango_config).to receive(:password=).with('pass')
|
152
|
+
|
153
|
+
subject.create_database_connection config_struct
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should pass the Guacamole logger to the Ashikawa::Core::Database connection' do
|
157
|
+
expect(arango_config).to receive(:logger=).with(guacamole_logger)
|
158
|
+
|
159
|
+
subject.create_database_connection config_struct
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should assign the database connection to the configuration instance' do
|
163
|
+
subject.create_database_connection config_struct
|
164
|
+
|
165
|
+
expect(subject.database).to eq database
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
83
169
|
describe 'load' do
|
84
170
|
let(:config) { double('Config') }
|
171
|
+
let(:env_config) { double('ConfigForEnv') }
|
172
|
+
let(:config_struct) { double('ConfigStruct') }
|
85
173
|
let(:current_environment) { 'development' }
|
86
174
|
|
87
175
|
before do
|
88
176
|
allow(subject).to receive(:current_environment).and_return(current_environment)
|
89
|
-
allow(subject).to receive(:
|
90
|
-
allow(subject).to receive(:
|
91
|
-
allow(
|
92
|
-
allow(
|
177
|
+
allow(subject).to receive(:warn_if_database_was_not_yet_created)
|
178
|
+
allow(subject).to receive(:create_database_connection)
|
179
|
+
allow(subject).to receive(:process_file_with_erb).with('config_file.yml')
|
180
|
+
allow(subject).to receive(:build_config).and_return(config_struct)
|
181
|
+
allow(config).to receive(:[]).with('development').and_return(env_config)
|
182
|
+
allow(YAML).to receive(:load).and_return(config)
|
93
183
|
end
|
94
184
|
|
95
185
|
it 'should parse a YAML configuration' do
|
96
|
-
expect(YAML).to receive(:
|
186
|
+
expect(YAML).to receive(:load).and_return(config)
|
97
187
|
|
98
188
|
subject.load 'config_file.yml'
|
99
189
|
end
|
@@ -104,27 +194,81 @@ describe Guacamole::Configuration do
|
|
104
194
|
subject.load 'config_file.yml'
|
105
195
|
end
|
106
196
|
|
107
|
-
it 'should create
|
108
|
-
|
109
|
-
expect(arango_config).to receive(:url=).with('http://localhost:8529/_db/test_db')
|
110
|
-
expect(arango_config).to receive(:username=).with('')
|
111
|
-
expect(arango_config).to receive(:password=).with('')
|
112
|
-
expect(arango_config).to receive(:logger=).with(subject.logger)
|
197
|
+
it 'should create a database config struct from config file' do
|
198
|
+
expect(subject).to receive(:build_config).with(env_config).and_return(config_struct)
|
113
199
|
|
114
|
-
|
200
|
+
subject.load 'config_file.yml'
|
201
|
+
end
|
115
202
|
|
116
|
-
|
117
|
-
|
118
|
-
'host' => 'localhost',
|
119
|
-
'port' => 8529,
|
120
|
-
'username' => '',
|
121
|
-
'password' => '',
|
122
|
-
'database' => 'test_db'
|
123
|
-
)
|
124
|
-
allow(subject).to receive(:create_database_connection_from).and_call_original
|
203
|
+
it 'should create the database connection with a config struct' do
|
204
|
+
expect(subject).to receive(:create_database_connection).with(config_struct)
|
125
205
|
|
126
206
|
subject.load 'config_file.yml'
|
127
207
|
end
|
208
|
+
|
209
|
+
it 'should warn if the database was not found' do
|
210
|
+
allow(subject).to receive(:database).and_return(double('Database'))
|
211
|
+
allow(subject.database).to receive(:name)
|
212
|
+
expect(subject.database).to receive(:send_request).with('version').and_raise(Ashikawa::Core::ResourceNotFound)
|
213
|
+
expect(subject).to receive(:warn_if_database_was_not_yet_created).and_call_original
|
214
|
+
|
215
|
+
logger = double('logger')
|
216
|
+
expect(logger).to receive(:warn)
|
217
|
+
expect(subject).to receive(:warn)
|
218
|
+
allow(subject).to receive(:logger).and_return(logger)
|
219
|
+
|
220
|
+
subject.load 'config_file.yml'
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'erb support' do
|
224
|
+
let(:config_file) { File.open 'spec/support/guacamole.yml.erb' }
|
225
|
+
let(:protocol_via_erb) { ENV['ARANGODB_PROTOCOL'] = 'https' }
|
226
|
+
let(:database_via_erb) { ENV['ARANGODB_DATABASE'] = 'my_playground' }
|
227
|
+
|
228
|
+
before do
|
229
|
+
allow(subject).to receive(:process_file_with_erb).and_call_original
|
230
|
+
end
|
231
|
+
|
232
|
+
after do
|
233
|
+
ENV.delete 'ARANGODB_PROTOCOL'
|
234
|
+
ENV.delete 'ARANGODB_DATABASE'
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should process the YAML file with ERB' do
|
238
|
+
processed_yaml = <<-YAML
|
239
|
+
development:
|
240
|
+
protocol: '#{protocol_via_erb}'
|
241
|
+
host: 'localhost'
|
242
|
+
port: 8529
|
243
|
+
database: '#{database_via_erb}'
|
244
|
+
YAML
|
245
|
+
expect(YAML).to receive(:load).with(processed_yaml)
|
246
|
+
|
247
|
+
subject.load config_file.path
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe 'configure with a connection URI' do
|
253
|
+
let(:config_struct) { double('ConfigStruct') }
|
254
|
+
let(:connection_uri) { 'http://username:password@locahost:8529/_db/awesome_db' }
|
255
|
+
|
256
|
+
before do
|
257
|
+
allow(subject).to receive(:create_database_connection)
|
258
|
+
allow(subject).to receive(:build_config).and_return(config_struct)
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should build a config_struct from the connection URI' do
|
262
|
+
expect(subject).to receive(:build_config).with(connection_uri)
|
263
|
+
|
264
|
+
subject.configure_with_uri(connection_uri)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should use the config_struct to create the database connection' do
|
268
|
+
expect(subject).to receive(:create_database_connection).with(config_struct)
|
269
|
+
|
270
|
+
subject.configure_with_uri(connection_uri)
|
271
|
+
end
|
128
272
|
end
|
129
273
|
|
130
274
|
describe 'experimental_features' do
|