iqeo-conf 0.0.2 → 0.0.3
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.
- data/Gemfile.lock +1 -1
- data/README.md +24 -13
- data/lib/iqeo/configuration/hash_with_indifferent_access.rb +169 -0
- data/lib/iqeo/configuration/version.rb +1 -1
- data/lib/iqeo/configuration.rb +47 -16
- data/pkg/iqeo-conf-0.0.2.gem +0 -0
- data/spec/configuration_spec.rb +141 -26
- metadata +3 -3
- data/scratch.txt +0 -122
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -12,12 +12,14 @@ $ gem install iqeo-conf
|
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
|
-
|
15
|
+
Require it...
|
16
16
|
|
17
17
|
```ruby
|
18
18
|
require 'iqeo/configuration'
|
19
19
|
```
|
20
20
|
|
21
|
+
### Create a configuration
|
22
|
+
|
21
23
|
Set values...
|
22
24
|
|
23
25
|
#### Directly on a configuration object
|
@@ -46,7 +48,7 @@ conf = Iqeo::Configuration.new do |c|
|
|
46
48
|
end
|
47
49
|
```
|
48
50
|
|
49
|
-
|
51
|
+
#### Configuration DSL instance_eval style
|
50
52
|
|
51
53
|
```ruby
|
52
54
|
conf = Iqeo::Configuration.new do
|
@@ -72,24 +74,33 @@ conf.delta => [ 1, 2, 3 ]
|
|
72
74
|
|
73
75
|
## Other features
|
74
76
|
|
75
|
-
This README may not be complete, see rspec tests for all features.
|
77
|
+
This README may not be complete, see rspec tests for all working features.
|
76
78
|
|
77
|
-
##
|
79
|
+
## Done
|
80
|
+
|
81
|
+
Need docs...
|
78
82
|
|
79
|
-
* Hash operators [] & []=
|
80
|
-
* Nested configurations
|
83
|
+
* Hash operators [] & []=
|
84
|
+
* Nested configurations
|
81
85
|
* Nested configurations inherit settings
|
82
86
|
* Nested configurations override inherited settings
|
83
|
-
* Indifferent hash access, symbol, strings, case sensitivity optional ?
|
84
|
-
* Iterate over items hash - access to hash / mixin enumerable / delegation to hash ?
|
85
87
|
* Load configurations from a string or file at creation
|
86
|
-
*
|
87
|
-
*
|
88
|
-
|
89
|
-
|
88
|
+
* Iterate over items hash - by delegation to hash
|
89
|
+
* Indifferent hash access - using ActiveSupport/HashWithIndifferentAccess
|
90
|
+
|
91
|
+
## Todo
|
92
|
+
|
93
|
+
Need time (have motivation)...
|
94
|
+
|
95
|
+
* Configuration file load path
|
90
96
|
* Use an existing configuration for defaults
|
97
|
+
* Clean DSL syntax for creating a nested configuration - just a block ?
|
98
|
+
* Load configurations from a string or file after creation / in DSL block
|
99
|
+
* Option to get hash directly to prevent polluting namespace with delegated hash methods
|
100
|
+
* Blank slate for DSL ? - optional ?
|
91
101
|
* Global configuration - watch for collisions ?
|
92
|
-
*
|
102
|
+
* Issues around deferred interpolation / procs / lambdas etc...
|
103
|
+
* Load other formats into configuration - YAML, CSV, ...anything Enumerable should be easy enough.
|
93
104
|
|
94
105
|
## License
|
95
106
|
|
@@ -0,0 +1,169 @@
|
|
1
|
+
|
2
|
+
module Iqeo
|
3
|
+
|
4
|
+
# from ActiveSupport 3.2.3 @ http://github.com/rails/rails/tree/3-2-stable/activesupport/lib/active_support
|
5
|
+
# did not want dependency on all of ActiveSupport
|
6
|
+
|
7
|
+
class HashWithIndifferentAccess < Hash
|
8
|
+
|
9
|
+
# Always returns true, so that <tt>Array#extract_options!</tt> finds members of this class.
|
10
|
+
def extractable_options?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_indifferent_access
|
15
|
+
dup
|
16
|
+
end
|
17
|
+
|
18
|
+
def nested_under_indifferent_access
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(constructor = {})
|
23
|
+
if constructor.is_a?(Hash)
|
24
|
+
super()
|
25
|
+
update(constructor)
|
26
|
+
else
|
27
|
+
super(constructor)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def default(key = nil)
|
32
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
33
|
+
self[key]
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.new_from_hash_copying_default(hash)
|
40
|
+
new(hash).tap do |new_hash|
|
41
|
+
new_hash.default = hash.default
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
46
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
47
|
+
|
48
|
+
# Assigns a new value to the hash:
|
49
|
+
#
|
50
|
+
# hash = HashWithIndifferentAccess.new
|
51
|
+
# hash[:key] = "value"
|
52
|
+
#
|
53
|
+
def []=(key, value)
|
54
|
+
regular_writer(convert_key(key), convert_value(value))
|
55
|
+
end
|
56
|
+
|
57
|
+
alias_method :store, :[]=
|
58
|
+
|
59
|
+
# Updates the instantized hash with values from the second:
|
60
|
+
#
|
61
|
+
# hash_1 = HashWithIndifferentAccess.new
|
62
|
+
# hash_1[:key] = "value"
|
63
|
+
#
|
64
|
+
# hash_2 = HashWithIndifferentAccess.new
|
65
|
+
# hash_2[:key] = "New Value!"
|
66
|
+
#
|
67
|
+
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
68
|
+
#
|
69
|
+
def update(other_hash)
|
70
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
71
|
+
super(other_hash)
|
72
|
+
else
|
73
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
74
|
+
self
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
alias_method :merge!, :update
|
79
|
+
|
80
|
+
# Checks the hash for a key matching the argument passed in:
|
81
|
+
#
|
82
|
+
# hash = HashWithIndifferentAccess.new
|
83
|
+
# hash["key"] = "value"
|
84
|
+
# hash.key? :key # => true
|
85
|
+
# hash.key? "key" # => true
|
86
|
+
#
|
87
|
+
def key?(key)
|
88
|
+
super(convert_key(key))
|
89
|
+
end
|
90
|
+
|
91
|
+
alias_method :include?, :key?
|
92
|
+
alias_method :has_key?, :key?
|
93
|
+
alias_method :member?, :key?
|
94
|
+
|
95
|
+
# Fetches the value for the specified key, same as doing hash[key]
|
96
|
+
def fetch(key, *extras)
|
97
|
+
super(convert_key(key), *extras)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns an array of the values at the specified indices:
|
101
|
+
#
|
102
|
+
# hash = HashWithIndifferentAccess.new
|
103
|
+
# hash[:a] = "x"
|
104
|
+
# hash[:b] = "y"
|
105
|
+
# hash.values_at("a", "b") # => ["x", "y"]
|
106
|
+
#
|
107
|
+
def values_at(*indices)
|
108
|
+
indices.collect {|key| self[convert_key(key)]}
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns an exact copy of the hash.
|
112
|
+
def dup
|
113
|
+
self.class.new(self).tap do |new_hash|
|
114
|
+
new_hash.default = default
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash.
|
119
|
+
# Does not overwrite the existing hash.
|
120
|
+
def merge(hash)
|
121
|
+
self.dup.update(hash)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
125
|
+
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a <tt>HashWithDifferentAccess</tt>.
|
126
|
+
def reverse_merge(other_hash)
|
127
|
+
super self.class.new_from_hash_copying_default(other_hash)
|
128
|
+
end
|
129
|
+
|
130
|
+
def reverse_merge!(other_hash)
|
131
|
+
replace(reverse_merge( other_hash ))
|
132
|
+
end
|
133
|
+
|
134
|
+
# Removes a specified key from the hash.
|
135
|
+
def delete(key)
|
136
|
+
super(convert_key(key))
|
137
|
+
end
|
138
|
+
|
139
|
+
def stringify_keys!; self end
|
140
|
+
def stringify_keys; dup end
|
141
|
+
# undef :symbolize_keys! # was causing error in Iqeo::Configuration
|
142
|
+
def symbolize_keys; to_hash.symbolize_keys end
|
143
|
+
def to_options!; self end
|
144
|
+
|
145
|
+
# Convert to a Hash with String keys.
|
146
|
+
def to_hash
|
147
|
+
Hash.new(default).merge!(self)
|
148
|
+
end
|
149
|
+
|
150
|
+
protected
|
151
|
+
|
152
|
+
def convert_key(key)
|
153
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
154
|
+
end
|
155
|
+
|
156
|
+
def convert_value(value)
|
157
|
+
if value.is_a? Hash
|
158
|
+
# value.nested_under_indifferent_access : this would require modifying Hash - we're not going to do that!
|
159
|
+
HashWithIndifferentAccess.new_from_hash_copying_default(value)
|
160
|
+
elsif value.is_a?(Array)
|
161
|
+
value.dup.replace(value.map { |e| convert_value(e) })
|
162
|
+
else
|
163
|
+
value
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
data/lib/iqeo/configuration.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
|
2
2
|
require_relative "configuration/version"
|
3
|
+
require_relative "configuration/hash_with_indifferent_access"
|
3
4
|
|
4
|
-
# todo:
|
5
|
-
# todo: load configurations from string & file
|
6
|
-
# todo: configuration file load path
|
7
|
-
# todo: iterate over items hash - access to hash / mixin enumerable / delegation to hash ?
|
8
|
-
# todo: indifferent hash access
|
5
|
+
# todo: configuration file load path - array of Dir.glob like file specs ?
|
9
6
|
# todo: use an existing configuration for defaults
|
7
|
+
# todo: clean DSL syntax for creating a configuration - just a block ?
|
8
|
+
# todo: load configurations from a string or file after creation / in DSL block
|
9
|
+
# todo: option to get hash directly to prevent polluting namespace with delegated hash methods
|
10
|
+
# todo: blank slate for DSL - optional ?
|
10
11
|
# todo: global configuration - watch for collisions ?
|
11
12
|
# todo: deferred interpolation / procs / lambdas etc...
|
12
|
-
# todo: blank slate for DSL - optional ?
|
13
13
|
# todo: load other formats from string & file - YAML, XML?
|
14
14
|
|
15
15
|
module Iqeo
|
@@ -20,8 +20,19 @@ module Iqeo
|
|
20
20
|
VERSION
|
21
21
|
end
|
22
22
|
|
23
|
+
def self.read string
|
24
|
+
conf = self.new
|
25
|
+
conf.instance_eval string
|
26
|
+
conf
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.file file
|
30
|
+
return self.read file.respond_to?(:read) ? file.read : File.read(file)
|
31
|
+
end
|
32
|
+
|
23
33
|
def initialize &block
|
24
|
-
@items =
|
34
|
+
@items = HashWithIndifferentAccess.new
|
35
|
+
@_parent = nil
|
25
36
|
if block_given?
|
26
37
|
if block.arity == 1
|
27
38
|
yield self
|
@@ -32,17 +43,37 @@ module Iqeo
|
|
32
43
|
end
|
33
44
|
|
34
45
|
def method_missing name, *values
|
35
|
-
|
36
|
-
|
37
|
-
when
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
return @items.send name, *values if @items.respond_to? name
|
47
|
+
# this is unreachable since these methods are delegated to @items hash
|
48
|
+
# but keep it around for when we make selective delegation an option
|
49
|
+
#case name
|
50
|
+
#when :[]= then return _set values.shift, values.size > 1 ? values : values.first
|
51
|
+
#when :[] then return _get values.shift
|
52
|
+
#end
|
53
|
+
name = name.to_s.chomp('=') # todo: write a test case for a non-string object as key being converted by .to_s
|
54
|
+
return _get name if values.empty?
|
55
|
+
return _set name, values if values.size > 1
|
56
|
+
return _set name, values.first
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_accessor :_parent # todo: should attr_writer be protected ?
|
60
|
+
|
61
|
+
def _set key, value
|
62
|
+
# todo: extend parenting for enumerable with configurations at arbitrary depth ?
|
63
|
+
case
|
64
|
+
when value.kind_of?( Configuration ) then value._parent = self
|
65
|
+
when value.kind_of?( Enumerable ) then value.each { |v| v._parent = self if v.kind_of? Configuration }
|
43
66
|
end
|
67
|
+
@items[key] = value
|
44
68
|
end
|
45
|
-
|
69
|
+
|
70
|
+
def _get key
|
71
|
+
return @items[key] unless @items[key].nil?
|
72
|
+
return @items[key] if _parent.nil?
|
73
|
+
return _parent._get key
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
46
77
|
|
47
78
|
end
|
48
79
|
|
data/pkg/iqeo-conf-0.0.2.gem
CHANGED
Binary file
|
data/spec/configuration_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'iqeo/configuration'
|
3
|
+
require 'stringio'
|
3
4
|
|
4
5
|
include Iqeo
|
5
6
|
|
@@ -53,31 +54,27 @@ describe Configuration do
|
|
53
54
|
expect do
|
54
55
|
conf = Configuration.new
|
55
56
|
conf.alpha 1
|
56
|
-
conf.bravo
|
57
|
+
conf.bravo 'two'
|
57
58
|
conf.charlie 3.0
|
58
59
|
conf.delta :four
|
59
60
|
end.to_not raise_error
|
60
61
|
conf.should_not be_nil
|
61
62
|
conf.alpha.should == 1 and conf.alpha.should be_a Fixnum
|
62
|
-
conf.bravo.should ==
|
63
|
+
conf.bravo.should == 'two' and conf.bravo.should be_a String
|
63
64
|
conf.charlie.should == 3.0 and conf.charlie.should be_a Float
|
64
65
|
conf.delta.should == :four and conf.delta.should be_a Symbol
|
65
66
|
end
|
66
67
|
|
67
68
|
it 'accepts complex values' do
|
68
|
-
conf =
|
69
|
-
|
70
|
-
|
71
|
-
conf.alpha = [ :a, :b, :c ]
|
72
|
-
conf.bravo = { :a => 1, :b => 2, :c => 3 }
|
73
|
-
end.to_not raise_error
|
74
|
-
conf.should_not be_nil
|
69
|
+
conf = Configuration.new
|
70
|
+
conf.alpha = [ :a, :b, :c ]
|
71
|
+
conf.bravo = { :a => 1, :b => 2, :c => 3 }
|
75
72
|
conf.alpha.should == [ :a, :b, :c] and conf.alpha.should be_an Array
|
76
73
|
conf.alpha.size.should == 3
|
77
74
|
conf.alpha[0].should == :a
|
78
75
|
conf.alpha[1].should == :b
|
79
76
|
conf.alpha[2].should == :c
|
80
|
-
conf.bravo.should == {
|
77
|
+
conf.bravo.should == { 'a' => 1, 'b' => 2, 'c' => 3} and conf.bravo.should be_a Hash
|
81
78
|
conf.bravo.size.should == 3
|
82
79
|
conf.bravo[:a].should == 1
|
83
80
|
conf.bravo[:b].should == 2
|
@@ -89,13 +86,9 @@ describe Configuration do
|
|
89
86
|
context 'multiple value setting' do
|
90
87
|
|
91
88
|
it 'accepts hash without brackets' do
|
92
|
-
conf =
|
93
|
-
|
94
|
-
|
95
|
-
conf.alpha :a => 1, :b => 2, :c => 3
|
96
|
-
end.to_not raise_error
|
97
|
-
conf.should_not be_nil
|
98
|
-
conf.alpha.should == { :a => 1, :b => 2, :c => 3} and conf.alpha.should be_a Hash
|
89
|
+
conf = Configuration.new
|
90
|
+
conf.alpha :a => 1, :b => 2, :c => 3
|
91
|
+
conf.alpha.should == { 'a' => 1, 'b' => 2, 'c' => 3} and conf.alpha.should be_a Hash
|
99
92
|
end
|
100
93
|
|
101
94
|
it 'treats multiple values as an array' do
|
@@ -109,13 +102,9 @@ describe Configuration do
|
|
109
102
|
end
|
110
103
|
|
111
104
|
it 'treats hash without brackets after multiple values as last element of array' do
|
112
|
-
conf =
|
113
|
-
|
114
|
-
|
115
|
-
conf.alpha 1, 2, 3, :a => 4, :b => 5, :c => 6
|
116
|
-
end.to_not raise_error
|
117
|
-
conf.should_not be_nil
|
118
|
-
conf.alpha.should == [ 1, 2, 3, { :a => 4, :b => 5, :c => 6} ] and conf.alpha.should be_a Array
|
105
|
+
conf = Configuration.new
|
106
|
+
conf.alpha 1, 2, 3, :a => 4, :b => 5, :c => 6
|
107
|
+
conf.alpha.should == [ 1, 2, 3, { 'a' => 4, 'b' => 5, 'c' => 6} ] and conf.alpha.should be_a Array
|
119
108
|
end
|
120
109
|
|
121
110
|
end
|
@@ -159,12 +148,64 @@ describe Configuration do
|
|
159
148
|
conf.alpha.bravo.charlie.should be_true
|
160
149
|
end
|
161
150
|
|
151
|
+
it 'knows its parent when referenced directly' do
|
152
|
+
conf = nil
|
153
|
+
expect do
|
154
|
+
conf = Configuration.new
|
155
|
+
conf.alpha Configuration.new
|
156
|
+
conf.alpha.bravo Configuration.new
|
157
|
+
conf.alpha.bravo.charlie true
|
158
|
+
end.to_not raise_error
|
159
|
+
conf.should_not be_nil
|
160
|
+
conf.alpha.bravo._parent.should be conf.alpha
|
161
|
+
conf.alpha._parent.should be conf
|
162
|
+
conf._parent.should be_nil
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'knows its parent when contained in an enumerable' do
|
166
|
+
conf = nil
|
167
|
+
expect do
|
168
|
+
conf = Configuration.new
|
169
|
+
conf.alpha Configuration.new, Configuration.new, Configuration.new
|
170
|
+
end.to_not raise_error
|
171
|
+
conf.should_not be_nil
|
172
|
+
conf.alpha.each { |child| child._parent.should be conf }
|
173
|
+
conf._parent.should be_nil
|
174
|
+
end
|
175
|
+
|
162
176
|
it 'inherits settings' do
|
163
|
-
|
177
|
+
conf = nil
|
178
|
+
expect do
|
179
|
+
conf = Configuration.new
|
180
|
+
conf.alpha Configuration.new
|
181
|
+
conf.alpha.bravo Configuration.new
|
182
|
+
conf.top = true
|
183
|
+
conf.alpha.middle = true
|
184
|
+
conf.alpha.bravo.bottom = true
|
185
|
+
end.to_not raise_error
|
186
|
+
conf.should_not be_nil
|
187
|
+
conf.top.should be_true
|
188
|
+
conf.alpha.top.should be_true
|
189
|
+
conf.alpha.middle.should be_true
|
190
|
+
conf.alpha.bravo.top.should be_true
|
191
|
+
conf.alpha.bravo.middle.should be_true
|
192
|
+
conf.alpha.bravo.bottom.should be_true
|
164
193
|
end
|
165
194
|
|
166
195
|
it 'can override inherited settings' do
|
167
|
-
|
196
|
+
conf = nil
|
197
|
+
expect do
|
198
|
+
conf = Configuration.new
|
199
|
+
conf.alpha Configuration.new
|
200
|
+
conf.alpha.bravo Configuration.new
|
201
|
+
conf.level = 1
|
202
|
+
conf.alpha.level = 2
|
203
|
+
conf.alpha.bravo.level = 3
|
204
|
+
end.to_not raise_error
|
205
|
+
conf.should_not be_nil
|
206
|
+
conf.level.should == 1
|
207
|
+
conf.alpha.level.should == 2
|
208
|
+
conf.alpha.bravo.level.should == 3
|
168
209
|
end
|
169
210
|
|
170
211
|
end
|
@@ -277,4 +318,78 @@ describe Configuration do
|
|
277
318
|
|
278
319
|
end
|
279
320
|
|
321
|
+
context 'loads' do
|
322
|
+
|
323
|
+
it 'simple eval DSL from string' do
|
324
|
+
string = "alpha 1\nbravo 'two'\ncharlie 3.0\ndelta :four"
|
325
|
+
conf = nil
|
326
|
+
expect do
|
327
|
+
conf = Configuration.read string
|
328
|
+
end.to_not raise_error
|
329
|
+
conf.should_not be_nil
|
330
|
+
conf.alpha.should == 1 and conf.alpha.should be_a Fixnum
|
331
|
+
conf.bravo.should == "two" and conf.bravo.should be_a String
|
332
|
+
conf.charlie.should == 3.0 and conf.charlie.should be_a Float
|
333
|
+
conf.delta.should == :four and conf.delta.should be_a Symbol
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'simple eval DSL from file (by StringIO fake)' do
|
337
|
+
io = StringIO.new "alpha 1\nbravo 'two'\ncharlie 3.0\ndelta :four"
|
338
|
+
conf = nil
|
339
|
+
expect do
|
340
|
+
conf = Configuration.file io
|
341
|
+
end.to_not raise_error
|
342
|
+
conf.should_not be_nil
|
343
|
+
conf.alpha.should == 1 and conf.alpha.should be_a Fixnum
|
344
|
+
conf.bravo.should == "two" and conf.bravo.should be_a String
|
345
|
+
conf.charlie.should == 3.0 and conf.charlie.should be_a Float
|
346
|
+
conf.delta.should == :four and conf.delta.should be_a Symbol
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'simple eval DSL from file (by mock and expected methods)' do
|
350
|
+
file = mock
|
351
|
+
file.should_receive( :respond_to? ).with( :read ).and_return true
|
352
|
+
file.should_receive( :read ).and_return "alpha 1\nbravo 'two'\ncharlie 3.0\ndelta :four"
|
353
|
+
conf = nil
|
354
|
+
expect do
|
355
|
+
conf = Configuration.file file
|
356
|
+
end.to_not raise_error
|
357
|
+
conf.should_not be_nil
|
358
|
+
conf.alpha.should == 1 and conf.alpha.should be_a Fixnum
|
359
|
+
conf.bravo.should == "two" and conf.bravo.should be_a String
|
360
|
+
conf.charlie.should == 3.0 and conf.charlie.should be_a Float
|
361
|
+
conf.delta.should == :four and conf.delta.should be_a Symbol
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'simple eval DSL from filename (by expected methods)' do
|
365
|
+
File.should_receive( :read ).with( "filename" ).and_return "alpha 1\nbravo 'two'\ncharlie 3.0\ndelta :four"
|
366
|
+
conf = nil
|
367
|
+
expect do
|
368
|
+
conf = Configuration.file "filename"
|
369
|
+
end.to_not raise_error
|
370
|
+
conf.should_not be_nil
|
371
|
+
conf.alpha.should == 1 and conf.alpha.should be_a Fixnum
|
372
|
+
conf.bravo.should == "two" and conf.bravo.should be_a String
|
373
|
+
conf.charlie.should == 3.0 and conf.charlie.should be_a Float
|
374
|
+
conf.delta.should == :four and conf.delta.should be_a Symbol
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
378
|
+
|
379
|
+
it 'delegates hash methods to internal hash' do
|
380
|
+
conf = nil
|
381
|
+
expect do
|
382
|
+
conf = Configuration.new
|
383
|
+
conf.alpha 1
|
384
|
+
conf.bravo 'two'
|
385
|
+
conf.charlie 3.0
|
386
|
+
conf.delta :four
|
387
|
+
end.to_not raise_error
|
388
|
+
conf.should_not be_nil
|
389
|
+
expect do
|
390
|
+
conf.each { |k,v| x = v }
|
391
|
+
end.to_not raise_error
|
392
|
+
conf.size.should == 4
|
393
|
+
end
|
394
|
+
|
280
395
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iqeo-conf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -61,10 +61,10 @@ files:
|
|
61
61
|
- Rakefile
|
62
62
|
- iqeo-conf.gemspec
|
63
63
|
- lib/iqeo/configuration.rb
|
64
|
+
- lib/iqeo/configuration/hash_with_indifferent_access.rb
|
64
65
|
- lib/iqeo/configuration/version.rb
|
65
66
|
- pkg/iqeo-conf-0.0.1.gem
|
66
67
|
- pkg/iqeo-conf-0.0.2.gem
|
67
|
-
- scratch.txt
|
68
68
|
- spec/configuration_spec.rb
|
69
69
|
- spec/spec_helper.rb
|
70
70
|
homepage: http://github.com/iqeo/iqeo-conf
|
data/scratch.txt
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
conf = Conf.new 'name_0' do
|
2
|
-
|
3
|
-
# values
|
4
|
-
|
5
|
-
var_str "String"
|
6
|
-
var_int 123
|
7
|
-
var_arr [ 1, 2, 3]
|
8
|
-
var_hsh { :a => 1, :b => 2, :c => 3 }
|
9
|
-
|
10
|
-
# sub configs in different ways
|
11
|
-
|
12
|
-
var_conf_1 Conf.new 'name_1' do
|
13
|
-
...
|
14
|
-
end
|
15
|
-
|
16
|
-
var_conf_2 Conf.new do
|
17
|
-
...
|
18
|
-
end
|
19
|
-
|
20
|
-
var_conf_3 'name_3' do
|
21
|
-
...
|
22
|
-
end
|
23
|
-
|
24
|
-
var_conf_4 do
|
25
|
-
...
|
26
|
-
end
|
27
|
-
|
28
|
-
level 1
|
29
|
-
|
30
|
-
var_conf_5 'name_5' do
|
31
|
-
|
32
|
-
level 2
|
33
|
-
|
34
|
-
var_conf_6 'name_6' do
|
35
|
-
|
36
|
-
level 3
|
37
|
-
|
38
|
-
var_conf_7 'name_7' do
|
39
|
-
|
40
|
-
# Conf.inherit ?
|
41
|
-
level 4
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
other Conf.load 'file...' # etc...
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
# include config files
|
55
|
-
|
56
|
-
## return either a single Conf hierarchy or an array of Conf depending upon the file contents
|
57
|
-
|
58
|
-
Conf.path = [ '*' , '**/*.rb', "config/config.rb" ]
|
59
|
-
Conf.load => Conf... # no parameter defaults to Conf::path value
|
60
|
-
Conf.load filename => Conf...
|
61
|
-
Conf.load glob => Conf... / [Conf..., ...]
|
62
|
-
Conf.load [filename,...] => Conf... / [Conf..., ...]
|
63
|
-
Conf.load [glob,...] => Conf... / [Conf..., ...]
|
64
|
-
|
65
|
-
# usage
|
66
|
-
|
67
|
-
## retrieve values
|
68
|
-
|
69
|
-
conf.name => 'name_0'
|
70
|
-
conf.var_str => "String"
|
71
|
-
conf.var_int => 123
|
72
|
-
conf.var_arr => [1,2,3]
|
73
|
-
conf.var_hsh => { :a => 1, :b => 2, :c => 3 }
|
74
|
-
|
75
|
-
## retrieve sub-configurations
|
76
|
-
|
77
|
-
conf.var_conf_1 => Conf...
|
78
|
-
conf.var_conf_1.name => 'name_1'
|
79
|
-
|
80
|
-
## nested configurations
|
81
|
-
|
82
|
-
conf.level => 1
|
83
|
-
conf.var_conf_5.level => 2
|
84
|
-
conf.var_conf_5.var_conf_6.level => 3
|
85
|
-
conf.var_conf_5.var_conf_6.var_conf_7.level => 4
|
86
|
-
|
87
|
-
## set or create values
|
88
|
-
|
89
|
-
conf.existing_item "change to this"
|
90
|
-
conf.new_item "new value"
|
91
|
-
|
92
|
-
## indifferent keys
|
93
|
-
|
94
|
-
conf.name => 'name_0'
|
95
|
-
conf[:name] => 'name_0'
|
96
|
-
conf['name'] => 'name_0'
|
97
|
-
|
98
|
-
## enumeration
|
99
|
-
|
100
|
-
conf.values => # array of values like a hash
|
101
|
-
|
102
|
-
conf.keys => # array of string keys
|
103
|
-
conf.keys_as_strings => # array of string keys
|
104
|
-
conf.keys_as_symbols => # array of symbol keys
|
105
|
-
|
106
|
-
conf.to_hash => # hash of string key + value pairs
|
107
|
-
conf.to_hash_with_strings => # hash of string key + value pairs
|
108
|
-
conf.to_hash_with_symbols => # hash of symbol key + value pairs
|
109
|
-
|
110
|
-
conf.each do |key,value| # key will be string
|
111
|
-
puts key + " = " + value
|
112
|
-
end
|
113
|
-
|
114
|
-
conf.each_with_strings |key,value| # key will be string
|
115
|
-
...
|
116
|
-
|
117
|
-
conf.each_with_symbols |key,value| # key will be hash
|
118
|
-
...
|
119
|
-
|
120
|
-
# how about hashes with keys other than strings and symbols ?
|
121
|
-
# conf.to_hash { |k| k.method ... }
|
122
|
-
|