configurator2 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --backtrace
2
+ --colour
3
+
data/Guardfile ADDED
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara request specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Configurator
2
+ ## Add simple configuration to any Ruby class
3
+
4
+ ### Installation
5
+ 1. Add `gem 'configurator2'` to your Gemfile
6
+ 2. Run `bundle`
7
+ 3. Profit
8
+
9
+ ### Usage
10
+
11
+ #### Mix into any Ruby class and add options
12
+ ```ruby
13
+ class Application
14
+ extend Configurator
15
+ option :api_url, "https://www.myapp.com/api/v1"
16
+ options :format, :mode, :whatevs
17
+ end
18
+ ```
19
+
20
+ This will add `Application.config.api_url`, which will be overridable but default
21
+ to `https://www.myapp.com/api/v1`. It also adds a number of options without
22
+ defaults, namely `format`, `mode`, and `whatevs`.
23
+
24
+ Every call to `option` or `options` adds getters and setters for these options,
25
+ but you can also use the alternate syntax by ommitting the equals sign when setting
26
+ an option.
27
+
28
+ #### Configure your class
29
+ Configurator supports three different interfaces and two setter methods:
30
+
31
+ ##### Block configuration with implicit configuration object
32
+ ```ruby
33
+ Application.config do
34
+ api_url "https://www.some.other.app/api/v2"
35
+ format :json
36
+ end
37
+ ```
38
+
39
+ ##### Block configuration with passed configuration object
40
+ ```ruby
41
+ Application.config do |config|
42
+ config.api_url = "https://www.some.other.app/api/v2"
43
+ config.format = :json
44
+ end
45
+ ```
46
+
47
+ ##### Direct configuration
48
+ ```ruby
49
+ Application.config.api_url = "https://www.some.other.app/api/v2"
50
+ Application.config.format = :json
51
+ ```
52
+
53
+ OR omit the equals operators:
54
+
55
+ ```ruby
56
+ Application.config.mode :production
57
+ ```
58
+
59
+ #### Sub-configurations
60
+ Adding a sub-configuration is simple, too, like so:
61
+
62
+ ```ruby
63
+ class Application
64
+ extend Configurator
65
+ option :smtp_server do
66
+ options :host, :port, :password, :username
67
+ end
68
+ end
69
+ ```
70
+
71
+ Now, you can refer to an Application's smtp_server configuration like so:
72
+
73
+ ```ruby
74
+ Application.config.smtp_server.host
75
+ Application.config.smtp_server.port
76
+ # etc
77
+ ```
78
+
79
+ You can also configure a group of configuration options as a hash:
80
+
81
+ ```ruby
82
+ Application.config.smtp_server = {
83
+ host: "smtp.host.com",
84
+ port: "3306",
85
+ username: "user",
86
+ password: "pass"
87
+ }
88
+ ```
89
+
90
+ #### Observe your users' configuration choices later
91
+
92
+ Just refer to a class or module's configuration setting later, pretty simply:
93
+
94
+ ```ruby
95
+ if Application.config.smtp_server.host
96
+ Mailer.send_email_with_options(Application.config.smtp_server)
97
+ end
98
+ ```
99
+
100
+ Or whatever.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gemspec|
6
+ gemspec.name = "configurator2"
7
+ gemspec.summary = "A mixin to add a .config method and options with defaults to any library"
8
+ gemspec.description = %{}
9
+ gemspec.email = "flip@getplinq.com"
10
+ gemspec.homepage = "http://github.com/Plinq/configurator"
11
+ gemspec.authors = ["Flip Sasser"]
12
+ end
13
+ rescue LoadError
14
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,45 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "configurator2"
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Flip Sasser"]
12
+ s.date = "2013-01-02"
13
+ s.description = ""
14
+ s.email = "flip@getplinq.com"
15
+ s.extra_rdoc_files = [
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".rspec",
20
+ "Guardfile",
21
+ "README.md",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "configurator2.gemspec",
25
+ "lib/configurator.rb",
26
+ "lib/configurator/configuration.rb",
27
+ "lib/configurator/option.rb",
28
+ "spec/lib/configurator_spec.rb",
29
+ "spec/spec_helper.rb"
30
+ ]
31
+ s.homepage = "http://github.com/Plinq/configurator"
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = "1.8.24"
34
+ s.summary = "A mixin to add a .config method and options with defaults to any library"
35
+
36
+ if s.respond_to? :specification_version then
37
+ s.specification_version = 3
38
+
39
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
+ else
41
+ end
42
+ else
43
+ end
44
+ end
45
+
@@ -0,0 +1,59 @@
1
+ require 'configurator/option'
2
+
3
+ module Configurator
4
+ class Configuration < Hash
5
+ include Option
6
+
7
+ def add_option(name, default, &block)
8
+ defaults[name.to_sym] = default || block
9
+ end
10
+
11
+ def config
12
+ self
13
+ end
14
+
15
+ def defaults
16
+ @defaults ||= {}
17
+ end
18
+
19
+ def initialize(options = {})
20
+ options.each do |key, value|
21
+ set(key, value)
22
+ end
23
+ end
24
+
25
+ def get(name)
26
+ name = name.to_sym
27
+ value = self.key?(name) ? self[name] : defaults[name]
28
+ if value.respond_to? :call
29
+ value = value.call
30
+ end
31
+ value
32
+ end
33
+
34
+ def set(name, value, &block)
35
+ name = name.to_sym
36
+ if block_given?
37
+ self[name] = block
38
+ elsif value.is_a?(Hash)
39
+ self[name] = defaults[name] || self.class.new
40
+ value.each do |key, value_two|
41
+ self[name].send("#{key}=", value_two)
42
+ end
43
+ else
44
+ self[name] = value
45
+ end
46
+ end
47
+
48
+ private
49
+ def method_missing(method, *args, &block)
50
+ method_name = method.to_s
51
+ setter = method_name.chomp!('=') || !args.empty? || block_given?
52
+ if setter
53
+ set(method_name, args.first, &block)
54
+ else
55
+ get(method)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ module Configurator
2
+ module Option
3
+ def option(name, default = nil, &block)
4
+ config.add_option(name, block_given? ? Configuration.new : default)
5
+ if block_given?
6
+ config.get(name).instance_exec(config.get(name), &block)
7
+ end
8
+ end
9
+ private :option
10
+
11
+ def options(*names)
12
+ names.each {|name| option(name) }
13
+ end
14
+ private :options
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'configurator/option'
2
+
3
+ module Configurator
4
+ autoload :Configuration, 'configurator/configuration'
5
+ include Option
6
+
7
+ def self.extended(base)
8
+ base.class_eval { remove_instance_variable(:@configuration) if defined? @configuration }
9
+ end
10
+
11
+ def config(&block)
12
+ @configuration ||= Configuration.new
13
+ if block_given?
14
+ @configuration.instance_exec(@configuration, &block)
15
+ end
16
+ @configuration
17
+ end
18
+ end
@@ -0,0 +1,141 @@
1
+ require 'configurator'
2
+
3
+ describe Configurator do
4
+ it "extends objects without exploding" do
5
+ lambda {
6
+ class FooBar
7
+ extend Configurator
8
+ end
9
+ }.should_not raise_error
10
+ end
11
+
12
+ describe "mixed into a class" do
13
+ before do
14
+ class TestClass
15
+ extend Configurator
16
+ end
17
+ end
18
+
19
+ it "defines a `config` method" do
20
+ TestClass.should respond_to(:config)
21
+ end
22
+
23
+ describe "adds a `config` method that" do
24
+ it "accepts a block" do
25
+ lambda {
26
+ TestClass.config { inspect }
27
+ }.should_not raise_error
28
+ end
29
+
30
+ it "executes the block in the context of the configured class' new configuration instance" do
31
+ TestClass.config.should_receive(:puts).and_return(nil)
32
+ TestClass.config { puts "ohai" }
33
+ end
34
+ end
35
+
36
+ describe "adds an `option` method that" do
37
+ it "allows developers to declare class-level options" do
38
+ TestClass.send(:option, :do_something)
39
+ TestClass.config.defaults.key?(:do_something).should be_true
40
+ end
41
+
42
+ it "allows developers to declare defaults on options" do
43
+ TestClass.send(:option, :do_something, true)
44
+ TestClass.config.defaults[:do_something].should be_true
45
+ end
46
+
47
+ it "defines getter methods on the config class method" do
48
+ TestClass.send(:option, :do_something)
49
+ TestClass.config.do_something.should be_nil
50
+ end
51
+
52
+ it "defines setter methods on the class" do
53
+ TestClass.send(:option, :do_something)
54
+ lambda { TestClass.config.do_something = "ohai" }.should_not raise_error
55
+ end
56
+
57
+ describe "that adds a class-level accessor that" do
58
+ it "returns default values when a developer has not overriden it" do
59
+ TestClass.send(:option, :do_something, "now!")
60
+ TestClass.config.do_something.should == "now!"
61
+ end
62
+
63
+ it "returns overriden values when a developer has overriden them" do
64
+ TestClass.send(:option, :do_something, "now!")
65
+ TestClass.config do
66
+ do_something "later..."
67
+ end
68
+ TestClass.config.do_something.should == "later..."
69
+ end
70
+
71
+ it "uses a lambda to defer processing until it's called" do
72
+ TestClass.send(:option, :payment_method, lambda {
73
+ defined?(Paypal) ? :paypal : :plinq
74
+ })
75
+ TestClass.config.payment_method.should == :plinq
76
+ end
77
+
78
+ it "returns nil when a value is explicitly nil" do
79
+ TestClass.send(:option, :current_user_method, :current_user)
80
+ TestClass.config.current_user_method.should == :current_user
81
+ #TestClass.config.current_user_method = nil
82
+ TestClass.config do
83
+ current_user_method nil
84
+ end
85
+ TestClass.config.current_user_method.should be_nil
86
+ end
87
+ it "accepts a setter format" do
88
+ TestClass.send(:option, :do_something, "now!")
89
+ TestClass.config.do_something = "later..."
90
+ TestClass.config.do_something.should == "later..."
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '#option with sub-options' do
96
+ before :each do
97
+ TestClass.send(:option, :advanced_options) do
98
+ option :bitrate, 1024
99
+ option :fps, 30
100
+ end
101
+ end
102
+
103
+ it "accepts a block that creates a sub-configuration" do
104
+ TestClass.config.advanced_options.bitrate.should == 1024
105
+ TestClass.config.advanced_options.fps.should == 30
106
+ end
107
+
108
+ it "accepts a hash that for a sub-configuration" do
109
+ TestClass.config.advanced_options = {
110
+ bitrate: 2000,
111
+ fps: 60
112
+ }
113
+ TestClass.config.advanced_options.bitrate.should == 2000
114
+ TestClass.config.advanced_options.fps.should == 60
115
+ end
116
+
117
+ it "doesn't overwrite a defaults hash if you set one value but not the other" do
118
+ TestClass.config.advanced_options = {bitrate: 2000}
119
+ TestClass.config.advanced_options.bitrate.should == 2000
120
+ TestClass.config.advanced_options.fps.should == 30
121
+ end
122
+
123
+ it "accepts even MORE options below the other ones, yo" do
124
+ TestClass.send(:option, :sub) do
125
+ option(:name, :face)
126
+ option(:sub) do
127
+ option(:name, :fiz)
128
+ end
129
+ end
130
+ TestClass.config.sub.name.should == :face
131
+ TestClass.config.sub.sub.name.should == :fiz
132
+ end
133
+ end
134
+
135
+ it "adds an `options` method that defines many options with default nil values" do
136
+ TestClass.should_receive(:option).once.with(:host)
137
+ TestClass.should_receive(:option).once.with(:api_key)
138
+ TestClass.send :options, :host, :api_key
139
+ end
140
+ end
141
+ end
@@ -0,0 +1 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: configurator2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Flip Sasser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ''
15
+ email: flip@getplinq.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - README.md
20
+ files:
21
+ - .rspec
22
+ - Guardfile
23
+ - README.md
24
+ - Rakefile
25
+ - VERSION
26
+ - configurator2.gemspec
27
+ - lib/configurator.rb
28
+ - lib/configurator/configuration.rb
29
+ - lib/configurator/option.rb
30
+ - spec/lib/configurator_spec.rb
31
+ - spec/spec_helper.rb
32
+ homepage: http://github.com/Plinq/configurator
33
+ licenses: []
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 1.8.24
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: A mixin to add a .config method and options with defaults to any library
56
+ test_files: []