configurations 1.0.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 +7 -0
- data/.gitignore +4 -0
- data/.ruby-version +1 -0
- data/.travis.yml +13 -0
- data/Gemfile +3 -0
- data/License.txt +20 -0
- data/README.md +147 -0
- data/Rakefile +8 -0
- data/configurations.gemspec +21 -0
- data/lib/configurations/configurable.rb +67 -0
- data/lib/configurations/configuration.rb +163 -0
- data/lib/configurations/error.rb +5 -0
- data/lib/configurations.rb +16 -0
- data/test/configurations/test_configuration.rb +93 -0
- data/test/configurations/test_stricter_configuration.rb +81 -0
- data/test/support/testmodules.rb +10 -0
- data/test/test_helper.rb +18 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7415bb2455bde354b3e2db792f4ff3b0d39ed012
|
4
|
+
data.tar.gz: fc663b3bb7de0224af0e6112008e5752760c930e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 75dd7197ee0fead9848bd6896550d950487c8f8853e3c9177c7ccaae63821db9827a770ea023ffa1fc18e8b7b44852fc7efd48ed5432896b6ce131e9ab01233b
|
7
|
+
data.tar.gz: 0579d9eaf837f25f766f2dfc9e392d51d940604e490870d180147b380e0f37c8067f14f86e15588c72f85c080faeec5f9d67c764abb641381e854aae47aadb47
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p481
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 Beat Richartz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# Configurations
|
2
|
+
|
3
|
+
Configurations provides a unified approach to do configurations using the `MyGem.configure do ... end` idiom with the flexibility to do everything from arbitrary configurations to type asserted configurations for your gem or any other ruby code.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
`gem install configurations`
|
8
|
+
|
9
|
+
or with Bundler
|
10
|
+
|
11
|
+
`gem 'configurations', '~> 1.0.0'`
|
12
|
+
|
13
|
+
Configurations uses [Semver 2.0](http://semver.org/)
|
14
|
+
|
15
|
+
## Why?
|
16
|
+
|
17
|
+
There are various ways to do configurations, yet there seems to be a broad consensus on the `MyGem.configure do ... end` idiom.
|
18
|
+
So instead of rolling your own, you can add this gem to your gem and get that functionality for free, plus some goodies you may want
|
19
|
+
but do not have the time to write like type assertion or nested configurations.
|
20
|
+
|
21
|
+
Less time copy pasting configuration code, more time writing exciting code for you.
|
22
|
+
|
23
|
+
## Configure
|
24
|
+
|
25
|
+
### First way: Arbitrary Configuration
|
26
|
+
|
27
|
+
Go boom! with ease. This allows your gem / code users to set any value they like.
|
28
|
+
|
29
|
+
```
|
30
|
+
module MyGem
|
31
|
+
include Configurations
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Gives your users:
|
36
|
+
|
37
|
+
```
|
38
|
+
MyGem.configure do |c|
|
39
|
+
c.foo.bar.baz = 'fizz'
|
40
|
+
c.hi = 'Hello-o'
|
41
|
+
c.class = 'oooh wow' # Such flexible!
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
Gives you:
|
46
|
+
|
47
|
+
```
|
48
|
+
MyGem.configuration.class #=> 'oooh wow'
|
49
|
+
MyGem.configuration.foo.bar.baz #=> 'fizz'
|
50
|
+
```
|
51
|
+
|
52
|
+
### Second way: Restricted Configuration
|
53
|
+
|
54
|
+
If you just want some properties to be configurable, consider this option
|
55
|
+
|
56
|
+
```
|
57
|
+
module MyGem
|
58
|
+
include Configurations
|
59
|
+
configurable :foo, bar: :baz, biz: %i(bi ba bu)
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Gives your users:
|
64
|
+
|
65
|
+
```
|
66
|
+
MyGem.configure do |c|
|
67
|
+
c.foo = 'FOO'
|
68
|
+
c.bar.baz = 'FIZZ'
|
69
|
+
c.biz.bi = 'BI'
|
70
|
+
c.biz.ba = 'BA'
|
71
|
+
|
72
|
+
# This would raise NoMethodError
|
73
|
+
# c.bar.biz
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
Gives you:
|
78
|
+
|
79
|
+
```
|
80
|
+
MyGem.configuration.foo #=> 'FOO'
|
81
|
+
MyGem.configuration.bar.baz #=> 'FIZZ'
|
82
|
+
```
|
83
|
+
|
84
|
+
### Third way: Type Restricted Configuration
|
85
|
+
|
86
|
+
If you want to make sure your configurations only accept one type, consider this option
|
87
|
+
|
88
|
+
```
|
89
|
+
module MyGem
|
90
|
+
include Configurations
|
91
|
+
configurable String, :foo
|
92
|
+
configurable Array, bar: :baz
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
Gives your users:
|
97
|
+
|
98
|
+
```
|
99
|
+
MyGem.configure do |c|
|
100
|
+
c.foo = 'FOO'
|
101
|
+
c.bar.baz = %w(hello)
|
102
|
+
|
103
|
+
# This would raise Configurations::ConfigurationError
|
104
|
+
# c.foo = :not_so_foo
|
105
|
+
# c.bar.baz = 'oh my cannot configure'
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
Gives you:
|
110
|
+
|
111
|
+
```
|
112
|
+
MyGem.configuration.foo #=> 100% String
|
113
|
+
MyGem.configuration.bar.baz #=> 100% Array
|
114
|
+
```
|
115
|
+
|
116
|
+
### Defaults:
|
117
|
+
|
118
|
+
```
|
119
|
+
module MyGem
|
120
|
+
include Configurations
|
121
|
+
configuration_defaults do |c|
|
122
|
+
c.foo.bar.baz = 'BAR'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
127
|
+
### Get a hash if you need it
|
128
|
+
|
129
|
+
```
|
130
|
+
MyGem.configuration.to_h #=> a Hash
|
131
|
+
|
132
|
+
```
|
133
|
+
|
134
|
+
### Some caveats
|
135
|
+
|
136
|
+
The `to_h` from above is along with `method_missing` and `initialize` the only purposely defined method which you can not overwrite with a configuration value.
|
137
|
+
Apart from these methods, you should be able to set pretty much any property name you like. `Configuration` inherits from `BasicObject`, so even standard Ruby method names are available.
|
138
|
+
|
139
|
+
## Contributing
|
140
|
+
|
141
|
+
YES!
|
142
|
+
|
143
|
+
Let's make this awesome. Write tests for your added stuff, bonus points for feature branches. If you don't have to time to write a fix, raise an issue.
|
144
|
+
|
145
|
+
### Copyright
|
146
|
+
|
147
|
+
Copyright © 2014 Beat Richartz. See LICENSE.txt for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
require 'configurations'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'configurations'
|
6
|
+
s.version = Configurations::VERSION
|
7
|
+
s.authors = ['Beat Richartz']
|
8
|
+
s.description = 'Configurations provides a unified approach to do configurations with the flexibility to do everything from arbitrary configurations to type asserted configurations for your gem or any other ruby code.'
|
9
|
+
s.email = 'attr_accessor@gmail.com'
|
10
|
+
s.homepage = 'http://github.com/beatrichartz/configurations'
|
11
|
+
s.licenses = %w(MIT)
|
12
|
+
s.require_paths = %w(lib)
|
13
|
+
s.summary = 'Configurations with a configure block from arbitrary to type-restricted for your gem or other ruby code.'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
17
|
+
|
18
|
+
s.add_development_dependency 'minitest', '~> 5.4'
|
19
|
+
s.add_development_dependency 'yard', '~> 0.8'
|
20
|
+
s.add_development_dependency 'rake', '~> 10'
|
21
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Configurations
|
2
|
+
# Module configurable provides the API of configurations
|
3
|
+
#
|
4
|
+
module Configurable
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# Once included, Configurations installs three methods in the host module: configure, configuration_defaults and configurable
|
8
|
+
#
|
9
|
+
def included(base)
|
10
|
+
install_configure_in(base)
|
11
|
+
base.class_eval do
|
12
|
+
extend ClassMethods
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Installs #configure in base, and makes sure that it will instantiate configuration as a subclass of the host module
|
17
|
+
#
|
18
|
+
def install_configure_in(base)
|
19
|
+
base.class_eval <<-EOF
|
20
|
+
class << self
|
21
|
+
# The central configure method
|
22
|
+
# @params [Proc] block the block to configure host module with
|
23
|
+
#
|
24
|
+
def configure(&block)
|
25
|
+
@configuration = #{self}::Configuration.new(@configuration_defaults, @configurable, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
EOF
|
29
|
+
end
|
30
|
+
|
31
|
+
# Class methods that will get installed in the host module
|
32
|
+
#
|
33
|
+
module ClassMethods
|
34
|
+
# A reader for Configuration
|
35
|
+
#
|
36
|
+
attr_reader :configuration
|
37
|
+
|
38
|
+
# Configuration defaults can be used to set the defaults of any Configuration
|
39
|
+
# @param [Proc] block setting the default values of the configuration
|
40
|
+
#
|
41
|
+
def configuration_defaults(&block)
|
42
|
+
@configuration_defaults = block
|
43
|
+
end
|
44
|
+
|
45
|
+
# configurable can be used to set the properties which should be configurable, as well as a type which
|
46
|
+
# the given property should be asserted to
|
47
|
+
# @param [Class, Symbol, Hash] properties a type as a first argument to type assert (if any) or nested properties to allow for setting
|
48
|
+
#
|
49
|
+
def configurable(*properties)
|
50
|
+
type = properties.shift if properties.first.is_a?(Class)
|
51
|
+
@configurable ||= {}
|
52
|
+
@configurable.merge!(to_configurable_hash(properties, type))
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# Instantiates a configurable hash from a property and a type
|
58
|
+
# @param [Symbol, Hash, Array] properties configurable properties, either single or nested
|
59
|
+
# @param [Class] type the type to assert, if any
|
60
|
+
# @return a hash with configurable values pointing to their types
|
61
|
+
#
|
62
|
+
def to_configurable_hash(properties, type)
|
63
|
+
Hash[properties.zip(Array(type) * properties.size)]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Configurations
|
2
|
+
# Configuration is a blank object in order to allow configuration of various properties including keywords
|
3
|
+
#
|
4
|
+
class Configuration < BasicObject
|
5
|
+
|
6
|
+
# @!macro [attach] install_kernel_method
|
7
|
+
# @method $1
|
8
|
+
#
|
9
|
+
def self.install_kernel_method(method)
|
10
|
+
kernel_method = ::Kernel.instance_method(method)
|
11
|
+
define_method method do |*args, &block|
|
12
|
+
kernel_method.bind(self).call(*args, &block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Installs the type asserting is_a? method from Kernel
|
17
|
+
#
|
18
|
+
install_kernel_method(:is_a?)
|
19
|
+
|
20
|
+
# Installs the inspect method from Kernel
|
21
|
+
#
|
22
|
+
install_kernel_method(:inspect)
|
23
|
+
|
24
|
+
# Initialize a new configuration
|
25
|
+
# @param [Proc] configuration_defaults A proc yielding to a default configuration
|
26
|
+
# @param [Hash] configurable a hash of configurable properties and their asserted types if given
|
27
|
+
# @param [Proc] block a block to configure this configuration with
|
28
|
+
# @return [HostModule::Configuration] a configuration
|
29
|
+
#
|
30
|
+
def initialize(configuration_defaults, configurable, &block)
|
31
|
+
@_writeable = true
|
32
|
+
@configurable = configurable
|
33
|
+
@configuration = _configuration_hash
|
34
|
+
|
35
|
+
_evaluate_configurable!
|
36
|
+
|
37
|
+
self.instance_eval(&configuration_defaults) if configuration_defaults
|
38
|
+
|
39
|
+
if block
|
40
|
+
self.instance_eval(&block)
|
41
|
+
self._writeable = false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Method missing gives access for reading and writing to the underlying configuration hash via dot notation
|
46
|
+
#
|
47
|
+
def method_missing(method, *args, &block)
|
48
|
+
property = method.to_s[0..-2].to_sym
|
49
|
+
|
50
|
+
if _is_writer?(method) && _configurable?(property)
|
51
|
+
_assert_type!(property, args.first)
|
52
|
+
@configuration[property] = args.first
|
53
|
+
elsif !_is_writer?(method) && @_writeable || _configured?(method)
|
54
|
+
@configuration[method]
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Respond to missing according to the method_missing implementation
|
61
|
+
#
|
62
|
+
def respond_to_missing?(method, include_private = false)
|
63
|
+
is_setter?(method) || @_writeable || _configured?(method) || super
|
64
|
+
end
|
65
|
+
|
66
|
+
# Set the configuration to writeable or read only. Access to writer methods is only allowed within the
|
67
|
+
# configure block, this method is used to invoke writability for subconfigurations.
|
68
|
+
# @param [Boolean] data true if the configuration should be writeable, false otherwise
|
69
|
+
#
|
70
|
+
def _writeable=(data)
|
71
|
+
@_writeable = data
|
72
|
+
@configuration.each do |k,v|
|
73
|
+
v._writeable = data if v.is_a?(Configuration)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# A convenience accessor to get a hash representation of the current state of the configuration
|
78
|
+
# @return [Hash] the configuration in hash form
|
79
|
+
#
|
80
|
+
def to_h
|
81
|
+
@configuration.inject({}) do |h, (k,v)|
|
82
|
+
h[k] = v.is_a?(Configuration) ? v.to_h : v
|
83
|
+
|
84
|
+
h
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# @param [Symbol] property The property to test for configurability
|
91
|
+
# @return [Boolean] whether the given property is configurable
|
92
|
+
#
|
93
|
+
def _configurable?(property)
|
94
|
+
_arbitrarily_configurable? or @configurable.has_key?(property)
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [Symbol] property The property to test for
|
98
|
+
# @return [Boolean] whether the given property has been configured
|
99
|
+
#
|
100
|
+
def _configured?(property)
|
101
|
+
@configuration.has_key?(property)
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [Hash] A configuration hash instantiating subhashes if the key is configurable
|
105
|
+
#
|
106
|
+
def _configuration_hash
|
107
|
+
::Hash.new do |h, k|
|
108
|
+
h[k] = Configuration.new(nil, @configurable) if _configurable?(k)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Evaluates configurable properties and passes eventual hashes down to subconfigurations
|
113
|
+
#
|
114
|
+
def _evaluate_configurable!
|
115
|
+
return if _arbitrarily_configurable?
|
116
|
+
|
117
|
+
@configurable.each do |k, type|
|
118
|
+
if k.is_a?(::Hash)
|
119
|
+
k.each do |property, nested|
|
120
|
+
@configuration[property] = Configuration.new(nil, _to_configurable_hash(nested, type))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# @param [Symbol, Hash, Array] value configurable properties, either single or nested
|
127
|
+
# @param [Class] type the type to assert, if any
|
128
|
+
# @return a hash with configurable values pointing to their types
|
129
|
+
#
|
130
|
+
def _to_configurable_hash(value, type)
|
131
|
+
value = [value] unless value.is_a?(::Array)
|
132
|
+
::Hash[value.zip([type].flatten*value.size)]
|
133
|
+
end
|
134
|
+
|
135
|
+
# Type assertion for configurable properties
|
136
|
+
# @param [Symbol] property the property to type test
|
137
|
+
# @param [Any] value the given value
|
138
|
+
# @raise [ConfigurationError] if the given value has the wrong type
|
139
|
+
#
|
140
|
+
def _assert_type!(property, value)
|
141
|
+
return if _arbitrarily_configurable?
|
142
|
+
|
143
|
+
expected_type = @configurable[property]
|
144
|
+
return if expected_type.nil?
|
145
|
+
|
146
|
+
::Kernel.raise ConfigurationError, "Expected #{property} to be configured with #{expected_type}, but got #{value.class.inspect}", caller unless value.is_a?(expected_type)
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [Boolean] whether this configuration is arbitrarily configurable
|
150
|
+
#
|
151
|
+
def _arbitrarily_configurable?
|
152
|
+
@configurable.nil? or @configurable.empty?
|
153
|
+
end
|
154
|
+
|
155
|
+
# @param [Symbol] method the method to test for
|
156
|
+
# @return [Boolean] whether the given method is a writer
|
157
|
+
#
|
158
|
+
def _is_writer?(method)
|
159
|
+
method.to_s.end_with?('=')
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'configurations/error'
|
2
|
+
require_relative 'configurations/configuration'
|
3
|
+
require_relative 'configurations/configurable'
|
4
|
+
|
5
|
+
# Configurations provides a unified approach to do configurations with the flexibility to do everything
|
6
|
+
# from arbitrary configurations to type asserted configurations for your gem or any other ruby code.
|
7
|
+
# @version 1.0.0
|
8
|
+
# @author Beat Richartz
|
9
|
+
#
|
10
|
+
module Configurations
|
11
|
+
extend Configurable
|
12
|
+
|
13
|
+
# Version number of Configurations
|
14
|
+
#
|
15
|
+
VERSION = '1.0.0'
|
16
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestConfiguration < Minitest::Test
|
4
|
+
|
5
|
+
ConfigurationTestModule = testmodule_for(Configurations)
|
6
|
+
ConfigurationTestModule.module_eval do
|
7
|
+
configuration_defaults do |c|
|
8
|
+
c.uh.this.is.neat = 'NEAT'
|
9
|
+
c.pah = 'PUH'
|
10
|
+
c.overwrite.this = ''
|
11
|
+
c.overwriteee = 'BLA'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
def setup
|
15
|
+
ConfigurationTestModule.configure do |c|
|
16
|
+
c.basic = 'BASIC'
|
17
|
+
c.class = 'KEY'
|
18
|
+
c.overwriteee = 'YEAH'
|
19
|
+
c.overwrite.this = 'OVERWRITE'
|
20
|
+
c.github.repo = 'github.com/beatrichartz/configurations'
|
21
|
+
c.github.access_key = 'ABCDEF'
|
22
|
+
c.something.else.entirely.nested.deep.below = 'something'
|
23
|
+
end
|
24
|
+
|
25
|
+
@configuration = ConfigurationTestModule.configuration
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_configuration_is_subclass_of_host_module
|
29
|
+
assert_equal true, ConfigurationTestModule.const_defined?(:Configuration)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_configuration_to_h
|
33
|
+
assert_equal(
|
34
|
+
{
|
35
|
+
uh:
|
36
|
+
{
|
37
|
+
this: { is: { neat: 'NEAT' } }
|
38
|
+
},
|
39
|
+
pah: 'PUH',
|
40
|
+
overwrite: {
|
41
|
+
this: 'OVERWRITE'
|
42
|
+
},
|
43
|
+
overwriteee: 'YEAH',
|
44
|
+
basic: 'BASIC',
|
45
|
+
class: 'KEY',
|
46
|
+
github: {
|
47
|
+
repo: 'github.com/beatrichartz/configurations',
|
48
|
+
access_key: 'ABCDEF'
|
49
|
+
},
|
50
|
+
something: { else: { entirely: { nested: { deep: { below: 'something' } } } } }
|
51
|
+
}, @configuration.to_h)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_defaults
|
55
|
+
assert_equal 'PUH', @configuration.pah
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_defaults_overwrite
|
59
|
+
assert_equal 'YEAH', @configuration.overwriteee
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_nested_defaults
|
63
|
+
assert_equal 'NEAT', @configuration.uh.this.is.neat
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_nested_defaults_overwrite
|
67
|
+
assert_equal 'OVERWRITE', @configuration.overwrite.this
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_configurable
|
71
|
+
assert_equal 'BASIC', @configuration.basic
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_keywords_configurable
|
75
|
+
assert_equal 'KEY', @configuration.class
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_nested_properties_with_same_key_configurable
|
79
|
+
assert_equal 'github.com/beatrichartz/configurations', @configuration.github.repo
|
80
|
+
assert_equal 'ABCDEF', @configuration.github.access_key
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_deeply_nested_properties_configurable
|
84
|
+
assert_equal 'something', @configuration.something.else.entirely.nested.deep.below
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_not_callable_with_undefined_property
|
88
|
+
assert_raises NoMethodError do
|
89
|
+
@configuration.somethings
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestStricterConfiguration < Minitest::Test
|
4
|
+
|
5
|
+
StrictConfigurationTestModule = testmodule_for(Configurations)
|
6
|
+
StrictConfigurationTestModule.module_eval do
|
7
|
+
configurable :property1, :property2
|
8
|
+
configurable String, :property3
|
9
|
+
configurable Symbol, property4: :property5, property6: [:property7, :property8]
|
10
|
+
configurable Array, property9: { property10: :property11 }
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup
|
14
|
+
StrictConfigurationTestModule.configure do |c|
|
15
|
+
c.property1 = 'BASIC1'
|
16
|
+
c.property2 = 'BASIC2'
|
17
|
+
c.property3 = 'STRING'
|
18
|
+
c.property4.property5 = :something
|
19
|
+
c.property6.property7 = :anything
|
20
|
+
c.property6.property8 = :everything
|
21
|
+
c.property9.property10.property11 = %w(here I am)
|
22
|
+
end
|
23
|
+
|
24
|
+
@configuration = StrictConfigurationTestModule.configuration
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_configurable_when_set_configurable
|
28
|
+
assert_equal 'BASIC1', @configuration.property1
|
29
|
+
assert_equal 'BASIC2', @configuration.property2
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_configurable_when_set_nested_configurable
|
33
|
+
assert_equal :something, @configuration.property4.property5
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_configurable_with_same_key_when_set_nested_configurable
|
37
|
+
assert_equal :anything, @configuration.property6.property7
|
38
|
+
assert_equal :everything, @configuration.property6.property8
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_configurable_with_deeply_nested_property
|
42
|
+
assert_equal %w(here I am), @configuration.property9.property10.property11
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_not_configurable_with_wrong_type
|
46
|
+
assert_raises Configurations::ConfigurationError do
|
47
|
+
StrictConfigurationTestModule.configure do |c|
|
48
|
+
c.property3 = {}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_not_configurable_with_undefined_property
|
54
|
+
assert_raises NoMethodError do
|
55
|
+
StrictConfigurationTestModule.configure do |c|
|
56
|
+
c.property4 = {}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_not_callable_with_undefined_property
|
62
|
+
assert_raises NoMethodError do
|
63
|
+
@configuration.property12
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_not_configurable_with_undefined_nested_property
|
68
|
+
assert_raises NoMethodError do
|
69
|
+
StrictConfigurationTestModule.configure do |c|
|
70
|
+
c.property6.property9 = {}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_not_callable_with_undefined_nested_property
|
76
|
+
assert_raises NoMethodError do
|
77
|
+
@configuration.property6.property9
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'minitest'
|
3
|
+
|
4
|
+
PATH = Pathname.new(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift PATH, File.expand_path('../../lib', __FILE__)
|
7
|
+
|
8
|
+
Dir[PATH.join('support', '**', '*.rb')].each(&method(:require))
|
9
|
+
|
10
|
+
Minitest::Test.class_eval do
|
11
|
+
extend TestModules
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'minitest/autorun'
|
15
|
+
require 'minitest/pride'
|
16
|
+
require 'test/unit/assertions'
|
17
|
+
|
18
|
+
require 'configurations'
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: configurations
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Beat Richartz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.4'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.8'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10'
|
55
|
+
description: Configurations provides a unified approach to do configurations with
|
56
|
+
the flexibility to do everything from arbitrary configurations to type asserted
|
57
|
+
configurations for your gem or any other ruby code.
|
58
|
+
email: attr_accessor@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- .ruby-version
|
65
|
+
- .travis.yml
|
66
|
+
- Gemfile
|
67
|
+
- License.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- configurations.gemspec
|
71
|
+
- lib/configurations.rb
|
72
|
+
- lib/configurations/configurable.rb
|
73
|
+
- lib/configurations/configuration.rb
|
74
|
+
- lib/configurations/error.rb
|
75
|
+
- test/configurations/test_configuration.rb
|
76
|
+
- test/configurations/test_stricter_configuration.rb
|
77
|
+
- test/support/testmodules.rb
|
78
|
+
- test/test_helper.rb
|
79
|
+
homepage: http://github.com/beatrichartz/configurations
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.0.14
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Configurations with a configure block from arbitrary to type-restricted for
|
103
|
+
your gem or other ruby code.
|
104
|
+
test_files:
|
105
|
+
- test/configurations/test_configuration.rb
|
106
|
+
- test/configurations/test_stricter_configuration.rb
|
107
|
+
- test/support/testmodules.rb
|
108
|
+
- test/test_helper.rb
|
109
|
+
has_rdoc:
|