guacamole 0.2.0 → 0.3.0

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