envied 0.9.3 → 0.10.0.alpha1
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.
- checksums.yaml +4 -4
- data/.envrc.sample +9 -0
- data/.github/pull_request_template.md +2 -0
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +4 -3
- data/.rspec +1 -0
- data/CHANGELOG.md +13 -1
- data/LICENSE.txt +1 -1
- data/README.md +154 -54
- data/bin/bundle +105 -0
- data/bin/console +2 -6
- data/bin/envied +3 -2
- data/bin/rspec +29 -0
- data/envied.gemspec +15 -5
- data/examples/extensive_envfile +0 -2
- data/exe/envied +4 -0
- data/lib/envied.rb +17 -0
- data/lib/envied/cli.rb +9 -0
- data/lib/envied/coercer.rb +1 -1
- data/lib/envied/coercer/envied_string.rb +4 -0
- data/lib/envied/configuration.rb +14 -32
- data/lib/envied/env_interceptor.rb +19 -0
- data/lib/envied/env_proxy.rb +8 -5
- data/lib/envied/templates/Envfile.tt +5 -3
- data/lib/envied/variable.rb +2 -11
- data/lib/envied/version.rb +1 -1
- metadata +32 -27
- data/spec/coercer_spec.rb +0 -274
- data/spec/configuration_spec.rb +0 -113
- data/spec/env_var_extractor_spec.rb +0 -22
- data/spec/envied_spec.rb +0 -339
- data/spec/gemspec_spec.rb +0 -17
- data/spec/spec_helper.rb +0 -74
- data/spec/variable_spec.rb +0 -25
data/spec/coercer_spec.rb
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
RSpec.describe ENVied::Coercer do
|
2
|
-
it { is_expected.to respond_to :coerce }
|
3
|
-
it { is_expected.to respond_to :coerced? }
|
4
|
-
it { is_expected.to respond_to :coercible? }
|
5
|
-
it { is_expected.to respond_to :supported_types }
|
6
|
-
it { is_expected.to respond_to :supported_type? }
|
7
|
-
|
8
|
-
describe '.supported_types' do
|
9
|
-
it 'returns a sorted set of supported types' do
|
10
|
-
expect(described_class.supported_types).to eq %i(array boolean date float hash integer string symbol time uri)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe '.supported_type?' do
|
15
|
-
it 'returns true for supported type' do
|
16
|
-
%i(array boolean date float hash integer string symbol time uri).each do |type|
|
17
|
-
expect(described_class.supported_type?(type)).to eq true
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'returns false for unsupported type' do
|
22
|
-
expect(described_class.supported_type?(:fixnum)).to eq false
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '#supported_types' do
|
27
|
-
it 'calls class method implementation' do
|
28
|
-
expect(described_class).to receive(:supported_types).and_call_original
|
29
|
-
described_class.new.supported_types
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '#supported_type?' do
|
34
|
-
it 'calls class method implementation' do
|
35
|
-
expect(described_class).to receive(:supported_type?).with(:string).and_call_original
|
36
|
-
described_class.new.supported_type?(:string)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#coerced?' do
|
41
|
-
let(:coercer) { described_class.new }
|
42
|
-
|
43
|
-
it 'returns true if value has been coerced (not a string)' do
|
44
|
-
expect(coercer.coerced?(1)).to eq true
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'returns false if value is not a string' do
|
48
|
-
expect(coercer.coerced?('1')).to eq false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe '#coercible?' do
|
53
|
-
let(:coercer) { described_class.new }
|
54
|
-
|
55
|
-
it 'returns false for unsupported type' do
|
56
|
-
expect(coercer.coercible?('value', :invalid_type)).to eq false
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'returns false for a failed coercion' do
|
60
|
-
expect(coercer.coercible?('value', :boolean)).to eq false
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'returns true for a coercible value' do
|
64
|
-
expect(coercer.coercible?('value', :string)).to eq true
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '#coerce' do
|
69
|
-
let(:coercer){ described_class.new }
|
70
|
-
|
71
|
-
def coerce(str, type)
|
72
|
-
coercer.coerce(str, type)
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'fails with an invalid type' do
|
76
|
-
expect { coerce('', :fixnum) }.to raise_error(ArgumentError, "The type `:fixnum` is not supported.")
|
77
|
-
end
|
78
|
-
|
79
|
-
describe 'to string' do
|
80
|
-
it 'returns the input untouched' do
|
81
|
-
expect(coerce('1', :string)).to eq '1'
|
82
|
-
expect(coerce(' 1', :string)).to eq ' 1'
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'fails when the value does not respond to #to_str' do
|
86
|
-
value = Object.new
|
87
|
-
expect { coerce(value, :string) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe 'to integer' do
|
92
|
-
{
|
93
|
-
'1' => 1,
|
94
|
-
'+1' => 1,
|
95
|
-
'-1' => -1,
|
96
|
-
'10' => 10,
|
97
|
-
'100_00' => 100_00,
|
98
|
-
'1_000_00' => 1_000_00
|
99
|
-
}.each do |value, integer|
|
100
|
-
it "converts #{value.inspect} to an integer" do
|
101
|
-
expect(coerce(value, :integer)).to be_kind_of(Integer)
|
102
|
-
expect(coerce(value, :integer)).to eq integer
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'fails with an invalid string' do
|
107
|
-
expect { coerce('non-integer', :integer) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'fails with a float' do
|
111
|
-
expect { coerce('1.23', :integer) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
describe 'to float' do
|
116
|
-
{
|
117
|
-
'1' => 1.0,
|
118
|
-
'+1' => 1.0,
|
119
|
-
'-1' => -1.0,
|
120
|
-
'1_000.0' => 1_000.0,
|
121
|
-
'10_000.23' => 10_000.23,
|
122
|
-
'1_000_000.0' => 1_000_000.0,
|
123
|
-
'1.0' => 1.0,
|
124
|
-
'1.234' => 1.234,
|
125
|
-
'1.0e+1' => 10.0,
|
126
|
-
'1.0e-1' => 0.1,
|
127
|
-
'1.0E+1' => 10.0,
|
128
|
-
'1.0E-1' => 0.1,
|
129
|
-
'+1.0' => 1.0,
|
130
|
-
'+1.0e+1' => 10.0,
|
131
|
-
'+1.0e-1' => 0.1,
|
132
|
-
'+1.0E+1' => 10.0,
|
133
|
-
'+1.0E-1' => 0.1,
|
134
|
-
'-1.0' => -1.0,
|
135
|
-
'-1.234' => -1.234,
|
136
|
-
'-1.0e+1' => -10.0,
|
137
|
-
'-1.0e-1' => -0.1,
|
138
|
-
'-1.0E+1' => -10.0,
|
139
|
-
'-1.0E-1' => -0.1,
|
140
|
-
'.1' => 0.1,
|
141
|
-
'.1e+1' => 1.0,
|
142
|
-
'.1e-1' => 0.01,
|
143
|
-
'.1E+1' => 1.0,
|
144
|
-
'.1E-1' => 0.01,
|
145
|
-
'1e1' => 10.0,
|
146
|
-
'1E+1' => 10.0,
|
147
|
-
'+1e-1' => 0.1,
|
148
|
-
'-1E1' => -10.0,
|
149
|
-
'-1e-1' => -0.1,
|
150
|
-
}.each do |value, float|
|
151
|
-
it "converts #{value.inspect} to a float" do
|
152
|
-
expect(coerce(value, :float)).to be_kind_of(Float)
|
153
|
-
expect(coerce(value, :float)).to eq float
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
it 'fails with an invalid string' do
|
158
|
-
expect { coerce('non-float', :float) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'fails when string starts with e' do
|
162
|
-
expect { coerce('e1', :float) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
describe 'to boolean' do
|
167
|
-
%w[ 1 on ON t true T TRUE y yes Y YES ].each do |value|
|
168
|
-
it "converts #{value.inspect} to `true`" do
|
169
|
-
expect(coerce(value, :boolean)).to eq true
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
%w[ 0 off OFF f false F FALSE n no N NO ].each do |value|
|
174
|
-
it "converts #{value.inspect} to `false`" do
|
175
|
-
expect(coerce(value, :boolean)).to eq false
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'fails with an invalid boolean string' do
|
180
|
-
expect { coerce('non-boolean', :boolean) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
describe 'to symbol' do
|
185
|
-
it 'converts strings to symbols' do
|
186
|
-
expect(coerce('a', :symbol)).to eq :a
|
187
|
-
expect(coerce('nice_symbol', :symbol)).to eq :nice_symbol
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
describe 'to date' do
|
192
|
-
it 'converts string to date' do
|
193
|
-
date = coerce('2019-03-22', :date)
|
194
|
-
|
195
|
-
expect(date).to be_instance_of(Date)
|
196
|
-
expect(date.year).to eq 2019
|
197
|
-
expect(date.month).to eq 3
|
198
|
-
expect(date.day).to eq 22
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'converts other string formats to date' do
|
202
|
-
expect(coerce('March 22nd, 2019', :date)).to eq Date.parse('2019-03-22')
|
203
|
-
expect(coerce('Sat, March 23rd, 2019', :date)).to eq Date.parse('2019-03-23')
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'fails with an invalid string' do
|
207
|
-
expect { coerce('non-date', :date) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
describe 'to time' do
|
212
|
-
it 'converts string to time without time part' do
|
213
|
-
time = coerce("2019-03-22", :time)
|
214
|
-
|
215
|
-
expect(time).to be_instance_of(Time)
|
216
|
-
expect(time.year).to eq 2019
|
217
|
-
expect(time.month).to eq 3
|
218
|
-
expect(time.day).to eq 22
|
219
|
-
expect(time.hour).to eq 0
|
220
|
-
expect(time.min).to eq 0
|
221
|
-
expect(time.sec).to eq 0
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'converts string to time with time portion' do
|
225
|
-
time = coerce("March 22nd, 2019 9:30:55", :time)
|
226
|
-
|
227
|
-
expect(time).to be_instance_of(Time)
|
228
|
-
expect(time.year).to eq 2019
|
229
|
-
expect(time.month).to eq 3
|
230
|
-
expect(time.day).to eq 22
|
231
|
-
expect(time.hour).to eq 9
|
232
|
-
expect(time.min).to eq 30
|
233
|
-
expect(time.sec).to eq 55
|
234
|
-
end
|
235
|
-
|
236
|
-
it 'fails with an invalid string' do
|
237
|
-
expect { coerce('2999', :time) }.to raise_error(ENVied::Coercer::UnsupportedCoercion)
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
describe 'to array' do
|
242
|
-
it 'converts strings to array' do
|
243
|
-
{
|
244
|
-
'a,b' => ['a','b'],
|
245
|
-
' a, b' => [' a',' b'],
|
246
|
-
'apples,and\, of course\, pears' => ['apples','and, of course, pears'],
|
247
|
-
}.each do |value, array|
|
248
|
-
expect(coerce(value, :array)).to eq array
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
describe 'to hash' do
|
254
|
-
it 'converts strings to hashes' do
|
255
|
-
{
|
256
|
-
'a=1' => {'a' => '1'},
|
257
|
-
'a=1&b=2' => {'a' => '1', 'b' => '2'},
|
258
|
-
'a=&b=2' => {'a' => '', 'b' => '2'},
|
259
|
-
'a&b=2' => {'a' => nil, 'b' => '2'},
|
260
|
-
}.each do |value, hash|
|
261
|
-
expect(coerce(value, :hash)).to eq hash
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
describe 'to uri' do
|
267
|
-
it 'converts strings to uris' do
|
268
|
-
expect(coerce('https://www.google.com', :uri)).to be_a(URI)
|
269
|
-
expect(coerce('https://www.google.com', :uri).scheme).to eq 'https'
|
270
|
-
expect(coerce('https://www.google.com', :uri).host).to eq 'www.google.com'
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
data/spec/configuration_spec.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
RSpec.describe ENVied::Configuration do
|
2
|
-
it { is_expected.to respond_to :variable }
|
3
|
-
it { is_expected.to respond_to :group }
|
4
|
-
it { is_expected.to respond_to :enable_defaults! }
|
5
|
-
it { is_expected.to respond_to :defaults_enabled? }
|
6
|
-
|
7
|
-
def with_envfile(**options, &block)
|
8
|
-
@config = ENVied::Configuration.new(options, &block)
|
9
|
-
end
|
10
|
-
attr_reader :config
|
11
|
-
|
12
|
-
describe 'variables' do
|
13
|
-
it 'results in an added variable' do
|
14
|
-
with_envfile do
|
15
|
-
variable :foo, :boolean
|
16
|
-
end
|
17
|
-
|
18
|
-
expect(config.variables).to include ENVied::Variable.new(:foo, :boolean, group: :default)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'sets string as default type when no type is given' do
|
22
|
-
with_envfile do
|
23
|
-
variable :bar
|
24
|
-
end
|
25
|
-
|
26
|
-
expect(config.variables).to include ENVied::Variable.new(:bar, :string, default: nil, group: :default)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'sets a default value when specified' do
|
30
|
-
with_envfile do
|
31
|
-
variable :bar, default: 'bar'
|
32
|
-
end
|
33
|
-
|
34
|
-
expect(config.variables).to include ENVied::Variable.new(:bar, :string, default: 'bar', group: :default)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'sets specific group for variable' do
|
38
|
-
with_envfile do
|
39
|
-
group :production do
|
40
|
-
variable :SECRET_KEY_BASE
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
expect(config.variables).to include ENVied::Variable.new(:SECRET_KEY_BASE, :string, group: :production)
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'sets the same variable for multiple groups' do
|
48
|
-
with_envfile do
|
49
|
-
group :development, :test do
|
50
|
-
variable :DISABLE_PRY, :boolean, default: 'false'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
expect(config.variables).to eq [
|
55
|
-
ENVied::Variable.new(:DISABLE_PRY, :boolean, default: 'false', group: :development),
|
56
|
-
ENVied::Variable.new(:DISABLE_PRY, :boolean, default: 'false', group: :test)
|
57
|
-
]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe 'defaults' do
|
62
|
-
it 'is disabled by default' do
|
63
|
-
expect(subject.defaults_enabled?).to eq false
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'can be enabled with an ENV variable' do
|
67
|
-
allow(ENV).to receive(:[]).with("ENVIED_ENABLE_DEFAULTS").and_return("true")
|
68
|
-
expect(subject.defaults_enabled?).to eq true
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'can be enabled through a config option' do
|
72
|
-
with_envfile(enable_defaults: true) { }
|
73
|
-
|
74
|
-
expect(config.defaults_enabled?).to eq true
|
75
|
-
end
|
76
|
-
|
77
|
-
describe '#enable_defaults!' do
|
78
|
-
it 'can be enabled in a block by calling `enable_defaults!`' do
|
79
|
-
with_envfile do
|
80
|
-
enable_defaults!
|
81
|
-
end
|
82
|
-
|
83
|
-
expect(config.defaults_enabled?).to eq true
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'can be enabled by calling `enable_defaults!` with a Proc' do
|
87
|
-
with_envfile do
|
88
|
-
enable_defaults! { true }
|
89
|
-
end
|
90
|
-
|
91
|
-
expect(config.defaults_enabled?).to eq true
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'defaults to true with no arguments' do
|
95
|
-
expect {
|
96
|
-
subject.enable_defaults!
|
97
|
-
}.to change { subject.defaults_enabled? }.from(false).to(true)
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'can be passed a boolean value' do
|
101
|
-
expect {
|
102
|
-
subject.enable_defaults!(true)
|
103
|
-
}.to change { subject.defaults_enabled? }.from(false).to(true)
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'can be passed a block' do
|
107
|
-
expect {
|
108
|
-
subject.enable_defaults! { true }
|
109
|
-
}.to change { subject.defaults_enabled? }.from(false).to(true)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
RSpec.describe ENVied::EnvVarExtractor do
|
2
|
-
|
3
|
-
describe "#capture_variables" do
|
4
|
-
def capture_variables(text)
|
5
|
-
described_class.new.capture_variables(text)
|
6
|
-
end
|
7
|
-
|
8
|
-
{
|
9
|
-
%{self.a = ENV['A']} => %w(A),
|
10
|
-
%{self.a = ENV["A"]} => %w(A),
|
11
|
-
%{self.a = ENV.fetch('A')]} => %w(A),
|
12
|
-
%{self.a = ENV.fetch("A")]} => %w(A),
|
13
|
-
%{# self.a = ENV["A"]} => %w(A),
|
14
|
-
%{self.a = ENV["A"] && self.b = ENV["B"]} => %w(A B),
|
15
|
-
%{self.a = ENV["A3"]} => %w(A3)
|
16
|
-
}.each do |line, expected|
|
17
|
-
it "captures #{expected} from #{line.inspect}" do
|
18
|
-
expect(capture_variables(line)).to contain_exactly(*expected)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/spec/envied_spec.rb
DELETED
@@ -1,339 +0,0 @@
|
|
1
|
-
RSpec.describe ENVied do
|
2
|
-
describe 'class' do
|
3
|
-
subject { described_class }
|
4
|
-
it { is_expected.to respond_to :require }
|
5
|
-
end
|
6
|
-
|
7
|
-
def reset_envied
|
8
|
-
ENVied.instance_eval do
|
9
|
-
@env = nil
|
10
|
-
@config = nil
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'configured' do
|
15
|
-
|
16
|
-
before do
|
17
|
-
reset_envied
|
18
|
-
end
|
19
|
-
|
20
|
-
def set_ENV(env = {})
|
21
|
-
stub_const("ENV", env)
|
22
|
-
end
|
23
|
-
|
24
|
-
def configure(**options, &block)
|
25
|
-
@config = ENVied::Configuration.new(options, &block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def configured_with(**hash)
|
29
|
-
@config = ENVied::Configuration.new.tap do |config|
|
30
|
-
hash.each do |name, type|
|
31
|
-
config.variable(name, type)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def envied_require(*args, **options)
|
37
|
-
options[:config] = @config || ENVied::Configuration.new # Prevent `Configuration.load` from being called
|
38
|
-
ENVied.require(*args, **options)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'does respond to configured variables' do
|
42
|
-
set_ENV('A' => '1')
|
43
|
-
configured_with(A: :integer)
|
44
|
-
envied_require
|
45
|
-
|
46
|
-
expect(described_class).to respond_to :A
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'does not respond to unconfigured variables' do
|
50
|
-
set_ENV('A' => '1')
|
51
|
-
configured_with
|
52
|
-
envied_require
|
53
|
-
|
54
|
-
expect(described_class).to_not respond_to :B
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'sets ENVied.config' do
|
58
|
-
set_ENV('A' => '1')
|
59
|
-
configured_with(A: :integer)
|
60
|
-
envied_require
|
61
|
-
|
62
|
-
expect(ENVied.config).to be_instance_of(ENVied::Configuration)
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'ENV contains not all configured variables' do
|
66
|
-
before do
|
67
|
-
set_ENV
|
68
|
-
configured_with(A: :integer)
|
69
|
-
end
|
70
|
-
|
71
|
-
specify do
|
72
|
-
expect {
|
73
|
-
envied_require
|
74
|
-
}.to raise_error(RuntimeError, 'The following environment variables should be set: A.')
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'ENV variables are not coercible' do
|
79
|
-
before do
|
80
|
-
set_ENV('A' => 'NaN', 'B' => 'invalid')
|
81
|
-
configured_with(A: :integer, B: :boolean)
|
82
|
-
end
|
83
|
-
|
84
|
-
specify do
|
85
|
-
expect {
|
86
|
-
envied_require
|
87
|
-
}.to raise_error(
|
88
|
-
RuntimeError,
|
89
|
-
'The following environment variables are not coercible: A with "NaN" (integer), B with "invalid" (boolean).'
|
90
|
-
)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
context 'configuring' do
|
95
|
-
it 'raises error when configuring variable of unknown type' do
|
96
|
-
expect {
|
97
|
-
configured_with(A: :fixnum)
|
98
|
-
}.to raise_error(ArgumentError, ":fixnum is not a supported type. Should be one of #{ENVied::Coercer.supported_types}")
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# TODO: review needed, doesn't make sense?
|
103
|
-
context 'bug: default value "false" is not coercible' do
|
104
|
-
before do
|
105
|
-
configure(enable_defaults: true) do
|
106
|
-
variable :FORCE_SSL, :boolean, default: true
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
specify do
|
111
|
-
expect {
|
112
|
-
envied_require
|
113
|
-
}.not_to raise_error
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
describe 'defaults' do
|
118
|
-
describe 'assigning' do
|
119
|
-
it 'sets a default value for ENV variable' do
|
120
|
-
configure(enable_defaults: true) do
|
121
|
-
variable :A, :integer, default: '1'
|
122
|
-
end
|
123
|
-
envied_require
|
124
|
-
|
125
|
-
expect(described_class.A).to eq 1
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'sets a default value from calling a proc for ENV variable' do
|
129
|
-
configure(enable_defaults: true) do
|
130
|
-
variable :A, :integer, default: proc { "1" }
|
131
|
-
end
|
132
|
-
envied_require
|
133
|
-
|
134
|
-
expect(described_class.A).to eq 1
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'ignores setting defaults if they are disabled' do
|
138
|
-
set_ENV
|
139
|
-
configure(enable_defaults: false) do
|
140
|
-
variable :A, :integer, default: "1"
|
141
|
-
variable :B, :integer, default: "1"
|
142
|
-
end
|
143
|
-
|
144
|
-
expect {
|
145
|
-
envied_require
|
146
|
-
}.to raise_error(RuntimeError, 'The following environment variables should be set: A, B.')
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'ignores a default value if ENV variable is already provided' do
|
150
|
-
set_ENV('A' => '2')
|
151
|
-
configure(enable_defaults: true) do
|
152
|
-
variable :A, :integer, default: "1"
|
153
|
-
end
|
154
|
-
envied_require
|
155
|
-
|
156
|
-
expect(described_class.A).to eq 2
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'can set a default value via a proc that references another ENV variable' do
|
160
|
-
set_ENV('A' => '1')
|
161
|
-
configure(enable_defaults: true) do
|
162
|
-
variable :A, :integer
|
163
|
-
variable :B, :integer, default: proc {|env| env.A * 2 }
|
164
|
-
end
|
165
|
-
envied_require
|
166
|
-
|
167
|
-
expect(described_class.B).to eq 2
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
describe ".required?" do
|
173
|
-
# TODO: change to always return boolean
|
174
|
-
it 'returns true-ish if `ENVied.require` was called' do
|
175
|
-
expect {
|
176
|
-
envied_require
|
177
|
-
}.to change { ENVied.required? }.from(nil).to(anything)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
describe "groups" do
|
182
|
-
context 'a variable in a group' do
|
183
|
-
before do
|
184
|
-
set_ENV
|
185
|
-
configure do
|
186
|
-
variable :MORE
|
187
|
-
|
188
|
-
group :foo do
|
189
|
-
variable :BAR
|
190
|
-
end
|
191
|
-
group :moo do
|
192
|
-
variable :BAT
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
it 'is required when requiring the groups passed as a delimited string' do
|
198
|
-
expect {
|
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
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'is not required when requiring another group' do
|
212
|
-
[:bat, 'bat'].each do |group|
|
213
|
-
expect {
|
214
|
-
envied_require(group)
|
215
|
-
}.to_not raise_error
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'will not define variables not part of the default group' do
|
220
|
-
set_ENV('MORE' => 'yes')
|
221
|
-
envied_require(:default)
|
222
|
-
|
223
|
-
expect {
|
224
|
-
described_class.BAR
|
225
|
-
}.to raise_error(NoMethodError)
|
226
|
-
end
|
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
|
-
|
242
|
-
it 'requires variables without a group when requiring the default group' do
|
243
|
-
[:default, 'default'].each do |group|
|
244
|
-
expect {
|
245
|
-
envied_require(group)
|
246
|
-
}.to raise_error(RuntimeError, 'The following environment variables should be set: MORE.')
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
context 'a variable in multiple groups' do
|
252
|
-
before do
|
253
|
-
set_ENV
|
254
|
-
configure do
|
255
|
-
variable :MORE
|
256
|
-
|
257
|
-
group :foo, :moo do
|
258
|
-
variable :BAR
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
it 'is required when requiring any of the groups' do
|
264
|
-
expect {
|
265
|
-
envied_require(:foo)
|
266
|
-
}.to raise_error(RuntimeError, 'The following environment variables should be set: BAR.')
|
267
|
-
|
268
|
-
expect {
|
269
|
-
envied_require(:moo)
|
270
|
-
}.to raise_error(RuntimeError, 'The following environment variables should be set: BAR.')
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
describe 'Hashable' do
|
275
|
-
before do
|
276
|
-
set_ENV('FOO' => 'a=1&b=&c', 'BAR' => '')
|
277
|
-
configure do
|
278
|
-
variable :FOO, :hash
|
279
|
-
variable :BAR, :hash
|
280
|
-
end
|
281
|
-
envied_require
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'yields hash from string' do
|
285
|
-
expect(ENVied.FOO).to eq({ 'a' => '1', 'b' => '', 'c' => nil })
|
286
|
-
end
|
287
|
-
|
288
|
-
it 'yields hash from an empty string' do
|
289
|
-
expect(ENVied.BAR).to eq({})
|
290
|
-
end
|
291
|
-
|
292
|
-
context 'with defaults enabled' do
|
293
|
-
before do
|
294
|
-
set_ENV
|
295
|
-
configure(enable_defaults: true) do
|
296
|
-
variable :BAZ, :hash
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
it 'has no default by default' do
|
301
|
-
# fixes a bug where variables of type :Hash had a default even
|
302
|
-
# when none was configured.
|
303
|
-
expect { envied_require }.to raise_error(RuntimeError, 'The following environment variables should be set: BAZ.')
|
304
|
-
end
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
describe 'Arrayable' do
|
309
|
-
before do
|
310
|
-
set_ENV('MORE' => 'a, b, and\, c')
|
311
|
-
configure do
|
312
|
-
variable :MORE, :array
|
313
|
-
end
|
314
|
-
envied_require
|
315
|
-
end
|
316
|
-
|
317
|
-
it 'yields array from string' do
|
318
|
-
expect(ENVied.MORE).to eq ['a',' b',' and, c']
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
describe 'URIable' do
|
323
|
-
before do
|
324
|
-
set_ENV('SITE_URL' => 'https://www.google.com')
|
325
|
-
configure do
|
326
|
-
variable :SITE_URL, :uri
|
327
|
-
end
|
328
|
-
envied_require
|
329
|
-
end
|
330
|
-
|
331
|
-
it 'yields a URI from string' do
|
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'
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
339
|
-
end
|