platonic_config 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage
6
+ doc
7
+ .yardoc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in platonic_config.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # Platonic Config
2
+ A mixin to allow easy class and instance level configuration, with easy
3
+ defaults.
4
+
5
+ ## Installation
6
+
7
+ ```shell
8
+ gem install platonic_config
9
+ ```
10
+
11
+ ## Example Usage
12
+
13
+ ```ruby
14
+ require 'platonic_config'
15
+ class MyAwesomeShirt
16
+ include PlatonicConfig
17
+ define_options :color => 'red', :size => 'large', :logo => nil
18
+ end
19
+
20
+ MyAwesomeShirt.color # => 'red'
21
+ MyAwesomeShirt.color 'blue'
22
+ MyAwesomeShirt.color # => 'blue'
23
+
24
+ MyAwesomeShirt.config do |c|
25
+ c.size 'large'
26
+ end
27
+
28
+ MyAwesomeShirt.size # => 'large'
29
+
30
+ shirt = MyAwesomeShirt.new
31
+
32
+ shirt.config do |c|
33
+ c.logo 'Batman'
34
+ c.size 'medium'
35
+ end
36
+
37
+ shirt.logo # => 'Batman'
38
+ shirt.options # => { :color => 'red', :size => 'medium', :logo => 'Batman' }
39
+
40
+ MyAwesomeShirt.reset_defaults
41
+ MyAwesomeShirt.options # => :color => 'red', :size => 'large', :logo => nil
42
+ another_shirt = MyAwesomeShirt.new
43
+ another_shirt.options # => :color => 'red', :size => 'large', :logo => nil
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ To start using PlatonicConfig, include the module in your class, and set
49
+ the default configuration values.
50
+
51
+ ```ruby
52
+ class C
53
+ include PlatonicConfig
54
+ define_options :opt1 => 'foo', :opt2 => 'bar'
55
+ end
56
+ ```
57
+
58
+ ### On the class
59
+
60
+ From this point on, your class will respond to all these configuration
61
+ options, and be able to be configured using a block.
62
+
63
+ ```ruby
64
+ C.config do |c|
65
+ c.opt1 'spam'
66
+ end
67
+ ```
68
+
69
+ Any individual option can be queried with the option name, or all
70
+ options can be looked at with "options".
71
+
72
+ ```ruby
73
+ C.opt1 # => 'spam'
74
+ C.options # => { :opt1 => 'foo', :opt2 => 'bar' }
75
+ ```
76
+
77
+ To reset configuration to the defaults you specified, call
78
+ reset_defaults.
79
+
80
+ ```ruby
81
+ C.reset_defaults
82
+ ```
83
+
84
+
85
+ ### On the instance
86
+
87
+ Any new instances of your class can be configured independently
88
+
89
+ ```ruby
90
+ instance = C.new
91
+ instance.config do |c|
92
+ c.opt2 'bananas'
93
+ end
94
+ ```
95
+
96
+ All options are merged with the options set in the class, with the
97
+ instance variables overriding. Any of these options can be queried
98
+ individually, or examined all at once.
99
+
100
+ ```ruby
101
+ instance.opt2 # => 'bananas'
102
+ instance.options # => { :opt1 => 'foo', :opt2 => 'bananas' }
103
+ ```
104
+
105
+ To clear the options set on the instance (and letting the class defaults
106
+ come through), call reset_defaults.
107
+
108
+ ```ruby
109
+ instance.reset_defaults
110
+ ```
111
+
112
+
113
+
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new do |t|
5
+ t.rspec_opts = ['--format nested --color']
6
+ end
7
+
8
+ desc "Run RSpec with code coverage"
9
+ task :coverage do
10
+ ENV['COVERAGE'] = "true"
11
+ Rake::Task["spec"].execute
12
+ end
13
+
14
+ task :default => :spec
15
+
16
+ begin
17
+ require 'yard'
18
+ YARD::Rake::YardocTask.new do |t|
19
+ t.files = %w(lib/**/*.rb)
20
+ end
21
+ rescue LoadError
22
+ task :yard do
23
+ abort "YARD is not available. In order to run yard, you must: gem install yard"
24
+ end
25
+ end
@@ -0,0 +1,103 @@
1
+ require "platonic_config/version"
2
+
3
+
4
+ module PlatonicConfig
5
+
6
+ # Give the options defined on the instance merged with the class-level defaults
7
+ def options
8
+ self.class.options.merge instance_options
9
+ end
10
+
11
+ # return just the options set on the instance
12
+ def instance_options
13
+ @options ||= {}
14
+ end
15
+
16
+ # convenience method to allow for block level configuration
17
+ def configure
18
+ yield self
19
+ self
20
+ end
21
+ alias config configure
22
+
23
+ # Set up configuration methodss on the base class
24
+ def self.included(base)
25
+ base.extend ClassMethods
26
+ end
27
+
28
+ # Allow calls directly on the object to configuration keys
29
+ # Ex: define_options :foo => bar
30
+ # instance.foo
31
+ def method_missing(sym,*args,&block)
32
+ if self.class.options.has_key? sym
33
+ if args.length == 1
34
+ instance_options[sym] = args[0]
35
+ end
36
+ options[sym]
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ # Let respond_to? answer for symbols defined in the options
43
+ def respond_to?(sym)
44
+ if self.class.options.has_key? sym
45
+ true
46
+ else
47
+ super
48
+ end
49
+ end
50
+
51
+ # Reset all config values set on the instance
52
+ def reset_defaults
53
+ @options = {}
54
+ end
55
+
56
+ module ClassMethods
57
+ # Define the options and defaults for this coniguration
58
+ def define_options(options = {})
59
+ @default_options = options
60
+ reset_defaults
61
+ end
62
+
63
+ # return the set of configured options
64
+ def options
65
+ @options
66
+ end
67
+
68
+ # set all configured options back to their default values
69
+ def reset_defaults
70
+ @options = @default_options.dup
71
+ end
72
+
73
+ # Allow calls directly on the object to configuration keys
74
+ # Ex: define_options :foo => bar
75
+ # Class.foo
76
+ def method_missing(sym,*args,&block)
77
+ if @options.has_key? sym
78
+ if args.length == 1
79
+ @options[sym] = args[0]
80
+ end
81
+ @options[sym]
82
+ else
83
+ super
84
+ end
85
+ end
86
+
87
+ # Let respond_to? answer for symbols defined in the options
88
+ def respond_to?(sym)
89
+ if @options.has_key? sym
90
+ true
91
+ else
92
+ super
93
+ end
94
+ end
95
+
96
+ # convenience method to allow for block level configuration
97
+ def configure
98
+ yield self
99
+ self
100
+ end
101
+ alias config configure
102
+ end
103
+ end
@@ -0,0 +1,5 @@
1
+ # Placeholder module for versioning
2
+ module PlatonicConfig
3
+ # Version of the module
4
+ VERSION = "0.1.1"
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "platonic_config/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "platonic_config"
7
+ s.version = PlatonicConfig::VERSION
8
+ s.authors = ["Ryan Sorensen"]
9
+ s.email = ["rcsorensen@gmail.com"]
10
+ s.homepage = "http://github.com/rcs/platonic_config"
11
+ s.summary = %q{Easy per class and per instance configuration}
12
+ s.description = %q{Platonic makes it easy to stop worrying about the implementation details of class configuration}
13
+
14
+ s.rubyforge_project = "platonic_config"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "simplecov"
22
+ s.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "PlatonicConfig" do
4
+ describe "basic use" do
5
+ it "can be mixed in" do
6
+ expect {
7
+ Class.new.send(:include, PlatonicConfig)
8
+ }.to_not raise_error
9
+ end
10
+ end
11
+ describe "on the class" do
12
+ before :each do
13
+ @klass = Class.new do
14
+ include PlatonicConfig
15
+ define_options :color => nil, :size => nil
16
+ end
17
+ end
18
+
19
+ it "exposes the config methods" do
20
+ @klass.respond_to? :color
21
+ end
22
+
23
+ it "doesn't bork method_missing" do
24
+ expect {
25
+ @klass.not_a_method
26
+ }.to raise_error NoMethodError
27
+ end
28
+
29
+ it "doesn't bork respond_to?" do
30
+ @klass.respond_to?(:not_a_method).should_not be_true
31
+ end
32
+
33
+ it "returns a hash of the options" do
34
+ @klass.options.should == { :color => nil, :size => nil }
35
+ end
36
+
37
+ it "exposes the config methods in the instance" do
38
+ @klass.new.respond_to? :color
39
+ end
40
+
41
+ it "stores configuration values" do
42
+ @klass.color "red"
43
+ @klass.color.should == "red"
44
+ end
45
+
46
+ it "resets configuration values" do
47
+ @klass.color "red"
48
+ @klass.reset_defaults
49
+ @klass.color.should be_nil
50
+ end
51
+
52
+ it "exposes options in instances" do
53
+ @klass.new.options.should == { :color => nil, :size => nil }
54
+ end
55
+
56
+ it "exposes class values in instances" do
57
+ @klass.color "red"
58
+ @klass.new.color.should == "red"
59
+ end
60
+
61
+ it "can be configured with a block" do
62
+ @klass.config do |c|
63
+ c.color "chartreuse"
64
+ end
65
+
66
+ @klass.color.should == "chartreuse"
67
+ end
68
+
69
+ describe "for the instance" do
70
+ before :each do
71
+ @instance = @klass.new
72
+ end
73
+
74
+ it "allows overriding in instances" do
75
+ @klass.color "red"
76
+ @instance.color "blue"
77
+ @instance.color.should == "blue"
78
+ end
79
+
80
+ it "merges options in instances" do
81
+ @klass.color "red"
82
+ @instance.size "large"
83
+ @instance.options.should == { :color => "red", :size => "large" }
84
+ end
85
+
86
+ it "doesn't allow different instances to effect each other" do
87
+ a = @klass.new
88
+ a.color "brown"
89
+ b = @klass.new
90
+ b.color "black"
91
+ a.color.should == "brown"
92
+ b.color.should == "black"
93
+ end
94
+ it "can be configured with a block" do
95
+ @instance.config do |c|
96
+ c.size "middling"
97
+ end
98
+ @instance.size.should == "middling"
99
+ end
100
+
101
+ it "resets only instance values" do
102
+ @klass.color 'crimson'
103
+ @instance.color 'vermillion'
104
+ @instance.color.should == 'vermillion'
105
+ @instance.reset_defaults
106
+ @instance.color.should == 'crimson'
107
+ end
108
+
109
+ it "doesn't bork method_missing" do
110
+ expect {
111
+ @instance.not_a_method
112
+ }.to raise_error NoMethodError
113
+ end
114
+
115
+ it "doesn't bork respond_to?" do
116
+ @instance.respond_to?(:not_a_method).should_not be_true
117
+ end
118
+
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,9 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ end if ENV['COVERAGE']
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'rspec'
9
+ require 'platonic_config'
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: platonic_config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Sorensen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-24 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: simplecov
16
+ requirement: &70133964734180 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70133964734180
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70133964733760 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70133964733760
36
+ description: Platonic makes it easy to stop worrying about the implementation details
37
+ of class configuration
38
+ email:
39
+ - rcsorensen@gmail.com
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - README.md
47
+ - Rakefile
48
+ - lib/platonic_config.rb
49
+ - lib/platonic_config/version.rb
50
+ - platonic_config.gemspec
51
+ - spec/platonic_config_spec.rb
52
+ - spec/spec_helper.rb
53
+ homepage: http://github.com/rcs/platonic_config
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project: platonic_config
73
+ rubygems_version: 1.8.6
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Easy per class and per instance configuration
77
+ test_files:
78
+ - spec/platonic_config_spec.rb
79
+ - spec/spec_helper.rb