iqeo-conf 1.0.1 → 1.1.0.pre.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.
- data/README.md +3 -1
- data/lib/iqeo/configuration/version.rb +1 -1
- data/lib/iqeo/configuration.rb +58 -13
- data/spec/configuration_spec.rb +162 -7
- metadata +5 -5
data/README.md
CHANGED
|
@@ -121,12 +121,14 @@ conf.collect { |key,value| value } # => [ 1, 2.0, :three, 'four' ]
|
|
|
121
121
|
* defaults
|
|
122
122
|
* merge configurations recursively
|
|
123
123
|
* blank slate for DSL
|
|
124
|
+
* wildcard * for chained usage: a.b.*.d
|
|
124
125
|
|
|
125
|
-
##
|
|
126
|
+
## Application
|
|
126
127
|
|
|
127
128
|
* Dynamic settings by '[]' & '[]=' & 'self'
|
|
128
129
|
* Multiple configuration files
|
|
129
130
|
* Hierarchial configuration files
|
|
131
|
+
* Validation: if a.b.*.d == true
|
|
130
132
|
|
|
131
133
|
## License
|
|
132
134
|
|
data/lib/iqeo/configuration.rb
CHANGED
|
@@ -59,8 +59,8 @@ module Iqeo
|
|
|
59
59
|
#
|
|
60
60
|
# Content should be in eval DSL format.
|
|
61
61
|
|
|
62
|
-
def self.read string
|
|
63
|
-
conf = self.new
|
|
62
|
+
def self.read string, options = {}
|
|
63
|
+
conf = self.new nil, options
|
|
64
64
|
conf.instance_eval string
|
|
65
65
|
conf
|
|
66
66
|
end
|
|
@@ -69,12 +69,12 @@ module Iqeo
|
|
|
69
69
|
#
|
|
70
70
|
# Content should be in eval DSL format.
|
|
71
71
|
|
|
72
|
-
def self.load file
|
|
72
|
+
def self.load file, options = {}
|
|
73
73
|
return self.read file.respond_to?(:read) ? file.read : File.read(file)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
def self.new_defer_block_for_parent parent, &block
|
|
77
|
-
conf = Configuration.new
|
|
76
|
+
def self.new_defer_block_for_parent parent, options = {}, &block
|
|
77
|
+
conf = Configuration.new nil, options
|
|
78
78
|
conf._parent = parent
|
|
79
79
|
if block_given? && block.arity > 0
|
|
80
80
|
block.call(conf) # this is 'yield self' from the outside
|
|
@@ -82,9 +82,18 @@ module Iqeo
|
|
|
82
82
|
conf
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
OPTIONS = {
|
|
86
|
+
:blankslate => true,
|
|
87
|
+
:case_sensitive => true
|
|
88
|
+
}
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
attr_accessor :_parent, :_items, :_options
|
|
91
|
+
|
|
92
|
+
# todo: why can't :_parent= be protected ?
|
|
93
|
+
#protected :_parent, :_items, :_items= #, :_get, :[], :_set, :[]=
|
|
94
|
+
|
|
95
|
+
def initialize default = nil, options = {}, &block
|
|
96
|
+
_process_options options
|
|
88
97
|
@_items = HashWithIndifferentAccess.new
|
|
89
98
|
@_parent = nil
|
|
90
99
|
_merge! default if default.kind_of?( Configuration )
|
|
@@ -105,11 +114,11 @@ module Iqeo
|
|
|
105
114
|
|
|
106
115
|
name = name.to_s.chomp('=')
|
|
107
116
|
|
|
108
|
-
if block_given?
|
|
109
|
-
if block.arity == 1
|
|
110
|
-
return _set name, Configuration.new_defer_block_for_parent( self, &block )
|
|
117
|
+
if block_given? # block is a nested configuration
|
|
118
|
+
if block.arity == 1 # yield DSL needs deferred block to set parent without binding
|
|
119
|
+
return _set name, Configuration.new_defer_block_for_parent( self, @_options, &block )
|
|
111
120
|
else
|
|
112
|
-
return _set name, Configuration.new( &block )
|
|
121
|
+
return _set name, Configuration.new( nil, @_options, &block ) # eval DSL can set parent from block binding in initialize
|
|
113
122
|
end
|
|
114
123
|
end
|
|
115
124
|
|
|
@@ -161,9 +170,45 @@ module Iqeo
|
|
|
161
170
|
self.dup._merge! other
|
|
162
171
|
end
|
|
163
172
|
|
|
164
|
-
|
|
173
|
+
def _configurations
|
|
174
|
+
@_items.values.select { |value| value.kind_of? Configuration }
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def _process_options options
|
|
178
|
+
@_options = OPTIONS.merge options
|
|
179
|
+
#_wipe if @_options[:blankslate] # todo: how to make blankslate optional ?
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# todo: method '*' for wildcard dir glob like selections eg top.*.bottom ?
|
|
183
|
+
|
|
184
|
+
def *
|
|
185
|
+
ConfigurationDelegator.new _configurations
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
end
|
|
165
189
|
|
|
166
|
-
|
|
190
|
+
class ConfigurationDelegator # todo: inherit from < Blankslate ?
|
|
191
|
+
|
|
192
|
+
attr_reader :_confs
|
|
193
|
+
|
|
194
|
+
# protected :_confs
|
|
195
|
+
|
|
196
|
+
def initialize confs
|
|
197
|
+
@_confs = confs
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def method_missing name, *values, &block
|
|
201
|
+
return @_confs.send( name, *values, &block ) if @_confs.respond_to? name # @_confs methods are highest priority
|
|
202
|
+
end
|
|
203
|
+
#alias [] method_missing # so we don't have to deal with [ and 'key' separately ( see alias [] _get in Configuration )
|
|
204
|
+
|
|
205
|
+
def empty?
|
|
206
|
+
@_confs.empty?
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def *
|
|
210
|
+
ConfigurationDelegator.new( @_confs.inject([]) { |array,conf| array + conf._configurations } )
|
|
211
|
+
end
|
|
167
212
|
|
|
168
213
|
end
|
|
169
214
|
|
data/spec/configuration_spec.rb
CHANGED
|
@@ -951,13 +951,168 @@ describe Configuration do
|
|
|
951
951
|
|
|
952
952
|
end # "v1.0"
|
|
953
953
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
954
|
+
def simple_config_1
|
|
955
|
+
Configuration.new do
|
|
956
|
+
alpha 1
|
|
957
|
+
bravo 'one'
|
|
958
|
+
charlie 1.0
|
|
959
|
+
delta :one
|
|
960
|
+
end
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
def simple_config_1_example conf
|
|
964
|
+
conf.should_not be_nil
|
|
965
|
+
conf.alpha.should == 1 and conf.alpha.should be_a Fixnum
|
|
966
|
+
conf.bravo.should == "one" and conf.bravo.should be_a String
|
|
967
|
+
conf.charlie.should == 1.0 and conf.charlie.should be_a Float
|
|
968
|
+
conf.delta.should == :one and conf.delta.should be_a Symbol
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
def simple_config_2
|
|
972
|
+
Configuration.new do
|
|
973
|
+
echo 2
|
|
974
|
+
foxtrot 'two'
|
|
975
|
+
hotel 2.0
|
|
976
|
+
india :two
|
|
977
|
+
end
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
def simple_config_2_example conf
|
|
981
|
+
conf.should_not be_nil
|
|
982
|
+
conf.echo.should == 2 and conf.echo.should be_a Fixnum
|
|
983
|
+
conf.foxtrot.should == "two" and conf.foxtrot.should be_a String
|
|
984
|
+
conf.hotel.should == 2.0 and conf.hotel.should be_a Float
|
|
985
|
+
conf.india.should == :two and conf.india.should be_a Symbol
|
|
986
|
+
conf['echo']
|
|
987
|
+
#and conf[:echo].should be_a Fixnum
|
|
988
|
+
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
def simple_config_3
|
|
992
|
+
Configuration.new do
|
|
993
|
+
juliet 3
|
|
994
|
+
kilo 'three'
|
|
995
|
+
lima 3.0
|
|
996
|
+
mike :three
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
def simple_config_3_example conf
|
|
1001
|
+
conf.should_not be_nil
|
|
1002
|
+
conf.juliet.should == 3 and conf.juliet.should be_a Fixnum
|
|
1003
|
+
conf.kilo.should == "three" and conf.kilo.should be_a String
|
|
1004
|
+
conf.lima.should == 3.0 and conf.lima.should be_a Float
|
|
1005
|
+
conf.mike.should == :three and conf.mike.should be_a Symbol
|
|
1006
|
+
end
|
|
1007
|
+
|
|
1008
|
+
context 'v1.1' do
|
|
1009
|
+
|
|
1010
|
+
context 'options' do
|
|
1011
|
+
|
|
1012
|
+
it 'have defaults at Configuration creation' do
|
|
1013
|
+
conf = Configuration.new
|
|
1014
|
+
conf._options[:blankslate].should be true
|
|
1015
|
+
conf._options[:case_sensitive].should be true
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
it 'are accepted at Configuration creation' do
|
|
1019
|
+
conf = Configuration.new nil, :blankslate => false, :case_sensitive => false
|
|
1020
|
+
conf._options[:blankslate].should be false
|
|
1021
|
+
conf._options[:case_sensitive].should be false
|
|
1022
|
+
end
|
|
1023
|
+
|
|
1024
|
+
end
|
|
1025
|
+
|
|
1026
|
+
context 'wildcard *' do
|
|
1027
|
+
|
|
1028
|
+
it 'returns an empty ConfigurationDelegator for subject with no child configurations' do
|
|
1029
|
+
conf = simple_config_1
|
|
1030
|
+
simple_config_1_example conf
|
|
1031
|
+
delegator = conf.*
|
|
1032
|
+
delegator.should be_a ConfigurationDelegator
|
|
1033
|
+
delegator.should be_empty
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
it 'returns ConfigurationDelegator containing child configurations for subject' do
|
|
1037
|
+
conf = simple_config_1
|
|
1038
|
+
conf.nested2 = simple_config_2
|
|
1039
|
+
conf.nested3 = simple_config_3
|
|
1040
|
+
simple_config_1_example conf
|
|
1041
|
+
simple_config_2_example conf.nested2
|
|
1042
|
+
simple_config_3_example conf.nested3
|
|
1043
|
+
delegator = conf.*
|
|
1044
|
+
delegator.should be_a ConfigurationDelegator
|
|
1045
|
+
delegator.size.should be 2
|
|
1046
|
+
delegator[0].should be conf.nested2
|
|
1047
|
+
delegator[1].should be conf.nested3
|
|
1048
|
+
end
|
|
1049
|
+
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
context 'ConfigurationDelegator' do
|
|
1053
|
+
|
|
1054
|
+
it 'can be created with no child configurations' do
|
|
1055
|
+
delegator = ConfigurationDelegator.new []
|
|
1056
|
+
delegator.should be_a ConfigurationDelegator
|
|
1057
|
+
delegator.should be_empty
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
context 'wildcard *' do
|
|
1061
|
+
|
|
1062
|
+
# todo: question : should wildcard return nil for already empty ConfigurationDelegator / overshoot ?
|
|
1063
|
+
|
|
1064
|
+
it 'returns an empty ConfigurationDelegator for ConfigurationDelegator with no child configurations' do
|
|
1065
|
+
conf = simple_config_1
|
|
1066
|
+
conf.nested2 = simple_config_2
|
|
1067
|
+
conf.nested3 = simple_config_3
|
|
1068
|
+
simple_config_1_example conf
|
|
1069
|
+
simple_config_2_example conf.nested2
|
|
1070
|
+
simple_config_3_example conf.nested3
|
|
1071
|
+
delegator = conf.*.*
|
|
1072
|
+
delegator.should be_a ConfigurationDelegator
|
|
1073
|
+
delegator.should be_empty
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
it 'returns an empty ConfigurationDelegator when overshoots' do
|
|
1077
|
+
conf = simple_config_1
|
|
1078
|
+
conf.nested2 = simple_config_2
|
|
1079
|
+
conf.nested3 = simple_config_3
|
|
1080
|
+
simple_config_1_example conf
|
|
1081
|
+
simple_config_2_example conf.nested2
|
|
1082
|
+
simple_config_3_example conf.nested3
|
|
1083
|
+
delegator = conf.*.*.*.*.*.*.*.*.*
|
|
1084
|
+
delegator.should be_a ConfigurationDelegator
|
|
1085
|
+
delegator.should be_empty
|
|
1086
|
+
end
|
|
1087
|
+
|
|
1088
|
+
it 'returns ConfigurationDelegator containing child configurations for ConfigurationDelegator' do
|
|
1089
|
+
conf = simple_config_1
|
|
1090
|
+
conf.nested2 = simple_config_2
|
|
1091
|
+
conf.nested3 = simple_config_3
|
|
1092
|
+
conf.nested2.nested2 = simple_config_2
|
|
1093
|
+
conf.nested2.nested3 = simple_config_3
|
|
1094
|
+
conf.nested3.nested2 = simple_config_2
|
|
1095
|
+
conf.nested3.nested3 = simple_config_3
|
|
1096
|
+
simple_config_1_example conf
|
|
1097
|
+
simple_config_2_example conf.nested2
|
|
1098
|
+
simple_config_2_example conf.nested2.nested2
|
|
1099
|
+
simple_config_2_example conf.nested3.nested2
|
|
1100
|
+
simple_config_3_example conf.nested3
|
|
1101
|
+
simple_config_3_example conf.nested2.nested3
|
|
1102
|
+
simple_config_3_example conf.nested3.nested3
|
|
1103
|
+
delegator = conf.*.*
|
|
1104
|
+
delegator.size.should be 4
|
|
1105
|
+
delegator[0].should be conf.nested2.nested2
|
|
1106
|
+
delegator[1].should be conf.nested2.nested3
|
|
1107
|
+
delegator[2].should be conf.nested3.nested2
|
|
1108
|
+
delegator[3].should be conf.nested3.nested3
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
end # wildcard *
|
|
1112
|
+
|
|
1113
|
+
end # ConfigurationDelagator
|
|
1114
|
+
|
|
1115
|
+
end #v1.1
|
|
961
1116
|
|
|
962
1117
|
end
|
|
963
1118
|
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: iqeo-conf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 1.1.0.pre.0
|
|
5
|
+
prerelease: 6
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Gerard Fowley
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-05-
|
|
12
|
+
date: 2012-05-25 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rake
|
|
@@ -146,9 +146,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
146
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
147
|
none: false
|
|
148
148
|
requirements:
|
|
149
|
-
- - ! '
|
|
149
|
+
- - ! '>'
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
|
-
version:
|
|
151
|
+
version: 1.3.1
|
|
152
152
|
requirements: []
|
|
153
153
|
rubyforge_project:
|
|
154
154
|
rubygems_version: 1.8.24
|