configru 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Change Log
2
2
 
3
+ ## 3.0.0 (22 September 2012)
4
+
5
+ * Added option arrays
6
+ * Accessing a key that is not declared in `Configru.load` now raises
7
+ `NoMethodError`, rather than returning `nil`.
8
+
3
9
  ## 2.0.1 (14 September 2012)
4
10
 
5
11
  * Fix: Cascade options in loaded files
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source :rubygems
2
2
 
3
3
  group :development do
4
4
  gem "rake", "~> 0.9.0"
5
- gem "rspec", "~> 2.10.0"
5
+ gem "rspec", "~> 2.11.0"
6
6
  gem "simplecov", "~> 0.6.0"
7
7
  end
8
8
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- configru (2.0.1)
4
+ configru (3.0.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -9,14 +9,14 @@ GEM
9
9
  diff-lcs (1.1.3)
10
10
  multi_json (1.3.6)
11
11
  rake (0.9.2.2)
12
- rspec (2.10.0)
13
- rspec-core (~> 2.10.0)
14
- rspec-expectations (~> 2.10.0)
15
- rspec-mocks (~> 2.10.0)
16
- rspec-core (2.10.1)
17
- rspec-expectations (2.10.0)
12
+ rspec (2.11.0)
13
+ rspec-core (~> 2.11.0)
14
+ rspec-expectations (~> 2.11.0)
15
+ rspec-mocks (~> 2.11.0)
16
+ rspec-core (2.11.1)
17
+ rspec-expectations (2.11.3)
18
18
  diff-lcs (~> 1.1.3)
19
- rspec-mocks (2.10.1)
19
+ rspec-mocks (2.11.2)
20
20
  simplecov (0.6.4)
21
21
  multi_json (~> 1.0)
22
22
  simplecov-html (~> 0.5.3)
@@ -28,5 +28,5 @@ PLATFORMS
28
28
  DEPENDENCIES
29
29
  configru!
30
30
  rake (~> 0.9.0)
31
- rspec (~> 2.10.0)
31
+ rspec (~> 2.11.0)
32
32
  simplecov (~> 0.6.0)
data/lib/configru/dsl.rb CHANGED
@@ -10,8 +10,14 @@ module Configru
10
10
  instance_eval(&block)
11
11
  end
12
12
 
13
- def option(name, type = Object, default = nil, validate = nil, &block)
14
- option = Configru::Option.new(type, default, validate, nil)
13
+ def option(name, type = Object, default = nil, validation = nil, &block)
14
+ option = Configru::Option.new(type, default, validation, nil)
15
+ Option.new(option, &block) if block
16
+ @options[name.to_s] = option
17
+ end
18
+
19
+ def option_array(name, type = Object, default = [], validation = nil, &block)
20
+ option = Configru::OptionArray.new(type, default, validation, nil)
15
21
  Option.new(option, &block) if block
16
22
  @options[name.to_s] = option
17
23
  end
@@ -36,11 +42,11 @@ module Configru
36
42
  end
37
43
 
38
44
  def validate(v = nil, &block)
39
- @option.validate = v || block
45
+ @option.validation = v || block
40
46
  end
41
47
 
42
48
  def transform(&block)
43
- @option.transform = block
49
+ @option.transformation = block
44
50
  end
45
51
  end
46
52
  end
@@ -1,3 +1,38 @@
1
1
  module Configru
2
- Option = Struct.new(:type, :default, :validate, :transform)
2
+ class Option < Struct.new(:type, :default, :validation, :transformation)
3
+ def type?(value)
4
+ value.is_a?(self.type)
5
+ end
6
+
7
+ def valid?(value)
8
+ return true unless self.validation
9
+ self.validation === value
10
+ end
11
+
12
+ def transform(value)
13
+ return value unless self.transformation
14
+ self.transformation[value]
15
+ end
16
+ end
17
+
18
+ class OptionArray < Option
19
+ def type?(values)
20
+ return false unless values.is_a?(Array)
21
+ values.all? {|x| x.is_a?(self.type) }
22
+ end
23
+
24
+ def valid?(values)
25
+ return true unless self.validation
26
+ values.all? do |x|
27
+ # Use === instead of passing validation as the block to #all? so that
28
+ # non-block validations (Regexp, Range) work
29
+ self.validation === x
30
+ end
31
+ end
32
+
33
+ def transform(values)
34
+ return values unless self.transformation
35
+ values.map(&self.transformation)
36
+ end
37
+ end
3
38
  end
@@ -1,6 +1,8 @@
1
1
  module Configru
2
2
  class StructHash < Hash
3
- def method_missing(key)
3
+ def method_missing(key, *args)
4
+ # Raise NoMethodError if the key does not exist
5
+ super(key, *args) unless args.empty? && self.include?(key.to_s)
4
6
  self[key.to_s]
5
7
  end
6
8
  end
@@ -1,3 +1,3 @@
1
1
  module Configru
2
- VERSION = "2.0.1"
2
+ VERSION = "3.0.0"
3
3
  end
data/lib/configru.rb CHANGED
@@ -19,10 +19,10 @@ module Configru
19
19
 
20
20
  class OptionValidationError < OptionError
21
21
  def initialize(path, validation = nil)
22
- if validation
23
- super(path, "failed validation `#{validation.inspect}`")
24
- else
22
+ if validation.is_a?(Proc)
25
23
  super(path, "failed validation")
24
+ else
25
+ super(path, "failed validation `#{validation.inspect}`")
26
26
  end
27
27
  end
28
28
  end
@@ -80,21 +80,15 @@ module Configru
80
80
  value = option.default
81
81
  end
82
82
 
83
- unless value.is_a? option.type
83
+ unless option.type?(value)
84
84
  raise OptionTypeError.new(@option_path, option.type, value.class)
85
85
  end
86
86
 
87
- if option.validate.is_a? Proc
88
- unless option.validate[value]
89
- raise OptionValidationError.new(@option_path)
90
- end
91
- elsif option.validate
92
- unless option.validate === value
93
- raise OptionValidationError.new(@option_path, option.validate)
94
- end
87
+ unless option.valid?(value)
88
+ raise OptionValidationError.new(@option_path, option.validation)
95
89
  end
96
90
 
97
- output[key] = option.transform ? option.transform[value] : value
91
+ output[key] = option.transform(value)
98
92
 
99
93
  @option_path.pop
100
94
  end
@@ -105,9 +99,6 @@ module Configru
105
99
  end
106
100
 
107
101
  def self.method_missing(method, *args)
108
- # Let super raise the appropriate exception if it looks like the caller
109
- # wants a real method
110
- super(method, *args) unless args.empty?
111
- @root.send(method)
102
+ @root.send(method, *args)
112
103
  end
113
104
  end
@@ -11,12 +11,14 @@ describe Configru do
11
11
  Configru.example.should == 'example'
12
12
  end
13
13
 
14
- it 'behaves like a hash' do
14
+ it 'behaves like a StructHash' do
15
15
  Configru.load do
16
16
  option :example, String, 'example'
17
17
  end
18
18
 
19
19
  Configru['example'].should == 'example'
20
+ Configru.example.should == 'example'
21
+ expect { Configru.example2 }.to raise_error(NoMethodError)
20
22
  end
21
23
 
22
24
  it 'loads defaults if no files exist' do
@@ -123,4 +125,48 @@ describe Configru do
123
125
 
124
126
  Configru.example.should == 'example_dt'
125
127
  end
128
+
129
+ it 'checks that array option values are arrays' do
130
+ expect do
131
+ Configru.load(example_file :a) do
132
+ option_array :example
133
+ end
134
+ end.to raise_error(Configru::OptionTypeError)
135
+ end
136
+
137
+ it 'checks array option types' do
138
+ expect do
139
+ Configru.load(example_file :i) do
140
+ option_array :hetero, String
141
+ end
142
+ end.to raise_error(Configru::OptionTypeError)
143
+ end
144
+
145
+ it 'validates option arrays against values' do
146
+ expect do
147
+ Configru.load(example_file :i) do
148
+ option_array :example, Fixnum, [], 1..6
149
+ end
150
+ end.to raise_error(Configru::OptionValidationError)
151
+ end
152
+
153
+ it 'validates option arrays against blocks' do
154
+ expect do
155
+ Configru.load(example_file :i) do
156
+ option_array :example, Fixnum, [] do
157
+ validate {|x| x.even? }
158
+ end
159
+ end
160
+ end.to raise_error(Configru::OptionValidationError)
161
+ end
162
+
163
+ it 'applies transformations to option arrays' do
164
+ Configru.load(example_file :i) do
165
+ option_array :example, Fixnum, [] do
166
+ transform {|x| x + 1 }
167
+ end
168
+ end
169
+
170
+ Configru.example.should == [3, 5, 7, 8]
171
+ end
126
172
  end
data/spec/dsl_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  describe Configru::DSL::Option do
2
2
  before do
3
- @option = Configru::Option.new(:type, :default, :validate, :transform)
3
+ @option = Configru::Option.new(:type, :default, :validation, :transformation)
4
4
  end
5
5
 
6
6
  it 'sets option type' do
@@ -24,7 +24,7 @@ describe Configru::DSL::Option do
24
24
  validate /example/
25
25
  end
26
26
 
27
- @option.validate.should == /example/
27
+ @option.validation.should == /example/
28
28
  end
29
29
 
30
30
  it 'sets option validate block' do
@@ -34,19 +34,19 @@ describe Configru::DSL::Option do
34
34
  end
35
35
  end
36
36
 
37
- @option.validate.should be_a(Proc)
38
- @option.validate.call.should == :example
37
+ @option.validation.should be_a(Proc)
38
+ @option.validation.call.should == :example
39
39
  end
40
40
 
41
- it 'sets option transofmr block' do
41
+ it 'sets option transform block' do
42
42
  described_class.new(@option) do
43
43
  transform do
44
44
  :example
45
45
  end
46
46
  end
47
47
 
48
- @option.transform.should be_a(Proc)
49
- @option.transform.call.should == :example
48
+ @option.transformation.should be_a(Proc)
49
+ @option.transformation.call.should == :example
50
50
  end
51
51
  end
52
52
 
@@ -58,6 +58,10 @@ describe Configru::DSL::OptionGroup do
58
58
 
59
59
  group.options.should have_key('example')
60
60
  group.options['example'].should be_a(Configru::Option)
61
+ group.options['example'].type.should == Object
62
+ group.options['example'].default.should be_nil
63
+ group.options['example'].validation.should be_nil
64
+ group.options['example'].transformation.should be_nil
61
65
  end
62
66
 
63
67
  it 'converts option names to strings' do
@@ -68,15 +72,25 @@ describe Configru::DSL::OptionGroup do
68
72
  group.options.should have_key('example')
69
73
  end
70
74
 
71
- it 'creates a default option' do
75
+ it 'creates an option array' do
72
76
  group = described_class.new do
73
- option 'example'
77
+ option_array 'example'
74
78
  end
75
79
 
80
+ group.options.should have_key('example')
81
+ group.options['example'].should be_a(Configru::OptionArray)
76
82
  group.options['example'].type.should == Object
77
- group.options['example'].default.should be_nil
78
- group.options['example'].validate.should be_nil
79
- group.options['example'].transform.should be_nil
83
+ group.options['example'].default.should == []
84
+ group.options['example'].validation.should be_nil
85
+ group.options['example'].transformation.should be_nil
86
+ end
87
+
88
+ it 'converts option array names to strings' do
89
+ group = described_class.new do
90
+ option_array :example
91
+ end
92
+
93
+ group.options.should have_key('example')
80
94
  end
81
95
 
82
96
  it 'runs the Option DSL' do
@@ -84,9 +98,13 @@ describe Configru::DSL::OptionGroup do
84
98
  option 'example' do
85
99
  type String
86
100
  end
101
+ option_array 'example_array' do
102
+ type String
103
+ end
87
104
  end
88
105
 
89
106
  group.options['example'].type.should == String
107
+ group.options['example_array'].type.should == String
90
108
  end
91
109
 
92
110
  it 'creates a group' do
@@ -0,0 +1,2 @@
1
+ hetero: ["string", 2]
2
+ example: [2, 4, 6, 7]
@@ -7,8 +7,13 @@ describe Configru::StructHash do
7
7
  @hash.should be_a_kind_of(Hash)
8
8
  end
9
9
 
10
- it 'returns nil for missing method key' do
11
- @hash.example.should be_nil
10
+ it 'raises NoMethodError for missing method key' do
11
+ expect { @hash.example }.to raise_error(NoMethodError)
12
+ end
13
+
14
+ it 'raises NoMethodError if method key exists but is called with arguments' do
15
+ @hash['example'] = :example
16
+ expect { @hash.example(:foo) }.to raise_error(NoMethodError)
12
17
  end
13
18
 
14
19
  it 'returns value for method key' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configru
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0
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-09-14 00:00:00.000000000 Z
12
+ date: 2012-09-22 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: YAML configuration file loader
15
15
  email:
@@ -42,6 +42,7 @@ files:
42
42
  - spec/example_files/example_f.yml
43
43
  - spec/example_files/example_g.yml
44
44
  - spec/example_files/example_h.yml
45
+ - spec/example_files/example_i.yml
45
46
  - spec/spec_helper.rb
46
47
  - spec/structhash_spec.rb
47
48
  homepage: https://github.com/programble/configru
@@ -58,7 +59,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
59
  version: '0'
59
60
  segments:
60
61
  - 0
61
- hash: 872203077689334122
62
+ hash: 2949675092247533978
62
63
  required_rubygems_version: !ruby/object:Gem::Requirement
63
64
  none: false
64
65
  requirements:
@@ -67,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
68
  version: '0'
68
69
  segments:
69
70
  - 0
70
- hash: 872203077689334122
71
+ hash: 2949675092247533978
71
72
  requirements: []
72
73
  rubyforge_project:
73
74
  rubygems_version: 1.8.24
@@ -85,5 +86,6 @@ test_files:
85
86
  - spec/example_files/example_f.yml
86
87
  - spec/example_files/example_g.yml
87
88
  - spec/example_files/example_h.yml
89
+ - spec/example_files/example_i.yml
88
90
  - spec/spec_helper.rb
89
91
  - spec/structhash_spec.rb