inquisitive 3.1.1 → 4.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: 78b5345c827669dee4928a4907d68799180a7b6a
4
- data.tar.gz: 39899a19a8e7701645acc4134d1c1f8d4e7af5a0
3
+ metadata.gz: 1bf41f9d4ffbed28a841aaab8e093bcd954ec01c
4
+ data.tar.gz: 489460f2ad128b65ad6f0802619e03fbfaab1034
5
5
  SHA512:
6
- metadata.gz: 0a8a2423a9dccc219ac6d3dd13fc9d953e827a83cf6aa089e6dec24deaf21e171c73f4e4b130e7472c3c4467ad4cd821bf75450c13f028096df95153f806580a
7
- data.tar.gz: aae5568da7e1a36a75adbc0573fa7a2a3c26b2ef543deee13f1c44631870e752e2710d441603004fed126ca2b7bcf419ae82ca38f93d6249ff7542012bc45349
6
+ metadata.gz: 7c1b287a58cd1553cc9494f44f66a047f0dee425854c07255b770e050073b358564f6e9d55d9733ab18b406301be9005208d3354c1fb117f1fa1da65086ab9b8
7
+ data.tar.gz: 0de5a6cbb898c07464c96001903c699ea8797d608bf557a1e65ed10b996c7097ee72f3b599404b8baa59d7bc0155c88e5237613c60ea7a03671759506b9f7a0d
@@ -21,6 +21,10 @@ env:
21
21
 
22
22
  matrix:
23
23
  fast_finish: true
24
+ allow_failures:
25
+ - rvm: 1.9.3
26
+ - rvm: jruby # Until it gets up to 2.0.0 syntax
27
+ - rvm: rbx-2 # Ditto
24
28
  exclude:
25
29
  - gemfile: Gemfile.ActiveSupport
26
30
  env: ""
@@ -0,0 +1,170 @@
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
+ [4.0.0]: https://github.com/christhekeele/inquisitive/tree/4.0.0
12
+
13
+ [2.0.1]: https://github.com/christhekeele/inquisitive/tree/2.0.1
14
+ [2.0.0]: https://github.com/christhekeele/inquisitive/tree/2.0.0
15
+
16
+ [1.2.0]: https://github.com/christhekeele/inquisitive/tree/f314eaf84f7c3d9a2d56ae684d031dd81d2f7b85
17
+
18
+ - [4.0.0](#4.0.0)
19
+ - [2.0.0](#2.0.0)
20
+ - [1.2.0](#1.2.0)
21
+
22
+ 4.0.0 - [2015.03.06][4.0.0]
23
+ ---------------------------
24
+
25
+ Inquisitive has seen several new versions since this Changelog has been updated, all aimed at simplifying the codebase and adding a few features I've long desired. These goals have been accomplished with version 4.0.0, so now's as good as time as any to enumerate the changes. It's also a great time to upgrade!
26
+
27
+ - `ruby-1.9.3`: **support dropped**
28
+
29
+ Support for ruby 1.9.3 has been dropped, as it has reached end of life. Syntactically 4.0.0 should still work with 1.9.3, but that's no longer assured and may change. 1.9.3 is still a part of the build matrix but failures are allowed. Refer to the continuous integration to see if it's still viable.
30
+
31
+ - `Inquisitive::Environment.inquires_about`: **modes dropped**
32
+
33
+ Environment inquiry modes no longer exist; all lookups are dynamic. While cached inquiries are about 3 times faster each inquiry takes a fraction of a percent of a millisecond so the speed up is negligible. More importantly, dynamic-by-default follows the principle of least surprise. Between the two there's no reason offer other modes. The option is now silently ignored when declaring inquirers, but your application's behavior may change if you were relying on caching by default.
34
+
35
+ - `Inquisitive::NilClass`: **null objects now available**
36
+
37
+ While `Inquisitive::NilClass`s don't act falsey in boolean checks, they're useful wherever you may have been expecting another Inquisitive object, because they respond to methods like all other Inquisitive objects. It's also a "black hole" object, so it'll return itself on deep inquiries to mock nested inquisitive datastructures:
38
+
39
+ ```ruby
40
+ nillish = Inquisitive::NilClass.new
41
+ #=> nil
42
+
43
+ nillish.nil?
44
+ #=> true
45
+ nillish.present?
46
+ #=> false
47
+
48
+ nillish.predicate?
49
+ #=> false
50
+ nillish.access
51
+ #=> nil
52
+ nillish.deep.access
53
+ #=> nil
54
+ nillish.not.access
55
+ #=> true
56
+ nillish.exclude.access
57
+ #=> true
58
+ nillish.no.access
59
+ #=> true
60
+ ```
61
+
62
+ - `Inquisitive::Hash`: **missing keys return `Inquisitive::NilClass` instances**
63
+
64
+ This allows for further method chaining when you anticipate nested datastructures where there aren't any.
65
+
66
+ - `Inquisitive::Environment.inquires_about`: **default values**
67
+
68
+ Environment inquirers can now set default values:
69
+
70
+ ```ruby
71
+ class MyApp
72
+ extend Inquisitive::Environment
73
+ inquires_about 'ENV', default: 'production'
74
+ end
75
+
76
+ MyApp.env?
77
+ #=> true
78
+ MyApp.env.production?
79
+ #=> true
80
+ ```
81
+
82
+ - `Inquisitive::Environment.inquires_about`: **empty values**
83
+
84
+ Environment inquirers without defaults will return `Inquisitive::NilClass` instances for empty environment variables to allow method chains as if you had nested datastructures.
85
+
86
+ - `Inquisitive::Environment.inquires_about`: **nested hashes**
87
+
88
+ You can now construct nested hashes from environment variables with multiple `__`s in their names:
89
+
90
+ ```ruby
91
+ ENV['STUB__API__PROTOCOL'] = 'https'
92
+ ENV['STUB__API__SUBDOMAINS'] = 'app,web,db'
93
+ class MyApp
94
+ extend Inquisitive::Environment
95
+ inquires_about 'STUB'
96
+ end
97
+
98
+ MyApp.stub
99
+ #=> {api: {protocol: "https", subdomains: ["app", "web", "db"]}}
100
+ MyApp.stub.api.protocol.http?
101
+ #=> false
102
+ MyApp.stub.api.subdomains.web?
103
+ #=> true
104
+ ```
105
+
106
+ Refer to the documentation in the README.md for a through overview and more examples.
107
+
108
+ 2.0.1 - [2014.09.24][2.0.1]
109
+ ---------------------------
110
+
111
+ ### Non-breaking
112
+
113
+ - `Inquisitive::Environment.truthy`: **helper regex**
114
+
115
+ The `truthy` method provides an easy way to handle various command-line representations of truthiness.
116
+
117
+
118
+ 2.0.0 - [2014.06.19][2.0.0]
119
+ ---------------------------
120
+
121
+ ### Breaking
122
+
123
+ - `Inquisitive::Environment`: **hash detection**
124
+
125
+ 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:
126
+
127
+ ```ruby
128
+ ENV['PREFIX_KEY1'] = "value1"
129
+ ENV['PREFIX_KEY2'] = "value2"
130
+ module Mine
131
+ extend Inquisitive::Environment
132
+ inquires_about 'PREFIX_'
133
+ end
134
+ Mine.prefix
135
+ #=> { 'key1' => 'value1', 'key2' => 'value2' }
136
+ ```
137
+
138
+ Now it auto-detects hash groupings by looking for a double-`_` in the key itself:
139
+
140
+ ```ruby
141
+ ENV['PREFIX__KEY1'] = "value1"
142
+ ENV['PREFIX__KEY2'] = "value2"
143
+ module Mine
144
+ extend Inquisitive::Environment
145
+ inquires_about 'PREFIX'
146
+ end
147
+ Mine.prefix
148
+ #=> { 'key1' => 'value1', 'key2' => 'value2' }
149
+ ```
150
+
151
+ Nested hashes (through multiple `__`'s) are not yet supported.
152
+
153
+ - `Inquisitive::Environment`: **default modes**
154
+
155
+ Previously the default mode was `:dynamic`. This was mostly to prevent unexpected behaviour for newcomers.
156
+
157
+ 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.
158
+
159
+ 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.
160
+
161
+ ### Non-breaking
162
+
163
+ - `Inquisitive::Environment`: **cached mode now lazy mode**
164
+
165
+ 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`.
166
+
167
+ 1.2.0 - [2013.11.21][1.2.0]
168
+ ---------------------------
169
+
170
+ Everything to date.
data/README.md CHANGED
@@ -196,7 +196,7 @@ stubbed = Inquisitive::Hash.new(
196
196
  in: 'development',
197
197
  services: %w[database api],
198
198
  api: {protocol: 'https', subdomains: %w[app web db]},
199
- ignorable: { junk: [ "" ] }
199
+ ignorable: { junk: [ '' ] }
200
200
  )
201
201
  #=> {"authentication"=>true,
202
202
  #=> "in"=>"development",
@@ -315,8 +315,12 @@ nillish.present?
315
315
  #=> false
316
316
 
317
317
 
318
+ nillish.predicate?
319
+ #=> false
318
320
  nillish.access
319
321
  #=> nil
322
+ nillish.deep.access
323
+ #=> nil
320
324
  nillish.not.access
321
325
  #=> true
322
326
  nillish.exclude.access
@@ -325,7 +329,7 @@ nillish.no.access
325
329
  #=> true
326
330
  ```
327
331
 
328
- **Be warned**: since Ruby doesn't allow subclassing `NilClass` and provides no boolean-coercion mechanism, `Inquisitive::NilClass` **will** appear truthy. I recommend using built-in predicates (`stubbed.authentication? && ...`), presence predicates with ActiveSupport (`stubbed.authentication.present? && ...`), Inquisitive's presence utility (`Inquisitive.present?(stubbed.authentication) && ...`) or nil predicates (`stubbed.authentication.nil? || ...`) in boolean chains. Also note that for `Inquisitive::Hash` access, `stubbed.fetch(:authentication, ...)` behaves as expected.
332
+ **Be warned**: since Ruby doesn't allow subclassing `NilClass` and provides no boolean-coercion interface, `Inquisitive::NilClass` **will** appear truthy. I recommend using built-in predicates (`stubbed.authentication? && ...`), presence predicates with ActiveSupport (`stubbed.authentication.present? && ...`), Inquisitive's presence utility (`Inquisitive.present?(stubbed.authentication) && ...`) or nil predicates (`stubbed.authentication.nil? || ...`) in boolean chains. Also note that for `Inquisitive::Hash` access, `stubbed.fetch(:authentication, ...)` behaves as expected.
329
333
 
330
334
 
331
335
  ### Inquisitive Environment
@@ -335,7 +339,7 @@ nillish.no.access
335
339
  #### Strings
336
340
 
337
341
  ```ruby
338
- ENV['ENVIRONMENT'] = "development"
342
+ ENV['ENVIRONMENT'] = 'development'
339
343
  class MyApp
340
344
  extend Inquisitive::Environment
341
345
  inquires_about 'ENVIRONMENT'
@@ -354,7 +358,7 @@ MyApp.environment.production?
354
358
  Arrays are recognized when environment variables contain commas:
355
359
 
356
360
  ```ruby
357
- ENV['SUPPORTED_DATABASES'] = "mysql,postgres,sqlite"
361
+ ENV['SUPPORTED_DATABASES'] = 'mysql,postgres,sqlite'
358
362
  class MyApp
359
363
  extend Inquisitive::Environment
360
364
  inquires_about 'SUPPORTED_DATABASES'
@@ -373,11 +377,11 @@ MyApp.supported_databases.sql_server?
373
377
  Hashes are recognized when environment variables names contain double underscores:
374
378
 
375
379
  ```ruby
376
- ENV['STUB__AUTHENTICATION'] = 'true'
377
- ENV['STUB__IN'] = "development"
378
- ENV['STUB__SERVICES'] = "database,api"
379
- ENV['STUB__API__PROTOCOL'] = "https"
380
- ENV['STUB__API__SUBDOMAINS'] = "app,web,db"
380
+ ENV['STUB__AUTHENTICATION'] = 'true'
381
+ ENV['STUB__IN'] = 'development'
382
+ ENV['STUB__SERVICES'] = 'database,api'
383
+ ENV['STUB__API__PROTOCOL'] = 'https'
384
+ ENV['STUB__API__SUBDOMAINS'] = 'app,web,db'
381
385
  class MyApp
382
386
  extend Inquisitive::Environment
383
387
  inquires_about 'STUB'
@@ -401,12 +405,28 @@ MyApp.stub.api.subdomains.web?
401
405
  #=> true
402
406
  ```
403
407
 
408
+ #### Defaults
409
+
410
+ You can set default values for your environment inquirers.
411
+
412
+ ```ruby
413
+ class MyApp
414
+ extend Inquisitive::Environment
415
+ inquires_about 'ENV', default: 'production'
416
+ end
417
+
418
+ MyApp.env?
419
+ #=> true
420
+ MyApp.env.production?
421
+ #=> true
422
+ ```
423
+
404
424
  #### Naming
405
425
 
406
- You can name your environment inquirers with `:with`:
426
+ You can also give your environment inquirers custom names:
407
427
 
408
428
  ```ruby
409
- ENV['ENVIRONMENT'] = "development"
429
+ ENV['ENVIRONMENT'] = 'development'
410
430
  class MyApp
411
431
  extend Inquisitive::Environment
412
432
  inquires_about 'ENVIRONMENT', with: :env
@@ -446,11 +466,11 @@ By default such variables will be parsed as an `Inquisitive::String`, so predica
446
466
 
447
467
  ```ruby
448
468
  ENV['STUB_AUTHENTICATION'] = 'false'
449
- ENV['STUB_REGISTRATION'] = 'true'
469
+ ENV['STUB_REGISTRATION'] = 'true'
450
470
  class MyApp
451
471
  extend Inquisitive::Environment
452
472
  inquires_about 'STUB_AUTHENTICATION', present_if: 'true'
453
- inquires_about 'STUB_REGISTRATION', present_if: 'true'
473
+ inquires_about 'STUB_REGISTRATION', present_if: 'true'
454
474
  end
455
475
 
456
476
  MyApp.stub_authentication
@@ -468,24 +488,24 @@ This only works on top-level inquirers, so there's no way to get our nested `MyA
468
488
 
469
489
  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.
470
490
 
471
- ##### Truthy Booleans
491
+ ##### Truthy Strings
472
492
 
473
- `Inquisitive::Environment.truthy` contains a regex useful for reading booleans from environment variables.
493
+ `Inquisitive::Environment.truthy` contains a regex useful for trying to read truthy values from string environment variables.
474
494
 
475
495
  ```ruby
476
- ENV['NO'] = 'no'
477
- ENV['YES'] = 'yes'
478
- ENV['TRUTHY'] = 'TrUe'
479
- ENV['FALSEY'] = 'FaLsE'
480
- ENV['BOOLEAN'] = '1'
496
+ ENV['NO'] = 'no'
497
+ ENV['YES'] = 'yes'
498
+ ENV['TRUTHY'] = 'TrUe'
499
+ ENV['FALSEY'] = 'FaLsE'
500
+ ENV['BOOLEAN'] = '1'
481
501
  ENV['BOOLENOPE'] = '0'
482
502
  class MyCli
483
503
  extend Inquisitive::Environment
484
- inquires_about 'NO', present_if: truthy
485
- inquires_about 'YES', present_if: truthy
486
- inquires_about 'TRUTHY', present_if: truthy
487
- inquires_about 'FALSEY', present_if: truthy
488
- inquires_about 'BOOLEAN', present_if: truthy
504
+ inquires_about 'NO', present_if: truthy
505
+ inquires_about 'YES', present_if: truthy
506
+ inquires_about 'TRUTHY', present_if: truthy
507
+ inquires_about 'FALSEY', present_if: truthy
508
+ inquires_about 'BOOLEAN', present_if: truthy
489
509
  inquires_about 'BOOLENOPE', present_if: truthy
490
510
  end
491
511
 
@@ -502,37 +522,9 @@ MyApp.falsey?
502
522
  MyApp.boolean?
503
523
  #=> true
504
524
  MyApp.boolenope?
525
+ #=> false
505
526
  ```
506
527
 
507
- #### Inquiry mode
508
-
509
- Environment inquirers have three configurable modes, defaulting to `:static`.
510
-
511
- ```ruby
512
- class MyApp
513
- extend Inquisitive::Environment
514
- inquires_about 'STUB', mode: %i[dynamic lazy static].sample
515
- end
516
- ```
517
-
518
- - **Dynamic**
519
-
520
- Environment inquiries parse `ENV` on every invocation.
521
-
522
- Use if you're manipulating the environment in between invocations, so `Inquisitive` can pick up on new values, detect changes between string or array notation, and discover new keys for hash notation.
523
-
524
- - **Lazy**
525
-
526
- Environment inquiries check `ENV` on their first invocation, and re-use the response in future invocations.
527
-
528
- Use if you're loading the module with environment inquiry methods before you've finished preparing your environment.
529
-
530
- - **Static**
531
-
532
- Environment inquiries use the contents of `ENV` at the moment `inquires_about` was invoked.
533
-
534
- Use if your application is well-behaved and doesn't go mucking around with the environment at runtim.
535
-
536
528
 
537
529
 
538
530
  Contributing
@@ -3,11 +3,11 @@ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "inquisitive"
7
- spec.version = "3.1.1"
8
- spec.authors = ["Chris Keele"]
9
- spec.email = ["dev@chriskeele.com"]
10
- spec.summary = "Predicate methods for those curious about their datastructures."
6
+ spec.name = 'inquisitive'
7
+ spec.version = '4.0.0'
8
+ spec.authors = ['Chris Keele']
9
+ spec.email = ['dev@chriskeele.com']
10
+ spec.summary = 'Predicate methods for those curious about their datastructures.'
11
11
  spec.description = <<-DESC
12
12
  Predicate methods for those curious about their datastructures.
13
13
 
@@ -18,13 +18,13 @@ 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 = "http://christhekeele.github.io/inquisitive"
22
- spec.license = "MIT"
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($/)
25
- spec.require_paths = ["lib"]
21
+ spec.homepage = 'http://christhekeele.github.io/inquisitive'
22
+ spec.license = 'MIT'
23
+ spec.files = `git ls-files lib inquisitive.gemspec Gemfile Gemfile.lock Gemfile.ActiveSupport Rakefile CHANGELOG.md README.md LICENSE.md`.split($/)
24
+ spec.test_files = `git ls-files test .travis.yml .coveralls.yml`.split($/)
25
+ spec.require_paths = ['lib']
26
26
 
27
- spec.add_development_dependency "bundler", ">= 1.3"
28
- spec.add_development_dependency "rake", ">= 10.0"
29
- spec.add_development_dependency "minitest", ">= 5.0"
27
+ spec.add_development_dependency 'bundler', '>= 1.3'
28
+ spec.add_development_dependency 'rake', '>= 10.0'
29
+ spec.add_development_dependency 'minitest', '>= 5.0'
30
30
  end
@@ -46,22 +46,6 @@ module Inquisitive
46
46
 
47
47
  end
48
48
 
49
- private
50
-
51
- module Utils
52
-
53
- private
54
-
55
- def predicate_method?(string)
56
- string[-1] == '?'
57
- end
58
-
59
- def predication(string)
60
- string[0..-2]
61
- end
62
-
63
- end
64
-
65
49
  end
66
50
 
67
51
  require "inquisitive/nil_class"
@@ -1,3 +1,5 @@
1
+ require 'inquisitive/utils'
2
+
1
3
  module Inquisitive
2
4
  class Array < ::Array
3
5
  include Inquisitive::Utils
@@ -1,3 +1,5 @@
1
+ require 'inquisitive/utils'
2
+
1
3
  module Inquisitive
2
4
  module Environment
3
5
  include Inquisitive::Utils
@@ -8,44 +10,27 @@ module Inquisitive
8
10
 
9
11
  def inquires_about(env_var, opts={})
10
12
 
11
- env_accessor = opts.fetch(:with, env_var.downcase[/(.*?)(?=(?:_$|$))/])
12
- @__env_accessors__ ||= HashWithIndifferentAccess.new
13
- @__env_accessors__[env_accessor] = env_var
14
-
15
- mode = Inquisitive[ opts.fetch(:mode, :static).to_s ]
13
+ env_accessor = opts.fetch(:with, env_var.downcase[/(.*?)(?=(?:_$|$))/]).to_sym
14
+ env_presence = :"#{env_accessor}?"
15
+ env_default = opts[:default]
16
+ present_if = opts[:present_if]
16
17
 
17
- if mode.dynamic?
18
-
19
- define_singleton_method :"#{env_accessor}" do
20
- Inquisitive[Parser[@__env_accessors__[__method__]]]
18
+ define_singleton_method env_presence do |opts={with_default: true}|
19
+ !!(opts[:with_default] and env_default) || if present_if
20
+ present_if === Inquisitive[Parser[env_var]]
21
+ else
22
+ Inquisitive.present? Inquisitive[Parser[env_var]]
21
23
  end
24
+ end
22
25
 
23
- else
24
-
25
- @__cached_env__ ||= HashWithIndifferentAccess.new
26
- @__cached_env__[env_accessor] = Inquisitive[Parser[env_var]] if mode.static?
27
-
28
- define_singleton_method :"#{env_accessor}" do
29
- if @__cached_env__.has_key? __method__
30
- @__cached_env__[__method__]
26
+ define_singleton_method env_accessor do
27
+ Inquisitive[
28
+ if send env_presence, with_default: false
29
+ Parser[env_var]
31
30
  else
32
- @__cached_env__[__method__] = Inquisitive[Parser[@__env_accessors__[__method__]]]
31
+ env_default
33
32
  end
34
- end
35
-
36
- end
37
-
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
33
+ ]
49
34
  end
50
35
 
51
36
  end
@@ -56,7 +41,7 @@ module Inquisitive
56
41
  class << self
57
42
 
58
43
  def [](var_name)
59
- result = if ENV.has_key? var_name
44
+ result = if ENV.has_key? var_name.to_s
60
45
 
61
46
  env_var = ENV[var_name]
62
47
  if env_var.include? ','
@@ -1,3 +1,5 @@
1
+ require 'inquisitive/utils'
2
+
1
3
  module Inquisitive
2
4
  class Hash < HashWithIndifferentAccess
3
5
  include Inquisitive::Utils
@@ -24,8 +26,10 @@ module Inquisitive
24
26
  else
25
27
  if block_given?
26
28
  yield(key)
27
- else
29
+ elsif default
28
30
  default
31
+ else
32
+ raise KeyError, "key not found: #{key}"
29
33
  end
30
34
  end
31
35
  end
@@ -1,3 +1,5 @@
1
+ require 'inquisitive/utils'
2
+
1
3
  module Inquisitive
2
4
  class NilClass
3
5
  include Inquisitive::Utils
@@ -38,9 +40,9 @@ module Inquisitive
38
40
  def respond_to_missing?(method_name, include_private = false)
39
41
  true # nil.respond_to? method_name or predicate_method? method_name
40
42
  end
41
- def method_missing(method_name, *arguments)
43
+ def method_missing(method_name, *arguments, &block)
42
44
  if nil.respond_to? method_name
43
- nil.send method_name, *arguments
45
+ nil.send method_name, *arguments, &block
44
46
  elsif predicate_method? method_name
45
47
  presence
46
48
  else
@@ -1,3 +1,5 @@
1
+ require 'inquisitive/utils'
2
+
1
3
  module Inquisitive
2
4
  class String < ::String
3
5
  include Inquisitive::Utils
@@ -0,0 +1,17 @@
1
+ module Inquisitive
2
+
3
+ module Utils
4
+
5
+ private
6
+
7
+ def predicate_method?(string)
8
+ string[-1] == '?'
9
+ end
10
+
11
+ def predication(string)
12
+ string[0..-2]
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -16,6 +16,7 @@ class InquisitiveCombinatorialEnvironmentTest < EnvironmentTest
16
16
  end
17
17
  def teardown
18
18
  super
19
+ ENV.delete 'NIL_OBJECT'
19
20
  ENV.delete 'STRING'
20
21
  ENV.delete 'ARRAY'
21
22
  ENV.delete 'HASH__NOTHING'
@@ -42,46 +43,40 @@ class InquisitiveCombinatorialEnvironmentTest < EnvironmentTest
42
43
 
43
44
  end
44
45
 
45
- %w[dynamic lazy static].each do |mode|
46
- %w[nil_object string array hash].each do |type|
46
+ %w[nil_object string array hash].each do |type|
47
47
 
48
- Inquisitive.const_set(
49
- :"Inquisitive#{mode.capitalize}#{type.split('_').map(&:capitalize).join}EnvironmentTest",
50
- Class.new(InquisitiveCombinatorialEnvironmentTest) do
48
+ Inquisitive.const_set(
49
+ :"Inquisitive#{type.split('_').map(&:capitalize).join}EnvironmentTest",
50
+ Class.new(InquisitiveCombinatorialEnvironmentTest) do
51
51
 
52
- class << self
53
- attr_accessor :mode, :type
54
- end
52
+ class << self
53
+ attr_accessor :type
54
+ end
55
55
 
56
- def setup
57
- super
58
- @mode = Inquisitive[self.class.mode]
59
- @type = Inquisitive[self.class.type]
60
- App.inquires_about @type.upcase, mode: @mode
61
- end
56
+ def setup
57
+ super
58
+ @type = Inquisitive[self.class.type]
59
+ App.inquires_about @type.upcase
60
+ end
62
61
 
63
- def nil_object
64
- App.nil_object
65
- end
66
- def string
67
- App.string
68
- end
69
- def array
70
- App.array
71
- end
72
- def hash
73
- App.hash
74
- end
62
+ def nil_object
63
+ App.nil_object
64
+ end
65
+ def string
66
+ App.string
67
+ end
68
+ def array
69
+ App.array
70
+ end
71
+ def hash
72
+ App.hash
73
+ end
75
74
 
76
- include CombinatorialEnvironmentTests
75
+ include CombinatorialEnvironmentTests
77
76
 
78
- end
79
- ).tap do |klass|
80
- klass.mode = mode
81
- klass.type = type
82
- end.send :include, Object.const_get(:"#{type.split('_').map(&:capitalize).join}Tests")
83
- # Mixes in type-specific tests to ensure lookup behaves normally
84
- # when accessed through the modes of App getters
77
+ end
78
+ ).tap do |klass|
79
+ klass.type = type
80
+ end.send :include, Object.const_get(:"#{type.split('_').map(&:capitalize).join}Tests")
85
81
 
86
- end
87
82
  end
@@ -12,39 +12,60 @@ class InquisitiveEnvironmentTest < EnvironmentTest
12
12
  assert App.respond_to? :name_not_specified
13
13
  end
14
14
 
15
- def test_default_mode_of_static
16
- ENV['DEFAULTS_TO'] = 'static'
17
- App.inquires_about 'DEFAULTS_TO'
18
- ENV['DEFAULTS_TO'] = 'lazy'
19
- assert App.defaults_to.static?
20
- ENV['DEFAULTS_TO'] = 'dynamic'
21
- assert App.defaults_to.static?
22
- end
23
-
24
15
  def test_custom_string_presence
25
- ENV['AUTHORIZABLE'] = 'false'
26
16
  App.inquires_about 'AUTHORIZABLE', present_if: 'true'
17
+ ENV['AUTHORIZABLE'] = 'false'
27
18
  refute App.authorizable?
19
+ ENV['AUTHORIZABLE'] = 'true'
20
+ assert App.authorizable?
28
21
  end
29
22
 
30
23
  def test_custom_regex_presence
31
- ENV['AUTHORIZABLE'] = 'not at all'
32
24
  App.inquires_about 'AUTHORIZABLE', present_if: /yes/
25
+ ENV['AUTHORIZABLE'] = 'false'
33
26
  refute App.authorizable?
27
+ ENV['AUTHORIZABLE'] = 'yes'
28
+ assert App.authorizable?
34
29
  end
35
30
 
36
31
  def test_custom_class_presence
37
- ENV['AUTHORIZABLE'] = 'not at all'
38
32
  App.inquires_about 'AUTHORIZABLE', present_if: Array
33
+ ENV['AUTHORIZABLE'] = 'false'
39
34
  refute App.authorizable?
35
+ ENV['AUTHORIZABLE'] = 'false,schmalse'
36
+ assert App.authorizable?
40
37
  end
41
38
 
42
39
  %w[true True TrUe TRUE yes Yes YeS YES 1].each do |truthy_var|
43
40
  define_method :"test_truthy_var_#{truthy_var}" do
44
- ENV['TRUTHY'] = truthy_var
45
41
  App.inquires_about 'TRUTHY', present_if: App.truthy
42
+ ENV['TRUTHY'] = 'false'
43
+ refute App.truthy?
44
+ ENV['TRUTHY'] = truthy_var
46
45
  assert App.truthy?
47
46
  end
48
47
  end
49
48
 
49
+ def test_default_accessor_for_missing
50
+ App.inquires_about 'MISSING_WITH_DEFAULT', default: 'default'
51
+ assert_equal 'default', App.missing_with_default
52
+ end
53
+
54
+ def test_default_predicate_for_missing
55
+ App.inquires_about 'MISSING_WITH_DEFAULT', default: 'default'
56
+ assert App.missing_with_default?
57
+ end
58
+
59
+ def test_default_accessor_for_existing
60
+ App.inquires_about 'EXISTING_WITH_DEFAULT', default: 'default'
61
+ ENV['EXISTING_WITH_DEFAULT'] = @raw_string
62
+ assert_equal @raw_string, App.existing_with_default
63
+ end
64
+
65
+ def test_default_predicate_for_existing
66
+ App.inquires_about 'EXISTING_WITH_DEFAULT', default: 'default'
67
+ ENV['EXISTING_WITH_DEFAULT'] = @raw_string
68
+ assert App.existing_with_default?
69
+ end
70
+
50
71
  end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ class UtilsTest
4
+ Utils = Module.new.extend Inquisitive::Utils
5
+
6
+ def test_found_symbol_predicate_method_helper
7
+ assert Utils.send(:predicate_method?, :foo?)
8
+ end
9
+ def test_found_string_predicate_method_helper
10
+ assert Utils.send(:predicate_method?, "foo?")
11
+ end
12
+ def test_missing_symbol_predicate_method_helper
13
+ refute Utils.send(:predicate_method?, :foo)
14
+ end
15
+ def test_missing_string_predicate_method_helper
16
+ refute Utils.send(:predicate_method?, "foo")
17
+ end
18
+
19
+ def test_symbol_predication_helper
20
+ assert_equal Utils.send(:predication, :foo?), 'foo'
21
+ end
22
+ def test_string_predication_helper
23
+ assert_equal Utils.send(:predication, "foo?"), 'foo'
24
+ end
25
+
26
+ end
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class InquisitiveTest < Test
4
- Utils = Module.new.extend Inquisitive::Utils
5
4
  HashWithIndifferentAccess ||= Inquisitive::HashWithIndifferentAccess
6
5
 
7
6
  def setup
@@ -146,26 +145,14 @@ class InquisitiveTest < Test
146
145
  refute Inquisitive.present?({})
147
146
  end
148
147
 
149
- ####
150
- # UTILS
151
- ##
152
- def test_found_symbol_predicate_method_helper
153
- assert Utils.send :predicate_method?, :foo?
154
- end
155
- def test_found_string_predicate_method_helper
156
- assert Utils.send :predicate_method?, "foo?"
157
- end
158
- def test_missing_symbol_predicate_method_helper
159
- refute Utils.send :predicate_method?, :foo
160
- end
161
- def test_missing_string_predicate_method_helper
162
- refute Utils.send :predicate_method?, "foo"
148
+ def test_presence_predication
149
+ assert_throws :predicated do
150
+ object = Object.new
151
+ def object.present?
152
+ throw :predicated
153
+ end
154
+ Inquisitive.present? object
155
+ end
163
156
  end
164
157
 
165
- def test_symbol_predication_helper
166
- assert_equal Utils.send(:predication, :foo?), 'foo'
167
- end
168
- def test_string_predication_helper
169
- assert_equal Utils.send(:predication, "foo?"), 'foo'
170
- end
171
158
  end
@@ -14,18 +14,9 @@ module CombinatorialEnvironmentTests
14
14
  )
15
15
  end
16
16
 
17
- def test_changing_variable_after_definition
18
- App.inquires_about @type.upcase, mode: @mode, with: :precache
19
- test = @mode.static? ? :assert_equal : :refute_equal
20
- precache = App.precache
21
- send :"change_#{@type}_variable"
22
- send test, App.send(@type), precache
23
- end
24
-
25
- def test_changing_variable_after_invocation
26
- test = @mode.dynamic? ? :assert_change : :refute_change
27
- monitor = -> { App.send(@type) }
28
- send test, monitor do
17
+ def test_changing_variable
18
+ App.inquires_about @type.upcase, with: :changeable
19
+ assert_change ->{ App.changeable } do
29
20
  send :"change_#{@type}_variable"
30
21
  end
31
22
  end
@@ -42,13 +42,24 @@ module HashTests
42
42
  assert_instance_of Inquisitive::Hash, hash[:nested]
43
43
  end
44
44
 
45
- def test_hash_fetch_implicit_nil
45
+ def test_hash_fetch_missing
46
+ assert_raises KeyError do
47
+ hash.fetch(:nothing)
48
+ end
49
+ end
50
+ def test_hash_fetch_implicit_nil_with_default_value
46
51
  assert_equal hash.fetch(:missing_key, @default_value), @default_value
47
52
  end
48
- def test_hash_fetch_explicit_nil
53
+ def test_hash_fetch_explicit_nil_with_default_value
49
54
  assert_equal hash.fetch(:nothing, @default_value), @default_value
50
55
  end
51
- def test_hash_present_value
56
+ def test_hash_fetch_implicit_nil_with_default_block
57
+ assert_equal hash.fetch(:missing_key){@default_value}, @default_value
58
+ end
59
+ def test_hash_fetch_explicit_nil_with_default_block
60
+ assert_equal hash.fetch(:nothing){@default_value}, @default_value
61
+ end
62
+ def test_hash_fetch_present_value
52
63
  assert_equal hash.fetch(:in), @raw_string
53
64
  end
54
65
 
@@ -13,6 +13,15 @@ module NilObjectTests
13
13
  def test_nil_object_miss
14
14
  refute nil_object.anything_else?
15
15
  end
16
+ def test_nil_object_presence_predicate
17
+ refute nil_object.present?
18
+ end
19
+ def test_nil_object_presence_predicate_negataive
20
+ assert nil_object.not.present?
21
+ end
22
+ def test_nil_object_presence_predicate_double_negataive
23
+ refute nil_object.not.not.present?
24
+ end
16
25
 
17
26
  def test_nil_object_string_interface
18
27
  string = nil_object
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: 3.1.1
4
+ version: 4.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: 2015-03-03 00:00:00.000000000 Z
11
+ date: 2015-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -69,6 +69,7 @@ extra_rdoc_files: []
69
69
  files:
70
70
  - ".coveralls.yml"
71
71
  - ".travis.yml"
72
+ - CHANGELOG.md
72
73
  - Gemfile
73
74
  - Gemfile.ActiveSupport
74
75
  - LICENSE.md
@@ -82,6 +83,7 @@ files:
82
83
  - lib/inquisitive/hash_with_indifferent_access.rb
83
84
  - lib/inquisitive/nil_class.rb
84
85
  - lib/inquisitive/string.rb
86
+ - lib/inquisitive/utils.rb
85
87
  - test/inquisitive/array_test.rb
86
88
  - test/inquisitive/combinatorial_environment_test.rb
87
89
  - test/inquisitive/environment_test.rb
@@ -89,6 +91,7 @@ files:
89
91
  - test/inquisitive/hash_with_indifferent_access_test.rb
90
92
  - test/inquisitive/nil_object_test.rb
91
93
  - test/inquisitive/string_test.rb
94
+ - test/inquisitive/utils_test.rb
92
95
  - test/inquisitive_test.rb
93
96
  - test/shared/array_tests.rb
94
97
  - test/shared/combinatorial_environment_tests.rb
@@ -123,10 +126,6 @@ summary: Predicate methods for those curious about their datastructures.
123
126
  test_files:
124
127
  - ".coveralls.yml"
125
128
  - ".travis.yml"
126
- - Gemfile
127
- - Gemfile.ActiveSupport
128
- - Rakefile
129
- - inquisitive.gemspec
130
129
  - test/inquisitive/array_test.rb
131
130
  - test/inquisitive/combinatorial_environment_test.rb
132
131
  - test/inquisitive/environment_test.rb
@@ -134,6 +133,7 @@ test_files:
134
133
  - test/inquisitive/hash_with_indifferent_access_test.rb
135
134
  - test/inquisitive/nil_object_test.rb
136
135
  - test/inquisitive/string_test.rb
136
+ - test/inquisitive/utils_test.rb
137
137
  - test/inquisitive_test.rb
138
138
  - test/shared/array_tests.rb
139
139
  - test/shared/combinatorial_environment_tests.rb