envied 0.9.1 → 0.9.2

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.
data/spec/envied_spec.rb CHANGED
@@ -1,112 +1,93 @@
1
- require 'spec_helper'
2
-
3
- describe ENVied do
1
+ RSpec.describe ENVied do
4
2
  describe 'class' do
5
3
  subject { described_class }
6
-
7
4
  it { is_expected.to respond_to :require }
8
5
  end
9
6
 
10
- describe 'responding to methods that are variables' do
11
- end
12
-
13
- before do
14
- reset_env
15
- reset_envied_config
16
- reset_configuration
17
- end
18
-
19
- def reset_configuration
20
- @config = ENVied::Configuration.new
21
- end
22
-
23
- def reset_env
24
- ENVied.instance_eval { @env = nil }
25
- end
26
-
27
- def reset_envied_config
28
- ENVied.instance_eval { @config = nil }
7
+ def reset_envied
8
+ ENVied.instance_eval do
9
+ @env = nil
10
+ @config = nil
11
+ end
29
12
  end
30
13
 
31
14
  context 'configured' do
32
15
 
33
- def unconfigured
34
- configured_with
35
- self
16
+ before do
17
+ reset_envied
36
18
  end
37
19
 
38
- def config
39
- @config
20
+ def set_ENV(env = {})
21
+ stub_const("ENV", env)
40
22
  end
41
23
 
42
- def configure(options = {}, &block)
24
+ def configure(**options, &block)
43
25
  @config = ENVied::Configuration.new(options, &block)
44
- self
45
26
  end
46
27
 
47
- def configured_with(hash = {})
48
- @config = ENVied::Configuration.new.tap do |c|
28
+ def configured_with(**hash)
29
+ @config = ENVied::Configuration.new.tap do |config|
49
30
  hash.each do |name, type|
50
- c.variable(name, *type)
31
+ config.variable(name, type)
51
32
  end
52
33
  end
53
- self
54
- end
55
-
56
- def and_ENV(env = {})
57
- stub_const("ENV", env)
58
- described_class
59
34
  end
60
35
 
61
- def and_no_ENV
62
- and_ENV
36
+ def envied_require(*args, **options)
37
+ options[:config] = @config || ENVied::Configuration.new # Prevent `Configuration.load` from being called
38
+ ENVied.require(*args, **options)
63
39
  end
64
40
 
65
- def envied_require(*args)
66
- options = args.last.is_a?(Hash) ? args.pop : {}
67
- options[:config] = options[:config] || config
68
-
69
- ENVied.require(*args, options)
70
- end
71
-
72
- it 'responds to configured variables' do
73
- configured_with(a: :integer).and_ENV({'a' => '1'})
41
+ it 'does respond to configured variables' do
42
+ set_ENV('A' => '1')
43
+ configured_with(A: :integer)
74
44
  envied_require
75
45
 
76
- expect(described_class).to respond_to :a
46
+ expect(described_class).to respond_to :A
77
47
  end
78
48
 
79
- it 'responds not to unconfigured variables' do
80
- unconfigured.and_ENV({'A' => '1'})
49
+ it 'does not respond to unconfigured variables' do
50
+ set_ENV('A' => '1')
51
+ configured_with
81
52
  envied_require
82
53
 
83
54
  expect(described_class).to_not respond_to :B
84
55
  end
85
56
 
86
57
  it 'sets ENVied.config' do
87
- configured_with(a: :integer).and_ENV({'a' => '1'})
58
+ set_ENV('A' => '1')
59
+ configured_with(A: :integer)
88
60
  envied_require
89
61
 
90
- expect(ENVied.config).to_not be(nil)
62
+ expect(ENVied.config).to be_instance_of(ENVied::Configuration)
91
63
  end
92
64
 
93
65
  context 'ENV contains not all configured variables' do
94
- before { configured_with(a: :integer).and_no_ENV }
66
+ before do
67
+ set_ENV
68
+ configured_with(A: :integer)
69
+ end
95
70
 
96
71
  specify do
97
72
  expect {
98
73
  envied_require
99
- }.to raise_error(RuntimeError, 'The following environment variables should be set: a.')
74
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: A.')
100
75
  end
101
76
  end
102
77
 
103
78
  context 'ENV variables are not coercible' do
104
- before { configured_with(A: :integer).and_ENV('A' => 'NaN') }
79
+ before do
80
+ set_ENV('A' => 'NaN', 'B' => 'invalid')
81
+ configured_with(A: :integer, B: :boolean)
82
+ end
105
83
 
106
84
  specify do
107
85
  expect {
108
86
  envied_require
109
- }.to raise_error(/A \('NaN' can't be coerced to integer/)
87
+ }.to raise_error(
88
+ RuntimeError,
89
+ 'The following environment variables are not coercible: A with "NaN" (integer), B with "invalid" (boolean).'
90
+ )
110
91
  end
111
92
  end
112
93
 
@@ -114,16 +95,17 @@ describe ENVied do
114
95
  it 'raises error when configuring variable of unknown type' do
115
96
  expect {
116
97
  configured_with(A: :fixnum)
117
- }.to raise_error(ArgumentError, /Variable type \(of A\) should be one of \[/)
98
+ }.to raise_error(ArgumentError, ":fixnum is not a supported type. Should be one of #{ENVied::Coercer.supported_types}")
118
99
  end
119
100
  end
120
101
 
102
+ # TODO: review needed, doesn't make sense?
121
103
  context 'bug: default value "false" is not coercible' do
122
- before {
104
+ before do
123
105
  configure(enable_defaults: true) do
124
106
  variable :FORCE_SSL, :boolean, default: true
125
107
  end
126
- }
108
+ end
127
109
 
128
110
  specify do
129
111
  expect {
@@ -133,41 +115,8 @@ describe ENVied do
133
115
  end
134
116
 
135
117
  describe 'defaults' do
136
- describe 'setting' do
137
- subject { config }
138
-
139
- it 'is disabled by default' do
140
- expect(subject.defaults_enabled?).to_not be
141
- end
142
-
143
- it 'yields ENV["ENVIED_ENABLE_DEFAULTS"] if not set otherwise' do
144
- stub_const("ENV", {'ENVIED_ENABLE_DEFAULTS' => '1'})
145
- configure
146
-
147
- expect(subject.defaults_enabled?).to be
148
- end
149
-
150
- it 'can be enabled via #configure' do
151
- configure(enable_defaults: true){ }
152
-
153
- expect(subject.defaults_enabled?).to be
154
- end
155
-
156
- it 'can be enabled via a configure-block' do
157
- configure { self.enable_defaults! }
158
-
159
- expect(subject.defaults_enabled?).to be
160
- end
161
-
162
- it 'can be assigned a Proc' do
163
- configure { self.enable_defaults! { true } }
164
-
165
- expect(subject.defaults_enabled?).to be
166
- end
167
- end
168
-
169
118
  describe 'assigning' do
170
- it 'can be a value' do
119
+ it 'sets a default value for ENV variable' do
171
120
  configure(enable_defaults: true) do
172
121
  variable :A, :integer, default: '1'
173
122
  end
@@ -176,7 +125,7 @@ describe ENVied do
176
125
  expect(described_class.A).to eq 1
177
126
  end
178
127
 
179
- it 'can be a Proc' do
128
+ it 'sets a default value from calling a proc for ENV variable' do
180
129
  configure(enable_defaults: true) do
181
130
  variable :A, :integer, default: proc { "1" }
182
131
  end
@@ -185,30 +134,34 @@ describe ENVied do
185
134
  expect(described_class.A).to eq 1
186
135
  end
187
136
 
188
- it 'is ignored if defaults are disabled' do
137
+ it 'ignores setting defaults if they are disabled' do
138
+ set_ENV
189
139
  configure(enable_defaults: false) do
190
140
  variable :A, :integer, default: "1"
191
- end.and_no_ENV
141
+ variable :B, :integer, default: "1"
142
+ end
192
143
 
193
144
  expect {
194
145
  envied_require
195
- }.to raise_error(RuntimeError, 'The following environment variables should be set: A.')
146
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: A, B.')
196
147
  end
197
148
 
198
- it 'is ignored if ENV is provided' do
149
+ it 'ignores a default value if ENV variable is already provided' do
150
+ set_ENV('A' => '2')
199
151
  configure(enable_defaults: true) do
200
152
  variable :A, :integer, default: "1"
201
- end.and_ENV('A' => '2')
153
+ end
202
154
  envied_require
203
155
 
204
156
  expect(described_class.A).to eq 2
205
157
  end
206
158
 
207
- it 'can be defined in terms of other variables' do
159
+ it 'can set a default value via a proc that references another ENV variable' do
160
+ set_ENV('A' => '1')
208
161
  configure(enable_defaults: true) do
209
162
  variable :A, :integer
210
163
  variable :B, :integer, default: proc {|env| env.A * 2 }
211
- end.and_ENV('A' => '1')
164
+ end
212
165
  envied_require
213
166
 
214
167
  expect(described_class.B).to eq 2
@@ -216,8 +169,9 @@ describe ENVied do
216
169
  end
217
170
  end
218
171
 
219
- describe "::required?" do
220
- it 'yields true-ish when ::require is called' do
172
+ describe ".required?" do
173
+ # TODO: change to always return boolean
174
+ it 'returns true-ish if `ENVied.require` was called' do
221
175
  expect {
222
176
  envied_require
223
177
  }.to change { ENVied.required? }.from(nil).to(anything)
@@ -225,154 +179,159 @@ describe ENVied do
225
179
  end
226
180
 
227
181
  describe "groups" do
228
- describe 'requiring' do
229
-
230
- it 'yields :default when nothing passed to require' do
231
- envied_require
232
- expect(ENVied.env.groups).to eq [:default]
233
- end
234
-
235
- it 'takes ENV["ENVIED_GROUPS"] into account when nothing passed to require' do
236
- and_ENV('ENVIED_GROUPS' => 'baz')
237
- envied_require
238
- expect(ENVied.env.groups).to eq [:baz]
239
- end
240
-
241
- it 'yields groupnames passed to it as string' do
242
- envied_require('bar')
243
- expect(ENVied.env.groups).to eq [:bar]
244
- end
245
-
246
- it 'yields groupnames passed to it as symbols' do
247
- envied_require(:foo)
248
- expect(ENVied.env.groups).to eq [:foo]
249
- end
250
-
251
- it 'yields the groups passed via a string with groupnames' do
252
- envied_require('foo,bar')
253
- expect(ENVied.env.groups).to eq [:foo, :bar]
254
- end
255
- end
256
-
257
182
  context 'a variable in a group' do
258
183
  before do
184
+ set_ENV
259
185
  configure do
260
- variable :moar
186
+ variable :MORE
261
187
 
262
188
  group :foo do
263
- variable :bar
189
+ variable :BAR
264
190
  end
265
- end.and_no_ENV
191
+ group :moo do
192
+ variable :BAT
193
+ end
194
+ end
266
195
  end
267
196
 
268
- it 'is required when requiring the group' do
197
+ it 'is required when requiring the groups passed as a delimited string' do
269
198
  expect {
270
- envied_require(:foo)
271
- }.to raise_error(/bar/)
199
+ envied_require('foo,moo')
200
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: BAR, BAT.')
201
+ end
202
+
203
+ it 'is required when requiring the group' do
204
+ [:foo, 'foo'].each do |group|
205
+ expect {
206
+ envied_require(group)
207
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: BAR.')
208
+ end
272
209
  end
273
210
 
274
211
  it 'is not required when requiring another group' do
275
- expect {
276
- envied_require(:bat)
277
- }.to_not raise_error
212
+ [:bat, 'bat'].each do |group|
213
+ expect {
214
+ envied_require(group)
215
+ }.to_not raise_error
216
+ end
278
217
  end
279
218
 
280
- it 'wont define non-required variables on ENVied' do
281
- stub_const("ENV", {'moar' => 'yes'})
219
+ it 'will not define variables not part of the default group' do
220
+ set_ENV('MORE' => 'yes')
282
221
  envied_require(:default)
283
222
 
284
223
  expect {
285
- described_class.bar
224
+ described_class.BAR
286
225
  }.to raise_error(NoMethodError)
287
226
  end
288
227
 
228
+ it 'takes ENV["ENVIED_GROUPS"] into account when nothing is passed to require' do
229
+ set_ENV('ENVIED_GROUPS' => 'foo')
230
+ expect {
231
+ envied_require
232
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: BAR.')
233
+ end
234
+
235
+ it 'will define variables in the default group when nothing is passed to require' do
236
+ set_ENV('MORE' => 'yes')
237
+ envied_require
238
+
239
+ expect(described_class.MORE).to eq 'yes'
240
+ end
241
+
289
242
  it 'requires variables without a group when requiring the default group' do
290
- [:default, 'default'].each do |groups|
243
+ [:default, 'default'].each do |group|
291
244
  expect {
292
- envied_require(*groups)
293
- }.to raise_error(/moar/)
245
+ envied_require(group)
246
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: MORE.')
294
247
  end
295
248
  end
296
249
  end
297
250
 
298
251
  context 'a variable in multiple groups' do
299
252
  before do
253
+ set_ENV
300
254
  configure do
301
- variable :moar
255
+ variable :MORE
302
256
 
303
257
  group :foo, :moo do
304
- variable :bar
258
+ variable :BAR
305
259
  end
306
- end.and_no_ENV
260
+ end
307
261
  end
308
262
 
309
263
  it 'is required when requiring any of the groups' do
310
264
  expect {
311
265
  envied_require(:foo)
312
- }.to raise_error(/bar/)
266
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: BAR.')
313
267
 
314
268
  expect {
315
269
  envied_require(:moo)
316
- }.to raise_error(/bar/)
270
+ }.to raise_error(RuntimeError, 'The following environment variables should be set: BAR.')
317
271
  end
318
272
  end
319
273
 
320
274
  describe 'Hashable' do
321
275
  before do
276
+ set_ENV('FOO' => 'a=1&b=&c', 'BAR' => '')
322
277
  configure do
323
- variable :foo, :hash
324
- variable :bar, :hash
325
- end.and_ENV('foo' => 'a=1&b=&c', 'bar' => '')
278
+ variable :FOO, :hash
279
+ variable :BAR, :hash
280
+ end
326
281
  envied_require
327
282
  end
328
283
 
329
284
  it 'yields hash from string' do
330
- expect(ENVied.foo).to eq Hash['a'=> '1', 'b' => '', 'c' => nil]
285
+ expect(ENVied.FOO).to eq({ 'a' => '1', 'b' => '', 'c' => nil })
331
286
  end
332
287
 
333
288
  it 'yields hash from an empty string' do
334
- expect(ENVied.bar).to eq Hash.new
289
+ expect(ENVied.BAR).to eq({})
335
290
  end
336
291
 
337
292
  context 'with defaults enabled' do
338
293
  before do
294
+ set_ENV
339
295
  configure(enable_defaults: true) do
340
- variable :baz, :hash
341
- end.and_no_ENV
296
+ variable :BAZ, :hash
297
+ end
342
298
  end
343
299
 
344
300
  it 'has no default by default' do
345
301
  # fixes a bug where variables of type :Hash had a default even
346
302
  # when none was configured.
347
- expect { envied_require }.to raise_error(RuntimeError, 'The following environment variables should be set: baz.')
303
+ expect { envied_require }.to raise_error(RuntimeError, 'The following environment variables should be set: BAZ.')
348
304
  end
349
305
  end
350
306
  end
351
307
 
352
308
  describe 'Arrayable' do
353
309
  before do
310
+ set_ENV('MORE' => 'a, b, and\, c')
354
311
  configure do
355
- variable :moar, :array
356
- end.and_ENV('moar' => 'a, b, and\, c')
312
+ variable :MORE, :array
313
+ end
357
314
  envied_require
358
315
  end
359
316
 
360
317
  it 'yields array from string' do
361
- expect(ENVied.moar).to eq ['a',' b',' and, c']
318
+ expect(ENVied.MORE).to eq ['a',' b',' and, c']
362
319
  end
363
320
  end
364
321
 
365
322
  describe 'URIable' do
366
323
  before do
324
+ set_ENV('SITE_URL' => 'https://www.google.com')
367
325
  configure do
368
- variable :site_url, :uri
369
- end.and_ENV('site_url' => 'https://www.google.com')
326
+ variable :SITE_URL, :uri
327
+ end
370
328
  envied_require
371
329
  end
372
330
 
373
331
  it 'yields a URI from string' do
374
- expect(ENVied.site_url).to be_a URI
375
- expect(ENVied.site_url.host).to eq 'www.google.com'
332
+ expect(ENVied.SITE_URL).to be_a URI
333
+ expect(ENVied.SITE_URL.scheme).to eq 'https'
334
+ expect(ENVied.SITE_URL.host).to eq 'www.google.com'
376
335
  end
377
336
  end
378
337
  end
@@ -0,0 +1,17 @@
1
+ require "open3"
2
+
3
+ RSpec.describe 'envied.gemspec' do
4
+ let!(:build) { Open3.capture3("gem build envied.gemspec") }
5
+
6
+ after do
7
+ Dir.glob("envied-*.gem").each { |f| File.delete(f) }
8
+ end
9
+
10
+ it 'builds without warnings' do
11
+ expect(build[1]).to_not match(/WARNING/)
12
+ end
13
+
14
+ it 'builds successfully' do
15
+ expect(build[2].success?).to eq true
16
+ end
17
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,74 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- Bundler.setup
1
+ require "bundler/setup"
2
+ require "envied"
4
3
 
5
- $:.unshift File.expand_path("../../lib", __FILE__)
6
- require 'envied'
4
+ RSpec.configure do |config|
5
+ # rspec-expectations config goes here. You can use an alternate
6
+ # assertion/expectation library such as wrong or the stdlib/minitest
7
+ # assertions if you prefer.
8
+ config.expect_with :rspec do |expectations|
9
+ # This option will default to `true` in RSpec 4. It makes the `description`
10
+ # and `failure_message` of custom matchers include text for helper methods
11
+ # defined using `chain`, e.g.:
12
+ # be_bigger_than(2).and_smaller_than(4).description
13
+ # # => "be bigger than 2 and smaller than 4"
14
+ # ...rather than:
15
+ # # => "be bigger than 2"
16
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
17
+ end
18
+
19
+ # rspec-mocks config goes here. You can use an alternate test double
20
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
21
+ config.mock_with :rspec do |mocks|
22
+ # Prevents you from mocking or stubbing a method that does not exist on
23
+ # a real object. This is generally recommended, and will default to
24
+ # `true` in RSpec 4.
25
+ mocks.verify_partial_doubles = true
26
+ end
27
+
28
+ # These two settings work together to allow you to limit a spec run
29
+ # to individual examples or groups you care about by tagging them with
30
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
31
+ # get run.
32
+ # config.filter_run :focus
33
+ # config.run_all_when_everything_filtered = true
34
+
35
+ # Allows RSpec to persist some state between runs in order to support
36
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
37
+ # you configure your source control system to ignore this file.
38
+ config.example_status_persistence_file_path = "spec/examples.txt"
39
+
40
+ # Limits the available syntax to the non-monkey patched syntax that is
41
+ # recommended. For more details, see:
42
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
43
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
44
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
45
+ config.disable_monkey_patching!
46
+
47
+ # Many RSpec users commonly either run the entire suite or an individual
48
+ # file, and it's useful to allow more verbose output when running an
49
+ # individual spec file.
50
+ if config.files_to_run.one?
51
+ # Use the documentation formatter for detailed output,
52
+ # unless a formatter has already been configured
53
+ # (e.g. via a command-line flag).
54
+ config.default_formatter = 'doc'
55
+ end
56
+
57
+ # Print the 10 slowest examples and example groups at the
58
+ # end of the spec run, to help surface which specs are running
59
+ # particularly slow.
60
+ # config.profile_examples = 10
61
+
62
+ # Run specs in random order to surface order dependencies. If you find an
63
+ # order dependency and want to debug it, you can fix the order by providing
64
+ # the seed, which is printed after each run.
65
+ # --seed 1234
66
+ config.order = :random
67
+
68
+ # Seed global randomization in this process using the `--seed` CLI option.
69
+ # Setting this allows you to use `--seed` to deterministically reproduce
70
+ # test failures related to randomization by passing the same `--seed` value
71
+ # as the one that triggered the failure.
72
+ Kernel.srand config.seed
73
+
74
+ end
@@ -1,15 +1,25 @@
1
- require 'spec_helper'
2
-
3
- describe ENVied::Variable do
1
+ RSpec.describe ENVied::Variable do
4
2
  def variable(*args)
5
3
  described_class.new(*args)
6
4
  end
7
5
 
8
- def set_env(env)
9
- stub_const("ENV", env)
10
- end
11
-
12
6
  describe 'an instance' do
13
7
  subject { variable(:A, :string) }
8
+ it { is_expected.to respond_to :name }
9
+ it { is_expected.to respond_to :type }
10
+ it { is_expected.to respond_to :group }
11
+ it { is_expected.to respond_to :default }
12
+ it { is_expected.to respond_to :== }
13
+ it { is_expected.to respond_to :default_value }
14
+ end
15
+
16
+ describe 'defaults' do
17
+ it 'returns the default value as it is' do
18
+ expect(variable(:A, :string, default: 'A').default_value).to eq 'A'
19
+ end
20
+
21
+ it 'returns the default value from calling the proc provided' do
22
+ expect(variable(:A, :string, default: ->{ 'A' * 2 }).default_value).to eq 'AA'
23
+ end
14
24
  end
15
25
  end