inquisitive 2.0.1 → 3.0.0

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
  SHA1:
3
- metadata.gz: ae129b66c1055352e43e907ac246009511ef0cd2
4
- data.tar.gz: 4cc0713d97d9ed273f904a186bd12cc2d8bdf8b3
3
+ metadata.gz: 80d236d855c6c33b3ec287fcd2c3a302388608f3
4
+ data.tar.gz: bd301adffafcbc757db422e5e0adeb780a06b5e4
5
5
  SHA512:
6
- metadata.gz: 82aa740e308e0cc964700818ce3ea10446a90c586788ea8e856102a89ec00676a23ccfb60de5b3670ef48333c720e6dc20cc6c15ff66a3b46e854579eb76f368
7
- data.tar.gz: b6d575e5815e3ee08fb6c933779604288f5a6995f6ad7d03ac78f01f3fbf91a6b766b45169fad54fdf2463d401aeafda30701f53643da9919891b0ed3d450b96
6
+ metadata.gz: e19cf79e18d77f23a58ee9c6dfc6d87af7262e4fd828f271e9cfe3694c67b38d11ea6c10764a14b6483ce037accac1491348a9a25ef6351c5d7332b6f0cd1d6a
7
+ data.tar.gz: 5e287d046ac747a2f27391bb6c38046b33c3123c93e953546948a06d16500cacde4629fcb77b66c39cfee4941eebb8e1d8df6ba7e4ca41ae6313d7c5989cadd3
data/.travis.yml CHANGED
@@ -4,10 +4,11 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1
7
+ - 2.2
7
8
  - ruby-head
8
9
  - rbx-2
9
10
  - jruby
10
-
11
+
11
12
  gemfile:
12
13
  - Gemfile
13
14
  - Gemfile.ActiveSupport
@@ -20,10 +21,6 @@ env:
20
21
 
21
22
  matrix:
22
23
  fast_finish: true
23
- allow_failures:
24
- - rvm: rbx-2
25
- - rvm: jruby
26
- - rvm: ruby-head
27
24
  exclude:
28
25
  - gemfile: Gemfile.ActiveSupport
29
26
  env: ""
@@ -33,7 +30,7 @@ matrix:
33
30
  env: "activesupport=4.1.1"
34
31
  - gemfile: Gemfile
35
32
  env: "activesupport=master"
36
-
33
+
37
34
  branches:
38
35
  except:
39
36
  - gh-pages
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Chris Keele
1
+ Copyright (c) 2013-2015 Chris Keele
2
2
  ------------------------------
3
3
 
4
4
  MIT License
data/README.md CHANGED
@@ -4,6 +4,7 @@ Inquisitive
4
4
  > **Predicate methods for those curious about their datastructures.**
5
5
 
6
6
 
7
+
7
8
  Synopsis
8
9
  --------
9
10
 
@@ -14,10 +15,12 @@ It also allows you to auto-instanciate and read inquisitive datastructures strai
14
15
  Inquisitive will try to use ActiveSupport's `HashWithIndifferentAccess`, but if that cannot be found it will bootstrap itself with a minimal, well-tested version extracted from ActiveSupport 4.0.
15
16
 
16
17
 
18
+
17
19
  Status
18
20
  ------
19
21
 
20
- [status]: https://travis-ci.org/christhekeele/inquisitive
22
+ [status]: https://travis-ci.org/christhekeele/inquisitive
23
+ [coverage]: https://rawgit.com/christhekeele/inquisitive/master/coverage/index.html
21
24
 
22
25
  [version]: https://rubygems.org/gems/inquisitive/versions
23
26
  [version-image]: https://badge.fury.io/rb/inquisitive@2x.svg
@@ -38,12 +41,13 @@ Status
38
41
 
39
42
  [![Version][version-image]][version] [![Quality][quality-image]][quality] [![Dependencies][dependencies-image]][dependencies]
40
43
 
41
- | :thumbsup: | [Continuous Integration][status] | Test Coverage |
44
+ | :thumbsup: | [Continuous Integration][status] | [Test Coverage][coverage] |
42
45
  |:--------------------------:|:-----------------------------------:|:----------------------------------------:|
43
46
  | [Master][master] | ![Build Status][master-status] | ![Coverage Status][master-coverage] |
44
47
  | [Development][development] | ![Build Status][development-status] | ![Coverage Status][development-coverage] |
45
48
 
46
49
 
50
+
47
51
  Installation
48
52
  ------------
49
53
 
@@ -61,9 +65,11 @@ $ gem install inquisitive
61
65
  ```
62
66
 
63
67
 
68
+
64
69
  Usage
65
70
  -----
66
71
 
72
+
67
73
  ### String
68
74
 
69
75
  `Inquisitive::String` tests equality:
@@ -77,6 +83,7 @@ environment.not.development?
77
83
  #=> false
78
84
  ```
79
85
 
86
+
80
87
  ### Array
81
88
 
82
89
  `Inquisitive::Array` tests inclusion:
@@ -92,6 +99,7 @@ supported_databases.exclude.sql_server?
92
99
  #=> true
93
100
  ```
94
101
 
102
+
95
103
  ### Hash
96
104
 
97
105
  `Inquisitive::Hash` provides struct-like access to its values, wrapped in other inquisitive objects:
@@ -101,11 +109,13 @@ stubbed = Inquisitive::Hash.new(
101
109
  authentication: true,
102
110
  in: 'development',
103
111
  services: %w[database api],
112
+ api: {protocol: 'https', subdomains: %w[app web db]},
104
113
  ignorable: { junk: [ "" ] }
105
114
  )
106
115
  #=> {"authentication"=>true,
107
116
  #=> "in"=>"development",
108
117
  #=> "services"=>["database", "api"],
118
+ #=> "api"=>{"protocol"=>"https", "subdomains"=>["app", "web", "db"]},
109
119
  #=> "ignorable"=>{"junk"=>[""]}}
110
120
 
111
121
  stubbed.authentication?
@@ -114,6 +124,8 @@ stubbed.registration?
114
124
  #=> false
115
125
  stubbed.services?
116
126
  #=> true
127
+ stubbed.api?
128
+ #=> true
117
129
  stubbed.ignorable?
118
130
  #=> false
119
131
 
@@ -121,10 +133,18 @@ stubbed.in.development?
121
133
  #=> true
122
134
  stubbed.in.production?
123
135
  #=> false
136
+
124
137
  stubbed.services.database?
125
138
  #=> true
126
139
  stubbed.services.sidekiq?
127
140
  #=> false
141
+
142
+ stubbed.api.protocol?
143
+ #=> true
144
+ stubbed.api.protocol.http?
145
+ #=> false
146
+ stubbed.api.domains.web?
147
+ #=> true
128
148
  ```
129
149
 
130
150
  `Inquisitive::Hash` also allows negation with the `no` method:
@@ -143,6 +163,56 @@ config.no.api?
143
163
  #=> true
144
164
  ```
145
165
 
166
+ Empty keys and nil values become instances of `Inquisitive::NilClass`, which is a black-hole null object that respects the Inquisitive interface, allowing you to inquire on non-existant nested datastructures as if there was one there, negated methods included:
167
+
168
+ ```ruby
169
+ stubbed = Inquisitive::Hash.new
170
+ #=> {}
171
+
172
+ # We can query it as if we assumed we had:
173
+ #=> {"authentication"=>true,
174
+ #=> "in"=>"development",
175
+ #=> "services"=>["database", "api"],
176
+ #=> "api"=>{"protocol"=>"https", "subdomains"=>["app", "web", "db"]}}
177
+
178
+ stubbed.authentication?
179
+ #=> false
180
+ stubbed.registration?
181
+ #=> false
182
+ stubbed.services?
183
+ #=> false
184
+ stubbed.api?
185
+ #=> false
186
+ stubbed.ignorable?
187
+ #=> false
188
+ stubbed.no.ignorable?
189
+ #=> true
190
+
191
+ stubbed.in.development?
192
+ #=> false
193
+ stubbed.in.production?
194
+ #=> false
195
+ stubbed.in.not.production?
196
+ #=> true
197
+
198
+ stubbed.services.database?
199
+ #=> false
200
+ stubbed.services.sidekiq?
201
+ #=> false
202
+ stubbed.services.exclude.sidekiq?
203
+ #=> true
204
+
205
+ stubbed.api.protocol?
206
+ #=> false
207
+ stubbed.api.no.protocol?
208
+ #=> true
209
+ stubbed.api.protocol.http?
210
+ #=> false
211
+ stubbed.api.domains.web?
212
+ #=> false
213
+ ```
214
+
215
+
146
216
  ### Inquisitive Environment
147
217
 
148
218
  `Inquisitive::Environment` can be used in your modules and classes to more easily interrogate `ENV` variables with inquisitive objects:
@@ -151,59 +221,69 @@ config.no.api?
151
221
 
152
222
  ```ruby
153
223
  ENV['ENVIRONMENT'] = "development"
154
- class MyGame
224
+ class MyApp
155
225
  extend Inquisitive::Environment
156
226
  inquires_about 'ENVIRONMENT'
157
227
  end
158
228
 
159
- MyGame.environment
229
+ MyApp.environment
160
230
  #=> "development"
161
- MyGame.environment.development?
231
+ MyApp.environment.development?
162
232
  #=> true
163
- MyGame.environment.production?
233
+ MyApp.environment.production?
164
234
  #=> false
165
235
  ```
166
236
 
167
237
  #### Arrays
168
238
 
239
+ Arrays are recognized when environment variables contain commas:
240
+
169
241
  ```ruby
170
242
  ENV['SUPPORTED_DATABASES'] = "mysql,postgres,sqlite"
171
- class MyGame
243
+ class MyApp
172
244
  extend Inquisitive::Environment
173
245
  inquires_about 'SUPPORTED_DATABASES'
174
246
  end
175
247
 
176
- MyGame.supported_databases
248
+ MyApp.supported_databases
177
249
  #=> ["mysql", "postgres", "sqlite"]
178
- MyGame.supported_databases.sqlite?
250
+ MyApp.supported_databases.sqlite?
179
251
  #=> true
180
- MyGame.supported_databases.sql_server?
252
+ MyApp.supported_databases.sql_server?
181
253
  #=> false
182
254
  ```
183
255
 
184
256
  #### Hashes
185
257
 
258
+ Hashes are recognized when environment variables names contain double underscores:
259
+
186
260
  ```ruby
187
261
  ENV['STUB__AUTHENTICATION'] = 'true'
188
262
  ENV['STUB__IN'] = "development"
189
263
  ENV['STUB__SERVICES'] = "database,api"
190
- class MyGame
264
+ ENV['STUB__API__PROTOCOL'] = "https"
265
+ ENV['STUB__API__SUBDOMAINS'] = "app,web,db"
266
+ class MyApp
191
267
  extend Inquisitive::Environment
192
268
  inquires_about 'STUB'
193
269
  end
194
270
 
195
- MyGame.stub.authentication?
271
+ MyApp.stub.authentication?
196
272
  #=> true
197
- MyGame.stub.registration?
273
+ MyApp.stub.registration?
198
274
  #=> false
199
- MyGame.stub.in.development?
275
+ MyApp.stub.in.development?
200
276
  #=> true
201
- MyGame.stub.in.production?
277
+ MyApp.stub.in.production?
202
278
  #=> false
203
- MyGame.stub.services.exclude.sidekiq?
279
+ MyApp.stub.services.exclude.sidekiq?
204
280
  #=> true
205
- MyGame.stub.services.sidekiq?
281
+ MyApp.stub.services.sidekiq?
282
+ #=> false
283
+ MyApp.stub.api.protocol.http?
206
284
  #=> false
285
+ MyApp.stub.api.subdomains.web?
286
+ #=> true
207
287
  ```
208
288
 
209
289
  #### Naming
@@ -212,100 +292,16 @@ You can name your environment inquirers with `:with`:
212
292
 
213
293
  ```ruby
214
294
  ENV['ENVIRONMENT'] = "development"
215
- class MyGame
295
+ class MyApp
216
296
  extend Inquisitive::Environment
217
297
  inquires_about 'ENVIRONMENT', with: :env
218
298
  end
219
299
 
220
- MyGame.env
300
+ MyApp.env
221
301
  #=> "development"
222
- MyGame.env.development?
223
- #=> true
224
- MyGame.env.production?
225
- #=> false
226
- ```
227
-
228
- #### Presence
229
-
230
- Environment inquirers can have explicit presence checks, circumventing a common pitfall when reasoning about environment variables. Borrowing from the example above:
231
-
232
- ```ruby
233
- ENV['STUB__AUTHENTICATION'] = 'false'
234
- class MyGame
235
- extend Inquisitive::Environment
236
- inquires_about 'STUB'
237
- end
238
-
239
- MyGame.stub.authentication
240
- #=> "false"
241
- MyGame.stub.authentication?
302
+ MyApp.env.development?
242
303
  #=> true
243
- MyGame.stub.authentication.true?
244
- #=> false
245
- ```
246
-
247
- It's common to use the presence of environment variables as runtime booleans. This is frequently done by setting the environment variable to the string `"true"` when you want it to be true, and not at all otherwise. As demonstrated, this pattern can lead to ambiguity when the string is other values.
248
-
249
- By default such variables will be parsed as an `Inquisitive::String`, so predicate methods will return true whatever their contents, as long as they exist. You can bind the predicate method tighter to an explicit value if you prefer:
250
-
251
- ```ruby
252
- ENV['STUB_AUTHENTICATION'] = 'false'
253
- ENV['STUB_REGISTRATION'] = 'true'
254
- class MyGame
255
- extend Inquisitive::Environment
256
- inquires_about 'STUB_AUTHENTICATION', present_if: 'true'
257
- inquires_about 'STUB_REGISTRATION', present_if: 'true'
258
- end
259
-
260
- MyGame.stub_authentication
261
- #=> "false"
262
- MyGame.stub_authentication?
263
- #=> false
264
-
265
- MyGame.stub_registration
266
- #=> "true"
267
- MyGame.stub_registration?
268
- #=> true
269
- ```
270
-
271
- This only works on top-level inquirers, so there's no way to get our nested `MyGame.stubbed.authentication?` to behave as expected (currently).
272
-
273
- The `present_if` check uses `===` under the covers for maximum expressiveness, so you can also use it to match against regexs, classes, and other constructs.
274
-
275
- ##### Truthy Booleans
276
-
277
- `Inquisitive::Environment.truthy` contains a regex useful for reading booleans from environment variables.
278
-
279
- ```ruby
280
- ENV['NO'] = 'no'
281
- ENV['YES'] = 'yes'
282
- ENV['TRUTHY'] = 'TrUe'
283
- ENV['FALSEY'] = 'FaLsE'
284
- ENV['BOOLEAN'] = '1'
285
- ENV['BOOLENOPE'] = '0'
286
- class MyCli
287
- extend Inquisitive::Environment
288
- inquires_about 'NO', present_if: truthy
289
- inquires_about 'YES', present_if: truthy
290
- inquires_about 'TRUTHY', present_if: truthy
291
- inquires_about 'FALSEY', present_if: truthy
292
- inquires_about 'BOOLEAN', present_if: truthy
293
- inquires_about 'BOOLENOPE', present_if: truthy
294
- end
295
-
296
- MyGame.no?
297
- #=> false
298
- MyGame.yes?
299
- #=> true
300
-
301
- MyGame.truthy?
302
- #=> true
303
- MyGame.falsey?
304
- #=> false
305
-
306
- MyGame.boolean?
307
- #=> true
308
- MyGame.boolenope?
304
+ MyApp.env.production?
309
305
  #=> false
310
306
  ```
311
307
 
@@ -314,7 +310,7 @@ MyGame.boolenope?
314
310
  Environment inquirers have three configurable modes, defaulting to `:static`.
315
311
 
316
312
  ```ruby
317
- class MyGame
313
+ class MyApp
318
314
  extend Inquisitive::Environment
319
315
  inquires_about 'STUB', mode: %i[dynamic lazy static].sample
320
316
  end
@@ -336,7 +332,8 @@ end
336
332
 
337
333
  Environment inquiries use the contents of `ENV` at the moment `inquires_about` was invoked.
338
334
 
339
- Use if your application is well-behaved and doesn't go mucking around with the environment at runtime.
335
+ Use if your application is well-behaved and doesn't go mucking around with the environment at runtim.
336
+
340
337
 
341
338
 
342
339
  Contributing
data/Rakefile CHANGED
@@ -7,6 +7,17 @@ Rake::TestTask.new do |t|
7
7
  end
8
8
  task default: :test
9
9
 
10
- task :console do
11
- `pry -I lib -r inquisitive.rb`
10
+ desc "Open a pry console preloaded with this library"
11
+ task console: 'console:pry'
12
+
13
+ namespace :console do
14
+
15
+ task :pry do
16
+ sh "bundle exec pry -I lib -r inquisitive.rb"
17
+ end
18
+
19
+ task :irb do
20
+ sh "bundle exec irb -I lib -r inquisitive.rb"
21
+ end
22
+
12
23
  end
data/inquisitive.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "inquisitive"
7
- spec.version = "2.0.1"
7
+ spec.version = "3.0.0"
8
8
  spec.authors = ["Chris Keele"]
9
9
  spec.email = ["dev@chriskeele.com"]
10
10
  spec.summary = "Predicate methods for those curious about their datastructures."
@@ -18,11 +18,10 @@ Gem::Specification.new do |spec|
18
18
  Also allows you to auto-instanciate and read inquisitive datastructures straight
19
19
  from your `ENV` hash.
20
20
  DESC
21
- spec.homepage = "https://github.com/rawsugar/inquisitive"
21
+ spec.homepage = "http://christhekeele.github.io/inquisitive"
22
22
  spec.license = "MIT"
23
-
24
- spec.files = `git ls-files`.split($/)
25
- spec.test_files = spec.files.grep(%r{^(test)/})
23
+ spec.files = `git ls-files lib README.md LICENSE.md`.split($/)
24
+ spec.test_files = `git ls-files test inquisitive.gemspec Gemfile Gemfile.lock Gemfile.ActiveSupport Rakefile .travis.yml .coveralls.yml`.split($/)
26
25
  spec.require_paths = ["lib"]
27
26
 
28
27
  spec.add_development_dependency "bundler", ">= 1.3"
data/lib/inquisitive.rb CHANGED
@@ -10,16 +10,18 @@ module Inquisitive
10
10
 
11
11
  def present?(object)
12
12
  case object
13
- when ::String
13
+ when ::String, String
14
14
  not object.empty?
15
- when ::Array
15
+ when ::Array, Array
16
16
  object.any? do |value|
17
17
  Inquisitive.present? value
18
18
  end
19
- when ::Hash
19
+ when ::Hash, Hash
20
20
  object.values.any? do |value|
21
21
  Inquisitive.present? value
22
22
  end
23
+ when ::NilClass, NilClass
24
+ false
23
25
  else
24
26
  !!object
25
27
  end
@@ -39,6 +41,7 @@ private
39
41
 
40
42
  end
41
43
 
44
+ require "inquisitive/nil_class"
42
45
  require "inquisitive/string"
43
46
  require "inquisitive/array"
44
47
  unless Object.const_defined? :HashWithIndifferentAccess
@@ -1,12 +1,16 @@
1
1
  module Inquisitive
2
2
  class Array < ::Array
3
3
  include Inquisitive
4
- attr_accessor :negated, :array
5
4
 
5
+ attr_accessor :negated
6
6
  def exclude
7
7
  self.dup.tap{ |a| a.negated = !a.negated }
8
8
  end
9
9
 
10
+ def === other
11
+ other.class == Class and other == ::Array or super
12
+ end
13
+
10
14
  private
11
15
 
12
16
  def respond_to_missing?(method_name, include_private = false)
@@ -2,10 +2,6 @@ module Inquisitive
2
2
  module Environment
3
3
  include Inquisitive
4
4
 
5
- def truthy
6
- /true|yes|1/i
7
- end
8
-
9
5
  def inquires_about(env_var, opts={})
10
6
 
11
7
  env_accessor = opts.fetch(:with, env_var.downcase[/(.*?)(?=(?:_$|$))/])
@@ -35,19 +31,6 @@ module Inquisitive
35
31
 
36
32
  end
37
33
 
38
- present_if = opts.fetch(:present_if, nil)
39
-
40
- @__env_presence__ ||= HashWithIndifferentAccess.new
41
- @__env_presence__["#{env_accessor}?"] = present_if if present_if
42
-
43
- define_singleton_method :"#{env_accessor}?" do
44
- if @__env_presence__.has_key? __method__
45
- @__env_presence__[__method__] === send(predication(__method__))
46
- else
47
- Inquisitive.present? send(predication(__method__))
48
- end
49
- end
50
-
51
34
  end
52
35
 
53
36
  private
@@ -56,7 +39,7 @@ module Inquisitive
56
39
  class << self
57
40
 
58
41
  def [](var_name)
59
- if ENV.has_key? var_name
42
+ result = if ENV.has_key? var_name
60
43
 
61
44
  env_var = ENV[var_name]
62
45
  if env_var.include? ','
@@ -67,14 +50,15 @@ module Inquisitive
67
50
 
68
51
  elsif env_vars = can_find_env_keys_from(var_name)
69
52
 
70
- env_vars.reduce({}) do |hash, key|
71
- hash[key_for(key, var_name)] = Inquisitive[Parser[key]]
72
- hash
53
+ Hash[].tap do |hash|
54
+ env_vars.each do |key|
55
+ set_hash_value_of hash, key
56
+ end
73
57
  end
74
58
 
75
- else
76
- ""
77
59
  end
60
+
61
+ replace_empty result
78
62
  end
79
63
 
80
64
  def can_find_env_keys_from(var_name)
@@ -88,8 +72,26 @@ module Inquisitive
88
72
  end
89
73
  end
90
74
 
91
- def key_for(env_key, var_name)
92
- env_key.gsub("#{var_name}__", '').downcase
75
+ def set_hash_value_of(hash, var)
76
+ keypath = var.split('__').map(&:downcase)
77
+ keypath.shift
78
+ hash.tap do |hash|
79
+ keypath.reduce(hash) do |namespace, key|
80
+ namespace[key] = if key == keypath.last
81
+ replace_empty Inquisitive[Parser[var]]
82
+ else
83
+ if namespace[key].respond_to? :store
84
+ namespace[key]
85
+ else
86
+ Hash.new
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def replace_empty(value)
94
+ value == "" or value.nil? ? NilClass.new(nil) : value
93
95
  end
94
96
 
95
97
  end
@@ -11,6 +11,10 @@ module Inquisitive
11
11
  super(Inquisitive[value], options)
12
12
  end
13
13
 
14
+ def === other
15
+ other.class == Class and other == ::Hash or super
16
+ end
17
+
14
18
  private
15
19
 
16
20
  def dup
@@ -27,10 +31,8 @@ module Inquisitive
27
31
  else
28
32
  false
29
33
  end ^ negated
30
- elsif has_key? method_name
31
- self[method_name]
32
34
  else
33
- super
35
+ Inquisitive[self[method_name]]
34
36
  end
35
37
  end
36
38
 
@@ -0,0 +1,48 @@
1
+ module Inquisitive
2
+ class NilClass
3
+ include Inquisitive
4
+
5
+ def initialize(object=nil); end
6
+
7
+ attr_accessor :negated
8
+ def not
9
+ self.dup.tap{ |s| s.negated = !s.negated }
10
+ end
11
+ alias_method :exclude, :not
12
+ alias_method :no, :not
13
+
14
+ undef_method :nil?, :inspect, :to_s
15
+
16
+ # Since we can't subclass NilClass
17
+ # (it has no allocate method)
18
+ # we fake its identity.
19
+ def instance_of?(klass)
20
+ klass == ::NilClass or super
21
+ end
22
+ alias_method :kind_of?, :instance_of?
23
+ alias_method :is_a?, :instance_of?
24
+
25
+ def == other
26
+ other.nil?
27
+ end
28
+ def === other
29
+ other.class == Class and other == ::NilClass or super
30
+ end
31
+
32
+ private
33
+
34
+ def respond_to_missing?(method_name, include_private = false)
35
+ true # nil.respond_to? method_name or predicate_method? method_name
36
+ end
37
+ def method_missing(method_name, *arguments)
38
+ if nil.respond_to? method_name
39
+ nil.send method_name, *arguments
40
+ elsif predicate_method? method_name
41
+ false ^ negated
42
+ else
43
+ self
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -7,6 +7,10 @@ module Inquisitive
7
7
  self.dup.tap{ |s| s.negated = !s.negated }
8
8
  end
9
9
 
10
+ def === other
11
+ other.class == Class and other == ::String or super
12
+ end
13
+
10
14
  private
11
15
 
12
16
  def respond_to_missing?(method_name, include_private = false)
@@ -4,22 +4,31 @@ class InquisitiveCombinatorialEnvironmentTest < EnvironmentTest
4
4
 
5
5
  def setup
6
6
  super
7
+ ENV['NIL_OBJECT'] = @raw_nil_object
7
8
  ENV['STRING'] = @raw_string
8
9
  ENV['ARRAY'] = @raw_array.join(',')
10
+ ENV['HASH__NOTHING'] = @raw_hash[:nothing]
9
11
  ENV['HASH__AUTHENTICATION'] = @raw_hash[:authentication].to_s
10
12
  ENV['HASH__IN'] = @raw_hash[:in]
11
13
  ENV['HASH__DATABASES'] = @raw_hash[:databases].join(',')
14
+ ENV['HASH__NESTED__KEY'] = @raw_hash[:nested][:key]
15
+ ENV['HASH__NESTED__ARRAY'] = @raw_hash[:nested][:array].join(',')
12
16
  end
13
17
  def teardown
14
18
  super
15
19
  ENV.delete 'STRING'
16
20
  ENV.delete 'ARRAY'
21
+ ENV.delete 'HASH__NOTHING'
17
22
  ENV.delete 'HASH__AUTHENTICATION'
18
23
  ENV.delete 'HASH__IN'
19
24
  ENV.delete 'HASH__DATABASES'
25
+ ENV.delete 'HASH__NESTED__KEY'
20
26
  ENV.delete 'HASH__SOMETHING_NEW'
21
27
  end
22
28
 
29
+ def change_nil_object_variable
30
+ ENV['NIL_OBJECT'] = 'something_new'
31
+ end
23
32
  def change_string_variable
24
33
  ENV['STRING'] = 'something_new'
25
34
  end
@@ -33,10 +42,10 @@ class InquisitiveCombinatorialEnvironmentTest < EnvironmentTest
33
42
  end
34
43
 
35
44
  %w[dynamic lazy static].each do |mode|
36
- %w[string array hash].each do |type|
45
+ %w[nil_object string array hash].each do |type|
37
46
 
38
47
  Inquisitive.const_set(
39
- :"Inquisitive#{mode.capitalize}#{type.capitalize}EnvironmentTest",
48
+ :"Inquisitive#{mode.capitalize}#{type.split('_').map(&:capitalize).join}EnvironmentTest",
40
49
  Class.new(InquisitiveCombinatorialEnvironmentTest) do
41
50
 
42
51
  class << self
@@ -50,6 +59,9 @@ end
50
59
  App.inquires_about @type.upcase, mode: @mode
51
60
  end
52
61
 
62
+ def nil_object
63
+ App.nil_object
64
+ end
53
65
  def string
54
66
  App.string
55
67
  end
@@ -66,7 +78,7 @@ end
66
78
  ).tap do |klass|
67
79
  klass.mode = mode
68
80
  klass.type = type
69
- end.send :include, Object.const_get(:"#{type.capitalize}Tests")
81
+ end.send :include, Object.const_get(:"#{type.split('_').map(&:capitalize).join}Tests")
70
82
  # Mixes in type-specific tests to ensure lookup behaves normally
71
83
  # when accessed through the modes of App getters
72
84
 
@@ -2,15 +2,6 @@ require 'test_helper'
2
2
 
3
3
  class InquisitiveEnvironmentTest < EnvironmentTest
4
4
 
5
- def test_missing_variable_responses
6
- App.inquires_about 'DOES_NOT_EXIST', with: :exists
7
- assert_equal "", App.exists
8
- end
9
- def test_missing_variable_predicates
10
- App.inquires_about 'DOES_NOT_EXIST', with: :exists
11
- refute App.exists?
12
- end
13
-
14
5
  def test_autonaming_of_inquirers
15
6
  App.inquires_about 'NAME_NOT_SPECIFIED'
16
7
  assert App.respond_to? :name_not_specified
@@ -25,30 +16,4 @@ class InquisitiveEnvironmentTest < EnvironmentTest
25
16
  assert App.defaults_to.static?
26
17
  end
27
18
 
28
- def test_custom_string_presence
29
- ENV['AUTHORIZABLE'] = 'false'
30
- App.inquires_about 'AUTHORIZABLE', present_if: 'true'
31
- refute App.authorizable?
32
- end
33
-
34
- def test_custom_regex_presence
35
- ENV['AUTHORIZABLE'] = 'not at all'
36
- App.inquires_about 'AUTHORIZABLE', present_if: /yes/
37
- refute App.authorizable?
38
- end
39
-
40
- def test_custom_class_presence
41
- ENV['AUTHORIZABLE'] = 'not at all'
42
- App.inquires_about 'AUTHORIZABLE', present_if: Array
43
- refute App.authorizable?
44
- end
45
-
46
- %w[true True TrUe TRUE yes Yes YeS YES 1].each do |truthy_var|
47
- define_method :"test_truthy_var_#{truthy_var}" do
48
- ENV['TRUTHY'] = truthy_var
49
- App.inquires_about 'TRUTHY', present_if: App.truthy
50
- assert App.truthy?
51
- end
52
- end
53
-
54
19
  end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class NilObjectTest < Test
4
+
5
+ def nil_object
6
+ Inquisitive::NilClass.new
7
+ end
8
+
9
+ include NilObjectTests
10
+
11
+ end
@@ -19,9 +19,6 @@ class InquisitiveTest < Test
19
19
  ####
20
20
  # CONVERSION
21
21
  ##
22
- def test_converted_nil_equality
23
- assert_equal Inquisitive[nil], nil
24
- end
25
22
  def test_converted_false_equality
26
23
  assert_equal Inquisitive[false], false
27
24
  end
@@ -41,22 +38,45 @@ class InquisitiveTest < Test
41
38
  assert_equal Inquisitive[@object], @object
42
39
  end
43
40
 
41
+ def test_converted_nil_object_ancestry
42
+ assert_kind_of NilClass, Inquisitive[nil]
43
+ assert Inquisitive[nil] === NilClass
44
+ end
45
+ def test_converted_nil_object_instanciation
46
+ assert_kind_of Inquisitive::NilClass, Inquisitive[nil]
47
+ end
48
+ def test_converted_nil_object_equality
49
+ assert_equal Inquisitive[nil], @raw_nil_object
50
+ end
51
+
52
+ def test_converted_string_ancestry
53
+ assert_kind_of String, Inquisitive[@raw_string]
54
+ assert Inquisitive[@raw_string] === String
55
+ end
44
56
  def test_converted_string_instanciation
45
- assert_instance_of Inquisitive::String, Inquisitive[@raw_string]
57
+ assert_kind_of Inquisitive::String, Inquisitive[@raw_string]
46
58
  end
47
59
  def test_converted_string_equality
48
60
  assert_equal Inquisitive[@raw_string], @raw_string
49
61
  end
50
62
 
63
+ def test_converted_array_ancestry
64
+ assert_kind_of Array, Inquisitive[@raw_array]
65
+ assert Inquisitive[@raw_array] === Array
66
+ end
51
67
  def test_converted_array_instanciation
52
- assert_instance_of Inquisitive::Array, Inquisitive[@raw_array]
68
+ assert_kind_of Inquisitive::Array, Inquisitive[@raw_array]
53
69
  end
54
70
  def test_converted_array_equality
55
71
  assert_equal Inquisitive[@raw_array], @raw_array
56
72
  end
57
73
 
74
+ def test_converted_hash_ancestry
75
+ assert_kind_of Hash, Inquisitive[@raw_hash]
76
+ assert Inquisitive[@raw_hash] === Hash
77
+ end
58
78
  def test_converted_hash_instanciation
59
- assert_instance_of Inquisitive::Hash, Inquisitive[@raw_hash]
79
+ assert_kind_of Inquisitive::Hash, Inquisitive[@raw_hash]
60
80
  end
61
81
  def test_converted_hash_equality
62
82
  assert_equal Inquisitive[@raw_hash], HashWithIndifferentAccess.new(@raw_hash)
@@ -2,27 +2,28 @@ module ArrayTests
2
2
  def test_array_value_type
3
3
  assert_instance_of Inquisitive::Array, array
4
4
  end
5
+
5
6
  def test_array_match
6
7
  assert array.postgres?
7
8
  end
8
9
  def test_array_miss
9
10
  refute array.sql_server?
10
11
  end
12
+
11
13
  def test_array_negative_match
12
14
  assert array.exclude.sql_server?
13
15
  end
14
16
  def test_array_negative_miss
15
17
  refute array.exclude.postgres?
16
18
  end
19
+
17
20
  def test_array_double_negative_match
18
21
  assert array.exclude.exclude.postgres?
19
22
  end
20
23
  def test_array_double_negative_miss
21
24
  refute array.exclude.exclude.sql_server?
22
25
  end
23
- def test_array_missing_question_mark
24
- assert_raises(NoMethodError) { array.postgres }
25
- end
26
+
26
27
  def test_array_respond_to
27
28
  assert_respond_to array, :postgres?
28
29
  end
@@ -2,14 +2,14 @@ module CombinatorialEnvironmentTests
2
2
 
3
3
  def test_type_is_parsed_correctly
4
4
  assert_kind_of(
5
- Object.const_get(:"#{@type.capitalize}"),
5
+ Object.const_get(:"#{type_const_name}"),
6
6
  App.send(@type)
7
7
  )
8
8
  end
9
9
 
10
10
  def test_type_is_converted_correctly
11
11
  assert_kind_of(
12
- Inquisitive.const_get(:"#{@type.capitalize}"),
12
+ Inquisitive.const_get(:"#{type_const_name}"),
13
13
  App.send(@type)
14
14
  )
15
15
  end
@@ -30,4 +30,10 @@ module CombinatorialEnvironmentTests
30
30
  end
31
31
  end
32
32
 
33
+ private
34
+
35
+ def type_const_name
36
+ @type == 'nil_object' ? 'NilClass' : @type.capitalize
37
+ end
38
+
33
39
  end
@@ -1,26 +1,46 @@
1
1
  module HashTests
2
+ def test_hash_value_type
3
+ assert_instance_of Inquisitive::Hash, hash
4
+ end
5
+
2
6
  def test_hash_match
3
7
  assert hash.authentication?
4
8
  end
5
9
  def test_hash_miss
6
10
  refute hash.registration?
7
11
  end
12
+
13
+ def test_hash_access_implicit_nil
14
+ assert_instance_of Inquisitive::NilClass, hash.missing_key
15
+ end
16
+ def test_hash_access_explicit_nil
17
+ assert_instance_of Inquisitive::NilClass, hash.nothing
18
+ end
19
+ def test_hash_access_string
20
+ assert_instance_of Inquisitive::String, hash.in
21
+ end
22
+ def test_hash_access_array
23
+ assert_instance_of Inquisitive::Array, hash.databases
24
+ end
25
+ def test_hash_access_hash
26
+ assert_instance_of Inquisitive::Hash, hash.nested
27
+ end
28
+
8
29
  def test_hash_negative_match
9
30
  assert hash.no.registration?
10
31
  end
11
32
  def test_hash_negative_miss
12
33
  refute hash.no.authentication?
13
34
  end
35
+
14
36
  def test_hash_double_negative_match
15
37
  assert hash.no.no.authentication?
16
38
  end
17
39
  def test_hash_double_negative_miss
18
40
  refute hash.no.no.registration?
19
41
  end
42
+
20
43
  def test_hash_respond_to
21
44
  assert_respond_to hash, :authentication?
22
45
  end
23
- def test_hash_method_missing
24
- assert_raises(NoMethodError) { hash.undefined }
25
- end
26
46
  end
@@ -0,0 +1,56 @@
1
+ module NilObjectTests
2
+ def test_nil_object_value_type
3
+ assert_instance_of Inquisitive::NilClass, nil_object
4
+ end
5
+
6
+ def test_nil_object_chains
7
+ assert_instance_of Inquisitive::NilClass, nil_object.chain
8
+ end
9
+
10
+ def test_nil_object_match
11
+ assert nil_object.nil?
12
+ end
13
+ def test_nil_object_miss
14
+ refute nil_object.anything_else?
15
+ end
16
+
17
+ def test_nil_object_string_interface
18
+ string = nil_object
19
+ refute string.production?
20
+ end
21
+ def test_nil_object_string_interface_negative
22
+ string = nil_object
23
+ assert string.not.development?
24
+ end
25
+ def test_nil_object_string_interface_double_negative
26
+ string = nil_object
27
+ refute string.not.not.development?
28
+ end
29
+
30
+ def test_nil_object_array_interface
31
+ array = nil_object
32
+ refute array.production?
33
+ end
34
+ def test_nil_object_array_interface_negative
35
+ array = nil_object
36
+ assert array.exclude.development?
37
+ end
38
+ def test_nil_object_array_interface_double_negative
39
+ array = nil_object
40
+ refute array.exclude.exclude.development?
41
+ end
42
+
43
+ def test_nil_object_hash_interface
44
+ hash = nil_object
45
+ refute hash.production?
46
+ end
47
+ def test_nil_object_hash_interface_negative
48
+ hash = nil_object
49
+ assert hash.no.development?
50
+ end
51
+ def test_nil_object_hash_interface_double_negative
52
+ hash = nil_object
53
+ refute hash.no.no.development?
54
+ end
55
+
56
+ end
@@ -2,27 +2,28 @@ module StringTests
2
2
  def test_string_value_type
3
3
  assert_instance_of Inquisitive::String, string
4
4
  end
5
+
5
6
  def test_string_match
6
7
  assert string.production?
7
8
  end
8
9
  def test_string_miss
9
10
  refute string.development?
10
11
  end
12
+
11
13
  def test_string_negative_match
12
14
  assert string.not.development?
13
15
  end
14
16
  def test_string_negative_miss
15
17
  refute string.not.production?
16
18
  end
19
+
17
20
  def test_string_double_negative_match
18
21
  assert string.not.not.production?
19
22
  end
20
23
  def test_string_double_negative_miss
21
24
  refute string.not.not.development?
22
25
  end
23
- def test_string_missing_question_mark
24
- assert_raises(NoMethodError) { string.production }
25
- end
26
+
26
27
  def test_string_respond_to
27
28
  assert_respond_to string, :development?
28
29
  end
data/test/test_helper.rb CHANGED
@@ -1,8 +1,9 @@
1
- require "rubygems"
1
+ require 'rubygems'
2
+ require 'pry'
2
3
 
3
4
  begin
4
5
  require 'simplecov'
5
- SimpleCov.coverage_dir '.coverage'
6
+ SimpleCov.coverage_dir 'coverage'
6
7
  if ENV['CI']
7
8
  require 'coveralls'
8
9
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
@@ -12,11 +13,10 @@ begin
12
13
  end
13
14
  SimpleCov.start do
14
15
  add_filter "/test"
15
- add_filter "/vendor"
16
16
  end
17
17
  end
18
18
 
19
- require "minitest/autorun"
19
+ require 'minitest/autorun'
20
20
 
21
21
  class Test < MiniTest::Test
22
22
 
@@ -46,12 +46,15 @@ class Test < MiniTest::Test
46
46
  end
47
47
 
48
48
  def setup
49
+ @raw_nil_object = nil
49
50
  @raw_string = 'production'
50
51
  @raw_array = %w[mysql postgres sqlite]
51
52
  @raw_hash = {
53
+ nothing: @raw_nil_object,
52
54
  authentication: true,
53
55
  in: @raw_string,
54
- databases: @raw_array
56
+ databases: @raw_array,
57
+ nested: {key: 'value', array: %w[foo bar]}
55
58
  }
56
59
  end
57
60
 
@@ -71,9 +74,10 @@ class EnvironmentTest < Test
71
74
 
72
75
  end
73
76
 
74
- require "shared/string_tests"
75
- require "shared/array_tests"
76
- require "shared/hash_tests"
77
- require "shared/combinatorial_environment_tests"
77
+ require 'shared/nil_object_tests'
78
+ require 'shared/string_tests'
79
+ require 'shared/array_tests'
80
+ require 'shared/hash_tests'
81
+ require 'shared/combinatorial_environment_tests'
78
82
 
79
- require "inquisitive"
83
+ require 'inquisitive'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inquisitive
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Keele
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-24 00:00:00.000000000 Z
11
+ date: 2015-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -68,9 +68,7 @@ extensions: []
68
68
  extra_rdoc_files: []
69
69
  files:
70
70
  - ".coveralls.yml"
71
- - ".gitignore"
72
71
  - ".travis.yml"
73
- - CHANGELOG.md
74
72
  - Gemfile
75
73
  - Gemfile.ActiveSupport
76
74
  - LICENSE.md
@@ -82,20 +80,23 @@ files:
82
80
  - lib/inquisitive/environment.rb
83
81
  - lib/inquisitive/hash.rb
84
82
  - lib/inquisitive/hash_with_indifferent_access.rb
83
+ - lib/inquisitive/nil_class.rb
85
84
  - lib/inquisitive/string.rb
86
85
  - test/inquisitive/array_test.rb
87
86
  - test/inquisitive/combinatorial_environment_test.rb
88
87
  - test/inquisitive/environment_test.rb
89
88
  - test/inquisitive/hash_test.rb
90
89
  - test/inquisitive/hash_with_indifferent_access_test.rb
90
+ - test/inquisitive/nil_object_test.rb
91
91
  - test/inquisitive/string_test.rb
92
92
  - test/inquisitive_test.rb
93
93
  - test/shared/array_tests.rb
94
94
  - test/shared/combinatorial_environment_tests.rb
95
95
  - test/shared/hash_tests.rb
96
+ - test/shared/nil_object_tests.rb
96
97
  - test/shared/string_tests.rb
97
98
  - test/test_helper.rb
98
- homepage: https://github.com/rawsugar/inquisitive
99
+ homepage: http://christhekeele.github.io/inquisitive
99
100
  licenses:
100
101
  - MIT
101
102
  metadata: {}
@@ -120,15 +121,23 @@ signing_key:
120
121
  specification_version: 4
121
122
  summary: Predicate methods for those curious about their datastructures.
122
123
  test_files:
124
+ - ".coveralls.yml"
125
+ - ".travis.yml"
126
+ - Gemfile
127
+ - Gemfile.ActiveSupport
128
+ - Rakefile
129
+ - inquisitive.gemspec
123
130
  - test/inquisitive/array_test.rb
124
131
  - test/inquisitive/combinatorial_environment_test.rb
125
132
  - test/inquisitive/environment_test.rb
126
133
  - test/inquisitive/hash_test.rb
127
134
  - test/inquisitive/hash_with_indifferent_access_test.rb
135
+ - test/inquisitive/nil_object_test.rb
128
136
  - test/inquisitive/string_test.rb
129
137
  - test/inquisitive_test.rb
130
138
  - test/shared/array_tests.rb
131
139
  - test/shared/combinatorial_environment_tests.rb
132
140
  - test/shared/hash_tests.rb
141
+ - test/shared/nil_object_tests.rb
133
142
  - test/shared/string_tests.rb
134
143
  - test/test_helper.rb
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .coverage
6
- .yardoc
7
- Gemfile.lock
8
- InstalledFiles
9
- _yardoc
10
- coverage
11
- doc/
12
- lib/bundler/man
13
- pkg
14
- rdoc
15
- spec/reports
16
- test/tmp
17
- test/version_tmp
18
- tmp
data/CHANGELOG.md DELETED
@@ -1,80 +0,0 @@
1
- Changes to Inquisitive
2
- ======================
3
-
4
- > **Please consult this file when upgrading Inquisitive for important information on bugfixes, new features, and backwards incompatible changes.**
5
-
6
- Starting with **[2.0.0](#2.0.0)**, Inquisitive follows [symantic versioning](symver.org) to help inform you of the implications of upgrades.
7
-
8
- Releases
9
- --------
10
-
11
- [2.0.1]: https://github.com/christhekeele/inquisitive/tree/2.0.1
12
- [2.0.0]: https://github.com/christhekeele/inquisitive/tree/2.0.0
13
- [1.2.0]: https://github.com/christhekeele/inquisitive/tree/f314eaf84f7c3d9a2d56ae684d031dd81d2f7b85
14
-
15
- - [2.0.0](#2.0.0)
16
- - [1.2.0](#1.2.0)
17
-
18
- 2.0.1 - [2014.09.24][2.0.1]
19
- ---------------------------
20
-
21
- ### Non-breaking
22
-
23
- - `Inquisitive::Environment.truthy`: **helper regex**
24
-
25
- The `truthy` method provides an easy way to handle various command-line representations of truthiness.
26
-
27
-
28
- 2.0.0 - [2014.06.19][2.0.0]
29
- ---------------------------
30
-
31
- ### Breaking
32
-
33
- - `Inquisitive::Environment`: **hash detection**
34
-
35
- Previously `inquires_about` needed a special syntax to detect when you want to parse a group of environment variables as a hash. This was accomplished by leaving a trailing `_` in the declaration, such as:
36
-
37
- ```ruby
38
- ENV['PREFIX_KEY1'] = "value1"
39
- ENV['PREFIX_KEY2'] = "value2"
40
- module Mine
41
- extend Inquisitive::Environment
42
- inquires_about 'PREFIX_'
43
- end
44
- Mine.prefix
45
- #=> { 'key1' => 'value1', 'key2' => 'value2' }
46
- ```
47
-
48
- Now it auto-detects hash groupings by looking for a double-`_` in the key itself:
49
-
50
- ```ruby
51
- ENV['PREFIX__KEY1'] = "value1"
52
- ENV['PREFIX__KEY2'] = "value2"
53
- module Mine
54
- extend Inquisitive::Environment
55
- inquires_about 'PREFIX'
56
- end
57
- Mine.prefix
58
- #=> { 'key1' => 'value1', 'key2' => 'value2' }
59
- ```
60
-
61
- Nested hashes (through multiple `__`'s) are not yet supported.
62
-
63
- - `Inquisitive::Environment`: **default modes**
64
-
65
- Previously the default mode was `:dynamic`. This was mostly to prevent unexpected behaviour for newcomers.
66
-
67
- Now `:static` is the default. This is because `Inquisitive::Environment` is meant to be loaded immediately after a boot script that prepares your environment variables, and queried often later. `:static` optimizes to this usecase.
68
-
69
- To reproduce the old behaviour, you must explicitly pass `mode: :dynamic` each to `inquires_about` invocation. Alternatively, `mode: :lazy` might be a viable way to get the benefits of `:static` without refactoring your boot process.
70
-
71
- ### Non-breaking
72
-
73
- - `Inquisitive::Environment`: **cached mode now lazy mode**
74
-
75
- The `:cached` environment mode is now known as `:lazy`. This is backwards compatible because all logic handling modes explicitly checks for `:static` or `:dynamic`, so any other named mode has the same behaviour as `:lazy`.
76
-
77
- 1.2.0 - [2013.11.21][1.2.0]
78
- ---------------------------
79
-
80
- Everything to date.