configatronn 4.5.2
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 +7 -0
- data/.github/workflows/test.yml +27 -0
- data/.gitignore +22 -0
- data/Gemfile +6 -0
- data/History.txt +82 -0
- data/LICENSE.txt +23 -0
- data/README.md +312 -0
- data/Rakefile +15 -0
- data/configatronn.gemspec +28 -0
- data/lib/configatron/core.rb +6 -0
- data/lib/configatron/delayed.rb +2 -0
- data/lib/configatron/dynamic.rb +7 -0
- data/lib/configatron/errors.rb +9 -0
- data/lib/configatron/ext/kernel.rb +5 -0
- data/lib/configatron/integrations/minitest.rb +29 -0
- data/lib/configatron/integrations/rails.rb +53 -0
- data/lib/configatron/integrations.rb +4 -0
- data/lib/configatron/proc.rb +34 -0
- data/lib/configatron/root_store.rb +126 -0
- data/lib/configatron/store.rb +182 -0
- data/lib/configatron/version.rb +3 -0
- data/lib/configatron.rb +23 -0
- data/lib/generators/configatron/install/install_generator.rb +24 -0
- data/lib/generators/configatron/install/templates/configatron/defaults.rb +7 -0
- data/lib/generators/configatron/install/templates/configatron/development.rb +4 -0
- data/lib/generators/configatron/install/templates/configatron/production.rb +4 -0
- data/lib/generators/configatron/install/templates/configatron/test.rb +4 -0
- data/lib/generators/configatron/install/templates/initializers/configatron.rb +2 -0
- data/test/_lib.rb +17 -0
- data/test/functional/_lib/scripts/core.rb +11 -0
- data/test/functional/_lib.rb +10 -0
- data/test/functional/configatron.rb +194 -0
- data/test/functional/delayed.rb +18 -0
- data/test/functional/loading.rb +10 -0
- data/test/functional/minitest.rb +18 -0
- data/test/functional/rails.rb +94 -0
- data/test/unit/_lib.rb +10 -0
- data/test/unit/configatron/proc.rb +24 -0
- data/test/unit/configatron/root_store.rb +37 -0
- data/test/unit/configatron/store.rb +149 -0
- metadata +203 -0
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
# This is the root configatron object, and contains methods which
|
5
|
+
# operate on the entire configatron hierarchy.
|
6
|
+
class Configatron::RootStore < BasicObject
|
7
|
+
include ::Singleton
|
8
|
+
extend ::Forwardable
|
9
|
+
|
10
|
+
attr_reader :store
|
11
|
+
|
12
|
+
# Have one global RootStore instance, but allow people to create
|
13
|
+
# their own parallel ones if they desire.
|
14
|
+
class << self
|
15
|
+
public :new
|
16
|
+
end
|
17
|
+
|
18
|
+
@@cow = 0
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@locked = false
|
22
|
+
@cow = nil
|
23
|
+
|
24
|
+
@temporary_locks = []
|
25
|
+
@temporary_states = []
|
26
|
+
|
27
|
+
reset!
|
28
|
+
end
|
29
|
+
|
30
|
+
def __cow
|
31
|
+
@cow
|
32
|
+
end
|
33
|
+
|
34
|
+
def __cow_path(path)
|
35
|
+
start = @store.__cow_clone
|
36
|
+
|
37
|
+
node = start
|
38
|
+
branch = path.map do |key|
|
39
|
+
node = node[key]
|
40
|
+
node.__cow_clone
|
41
|
+
end
|
42
|
+
nodes = [start] + branch
|
43
|
+
|
44
|
+
# [node1, node2, node3] with
|
45
|
+
# [node2, node3, node4] and
|
46
|
+
# ['key1', 'key2, 'key3']
|
47
|
+
nodes[0...-1].zip(nodes[1..-1], path) do |parent, child, key|
|
48
|
+
# These are all cow_clones, so won't trigger a further cow
|
49
|
+
# modification.
|
50
|
+
parent[key] = child
|
51
|
+
end
|
52
|
+
|
53
|
+
@store = nodes.first
|
54
|
+
nodes.last
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing(name, *args, &block)
|
58
|
+
store.__send__(name, *args, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def reset!
|
62
|
+
@store = ::Configatron::Store.new(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
def temp(&block)
|
66
|
+
temp_start
|
67
|
+
|
68
|
+
begin
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
temp_end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def temp_start
|
76
|
+
@temp_cow = @cow
|
77
|
+
|
78
|
+
# Just need to have a unique Copy-on-Write generation ID
|
79
|
+
@cow = @@cow += 1
|
80
|
+
|
81
|
+
@temporary_locks.push(@locked)
|
82
|
+
@temporary_states.push(@store)
|
83
|
+
end
|
84
|
+
|
85
|
+
def temp_end
|
86
|
+
@cow = @temp_cow
|
87
|
+
|
88
|
+
@locked = @temporary_locks.pop
|
89
|
+
@store = @temporary_states.pop
|
90
|
+
end
|
91
|
+
|
92
|
+
def locked?
|
93
|
+
@locked
|
94
|
+
end
|
95
|
+
|
96
|
+
def lock!(&blk)
|
97
|
+
if blk
|
98
|
+
orig = @locked
|
99
|
+
begin
|
100
|
+
@locked = true
|
101
|
+
blk.call
|
102
|
+
ensure
|
103
|
+
@locked = orig
|
104
|
+
end
|
105
|
+
else
|
106
|
+
@locked = true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def unlock!(&blk)
|
111
|
+
if blk
|
112
|
+
orig = @locked
|
113
|
+
begin
|
114
|
+
@locked = false
|
115
|
+
blk.call
|
116
|
+
ensure
|
117
|
+
@locked = orig
|
118
|
+
end
|
119
|
+
else
|
120
|
+
@locked = false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def_delegator :@store, :to_s
|
125
|
+
def_delegator :@store, :inspect
|
126
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
class Configatron
|
4
|
+
class Store < BasicObject
|
5
|
+
extend ::Forwardable
|
6
|
+
|
7
|
+
def initialize(root_store, name='configatron', attributes={}, path=[])
|
8
|
+
@root_store = root_store
|
9
|
+
@name = name
|
10
|
+
@attributes = attributes
|
11
|
+
|
12
|
+
# We could derive @name from @path, though this would break
|
13
|
+
# backwards-compatibility.
|
14
|
+
@path = path
|
15
|
+
|
16
|
+
@cow = root_store.__cow
|
17
|
+
end
|
18
|
+
|
19
|
+
def clone
|
20
|
+
Store.new(
|
21
|
+
@root_store,
|
22
|
+
@name,
|
23
|
+
@attributes.clone,
|
24
|
+
@path
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def __cow
|
29
|
+
@cow
|
30
|
+
end
|
31
|
+
|
32
|
+
def __cow_clone
|
33
|
+
# A temp has started since the last time this was written
|
34
|
+
if @root_store.__cow != @cow
|
35
|
+
self.clone
|
36
|
+
else
|
37
|
+
self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](key)
|
42
|
+
val = fetch(key.to_sym) do
|
43
|
+
if @root_store.locked?
|
44
|
+
::Kernel.raise ::Configatron::UndefinedKeyError.new("Key not found: #{key} (for locked #{self})")
|
45
|
+
end
|
46
|
+
::Configatron::Store.new(@root_store, "#{@name}.#{key}", {}, @path + [key])
|
47
|
+
end
|
48
|
+
return val
|
49
|
+
end
|
50
|
+
|
51
|
+
def store(key, value)
|
52
|
+
if @root_store.locked?
|
53
|
+
::Kernel.raise ::Configatron::LockedError.new("Cannot set key #{key} for locked #{self}")
|
54
|
+
end
|
55
|
+
|
56
|
+
key = key.to_sym
|
57
|
+
if @root_store.__cow != @cow
|
58
|
+
copy = @root_store.__cow_path(@path)
|
59
|
+
# Cow should now match, so this won't recurse. (Note this is
|
60
|
+
# not particularly thread-safe.)
|
61
|
+
copy.store(key, value)
|
62
|
+
else
|
63
|
+
@attributes[key] = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def fetch(key, default_value = nil, &block)
|
68
|
+
key = key.to_sym
|
69
|
+
if key?(key)
|
70
|
+
val = @attributes[key]
|
71
|
+
else
|
72
|
+
if block
|
73
|
+
val = block.call
|
74
|
+
elsif default_value
|
75
|
+
val = default_value
|
76
|
+
end
|
77
|
+
store(key, val)
|
78
|
+
end
|
79
|
+
if ::Configatron::Proc === val
|
80
|
+
val = val.call
|
81
|
+
end
|
82
|
+
return val
|
83
|
+
end
|
84
|
+
|
85
|
+
def key?(key)
|
86
|
+
@attributes.key?(key.to_sym)
|
87
|
+
end
|
88
|
+
|
89
|
+
def configure_from_hash(hash)
|
90
|
+
hash.each do |key, value|
|
91
|
+
if ::Hash === value
|
92
|
+
self[key].configure_from_hash(value)
|
93
|
+
else
|
94
|
+
store(key, value)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_s
|
100
|
+
@name
|
101
|
+
end
|
102
|
+
|
103
|
+
def inspect
|
104
|
+
f_out = []
|
105
|
+
@attributes.each do |k, v|
|
106
|
+
if ::Configatron::Store === v
|
107
|
+
v.inspect.each_line do |line|
|
108
|
+
if line.match(/\n/)
|
109
|
+
line.each_line do |l|
|
110
|
+
l.strip!
|
111
|
+
f_out << l
|
112
|
+
end
|
113
|
+
else
|
114
|
+
line.strip!
|
115
|
+
f_out << line
|
116
|
+
end
|
117
|
+
end
|
118
|
+
else
|
119
|
+
f_out << "#{@name}.#{k} = #{v.inspect}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
f_out.compact.sort.join("\n")
|
123
|
+
end
|
124
|
+
|
125
|
+
def method_missing(name, *args, &block)
|
126
|
+
do_lookup(name, *args, &block)
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_h
|
130
|
+
@attributes.each_with_object({}) do |(k, v), h|
|
131
|
+
v = v.call if ::Configatron::Proc === v
|
132
|
+
h[k] = Store === v ? v.to_h : v
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# So that puts works (it expects the object to respond to to_ary)
|
137
|
+
def to_ary
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
|
141
|
+
# So that we keep backward-compatibility in case people are using nil? to check
|
142
|
+
# configatron settings:
|
143
|
+
def nil?
|
144
|
+
false
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def do_lookup(name, *args, &block)
|
150
|
+
if block
|
151
|
+
yield self[name]
|
152
|
+
else
|
153
|
+
name = name.to_s
|
154
|
+
if name.end_with?('=')
|
155
|
+
return store(name[0..-2], args[0])
|
156
|
+
elsif name.end_with?('!')
|
157
|
+
key = name[0..-2]
|
158
|
+
if self.has_key?(key)
|
159
|
+
return self[key]
|
160
|
+
else
|
161
|
+
::Kernel.raise ::Configatron::UndefinedKeyError.new($1)
|
162
|
+
end
|
163
|
+
else
|
164
|
+
return self[name]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
alias :[]= :store
|
170
|
+
alias :has_key? :key?
|
171
|
+
alias :to_hash :to_h
|
172
|
+
|
173
|
+
def_delegator :@attributes, :values
|
174
|
+
def_delegator :@attributes, :keys
|
175
|
+
def_delegator :@attributes, :each
|
176
|
+
def_delegator :@attributes, :delete
|
177
|
+
# def_delegator :@attributes, :fetch
|
178
|
+
# def_delegator :@attributes, :has_key?
|
179
|
+
# def_delegator :$stdout, :puts
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
data/lib/configatron.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'configatron/version'
|
2
|
+
|
3
|
+
require 'configatron/errors'
|
4
|
+
require 'configatron/integrations'
|
5
|
+
require 'configatron/root_store'
|
6
|
+
require 'configatron/store'
|
7
|
+
|
8
|
+
# Proc *must* load before dynamic/delayed, or else Configatron::Proc
|
9
|
+
# will refer to the global ::Proc
|
10
|
+
require 'configatron/proc'
|
11
|
+
require 'configatron/delayed'
|
12
|
+
require 'configatron/dynamic'
|
13
|
+
|
14
|
+
class Configatron
|
15
|
+
end
|
16
|
+
|
17
|
+
# NO_EXT gets defined when you require "configatron/core", which
|
18
|
+
# signals that you don't want any extensions. It'd be nice to have a
|
19
|
+
# better internal signaling mechanism (could use environment
|
20
|
+
# variables, but then they become part of the public interface).
|
21
|
+
unless defined?(Configatron::NO_EXT)
|
22
|
+
require 'configatron/ext/kernel'
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
class Configatron
|
4
|
+
class InstallGenerator < ::Rails::Generators::Base #:nodoc:
|
5
|
+
|
6
|
+
desc 'Generates configatron files for the default Rails environments.'
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@_configatron_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.banner
|
13
|
+
"rails generate configatron:install"
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_files
|
17
|
+
template 'initializers/configatron.rb', 'config/initializers/configatron.rb'
|
18
|
+
%w{defaults development production test}.each do |env|
|
19
|
+
template "configatron/#{env}.rb", "config/configatron/#{env}.rb"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
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/minitest'
|
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,194 @@
|
|
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
|
+
it 'nested' do
|
30
|
+
@kernel.foo.bar = 'original'
|
31
|
+
@kernel.temp do
|
32
|
+
@kernel.foo.bar = 'temp'
|
33
|
+
assert_equal('temp', @kernel.foo.bar)
|
34
|
+
end
|
35
|
+
assert_equal('original', @kernel.foo.bar)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'handles nested temps' do
|
39
|
+
@kernel.temp do
|
40
|
+
@kernel.a = 'Z'
|
41
|
+
@kernel.temp do
|
42
|
+
@kernel.a = 'Y'
|
43
|
+
assert_equal('Y', @kernel.a)
|
44
|
+
end
|
45
|
+
assert_equal('Z', @kernel.a)
|
46
|
+
end
|
47
|
+
assert_equal('A', @kernel.a)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'cleans up after an exception' do
|
51
|
+
@kernel.foo.bar = 'original'
|
52
|
+
|
53
|
+
assert_raises(RuntimeError) do
|
54
|
+
@kernel.temp do
|
55
|
+
@kernel.foo.bar = 'temp'
|
56
|
+
raise RuntimeError.new('error')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
assert_equal('original', @kernel.foo.bar)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'restores locking state' do
|
64
|
+
@kernel.lock!
|
65
|
+
@kernel.temp do
|
66
|
+
@kernel.unlock!
|
67
|
+
end
|
68
|
+
assert(@kernel.locked?)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'restores locking state in nested temps' do
|
72
|
+
@kernel.lock!
|
73
|
+
@kernel.temp do
|
74
|
+
@kernel.unlock!
|
75
|
+
@kernel.temp do
|
76
|
+
@kernel.lock!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
assert(@kernel.locked?)
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'start/end' do
|
83
|
+
it 'allows for temporary setting of values' do
|
84
|
+
assert_equal('A', @kernel.a)
|
85
|
+
assert_equal('B', @kernel.b)
|
86
|
+
@kernel.temp_start
|
87
|
+
@kernel.a = 'AA'
|
88
|
+
@kernel.c = 'C'
|
89
|
+
assert_equal('AA', @kernel.a)
|
90
|
+
assert_equal('B', @kernel.b)
|
91
|
+
assert_equal('C', @kernel.c)
|
92
|
+
@kernel.temp_end
|
93
|
+
assert_equal('A', @kernel.a)
|
94
|
+
assert_equal('B', @kernel.b)
|
95
|
+
assert_equal(false, @kernel.key?(:c))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'lock!' do
|
101
|
+
before do
|
102
|
+
@kernel.a.b.c.d = 'DD'
|
103
|
+
@kernel.lock!
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'raises an error when accessing non-existing values' do
|
107
|
+
assert @kernel.a != nil
|
108
|
+
assert @kernel.a.b != nil
|
109
|
+
assert @kernel.a.b.c != nil
|
110
|
+
assert_equal('DD', @kernel.a.b.c.d)
|
111
|
+
assert_raises(Configatron::UndefinedKeyError) do
|
112
|
+
@kernel.unknown
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'responds to nil? for backward compatibility' do
|
117
|
+
refute_nil @kernel.a
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'raises an error when trying to set a non-existing key' do
|
121
|
+
assert_raises(Configatron::LockedError) do
|
122
|
+
@kernel.unknown = 'known'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'locks during the block argument' do
|
127
|
+
@kernel.unlock!
|
128
|
+
|
129
|
+
@kernel.lock! do
|
130
|
+
assert(@kernel.locked?)
|
131
|
+
end
|
132
|
+
|
133
|
+
assert(!@kernel.locked?)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'executes a block argument' do
|
137
|
+
a = 1
|
138
|
+
@kernel.lock! do
|
139
|
+
a = 2
|
140
|
+
end
|
141
|
+
assert_equal(2, a)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe 'name' do
|
146
|
+
it 'assigns an appropriate nested name' do
|
147
|
+
name = @kernel.foo.bar.baz.to_s
|
148
|
+
assert_equal(name, 'configatron.foo.bar.baz')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'puts' do
|
153
|
+
it 'does not cause an exception' do
|
154
|
+
original_stdout = $stdout
|
155
|
+
$stdout = File.open(File::NULL, "w")
|
156
|
+
begin
|
157
|
+
puts @kernel
|
158
|
+
puts @kernel.hi
|
159
|
+
ensure
|
160
|
+
$stdout = original_stdout
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe 'private methods on kernel' do
|
166
|
+
it 'can be accessed through method accessors' do
|
167
|
+
@kernel.catch = 'hi'
|
168
|
+
@kernel.foo.catch = 'hi'
|
169
|
+
|
170
|
+
assert_equal('hi', @kernel.catch)
|
171
|
+
assert_equal('hi', @kernel.foo.catch)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe 'to_h and to_hash' do
|
176
|
+
before do
|
177
|
+
@kernel.a = 1
|
178
|
+
@kernel.b.c = Configatron::Delayed.new{ @kernel.a + 3 }
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'returns a hash representation' do
|
182
|
+
expected_hash = { a: 1, b: { c: 4 } }
|
183
|
+
assert_equal(expected_hash, @kernel.to_h)
|
184
|
+
assert_equal(expected_hash, @kernel.to_hash)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe 'nil value' do
|
189
|
+
it 'remembers a nil value' do
|
190
|
+
@kernel.a = nil
|
191
|
+
assert_nil(@kernel.a)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '_lib'
|
2
|
+
|
3
|
+
class Critic::Functional::DelayedTest < Critic::Functional::Test
|
4
|
+
before do
|
5
|
+
@kernel = Configatron::RootStore.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'delayed' do
|
9
|
+
before do
|
10
|
+
@kernel.a = Configatron::Delayed.new { @kernel.b }
|
11
|
+
@kernel.b = "expected"
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'works independent of the order' do
|
15
|
+
assert_equal('expected', @kernel.a)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
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
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '_lib'
|
2
|
+
require 'subprocess'
|
3
|
+
|
4
|
+
class Critic::Functional::MinitestTest < Critic::Functional::Test
|
5
|
+
include Configatron::Integrations::Minitest
|
6
|
+
|
7
|
+
describe 'multiple runs' do
|
8
|
+
it 'settings get reset: 1' do
|
9
|
+
assert(!configatron.key?(:my_crazy_setting))
|
10
|
+
configatron.my_crazy_setting = true
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'settings get reset: 2' do
|
14
|
+
assert(!configatron.key?(:my_crazy_setting))
|
15
|
+
configatron.my_crazy_setting = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|