configuratron 0.0.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 +5 -0
- data/.travis.yml +6 -0
- data/Gemfile +11 -0
- data/Guardfile +8 -0
- data/Rakefile +8 -0
- data/configuratron.gemspec +21 -0
- data/lib/configuratron.rb +76 -0
- data/lib/configuratron/blank_slate.rb +75 -0
- data/spec/configuratron/config_hash_spec.rb +93 -0
- data/spec/configuratron/configurable_spec.rb +41 -0
- data/spec/configuratron/configuratron_spec.rb +29 -0
- data/spec/spec_helper.rb +7 -0
- metadata +106 -0
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2, :cli => "--color --format nested", :rvm => ['1.8.7', '1.9.2'] do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { "spec" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "configuratron"
|
5
|
+
s.version = "0.0.1"
|
6
|
+
s.authors = ["Grzesiek Kolodziejczyk"]
|
7
|
+
s.email = ["gkolodziejczyk@gmail.com"]
|
8
|
+
s.homepage = "https://github.com/grk/configuratron"
|
9
|
+
s.summary = %q{Configuration storage library}
|
10
|
+
s.description = %q{Configuration storage library for Ruby with metaprogramming magic. Allows for hash-like and method-based key access.}
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec", ">= 2.6.0"
|
18
|
+
s.add_development_dependency "guard-rspec"
|
19
|
+
s.add_development_dependency "rake", ">= 0.9.2"
|
20
|
+
s.add_development_dependency "bundler"
|
21
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "configuratron/blank_slate"
|
2
|
+
|
3
|
+
class Configuratron < BlankSlate
|
4
|
+
def initialize
|
5
|
+
@config = ConfigHash.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
@config[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(key, value)
|
13
|
+
@config[key] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(name, *args, &block)
|
17
|
+
@config.__send__(name, *args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
module Configurable
|
21
|
+
def config
|
22
|
+
@config ||= Configuratron.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ConfigHash < BlankSlate
|
27
|
+
def initialize(hash = nil)
|
28
|
+
@hash = {}
|
29
|
+
if hash
|
30
|
+
hash.each do |k,v|
|
31
|
+
@hash[k] = v.is_a?(Hash) ? ConfigHash.new(v) : v
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def []=(k, v)
|
37
|
+
@hash[k] = v.is_a?(Hash) ? ConfigHash.new(v) : v
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](k)
|
41
|
+
@hash[k]
|
42
|
+
end
|
43
|
+
|
44
|
+
def method_missing(name, *args, &block)
|
45
|
+
if name.to_s[-1..-1] == '=' # workaround for 1.8 returning char
|
46
|
+
base_name = name.to_s[0..-2].to_sym
|
47
|
+
_define_singleton_method(name) do |name|
|
48
|
+
__send__ :[]=, base_name, value
|
49
|
+
end
|
50
|
+
__send__ :[]=, base_name, *args
|
51
|
+
else
|
52
|
+
_define_singleton_method(name) do
|
53
|
+
__send__ :[], name.to_sym
|
54
|
+
end
|
55
|
+
__send__ :[], name.to_sym
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def _singleton_class
|
61
|
+
class << self
|
62
|
+
self
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def _singleton_exec(*args, &block)
|
67
|
+
_singleton_class.instance_exec(*args, &block)
|
68
|
+
end
|
69
|
+
|
70
|
+
def _define_singleton_method(name, &block)
|
71
|
+
_singleton_exec(name) do |name|
|
72
|
+
define_method(name, &block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class BlankSlate
|
2
|
+
class << self
|
3
|
+
|
4
|
+
# Hide the method named +name+ in the BlankSlate class. Don't
|
5
|
+
# hide +instance_eval+ or any method beginning with "__".
|
6
|
+
def hide(name)
|
7
|
+
if instance_methods.include?(name) and name.to_s !~ /^(__|instance_eval|object_id)/
|
8
|
+
@hidden_methods ||= {}
|
9
|
+
@hidden_methods[name] = instance_method(name)
|
10
|
+
undef_method name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_hidden_method(name)
|
15
|
+
@hidden_methods ||= {}
|
16
|
+
@hidden_methods[name] || (superclass.find_hidden_method(name) if superclass.respond_to?(:find_hidden_method))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Redefine a previously hidden method so that it may be called on a blank
|
20
|
+
# slate object.
|
21
|
+
def reveal(name)
|
22
|
+
unbound_method = find_hidden_method(name)
|
23
|
+
fail "Don't know how to reveal method '#{name}'" unless unbound_method
|
24
|
+
define_method(name, unbound_method)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
instance_methods.each { |m| hide(m) }
|
29
|
+
end
|
30
|
+
|
31
|
+
module Kernel
|
32
|
+
class << self
|
33
|
+
alias_method :blank_slate_method_added, :method_added
|
34
|
+
|
35
|
+
# Detect method additions to Kernel and remove them in the
|
36
|
+
# BlankSlate class.
|
37
|
+
def method_added(name)
|
38
|
+
result = blank_slate_method_added(name)
|
39
|
+
return result if self != Kernel
|
40
|
+
BlankSlate.hide(name)
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Object
|
47
|
+
class << self
|
48
|
+
alias_method :blank_slate_method_added, :method_added
|
49
|
+
|
50
|
+
# Detect method additions to Object and remove them in the
|
51
|
+
# BlankSlate class.
|
52
|
+
def method_added(name)
|
53
|
+
result = blank_slate_method_added(name)
|
54
|
+
return result if self != Object
|
55
|
+
BlankSlate.hide(name)
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_hidden_method(name)
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Module
|
66
|
+
alias blankslate_original_append_features append_features
|
67
|
+
def append_features(mod)
|
68
|
+
result = blankslate_original_append_features(mod)
|
69
|
+
return result if mod != Object
|
70
|
+
instance_methods.each do |name|
|
71
|
+
BlankSlate.hide(name)
|
72
|
+
end
|
73
|
+
result
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Configuratron::ConfigHash do
|
4
|
+
%w(instance_variable_get is_a? methods).each do |m|
|
5
|
+
if RUBY18
|
6
|
+
Configuratron::ConfigHash.reveal(m)
|
7
|
+
else
|
8
|
+
Configuratron::ConfigHash.reveal(m.to_sym)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
|
13
|
+
Configuratron::ConfigHash.reveal("singleton_methods")
|
14
|
+
Configuratron::ConfigHash.reveal("kind_of?")
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
@ch = Configuratron::ConfigHash.new
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when created" do
|
22
|
+
it "should be empty" do
|
23
|
+
@ch.instance_variable_get(:@hash).should be_empty
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "keys" do
|
28
|
+
it "should return nil for missing key" do
|
29
|
+
@ch[:missing_key].should be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should set value for new key" do
|
33
|
+
@ch[:new_key] = :value
|
34
|
+
@ch.instance_variable_get(:@hash)[:new_key].should eql(:value)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return value for existing key" do
|
38
|
+
@ch.instance_variable_get(:@hash)[:existing_key] = :value
|
39
|
+
@ch[:existing_key].should eql(:value)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "method access" do
|
44
|
+
it "should return nil for missing key" do
|
45
|
+
@ch.missing_key.should be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should set value for new key" do
|
49
|
+
@ch.new_key = :value
|
50
|
+
@ch.instance_variable_get(:@hash)[:new_key].should eql(:value)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return value for existing key" do
|
54
|
+
@ch.instance_variable_get(:@hash)[:existing_key] = :value
|
55
|
+
@ch.existing_key.should eql(:value)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "hash keys" do
|
60
|
+
it "should convert hash keys to self class" do
|
61
|
+
@ch[:hash_key] = {:new => :hash}
|
62
|
+
@ch[:hash_key].should be_a(Configuratron::ConfigHash)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should convert nested hash keys recursively" do
|
66
|
+
@ch[:nested_hash] = {:root => {:nested => :value}}
|
67
|
+
@ch[:nested_hash].should be_a(Configuratron::ConfigHash)
|
68
|
+
@ch[:nested_hash][:root].should be_a(Configuratron::ConfigHash)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should access nested hash keys by methods" do
|
72
|
+
@ch.nested_hash = {:root => {:nested => :value}}
|
73
|
+
@ch.nested_hash.should be_a(Configuratron::ConfigHash)
|
74
|
+
@ch.nested_hash.root.should be_a(Configuratron::ConfigHash)
|
75
|
+
@ch.nested_hash.root.nested.should eql(:value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "defining methods on method_missing" do
|
80
|
+
it "should not have instance methods defined before first call" do
|
81
|
+
@ch.methods.should_not include(RUBY18 ? "test_key" : :test_key)
|
82
|
+
@ch.methods.should_not include(RUBY18 ? "test_key=" : :test_key=)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have instance methods defined after first call" do
|
86
|
+
@ch.test_key
|
87
|
+
@ch.methods.should include(RUBY18 ? "test_key" : :test_key)
|
88
|
+
|
89
|
+
@ch.test_key = :value
|
90
|
+
@ch.methods.should include(RUBY18 ? "test_key=" : :test_key=)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Configuratron::Configurable do
|
4
|
+
context "included" do
|
5
|
+
class A
|
6
|
+
include Configuratron::Configurable
|
7
|
+
end
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
@a = A.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should define config for instances" do
|
14
|
+
@a.should respond_to(:config)
|
15
|
+
@a.config.should be_a(Configuratron)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not define config for class" do
|
19
|
+
A.should_not respond_to(:config)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "extended" do
|
24
|
+
class B
|
25
|
+
extend Configuratron::Configurable
|
26
|
+
end
|
27
|
+
|
28
|
+
before(:all) do
|
29
|
+
@b = B.new
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not define config for instances" do
|
33
|
+
@b.should_not respond_to(:config)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should define config for class" do
|
37
|
+
B.should respond_to(:config)
|
38
|
+
B.config.should be_a(Configuratron)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Configuratron do
|
4
|
+
before(:each) do
|
5
|
+
@c = Configuratron.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context "hash-like access" do
|
9
|
+
it "should return nil for missing keys" do
|
10
|
+
@c[:key].should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should set value for new keys" do
|
14
|
+
@c[:key] = :value
|
15
|
+
@c[:key].should eql(:value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "method access" do
|
20
|
+
it "should return nil for missing keys" do
|
21
|
+
@c.key.should be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set value for new keys" do
|
25
|
+
@c.key = :value
|
26
|
+
@c.key.should eql(:value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: configuratron
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Grzesiek Kolodziejczyk
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-06-11 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &2156046840 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.6.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2156046840
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: guard-rspec
|
27
|
+
requirement: &2156045780 !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: *2156045780
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &2156044960 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.2
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2156044960
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: &2156044360 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2156044360
|
58
|
+
description: Configuration storage library for Ruby with metaprogramming magic. Allows
|
59
|
+
for hash-like and method-based key access.
|
60
|
+
email:
|
61
|
+
- gkolodziejczyk@gmail.com
|
62
|
+
executables: []
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- .gitignore
|
67
|
+
- .travis.yml
|
68
|
+
- Gemfile
|
69
|
+
- Guardfile
|
70
|
+
- Rakefile
|
71
|
+
- configuratron.gemspec
|
72
|
+
- lib/configuratron.rb
|
73
|
+
- lib/configuratron/blank_slate.rb
|
74
|
+
- spec/configuratron/config_hash_spec.rb
|
75
|
+
- spec/configuratron/configurable_spec.rb
|
76
|
+
- spec/configuratron/configuratron_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
homepage: https://github.com/grk/configuratron
|
79
|
+
licenses: []
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 1.8.5
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: Configuration storage library
|
102
|
+
test_files:
|
103
|
+
- spec/configuratron/config_hash_spec.rb
|
104
|
+
- spec/configuratron/configurable_spec.rb
|
105
|
+
- spec/configuratron/configuratron_spec.rb
|
106
|
+
- spec/spec_helper.rb
|