configatron 3.2.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/History.txt +26 -0
- data/Rakefile +8 -4
- data/configatron.gemspec +1 -0
- data/lib/configatron.rb +22 -3
- data/lib/configatron/core.rb +6 -6
- data/lib/configatron/deep_clone.rb +9 -6
- data/lib/configatron/ext/kernel.rb +5 -0
- data/lib/configatron/integrations.rb +7 -0
- data/lib/configatron/integrations/minitest.rb +29 -0
- data/lib/configatron/{rails.rb → integrations/rails.rb} +1 -1
- data/lib/configatron/root_store.rb +52 -0
- data/lib/configatron/store.rb +51 -56
- data/lib/configatron/version.rb +1 -1
- data/lib/generators/configatron/install/templates/initializers/configatron.rb +1 -1
- data/test/_lib.rb +17 -0
- data/test/functional/_lib.rb +10 -0
- data/test/functional/_lib/scripts/core.rb +11 -0
- data/test/functional/configatron.rb +76 -0
- data/test/functional/loading.rb +10 -0
- data/test/unit/_lib.rb +10 -0
- data/test/unit/configatron/proc.rb +24 -0
- data/test/unit/configatron/root_store.rb +20 -0
- data/test/unit/configatron/store.rb +149 -0
- metadata +41 -15
- data/lib/configatron/kernel.rb +0 -21
- data/test/configatron/kernel_test.rb +0 -24
- data/test/configatron/proc_test.rb +0 -27
- data/test/configatron/store_test.rb +0 -256
- data/test/configatron_test.rb +0 -5
- data/test/test_helper.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ade0eaacbaca6d1751e811972975ce00ccd7336e
|
4
|
+
data.tar.gz: 37087c12805c28940771cf27746b1c1858c115a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 901770f4fa820125723c7b4631cad49b74da6e0b4c0f44ff7f1dda511f172b7da947ae6e630dca94f3c7d0fb9a4282cf688d5bc01f76a94d654ad5e0ee4c4992
|
7
|
+
data.tar.gz: 9c6c28a946279c0cff614b99ce8a676f9c71039a7c9b70cbd4256b2c4d9ac8d6aeb7ab15728efd0777a94fca20bfd1312a703ab219d5638d2004f8024bc8a313
|
data/.travis.yml
CHANGED
data/History.txt
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
=== 4.0.0 (WIP)
|
2
|
+
|
3
|
+
This is largely a restructuring of existing functionality, making it
|
4
|
+
simpler and more consistent. The tests have also been fully
|
5
|
+
refactored.
|
6
|
+
|
7
|
+
Added the following:
|
8
|
+
|
9
|
+
* A Minitest integration at Configatron::Integrations::Minitest
|
10
|
+
* Key errors while locked return the name of the relevant configatron
|
11
|
+
* Configatron::RootStore is now the intended way to start a new configatron hiearchy. (You should likely not initialize a Configatron::Store yourself.)
|
12
|
+
|
13
|
+
Deprecated the following:
|
14
|
+
|
15
|
+
* Initializing a Configatron::Store with a custom hash
|
16
|
+
* Calling .nil?/.empty? on a Configatron::Store
|
17
|
+
* Calling locking, temp, or reset methods directly on a Configatron::Store (moved instead to Configatron::RootStore)
|
18
|
+
* A DeepClone module is no longer defined at the top-level
|
19
|
+
* Removed Configatron::KernelStore
|
20
|
+
|
21
|
+
Other backwards-incompatible changes:
|
22
|
+
|
23
|
+
* Renamespaced Configatron::Rails under Configatron::Integrations::Rails.
|
24
|
+
* Moved locking and temp methods to exist just on Configatron::RootStore.
|
25
|
+
* Configatron::Store.inspect no longer takes a name
|
26
|
+
* key? will now return true for sub-Configatron::Stores
|
data/Rakefile
CHANGED
@@ -3,7 +3,11 @@ require 'rake/testtask'
|
|
3
3
|
|
4
4
|
Bundler::GemHelper.install_tasks
|
5
5
|
|
6
|
-
Rake::TestTask.new
|
7
|
-
t.libs
|
8
|
-
t.
|
9
|
-
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs = ["lib"]
|
8
|
+
# t.warning = true
|
9
|
+
t.verbose = true
|
10
|
+
t.test_files = FileList['test/**/*.rb'].reject do |file|
|
11
|
+
file.end_with?('_lib.rb') || file.include?('/_lib/')
|
12
|
+
end
|
13
|
+
end
|
data/configatron.gemspec
CHANGED
data/lib/configatron.rb
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'configatron/version'
|
3
|
-
|
4
|
-
require 'configatron/
|
5
|
-
require 'configatron/
|
3
|
+
|
4
|
+
require 'configatron/deep_clone'
|
5
|
+
require 'configatron/errors'
|
6
|
+
require 'configatron/root_store'
|
7
|
+
require 'configatron/store'
|
8
|
+
|
9
|
+
# Proc *must* load before dynamic/delayed, or else Configatron::Proc
|
10
|
+
# will refer to the global ::Proc
|
11
|
+
require 'configatron/proc'
|
12
|
+
require 'configatron/delayed'
|
13
|
+
require 'configatron/dynamic'
|
14
|
+
|
15
|
+
class Configatron
|
16
|
+
end
|
17
|
+
|
18
|
+
# NO_EXT gets defined when you require "configatron/core", which
|
19
|
+
# signals that you don't want any extensions. It'd be nice to have a
|
20
|
+
# better internal signaling mechanism (could use environment
|
21
|
+
# variables, but then they become part of the public interface).
|
22
|
+
unless defined?(Configatron::NO_EXT)
|
23
|
+
require 'configatron/ext/kernel'
|
24
|
+
end
|
data/lib/configatron/core.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
class Configatron
|
2
|
+
# Signals that we should not load the extensions.
|
3
|
+
NO_EXT = true
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'configatron'
|
@@ -1,8 +1,8 @@
|
|
1
|
-
module DeepClone
|
1
|
+
module Configatron::DeepClone
|
2
2
|
# = DeepClone
|
3
3
|
#
|
4
4
|
# == Version
|
5
|
-
# 1.2006.05.23 (change of the first number means Big Change)
|
5
|
+
# 1.2006.05.23.configatron.1 (change of the first number means Big Change)
|
6
6
|
#
|
7
7
|
# == Description
|
8
8
|
# Adds deep_clone method to an object which produces deep copy of it. It means
|
@@ -34,9 +34,12 @@ module DeepClone
|
|
34
34
|
# == Licence
|
35
35
|
# You can redistribute it and/or modify it under the same terms of Ruby's license;
|
36
36
|
# either the dual license version in 2003, or any later version.
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def self.deep_clone( obj=self, cloned={} )
|
38
|
+
if obj.kind_of?(Configatron::RootStore)
|
39
|
+
# We never actually want to have multiple copies of our
|
40
|
+
# Configatron::RootStore (and every Store has a reference).
|
41
|
+
return obj
|
42
|
+
elsif cloned.has_key?( obj.object_id )
|
40
43
|
return cloned[obj.object_id]
|
41
44
|
else
|
42
45
|
begin
|
@@ -66,4 +69,4 @@ module DeepClone
|
|
66
69
|
end
|
67
70
|
end
|
68
71
|
end
|
69
|
-
end
|
72
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Include in a minitest to restore the global configatron object to
|
2
|
+
# its global state afterwards. Particularly useful if you'd like to test
|
3
|
+
# your application with various config settings.
|
4
|
+
#
|
5
|
+
# ```ruby
|
6
|
+
# class Test::Suite < Minitest::Unit
|
7
|
+
# include Configatron::Integrations::Minitest
|
8
|
+
#
|
9
|
+
# it 'works' do
|
10
|
+
# configatron.unlock! do
|
11
|
+
# configatron.some.setting = true
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# [...]
|
15
|
+
# end
|
16
|
+
# ```
|
17
|
+
module Configatron::Integrations
|
18
|
+
module Minitest
|
19
|
+
def before_setup
|
20
|
+
configatron.temp_start
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def before_teardown
|
25
|
+
super
|
26
|
+
configatron.temp_end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# This is the root configatron object, and contains methods which
|
2
|
+
# operate on the entire configatron hierarchy.
|
3
|
+
class Configatron::RootStore
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
attr_reader :store
|
7
|
+
|
8
|
+
# Have one global RootStore instance, but allow people to create
|
9
|
+
# their own parallel ones if they desire.
|
10
|
+
class << self
|
11
|
+
public :new
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@locked = false
|
16
|
+
reset!
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(name, *args, &block)
|
20
|
+
store.send(name, *args, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset!
|
24
|
+
@store = Configatron::Store.new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def temp(&block)
|
28
|
+
temp_start
|
29
|
+
yield
|
30
|
+
temp_end
|
31
|
+
end
|
32
|
+
|
33
|
+
def temp_start
|
34
|
+
@temp = Configatron::DeepClone.deep_clone(@store)
|
35
|
+
end
|
36
|
+
|
37
|
+
def temp_end
|
38
|
+
@store = @temp
|
39
|
+
end
|
40
|
+
|
41
|
+
def locked?
|
42
|
+
@locked
|
43
|
+
end
|
44
|
+
|
45
|
+
def lock!
|
46
|
+
@locked = true
|
47
|
+
end
|
48
|
+
|
49
|
+
def unlock!
|
50
|
+
@locked = false
|
51
|
+
end
|
52
|
+
end
|
data/lib/configatron/store.rb
CHANGED
@@ -1,36 +1,29 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
class Configatron
|
4
|
-
class Store
|
4
|
+
class Store
|
5
5
|
extend ::Forwardable
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@attributes.send(:extend, DeepClone)
|
11
|
-
end
|
12
|
-
|
13
|
-
def lock!(value=true)
|
14
|
-
@__locked = value
|
15
|
-
end
|
7
|
+
def initialize(root_store, name='configatron')
|
8
|
+
@root_store = root_store
|
9
|
+
@name = name
|
16
10
|
|
17
|
-
|
18
|
-
@attributes.clear
|
11
|
+
@attributes = {}
|
19
12
|
end
|
20
13
|
|
21
14
|
def [](key)
|
22
15
|
val = fetch(key.to_sym) do
|
23
|
-
if @
|
24
|
-
raise Configatron::UndefinedKeyError.new("Key
|
16
|
+
if @root_store.locked?
|
17
|
+
raise Configatron::UndefinedKeyError.new("Key not found: #{key} (for locked #{self})")
|
25
18
|
end
|
26
|
-
|
19
|
+
Configatron::Store.new(@root_store, "#{@name}.#{key}")
|
27
20
|
end
|
28
21
|
return val
|
29
22
|
end
|
30
23
|
|
31
24
|
def store(key, value)
|
32
|
-
if @
|
33
|
-
raise Configatron::LockedError.new("
|
25
|
+
if @root_store.locked?
|
26
|
+
raise Configatron::LockedError.new("Cannot set key #{key} for locked #{self}")
|
34
27
|
end
|
35
28
|
@attributes[key.to_sym] = value
|
36
29
|
end
|
@@ -51,13 +44,8 @@ class Configatron
|
|
51
44
|
return val
|
52
45
|
end
|
53
46
|
|
54
|
-
def nil?
|
55
|
-
@attributes.empty?
|
56
|
-
end
|
57
|
-
|
58
47
|
def key?(key)
|
59
|
-
|
60
|
-
!val.is_a?(Configatron::Store)
|
48
|
+
@attributes.key?(key.to_sym)
|
61
49
|
end
|
62
50
|
|
63
51
|
def configure_from_hash(hash)
|
@@ -70,22 +58,53 @@ class Configatron
|
|
70
58
|
end
|
71
59
|
end
|
72
60
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
temp_end
|
61
|
+
# Needed to allow 'puts'ing of a configatron.
|
62
|
+
def to_ary
|
63
|
+
raise NoMethodError
|
77
64
|
end
|
78
65
|
|
79
|
-
def
|
80
|
-
@
|
66
|
+
def to_s
|
67
|
+
@name
|
81
68
|
end
|
82
69
|
|
83
|
-
def
|
84
|
-
|
70
|
+
def inspect
|
71
|
+
f_out = []
|
72
|
+
@attributes.each do |k, v|
|
73
|
+
if v.is_a?(Configatron::Store)
|
74
|
+
v.inspect.each_line do |line|
|
75
|
+
if line.match(/\n/)
|
76
|
+
line.each_line do |l|
|
77
|
+
l.strip!
|
78
|
+
f_out << l
|
79
|
+
end
|
80
|
+
else
|
81
|
+
line.strip!
|
82
|
+
f_out << line
|
83
|
+
end
|
84
|
+
end
|
85
|
+
else
|
86
|
+
f_out << "#{@name}.#{k} = #{v.inspect}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
f_out.compact.sort.join("\n")
|
85
90
|
end
|
86
91
|
|
87
92
|
def method_missing(name, *args, &block)
|
88
|
-
|
93
|
+
# In case of Configatron bugs, prevent method_missing infinite
|
94
|
+
# loops.
|
95
|
+
if @method_missing
|
96
|
+
raise NoMethodError.new("Bug in configatron; ended up in method_missing while running: #{name.inspect}")
|
97
|
+
end
|
98
|
+
@method_missing = true
|
99
|
+
do_lookup(name, *args, &block)
|
100
|
+
ensure
|
101
|
+
@method_missing = false
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def do_lookup(name, *args, &block)
|
107
|
+
if block
|
89
108
|
yield self[name]
|
90
109
|
else
|
91
110
|
name = name.to_s
|
@@ -104,36 +123,12 @@ class Configatron
|
|
104
123
|
end
|
105
124
|
end
|
106
125
|
|
107
|
-
def inspect(name = 'configatron')
|
108
|
-
f_out = []
|
109
|
-
@attributes.each do |k, v|
|
110
|
-
if v.is_a?(Configatron::Store)
|
111
|
-
v.inspect("#{name}.#{k}").each_line do |line|
|
112
|
-
if line.match(/\n/)
|
113
|
-
line.each_line do |l|
|
114
|
-
l.strip!
|
115
|
-
f_out << l
|
116
|
-
end
|
117
|
-
else
|
118
|
-
line.strip!
|
119
|
-
f_out << line
|
120
|
-
end
|
121
|
-
end
|
122
|
-
else
|
123
|
-
f_out << "#{name}.#{k} = #{v.inspect}"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
f_out.compact.sort.join("\n")
|
127
|
-
end
|
128
|
-
|
129
126
|
alias :[]= :store
|
130
|
-
alias :blank? :nil?
|
131
127
|
alias :has_key? :key?
|
132
128
|
|
133
129
|
def_delegator :@attributes, :values
|
134
130
|
def_delegator :@attributes, :keys
|
135
131
|
def_delegator :@attributes, :each
|
136
|
-
def_delegator :@attributes, :empty?
|
137
132
|
def_delegator :@attributes, :to_h
|
138
133
|
def_delegator :@attributes, :to_hash
|
139
134
|
def_delegator :@attributes, :delete
|
data/lib/configatron/version.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'configatron'
|
2
|
-
Configatron::Rails.init
|
2
|
+
Configatron::Integrations::Rails.init
|
data/test/_lib.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
ENV['MT_NO_EXPECTATIONS'] = 'true'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require 'minitest/spec'
|
7
|
+
require 'mocha/setup'
|
8
|
+
|
9
|
+
require 'configatron'
|
10
|
+
|
11
|
+
module Critic
|
12
|
+
class Test < ::MiniTest::Spec
|
13
|
+
def setup
|
14
|
+
# Put any stubs here that you want to apply globally
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative '_lib'
|
2
|
+
|
3
|
+
class Critic::Functional::ConfigatronTest < Critic::Functional::Test
|
4
|
+
before do
|
5
|
+
@kernel = Configatron::RootStore.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'temp' do
|
9
|
+
before do
|
10
|
+
@kernel.a = 'A'
|
11
|
+
@kernel.b = 'B'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows for temporary setting of values' do
|
15
|
+
assert_equal('A', @kernel.a)
|
16
|
+
assert_equal('B', @kernel.b)
|
17
|
+
@kernel.temp do
|
18
|
+
@kernel.a = 'AA'
|
19
|
+
@kernel.c = 'C'
|
20
|
+
assert_equal('AA', @kernel.a)
|
21
|
+
assert_equal('B', @kernel.b)
|
22
|
+
assert_equal('C', @kernel.c)
|
23
|
+
end
|
24
|
+
assert_equal('A', @kernel.a)
|
25
|
+
assert_equal('B', @kernel.b)
|
26
|
+
assert_equal(false, @kernel.key?(:c))
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'start/end' do
|
30
|
+
it 'allows for temporary setting of values' do
|
31
|
+
assert_equal('A', @kernel.a)
|
32
|
+
assert_equal('B', @kernel.b)
|
33
|
+
@kernel.temp_start
|
34
|
+
@kernel.a = 'AA'
|
35
|
+
@kernel.c = 'C'
|
36
|
+
assert_equal('AA', @kernel.a)
|
37
|
+
assert_equal('B', @kernel.b)
|
38
|
+
assert_equal('C', @kernel.c)
|
39
|
+
@kernel.temp_end
|
40
|
+
assert_equal('A', @kernel.a)
|
41
|
+
assert_equal('B', @kernel.b)
|
42
|
+
assert_equal(false, @kernel.key?(:c))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'lock!' do
|
48
|
+
before do
|
49
|
+
@kernel.a.b.c.d = 'DD'
|
50
|
+
@kernel.lock!
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'raises an error when accessing non-existing values' do
|
54
|
+
refute_nil(@kernel.a)
|
55
|
+
refute_nil(@kernel.a.b)
|
56
|
+
refute_nil(@kernel.a.b.c)
|
57
|
+
assert_equal('DD', @kernel.a.b.c.d)
|
58
|
+
assert_raises(Configatron::UndefinedKeyError) do
|
59
|
+
@kernel.unknown
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'raises an error when trying to set a non-existing key' do
|
64
|
+
assert_raises(Configatron::LockedError) do
|
65
|
+
@kernel.unknown = 'known'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'name' do
|
71
|
+
it 'assigns an appropriate nested name' do
|
72
|
+
name = @kernel.foo.bar.baz.to_s
|
73
|
+
assert_equal(name, 'configatron.foo.bar.baz')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative '_lib'
|
2
|
+
require 'subprocess'
|
3
|
+
|
4
|
+
class Critic::Functional::ConfigatronTest < Critic::Functional::Test
|
5
|
+
describe 'loading' do
|
6
|
+
it 'does not define top-level configatron method if loading configatron/core' do
|
7
|
+
Subprocess.check_call([File.expand_path('../_lib/scripts/core.rb', __FILE__)])
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/test/unit/_lib.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative '../_lib'
|
2
|
+
|
3
|
+
class Critic::Unit::ProcTest < Critic::Unit::Test
|
4
|
+
before do
|
5
|
+
@proc = Configatron::Proc.new {rand}
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#call' do
|
9
|
+
it 'executes the block and returns the results' do
|
10
|
+
stubs(:rand).returns(4)
|
11
|
+
assert_equal(4, @proc.call)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'caches the result if finalize? return true' do
|
15
|
+
@proc.stubs(:finalize?).returns(true)
|
16
|
+
assert_equal(@proc.call, @proc.call)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'does not cache the result if finalize? returns false' do
|
20
|
+
@proc.stubs(:finalize?).returns(false)
|
21
|
+
refute_equal(@proc.call, @proc.call)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../_lib'
|
2
|
+
|
3
|
+
class Critic::Unit::KernelTest < Critic::Unit::Test
|
4
|
+
before do
|
5
|
+
@kernel = Configatron::RootStore.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'delegation' do
|
9
|
+
it 'passes on to Configatron::Store' do
|
10
|
+
@kernel.a.b.c.d = 'D'
|
11
|
+
assert_equal('D', @kernel.a.b.c.d)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'global configatron' do
|
16
|
+
it 'returns an instance of Configatron::RootStore' do
|
17
|
+
assert_equal(true, configatron.kind_of?(Configatron::RootStore))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require_relative '../_lib'
|
2
|
+
|
3
|
+
class Critic::Unit::StoreTest < Critic::Unit::Test
|
4
|
+
before do
|
5
|
+
@store = Configatron::Store.new(Configatron::RootStore.new)
|
6
|
+
@store.foo = 'bar'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "[]" do
|
10
|
+
it 'returns the value if there is one' do
|
11
|
+
assert_equal('bar', @store[:foo])
|
12
|
+
assert_equal('bar', @store['foo'])
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns a new Configatron::Store object if there is no value' do
|
16
|
+
assert_kind_of(Configatron::Store, @store[:unknown])
|
17
|
+
assert_kind_of(Configatron::Store, @store['unknown'])
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'Configatron::Proc' do
|
21
|
+
it 'executes the proc' do
|
22
|
+
@store.a = Configatron::Proc.new {1+1}
|
23
|
+
assert_equal(2, @store.a)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '[]=' do
|
30
|
+
it "sets the value" do
|
31
|
+
@store[:foo] = "bar"
|
32
|
+
assert_equal("bar", @store[:foo])
|
33
|
+
assert_equal("bar", @store["foo"])
|
34
|
+
|
35
|
+
@store[:baz] = "bazzy"
|
36
|
+
assert_equal("bazzy", @store[:baz])
|
37
|
+
assert_equal("bazzy", @store["baz"])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "fetch" do
|
42
|
+
it "returns the value" do
|
43
|
+
assert_equal("bar", @store.fetch(:foo))
|
44
|
+
assert_equal("bar", @store.fetch("foo"))
|
45
|
+
end
|
46
|
+
|
47
|
+
it "sets and returns the value of the default_value if no value is found" do
|
48
|
+
assert_equal("bar!!", @store.fetch(:bar, "bar!!"))
|
49
|
+
assert_equal("bar!!", @store.bar)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "sets and returns the value of the block if no value is found" do
|
53
|
+
@store.fetch(:bar) do
|
54
|
+
"bar!"
|
55
|
+
end
|
56
|
+
assert_equal("bar!", @store.bar)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "key?" do
|
61
|
+
it "returns true if there is a key" do
|
62
|
+
assert_equal(false, @store.key?(:bar))
|
63
|
+
@store.bar = "bar"
|
64
|
+
assert_equal(true, @store.key?(:bar))
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns true if the key is a Configatron::Store" do
|
68
|
+
assert_equal(false, @store.key?(:bar))
|
69
|
+
@store.bar = Configatron::Store.new(Configatron::RootStore)
|
70
|
+
assert_equal(true, @store.key?(:bar))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "has_key?" do
|
75
|
+
it "returns true if there is a key" do
|
76
|
+
assert_equal(false, @store.has_key?(:bar))
|
77
|
+
@store.bar = "bar"
|
78
|
+
assert_equal(true, @store.has_key?(:bar))
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns true if the key is a Configatron::Store" do
|
82
|
+
assert_equal(false, @store.has_key?(:bar))
|
83
|
+
@store.bar = Configatron::Store.new(Configatron::RootStore)
|
84
|
+
assert_equal(true, @store.has_key?(:bar))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "method_missing" do
|
89
|
+
it "returns the value if there is one" do
|
90
|
+
assert_equal("bar", @store.foo)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "returns a Configatron::Store if there is no value" do
|
94
|
+
assert_kind_of(Configatron::Store, @store.bar)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "works with deeply nested values" do
|
98
|
+
@store.a.b.c.d = "DD"
|
99
|
+
assert_equal("DD", @store.a.b.c.d)
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'with bang' do
|
103
|
+
it "raises an exception if the key doesn't exist" do
|
104
|
+
assert_raises(Configatron::UndefinedKeyError) do
|
105
|
+
@store.a.b!
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns the value" do
|
110
|
+
@store.a.b = 'B'
|
111
|
+
assert_equal('B', @store.a.b!)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "configuring" do
|
117
|
+
describe "configure_from_hash" do
|
118
|
+
it "allows setup from a hash" do
|
119
|
+
@store.configure_from_hash(one: 1, a: {b: {c: {d: "DD"}}})
|
120
|
+
assert_equal(1, @store.one)
|
121
|
+
assert_equal("DD", @store.a.b.c.d)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "with a block" do
|
126
|
+
before do
|
127
|
+
@store.a.b = 'B'
|
128
|
+
end
|
129
|
+
|
130
|
+
it "yields up the store to configure with" do
|
131
|
+
@store.a do |a|
|
132
|
+
a.c = 'CC'
|
133
|
+
end
|
134
|
+
assert_equal('B', @store.a.b)
|
135
|
+
assert_equal('CC', @store.a.c)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '#inspect' do
|
141
|
+
it 'returns a printable inspect' do
|
142
|
+
store = Configatron::Store.new(Configatron::RootStore.new)
|
143
|
+
|
144
|
+
store.a.b = 'B'
|
145
|
+
store.c.d = 'C'
|
146
|
+
assert_equal(%{configatron.a.b = "B"\nconfigatron.c.d = "C"}, store.inspect)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configatron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Bates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: subprocess
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,6 +79,7 @@ files:
|
|
65
79
|
- Gemfile
|
66
80
|
- Gemfile.lock
|
67
81
|
- Guardfile
|
82
|
+
- History.txt
|
68
83
|
- LICENSE.txt
|
69
84
|
- README.md
|
70
85
|
- Rakefile
|
@@ -76,9 +91,12 @@ files:
|
|
76
91
|
- lib/configatron/delayed.rb
|
77
92
|
- lib/configatron/dynamic.rb
|
78
93
|
- lib/configatron/errors.rb
|
79
|
-
- lib/configatron/kernel.rb
|
94
|
+
- lib/configatron/ext/kernel.rb
|
95
|
+
- lib/configatron/integrations.rb
|
96
|
+
- lib/configatron/integrations/minitest.rb
|
97
|
+
- lib/configatron/integrations/rails.rb
|
80
98
|
- lib/configatron/proc.rb
|
81
|
-
- lib/configatron/
|
99
|
+
- lib/configatron/root_store.rb
|
82
100
|
- lib/configatron/store.rb
|
83
101
|
- lib/configatron/version.rb
|
84
102
|
- lib/generators/configatron/install/install_generator.rb
|
@@ -87,11 +105,15 @@ files:
|
|
87
105
|
- lib/generators/configatron/install/templates/configatron/production.rb
|
88
106
|
- lib/generators/configatron/install/templates/configatron/test.rb
|
89
107
|
- lib/generators/configatron/install/templates/initializers/configatron.rb
|
90
|
-
- test/
|
91
|
-
- test/
|
92
|
-
- test/
|
93
|
-
- test/
|
94
|
-
- test/
|
108
|
+
- test/_lib.rb
|
109
|
+
- test/functional/_lib.rb
|
110
|
+
- test/functional/_lib/scripts/core.rb
|
111
|
+
- test/functional/configatron.rb
|
112
|
+
- test/functional/loading.rb
|
113
|
+
- test/unit/_lib.rb
|
114
|
+
- test/unit/configatron/proc.rb
|
115
|
+
- test/unit/configatron/root_store.rb
|
116
|
+
- test/unit/configatron/store.rb
|
95
117
|
homepage: https://github.com/markbates/configatron
|
96
118
|
licenses:
|
97
119
|
- MIT
|
@@ -112,13 +134,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
134
|
version: '0'
|
113
135
|
requirements: []
|
114
136
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.2.
|
137
|
+
rubygems_version: 2.2.0
|
116
138
|
signing_key:
|
117
139
|
specification_version: 4
|
118
140
|
summary: A powerful Ruby configuration system.
|
119
141
|
test_files:
|
120
|
-
- test/
|
121
|
-
- test/
|
122
|
-
- test/
|
123
|
-
- test/
|
124
|
-
- test/
|
142
|
+
- test/_lib.rb
|
143
|
+
- test/functional/_lib.rb
|
144
|
+
- test/functional/_lib/scripts/core.rb
|
145
|
+
- test/functional/configatron.rb
|
146
|
+
- test/functional/loading.rb
|
147
|
+
- test/unit/_lib.rb
|
148
|
+
- test/unit/configatron/proc.rb
|
149
|
+
- test/unit/configatron/root_store.rb
|
150
|
+
- test/unit/configatron/store.rb
|
data/lib/configatron/kernel.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
class Configatron::KernelStore < BasicObject
|
3
|
-
include ::Singleton
|
4
|
-
|
5
|
-
attr_reader :store
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@store = ::Configatron::Store.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def method_missing(name, *args, &block)
|
12
|
-
store.send(name, *args, &block)
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
module Kernel
|
18
|
-
def configatron
|
19
|
-
Configatron::KernelStore.instance
|
20
|
-
end
|
21
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Configatron::KernelStore do
|
4
|
-
|
5
|
-
let(:store) { Configatron::KernelStore.instance }
|
6
|
-
|
7
|
-
it 'passes on to Configatron::Store' do
|
8
|
-
configatron.a.b.c.d = 'D'
|
9
|
-
configatron.a.b.c.d.must_equal 'D'
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
describe Kernel do
|
15
|
-
|
16
|
-
describe 'configatron' do
|
17
|
-
|
18
|
-
it 'returns an instance of Configatron::Store' do
|
19
|
-
configatron.kind_of?(Configatron::Store).must_equal true
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Configatron::Proc do
|
4
|
-
|
5
|
-
let(:store) { Configatron::Store.new }
|
6
|
-
let(:proc) { Configatron::Proc.new {rand} }
|
7
|
-
|
8
|
-
describe '#call' do
|
9
|
-
|
10
|
-
it 'executes the block and returns the results' do
|
11
|
-
stubs(:rand).returns(4)
|
12
|
-
proc.call.must_equal 4
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'caches the result if finalize? return true' do
|
16
|
-
proc.stubs(:finalize?).returns(true)
|
17
|
-
proc.call.must_equal proc.call
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'does not cache the result if finalize? returns false' do
|
21
|
-
proc.stubs(:finalize?).returns(false)
|
22
|
-
proc.call.wont_equal proc.call
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
@@ -1,256 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Configatron::Store do
|
4
|
-
|
5
|
-
let(:store) { Configatron::Store.new }
|
6
|
-
|
7
|
-
context "[]" do
|
8
|
-
|
9
|
-
let(:store) { Configatron::Store.new(foo: "bar") }
|
10
|
-
|
11
|
-
it "returns the value if there is one" do
|
12
|
-
store[:foo].must_equal "bar"
|
13
|
-
store["foo"].must_equal "bar"
|
14
|
-
end
|
15
|
-
|
16
|
-
it "returns a new Configatron::Store object if there is no value" do
|
17
|
-
store[:unknown].must_be_kind_of Configatron::Store
|
18
|
-
store["unknown"].must_be_kind_of Configatron::Store
|
19
|
-
end
|
20
|
-
|
21
|
-
context 'Configatron::Proc' do
|
22
|
-
|
23
|
-
it 'executes the proc' do
|
24
|
-
store.a = Configatron::Proc.new {1+1}
|
25
|
-
store.a.must_equal 2
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
context "[]=" do
|
33
|
-
|
34
|
-
it "sets the value" do
|
35
|
-
store[:foo] = "bar"
|
36
|
-
store[:foo].must_equal "bar"
|
37
|
-
store["foo"].must_equal "bar"
|
38
|
-
|
39
|
-
store[:baz] = "bazzy"
|
40
|
-
store[:baz].must_equal "bazzy"
|
41
|
-
store["baz"].must_equal "bazzy"
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
context "fetch" do
|
47
|
-
|
48
|
-
let(:store) { Configatron::Store.new(foo: "bar") }
|
49
|
-
|
50
|
-
it "returns the value" do
|
51
|
-
store.fetch(:foo).must_equal "bar"
|
52
|
-
store.fetch("foo").must_equal "bar"
|
53
|
-
end
|
54
|
-
|
55
|
-
it "sets and returns the value of the default_value if no value is found" do
|
56
|
-
store.fetch(:bar, "bar!!").must_equal "bar!!"
|
57
|
-
store.bar.must_equal "bar!!"
|
58
|
-
end
|
59
|
-
|
60
|
-
it "sets and returns the value of the block if no value is found" do
|
61
|
-
store.fetch(:bar) do
|
62
|
-
"bar!"
|
63
|
-
end.must_equal "bar!"
|
64
|
-
store.bar.must_equal "bar!"
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
context "nil?" do
|
70
|
-
|
71
|
-
it "returns true if there is no value set" do
|
72
|
-
store.foo.must_be_nil
|
73
|
-
store.foo = "bar"
|
74
|
-
store.foo.wont_be_nil
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
context "empty?" do
|
80
|
-
|
81
|
-
it "returns true if there is no value set" do
|
82
|
-
store.foo.must_be_empty
|
83
|
-
store.foo = "bar"
|
84
|
-
store.foo.wont_be_empty
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
context "key?" do
|
90
|
-
|
91
|
-
it "returns true if there is a key" do
|
92
|
-
store.key?(:foo).must_equal false
|
93
|
-
store.foo = "bar"
|
94
|
-
store.key?(:foo).must_equal true
|
95
|
-
end
|
96
|
-
|
97
|
-
it "returns false if the key is a Configatron::Store" do
|
98
|
-
store.key?(:foo).must_equal false
|
99
|
-
store.foo = Configatron::Store.new
|
100
|
-
store.key?(:foo).must_equal false
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
context "has_key?" do
|
106
|
-
|
107
|
-
it "returns true if there is a key" do
|
108
|
-
store.has_key?(:foo).must_equal false
|
109
|
-
store.foo = "bar"
|
110
|
-
store.has_key?(:foo).must_equal true
|
111
|
-
end
|
112
|
-
|
113
|
-
it "returns false if the key is a Configatron::Store" do
|
114
|
-
store.has_key?(:foo).must_equal false
|
115
|
-
store.foo = Configatron::Store.new
|
116
|
-
store.has_key?(:foo).must_equal false
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
context "method_missing" do
|
122
|
-
|
123
|
-
let(:store) { Configatron::Store.new(foo: "bar") }
|
124
|
-
|
125
|
-
it "returns the value if there is one" do
|
126
|
-
store.foo.must_equal "bar"
|
127
|
-
end
|
128
|
-
|
129
|
-
it "returns a Configatron::Store if there is no value" do
|
130
|
-
store.bar.must_be_kind_of Configatron::Store
|
131
|
-
end
|
132
|
-
|
133
|
-
it "works with deeply nested values" do
|
134
|
-
store.a.b.c.d = "DD"
|
135
|
-
store.a.b.c.d.must_equal "DD"
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'with bang' do
|
139
|
-
|
140
|
-
it "raises an exception if the key doesn't exist" do
|
141
|
-
lambda {store.a.b!}.must_raise Configatron::UndefinedKeyError
|
142
|
-
end
|
143
|
-
|
144
|
-
it "returns the value" do
|
145
|
-
store.a.b = 'B'
|
146
|
-
store.a.b!.must_equal 'B'
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
context "lock!" do
|
154
|
-
|
155
|
-
before do
|
156
|
-
store.a.b.c.d = 'DD'
|
157
|
-
store.lock!
|
158
|
-
end
|
159
|
-
|
160
|
-
it "raises an error when accessing non-existing values" do
|
161
|
-
store.a.wont_be_nil
|
162
|
-
store.a.b.wont_be_nil
|
163
|
-
store.a.b.c.wont_be_nil
|
164
|
-
store.a.b.c.d.must_equal "DD"
|
165
|
-
proc {store.unknown}.must_raise(Configatron::UndefinedKeyError)
|
166
|
-
end
|
167
|
-
|
168
|
-
it "raises an error when trying to set a non-existing key" do
|
169
|
-
proc {store.unknown = "known"}.must_raise(Configatron::LockedError)
|
170
|
-
end
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
context "temp" do
|
175
|
-
|
176
|
-
before do
|
177
|
-
store.a = 'A'
|
178
|
-
store.b = 'B'
|
179
|
-
end
|
180
|
-
|
181
|
-
it "allows for temporary setting of values" do
|
182
|
-
store.a.must_equal 'A'
|
183
|
-
store.b.must_equal 'B'
|
184
|
-
store.temp do
|
185
|
-
store.a = 'AA'
|
186
|
-
store.c = 'C'
|
187
|
-
store.a.must_equal 'AA'
|
188
|
-
store.b.must_equal 'B'
|
189
|
-
store.c.must_equal 'C'
|
190
|
-
end
|
191
|
-
store.a.must_equal 'A'
|
192
|
-
store.b.must_equal 'B'
|
193
|
-
store.c.must_be_nil
|
194
|
-
end
|
195
|
-
|
196
|
-
context "start/end" do
|
197
|
-
|
198
|
-
it "allows for temporary setting of values" do
|
199
|
-
store.a.must_equal 'A'
|
200
|
-
store.b.must_equal 'B'
|
201
|
-
store.temp_start
|
202
|
-
store.a = 'AA'
|
203
|
-
store.c = 'C'
|
204
|
-
store.a.must_equal 'AA'
|
205
|
-
store.b.must_equal 'B'
|
206
|
-
store.c.must_equal 'C'
|
207
|
-
store.temp_end
|
208
|
-
store.a.must_equal 'A'
|
209
|
-
store.b.must_equal 'B'
|
210
|
-
store.c.must_be_nil
|
211
|
-
end
|
212
|
-
|
213
|
-
end
|
214
|
-
|
215
|
-
end
|
216
|
-
|
217
|
-
context "configuring" do
|
218
|
-
|
219
|
-
context "configure_from_hash" do
|
220
|
-
|
221
|
-
it "allows setup from a hash" do
|
222
|
-
store.configure_from_hash(one: 1, a: {b: {c: {d: "DD"}}})
|
223
|
-
store.one.must_equal 1
|
224
|
-
store.a.b.c.d.must_equal "DD"
|
225
|
-
end
|
226
|
-
|
227
|
-
end
|
228
|
-
|
229
|
-
context "with a block" do
|
230
|
-
|
231
|
-
before do
|
232
|
-
store.a.b = 'B'
|
233
|
-
end
|
234
|
-
|
235
|
-
it "yields up the store to configure with" do
|
236
|
-
store.a do |a|
|
237
|
-
a.c = 'CC'
|
238
|
-
end
|
239
|
-
store.a.b.must_equal 'B'
|
240
|
-
store.a.c.must_equal 'CC'
|
241
|
-
end
|
242
|
-
|
243
|
-
end
|
244
|
-
|
245
|
-
end
|
246
|
-
|
247
|
-
context '#inspect' do
|
248
|
-
|
249
|
-
it 'returns a printable inspect' do
|
250
|
-
store.a.b = 'B'
|
251
|
-
store.c.d = 'C'
|
252
|
-
store.inspect.must_equal %{configatron.a.b = "B"\nconfigatron.c.d = "C"}
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
data/test/configatron_test.rb
DELETED
data/test/test_helper.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
|
3
|
-
require 'configatron' # and any other gems you need
|
4
|
-
|
5
|
-
require 'minitest/autorun'
|
6
|
-
require "mocha/setup"
|
7
|
-
require 'mocha/mini_test'
|
8
|
-
|
9
|
-
class MiniTest::Spec
|
10
|
-
|
11
|
-
class << self
|
12
|
-
alias :context :describe
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|