configurator2 0.1.2

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/.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: []