econfig 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: