seielit-figaro 1.1.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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +30 -0
  5. data/CHANGELOG.md +122 -0
  6. data/CONTRIBUTING.md +48 -0
  7. data/Gemfile +14 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +350 -0
  10. data/Rakefile +6 -0
  11. data/bin/figaro +5 -0
  12. data/gemfiles/rails41.gemfile +12 -0
  13. data/gemfiles/rails42.gemfile +12 -0
  14. data/gemfiles/rails50.gemfile +13 -0
  15. data/gemfiles/rails51.gemfile +13 -0
  16. data/gemfiles/rails52.gemfile +14 -0
  17. data/gemfiles/rails60.gemfile +14 -0
  18. data/lib/figaro.rb +33 -0
  19. data/lib/figaro/application.rb +91 -0
  20. data/lib/figaro/cli.rb +42 -0
  21. data/lib/figaro/cli/heroku_set.rb +33 -0
  22. data/lib/figaro/cli/install.rb +32 -0
  23. data/lib/figaro/cli/install/application.yml +11 -0
  24. data/lib/figaro/cli/task.rb +33 -0
  25. data/lib/figaro/env.rb +45 -0
  26. data/lib/figaro/error.rb +17 -0
  27. data/lib/figaro/rails.rb +7 -0
  28. data/lib/figaro/rails/application.rb +21 -0
  29. data/lib/figaro/rails/railtie.rb +10 -0
  30. data/lib/figaro/rails/tasks.rake +6 -0
  31. data/lib/figaro/settings.rb +124 -0
  32. data/seielit-figaro.gemspec +23 -0
  33. data/spec/figaro/application_spec.rb +262 -0
  34. data/spec/figaro/cli/heroku_set_spec.rb +67 -0
  35. data/spec/figaro/cli/install_spec.rb +49 -0
  36. data/spec/figaro/env_spec.rb +195 -0
  37. data/spec/figaro/rails/application_spec.rb +47 -0
  38. data/spec/figaro/settings_spec.rb +109 -0
  39. data/spec/figaro_spec.rb +106 -0
  40. data/spec/rails_spec.rb +50 -0
  41. data/spec/spec_helper.rb +13 -0
  42. data/spec/support/aruba.rb +19 -0
  43. data/spec/support/bin/heroku +5 -0
  44. data/spec/support/command_helpers.rb +17 -0
  45. data/spec/support/command_interceptor.rb +33 -0
  46. data/spec/support/reset.rb +13 -0
  47. metadata +145 -0
@@ -0,0 +1,67 @@
1
+ # describe "figaro heroku:set" do
2
+ # before do
3
+ # create_dir("example")
4
+ # cd("example")
5
+ # write_file("config/application.yml", "foo: bar")
6
+ # end
7
+
8
+ # it "sends Figaro configuration to Heroku" do
9
+ # run_simple("figaro heroku:set")
10
+
11
+ # command = commands.last
12
+ # expect(command.name).to eq("heroku")
13
+ # expect(command.args).to eq(["config:set", "foo=bar"])
14
+ # end
15
+
16
+ # it "respects path" do
17
+ # write_file("env.yml", "foo: bar")
18
+
19
+ # run_simple("figaro heroku:set -p env.yml")
20
+
21
+ # command = commands.last
22
+ # expect(command.name).to eq("heroku")
23
+ # expect(command.args).to eq(["config:set", "foo=bar"])
24
+ # end
25
+
26
+ # it "respects environment" do
27
+ # overwrite_file("config/application.yml", <<-EOF)
28
+ # foo: bar
29
+ # test:
30
+ # foo: baz
31
+ # EOF
32
+
33
+ # run_simple("figaro heroku:set -e test")
34
+
35
+ # command = commands.last
36
+ # expect(command.name).to eq("heroku")
37
+ # expect(command.args).to eq(["config:set", "foo=baz"])
38
+ # end
39
+
40
+ # it "targets a specific Heroku app" do
41
+ # run_simple("figaro heroku:set -a foo-bar-app")
42
+
43
+ # command = commands.last
44
+ # expect(command.name).to eq("heroku")
45
+ # expect(command.args.shift).to eq("config:set")
46
+ # expect(command.args).to match_array(["foo=bar", "--app=foo-bar-app"])
47
+ # end
48
+
49
+ # it "targets a specific Heroku git remote" do
50
+ # run_simple("figaro heroku:set -r production")
51
+
52
+ # command = commands.last
53
+ # expect(command.name).to eq("heroku")
54
+ # expect(command.args.shift).to eq("config:set")
55
+ # expect(command.args).to match_array(["foo=bar", "--remote=production"])
56
+ # end
57
+
58
+ # it "handles values with special characters" do
59
+ # overwrite_file("config/application.yml", "foo: bar baz")
60
+
61
+ # run_simple("figaro heroku:set")
62
+
63
+ # command = commands.last
64
+ # expect(command.name).to eq("heroku")
65
+ # expect(command.args).to eq(["config:set", "foo=bar baz"])
66
+ # end
67
+ # end
@@ -0,0 +1,49 @@
1
+ describe "figaro install" do
2
+ before do
3
+ create_dir("example")
4
+ cd("example")
5
+ end
6
+
7
+ it "creates a configuration file" do
8
+ run_simple("figaro install")
9
+
10
+ check_file_presence(["config/application.yml"], true)
11
+ end
12
+
13
+ it "respects path" do
14
+ run_simple("figaro install -p env.yml")
15
+
16
+ check_file_presence(["env.yml"], true)
17
+ end
18
+
19
+ context "with a .gitignore file" do
20
+ before do
21
+ write_file(".gitignore", <<-EOF)
22
+ /foo
23
+ /bar
24
+ EOF
25
+ end
26
+
27
+ it "Git-ignores the configuration file if applicable" do
28
+ run_simple("figaro install")
29
+
30
+ check_file_content(".gitignore", %r(^/foo$), true)
31
+ check_file_content(".gitignore", %r(^/bar$), true)
32
+ check_file_content(".gitignore", %r(^/config/application\.yml$), true)
33
+ end
34
+
35
+ it "respects path" do
36
+ run_simple("figaro install -p env.yml")
37
+
38
+ check_file_content(".gitignore", %r(^/env\.yml$), true)
39
+ end
40
+ end
41
+
42
+ context "without a .gitignore file" do
43
+ it "doesn't generate a new .gitignore file" do
44
+ run_simple("figaro install")
45
+
46
+ check_file_presence([".gitignore"], false)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,195 @@
1
+ describe Figaro::ENV do
2
+ subject(:env) { Figaro::ENV }
3
+
4
+ before do
5
+ ::ENV["HELLO"] = "world"
6
+ ::ENV["foo"] = "bar"
7
+ end
8
+
9
+ describe "#method_missing" do
10
+ context "plain methods" do
11
+ it "makes ENV values accessible as lowercase methods" do
12
+ expect(env.hello).to eq("world")
13
+ expect(env.foo).to eq("bar")
14
+ end
15
+
16
+ it "makes ENV values accessible as uppercase methods" do
17
+ expect(env.HELLO).to eq("world")
18
+ expect(env.FOO).to eq("bar")
19
+ end
20
+
21
+ it "makes ENV values accessible as mixed-case methods" do
22
+ expect(env.Hello).to eq("world")
23
+ expect(env.fOO).to eq("bar")
24
+ end
25
+
26
+ it "returns nil if no ENV key matches" do
27
+ expect(env.goodbye).to eq(nil)
28
+ end
29
+
30
+ it "respects a stubbed plain method" do
31
+ allow(env).to receive(:bar) { "baz" }
32
+ expect(env.bar).to eq("baz")
33
+ end
34
+ end
35
+
36
+ context "bang methods" do
37
+ it "makes ENV values accessible as lowercase methods" do
38
+ expect(env.hello!).to eq("world")
39
+ expect(env.foo!).to eq("bar")
40
+ end
41
+
42
+ it "makes ENV values accessible as uppercase methods" do
43
+ expect(env.HELLO!).to eq("world")
44
+ expect(env.FOO!).to eq("bar")
45
+ end
46
+
47
+ it "makes ENV values accessible as mixed-case methods" do
48
+ expect(env.Hello!).to eq("world")
49
+ expect(env.fOO!).to eq("bar")
50
+ end
51
+
52
+ it "raises an error if no ENV key matches" do
53
+ expect { env.goodbye! }.to raise_error(Figaro::MissingKey)
54
+ end
55
+
56
+ it "respects a stubbed plain method" do
57
+ allow(env).to receive(:bar) { "baz" }
58
+ expect { expect(env.bar!).to eq("baz") }.not_to raise_error
59
+ end
60
+ end
61
+
62
+ context "boolean methods" do
63
+ it "returns true for accessible, lowercase methods" do
64
+ expect(env.hello?).to eq(true)
65
+ expect(env.foo?).to eq(true)
66
+ end
67
+
68
+ it "returns true for accessible, uppercase methods" do
69
+ expect(env.HELLO?).to eq(true)
70
+ expect(env.FOO?).to eq(true)
71
+ end
72
+
73
+ it "returns true for accessible, mixed-case methods" do
74
+ expect(env.Hello?).to eq(true)
75
+ expect(env.fOO?).to eq(true)
76
+ end
77
+
78
+ it "returns false if no ENV key matches" do
79
+ expect(env.goodbye?).to eq(false)
80
+ end
81
+
82
+ it "respects a stubbed plain method" do
83
+ allow(env).to receive(:bar) { "baz" }
84
+ expect(env.bar?).to eq(true)
85
+ end
86
+ end
87
+
88
+ context "setter methods" do
89
+ it "raises an error for accessible, lowercase methods" do
90
+ expect { env.hello = "world" }.to raise_error(NoMethodError)
91
+ expect { env.foo = "bar" }.to raise_error(NoMethodError)
92
+ end
93
+
94
+ it "raises an error for accessible, uppercase methods" do
95
+ expect { env.HELLO = "world" }.to raise_error(NoMethodError)
96
+ expect { env.FOO = "bar" }.to raise_error(NoMethodError)
97
+ end
98
+
99
+ it "raises an error for accessible, mixed-case methods" do
100
+ expect { env.Hello = "world" }.to raise_error(NoMethodError)
101
+ expect { env.fOO = "bar" }.to raise_error(NoMethodError)
102
+ end
103
+
104
+ it "raises an error if no ENV key matches" do
105
+ expect { env.goodbye = "world" }.to raise_error(NoMethodError)
106
+ end
107
+ end
108
+ end
109
+
110
+ describe "#respond_to?" do
111
+ context "plain methods" do
112
+ it "returns true for accessible, lowercase methods" do
113
+ expect(env.respond_to?(:hello)).to eq(true)
114
+ expect(env.respond_to?(:foo)).to eq(true)
115
+ end
116
+
117
+ it "returns true for accessible uppercase methods" do
118
+ expect(env.respond_to?(:HELLO)).to eq(true)
119
+ expect(env.respond_to?(:FOO)).to eq(true)
120
+ end
121
+
122
+ it "returns true for accessible mixed-case methods" do
123
+ expect(env.respond_to?(:Hello)).to eq(true)
124
+ expect(env.respond_to?(:fOO)).to eq(true)
125
+ end
126
+
127
+ it "returns true if no ENV key matches" do
128
+ expect(env.respond_to?(:baz)).to eq(true)
129
+ end
130
+ end
131
+
132
+ context "bang methods" do
133
+ it "returns true for accessible, lowercase methods" do
134
+ expect(env.respond_to?(:hello!)).to eq(true)
135
+ expect(env.respond_to?(:foo!)).to eq(true)
136
+ end
137
+
138
+ it "returns true for accessible uppercase methods" do
139
+ expect(env.respond_to?(:HELLO!)).to eq(true)
140
+ expect(env.respond_to?(:FOO!)).to eq(true)
141
+ end
142
+
143
+ it "returns true for accessible mixed-case methods" do
144
+ expect(env.respond_to?(:Hello!)).to eq(true)
145
+ expect(env.respond_to?(:fOO!)).to eq(true)
146
+ end
147
+
148
+ it "returns false if no ENV key matches" do
149
+ expect(env.respond_to?(:baz!)).to eq(false)
150
+ end
151
+ end
152
+
153
+ context "boolean methods" do
154
+ it "returns true for accessible, lowercase methods" do
155
+ expect(env.respond_to?(:hello?)).to eq(true)
156
+ expect(env.respond_to?(:foo?)).to eq(true)
157
+ end
158
+
159
+ it "returns true for accessible uppercase methods" do
160
+ expect(env.respond_to?(:HELLO?)).to eq(true)
161
+ expect(env.respond_to?(:FOO?)).to eq(true)
162
+ end
163
+
164
+ it "returns true for accessible mixed-case methods" do
165
+ expect(env.respond_to?(:Hello?)).to eq(true)
166
+ expect(env.respond_to?(:fOO?)).to eq(true)
167
+ end
168
+
169
+ it "returns true if no ENV key matches" do
170
+ expect(env.respond_to?(:baz?)).to eq(true)
171
+ end
172
+ end
173
+
174
+ context "setter methods" do
175
+ it "returns false for accessible, lowercase methods" do
176
+ expect(env.respond_to?(:hello=)).to eq(false)
177
+ expect(env.respond_to?(:foo=)).to eq(false)
178
+ end
179
+
180
+ it "returns false for accessible uppercase methods" do
181
+ expect(env.respond_to?(:HELLO=)).to eq(false)
182
+ expect(env.respond_to?(:FOO=)).to eq(false)
183
+ end
184
+
185
+ it "returns false for accessible mixed-case methods" do
186
+ expect(env.respond_to?(:Hello=)).to eq(false)
187
+ expect(env.respond_to?(:fOO=)).to eq(false)
188
+ end
189
+
190
+ it "returns false if no ENV key matches" do
191
+ expect(env.respond_to?(:baz=)).to eq(false)
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,47 @@
1
+ require 'figaro/rails/application'
2
+
3
+ module Figaro
4
+ module Rails
5
+ describe Application do
6
+ before do
7
+ stub_const('Rails', double('Rails'))
8
+ end
9
+
10
+ describe "#default_path" do
11
+ let!(:application) { Application.new }
12
+
13
+ it "defaults to config/application.yml in Rails.root" do
14
+ allow(::Rails).to receive(:root) { Pathname.new("/path/to/app") }
15
+
16
+ expect {
17
+ allow(::Rails).to receive(:root) { Pathname.new("/app") }
18
+ }.to change {
19
+ application.send(:default_path).to_s
20
+ }.from("/path/to/app/config/application.yml").to("/app/config/application.yml")
21
+ end
22
+
23
+ it "raises an error when Rails.root isn't set yet" do
24
+ allow(::Rails).to receive(:root) { nil }
25
+
26
+ expect {
27
+ application.send(:default_path)
28
+ }.to raise_error(RailsNotInitialized)
29
+ end
30
+ end
31
+
32
+ describe "#default_environment" do
33
+ let!(:application) { Application.new }
34
+
35
+ it "defaults to Rails.env" do
36
+ allow(::Rails).to receive(:env) { "development" }
37
+
38
+ expect {
39
+ allow(::Rails).to receive(:env) { "test" }
40
+ }.to change {
41
+ application.send(:default_environment).to_s
42
+ }.from("development").to("test")
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,109 @@
1
+ describe Figaro::Settings do
2
+ subject(:set) { Figaro::Settings }
3
+
4
+ before do
5
+ ::ENV["HELLO"] = "1234"
6
+ ::ENV["foo"] = "bar"
7
+ ::ENV["foo__bar"] = "baz"
8
+
9
+ ::ENV["true1"] = "on"
10
+ ::ENV["true2"] = "true"
11
+ ::ENV["true3"] = "yes"
12
+ ::ENV["true4"] = "enabled"
13
+
14
+ ::ENV["false1"] = "off"
15
+ ::ENV["false2"] = "false"
16
+ ::ENV["false3"] = "no"
17
+ ::ENV["false4"] = "disabled"
18
+ end
19
+
20
+ describe "#[]" do
21
+ context "building key" do
22
+ it "builds a simple key correctly" do
23
+ expect(set[:foo].key).to eq('foo')
24
+ end
25
+
26
+ it "builds a namespaced key correctly" do
27
+ expect(set[:foo][:bar].key).to eq('foo__bar')
28
+ end
29
+ end
30
+
31
+ context "accessing values" do
32
+ it "makes ENV values accessible using a simple key" do
33
+ expect(set[:foo].value).to eq('bar')
34
+ end
35
+ it "makes ENV values accessible using a namespaced key" do
36
+ expect(set[:foo][:bar].value).to eq('baz')
37
+ end
38
+ end
39
+
40
+ context "type conversion" do
41
+ context "plain methods" do
42
+ it "converts correct values successfully" do
43
+ expect(set[:foo].string).to eq('bar')
44
+ expect(set[:hello].int).to eq(1234)
45
+ expect(set[:hello].float).to eq(1234.0)
46
+ expect(set[:hello].decimal).to eq(BigDecimal(1234))
47
+ expect(set[:true1].bool).to be(true)
48
+ expect(set[:true2].bool).to be(true)
49
+ expect(set[:true3].bool).to be(true)
50
+ expect(set[:true4].bool).to be(true)
51
+ expect(set[:false1].bool).to be(false)
52
+ expect(set[:false2].bool).to be(false)
53
+ expect(set[:false3].bool).to be(false)
54
+ expect(set[:false4].bool).to be(false)
55
+ end
56
+
57
+ it "returns nil when value is invalid or non existing" do
58
+ expect(set[:foo].int).to be_nil
59
+ expect(set[:foos].int).to be_nil
60
+ end
61
+ end
62
+
63
+ context "bang methods" do
64
+ it "converts correct values successfully" do
65
+ expect(set[:foo].string!).to eq('bar')
66
+ expect(set[:hello].int!).to eq(1234)
67
+ expect(set[:hello].float!).to eq(1234.0)
68
+ expect(set[:hello].decimal!).to eq(BigDecimal(1234))
69
+ end
70
+
71
+ it "raises when value is invalid" do
72
+ expect { set[:foo].int! }.to raise_error(Figaro::Settings::DataTypes::InvalidKey)
73
+ expect { set[:foos].int! }.to raise_error(Figaro::Settings::DataTypes::InvalidKey)
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "extending" do
80
+ context "requiring" do
81
+ it "requires valid settings without raising error" do
82
+ expect {
83
+ class TestSettings < Figaro::Settings
84
+ requires :hello,
85
+ :int
86
+ requires :foo
87
+ end
88
+ }.not_to raise_error
89
+ end
90
+
91
+ it "requires raises an error when requiring non-existing setting" do
92
+ expect {
93
+ class TestSettings < Figaro::Settings
94
+ requires :foos
95
+ end
96
+ }.to raise_error(Figaro::MissingKey)
97
+ end
98
+
99
+ it "requires raises an error when requiring invalid setting" do
100
+ expect {
101
+ class TestSettings < Figaro::Settings
102
+ requires :foo,
103
+ :int
104
+ end
105
+ }.to raise_error(Figaro::Settings::DataTypes::InvalidKey)
106
+ end
107
+ end
108
+ end
109
+ end