configatron 3.2.0 → 4.0.0
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.
- 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
|