aerogel-configurator 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 042aa549ffd9d4f413d6a8de433bf0ae8946c456
4
- data.tar.gz: 41b201f4106c00992e80817d725a523f54c4f105
3
+ metadata.gz: d5d485f6753454a181a98d543f720a6663768b07
4
+ data.tar.gz: b4be097519b528236c765ef58a425c53d1e8fb38
5
5
  SHA512:
6
- metadata.gz: b04a7ab68eba0eff985fc3f4772801dd9ee3d212da69d92d280ffd040a8c81d1ee97fb2ebd1cffd8b1103204a3a5bab2e227c85c5a0f1d8ceb97c54c20e0175e
7
- data.tar.gz: 61dfb5acaf68e312755bef0533272fd3a5f38560f0213e6c3be69e36a6c6e2dd0d6570f0a0ae5794e1b461ee31a85736eb8990bd251cd6c1a3d6746b15d868ef
6
+ metadata.gz: 48e3384130d3f26e2ea6678b55893eb513dc604370f94463964abc798ef4430c0a69b6d900ed04368cf572944fb1facef1c8c74c19371d1cb6c18b93da1ba9ae
7
+ data.tar.gz: e946c8587ecc1cad999d7ba6b5ba5be89fca136980004bea93603c3904ae4dab8a865e8220712cd552c94c8a31b7b1e5f57b900ceb25b74ff453e2cc71af1497
data/.gitignore CHANGED
@@ -17,4 +17,6 @@ test/version_tmp
17
17
  tmp
18
18
  *.sublime-project
19
19
  *.sublime-workspace
20
- .rspec
20
+ .rspec
21
+ *.ruby-version
22
+ *.ruby-gemset
data/README.md CHANGED
@@ -63,6 +63,11 @@ config.foobar # => Configurator::Parameter::Undefined
63
63
  # however:
64
64
  config.foobar.nil? # => true
65
65
 
66
+ # there are helper methods for handling undefined parameters:
67
+ config.foo! # => 'bar'
68
+ config.foobar! # => ArgumentError 'Undefined parameter: .foobar'
69
+ config.foo? # => true, defined and not false or nil
70
+ config.foobar? # => false, undefined or is false or nil
66
71
  ```
67
72
 
68
73
  ### 2. Setting configuration parameters in your ruby code
data/Rakefile CHANGED
@@ -3,4 +3,10 @@ require "bundler/gem_tasks"
3
3
  desc "Run tests"
4
4
  task :default do
5
5
  system "bundle exec rspec"
6
+ end
7
+
8
+ desc "Load current gem in console"
9
+ task :console do
10
+ cmd = "irb"
11
+ sh "#{cmd} -I./lib -r 'aerogel/configurator'"
6
12
  end
@@ -0,0 +1,3 @@
1
+ foo "hello"
2
+ bar true
3
+ foobar false
@@ -0,0 +1,27 @@
1
+ require 'aerogel/configurator'
2
+
3
+ def test( config, param_chain )
4
+ config_param = "config.#{param_chain}"
5
+ begin
6
+ value = eval config_param
7
+ puts "#{config_param}: #{value.inspect}"
8
+ rescue StandardError => e
9
+ puts "#{config_param}: <error>: #{e}"
10
+ end
11
+ end
12
+
13
+ config = Configurator.load File.dirname( __FILE__ )+"/ex10.conf"
14
+
15
+
16
+ puts "config: #{config.to_hash}"
17
+
18
+ test config, "foo!"
19
+ test config, "foo?"
20
+ test config, "bar!"
21
+ test config, "bar?"
22
+ test config, "foobar!"
23
+ test config, "foobar?"
24
+ test config, "fuu!"
25
+ test config, "fuu?"
26
+ test config, "fuu.fuu.fuu!"
27
+ test config, "fuu.fuu.fuu?"
@@ -20,7 +20,7 @@ class Configurator
20
20
  end
21
21
 
22
22
  def respond_to?(method, include_private = false)
23
- super || Parameter.new( @params ).respond_to?(method, include_private)
23
+ super || (Parameter.new( @params ).respond_to? method, include_private)
24
24
  end
25
25
 
26
26
  # Loads parameters from +source+.
@@ -2,26 +2,49 @@ class Configurator
2
2
  private
3
3
  class Parameter
4
4
 
5
- def initialize( data = {} )
5
+ METHOD_NAME_REGEXP = /^([^\[\]=!?]*)[\[\]=!?]?$/
6
+
7
+ def initialize( data = {}, fullname = "" )
6
8
  @data = data
9
+ @fullname = fullname
7
10
  end
8
11
 
9
12
  def method_missing(method, *args)
10
- # puts "Parameter.method_missing: '#{method}' in #{@data}"
13
+ param_name = method.to_s.match(METHOD_NAME_REGEXP)[1].to_sym
14
+ force_value = false
15
+ force_boolean = false
16
+ # puts "Parameter.method_missing: #{@fullname}.#{method} '(#{param_name}) in #{@data}"
11
17
  if method.to_s =~ /=$/
12
- @data[method.to_s.match(/^(.*)=$/)[1].to_sym] = args.first
13
- elsif @data[method].is_a?(Hash)
14
- Parameter.new @data[method]
15
- elsif @data[method].nil?
16
- Undefined.new @data, [method]
17
- elsif @data[method].is_a? Proc
18
- @data[method].call
18
+ return @data[param_name] = args.first
19
+ elsif method.to_s =~ /\!$/
20
+ force_value = true
21
+ elsif method.to_s =~ /\?$/
22
+ force_boolean = true
23
+ end
24
+
25
+ # evaluate param
26
+ if @data[param_name].is_a?(Hash)
27
+ force_boolean ? true : Parameter.new( @data[param_name], "#{@fullname}.#{param_name}" )
28
+ elsif @data[param_name].nil?
29
+ raise ArgumentError.new "Undefined parameter: #{@fullname}.#{param_name}" if force_value
30
+ force_boolean ? false : Undefined.new( @data, [param_name], "#{@fullname}.#{param_name}" )
31
+ elsif @data[param_name].is_a? Proc
32
+ force_boolean ? !!@data[param_name].call : @data[param_name].call
19
33
  else
20
34
  # it's a leaf
21
- @data[method]
35
+ force_boolean ? !!@data[param_name] : @data[param_name]
22
36
  end
23
37
  end
24
38
 
39
+ def respond_to?( method, include_private = false )
40
+ super || respond_to_missing?( method, include_private )
41
+ end
42
+
43
+ # any valid identifier ending with '=', '!' or '?' is a valid method
44
+ def respond_to_missing?( method, include_private = false )
45
+ super || (method.to_s =~ METHOD_NAME_REGEXP ) || true
46
+ end
47
+
25
48
  def raw
26
49
  @data
27
50
  end
@@ -51,15 +74,21 @@ private
51
74
  # +name+ is an Array of chained names starting from mount point
52
75
  #
53
76
  class Undefined
54
- def initialize( root, name )
77
+ def initialize( root, name, fullname )
55
78
  # puts "Undefined.new: root=#{root} name=#{name.to_s} "
56
79
  @root = root
57
80
  @name = name # convert to array
81
+ @fullname = fullname
58
82
  end
59
83
 
60
84
  def method_missing(method, *args)
85
+ param_name = method.to_s.match(METHOD_NAME_REGEXP)[1].to_sym
61
86
  # puts "Undefined.method_missing: #{method} root=#{@root} names=#{@names}"
62
- if method.to_s =~ /=$/
87
+ if method.to_s =~ /!$/
88
+ raise ArgumentError.new "Undefined parameter: #{@fullname}.#{param_name}"
89
+ elsif method.to_s =~ /\?$/
90
+ false
91
+ elsif method.to_s =~ /=$/
63
92
  method = method.to_s.match(/^(.*)=$/)[1].to_sym
64
93
  # deep assign
65
94
  d = ( @root[@name.shift] ||= {} )
@@ -68,7 +97,7 @@ private
68
97
  end
69
98
  d[method] = args.first
70
99
  else
71
- Undefined.new( @root, @name+[method])
100
+ Undefined.new( @root, @name+[method], "#{@fullname}.#{@name.shift}" )
72
101
  end
73
102
  end
74
103
 
@@ -1,3 +1,3 @@
1
1
  class Configurator
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -0,0 +1,3 @@
1
+ foo "hello"
2
+ bar true
3
+ foobar false
@@ -22,4 +22,55 @@ describe "Configurator::DSL" do
22
22
  config.bar.should eql "hello"
23
23
  end
24
24
 
25
+ describe "<param>! method" do
26
+ it "should be provided for existing and non-existing parameters" do
27
+ config = Configurator.load test_filename('conf/f.conf')
28
+ config.should respond_to(:foo!)
29
+ config.should respond_to(:nofoo!)
30
+ end
31
+
32
+ it "should return parameter value for existing parameter" do
33
+ config = Configurator.load test_filename('conf/f.conf')
34
+ config.foo!.should eql("hello")
35
+ end
36
+
37
+ it "should raise ArgumentError for undefined parameter" do
38
+ config = Configurator.load test_filename('conf/f.conf')
39
+ expect { config.nofoo! }.to raise_error(ArgumentError)
40
+ end
41
+
42
+ it "should work at the end of a chain of undefined parameters" do
43
+ config = Configurator.load test_filename('conf/f.conf')
44
+ expect { config.nofoo.nofoo }.not_to raise_error
45
+ expect { config.nofoo.nofoo! }.to raise_error(ArgumentError)
46
+ end
47
+ end
48
+
49
+ describe "<param>? method" do
50
+ it "should be provided for existing and non-existing parameters" do
51
+ config = Configurator.load test_filename('conf/f.conf')
52
+ config.should respond_to(:foo?)
53
+ config.should respond_to(:nofoo?)
54
+ end
55
+
56
+ it "should return value coerced to Boolean for existing parameter" do
57
+ config = Configurator.load test_filename('conf/f.conf')
58
+ config.foo?.should be true
59
+ config.bar?.should be true
60
+ config.foobar?.should be false
61
+ end
62
+
63
+ it "should return false for non-existing parameter" do
64
+ config = Configurator.load test_filename('conf/f.conf')
65
+ config.nofoo?.should be false
66
+ end
67
+
68
+ it "should work at the end of a chain of undefined parameters" do
69
+ config = Configurator.load test_filename('conf/f.conf')
70
+ config.nofoo.nofoo.should be_nil
71
+ config.nofoo.nofoo?.should be false
72
+ end
73
+
74
+ end
75
+
25
76
  end # describe Configurator::DSL
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aerogel-configurator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Kukushkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-05 00:00:00.000000000 Z
11
+ date: 2014-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,6 +67,8 @@ files:
67
67
  - Rakefile
68
68
  - aerogel-configurator.gemspec
69
69
  - examples/ex1.rb
70
+ - examples/ex10.conf
71
+ - examples/ex10.rb
70
72
  - examples/ex2.conf
71
73
  - examples/ex2.rb
72
74
  - examples/ex3.conf
@@ -93,6 +95,7 @@ files:
93
95
  - spec/conf/c.conf
94
96
  - spec/conf/d.conf
95
97
  - spec/conf/e.conf
98
+ - spec/conf/f.conf
96
99
  - spec/lib/configurator_spec.rb
97
100
  - spec/lib/dsl_spec.rb
98
101
  - spec/spec_helper.rb
@@ -116,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
119
  version: '0'
117
120
  requirements: []
118
121
  rubyforge_project:
119
- rubygems_version: 2.0.3
122
+ rubygems_version: 2.0.6
120
123
  signing_key:
121
124
  specification_version: 4
122
125
  summary: Simple configuration files for Ruby applications
@@ -126,6 +129,7 @@ test_files:
126
129
  - spec/conf/c.conf
127
130
  - spec/conf/d.conf
128
131
  - spec/conf/e.conf
132
+ - spec/conf/f.conf
129
133
  - spec/lib/configurator_spec.rb
130
134
  - spec/lib/dsl_spec.rb
131
135
  - spec/spec_helper.rb