configurations 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91fb60bb5d9360f44127b6fe04e9ee5a44fc8cc4
4
- data.tar.gz: f6954851568a3a8dc02abb41867391ac9e83133d
3
+ metadata.gz: 2589e2f8682eac2622c16993dc89aab75f8d0835
4
+ data.tar.gz: 95c59f8d0f29f2c7cddb2a10dfbfdfa601c11989
5
5
  SHA512:
6
- metadata.gz: e5e0337c82a36aecf0716baaad50605372f31048ae57cfcea910a5946e6e7a04b6345ce08b851fe08c9721b80ac958f9b15c94d7573a1f4b027ec3f0be7cafb9
7
- data.tar.gz: 513d1a3804e612121dde365f0966edc22120b6d5ce7f17c8d173c14751d9de0967934111a05922afdf86770b16b1853b650b970bac3ce2f299bf83ace3c32ca3
6
+ metadata.gz: 7d59363609ad7d37bb56a596de502e59eaddbd60dc6e9138bd7f09650e768e6c61f8d22d81191dadf620ac0ce6fe40a2dcaac8ccd6d2971b1f0d6178a7cebc42
7
+ data.tar.gz: 45603cd9f38b71a9e1086c2b0486f29f089377de972c2b96dbaa7f57d819291f9c677104d8b4b5883b27c5aaff31e2c22031499c54a5b9c05a2ee0647ec1dff3
data/README.md CHANGED
@@ -10,7 +10,7 @@ Configurations provides a unified approach to do configurations using the `MyGem
10
10
 
11
11
  or with Bundler
12
12
 
13
- `gem 'configurations', '~> 1.0.0'`
13
+ `gem 'configurations', '~> 1.4.0'`
14
14
 
15
15
  Configurations uses [Semver 2.0](http://semver.org/)
16
16
 
@@ -204,6 +204,19 @@ end
204
204
  MyGem.configuration.to_h #=> a Hash
205
205
  ```
206
206
 
207
+ ### Configure with a hash where needed
208
+
209
+ Sometimes your users will have a hash of configuration values which are not handy to press into the block form. In that case, they can use `from_h` inside the `configure` block to either read in the full or a nested configuration.
210
+
211
+ ```
212
+ yaml_hash = YAML.load_file('configuration.yml')
213
+
214
+ MyGem.configure do |c|
215
+ c.foo = 'bar'
216
+ c.baz.from_h(yaml_hash)
217
+ end
218
+ ```
219
+
207
220
  ### Some caveats
208
221
 
209
222
  The `to_h` from above is along with `method_missing`, `object_id` and `initialize` the only purposely defined API method which you can not overwrite with a configuration value.
@@ -12,5 +12,5 @@ module Configurations
12
12
 
13
13
  # Version number of Configurations
14
14
  #
15
- VERSION = '1.3.5'
15
+ VERSION = '1.4.0'
16
16
  end
@@ -21,6 +21,10 @@ module Configurations
21
21
  # The central configure method
22
22
  # @params [Proc] block the block to configure host module with
23
23
  # @raise [ArgumentError] error when not given a block
24
+ # @example Configure a configuration
25
+ # MyGem.configure do |c|
26
+ # c.foo = :bar
27
+ # end
24
28
  #
25
29
  def configure(&block)
26
30
  raise ArgumentError, 'can not configure without a block' unless block_given?
@@ -50,6 +54,14 @@ module Configurations
50
54
  # the given property should be asserted to
51
55
  # @param [Class, Symbol, Hash] properties a type as a first argument to type assert (if any) or nested properties to allow for setting
52
56
  # @param [Proc] block a block with arity 2 to evaluate when a property is set. It will be given: property name and value
57
+ # @example Define a configurable property
58
+ # configurable :foo
59
+ # @example Define a type asserted, nested property for type String
60
+ # configurable String, bar: :baz
61
+ # @example Define a custom assertion for a property
62
+ # configurable biz: %i(bi bu) do |value|
63
+ # raise ArgumentError, 'must be one of a, b, c' unless %w(a b c).include?(value)
64
+ # end
53
65
  #
54
66
  def configurable(*properties, &block)
55
67
  type = properties.shift if properties.first.is_a?(Class)
@@ -65,8 +77,12 @@ module Configurations
65
77
  end
66
78
 
67
79
  # configuration method can be used to retrieve properties from the configuration which use your gem's context
68
- # @param [Class, Symbol, Hash] properties properties for retrieval
80
+ # @param [Class, Symbol, Hash] method the method to define
69
81
  # @param [Proc] block the block to evaluate
82
+ # @example Define a configuration method 'foobararg' returning configuration properties 'foo' and 'bar' plus an argument
83
+ # configuration_method :foobararg do |arg|
84
+ # foo + bar + arg
85
+ # end
70
86
  #
71
87
  def configuration_method(method, &block)
72
88
  raise ArgumentError, "#{method} can not be both a configurable property and a configuration method" if configurable?(method)
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module Configurations
2
3
  # Configuration is a blank object in order to allow configuration of various properties including keywords
3
4
  #
@@ -14,7 +15,7 @@ module Configurations
14
15
  :instance_of?, :kind_of?, :tap, :send, :public_send, :respond_to?, :respond_to_missing?, :extend,
15
16
  :display, :method, :public_method, :define_singleton_method, :to_enum, :enum_for
16
17
  else
17
- # @!macro [attach] install_kernel_method
18
+ # @macro [attach] install_kernel_method
18
19
  # @method $1
19
20
  #
20
21
  def self.install_kernel_method(method)
@@ -100,6 +101,23 @@ module Configurations
100
101
  end
101
102
  end
102
103
 
104
+ # A convenience accessor to instantiate a configuration from a hash
105
+ # @param [Hash] h the hash to read into the configuration
106
+ # @return [Configuration] the configuration with values assigned
107
+ # @note can only be accessed during writeable state (in configure block). Unassignable values are ignored
108
+ #
109
+ def from_h(h)
110
+ raise ArgumentError, 'can not dynamically assign values from a hash' unless @_writeable
111
+
112
+ h.each do |property, value|
113
+ if value.is_a?(::Hash) && _nested?(property)
114
+ @configuration[property].from_h(value)
115
+ elsif _configurable?(property)
116
+ _assign!(property, value)
117
+ end
118
+ end
119
+ end
120
+
103
121
  # @param [Symbol] property The property to test for configurability
104
122
  # @return [Boolean] whether the given property is configurable
105
123
  #
@@ -152,7 +170,7 @@ module Configurations
152
170
 
153
171
  # @param [Symbol, Hash, Array] property configurable properties, either single or nested
154
172
  # @param [Symbol, Hash, Array] value configurable properties, either single or nested
155
- # @param [Hash] assertions if any
173
+ # @param [Hash] assertion assertion if any
156
174
  # @return a hash with configurable values pointing to their types
157
175
  #
158
176
  def _configurable_hash(property, value, assertion)
@@ -205,6 +223,13 @@ module Configurations
205
223
  @configurable and @configurable.has_key?(property) and @configurable[property].is_a?(::Hash) and @configurable[property].has_key?(evaluation)
206
224
  end
207
225
 
226
+ # @param [Symbol] property The property to test for
227
+ # @return [Boolean] whether this property is nested
228
+ #
229
+ def _nested?(property)
230
+ _arbitrarily_configurable? or @configuration.has_key?(property) and @configuration[property].is_a?(Configuration)
231
+ end
232
+
208
233
  # @param [Symbol] method the method to test for
209
234
  # @return [Boolean] whether the given method is a writer
210
235
  #
@@ -40,25 +40,29 @@ class TestConfiguration < Minitest::Test
40
40
  end
41
41
 
42
42
  def test_configuration_to_h
43
- assert_equal(
44
- {
45
- uh:
46
- {
47
- this: { is: { neat: 'NEAT' } }
48
- },
49
- pah: 'PUH',
50
- overwrite: {
51
- this: 'OVERWRITE'
52
- },
53
- overwriteee: 'YEAH',
54
- basic: 'BASIC',
55
- class: 'KEY',
56
- github: {
57
- repo: 'github.com/beatrichartz/configurations',
58
- access_key: 'ABCDEF'
59
- },
60
- something: { else: { entirely: { nested: { deep: { below: 'something' } } } } }
61
- }, @configuration.to_h)
43
+ assert_equal({
44
+ uh:
45
+ {
46
+ this: { is: { neat: 'NEAT' } }
47
+ },
48
+ pah: 'PUH',
49
+ overwrite: {
50
+ this: 'OVERWRITE'
51
+ },
52
+ overwriteee: 'YEAH',
53
+ basic: 'BASIC',
54
+ class: 'KEY',
55
+ github: {
56
+ repo: 'github.com/beatrichartz/configurations',
57
+ access_key: 'ABCDEF'
58
+ },
59
+ something: { else: { entirely: { nested: { deep: { below: 'something' } } } } }
60
+ }, @configuration.to_h)
61
+ end
62
+
63
+ def test_configuration_from_h
64
+ old_to_h = @configuration.to_h.dup
65
+ assert_equal(old_to_h, ConfigurationTestModule.configure{ |c| c.from_h(old_to_h) }.to_h)
62
66
  end
63
67
 
64
68
  def test_not_configurable_unless_block_given
@@ -55,6 +55,38 @@ class TestStricterConfiguration < Minitest::Test
55
55
  end
56
56
  end
57
57
 
58
+ def test_strict_configuration_to_h
59
+ assert_equal({
60
+ property4: {
61
+ property5: :something,
62
+ property12: 12
63
+ },
64
+ property6: {
65
+ property7: :anything,
66
+ property8: :everything,
67
+ property14: 555
68
+ },
69
+ property9: {
70
+ property10: {
71
+ property11: {
72
+ property12: %w(here I am),
73
+ property13: {
74
+ hi: :bye
75
+ }
76
+ }
77
+ }
78
+ },
79
+ property1: 'BASIC1',
80
+ property2: 'BASIC2',
81
+ property3: 'STRING'
82
+ }, @configuration.to_h)
83
+ end
84
+
85
+ def test_strict_configuration_from_h
86
+ old_to_h = @configuration.to_h.dup
87
+ assert_equal(old_to_h, StrictConfigurationTestModule.configure{ |c| c.from_h(old_to_h) }.to_h)
88
+ end
89
+
58
90
  def test_configurable_with_same_key_when_set_nested_configurable
59
91
  assert_equal :anything, @configuration.property6.property7
60
92
  assert_equal :everything, @configuration.property6.property8
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configurations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Beat Richartz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-18 00:00:00.000000000 Z
11
+ date: 2014-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest