env_bang 1.0.0 → 2.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: caced8c854aedd70eb0f17e728eb76481aced9d7063907c4ddb221fdf0afc2ee
4
- data.tar.gz: 5dd565d37104212fde171396cd45dc07913ba2d3b4d8ab2881e54c7c1bc7c58d
3
+ metadata.gz: '094ce7c346a763599ef55ab0256e99cdbed2d4f3059782cb2078ce8f5ff42502'
4
+ data.tar.gz: 353125d00af13bcb825fba521115a53d414d78bfc2e80cc7c8573051ee7c45a7
5
5
  SHA512:
6
- metadata.gz: 5b08b2788b310bb0270f6f2b3643b5279bc4664adf9ca6d7dafd2e9836a82dce6bb15887b93bf098320fa479c2fb813f40e65f777cc7f5882cad67c100f7b7f4
7
- data.tar.gz: ce95a84a42164284beee119759cca029ee349f9c6bf0fe3fed3cfb731a3edab80be2a87f07601883d745654c14968607d75f8b497697ef9f8a1424e259e99c8c
6
+ metadata.gz: 878b656b6090bdbbca837f260032a99edb2a34a50890681d2d88f9ce0e071df2a9c860778288478b7f1627acee4ce7f38efe5f55f469da1806e5fe2ed1850090
7
+ data.tar.gz: c9045031fd3209dc99605ec3a59c67e579d937b658250e4dbd29b958ddd8ed0fe0483f1c850ae59f0cf93e558420674e10ed32bc506a122186978cdd10cddfa5
@@ -0,0 +1,39 @@
1
+ # Use the latest 2.1 version of CircleCI pipeline process engine.
2
+ # See: https://circleci.com/docs/2.0/configuration-reference
3
+ version: 2.1
4
+
5
+ orbs:
6
+ ruby: circleci/ruby@2.0.0
7
+ coveralls: coveralls/coveralls@2.1.0
8
+
9
+ # Define a job to be invoked later in a workflow.
10
+ # See: https://circleci.com/docs/2.0/configuration-reference/#jobs
11
+ jobs:
12
+ test:
13
+ parameters:
14
+ ruby-version:
15
+ type: string
16
+ docker:
17
+ # replace with your preferred image
18
+ - image: cimg/ruby:<< parameters.ruby-version >>
19
+ resource_class: small
20
+ environment:
21
+ COVERAGE: Summary
22
+ steps:
23
+ - checkout
24
+ - run: bundle install
25
+ - run: bundle exec rake
26
+ - coveralls/upload:
27
+ coverage_file: coverage/lcov.info
28
+
29
+ # Invoke jobs via workflows
30
+ # See: https://circleci.com/docs/2.0/configuration-reference/#workflows
31
+ workflows:
32
+ buidle_and_test:
33
+ jobs:
34
+ - test:
35
+ matrix:
36
+ parameters:
37
+ # https://github.com/CircleCI-Public/cimg-ruby
38
+ # only supports the last three ruby versions
39
+ ruby-version: ["2.6", "2.7", "3.0", "3.2"]
data/Gemfile CHANGED
@@ -2,6 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec name: 'env_bang'
4
4
 
5
- group :metrics do
6
- gem 'coveralls', require: false
5
+ group :test do
6
+ gem 'simplecov'
7
+ gem 'simplecov-lcov'
7
8
  end
data/README.md CHANGED
@@ -1,19 +1,17 @@
1
1
  # ENV!
2
2
 
3
- Do a bang-up job managing your environment variables.
3
+ Verify correctness of environment configuration at startup time.
4
4
 
5
5
  [![Gem Version](https://img.shields.io/gem/v/env_bang?logo=rubygems)](https://rubygems.org/gems/env_bang)
6
- [![Build Status](https://img.shields.io/travis/jcamenisch/ENV_BANG/main.svg?logo=travis)](https://app.travis-ci.com/github/jcamenisch/ENV_BANG)
6
+ [![Build Status](https://img.shields.io/circleci/build/github/jcamenisch/ENV_BANG/main)](https://dl.circleci.com/status-badge/redirect/gh/jcamenisch/ENV_BANG/tree/main)
7
7
  [![Maintainability](https://img.shields.io/codeclimate/maintainability/jcamenisch/ENV_BANG?logo=codeclimate)](https://codeclimate.com/github/jcamenisch/ENV_BANG)
8
8
  [![Coverage Status](https://img.shields.io/coverallsCoverage/github/jcamenisch/ENV_BANG?logo=coveralls)](https://coveralls.io/r/jcamenisch/ENV_BANG)
9
9
 
10
10
  ENV! provides a thin wrapper around ENV to accomplish a few things:
11
11
 
12
12
  - Provide a central place to specify all your app’s environment variables.
13
- - Fail loudly and helpfully if any environment variables are missing.
14
- - Prevent an application from starting up with missing environment variables.
15
- (This is especially helpful in environments like Heroku, as your app will
16
- continue running the old code until the server is configured for a new revision.)
13
+ - Fail loudly and helpfully if any environment variables are missing or invalid.
14
+ - Prevent an application from starting up with invalid environment variables.
17
15
 
18
16
  ## Installation
19
17
 
@@ -1,3 +1,3 @@
1
1
  class ENV_BANG
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0.alpha.1"
3
3
  end
data/lib/env_bang.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  require "env_bang/version"
2
2
  require "env_bang/classes"
3
3
  require "env_bang/formatter"
4
+ require "forwardable"
4
5
 
5
6
  class ENV_BANG
6
7
  class << self
8
+ extend Forwardable
9
+ include Enumerable
10
+
7
11
  def config(&block)
8
12
  instance_eval(&block)
9
13
  end
@@ -48,10 +52,6 @@ class ENV_BANG
48
52
  Classes.cast ENV[var], vars[var]
49
53
  end
50
54
 
51
- def method_missing(method, *args, &block)
52
- ENV.send(method, *args, &block)
53
- end
54
-
55
55
  def add_class(klass, &block)
56
56
  Classes.send :define_singleton_method, klass.to_s, &block
57
57
  end
@@ -63,6 +63,36 @@ class ENV_BANG
63
63
  Classes.default_class
64
64
  end
65
65
  end
66
+
67
+ def to_h
68
+ keys.map { |k| [k, self[k]] }.to_h
69
+ end
70
+
71
+ alias to_hash to_h
72
+
73
+ ####################################
74
+ # Implement Hash-like read methods #
75
+ ####################################
76
+
77
+ def_delegators :to_h,
78
+ :each, :assoc, :each_pair, :each_value, :empty?, :fetch,
79
+ :invert, :key, :rassoc, :values_at
80
+
81
+ def_delegators :vars, :each_key, :has_key?, :key?, :length, :size
82
+
83
+ def slice(*requested_keys)
84
+ (requested_keys & keys).map { |k| [k, self[k]] }.to_h
85
+ end
86
+
87
+ def except(*exceptions)
88
+ slice(*(keys - exceptions))
89
+ end
90
+
91
+ def value?(value)
92
+ values.include?(value)
93
+ end
94
+
95
+ alias has_value? value?
66
96
  end
67
97
  end
68
98
 
@@ -8,13 +8,13 @@ describe ENV_BANG do
8
8
 
9
9
  it "Raises exception if unconfigured ENV var requested" do
10
10
  ENV['UNCONFIGURED'] = 'unconfigured'
11
- proc { ENV!['UNCONFIGURED'] }.must_raise KeyError
11
+ _{ ENV!['UNCONFIGURED'] }.must_raise KeyError
12
12
  end
13
13
 
14
14
  it "Raises exception if configured ENV var is not present" do
15
15
  ENV.delete('NOT_PRESENT')
16
16
 
17
- proc {
17
+ _{
18
18
  ENV!.config do
19
19
  use 'NOT_PRESENT'
20
20
  end
@@ -22,12 +22,12 @@ describe ENV_BANG do
22
22
  end
23
23
 
24
24
  it "Raises exception immediately if value is invalid for the required type" do
25
- proc {
25
+ _{
26
26
  ENV['NOT_A_DATE'] = '2017-02-30'
27
27
  ENV!.use 'NOT_A_DATE', class: Date
28
28
  }.must_raise ArgumentError
29
29
 
30
- proc {
30
+ _{
31
31
  ENV!.use 'NOT_A_DATE_DEFAULT', class: Date, default: '2017-02-31'
32
32
  }.must_raise ArgumentError
33
33
  end
@@ -38,7 +38,7 @@ describe ENV_BANG do
38
38
  ENV!.config do
39
39
  use 'WASNT_PRESENT', default: 'a default value'
40
40
  end
41
- ENV!['WASNT_PRESENT'].must_equal 'a default value'
41
+ _(ENV!['WASNT_PRESENT']).must_equal 'a default value'
42
42
  end
43
43
 
44
44
  it "Returns actual value from ENV if present" do
@@ -47,7 +47,7 @@ describe ENV_BANG do
47
47
  ENV!.config do
48
48
  use 'PRESENT', default: "You won't need this."
49
49
  end
50
- ENV!['PRESENT'].must_equal 'present in environment'
50
+ _(ENV!['PRESENT']).must_equal 'present in environment'
51
51
  end
52
52
 
53
53
  describe "Type casting" do
@@ -61,14 +61,14 @@ describe ENV_BANG do
61
61
  ENV['INTEGER'] = integer
62
62
  ENV!.use 'INTEGER', class: Integer
63
63
 
64
- ENV!['INTEGER'].must_equal integer.to_i
64
+ _(ENV!['INTEGER']).must_equal integer.to_i
65
65
  end
66
66
 
67
67
  it "Casts Symbols" do
68
68
  ENV['SYMBOL'] = 'symbol'
69
69
  ENV!.use 'SYMBOL', class: Symbol
70
70
 
71
- ENV!['SYMBOL'].must_equal :symbol
71
+ _(ENV!['SYMBOL']).must_equal :symbol
72
72
  end
73
73
 
74
74
  it "Casts Floats" do
@@ -76,29 +76,29 @@ describe ENV_BANG do
76
76
  ENV['FLOAT'] = float
77
77
  ENV!.use 'FLOAT', class: Float
78
78
 
79
- ENV!['FLOAT'].must_equal float.to_f
80
- ENV!['FLOAT'].class.must_equal Float
79
+ _(ENV!['FLOAT']).must_equal float.to_f
80
+ _(ENV!['FLOAT'].class).must_equal Float
81
81
  end
82
82
 
83
83
  it "Casts Arrays" do
84
84
  ENV['ARRAY'] = 'one,two , three, four'
85
85
  ENV!.use 'ARRAY', class: Array
86
86
 
87
- ENV!['ARRAY'].must_equal %w[one two three four]
87
+ _(ENV!['ARRAY']).must_equal %w[one two three four]
88
88
  end
89
89
 
90
90
  it "Casts Arrays of Integers" do
91
91
  ENV['INTEGERS'] = integers.join(',')
92
92
  ENV!.use 'INTEGERS', class: Array, of: Integer
93
93
 
94
- ENV!['INTEGERS'].must_equal integers.map(&:to_i)
94
+ _(ENV!['INTEGERS']).must_equal integers.map(&:to_i)
95
95
  end
96
96
 
97
97
  it "Casts Arrays of Floats" do
98
98
  ENV['FLOATS'] = floats.join(',')
99
99
  ENV!.use 'FLOATS', class: Array, of: Float
100
100
 
101
- ENV!['FLOATS'].must_equal floats.map(&:to_f)
101
+ _(ENV!['FLOATS']).must_equal floats.map(&:to_f)
102
102
  end
103
103
 
104
104
  it "regression: Casting Array always returns Array" do
@@ -106,7 +106,7 @@ describe ENV_BANG do
106
106
  ENV!.use 'ARRAY', class: Array
107
107
 
108
108
  2.times do
109
- ENV!['ARRAY'].must_equal %w[one two three four]
109
+ _(ENV!['ARRAY']).must_equal %w[one two three four]
110
110
  end
111
111
  end
112
112
 
@@ -114,80 +114,80 @@ describe ENV_BANG do
114
114
  ENV['HASH'] = 'one: two, three: http://four.com'
115
115
  ENV!.use 'HASH', class: Hash
116
116
 
117
- ENV!['HASH'].must_equal({one: 'two', three: 'http://four.com'})
117
+ _(ENV!['HASH']).must_equal({one: 'two', three: 'http://four.com'})
118
118
  end
119
119
 
120
120
  it 'Casts Hashes of Integers' do
121
121
  ENV['INT_HASH'] = 'one: 111, two: 222'
122
122
  ENV!.use 'INT_HASH', class: Hash, of: Integer
123
123
 
124
- ENV!['INT_HASH'].must_equal({one: 111, two: 222})
124
+ _(ENV!['INT_HASH']).must_equal({one: 111, two: 222})
125
125
  end
126
126
 
127
127
  it 'Casts Hashes with String keys' do
128
128
  ENV['STRKEY_HASH'] = 'one: two, three: four'
129
129
  ENV!.use 'STRKEY_HASH', class: Hash, keys: String
130
130
 
131
- ENV!['STRKEY_HASH'].must_equal({'one' => 'two', 'three' => 'four'})
131
+ _(ENV!['STRKEY_HASH']).must_equal({'one' => 'two', 'three' => 'four'})
132
132
  end
133
133
 
134
134
  it 'Casts Hashes with alternate separators' do
135
135
  ENV['ALT_HASH'] = 'one:two = three; four,five=six'
136
136
  ENV!.use 'ALT_HASH', class: Hash, sep: ';', val_sep: '='
137
137
 
138
- ENV!['ALT_HASH'].must_equal({:'one:two' => 'three', :'four,five' => 'six'})
138
+ _(ENV!['ALT_HASH']).must_equal({:'one:two' => 'three', :'four,five' => 'six'})
139
139
  end
140
140
 
141
141
  it "Casts true" do
142
142
  ENV['TRUE'] = truthy_values.sample
143
143
  ENV!.use 'TRUE', class: :boolean
144
144
 
145
- ENV!['TRUE'].must_equal true
145
+ _(ENV!['TRUE']).must_equal true
146
146
  end
147
147
 
148
148
  it "Casts false" do
149
149
  ENV['FALSE'] = falsey_values.sample
150
150
  ENV!.use 'FALSE', class: :boolean
151
151
 
152
- ENV!['FALSE'].must_equal false
152
+ _(ENV!['FALSE']).must_equal false
153
153
  end
154
154
 
155
155
  it "converts falsey or empty string to false by default" do
156
156
  ENV['FALSE'] = falsey_values.sample
157
157
  ENV!.use 'FALSE'
158
158
 
159
- ENV!['FALSE'].must_equal false
159
+ _(ENV!['FALSE']).must_equal false
160
160
  end
161
161
 
162
162
  it "leaves falsey string as string if specified" do
163
163
  ENV['FALSE'] = falsey_values.sample
164
164
  ENV!.use 'FALSE', class: String
165
165
 
166
- ENV!['FALSE'].class.must_equal String
166
+ _(ENV!['FALSE'].class).must_equal String
167
167
  end
168
168
 
169
169
  it "casts Dates" do
170
170
  ENV['A_DATE'] = '2005-05-05'
171
171
  ENV!.use 'A_DATE', class: Date
172
172
 
173
- ENV!['A_DATE'].class.must_equal Date
174
- ENV!['A_DATE'].must_equal Date.new(2005, 5, 5)
173
+ _(ENV!['A_DATE'].class).must_equal Date
174
+ _(ENV!['A_DATE']).must_equal Date.new(2005, 5, 5)
175
175
  end
176
176
 
177
177
  it "casts DateTimes" do
178
178
  ENV['A_DATETIME'] = '2005-05-05 5:05pm'
179
179
  ENV!.use 'A_DATETIME', class: DateTime
180
180
 
181
- ENV!['A_DATETIME'].class.must_equal DateTime
182
- ENV!['A_DATETIME'].must_equal DateTime.new(2005, 5, 5, 17, 5)
181
+ _(ENV!['A_DATETIME'].class).must_equal DateTime
182
+ _(ENV!['A_DATETIME']).must_equal DateTime.new(2005, 5, 5, 17, 5)
183
183
  end
184
184
 
185
185
  it "casts Times" do
186
186
  ENV['A_TIME'] = '2005-05-05 5:05pm'
187
187
  ENV!.use 'A_TIME', class: Time
188
188
 
189
- ENV!['A_TIME'].class.must_equal Time
190
- ENV!['A_TIME'].must_equal Time.new(2005, 5, 5, 17, 5)
189
+ _(ENV!['A_TIME'].class).must_equal Time
190
+ _(ENV!['A_TIME']).must_equal Time.new(2005, 5, 5, 17, 5)
191
191
  end
192
192
 
193
193
  it "casts Regexps" do
@@ -195,51 +195,51 @@ describe ENV_BANG do
195
195
  ENV['A_REGEX'] = '^(this|is|a|[^tes.*\|]t.\.\*/\\\)$'
196
196
  ENV!.use 'A_REGEX', class: Regexp
197
197
 
198
- ENV!['A_REGEX'].class.must_equal Regexp
199
- ENV!['A_REGEX'].must_equal(/^(this|is|a|[^tes.*\|]t.\.\*\/\\)$/)
198
+ _(ENV!['A_REGEX'].class).must_equal Regexp
199
+ _(ENV!['A_REGEX']).must_equal(/^(this|is|a|[^tes.*\|]t.\.\*\/\\)$/)
200
200
  end
201
201
 
202
202
  it "casts inclusive Ranges of Integers by default" do
203
203
  ENV['A_RANGE'] = '1..100'
204
204
  ENV!.use 'A_RANGE', class: Range
205
205
 
206
- ENV!['A_RANGE'].class.must_equal Range
207
- ENV!['A_RANGE'].must_equal 1..100
206
+ _(ENV!['A_RANGE'].class).must_equal Range
207
+ _(ENV!['A_RANGE']).must_equal 1..100
208
208
  end
209
209
 
210
210
  it "casts exclusive Ranges as directed" do
211
211
  ENV['EXCLUSIVE_RANGE'] = '1..100'
212
212
  ENV!.use 'EXCLUSIVE_RANGE', class: Range, exclusive: true
213
213
 
214
- ENV!['EXCLUSIVE_RANGE'].must_equal 1...100
214
+ _(ENV!['EXCLUSIVE_RANGE']).must_equal 1...100
215
215
 
216
216
  ENV['ANOTHER_EXCLUSIVE_RANGE'] = '1...100'
217
217
  ENV!.use 'ANOTHER_EXCLUSIVE_RANGE', class: Range, exclusive: true
218
218
 
219
- ENV!['ANOTHER_EXCLUSIVE_RANGE'].must_equal 1...100
219
+ _(ENV!['ANOTHER_EXCLUSIVE_RANGE']).must_equal 1...100
220
220
  end
221
221
 
222
222
  it "casts Ranges of floats" do
223
223
  ENV['FLOAT_RANGE'] = '1.5..100.7'
224
224
  ENV!.use 'FLOAT_RANGE', class: Range, of: Float
225
225
 
226
- ENV!['FLOAT_RANGE'].must_equal 1.5..100.7
226
+ _(ENV!['FLOAT_RANGE']).must_equal 1.5..100.7
227
227
  end
228
228
 
229
229
  it "casts Ranges of strings" do
230
230
  ENV['FLOAT_RANGE'] = 'az..za'
231
231
  ENV!.use 'FLOAT_RANGE', class: Range, of: String
232
232
 
233
- ENV!['FLOAT_RANGE'].must_equal 'az'..'za'
233
+ _(ENV!['FLOAT_RANGE']).must_equal 'az'..'za'
234
234
  end
235
235
 
236
236
  it "allows default class to be overridden" do
237
- ENV!.default_class.must_equal :StringUnlessFalsey
237
+ _(ENV!.default_class).must_equal :StringUnlessFalsey
238
238
  ENV!.config { default_class String }
239
239
  ENV['FALSE'] = falsey_values.sample
240
240
  ENV!.use 'FALSE', class: String
241
241
 
242
- ENV!['FALSE'].class.must_equal String
242
+ _(ENV!['FALSE'].class).must_equal String
243
243
  end
244
244
 
245
245
  it "allows addition of custom types" do
@@ -254,7 +254,7 @@ describe ENV_BANG do
254
254
  use :NUMBER_SET, class: Set, of: Integer
255
255
  end
256
256
 
257
- ENV!['NUMBER_SET'].must_equal Set.new [1, 3, 5, 7, 9]
257
+ _(ENV!['NUMBER_SET']).must_equal Set.new [1, 3, 5, 7, 9]
258
258
  end
259
259
 
260
260
  describe "Kernel casting delegators" do
@@ -262,53 +262,53 @@ describe ENV_BANG do
262
262
  ENV['A_INTEGER'] = '-123'
263
263
  ENV!.use 'A_INTEGER', class: Integer
264
264
 
265
- ENV!['A_INTEGER'].must_equal(-123)
265
+ _(ENV!['A_INTEGER']).must_equal(-123)
266
266
  end
267
267
 
268
268
  it "casts Floats" do
269
269
  ENV['A_FLOAT'] = '123.456'
270
270
  ENV!.use 'A_FLOAT', class: Float
271
271
 
272
- ENV!['A_FLOAT'].must_equal 123.456
272
+ _(ENV!['A_FLOAT']).must_equal 123.456
273
273
  end
274
274
 
275
275
  it "casts Strings" do
276
276
  ENV['A_STRING'] = 'What do I write here?'
277
277
  ENV!.use 'A_STRING', class: String
278
- ENV!['A_STRING'].must_equal 'What do I write here?'
278
+ _(ENV!['A_STRING']).must_equal 'What do I write here?'
279
279
  end
280
280
 
281
281
  it "casts Rationals" do
282
282
  ENV['A_RATIONAL'] = '3/32'
283
283
  ENV!.use 'A_RATIONAL', class: Rational
284
284
 
285
- ENV!['A_RATIONAL'].class.must_equal Rational
286
- ENV!['A_RATIONAL'].must_equal 3.to_r/32
287
- ENV!['A_RATIONAL'].to_s.must_equal '3/32'
285
+ _(ENV!['A_RATIONAL'].class).must_equal Rational
286
+ _(ENV!['A_RATIONAL']).must_equal 3.to_r/32
287
+ _(ENV!['A_RATIONAL'].to_s).must_equal '3/32'
288
288
  end
289
289
 
290
290
  it "casts Complexes" do
291
291
  ENV['A_COMPLEX'] = '123+4i'
292
292
  ENV!.use 'A_COMPLEX', class: Complex
293
293
 
294
- ENV!['A_COMPLEX'].class.must_equal Complex
295
- ENV!['A_COMPLEX'].to_s.must_equal '123+4i'
294
+ _(ENV!['A_COMPLEX'].class).must_equal Complex
295
+ _(ENV!['A_COMPLEX'].to_s).must_equal '123+4i'
296
296
  end
297
297
 
298
298
  it "casts Pathnames" do
299
299
  ENV['A_PATHNAME'] = '~/.git/config'
300
300
  ENV!.use 'A_PATHNAME', class: Pathname
301
301
 
302
- ENV!['A_PATHNAME'].class.must_equal Pathname
303
- ENV!['A_PATHNAME'].to_s.must_equal '~/.git/config'
302
+ _(ENV!['A_PATHNAME'].class).must_equal Pathname
303
+ _(ENV!['A_PATHNAME'].to_s).must_equal '~/.git/config'
304
304
  end
305
305
 
306
306
  it "casts URIs" do
307
307
  ENV['A_URI'] = 'http://www.example.com/path/to/nowhere'
308
308
  ENV!.use 'A_URI', class: URI
309
309
 
310
- ENV!['A_URI'].class.must_equal URI::HTTP
311
- ENV!['A_URI'].to_s.must_equal 'http://www.example.com/path/to/nowhere'
310
+ _(ENV!['A_URI'].class).must_equal URI::HTTP
311
+ _(ENV!['A_URI'].to_s).must_equal 'http://www.example.com/path/to/nowhere'
312
312
  end
313
313
  end
314
314
  end
@@ -320,7 +320,7 @@ describe ENV_BANG do
320
320
  ENV!.use 'VAR1'
321
321
  ENV!.use 'VAR2'
322
322
 
323
- ENV!.keys.must_equal %w[VAR1 VAR2]
323
+ _(ENV!.keys).must_equal %w[VAR1 VAR2]
324
324
  end
325
325
 
326
326
  it "provides configured values" do
@@ -329,7 +329,7 @@ describe ENV_BANG do
329
329
  ENV!.use 'VAR1'
330
330
  ENV!.use 'VAR2'
331
331
 
332
- ENV!.values.must_equal %w[something something\ else]
332
+ _(ENV!.values).must_equal %w[something something\ else]
333
333
  end
334
334
  end
335
335
 
@@ -337,18 +337,18 @@ describe ENV_BANG do
337
337
  it "Includes provided description in error message" do
338
338
  ENV.delete('NOT_PRESENT')
339
339
 
340
- e = proc {
340
+ e = _{
341
341
  ENV!.config do
342
342
  use 'NOT_PRESENT', 'You need a NOT_PRESENT var in your ENV'
343
343
  end
344
344
  }.must_raise(KeyError)
345
- e.message.must_include 'You need a NOT_PRESENT var in your ENV'
345
+ _(e.message).must_include 'You need a NOT_PRESENT var in your ENV'
346
346
  end
347
347
 
348
348
  it "Removes indentation from provided descriptions" do
349
349
  ENV.delete('NOT_PRESENT')
350
350
 
351
- e = proc {
351
+ e = _{
352
352
  ENV!.config do
353
353
  use 'NOT_PRESENT', <<-DESC
354
354
  This multiline description
@@ -358,7 +358,7 @@ describe ENV_BANG do
358
358
  DESC
359
359
  end
360
360
  }.must_raise(KeyError)
361
- e.message.must_include <<-UNINDENTED
361
+ _(e.message).must_include <<-UNINDENTED
362
362
  This multiline description
363
363
  has a lot of indentation
364
364
  varying from line to line
@@ -366,4 +366,173 @@ describe ENV_BANG do
366
366
  UNINDENTED
367
367
  end
368
368
  end
369
+
370
+ describe "Enumerable methods" do
371
+ before do
372
+ ENV['ONE'] = '1'
373
+ ENV['A'] = 'A'
374
+ ENV['INT_HASH'] = 'one: 1, two: 2'
375
+ ENV['FLOAT'] = '1.234'
376
+
377
+ ENV!.config do
378
+ use 'ONE', class: Integer
379
+ use 'A', class: String
380
+ use 'INT_HASH', class: Hash, of: Integer
381
+ use 'FLOAT', class: Float
382
+ end
383
+ end
384
+
385
+ it "converts keys and parsed values to a Hash" do
386
+ _(ENV!.to_h).must_equal({
387
+ 'ONE' => 1,
388
+ 'A' => 'A',
389
+ 'INT_HASH' => { one: 1, two: 2 },
390
+ 'FLOAT' => 1.234,
391
+ })
392
+ end
393
+
394
+ it "Doesn't allow write access via the hash (It's not a reference to internal values)" do
395
+ h = ENV!.to_h
396
+ h['A'] = 'changed'
397
+ _(ENV!['A']).must_equal 'A'
398
+ end
399
+
400
+ it "returns an Array representation of the hash too" do
401
+ _(ENV!.to_a).must_equal [
402
+ ['ONE', 1],
403
+ ['A', 'A'],
404
+ ['INT_HASH', { one: 1, two: 2 }],
405
+ ['FLOAT', 1.234],
406
+ ]
407
+ end
408
+
409
+ it "implements other Enumerable methods too" do
410
+ _(ENV!.each.to_a).must_equal [
411
+ ['ONE', 1],
412
+ ['A', 'A'],
413
+ ['INT_HASH', { one: 1, two: 2 }],
414
+ ['FLOAT', 1.234],
415
+ ]
416
+
417
+ _(ENV!.to_enum.to_a).must_equal ENV!.to_a
418
+ end
419
+ end
420
+
421
+ describe "Hash-like read methods" do
422
+ before do
423
+ ENV['ONE'] = '1'
424
+ ENV['A'] = 'A'
425
+ ENV['INT_HASH'] = 'one: 1, two: 2'
426
+ ENV['FLOAT'] = '1.234'
427
+
428
+ ENV!.config do
429
+ use 'ONE', class: Integer
430
+ use 'A', class: String
431
+ use 'INT_HASH', class: Hash, of: Integer
432
+ use 'FLOAT', class: Float
433
+ end
434
+ end
435
+
436
+ it "implements .assoc and .rassoc correctly" do
437
+ _(ENV!.assoc('ONE')).must_equal ['ONE', 1]
438
+ _(ENV!.rassoc(1)).must_equal ['ONE', 1]
439
+ end
440
+
441
+ it "implements .each_key correctly" do
442
+ _(ENV!.each_key.to_a).must_equal(%w[ONE A INT_HASH FLOAT])
443
+ keys = []
444
+ ENV!.each_key do |key|
445
+ keys << key
446
+ end
447
+ _(keys).must_equal(%w[ONE A INT_HASH FLOAT])
448
+ end
449
+
450
+ it "implements .each_pair correctly" do
451
+ _(ENV!.each_pair.to_a).must_equal(ENV!.to_a)
452
+ pairs = []
453
+ ENV!.each_pair do |pair|
454
+ pairs << pair
455
+ end
456
+ _(pairs).must_equal(ENV!.to_a)
457
+ end
458
+
459
+ it "implements .each_value correctly" do
460
+ _(ENV!.each_value.to_a).must_equal [1, 'A', { one: 1, two: 2 }, 1.234]
461
+ values = []
462
+ ENV!.each_value do |value|
463
+ values << value
464
+ end
465
+ _(values).must_equal [1, 'A', { one: 1, two: 2 }, 1.234]
466
+ end
467
+
468
+ it "implements .empty? correctly" do
469
+ _(ENV!.empty?).must_equal(false)
470
+ end
471
+
472
+ it "implements .except correctly" do
473
+ _(ENV!.except('INT_HASH', 'FLOAT', 'NOTATHING')).must_equal({
474
+ 'ONE' => 1,
475
+ 'A' => 'A',
476
+ })
477
+ end
478
+
479
+ it "implements .fetch correctly" do
480
+ _(ENV!.fetch('ONE')).must_equal 1
481
+ _{
482
+ ENV!.fetch('TWO')
483
+ }.must_raise KeyError
484
+ _(ENV!.fetch('TWO', 2)).must_equal 2
485
+ _(ENV!.fetch('TWO') { 22 }).must_equal 22
486
+ end
487
+
488
+ it "implements .invert correctly" do
489
+ _(ENV!.invert).must_equal({
490
+ 1 => 'ONE',
491
+ 'A' => 'A',
492
+ { one: 1, two: 2 } => 'INT_HASH',
493
+ 1.234 => 'FLOAT',
494
+ })
495
+ end
496
+
497
+ it "implements .key correctly" do
498
+ _(ENV!.key(1)).must_equal 'ONE'
499
+ end
500
+
501
+ it "implements .key?/.has_key? correctly" do
502
+ _(ENV!.key?('ONE')).must_equal true
503
+ _(ENV!.has_key?('ONE')).must_equal true
504
+
505
+ _(ENV!.key?('TWO')).must_equal false
506
+ _(ENV!.has_key?('TWO')).must_equal false
507
+ end
508
+
509
+ it "implements .length correctly" do
510
+ _(ENV!.length).must_equal 4
511
+ _(ENV!.size).must_equal 4
512
+ end
513
+
514
+ it "implements .slice correctly" do
515
+ _(ENV!.slice('INT_HASH', 'FLOAT', 'NOTATHING')).must_equal({
516
+ 'INT_HASH' => { one: 1, two: 2 },
517
+ 'FLOAT' => 1.234,
518
+ })
519
+ end
520
+
521
+ it "implements .to_hash correctly" do
522
+ _(ENV!.to_hash).must_equal ENV!.to_h
523
+ end
524
+
525
+ it "implements .value?/has_value? correctly" do
526
+ _(ENV!.value?(1)).must_equal true
527
+ _(ENV!.value?(2)).must_equal false
528
+ _(ENV!.has_value?(1)).must_equal true
529
+ _(ENV!.has_value?(2)).must_equal false
530
+ end
531
+
532
+ it "implements .values_at correctly" do
533
+ _(ENV!.values_at('INT_HASH', 'FLOAT', 'NOTATHING')).must_equal [
534
+ { one: 1, two: 2 }, 1.234, nil
535
+ ]
536
+ end
537
+ end
369
538
  end
data/test/test_helper.rb CHANGED
@@ -1,13 +1,21 @@
1
- require 'simplecov'
2
- require 'coveralls'
3
-
4
1
  require 'minitest/autorun'
5
2
  require 'minitest/spec'
6
3
 
7
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
- SimpleCov::Formatter::HTMLFormatter,
9
- Coveralls::SimpleCov::Formatter
10
- ]
11
- SimpleCov.start
4
+ require 'simplecov'
5
+
6
+ SimpleCov.start 'rails' do
7
+ if ENV['CI']
8
+ require 'simplecov-lcov'
9
+
10
+ SimpleCov::Formatter::LcovFormatter.config do |c|
11
+ c.report_with_single_file = true
12
+ c.single_report_path = 'coverage/lcov.info'
13
+ end
14
+
15
+ formatter SimpleCov::Formatter::LcovFormatter
16
+ end
17
+
18
+ add_filter %w[version.rb initializer.rb]
19
+ end
12
20
 
13
21
  require 'env_bang'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: env_bang
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Camenisch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-14 00:00:00.000000000 Z
11
+ date: 2023-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -46,8 +46,8 @@ executables: []
46
46
  extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
+ - ".circleci/config.yml"
49
50
  - ".gitignore"
50
- - ".travis.yml"
51
51
  - Gemfile
52
52
  - LICENSE.txt
53
53
  - README.md
@@ -76,9 +76,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
76
  version: '0'
77
77
  required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
79
+ - - ">"
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: 1.3.1
82
82
  requirements: []
83
83
  rubygems_version: 3.3.7
84
84
  signing_key:
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.7
4
- - 3.0
5
- - 3.1
6
- - 3.2
7
- - ruby-head