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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +3 -0
  3. data/{config/reek.yml → .reek.yml} +5 -0
  4. data/.travis.yml +3 -0
  5. data/CHANGELOG.md +19 -0
  6. data/GOALS.md +20 -0
  7. data/Gemfile +1 -11
  8. data/Guardfile +0 -4
  9. data/README.md +147 -11
  10. data/Rakefile +33 -3
  11. data/guacamole.gemspec +12 -1
  12. data/lib/guacamole.rb +1 -0
  13. data/lib/guacamole/callbacks.rb +259 -0
  14. data/lib/guacamole/collection.rb +50 -32
  15. data/lib/guacamole/configuration.rb +92 -15
  16. data/lib/guacamole/model.rb +39 -1
  17. data/lib/guacamole/railtie.rb +9 -3
  18. data/lib/guacamole/version.rb +1 -1
  19. data/lib/rails/generators/guacamole/callbacks/callbacks_generator.rb +26 -0
  20. data/lib/rails/generators/guacamole/callbacks/templates/callbacks.rb.tt +13 -0
  21. data/lib/rails/generators/rspec/callbacks/callbacks_generator.rb +14 -0
  22. data/lib/rails/generators/rspec/callbacks/templates/callbacks_spec.rb.tt +7 -0
  23. data/lib/rails/generators/test_unit/callbacks/callbacks_generator.rb +13 -0
  24. data/lib/rails/generators/test_unit/callbacks/templates/callbacks_test.rb.tt +9 -0
  25. data/lib/rails/generators/test_unit/collection/collection_generator.rb +13 -0
  26. data/lib/rails/generators/test_unit/collection/templates/collection_test.rb.tt +10 -0
  27. data/spec/acceptance/aql_spec.rb +0 -12
  28. data/spec/acceptance/basic_spec.rb +16 -25
  29. data/spec/acceptance/callbacks_spec.rb +181 -0
  30. data/spec/acceptance/config/guacamole.yml +1 -1
  31. data/spec/acceptance/spec_helper.rb +24 -6
  32. data/spec/fabricators/article.rb +12 -0
  33. data/spec/fabricators/comment.rb +7 -0
  34. data/spec/fabricators/pony.rb +6 -4
  35. data/spec/fabricators/pony_fabricator.rb +7 -0
  36. data/spec/spec_helper.rb +5 -4
  37. data/spec/support/guacamole.yml.erb +5 -0
  38. data/spec/unit/callbacks_spec.rb +139 -0
  39. data/spec/unit/collection_spec.rb +85 -66
  40. data/spec/unit/configuration_spec.rb +165 -21
  41. data/spec/unit/identiy_map_spec.rb +2 -2
  42. data/spec/unit/model_spec.rb +36 -3
  43. metadata +181 -12
  44. data/Gemfile.devtools +0 -67
  45. data/config/devtools.yml +0 -4
  46. data/config/flay.yml +0 -3
  47. data/config/flog.yml +0 -2
  48. data/config/mutant.yml +0 -3
  49. data/config/yardstick.yml +0 -2
  50. data/tasks/adjustments.rake +0 -34
@@ -0,0 +1,5 @@
1
+ development:
2
+ protocol: '<%= ENV['ARANGODB_PROTOCOL'] %>'
3
+ host: 'localhost'
4
+ port: 8529
5
+ database: '<%= ENV['ARANGODB_DATABASE'] %>'
@@ -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
- context 'which is not persisted' do
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
- before do
139
- allow(connection).to receive(:create_document).with(document).and_return(document)
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 set the updated_at timestamp before replacing the document' do
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 replace the document' do
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 set timestamps before creating the document' do
310
- now = double('Time.now')
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
- expect(model).to receive(:created_at=).with(now).ordered
315
- expect(model).to receive(:updated_at=).with(now).ordered
301
+ subject.create model
302
+ end
316
303
 
317
- allow(connection).to receive(:create_document).with(document).and_return(document).ordered
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 add key to model' do
323
- expect(model).to receive(:key=).with(key)
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 add rev to model' do
329
- expect(model).to receive(:rev=).with(rev)
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 'replace' do
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 set the updated_at timestamp before replacing the document' do
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.replace model
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.replace model
519
+ subject.update model
517
520
  end
518
521
 
519
522
  it 'should return the model' do
520
- expect(subject.replace(model)).to eq model
523
+ expect(subject.update(model)).to eq model
521
524
  end
522
525
 
523
- it 'should not update created_at' do
524
- expect(model).not_to receive(:created_at=)
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.replace model
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 replace the document' do
545
+ it 'should not be used to update the document' do
536
546
  expect(connection).not_to receive(:replace)
537
547
 
538
- subject.replace model
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.replace model
554
+ subject.update model
546
555
  end
547
556
 
548
557
  it 'should return false' do
549
- expect(subject.replace(model)).to be false
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(:database=)
90
- allow(subject).to receive(:create_database_connection_from)
91
- allow(config).to receive(:[]).with('development')
92
- allow(YAML).to receive(:load_file).with('config_file.yml').and_return(config)
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(:load_file).with('config_file.yml').and_return(config)
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 an Ashikawa::Core::Database instance based on configuration' do
108
- arango_config = double('ArangoConfig')
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
- allow(Ashikawa::Core::Database).to receive(:new).and_yield(arango_config)
200
+ subject.load 'config_file.yml'
201
+ end
115
202
 
116
- allow(config).to receive(:[]).with('development').and_return(
117
- 'protocol' => 'http',
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