platonic_config 0.1.1

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/.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