guacamole 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|