configurations 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|