a9n 0.2.3 → 0.3.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/README.md +13 -18
- data/lib/a9n.rb +36 -69
- data/lib/a9n/ext/hash.rb +21 -0
- data/lib/a9n/loader.rb +57 -0
- data/lib/a9n/struct.rb +1 -1
- data/lib/a9n/version.rb +1 -1
- data/spec/integration/a9n_spec.rb +41 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/unit/a9n_spec.rb +198 -0
- data/spec/unit/loader_spec.rb +163 -0
- data/spec/{struct_spec.rb → unit/struct_spec.rb} +13 -1
- data/test_app/config/a9n/mandrill.yml +3 -0
- data/{spec/fixtures → test_app/config}/configuration.yml +1 -1
- data/test_app/config/configuration.yml.example +23 -0
- metadata +15 -9
- data/lib/a9n/core_ext/hash.rb +0 -17
- data/spec/a9n_spec.rb +0 -295
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1fa842e61082deb4d82eb3059efed6cb0ce0e50
|
4
|
+
data.tar.gz: a3250f33bf6df0ae3b06de1bb30774acf958d65f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca996bb79d7331734d27e51eb5b35c1759a95bc680056ca6a25c78ec138d2c6c2272e613cb2bbd18aa4cbb01155ef981d8fa4719f909239abfb3c15c273e9b2a
|
7
|
+
data.tar.gz: d9e4c62825e16d882d3f9dadb56e4689e64b7036a47b77557208ff9c89a2f5798992fde85eb77fbe26c97d310c35dfd8967b627135497fd18e0f6a1ad0e37841
|
data/README.md
CHANGED
@@ -10,8 +10,7 @@
|
|
10
10
|
[codeclimate]: https://codeclimate.com/github/knapo/a9n
|
11
11
|
[coveralls]: https://coveralls.io/r/knapo/a9n
|
12
12
|
|
13
|
-
|
14
|
-
Ruby 1.8 is not supported in version 0.1.2 and higher.
|
13
|
+
A9n is a simple tool for managing extra configuration in ruby/rails apps. It supports Rails 2.x, 3.x, 4.x and Ruby 1.9, 2.0. 2.1. Ruby 1.8 is not supported since version 0.1.2.
|
15
14
|
|
16
15
|
## Installation
|
17
16
|
|
@@ -37,15 +36,14 @@ after budler requires:
|
|
37
36
|
A9n.root = File.expand_path('../..', __FILE__)
|
38
37
|
A9n.load
|
39
38
|
|
40
|
-
|
41
39
|
It works with `Rails` by default. If you want to use `A9n` with non-rails app
|
42
|
-
you may need to tell
|
40
|
+
you may need to tell that to A9n by:
|
43
41
|
|
44
42
|
A9n.local_app = MyApp
|
45
43
|
|
46
44
|
## Usage
|
47
45
|
|
48
|
-
You can access any variable defined in configuration files
|
46
|
+
You can access any variable defined in configuration files by delegating it to
|
49
47
|
`A9n`. E.g:
|
50
48
|
|
51
49
|
defaults:
|
@@ -58,21 +56,22 @@ You can access any variable defined in configuration files but delegating it to
|
|
58
56
|
is accessible by:
|
59
57
|
|
60
58
|
A9n.app_host # => `knapo.net` in production and `localhost:3000` in development
|
61
|
-
A9n.email_from # => `no-reply@knapo.net` in
|
59
|
+
A9n.email_from # => `no-reply@knapo.net` in both envs
|
62
60
|
|
63
61
|
## Custom and multiple configuration files
|
64
62
|
|
65
|
-
If you
|
66
|
-
|
67
|
-
A9n.load('mongo.yml', 'other.yml', 'custom_dir/extra')
|
63
|
+
If you want to scope configuration you may split to multiple files. All files from `config/a9n` are loaded by default, but you may pass custom paths as an argument to `A9n.load` e.g. `A9n.load('lib/facebook/api.yml', 'config/mongoid.yml')`. In such cases config items are accessialbe via scope consistient with the file name.
|
68
64
|
|
69
|
-
|
65
|
+
E.g. if you have `config/a9n/mandrill.yml`:
|
66
|
+
|
67
|
+
defaults:
|
68
|
+
username: "joe"
|
69
|
+
api_key: "1234asdf"
|
70
70
|
|
71
|
-
|
71
|
+
you can access it by:
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
A9n.extra.varname
|
73
|
+
A9n.mandrill.username # => `joe`
|
74
|
+
A9n.mandrill.api_key # => `1234asdf`
|
76
75
|
|
77
76
|
## Contributing
|
78
77
|
|
@@ -82,7 +81,3 @@ and the configuration is availble under `mongo`, `other` and `extra` scopes:
|
|
82
81
|
4. Push to the branch (`git push origin my-new-feature`)
|
83
82
|
5. Create new Pull Request
|
84
83
|
|
85
|
-
### Contributors
|
86
|
-
|
87
|
-
* [Grzegorz Świrski](https://github.com/sognat)
|
88
|
-
* [Jakub Łopusiński](https://github.com/siemakuba)
|
data/lib/a9n.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "a9n/version"
|
2
2
|
require "a9n/struct"
|
3
|
-
require "a9n/
|
3
|
+
require "a9n/ext/hash"
|
4
|
+
require "a9n/loader"
|
4
5
|
require "yaml"
|
5
6
|
require "erb"
|
6
7
|
|
@@ -15,82 +16,63 @@ module A9n
|
|
15
16
|
|
16
17
|
class << self
|
17
18
|
def env
|
18
|
-
@env ||=
|
19
|
+
@env ||= app_env || get_env_var("RAILS_ENV") || get_env_var("RACK_ENV") || get_env_var("APP_ENV")
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
22
|
+
def app_env
|
23
|
+
app.env if app && app.respond_to?(:env)
|
23
24
|
end
|
24
25
|
|
25
|
-
def
|
26
|
-
@
|
26
|
+
def app
|
27
|
+
@app ||= get_rails
|
27
28
|
end
|
28
29
|
|
29
|
-
def
|
30
|
-
@
|
30
|
+
def app=(app_instance)
|
31
|
+
@app = app_instance
|
31
32
|
end
|
32
33
|
|
33
34
|
def root
|
34
|
-
@root ||=
|
35
|
+
@root ||= app.root
|
35
36
|
end
|
36
37
|
|
37
38
|
def root=(path)
|
38
|
-
|
39
|
-
@root = path.empty? ? nil : Pathname.new(path.to_s)
|
39
|
+
@root = path.to_s.empty? ? nil : Pathname.new(path.to_s)
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
42
|
+
def get_rails
|
43
|
+
defined?(Rails) ? Rails : nil
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
47
|
-
|
48
|
-
files.map do |file|
|
49
|
-
default_and_env_config = load_config(file)
|
50
|
-
|
51
|
-
instance_variable_set(var_name_for(file), A9n::Struct.new(default_and_env_config))
|
52
|
-
end
|
46
|
+
def get_env_var(name)
|
47
|
+
ENV[name]
|
53
48
|
end
|
54
49
|
|
55
|
-
def
|
56
|
-
|
57
|
-
env_local = load_yml("config/#{file}", env)
|
58
|
-
default_example = load_yml("config/#{file}.example", "defaults")
|
59
|
-
default_local = load_yml("config/#{file}", "defaults")
|
60
|
-
|
61
|
-
if env_example.nil? && env_local.nil? && default_example.nil? && default_local.nil?
|
62
|
-
raise MissingConfigurationData.new("Configuration data was not found in neither config/#{file}.example nor config/#{file}")
|
63
|
-
end
|
64
|
-
|
65
|
-
example = Hash.merge(default_example, env_example)
|
66
|
-
local = Hash.merge( default_local,env_local)
|
67
|
-
|
68
|
-
if !example.nil? && !local.nil?
|
69
|
-
verify!(example, local)
|
70
|
-
end
|
71
|
-
|
72
|
-
local || example
|
50
|
+
def fetch(*args)
|
51
|
+
scope(DEFAULT_SCOPE).fetch(*args)
|
73
52
|
end
|
74
53
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
54
|
+
def scope(name)
|
55
|
+
load unless instance_variable_defined?(var_name_for(name))
|
56
|
+
instance_variable_get(var_name_for(name))
|
57
|
+
end
|
79
58
|
|
80
|
-
|
81
|
-
|
82
|
-
else
|
83
|
-
return nil
|
84
|
-
end
|
59
|
+
def var_name_for(file)
|
60
|
+
:"@#{File.basename(file.to_s, '.*')}"
|
85
61
|
end
|
86
62
|
|
87
|
-
|
88
|
-
|
89
|
-
nil
|
63
|
+
def default_files
|
64
|
+
[root.join("config/#{DEFAULT_SCOPE}.yml").to_s] + Dir[root.join("config/a9n/*.yml")]
|
90
65
|
end
|
91
66
|
|
92
|
-
def
|
93
|
-
|
67
|
+
def load(*files)
|
68
|
+
if files.empty?
|
69
|
+
files = default_files
|
70
|
+
else
|
71
|
+
files = get_absolute_paths_for(files)
|
72
|
+
end
|
73
|
+
files.map do |file|
|
74
|
+
instance_variable_set(var_name_for(file), A9n::Loader.new(file, env).get)
|
75
|
+
end
|
94
76
|
end
|
95
77
|
|
96
78
|
def method_missing(name, *args)
|
@@ -101,25 +83,10 @@ module A9n
|
|
101
83
|
end
|
102
84
|
end
|
103
85
|
|
104
|
-
def get_rails
|
105
|
-
defined?(Rails) ? Rails : nil
|
106
|
-
end
|
107
|
-
|
108
|
-
def get_env_var(name)
|
109
|
-
ENV[name]
|
110
|
-
end
|
111
|
-
|
112
|
-
def var_name_for(file)
|
113
|
-
:"@#{file.to_s.split('/').last.split('.').first}"
|
114
|
-
end
|
115
|
-
|
116
86
|
private
|
117
87
|
|
118
|
-
def
|
119
|
-
|
120
|
-
if missing_keys.any?
|
121
|
-
raise MissingConfigurationVariables.new("Following variables are missing in your configuration file: #{missing_keys.join(",")}")
|
122
|
-
end
|
88
|
+
def get_absolute_paths_for(files)
|
89
|
+
files.map { |file| Pathname.new(file).absolute? ? file : self.root.join('config', file).to_s }
|
123
90
|
end
|
124
91
|
end
|
125
92
|
end
|
data/lib/a9n/ext/hash.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module A9n
|
2
|
+
class HashExt
|
3
|
+
class << self
|
4
|
+
# Hash#deep_symbolize_keys
|
5
|
+
# based on
|
6
|
+
# https://github.com/svenfuchs/i18n/blob/master/lib/i18n/core_ext/hash.rb
|
7
|
+
def deep_symbolize_keys(hash)
|
8
|
+
hash.inject({}) { |result, (key, value)|
|
9
|
+
value = deep_symbolize_keys(value) if value.is_a?(::Hash)
|
10
|
+
result[(key.to_sym rescue key) || key] = value
|
11
|
+
result
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def merge(*items)
|
16
|
+
return nil if items.compact.empty?
|
17
|
+
items.compact.inject({}){|sum, item| sum.merge!(item)}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/a9n/loader.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module A9n
|
4
|
+
class Loader
|
5
|
+
attr_reader :env, :local_file, :example_file
|
6
|
+
|
7
|
+
def initialize(file_path, env)
|
8
|
+
@env = env.to_s
|
9
|
+
@local_file = file_path
|
10
|
+
@example_file = "#{file_path}.example"
|
11
|
+
end
|
12
|
+
|
13
|
+
def get
|
14
|
+
@struct ||= load
|
15
|
+
end
|
16
|
+
|
17
|
+
def load
|
18
|
+
env_example = self.class.load_yml(example_file, env)
|
19
|
+
env_local = self.class.load_yml(local_file, env)
|
20
|
+
default_example = self.class.load_yml(example_file, "defaults")
|
21
|
+
default_local = self.class.load_yml(local_file, "defaults")
|
22
|
+
|
23
|
+
if env_example.nil? && env_local.nil? && default_example.nil? && default_local.nil?
|
24
|
+
raise A9n::MissingConfigurationData.new("Configuration data for *#{env}* env was not found in neither *#{example_file}* nor *#{local_file}*")
|
25
|
+
end
|
26
|
+
|
27
|
+
example = A9n::HashExt.merge(default_example, env_example)
|
28
|
+
local = A9n::HashExt.merge(default_local, env_local)
|
29
|
+
|
30
|
+
if !example.nil? && !local.nil?
|
31
|
+
verify!(example, local)
|
32
|
+
end
|
33
|
+
|
34
|
+
@struct = A9n::Struct.new(local || example)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.load_yml(file_path, env)
|
38
|
+
return nil unless File.exists?(file_path)
|
39
|
+
yml = YAML.load(ERB.new(File.read(file_path)).result)
|
40
|
+
|
41
|
+
if yml[env].is_a?(::Hash)
|
42
|
+
A9n::HashExt.deep_symbolize_keys(yml[env])
|
43
|
+
else
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def verify!(example, local)
|
51
|
+
missing_keys = example.keys - local.keys
|
52
|
+
if missing_keys.any?
|
53
|
+
raise A9n::MissingConfigurationVariables.new("Following variables are missing in #{local_file} file: #{missing_keys.join(",")}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/a9n/struct.rb
CHANGED
data/lib/a9n/version.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe A9n do
|
4
|
+
subject { described_class }
|
5
|
+
|
6
|
+
let(:env) { "test" }
|
7
|
+
|
8
|
+
before {
|
9
|
+
subject.app = double(env: env)
|
10
|
+
subject.root = File.expand_path("../../../test_app", __FILE__)
|
11
|
+
}
|
12
|
+
|
13
|
+
after {
|
14
|
+
subject.instance_variable_set(:@env, nil)
|
15
|
+
subject.root = nil
|
16
|
+
subject.app = nil
|
17
|
+
}
|
18
|
+
|
19
|
+
context "base config file" do
|
20
|
+
it {
|
21
|
+
expect(subject.default_dwarf).to eq("default dwarf")
|
22
|
+
expect(subject.overriden_dwarf).to eq("already overriden dwarf")
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
context "undefined env" do
|
27
|
+
let(:env) { "tropical" }
|
28
|
+
it {
|
29
|
+
expect(subject.default_dwarf).to eq("default dwarf")
|
30
|
+
expect(subject.overriden_dwarf).to eq("not yet overriden dwarf")
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
context "extra config file" do
|
35
|
+
it {
|
36
|
+
expect(subject.mandrill).to be_kind_of(A9n::Struct)
|
37
|
+
expect(subject.mandrill.username).to eq("joe")
|
38
|
+
expect(subject.mandrill.api_key).to eq("asdf1234")
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,198 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe A9n do
|
4
|
+
subject { described_class }
|
5
|
+
|
6
|
+
after {
|
7
|
+
subject.instance_variable_set(:@env, nil)
|
8
|
+
subject.root = nil
|
9
|
+
subject.app = nil
|
10
|
+
}
|
11
|
+
|
12
|
+
describe ".env" do
|
13
|
+
before {
|
14
|
+
subject.instance_variable_set(:@env, nil)
|
15
|
+
}
|
16
|
+
|
17
|
+
context "app_env is set" do
|
18
|
+
before {
|
19
|
+
expect(subject).to receive(:app).and_return(double(env: "dwarf_env")).exactly(3).times
|
20
|
+
expect(subject).to receive(:get_env_var).never
|
21
|
+
}
|
22
|
+
|
23
|
+
it { expect(subject.env).to eq("dwarf_env") }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when APP_ENV is set" do
|
27
|
+
before {
|
28
|
+
expect(subject).to receive(:app_env).and_return(nil)
|
29
|
+
expect(subject).to receive(:get_env_var).with("RAILS_ENV").and_return(nil)
|
30
|
+
expect(subject).to receive(:get_env_var).with("RACK_ENV").and_return(nil)
|
31
|
+
expect(subject).to receive(:get_env_var).with("APP_ENV").and_return("dwarf_env")
|
32
|
+
}
|
33
|
+
|
34
|
+
it { expect(subject.env).to eq("dwarf_env") }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe ".app" do
|
39
|
+
context "when rails not found" do
|
40
|
+
before {
|
41
|
+
expect(subject).to receive(:get_rails).and_return(nil)
|
42
|
+
}
|
43
|
+
specify {
|
44
|
+
expect(subject.app).to be_nil
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when rails app is being used" do
|
49
|
+
let(:app) { double(env: "test", root: "/apps/a9n") }
|
50
|
+
before {
|
51
|
+
expect(subject).to receive(:get_rails).and_return(app)
|
52
|
+
}
|
53
|
+
|
54
|
+
specify { expect(subject.app).to eq(app) }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when custom non-rails app is being used" do
|
58
|
+
let(:app) { double(env: "test", root: "/apps/a9n") }
|
59
|
+
before { subject.app = app }
|
60
|
+
|
61
|
+
specify { expect(subject.app).to eq(app) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe ".root" do
|
66
|
+
let(:app) { double(env: "test", root: "/apps/a9n") }
|
67
|
+
before { subject.app = app }
|
68
|
+
|
69
|
+
context "with custom path" do
|
70
|
+
before {
|
71
|
+
subject.root = "/home/knapo/workspace/a9n"
|
72
|
+
}
|
73
|
+
specify {
|
74
|
+
expect(subject.root).to eq(Pathname.new("/home/knapo/workspace/a9n"))
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with local app path" do
|
79
|
+
specify {
|
80
|
+
expect(subject.root).to eq("/apps/a9n")
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe ".get_rails" do
|
86
|
+
context "when defined" do
|
87
|
+
before {
|
88
|
+
Object.const_set(:Rails, Module.new)
|
89
|
+
}
|
90
|
+
after {
|
91
|
+
Object.send(:remove_const, :Rails)
|
92
|
+
}
|
93
|
+
it {
|
94
|
+
expect(subject.get_rails).to be_kind_of(Module)
|
95
|
+
}
|
96
|
+
end
|
97
|
+
context "when not defined" do
|
98
|
+
it { expect(subject.get_rails).to be_nil }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe ".get_env_var" do
|
103
|
+
before { ENV["DWARF"] = "little dwarf" }
|
104
|
+
it { expect(subject.get_env_var("DWARF")).to eq("little dwarf")}
|
105
|
+
it { expect(subject.get_env_var("IS_DWARF")).to be_nil}
|
106
|
+
end
|
107
|
+
|
108
|
+
describe ".var_name_for" do
|
109
|
+
it { expect(subject.var_name_for(:configuration)).to eq(:@configuration) }
|
110
|
+
it { expect(subject.var_name_for("configuration.yml")).to eq(:@configuration) }
|
111
|
+
it { expect(subject.var_name_for("custom_dir/extra.yml")).to eq(:@extra) }
|
112
|
+
end
|
113
|
+
|
114
|
+
describe ".fetch" do
|
115
|
+
let(:example_config) { A9n::Struct.new({hello: "world"}) }
|
116
|
+
before {
|
117
|
+
expect(subject).to receive(:scope).with(subject::DEFAULT_SCOPE).twice.and_return(example_config)
|
118
|
+
}
|
119
|
+
it {
|
120
|
+
expect(subject.fetch(:hello)).to eq("world")
|
121
|
+
expect(subject.fetch(:wold)).to eq(nil)
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
describe ".scope" do
|
126
|
+
context "when config has been loaded" do
|
127
|
+
before {
|
128
|
+
subject.instance_variable_set(:@custom1, { api_key: '1234asdf'})
|
129
|
+
expect(subject).to receive(:load).never
|
130
|
+
}
|
131
|
+
it {
|
132
|
+
expect(subject.scope(:custom1)).to eq({ api_key: '1234asdf'})
|
133
|
+
}
|
134
|
+
end
|
135
|
+
context "when config has not been loaded yet" do
|
136
|
+
it {
|
137
|
+
expect(subject).to receive(:load)
|
138
|
+
subject.scope(:custom2)
|
139
|
+
}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe ".default_files" do
|
144
|
+
before {
|
145
|
+
subject.root = File.expand_path("../../../test_app", __FILE__)
|
146
|
+
}
|
147
|
+
it {
|
148
|
+
expect(subject.default_files[0]).to include("configuration.yml")
|
149
|
+
expect(Pathname.new(subject.default_files[0])).to be_absolute
|
150
|
+
expect(subject.default_files[1]).to include("a9n/mandrill.yml")
|
151
|
+
expect(Pathname.new(subject.default_files[1])).to be_absolute
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
describe ".load" do
|
156
|
+
before {
|
157
|
+
expect(described_class).to receive(:env).exactly(2).times.and_return("dev")
|
158
|
+
subject.root = "/apps/test_app"
|
159
|
+
files.each do |f, cfg|
|
160
|
+
expect(A9n::Loader).to receive(:new).with(f, "dev").and_return(double(get: cfg))
|
161
|
+
end
|
162
|
+
}
|
163
|
+
context "when no files given" do
|
164
|
+
let(:files) {
|
165
|
+
{
|
166
|
+
"/apps/test_app/config/file1.yml" => { host: "host1.com" },
|
167
|
+
"/apps/test_app/config/dir/file2.yml" => { host: "host2.com" }
|
168
|
+
}
|
169
|
+
}
|
170
|
+
before {
|
171
|
+
expect(subject).to receive(:default_files).and_return(files.keys)
|
172
|
+
expect(subject).to receive(:get_absolute_paths_for).never
|
173
|
+
}
|
174
|
+
it {
|
175
|
+
expect(subject.load).to eq(files.values)
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
context "when custom files given" do
|
180
|
+
let(:given_files) {
|
181
|
+
["file3.yml", "/apps/test_app/config/dir/file4.yml"]
|
182
|
+
}
|
183
|
+
let(:files) {
|
184
|
+
{
|
185
|
+
"/apps/test_app/config/file3.yml" => { host: "host3.com" },
|
186
|
+
"/apps/test_app/config/dir/file4.yml" => { host: "host4.com" }
|
187
|
+
}
|
188
|
+
}
|
189
|
+
before {
|
190
|
+
expect(subject).to receive(:default_files).never
|
191
|
+
expect(subject).to receive(:get_absolute_paths_for).with(given_files).and_call_original
|
192
|
+
}
|
193
|
+
it {
|
194
|
+
expect(subject.load(*given_files)).to eq(files.values)
|
195
|
+
}
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe A9n::Loader do
|
4
|
+
let(:env) { "test" }
|
5
|
+
let(:root) { File.expand_path("../../../test_app", __FILE__) }
|
6
|
+
let(:file_path) { File.join(root, "config/configuration.yml") }
|
7
|
+
subject { described_class.new(file_path, env) }
|
8
|
+
|
9
|
+
describe "#intialize" do
|
10
|
+
it { expect(subject.env).to eq(env) }
|
11
|
+
it { expect(subject.local_file).to eq(file_path) }
|
12
|
+
it { expect(subject.example_file).to eq("#{file_path}.example") }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#load" do
|
16
|
+
let(:example_env_config) {
|
17
|
+
{ app_url: "http://127.0.0.1:3000", api_key: "base1234" }
|
18
|
+
}
|
19
|
+
let(:local_env_config) {
|
20
|
+
{ app_host: "127.0.0.1:3000", api_key: "local1234" }
|
21
|
+
}
|
22
|
+
let(:example_default_config) {
|
23
|
+
{ page_title: "Base Kielbasa", api_key: "example1234default" }
|
24
|
+
}
|
25
|
+
let(:local_default_config) {
|
26
|
+
{ page_title: "Local Kielbasa", api_key: "local1234default" }
|
27
|
+
}
|
28
|
+
let(:env){
|
29
|
+
"tropical"
|
30
|
+
}
|
31
|
+
let(:config) { subject.get }
|
32
|
+
|
33
|
+
context "when no configuration file exists" do
|
34
|
+
before do
|
35
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(nil)
|
36
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(nil)
|
37
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, "defaults").and_return(nil)
|
38
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, "defaults").and_return(nil)
|
39
|
+
expect(subject).to receive(:verify!).never
|
40
|
+
end
|
41
|
+
it "raises expection" do
|
42
|
+
expect {
|
43
|
+
subject.load
|
44
|
+
}.to raise_error(A9n::MissingConfigurationData)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when example configuration file exists with defaults" do
|
49
|
+
before do
|
50
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(example_env_config)
|
51
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(nil)
|
52
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, "defaults").and_return(example_default_config)
|
53
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, "defaults").and_return(nil)
|
54
|
+
|
55
|
+
expect(described_class).to receive(:verify!).never
|
56
|
+
subject.load
|
57
|
+
end
|
58
|
+
|
59
|
+
it { expect(config.app_url).to eq("http://127.0.0.1:3000") }
|
60
|
+
it { expect(config.page_title).to eq("Base Kielbasa") }
|
61
|
+
it { expect(config.api_key).to eq("base1234") }
|
62
|
+
|
63
|
+
it {
|
64
|
+
expect { config.app_host }.to raise_error(A9n::NoSuchConfigurationVariable)
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when local configuration file exists with defaults" do
|
69
|
+
before do
|
70
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(nil)
|
71
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(local_env_config)
|
72
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, "defaults").and_return(nil)
|
73
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, "defaults").and_return(local_default_config)
|
74
|
+
expect(described_class).to receive(:verify!).never
|
75
|
+
subject.load
|
76
|
+
end
|
77
|
+
it { expect(config.app_host).to eq("127.0.0.1:3000") }
|
78
|
+
it { expect(config.page_title).to eq("Local Kielbasa") }
|
79
|
+
it { expect(config.api_key).to eq("local1234") }
|
80
|
+
|
81
|
+
it {
|
82
|
+
expect { config.app_url }.to raise_error(A9n::NoSuchConfigurationVariable)
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when both local and base configuration file exists without defaults" do
|
87
|
+
context "with same data" do
|
88
|
+
before do
|
89
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(example_env_config)
|
90
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(example_env_config)
|
91
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, "defaults").and_return(nil)
|
92
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, "defaults").and_return(nil)
|
93
|
+
subject.load
|
94
|
+
end
|
95
|
+
|
96
|
+
it { expect(config.app_url).to eq("http://127.0.0.1:3000") }
|
97
|
+
it { expect(config.api_key).to eq("base1234") }
|
98
|
+
|
99
|
+
it {
|
100
|
+
expect { config.page_title }.to raise_error(A9n::NoSuchConfigurationVariable)
|
101
|
+
}
|
102
|
+
it {
|
103
|
+
expect { config.app_host }.to raise_error(A9n::NoSuchConfigurationVariable)
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
context "with different data" do
|
108
|
+
before do
|
109
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(example_env_config)
|
110
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(local_env_config)
|
111
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, "defaults").and_return(nil)
|
112
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, "defaults").and_return(nil)
|
113
|
+
end
|
114
|
+
it "raises expection" do
|
115
|
+
expect {
|
116
|
+
subject.load
|
117
|
+
}.to raise_error(A9n::MissingConfigurationVariables)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe ".load_yml" do
|
124
|
+
let(:env) { "test" }
|
125
|
+
subject { described_class.load_yml(file_path, env) }
|
126
|
+
|
127
|
+
context "when file not exists" do
|
128
|
+
let(:file_path) { "file_not_existing_in_universe.yml" }
|
129
|
+
|
130
|
+
it{ expect(subject).to be_nil }
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when file exists" do
|
134
|
+
let(:file_path) { File.join(root, "config/configuration.yml") }
|
135
|
+
|
136
|
+
before {
|
137
|
+
ENV["DWARF"] = "erbized dwarf"
|
138
|
+
}
|
139
|
+
|
140
|
+
context "and has data" do
|
141
|
+
it "returns non-empty hash" do
|
142
|
+
expect(subject).to be_kind_of(Hash)
|
143
|
+
expect(subject.keys).to_not be_empty
|
144
|
+
end
|
145
|
+
|
146
|
+
it "has symbolized keys" do
|
147
|
+
expect(subject.keys.first).to be_kind_of(Symbol)
|
148
|
+
expect(subject[:hash_dwarf]).to be_kind_of(Hash)
|
149
|
+
expect(subject[:hash_dwarf].keys.first).to be_kind_of(Symbol)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "parses erb" do
|
153
|
+
expect(subject[:erb_dwarf]).to eq("erbized dwarf")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "and has no data" do
|
158
|
+
let(:env) { "production" }
|
159
|
+
it{ expect(subject).to be_nil }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -47,8 +47,20 @@ describe A9n::Struct do
|
|
47
47
|
expect(subject.fetch(:non_empty_dwarf)).to eq('dwarf')
|
48
48
|
end
|
49
49
|
|
50
|
-
it '
|
50
|
+
it 'return false value' do
|
51
|
+
expect(subject.fetch(:false_dwarf)).to eq(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'return nil value' do
|
55
|
+
expect(subject.fetch(:nil_dwarf)).to eq(nil)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'return nil for non existing value' do
|
51
59
|
expect(subject.fetch(:non_existing_dwarf)).to eq(nil)
|
52
60
|
end
|
61
|
+
|
62
|
+
it 'return default for non existing value' do
|
63
|
+
expect(subject.fetch(:non_existing_dwarf, 'default')).to eq('default')
|
64
|
+
end
|
53
65
|
end
|
54
66
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
defaults:
|
2
|
+
default_dwarf: "example default dwarf"
|
3
|
+
overriden_dwarf: "example not yet overriden dwarf"
|
4
|
+
development:
|
5
|
+
nil_dwarf: ~
|
6
|
+
false_dwarf: false
|
7
|
+
true_dwarf: true
|
8
|
+
string_dwarf: "dwarf"
|
9
|
+
erb_dwarf: "<%= ENV['DWARF'] %>"
|
10
|
+
overriden_dwarf: "example already overriden dwarf"
|
11
|
+
hash_dwarf:
|
12
|
+
dwarf_1: "hello 1"
|
13
|
+
dwarf_2: "hello 2"
|
14
|
+
test:
|
15
|
+
nil_dwarf: ~
|
16
|
+
false_dwarf: false
|
17
|
+
true_dwarf: true
|
18
|
+
string_dwarf: "dwarf"
|
19
|
+
erb_dwarf: "<%= ENV['DWARF'] %>"
|
20
|
+
overriden_dwarf: "example already overriden dwarf"
|
21
|
+
hash_dwarf:
|
22
|
+
dwarf_1: "hello 1"
|
23
|
+
dwarf_2: "hello 2"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: a9n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Knapik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Simple tool for managing extra configuration in ruby/rails apps
|
14
14
|
email:
|
@@ -27,13 +27,18 @@ files:
|
|
27
27
|
- a9n.gemspec
|
28
28
|
- lib/a9n.rb
|
29
29
|
- lib/a9n/capistrano.rb
|
30
|
-
- lib/a9n/
|
30
|
+
- lib/a9n/ext/hash.rb
|
31
|
+
- lib/a9n/loader.rb
|
31
32
|
- lib/a9n/struct.rb
|
32
33
|
- lib/a9n/version.rb
|
33
|
-
- spec/a9n_spec.rb
|
34
|
-
- spec/fixtures/configuration.yml
|
34
|
+
- spec/integration/a9n_spec.rb
|
35
35
|
- spec/spec_helper.rb
|
36
|
-
- spec/
|
36
|
+
- spec/unit/a9n_spec.rb
|
37
|
+
- spec/unit/loader_spec.rb
|
38
|
+
- spec/unit/struct_spec.rb
|
39
|
+
- test_app/config/a9n/mandrill.yml
|
40
|
+
- test_app/config/configuration.yml
|
41
|
+
- test_app/config/configuration.yml.example
|
37
42
|
homepage: https://github.com/knapo/a9n
|
38
43
|
licenses:
|
39
44
|
- MIT
|
@@ -59,7 +64,8 @@ signing_key:
|
|
59
64
|
specification_version: 4
|
60
65
|
summary: a9n is a simple tool for managing extra configuration in ruby/rails apps
|
61
66
|
test_files:
|
62
|
-
- spec/a9n_spec.rb
|
63
|
-
- spec/fixtures/configuration.yml
|
67
|
+
- spec/integration/a9n_spec.rb
|
64
68
|
- spec/spec_helper.rb
|
65
|
-
- spec/
|
69
|
+
- spec/unit/a9n_spec.rb
|
70
|
+
- spec/unit/loader_spec.rb
|
71
|
+
- spec/unit/struct_spec.rb
|
data/lib/a9n/core_ext/hash.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
class Hash
|
2
|
-
# Hash#deep_symbolize_keys
|
3
|
-
# based on
|
4
|
-
# https://github.com/svenfuchs/i18n/blob/master/lib/i18n/core_ext/hash.rb
|
5
|
-
def deep_symbolize_keys
|
6
|
-
inject({}) { |result, (key, value)|
|
7
|
-
value = value.deep_symbolize_keys if value.is_a?(self.class)
|
8
|
-
result[(key.to_sym rescue key) || key] = value
|
9
|
-
result
|
10
|
-
}
|
11
|
-
end unless self.method_defined?(:deep_symbolize_keys)
|
12
|
-
|
13
|
-
def self.merge(*items)
|
14
|
-
return nil if items.compact.empty?
|
15
|
-
items.compact.inject({}){|sum, item| sum.merge!(item)}
|
16
|
-
end
|
17
|
-
end
|
data/spec/a9n_spec.rb
DELETED
@@ -1,295 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe A9n do
|
4
|
-
describe '.local_app' do
|
5
|
-
context 'when rails not found' do
|
6
|
-
before {
|
7
|
-
expect(described_class).to receive(:get_rails).and_return(nil)
|
8
|
-
}
|
9
|
-
specify {
|
10
|
-
expect(described_class.local_app).to be_nil
|
11
|
-
}
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'when custom non-rails app is being used' do
|
15
|
-
let(:local_app) { double(env: 'test', root: '/apps/a9n') }
|
16
|
-
before { described_class.local_app = local_app }
|
17
|
-
|
18
|
-
specify { expect(described_class.local_app).to eq(local_app) }
|
19
|
-
end
|
20
|
-
|
21
|
-
after { described_class.local_app = nil }
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '.root' do
|
25
|
-
let(:local_app) { double(env: 'test', root: '/apps/a9n') }
|
26
|
-
before { described_class.local_app = local_app }
|
27
|
-
|
28
|
-
context 'with custom path' do
|
29
|
-
before {
|
30
|
-
described_class.root = '/home/knapo/workspace/a9n'
|
31
|
-
}
|
32
|
-
specify {
|
33
|
-
expect(described_class.root).to eq(Pathname.new('/home/knapo/workspace/a9n'))
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'with local app path' do
|
38
|
-
specify {
|
39
|
-
expect(described_class.root).to eq('/apps/a9n')
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
after {
|
44
|
-
described_class.root = nil
|
45
|
-
described_class.local_app = nil
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '.load' do
|
50
|
-
let(:base_file) { described_class::DEFAULT_FILE }
|
51
|
-
let(:extra_file) { 'mongo.yml' }
|
52
|
-
let(:base_sample_config){
|
53
|
-
{ app_url: 'http://127.0.0.1:3000', api_key: 'base1234' }
|
54
|
-
}
|
55
|
-
let(:local_sample_config){
|
56
|
-
{ app_host: '127.0.0.1:3000', api_key: 'local1234' }
|
57
|
-
}
|
58
|
-
let(:base_default_config){
|
59
|
-
{ page_title: 'Base Kielbasa', api_key: 'base1234default' }
|
60
|
-
}
|
61
|
-
let(:local_default_config){
|
62
|
-
{ page_title: 'Local Kielbasa', api_key: 'local1234default' }
|
63
|
-
}
|
64
|
-
let(:env){
|
65
|
-
'tropical'
|
66
|
-
}
|
67
|
-
subject {
|
68
|
-
described_class
|
69
|
-
}
|
70
|
-
before do
|
71
|
-
allow(described_class).to receive(:env).and_return(env)
|
72
|
-
end
|
73
|
-
|
74
|
-
context 'when no configuration file exists' do
|
75
|
-
before do
|
76
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(nil)
|
77
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(nil)
|
78
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults').and_return(nil)
|
79
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults').and_return(nil)
|
80
|
-
expect(described_class).to receive(:verify!).never
|
81
|
-
end
|
82
|
-
it 'raises expection' do
|
83
|
-
expect {
|
84
|
-
described_class.load
|
85
|
-
}.to raise_error(described_class::MissingConfigurationData)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context 'when base configuration file exists with defaults' do
|
90
|
-
before do
|
91
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(base_sample_config)
|
92
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(nil)
|
93
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults').and_return(base_default_config)
|
94
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults').and_return(nil)
|
95
|
-
|
96
|
-
expect(described_class).to receive(:verify!).never
|
97
|
-
described_class.load
|
98
|
-
end
|
99
|
-
|
100
|
-
its(:app_url) { should_not be_nil }
|
101
|
-
its(:app_url) { should == subject.fetch(:app_url) }
|
102
|
-
its(:page_title) { should == 'Base Kielbasa' }
|
103
|
-
its(:api_key) { should == 'base1234' }
|
104
|
-
specify {
|
105
|
-
expect(subject.instance_variable_get("@configuration")).to be_kind_of(A9n::Struct)
|
106
|
-
}
|
107
|
-
specify {
|
108
|
-
expect { subject.app_host }.to raise_error(described_class::NoSuchConfigurationVariable)
|
109
|
-
}
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'when local configuration file exists with defaults' do
|
113
|
-
before do
|
114
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(nil)
|
115
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(local_sample_config)
|
116
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults').and_return(nil)
|
117
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults').and_return(local_default_config)
|
118
|
-
expect(described_class).to receive(:verify!).never
|
119
|
-
described_class.load
|
120
|
-
end
|
121
|
-
|
122
|
-
its(:app_host) { should_not be_nil }
|
123
|
-
its(:page_title) { should == 'Local Kielbasa' }
|
124
|
-
its(:api_key) { should == 'local1234' }
|
125
|
-
specify {
|
126
|
-
expect { subject.app_url }.to raise_error(described_class::NoSuchConfigurationVariable)
|
127
|
-
}
|
128
|
-
end
|
129
|
-
|
130
|
-
context 'when both local and base configuration file exists without defaults' do
|
131
|
-
context 'with same data' do
|
132
|
-
before do
|
133
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(base_sample_config)
|
134
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(base_sample_config)
|
135
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults').and_return(nil)
|
136
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults').and_return(nil)
|
137
|
-
described_class.load
|
138
|
-
end
|
139
|
-
|
140
|
-
its(:app_url) { should_not be_nil }
|
141
|
-
its(:api_key) { should == 'base1234' }
|
142
|
-
specify {
|
143
|
-
expect { subject.page_title }.to raise_error(described_class::NoSuchConfigurationVariable)
|
144
|
-
}
|
145
|
-
specify {
|
146
|
-
expect { subject.app_host }.to raise_error(described_class::NoSuchConfigurationVariable)
|
147
|
-
}
|
148
|
-
end
|
149
|
-
|
150
|
-
context 'with different data' do
|
151
|
-
before do
|
152
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(base_sample_config)
|
153
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(local_sample_config)
|
154
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults').and_return(nil)
|
155
|
-
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults').and_return(nil)
|
156
|
-
end
|
157
|
-
it 'raises expection' do
|
158
|
-
expect {
|
159
|
-
described_class.load
|
160
|
-
}.to raise_error(described_class::MissingConfigurationVariables)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
context 'when extra file is loaded' do
|
166
|
-
before do
|
167
|
-
expect(described_class).to receive(:load_yml).with("config/#{extra_file}.example", env).and_return(base_sample_config)
|
168
|
-
expect(described_class).to receive(:load_yml).with("config/#{extra_file}", env).and_return(nil)
|
169
|
-
expect(described_class).to receive(:load_yml).with("config/#{extra_file}.example", 'defaults').and_return(base_default_config)
|
170
|
-
expect(described_class).to receive(:load_yml).with("config/#{extra_file}", 'defaults').and_return(nil)
|
171
|
-
|
172
|
-
expect(described_class).to receive(:verify!).never
|
173
|
-
described_class.load('mongo.yml')
|
174
|
-
end
|
175
|
-
|
176
|
-
it { expect(subject.mongo).to be_kind_of(A9n::Struct) }
|
177
|
-
it { expect(subject.instance_variable_get("@mongo")).to be_kind_of(A9n::Struct) }
|
178
|
-
it { expect(subject.mongo.app_url).to eq("http://127.0.0.1:3000") }
|
179
|
-
it { expect(subject.mongo.page_title).to eq('Base Kielbasa') }
|
180
|
-
it { expect(subject.mongo.api_key).to eq('base1234') }
|
181
|
-
specify {
|
182
|
-
expect { subject.mongo.app_host }.to raise_error(described_class::NoSuchConfigurationVariable)
|
183
|
-
}
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
describe '.load_yml' do
|
188
|
-
let(:root) { File.dirname(__FILE__) }
|
189
|
-
let(:env) { 'test' }
|
190
|
-
subject { described_class.load_yml(file_path, env) }
|
191
|
-
|
192
|
-
before do
|
193
|
-
expect(described_class).to receive(:root).at_least(:once).and_return(root)
|
194
|
-
expect(described_class).to receive(:env).never
|
195
|
-
end
|
196
|
-
|
197
|
-
context 'when file not exists' do
|
198
|
-
let(:file_path) { 'file_not_existing_in_universe.yml' }
|
199
|
-
|
200
|
-
it 'returns nil' do
|
201
|
-
expect(subject).to be_nil
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
context 'when file exists' do
|
206
|
-
let(:file_path) { 'fixtures/configuration.yml'}
|
207
|
-
before {
|
208
|
-
ENV['DWARF'] = 'erbized dwarf'
|
209
|
-
}
|
210
|
-
|
211
|
-
context 'and has data' do
|
212
|
-
it 'returns non-empty hash' do
|
213
|
-
expect(subject).to be_kind_of(Hash)
|
214
|
-
expect(subject.keys).to_not be_empty
|
215
|
-
end
|
216
|
-
|
217
|
-
it 'has symbolized keys' do
|
218
|
-
expect(subject.keys.first).to be_kind_of(Symbol)
|
219
|
-
expect(subject[:hash_dwarf]).to be_kind_of(Hash)
|
220
|
-
expect(subject[:hash_dwarf].keys.first).to be_kind_of(Symbol)
|
221
|
-
end
|
222
|
-
|
223
|
-
it 'parses erb' do
|
224
|
-
expect(subject[:erb_dwarf]).to eq('erbized dwarf')
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
context 'and has no data' do
|
229
|
-
let(:env) { 'production' }
|
230
|
-
it { should be_nil }
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
describe '.env' do
|
236
|
-
before {
|
237
|
-
described_class.instance_variable_set(:@env, nil)
|
238
|
-
}
|
239
|
-
|
240
|
-
context 'local_app_env is set' do
|
241
|
-
before {
|
242
|
-
expect(described_class).to receive(:local_app).and_return(double(env: 'dwarf_env')).exactly(3).times
|
243
|
-
expect(described_class).to receive(:get_env_var).never
|
244
|
-
}
|
245
|
-
|
246
|
-
describe '#env' do
|
247
|
-
subject { super().env }
|
248
|
-
it { should == 'dwarf_env' }
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
context "when APP_ENV is set" do
|
253
|
-
before {
|
254
|
-
expect(described_class).to receive(:local_app_env).and_return(nil)
|
255
|
-
expect(described_class).to receive(:get_env_var).with('RAILS_ENV').and_return(nil)
|
256
|
-
expect(described_class).to receive(:get_env_var).with('RACK_ENV').and_return(nil)
|
257
|
-
expect(described_class).to receive(:get_env_var).with('APP_ENV').and_return('dwarf_env')
|
258
|
-
}
|
259
|
-
|
260
|
-
describe '#env' do
|
261
|
-
subject { super().env }
|
262
|
-
it { should == 'dwarf_env' }
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
describe '.get_env_var' do
|
268
|
-
before { ENV['DWARF'] = 'little dwarf' }
|
269
|
-
it { expect(described_class.get_env_var('DWARF')).to eq('little dwarf')}
|
270
|
-
it { expect(described_class.get_env_var('IS_DWARF')).to be_nil}
|
271
|
-
end
|
272
|
-
|
273
|
-
describe '.get_rails' do
|
274
|
-
context 'when defined' do
|
275
|
-
before {
|
276
|
-
Object.const_set(:Rails, Module.new)
|
277
|
-
}
|
278
|
-
after {
|
279
|
-
Object.send(:remove_const, :Rails)
|
280
|
-
}
|
281
|
-
it {
|
282
|
-
expect(described_class.get_rails).to be_kind_of(Module)
|
283
|
-
}
|
284
|
-
end
|
285
|
-
context 'when not defined' do
|
286
|
-
it { expect(described_class.get_rails).to be_nil }
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
describe '.var_name_for' do
|
291
|
-
it { expect(described_class.var_name_for(:configuration)).to eq(:@configuration) }
|
292
|
-
it { expect(described_class.var_name_for('configuration.yml')).to eq(:@configuration) }
|
293
|
-
it { expect(described_class.var_name_for('custom_dir/extra.yml')).to eq(:@extra) }
|
294
|
-
end
|
295
|
-
end
|