econfig 0.1.1 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a7e3bc4fa45ea6ef51d0dce442bf13f51d2d4ba4
4
- data.tar.gz: d870600bc13249713c6b91ac7e5a92a74cbf1537
3
+ metadata.gz: 5c5fb4ddc1d04e679fa21343c08f42bbe036033b
4
+ data.tar.gz: 2bbfcc7f840f8332c6257cc7a97937284c78a607
5
5
  SHA512:
6
- metadata.gz: b1145170d7baccae21942224722b5c8efd02315133a7d8179c545fdd0f6b0288d11f93412b93c7ff02029b66976bd789fb7e85a2f7d09a301cae27cd6d5ce837
7
- data.tar.gz: cee5b2354df7abf3185749e9805873747b241b8264e12e4cc96e4d87c5e457887f6c684ef2874c9ff98b2bec894ff634dff85ffc4fd0fbf754e97f1c3f7a2584
6
+ metadata.gz: 62fa0da6fb4838ccca0e12f48c2ee9f8b91ce4641554a3b1f2c88315f09b7b68816170e5a10fa1f684cda33e07a28f78d40d7a59d01cf505993d542fb05c5d0d
7
+ data.tar.gz: 5f00b0e0828f7084f589ecae5d8ba0594555db22a5d6a6d4d4012099438dee17e3620acfa4ef58e42d4ad8d1df0e4687472ac8adb5c1aca43f815cfa6c4714b2
data/README.md CHANGED
@@ -1,53 +1,48 @@
1
1
  # Econfig
2
2
 
3
- Econfig is a gem which allows you to easily configure your Rails applications
3
+ Econfig is a gem which allows you to easily configure your Ruby applications
4
4
  in a multitude of ways.
5
5
 
6
6
  ## Installation
7
7
 
8
- Add this to your gemfile:
8
+ Add this to your Gemfile:
9
9
 
10
10
  ``` ruby
11
- gem "econfig", :require => "econfig/rails"
11
+ gem "econfig"
12
12
  ```
13
13
 
14
- ## Accessing config options
15
-
16
- Econfig extends the Rails configuration, you can use it like this:
14
+ If you're using Rails, you'll want to require the Rails extension:
17
15
 
18
16
  ``` ruby
19
- MyApp::Application.config.app.aws_access_key
17
+ gem "econfig", require: "econfig/rails"
20
18
  ```
21
19
 
22
- Where `MyApp` is the name of your application and `aws_access_key` is whatever
23
- property you want to access. We recommend you add the shortcut module so you
24
- can access config options directly:
20
+ ## Accessing config options
21
+
22
+ Extend your main application module with the Econfig shortcut. In Rails, you'll
23
+ want to add this in `config/application.rb`:
25
24
 
26
25
  ``` ruby
27
26
  module MyApp
28
27
  extend Econfig::Shortcut
29
28
 
30
-
29
+ class Application < Rails::Application
30
+
31
+ end
31
32
  end
32
33
  ```
33
34
 
34
- In `config/application.rb`. This will give you:
35
+ Now you can access configuration like this:
35
36
 
36
37
  ``` ruby
37
- MyApp.aws_access_key_id
38
+ MyApp.config.aws_access_key_id
38
39
  ```
39
40
 
40
- which is obviously way more convenient. The rest of this README is going to
41
- assume that you added this shortcut.
42
-
43
- ## Forcing an option to exist
44
-
45
- Sometimes you want the application to crash early when a given config option is
46
- not set. Just add a bang (!) after the option name, and an error will be thrown
47
- if it is not set to a value which is present.
41
+ If the key you accessed is not configured, Econfig will raise an error. To
42
+ access optional configuration, which can be nil, use brackets:
48
43
 
49
44
  ``` ruby
50
- MyApp.aws_access_key_id!
45
+ MyApp.config[:aws_access_key_id]
51
46
  ```
52
47
 
53
48
  ## Configuring options.
@@ -58,14 +53,16 @@ You can specify configuration through:
58
53
  2. Redis
59
54
  3. Relational database
60
55
  4. YAML files
56
+ 5. OSX Keychain
61
57
 
62
- This allows you to set up econfig on most kinds of hosting solutions
58
+ This allows you to set up Econfig on most kinds of hosting solutions
63
59
  (EngineYard, Heroku, etc) without any additional effort, and to switch between
64
- them easily. The options are listed in descending order of preference.
60
+ them easily.
65
61
 
66
62
  ### ENV variables
67
63
 
68
- Just set an environment variable whose name is the name of the option being accessed uppercased.
64
+ Just set an environment variable whose name is the name of the option being
65
+ accessed uppercased.
69
66
 
70
67
  For example:
71
68
 
@@ -73,14 +70,46 @@ For example:
73
70
  AWS_ACCESS_KEY_ID=xyz rails server
74
71
  ```
75
72
 
73
+ You can now read it like this:
74
+
75
+ ``` ruby
76
+ MyApp.config.aws_access_key_id # => "xyz"
77
+ ```
78
+
76
79
  This is especially convenient for Heroku.
77
80
 
81
+ ### YAML
82
+
83
+ Add a yaml file to `config/app.yml`. This should have a similar layout to `config/database.yml`:
84
+
85
+ ``` yaml
86
+ development:
87
+ aws_access_key_id: "xyz"
88
+ aws_secret_access_key: "xyz"
89
+ production:
90
+ aws_access_key_id: "xyz"
91
+ aws_secret_access_key: "xyz"
92
+ ```
93
+
94
+ Econfig also reads configuration from `config/secret.yml` which is the new
95
+ standard for secret configuration parameters in Rails 4.1.
96
+
78
97
  ### Relational database
79
98
 
80
- This needs to be explicitly enabled. In `config/application.rb` add this line:
99
+ This needs to be explicitly enabled. In `config/application.rb` add this code:
100
+
101
+ ``` ruby
102
+ require "econfig/active_record"
103
+ Econfig.backends.insert_after :env, :db, Econfig::ActiveRecord.new
104
+ ```
105
+
106
+ You probably want environment variables to take precendence over configuration
107
+ from ActiveRecord, hence the `insert_after`. If you'd rather have ActiveRecord
108
+ configuration take precendence you can use this instead:
81
109
 
82
110
  ``` ruby
83
- Econfig.use_database
111
+ require "econfig/active_record"
112
+ Econfig.backends.unshift :db, Econfig::ActiveRecord.new
84
113
  ```
85
114
 
86
115
  You will also need to create a migration to create the necessary database tables:
@@ -90,41 +119,45 @@ rails generate econfig:migration
90
119
  rake db:migrate
91
120
  ```
92
121
 
93
- You can now set options by assigning them:
122
+ ### Redis
123
+
124
+ This needs to be explicitly enabled. In `config/application.rb` add this code:
94
125
 
95
126
  ``` ruby
96
- MyApp.aws_access_key_id = "xyz"
127
+ require "econfig/redis"
128
+ redis = Redis.new(:host => "myredis.com")
129
+ Econfig.backends.insert_after :env, :redis, Econfig::Redis.new(redis)
97
130
  ```
98
131
 
99
- You may not use both Redis and relational database storage at the same time.
132
+ If you wish to namespace your keys in Redis, you can use [redis namespace](http://rubygems.org/gems/redis-namespace).
100
133
 
101
- ### Redis
134
+ ### OSX Keychain
102
135
 
103
- This needs to be explicitly enabled. In `config/application.rb` add this line:
136
+ For the OSX keychain backend, see [econfig-keychain](https://github.com/elabs/econfig-keychain).
104
137
 
105
- ``` ruby
106
- Econfig.use_redis Redis.new(:host => "myredis.com")
107
- ```
138
+ ## Setting values
108
139
 
109
- You can now set options by assigning them:
140
+ You can set options by simply assigning them:
110
141
 
111
142
  ``` ruby
112
- MyApp.aws_access_key_id = "xyz"
143
+ MyApp.config[:aws_access_key_id] = "xyz"
113
144
  ```
114
145
 
115
- You may not use both Redis and relational database storage at the same time.
146
+ This will set the value in the default write backend, which by default is
147
+ `:memory`. This means that by default, configuration which is set like this is
148
+ not persisted in any way.
116
149
 
117
- ### YAML
150
+ If you always want to assign values to a different backend, for example the
151
+ database backend, you can set the default write backend like this:
118
152
 
119
- Add a yaml file to `config/app.yml`. This should have a similar layout to `config/database.yml`:
153
+ ``` ruby
154
+ Econfig.default_write_backend = :db
155
+ ```
120
156
 
121
- ``` yaml
122
- development:
123
- aws_access_key_id: "xyz"
124
- aws_secret_access_key: "xyz"
125
- production:
126
- aws_access_key_id: "xyz"
127
- aws_secret_access_key: "xyz"
157
+ You can also explicitly supply the backend when setting a configuration value:
158
+
159
+ ``` ruby
160
+ MyApp.config[:db, :aws_access_key_id] = "xyz"
128
161
  ```
129
162
 
130
163
  ## License
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :spec
@@ -18,6 +18,9 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
20
 
21
+ gem.required_ruby_version = "~> 2.0"
22
+
23
+ gem.add_development_dependency "rake"
21
24
  gem.add_development_dependency "rspec"
22
25
  gem.add_development_dependency "activerecord"
23
26
  gem.add_development_dependency "sqlite3"
@@ -1,29 +1,25 @@
1
+ require "forwardable"
1
2
  require "econfig/version"
2
3
  require "econfig/memory"
3
4
  require "econfig/yaml"
4
5
  require "econfig/env"
5
6
  require "econfig/configuration"
6
7
  require "econfig/shortcut"
8
+ require "econfig/backend_collection"
7
9
 
8
10
  module Econfig
9
11
  class NotFound < StandardError; end
10
12
  class UninitializedError < StandardError; end
11
13
 
12
14
  class << self
15
+ extend Forwardable
16
+
13
17
  attr_accessor :root, :env, :instance
14
18
 
15
- def use_database
16
- require "econfig/active_record"
17
- Econfig.instance.backends << Econfig::ActiveRecord.new
18
- end
19
-
20
- def use_redis(redis)
21
- require "econfig/redis"
22
- Econfig.instance.backends << Econfig::Redis.new(redis)
23
- end
19
+ def_delegators :instance, :backends, :default_write_backend, :default_write_backend=
24
20
 
25
21
  def init
26
- Econfig.instance.backends.each do |backend|
22
+ backends.each do |backend|
27
23
  backend.init if backend.respond_to?(:init)
28
24
  end
29
25
  end
@@ -31,5 +27,9 @@ module Econfig
31
27
  end
32
28
 
33
29
  Econfig.instance = Econfig::Configuration.new
34
- Econfig.instance.backends << Econfig::ENV.new
35
- Econfig.instance.backends << Econfig::YAML.new
30
+
31
+ Econfig.default_write_backend = :memory
32
+ Econfig.backends.use :memory, Econfig::Memory.new
33
+ Econfig.backends.use :env, Econfig::ENV.new
34
+ Econfig.backends.use :secret, Econfig::YAML.new("config/secret.yml")
35
+ Econfig.backends.use :yaml, Econfig::YAML.new("config/app.yml")
@@ -0,0 +1,61 @@
1
+ module Econfig
2
+ class BackendCollection
3
+ include Enumerable
4
+
5
+ def initialize
6
+ @backends = []
7
+ end
8
+
9
+ def [](name)
10
+ pair = @backends.assoc(name)
11
+ pair.last if pair
12
+ end
13
+
14
+ def each
15
+ if block_given?
16
+ @backends.each { |(name, backend)| yield backend }
17
+ else
18
+ enum_for { @backends.length }
19
+ end
20
+ end
21
+
22
+ def push(name, backend)
23
+ exists‽(name)
24
+ @backends.push([name, backend])
25
+ end
26
+ alias_method :use, :push
27
+
28
+ def unshift(name, backend)
29
+ exists‽(name)
30
+ @backends.unshift([name, backend])
31
+ end
32
+
33
+ def insert_before(other, name, backend)
34
+ exists‽(name)
35
+ @backends.insert(index_of!(other), [name, backend])
36
+ end
37
+
38
+ def insert_after(other, name, backend)
39
+ exists‽(name)
40
+ @backends.insert(index_of!(other) + 1, [name, backend])
41
+ end
42
+
43
+ def delete(name)
44
+ @backends.delete_at(index_of!(name))
45
+ end
46
+
47
+ private
48
+
49
+ def exists‽(name)
50
+ raise KeyError, "#{name} is already set" if index_of(name)
51
+ end
52
+
53
+ def index_of!(name)
54
+ index_of(name) or raise KeyError, "#{name} is not set"
55
+ end
56
+
57
+ def index_of(name)
58
+ @backends.index(@backends.assoc(name))
59
+ end
60
+ end
61
+ end
@@ -1,35 +1,44 @@
1
1
  module Econfig
2
2
  class Configuration
3
+ attr_accessor :default_write_backend
4
+
3
5
  def backends
4
- @backends ||= []
6
+ @backends ||= BackendCollection.new
5
7
  end
6
8
 
7
- def get(key)
8
- backend = backends.find { |backend| backend.get(key) }
9
- backend.get(key) if backend
9
+ def fetch(key)
10
+ self[key] or raise Econfig::NotFound, "configuration key '#{key}' is not set"
10
11
  end
11
12
 
12
- def get!(key)
13
- get(key) or raise Econfig::NotFound, "configuration key '#{key}' is not set"
13
+ def [](key)
14
+ backends.each do |backend|
15
+ value = backend.get(key.to_s)
16
+ return value if value
17
+ end
18
+ nil
14
19
  end
15
20
 
16
- def set(key, value)
17
- backend = backends.find { |backend| backend.respond_to?(:set) }
18
- backend.set(key, value) if backend
21
+ def []=(backend_name = default_write_backend, key, value)
22
+ raise ArgumentError, "no backend given" unless backend_name
23
+ if backend = backends[backend_name]
24
+ backend.set(key, value)
25
+ else
26
+ raise KeyError, "#{backend_name} is not set"
27
+ end
19
28
  end
20
29
 
21
30
  def method_missing(name, *args)
22
- if name.to_s.end_with?("=")
23
- set(name.to_s.sub(/=$/, ""), args.first)
24
- elsif name.to_s.end_with?("!")
25
- get!(name.to_s.sub(/!$/, ""))
31
+ if respond_to?(name)
32
+ raise ArgumentError, "too many arguments (#{args.length} for 0)" if args.length > 0
33
+ fetch(name)
26
34
  else
27
- get(name.to_s)
35
+ super
28
36
  end
29
37
  end
30
38
 
31
- def respond_to?(*)
32
- true
39
+ def respond_to_missing?(name, *)
40
+ name = name.to_s
41
+ not(name.end_with?("=") or name.end_with?("!") or name.end_with?("?"))
33
42
  end
34
43
  end
35
44
  end
@@ -5,11 +5,11 @@ module Econfig
5
5
  end
6
6
 
7
7
  def get(key)
8
- @redis.get("econfig_#{key}")
8
+ @redis.get(key)
9
9
  end
10
10
 
11
11
  def set(key, value)
12
- @redis.set("econfig_#{key}", value)
12
+ @redis.set(key, value)
13
13
  end
14
14
  end
15
15
  end
@@ -1,11 +1,7 @@
1
1
  module Econfig
2
2
  module Shortcut
3
- def method_missing(name, *args)
4
- Econfig.instance.send(name, *args)
5
- end
6
-
7
- def respond_to?(*)
8
- true
3
+ def config
4
+ Econfig.instance
9
5
  end
10
6
  end
11
7
  end
@@ -1,3 +1,3 @@
1
1
  module Econfig
2
- VERSION = "0.1.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  module Econfig
2
2
  class YAML
3
- def initialize(path="config/app.yml")
3
+ def initialize(path)
4
4
  @path = path
5
5
  end
6
6
 
@@ -10,8 +10,9 @@ module Econfig
10
10
 
11
11
  def init
12
12
  require "yaml"
13
+ require "erb"
13
14
  if File.exist?(path)
14
- @options = ::YAML.load_file(path)[Econfig.env]
15
+ @options = ::YAML.load(::ERB.new(File.read(path)).result)[Econfig.env]
15
16
  else
16
17
  @options = {}
17
18
  end
@@ -0,0 +1,101 @@
1
+ describe Econfig::Configuration do
2
+ let(:collection) { Econfig::BackendCollection.new }
3
+ let(:memory) { double("memory") }
4
+ let(:yaml) { double("yaml") }
5
+
6
+ describe "#[]" do
7
+ it "retrieves a backend" do
8
+ collection.push :memory, memory
9
+ collection[:memory].should equal(memory)
10
+ end
11
+ end
12
+
13
+ describe "#each" do
14
+ it "can be called without a block to receive an enumerator" do
15
+ collection.push :memory, memory
16
+ collection.each.take(1).should eq([memory])
17
+ end
18
+ end
19
+
20
+ describe "#push" do
21
+ it "adds a new backend at the bottom" do
22
+ collection.push :memory, memory
23
+ collection.push :yaml, yaml
24
+ collection.to_a.should eq([memory, yaml])
25
+ end
26
+
27
+ it "is aliased as `use`" do
28
+ collection.use :memory, memory
29
+ collection.use :yaml, yaml
30
+ collection.to_a.should eq([memory, yaml])
31
+ end
32
+
33
+ it "raises an error if backend already exist" do
34
+ collection.push :memory, memory
35
+ expect { collection.push :memory, yaml }.to raise_error(KeyError, "memory is already set")
36
+ end
37
+ end
38
+
39
+ describe "#unshift" do
40
+ it "adds a new backend at the top" do
41
+ collection.unshift :memory, memory
42
+ collection.unshift :yaml, yaml
43
+ collection.to_a.should eq([yaml, memory])
44
+ end
45
+
46
+ it "raises an error if backend already exist" do
47
+ collection.unshift :memory, memory
48
+ expect { collection.unshift :memory, yaml }.to raise_error(KeyError, "memory is already set")
49
+ end
50
+ end
51
+
52
+ describe "#insert_before" do
53
+ it "adds a new before the given backend" do
54
+ collection.push :quox, :quox
55
+ collection.push :baz, :baz
56
+ collection.push :foo, :foo
57
+ collection.insert_before :baz, :memory, memory
58
+ collection.to_a.should eq([:quox, memory, :baz, :foo])
59
+ end
60
+
61
+ it "raises an error if the backend does not exist" do
62
+ expect { collection.insert_before :baz, :memory, memory }.to raise_error(KeyError, /baz is not set/)
63
+ end
64
+
65
+ it "raises an error if the backend already exists" do
66
+ collection.push :foo, :foo
67
+ expect { collection.insert_before :foo, :foo, memory }.to raise_error(KeyError, /foo is already set/)
68
+ end
69
+ end
70
+
71
+ describe "#insert_after" do
72
+ it "adds a new after the given backend" do
73
+ collection.push :quox, :quox
74
+ collection.push :baz, :baz
75
+ collection.push :foo, :foo
76
+ collection.insert_after :baz, :memory, memory
77
+ collection.to_a.should eq([:quox, :baz, memory, :foo])
78
+ end
79
+
80
+ it "raises an error if the backend does not exist" do
81
+ expect { collection.insert_after :baz, :memory, memory }.to raise_error(KeyError, /baz is not set/)
82
+ end
83
+
84
+ it "raises an error if the backend already exists" do
85
+ collection.push :foo, :foo
86
+ expect { collection.insert_after :foo, :foo, memory }.to raise_error(KeyError, /foo is already set/)
87
+ end
88
+ end
89
+
90
+ describe "#delete" do
91
+ it "removes the given backend" do
92
+ collection.push :memory, memory
93
+ collection.delete :memory
94
+ collection[:memory].should be_nil
95
+ end
96
+
97
+ it "raises an error if the backend does not exist" do
98
+ expect { collection.delete :redis }.to raise_error(KeyError, /redis is not set/)
99
+ end
100
+ end
101
+ end
@@ -1,2 +1,3 @@
1
1
  test:
2
2
  quox: baz
3
+ envir: '<%= ENV['ECONFIG_EXAMPLE'] %>'
@@ -3,76 +3,109 @@ describe Econfig::Configuration do
3
3
  let(:other_backend) { double }
4
4
  let(:config) { Econfig::Configuration.new }
5
5
 
6
- before { config.backends.push(backend, other_backend) }
6
+ before do
7
+ config.backends.push(:one, backend)
8
+ config.backends.push(:other, other_backend)
9
+ end
7
10
 
8
- describe "#get" do
11
+ describe "#[]" do
9
12
  it "returns response from first backend" do
10
13
  backend.stub(:get).with("foobar").and_return("elephant")
11
- config.get("foobar").should == "elephant"
14
+ config["foobar"].should == "elephant"
12
15
  end
13
16
 
14
17
  it "tries multiple backends until it finds a response" do
15
18
  backend.stub(:get).with("foobar").and_return(nil)
16
19
  other_backend.stub(:get).with("foobar").and_return("elephant")
17
- config.get("foobar").should == "elephant"
20
+ config["foobar"].should == "elephant"
18
21
  end
19
22
 
20
23
  it "returns nil if the key can't be found in any backend" do
21
24
  backend.stub(:get).with("foobar").and_return(nil)
22
25
  other_backend.stub(:get).with("foobar").and_return(nil)
23
- config.get("foobar").should == nil
26
+ config["foobar"].should == nil
24
27
  end
25
28
  end
26
29
 
27
- describe "#get!" do
30
+ describe "#[]=" do
31
+ it "sets response on given backend" do
32
+ backend.should_receive(:set).with("foobar", "elephant")
33
+ config[:one, "foobar"] = "elephant"
34
+ end
35
+
36
+ it "sets response on default backend if default backend is set" do
37
+ config.default_write_backend = :other
38
+ other_backend.should_receive(:set).with("foobar", "elephant")
39
+ config["foobar"] = "elephant"
40
+ end
41
+
42
+ it "raises an error if no backend given and no default backend is set" do
43
+ config.default_write_backend = nil
44
+ expect { config["foobar"] = "elephant" }.to raise_error(ArgumentError, "no backend given")
45
+ end
46
+
47
+ it "raises an error if the backend does not exist" do
48
+ expect { config[:does_not_exist, "foobar"] = "elephant" }.to raise_error(KeyError, "does_not_exist is not set")
49
+ end
50
+ end
51
+
52
+ describe "#fetch" do
28
53
  it "returns response from first backend" do
29
54
  backend.stub(:get).with("foobar").and_return("elephant")
30
- config.get!("foobar").should == "elephant"
55
+ config.fetch("foobar").should == "elephant"
31
56
  end
32
57
 
33
58
  it "tries multiple backends until it finds a response" do
34
59
  backend.stub(:get).with("foobar").and_return(nil)
35
60
  other_backend.stub(:get).with("foobar").and_return("elephant")
36
- config.get!("foobar").should == "elephant"
61
+ config.fetch("foobar").should == "elephant"
37
62
  end
38
63
 
39
64
  it "raises error if the key can't be found in any backend" do
40
65
  backend.stub(:get).with("foobar").and_return(nil)
41
66
  other_backend.stub(:get).with("foobar").and_return(nil)
42
- expect { config.get!("foobar") }.to raise_error(Econfig::NotFound)
67
+ expect { config.fetch("foobar") }.to raise_error(Econfig::NotFound)
43
68
  end
44
69
  end
45
70
 
46
- describe "#set" do
47
- it "sets response on first backend" do
48
- backend.should_receive(:set).with("foobar", "elephant")
49
- config.set("foobar", "elephant")
71
+ describe "#method_missing" do
72
+ it "calls fetch for normal methods" do
73
+ backend.stub(:get).with("foobar").and_return("elephant")
74
+ config.foobar.should == "elephant"
50
75
  end
51
76
 
52
- it "skips backends which don't have a set method" do
53
- other_backend.should_receive(:set).with("foobar", "elephant")
54
- config.set("foobar", "elephant")
77
+ it "raises NoMethodError for bang methods" do
78
+ expect { config.foobar! }.to raise_error(NoMethodError)
79
+ end
80
+
81
+ it "raises NoMethodError for query methods" do
82
+ expect { config.foobar? }.to raise_error(NoMethodError)
55
83
  end
56
84
 
57
- it "does nothing when no backend has a setter method" do
58
- config.set("foobar", "elephant")
85
+ it "raises NoMethodError for setter methods" do
86
+ expect { config.foobar = "bar" }.to raise_error(NoMethodError)
87
+ end
88
+
89
+ it "raises an error when giving arguments to a getter" do
90
+ expect { config.foobar "Hey" }.to raise_error(ArgumentError, "too many arguments (1 for 0)")
59
91
  end
60
92
  end
61
93
 
62
- describe "#method_missing" do
63
- it "calls get for normal methods" do
64
- config.should_receive(:get).with("foobar").and_return("elephant")
65
- config.foobar.should == "elephant"
94
+ describe "#respond_to?" do
95
+ it "return true for normal methods" do
96
+ config.should respond_to(:foobar)
97
+ end
98
+
99
+ it "return false for bang methods" do
100
+ config.should_not respond_to(:foobar!)
66
101
  end
67
102
 
68
- it "calls get! for bang methods" do
69
- config.should_receive(:get!).with("foobar").and_return("elephant")
70
- config.foobar!.should == "elephant"
103
+ it "return false for query methods" do
104
+ config.should_not respond_to(:foobar?)
71
105
  end
72
106
 
73
- it "calls set for assignment methods" do
74
- config.should_receive(:set).with("foobar", "elephant")
75
- config.foobar = "elephant"
107
+ it "return false for assignment methods" do
108
+ config.should_not respond_to(:foobar=)
76
109
  end
77
110
  end
78
111
  end
@@ -14,7 +14,7 @@ describe Econfig::Redis do
14
14
  end
15
15
 
16
16
  it "fetches a previously persisted option" do
17
- redis.set("econfig_foo", "bar")
17
+ redis.set("foo", "bar")
18
18
  backend.get("foo").should == "bar"
19
19
  end
20
20
 
@@ -26,7 +26,7 @@ describe Econfig::Redis do
26
26
  describe "#set" do
27
27
  it "persists keys to database" do
28
28
  backend.set("foo", "bar")
29
- redis.get("econfig_foo").should == "bar"
29
+ redis.get("foo").should == "bar"
30
30
  end
31
31
  end
32
32
  end
@@ -2,15 +2,9 @@ describe Econfig::Shortcut do
2
2
  let(:mod) { Module.new }
3
3
  before { mod.extend Econfig::Shortcut }
4
4
 
5
- describe "#method_missing" do
6
- it "proxies getters to the Econfig instance" do
7
- Econfig.instance.should_receive(:get).with("foobar").and_return("elephant")
8
- mod.foobar.should == "elephant"
9
- end
10
-
11
- it "proxies bang methods to the Econfig instance" do
12
- Econfig.instance.should_receive(:get!).with("foobar").and_return("elephant")
13
- mod.foobar!.should == "elephant"
5
+ describe "#config" do
6
+ it "should be the econfig instance" do
7
+ mod.config.should equal(Econfig.instance)
14
8
  end
15
9
  end
16
10
  end
@@ -1,5 +1,5 @@
1
1
  describe Econfig::YAML do
2
- let(:backend) { Econfig::YAML.new.tap(&:init) }
2
+ let(:backend) { Econfig::YAML.new("config/app.yml").tap(&:init) }
3
3
  describe "#get" do
4
4
  it "fetches option from yaml config file" do
5
5
  backend.get("quox").should == "baz"
@@ -13,5 +13,19 @@ describe Econfig::YAML do
13
13
  backend = Econfig::YAML.new("/does/not/exist").tap(&:init)
14
14
  backend.get("does_not_exist").should be_nil
15
15
  end
16
+
17
+ it "evaluates the YAML config as ERB" do
18
+ with_env do
19
+ ENV['ECONFIG_EXAMPLE'] = "onment"
20
+ backend.get("envir").should == "onment"
21
+ end
22
+ end
23
+
24
+ def with_env(&block)
25
+ original = ENV.to_hash
26
+ yield if block_given?
27
+ ensure
28
+ ENV.replace(original)
29
+ end
16
30
  end
17
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: econfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
@@ -9,8 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-01 00:00:00.000000000 Z
12
+ date: 2014-05-26 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: rspec
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +99,7 @@ files:
85
99
  - econfig.gemspec
86
100
  - lib/econfig.rb
87
101
  - lib/econfig/active_record.rb
102
+ - lib/econfig/backend_collection.rb
88
103
  - lib/econfig/configuration.rb
89
104
  - lib/econfig/env.rb
90
105
  - lib/econfig/memory.rb
@@ -97,6 +112,7 @@ files:
97
112
  - lib/generators/econfig/migration/migration_generator.rb
98
113
  - lib/generators/econfig/migration/templates/migration.rb
99
114
  - spec/active_record_spec.rb
115
+ - spec/backend_collection_spec.rb
100
116
  - spec/config/app.yml
101
117
  - spec/configuration_spec.rb
102
118
  - spec/env_spec.rb
@@ -115,9 +131,9 @@ require_paths:
115
131
  - lib
116
132
  required_ruby_version: !ruby/object:Gem::Requirement
117
133
  requirements:
118
- - - ">="
134
+ - - "~>"
119
135
  - !ruby/object:Gem::Version
120
- version: '0'
136
+ version: '2.0'
121
137
  required_rubygems_version: !ruby/object:Gem::Requirement
122
138
  requirements:
123
139
  - - ">="
@@ -131,6 +147,7 @@ specification_version: 4
131
147
  summary: Congifure Ruby apps
132
148
  test_files:
133
149
  - spec/active_record_spec.rb
150
+ - spec/backend_collection_spec.rb
134
151
  - spec/config/app.yml
135
152
  - spec/configuration_spec.rb
136
153
  - spec/env_spec.rb
@@ -139,3 +156,4 @@ test_files:
139
156
  - spec/shortcut_spec.rb
140
157
  - spec/spec_helper.rb
141
158
  - spec/yaml_spec.rb
159
+ has_rdoc: