a9n 0.10.0 → 1.0.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.
@@ -1,96 +0,0 @@
1
- require 'simplecov'
2
- SimpleCov.start
3
-
4
- require 'rubygems'
5
- require 'bundler/setup'
6
-
7
- require 'a9n'
8
- require 'pry'
9
-
10
- RSpec.configure do |config|
11
- # rspec-expectations config goes here. You can use an alternate
12
- # assertion/expectation library such as wrong or the stdlib/minitest
13
- # assertions if you prefer.
14
- config.expect_with :rspec do |expectations|
15
- # This option will default to `true` in RSpec 4. It makes the `description`
16
- # and `failure_message` of custom matchers include text for helper methods
17
- # defined using `chain`, e.g.:
18
- # be_bigger_than(2).and_smaller_than(4).description
19
- # # => 'be bigger than 2 and smaller than 4'
20
- # ...rather than:
21
- # # => 'be bigger than 2'
22
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
- end
24
-
25
- # rspec-mocks config goes here. You can use an alternate test double
26
- # library (such as bogus or mocha) by changing the `mock_with` option here.
27
- config.mock_with :rspec do |mocks|
28
- # Prevents you from mocking or stubbing a method that does not exist on
29
- # a real object. This is generally recommended, and will default to
30
- # `true` in RSpec 4.
31
- mocks.verify_partial_doubles = true
32
- end
33
-
34
- # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
35
- # have no way to turn it off -- the option exists only for backwards
36
- # compatibility in RSpec 3). It causes shared context metadata to be
37
- # inherited by the metadata hash of host groups and examples, rather than
38
- # triggering implicit auto-inclusion in groups with matching metadata.
39
- config.shared_context_metadata_behavior = :apply_to_host_groups
40
-
41
- # This allows you to limit a spec run to individual examples or groups
42
- # you care about by tagging them with `:focus` metadata. When nothing
43
- # is tagged with `:focus`, all examples get run. RSpec also provides
44
- # aliases for `it`, `describe`, and `context` that include `:focus`
45
- # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
46
- config.filter_run_when_matching :focus
47
-
48
- # Allows RSpec to persist some state between runs in order to support
49
- # the `--only-failures` and `--next-failure` CLI options. We recommend
50
- # you configure your source control system to ignore this file.
51
- config.example_status_persistence_file_path = 'spec/examples.txt'
52
-
53
- # Limits the available syntax to the non-monkey patched syntax that is
54
- # recommended. For more details, see:
55
- # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
56
- # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
57
- # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
58
- config.disable_monkey_patching!
59
-
60
- # This setting enables warnings. It's recommended, but in some cases may
61
- # be too noisy due to issues in dependencies.
62
- config.warnings = true
63
-
64
- # Many RSpec users commonly either run the entire suite or an individual
65
- # file, and it's useful to allow more verbose output when running an
66
- # individual spec file.
67
- # if config.files_to_run.one?
68
- # # Use the documentation formatter for detailed output,
69
- # # unless a formatter has already been configured
70
- # # (e.g. via a command-line flag).
71
- # config.default_formatter = 'doc'
72
- # end
73
-
74
- # Print the 10 slowest examples and example groups at the
75
- # end of the spec run, to help surface which specs are running
76
- # particularly slow.
77
- config.profile_examples = 10
78
-
79
- # Run specs in random order to surface order dependencies. If you find an
80
- # order dependency and want to debug it, you can fix the order by providing
81
- # the seed, which is printed after each run.
82
- # --seed 1234
83
- config.order = :random
84
-
85
- # Seed global randomization in this process using the `--seed` CLI option.
86
- # Setting this allows you to use `--seed` to deterministically reproduce
87
- # test failures related to randomization by passing the same `--seed` value
88
- # as the one that triggered the failure.
89
- Kernel.srand config.seed
90
- end
91
-
92
- def clean_singleton(klass)
93
- [:@storage, :@env, :@app, :@root].each do |var|
94
- klass.instance_variable_defined?(var) && klass.remove_instance_variable(var)
95
- end
96
- end
@@ -1,268 +0,0 @@
1
- RSpec.describe A9n do
2
- subject { described_class }
3
- before { clean_singleton(subject) }
4
- after { clean_singleton(subject) }
5
-
6
- describe '.env' do
7
- before do
8
- subject.instance_variable_set(:@env, nil)
9
- end
10
-
11
- context 'app_env is set' do
12
- let(:app) { OpenStruct.new(env: ::A9n::StringInquirer.new('foo_env')) }
13
-
14
- before do
15
- allow(subject).to receive(:app).and_return(app)
16
- expect(subject).to receive(:env_var).never
17
- end
18
-
19
- it do
20
- expect(subject.env).to eq('foo_env')
21
- expect(subject.env.foo_env?).to eq(true)
22
- expect(subject.env.production?).to eq(false)
23
- end
24
- end
25
-
26
- context 'when APP_ENV is set' do
27
- before do
28
- expect(subject).to receive(:app_env).and_return(nil)
29
- expect(subject).to receive(:env_var).with('RAILS_ENV').and_return(nil)
30
- expect(subject).to receive(:env_var).with('RACK_ENV').and_return(nil)
31
- expect(subject).to receive(:env_var).with('APP_ENV').and_return('foo_env')
32
- end
33
-
34
- it do
35
- expect(subject.env).to eq('foo_env')
36
- expect(subject.env.foo_env?).to eq(true)
37
- expect(subject.env.production?).to eq(false)
38
- end
39
- end
40
-
41
- context 'unknown env' do
42
- before do
43
- expect(subject).to receive(:app_env).and_return(nil)
44
- expect(subject).to receive(:env_var).with('RAILS_ENV').and_return(nil)
45
- expect(subject).to receive(:env_var).with('RACK_ENV').and_return(nil)
46
- expect(subject).to receive(:env_var).with('APP_ENV').and_return(nil)
47
- end
48
-
49
- it do
50
- expect { subject.env }.to raise_error(A9n::UnknownEnvError)
51
- end
52
- end
53
- end
54
-
55
- describe '.groups' do
56
- before do
57
- subject.env = 'development'
58
- end
59
-
60
- it do
61
- expect(subject.groups).to eq(%w[default development])
62
- expect(subject.groups).to be_frozen
63
- end
64
- end
65
-
66
- describe '.app' do
67
- context 'when rails not found' do
68
- before do
69
- expect(subject).to receive(:rails_app).and_return(nil)
70
- end
71
-
72
- it do
73
- expect(subject.app).to be_nil
74
- end
75
- end
76
-
77
- context 'when rails app is being used' do
78
- let(:app) { double(env: 'test', root: '/apps/a9n') }
79
-
80
- before do
81
- expect(subject).to receive(:rails_app).and_return(app)
82
- end
83
-
84
- it do
85
- expect(subject.app).to eq(app)
86
- end
87
- end
88
-
89
- context 'when custom non-rails app is being used' do
90
- let(:app) { double(env: 'test', root: '/apps/a9n') }
91
-
92
- before do
93
- subject.app = app
94
- end
95
-
96
- it do
97
- expect(subject.app).to eq(app)
98
- end
99
- end
100
- end
101
-
102
- describe '.root' do
103
- context 'when app is set' do
104
- let(:app) { OpenStruct.new(env: 'test', root: '/apps/a9n') }
105
-
106
- before do
107
- subject.app = app
108
- end
109
-
110
- context 'with custom path' do
111
- before do
112
- subject.root = '/home/knapo/workspace/a9n'
113
- end
114
-
115
- it do
116
- expect(subject.root).to eq(Pathname.new('/home/knapo/workspace/a9n'))
117
- expect(subject.root).to be_frozen
118
- end
119
- end
120
-
121
- context 'with local app path' do
122
- it do
123
- expect(subject.root).to eq('/apps/a9n')
124
- end
125
- end
126
- end
127
-
128
- context 'when app is not set' do
129
- it do
130
- expect(subject.root).to eq(A9n.root_from_bundle_env)
131
- end
132
-
133
- context 'when setting a custom path' do
134
- before do
135
- subject.root = '/home/knapo/workspace/a9n'
136
- end
137
-
138
- it do
139
- expect(subject.root).to eq(Pathname.new('/home/knapo/workspace/a9n'))
140
- end
141
- end
142
- end
143
- end
144
-
145
- describe '.rails_app' do
146
- context 'when defined' do
147
- before do
148
- Object.const_set(:Rails, Module.new)
149
- end
150
-
151
- after do
152
- Object.send(:remove_const, :Rails)
153
- end
154
-
155
- it do
156
- expect(subject.rails_app).to be_kind_of(Module)
157
- end
158
- end
159
-
160
- context 'when not defined' do
161
- it do
162
- expect(subject.rails_app).to be_nil
163
- end
164
- end
165
- end
166
-
167
- describe '.env_var' do
168
- before do
169
- ENV['FOO'] = 'little foo'
170
- end
171
-
172
- it do
173
- expect(subject.env_var('FOO')).to eq('little foo')
174
- expect(subject.env_var('FOO')).to be_frozen
175
- end
176
-
177
- it do
178
- expect(subject.env_var('IS_FOO')).to be_nil
179
- end
180
- end
181
-
182
- describe '.default_files' do
183
- before do
184
- subject.root = File.expand_path('../../test_app', __dir__)
185
- end
186
-
187
- it do
188
- expect(subject.default_files[0]).to include('a9n.yml')
189
- expect(Pathname.new(subject.default_files[0])).to be_absolute
190
- expect(subject.default_files[1]).to include('a9n/aws.yml')
191
- expect(Pathname.new(subject.default_files[1])).to be_absolute
192
- end
193
- end
194
-
195
- describe '.load' do
196
- before do
197
- expect(described_class).to receive(:env).exactly(2).times.and_return('dev')
198
- subject.root = '/apps/test_app'
199
- files.each do |f, cfg|
200
- expect(A9n::Loader).to receive(:new).with(f, kind_of(A9n::Scope), 'dev').and_return(double(get: cfg))
201
- end
202
- end
203
-
204
- context 'when no files given' do
205
- let(:files) do
206
- {
207
- '/apps/test_app/config/file1.yml' => { host: 'host1.com' },
208
- '/apps/test_app/config/dir/file2.yml' => { host: 'host2.com' }
209
- }
210
- end
211
-
212
- before do
213
- expect(subject).to receive(:default_files).and_return(files.keys)
214
- expect(subject).to receive(:absolute_paths_for).never
215
- end
216
-
217
- it do
218
- expect(subject.load).to eq(files.values)
219
- end
220
- end
221
-
222
- context 'when custom files given' do
223
- let(:given_files) do
224
- ['file3.yml', '/apps/test_app/config/dir/file4.yml']
225
- end
226
-
227
- let(:files) do
228
- {
229
- '/apps/test_app/config/file3.yml' => { host: 'host3.com' },
230
- '/apps/test_app/config/dir/file4.yml' => { host: 'host4.com' }
231
- }
232
- end
233
-
234
- before do
235
- expect(subject).to receive(:default_files).never
236
- expect(subject).to receive(:absolute_paths_for).with(given_files).and_call_original
237
- end
238
-
239
- it do
240
- expect(subject.load(*given_files)).to eq(files.values)
241
- end
242
- end
243
- end
244
-
245
- describe '.method_missing' do
246
- context 'when storage is empty' do
247
- before do
248
- expect(subject).to receive(:load).once
249
- end
250
-
251
- it do
252
- expect(subject.storage).to be_empty
253
- expect { subject.whatever }.to raise_error(A9n::NoSuchConfigurationVariableError)
254
- end
255
- end
256
-
257
- context 'when storage is not empty' do
258
- before do
259
- subject.storage[:whenever] = 'whenever'
260
- expect(subject).not_to receive(:load)
261
- end
262
-
263
- it do
264
- expect { subject.whatever }.to raise_error(A9n::NoSuchConfigurationVariableError)
265
- end
266
- end
267
- end
268
- end
@@ -1,207 +0,0 @@
1
- RSpec.describe A9n::Loader do
2
- let(:scope) { A9n::Scope.new('a9n') }
3
- let(:env) { 'test' }
4
- let(:root) { File.expand_path('../../test_app', __dir__) }
5
- let(:file_path) { File.join(root, 'config/a9n.yml') }
6
- subject { described_class.new(file_path, scope, env) }
7
-
8
- describe '#intialize' do
9
- it { expect(subject.scope).to eq(scope) }
10
- it { expect(subject.env).to eq(env) }
11
- it { expect(subject.local_file).to eq(file_path) }
12
- it { expect(subject.example_file).to eq("#{file_path}.example") }
13
- end
14
-
15
- describe '#load' do
16
- let(:example_config) do
17
- { app_url: 'http://127.0.0.1:3000', api_key: 'example1234' }
18
- end
19
-
20
- let(:local_config) do
21
- { app_host: '127.0.0.1:3000', api_key: 'local1234' }
22
- end
23
-
24
- let(:env) { 'tropical' }
25
- let(:config) { subject.get }
26
-
27
- context 'when no configuration file exists' do
28
- before do
29
- expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(nil)
30
- expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(nil)
31
- end
32
-
33
- it 'raises expection' do
34
- expect {
35
- subject.load
36
- }.to raise_error(A9n::MissingConfigurationDataError)
37
- end
38
- end
39
-
40
- context 'when only example configuration file exists' do
41
- before do
42
- expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
43
- expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(nil)
44
- subject.load
45
- end
46
-
47
- it { expect(config.app_url).to eq('http://127.0.0.1:3000') }
48
- it { expect(config.api_key).to eq('example1234') }
49
-
50
- it do
51
- expect { config.app_host }.to raise_error(A9n::NoSuchConfigurationVariableError)
52
- end
53
- end
54
-
55
- context 'when only local configuration file exists' do
56
- before do
57
- expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(nil)
58
- expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(local_config)
59
- subject.load
60
- end
61
-
62
- it { expect(config.app_host).to eq('127.0.0.1:3000') }
63
- it { expect(config.api_key).to eq('local1234') }
64
-
65
- it do
66
- expect { config.app_url }.to raise_error(A9n::NoSuchConfigurationVariableError)
67
- end
68
- end
69
-
70
- context 'when both local and base configuration file exists without defaults' do
71
- context 'with same data' do
72
- before do
73
- expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
74
- expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(example_config)
75
- subject.load
76
- end
77
-
78
- it { expect(config.app_url).to eq('http://127.0.0.1:3000') }
79
- it { expect(config.api_key).to eq('example1234') }
80
-
81
- it do
82
- expect { config.app_host }.to raise_error(A9n::NoSuchConfigurationVariableError)
83
- end
84
- end
85
-
86
- context 'with different data' do
87
- before do
88
- expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
89
- expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(local_config)
90
- end
91
-
92
- let(:missing_variables_names) { example_config.keys - local_config.keys }
93
-
94
- it 'raises expection with missing variables names' do
95
- expect {
96
- subject.load
97
- }.to raise_error(A9n::MissingConfigurationVariablesError, /#{missing_variables_names.join(', ')}/)
98
- end
99
- end
100
- end
101
- end
102
-
103
- describe '.load_yml' do
104
- let(:env) { 'test' }
105
- subject { described_class.load_yml(file_path, scope, env) }
106
-
107
- context 'when file not exists' do
108
- let(:file_path) { 'file_not_existing_in_the_universe.yml' }
109
-
110
- it { expect(subject).to be_nil }
111
- end
112
-
113
- context 'when file exists' do
114
- shared_examples 'non-empty config file' do
115
- it 'returns non-empty hash' do
116
- expect(subject).to be_kind_of(Hash)
117
- expect(subject).to be_frozen
118
- expect(subject.keys).to_not be_empty
119
- end
120
- end
121
-
122
- before do
123
- ENV['ERB_FOO'] = 'erbized foo'
124
- ENV['FOO_PASSWORD'] = 'foo123'
125
- ENV['FOO_KEY'] = 'key123'
126
- end
127
-
128
- after do
129
- ENV.delete('ERB_FOO')
130
- ENV.delete('FOO_PASSWORD')
131
- ENV.delete('FOO_KEY')
132
- end
133
-
134
- context 'when file has erb extension' do
135
- let(:file_path) { File.join(root, 'config/a9n/cloud.yml.erb') }
136
-
137
- it_behaves_like 'non-empty config file'
138
- end
139
-
140
- context 'having env and defaults data' do
141
- let(:file_path) { File.join(root, 'config/a9n.yml') }
142
-
143
- it_behaves_like 'non-empty config file'
144
-
145
- it 'contains only frozen values' do
146
- expect(subject.values.reject(&:frozen?)).to eq([])
147
- end
148
-
149
- it 'contains keys from defaults scope' do
150
- expect(subject[:default_foo]).to eq('default foo')
151
- expect(subject[:overriden_foo]).to eq('already overriden foo')
152
- end
153
-
154
- it 'has symbolized keys' do
155
- expect(subject.keys.first).to be_kind_of(Symbol)
156
- expect(subject[:hash_foo]).to be_kind_of(Hash)
157
- expect(subject[:hash_foo].keys.first).to be_kind_of(Symbol)
158
- expect(subject[:hash_foo]).to eq(foo_1: 'hello 1', foo_2: 'hello 2', foo_key: 'key123')
159
- end
160
-
161
- it 'parses erb' do
162
- expect(subject[:erb_foo]).to eq('erbized foo')
163
- end
164
-
165
- it 'gets valus from ENV' do
166
- expect(subject[:foo_password]).to eq('foo123')
167
- end
168
-
169
- it 'raises exception when ENV var is not set' do
170
- ENV.delete('FOO_PASSWORD')
171
- expect { subject[:foo_password] }.to raise_error(A9n::MissingEnvVariableError)
172
- end
173
-
174
- it 'raises exception when ENV var is set to nil' do
175
- ENV['FOO_PASSWORD'] = nil
176
- expect { subject[:foo_password] }.to raise_error(A9n::MissingEnvVariableError)
177
- end
178
- end
179
-
180
- context 'having no env and only defaults data' do
181
- let(:file_path) { File.join(root, 'config/a9n.yml') }
182
- let(:env) { 'production' }
183
-
184
- it_behaves_like 'non-empty config file'
185
-
186
- it 'contains keys from defaults scope' do
187
- expect(subject[:default_foo]).to eq('default foo')
188
- expect(subject[:overriden_foo]).to eq('not yet overriden foo')
189
- end
190
- end
191
-
192
- context 'having only env and no default data' do
193
- let(:file_path) { File.join(root, 'config/no_defaults.yml') }
194
-
195
- context 'valid env' do
196
- let(:env) { 'production' }
197
- it_behaves_like 'non-empty config file'
198
- end
199
-
200
- context 'invalid env' do
201
- let(:env) { 'tropical' }
202
- it { expect(subject).to be_nil }
203
- end
204
- end
205
- end
206
- end
207
- end