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 +7 -0
- data/Gemfile +4 -0
- data/README.md +113 -0
- data/Rakefile +25 -0
- data/lib/platonic_config.rb +103 -0
- data/lib/platonic_config/version.rb +5 -0
- data/platonic_config.gemspec +23 -0
- data/spec/platonic_config_spec.rb +121 -0
- data/spec/spec_helper.rb +9 -0
- metadata +79 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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,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
|
data/spec/spec_helper.rb
ADDED
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
|