configure 0.1.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Philipp Brüll
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.rdoc ADDED
@@ -0,0 +1,53 @@
1
+
2
+ = Configure
3
+
4
+ Configure offers an easy way for configure your application using a DSL. It provides a single-method interface that
5
+ receives a block and returns well-structured configuration values.
6
+
7
+ == Usage
8
+
9
+ The most simple way <tt>configure</tt> can be used is to pass a block to the <tt>Configure.process</tt> method and
10
+ receive back a hash with the configuration values.
11
+
12
+ laser = Configure.process do
13
+ title "red laser"
14
+ wave_length 700
15
+ end
16
+
17
+ laser == {
18
+ :title => "red laser",
19
+ :wave_length => 700
20
+ } # => true
21
+
22
+ It is also possible to pass blocks to configuration keys and combine multiple values to an array.
23
+
24
+ laser = Configure.process do
25
+ title "red and violet pulse laser"
26
+ pulses do
27
+ wave_length 700
28
+ duration 20
29
+ end
30
+ pulses do
31
+ wave_length 400
32
+ duration 20
33
+ end
34
+ end
35
+
36
+ laser == {
37
+ :title => "red and violet pulse laser",
38
+ :pulses => [
39
+ { :wave_length => 700, :duration => 20 },
40
+ { :wave_length => 400, :duration => 20 }
41
+ ]
42
+ } # => true
43
+
44
+ == Development
45
+
46
+ Development has been done test-driven and the code follows at most the Clean Code paradigms. Code smells has been
47
+ removed by using the reek[http://github.com/kevinrutherford/reek] code smell detector.
48
+
49
+ This project is still under development. Any bug report and contribution is welcome!
50
+
51
+ == Support
52
+
53
+ Apart from contribution, support via Flattr[http://flattr.com/thing/145021/Configure-DSL-for-Ruby] is welcome.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ gem 'rspec'
3
+ gem 'reek'
4
+ require 'rspec'
5
+ require 'rake/rdoctask'
6
+ require 'rspec/core/rake_task'
7
+ require 'reek/rake/task'
8
+
9
+ task :default => :spec
10
+
11
+ namespace :gem do
12
+
13
+ desc "Builds the gem"
14
+ task :build do
15
+ system "gem build *.gemspec && mkdir -p pkg/ && mv *.gem pkg/"
16
+ end
17
+
18
+ desc "Builds and installs the gem"
19
+ task :install => :build do
20
+ system "gem install pkg/"
21
+ end
22
+
23
+ end
24
+
25
+ Reek::Rake::Task.new do |task|
26
+ task.fail_on_error = true
27
+ end
28
+
29
+ desc "Generate the rdoc"
30
+ Rake::RDocTask.new do |rdoc|
31
+ rdoc.rdoc_files.add [ "README.rdoc", "lib/**/*.rb" ]
32
+ rdoc.main = "README.rdoc"
33
+ rdoc.title = ""
34
+ end
35
+
36
+ desc "Run all specs in spec directory"
37
+ RSpec::Core::RakeTask.new do |task|
38
+ task.pattern = "spec/lib/**/*_spec.rb"
39
+ end
40
+
41
+ namespace :spec do
42
+
43
+ desc "Run all integration specs in spec/acceptance directory"
44
+ RSpec::Core::RakeTask.new(:acceptance) do |task|
45
+ task.pattern = "spec/acceptance/**/*_spec.rb"
46
+ end
47
+
48
+ end
data/lib/configure.rb ADDED
@@ -0,0 +1,18 @@
1
+
2
+ module Configure
3
+
4
+ autoload :Injector, File.join(File.dirname(__FILE__), "configure", "injector")
5
+ autoload :Sandbox, File.join(File.dirname(__FILE__), "configure", "sandbox")
6
+
7
+ def self.process(&block)
8
+ process_configuration Hash, &block
9
+ end
10
+
11
+ def self.process_configuration(configuration_class, &block)
12
+ injector = Injector.new configuration_class
13
+ sandbox = Sandbox.new injector
14
+ sandbox.instance_eval &block
15
+ injector.configuration
16
+ end
17
+
18
+ end
@@ -0,0 +1,43 @@
1
+
2
+ # Creates a configuration from the passed class and provides methods to inject values.
3
+ class Configure::Injector
4
+
5
+ attr_reader :configuration
6
+
7
+ def initialize(configuration_class)
8
+ @configuration_class = configuration_class
9
+ @configuration = @configuration_class.new
10
+ end
11
+
12
+ def put_block(key, &block)
13
+ value = Value.new @configuration, key
14
+ value.put Configure.process_configuration(@configuration_class, &block)
15
+ end
16
+
17
+ def put_arguments(key, arguments)
18
+ value = Value.new @configuration, key
19
+ value.put arguments.size == 1 ? arguments.first : arguments
20
+ end
21
+
22
+ # Injector for a single configuration value.
23
+ class Value
24
+
25
+ def initialize(configuration, key)
26
+ @configuration, @key = configuration, key
27
+ end
28
+
29
+ def get
30
+ @configuration[@key]
31
+ end
32
+
33
+ def put(value)
34
+ @configuration[@key] = exists? ? [ get, value ].flatten : value
35
+ end
36
+
37
+ def exists?
38
+ @configuration.has_key? @key
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,17 @@
1
+
2
+ # The sandbox can be used to catch method calls and delegates them the to passed injector.
3
+ class Configure::Sandbox
4
+
5
+ def initialize(injector)
6
+ @injector = injector
7
+ end
8
+
9
+ def method_missing(method_name, *arguments, &block)
10
+ if block_given?
11
+ @injector.put_block method_name, &block
12
+ else
13
+ @injector.put_arguments method_name, arguments
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe Configure do
4
+
5
+ describe "process" do
6
+
7
+ it "should turn method call into hash values" do
8
+ configuration = described_class.process do
9
+ test_key "one"
10
+ end
11
+
12
+ configuration.should == {
13
+ :test_key => "one"
14
+ }
15
+ end
16
+
17
+ it "should combine multiple arguments to an array" do
18
+ configuration = described_class.process do
19
+ test_key "one", "two"
20
+ end
21
+
22
+ configuration.should == {
23
+ :test_key => [ "one", "two" ]
24
+ }
25
+ end
26
+
27
+ it "should combine the values of multiple calls to an array" do
28
+ configuration = described_class.process do
29
+ test_key "one", "two"
30
+ test_key "three", "four"
31
+ end
32
+
33
+ configuration.should == {
34
+ :test_key => [ "one", "two", "three", "four" ]
35
+ }
36
+ end
37
+
38
+ it "should build nested configurations out of the passed blocks" do
39
+ configuration = described_class.process do
40
+ test_key do
41
+ nested_test_key "one"
42
+ end
43
+ end
44
+
45
+ configuration.should == {
46
+ :test_key => { :nested_test_key => "one" }
47
+ }
48
+ end
49
+
50
+ it "should combine nested configurations to an array" do
51
+ configuration = described_class.process do
52
+ test_key do
53
+ nested_test_key "one"
54
+ end
55
+ test_key do
56
+ nested_test_key "two"
57
+ end
58
+ end
59
+
60
+ configuration.should == {
61
+ :test_key => [
62
+ { :nested_test_key => "one" },
63
+ { :nested_test_key => "two" }
64
+ ]
65
+ }
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+
3
+ describe Configure::Injector do
4
+
5
+ before :each do
6
+ @injector = described_class.new Hash
7
+ end
8
+
9
+ describe "initialize" do
10
+
11
+ it "should create a configuration" do
12
+ @injector.configuration.should be_instance_of(Hash)
13
+ end
14
+
15
+ end
16
+
17
+ describe "put_block" do
18
+
19
+ before :each do
20
+ @block = Proc.new { }
21
+ Configure.stub(:process_configuration => :nested_configuration)
22
+ end
23
+
24
+ it "should process a newly created configuration" do
25
+ Configure.should_receive(:process_configuration).with(Hash, &@block)
26
+ @injector.put_block :test_key, &@block
27
+ end
28
+
29
+ it "should nest the configuration" do
30
+ @injector.put_block :test_key, &@block
31
+ @injector.configuration[:test_key].should == :nested_configuration
32
+ end
33
+
34
+ it "should combine nested configurations to an array" do
35
+ @injector.put_block :test_key, &@block
36
+ @injector.put_block :test_key, &@block
37
+ @injector.configuration[:test_key].should == [ :nested_configuration, :nested_configuration ]
38
+ end
39
+
40
+ end
41
+
42
+ describe "put_arguments" do
43
+
44
+ it "should assign a value" do
45
+ @injector.put_arguments :test_key, [ "one" ]
46
+ @injector.configuration[:test_key].should == "one"
47
+ end
48
+
49
+ it "should assign an array of values" do
50
+ @injector.put_arguments :test_key, [ "one", "two" ]
51
+ @injector.configuration[:test_key].should == [ "one", "two" ]
52
+ end
53
+
54
+ it "should combine existing with new values" do
55
+ @injector.put_arguments :test_key, [ "one" ]
56
+ @injector.put_arguments :test_key, [ "two" ]
57
+ @injector.configuration[:test_key].should == [ "one", "two" ]
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+
3
+ describe Configure::Sandbox do
4
+
5
+ before :each do
6
+ @injector = mock Configure::Injector, :put_arguments => nil, :put_block => nil
7
+ @sandbox = described_class.new @injector
8
+ end
9
+
10
+ it "should pass method calls without a block to the injector's :put_arguments" do
11
+ @injector.should_receive(:put_arguments).with(:test_key, [ "value" ])
12
+ @sandbox.test_key "value"
13
+ end
14
+
15
+ it "should pass method calls with a block to the injector's :put_block" do
16
+ block = Proc.new { }
17
+ @injector.should_receive(:put_block).with(:test_key, &block)
18
+ @sandbox.test_key &block
19
+ end
20
+
21
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe Configure do
4
+
5
+ before :each do
6
+ @block = Proc.new { }
7
+ end
8
+
9
+ describe "#process" do
10
+
11
+ before :each do
12
+ described_class.stub(:process_configuration)
13
+ end
14
+
15
+ it "should call :process_configuration" do
16
+ described_class.should_receive(:process_configuration).with(Hash, &@block)
17
+ described_class.process &@block
18
+ end
19
+
20
+ end
21
+
22
+ describe "#process_configuration" do
23
+
24
+ before :each do
25
+ @injector = mock described_class::Injector, :configuration => :configuration
26
+ described_class::Injector.stub :new => @injector
27
+
28
+ @sandbox = mock described_class::Sandbox, :instance_eval => nil
29
+ described_class::Sandbox.stub :new => @sandbox
30
+ end
31
+
32
+ it "should initialize the injector" do
33
+ described_class::Injector.should_receive(:new).with(Hash).and_return(@injector)
34
+ described_class.process_configuration Hash, &@block
35
+ end
36
+
37
+ it "should initialize the sandbox" do
38
+ described_class::Sandbox.should_receive(:new).with(@injector).and_return(@sandbox)
39
+ described_class.process_configuration Hash, &@block
40
+ end
41
+
42
+ it "should evaluate the block in the sandbox" do
43
+ @sandbox.should_receive(:instance_eval).with(&@block)
44
+ described_class.process_configuration Hash, &@block
45
+ end
46
+
47
+ it "should return the configuration" do
48
+ configuration = described_class.process_configuration Hash, &@block
49
+ configuration.should == :configuration
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>= 2'
3
+ require 'rspec'
4
+
5
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "configure"))
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: configure
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - "Philipp Br\xC3\xBCll"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-14 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "2"
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: reek
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "1.2"
36
+ type: :development
37
+ version_requirements: *id002
38
+ description: It provides a single-method interface that receives a block and returns well-structured configuration values.
39
+ email: b.phifty@gmail.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files:
45
+ - README.rdoc
46
+ files:
47
+ - README.rdoc
48
+ - LICENSE
49
+ - Rakefile
50
+ - lib/configure.rb
51
+ - lib/configure/injector.rb
52
+ - lib/configure/sandbox.rb
53
+ - spec/lib/configure_spec.rb
54
+ - spec/lib/configure/injector_spec.rb
55
+ - spec/lib/configure/sandbox_spec.rb
56
+ - spec/spec_helper.rb
57
+ - spec/acceptance/configure_spec.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/phifty/configure
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project: configure
82
+ rubygems_version: 1.6.1
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Configure offers an easy way for configure your application using a DSL.
86
+ test_files:
87
+ - spec/lib/configure_spec.rb
88
+ - spec/lib/configure/injector_spec.rb
89
+ - spec/lib/configure/sandbox_spec.rb
90
+ - spec/acceptance/configure_spec.rb