gem_config 0.1.0 → 0.2.1

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: 9c0001fb2a37e49f309f7c050560a2ca0b809cba
4
- data.tar.gz: 23ec574b1a07a169eed85427076150eae6fdf62b
3
+ metadata.gz: 0e1e002c0aa0ae05fd05fd299a13669fb1a3c860
4
+ data.tar.gz: ee74c15d5b3f9103863532ee46219bafcfe3f4b9
5
5
  SHA512:
6
- metadata.gz: 1dc0f00e99dbf3d5592024f904dd2a22c65a808b21e4c34357c0f86e0d254027f2612d5cf43547fa941872f70398bf81d2e7c3198effab1e721ea1fce4593670
7
- data.tar.gz: 1e7485ca57cf804347732159e6563457a51600548c612b27efa1ef8d3b1da20bb3d1cec817810bad204a4fcfdac1fea0bb32ba186793c6053057dc433753ecc9
6
+ metadata.gz: 8b727372b3882e136e0015f86d68ffd90e641cac46dc694245ddc77cca4de314c5f44da11488412c16d4257729843a7fa5217ef1948f32c8cbf7471e457b9233
7
+ data.tar.gz: 165e49cc5088dcd039df12d34472506a04481cb29e6639415bc984ad2f95bc57551f41212cc1da07da365da742df44e9d9296f972cc8c991e0b96a50ba083032
data/README.md CHANGED
@@ -23,7 +23,54 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
- ## TODO
26
+ ### As a gem author
27
+
28
+ Include the gem and add configuration options like this:
29
+
30
+ ```ruby
31
+ # awesomeness.gemspec
32
+ Gem::Specification.new do |gem|
33
+ ...
34
+ gem.add_runtime_dependency 'gem_config'
35
+ end
36
+
37
+ # lib/awesomeness.rb
38
+ module Awesomeness
39
+ include GemConfig::Base
40
+
41
+ with_configuration do
42
+ has :api_key, classes: String
43
+ has :format, values: [:json, :xml], default: :json
44
+ has :region, values: ['us-west', 'us-east', 'eu'], default: 'us-west'
45
+ end
46
+ end
47
+ ```
48
+
49
+ Access the configuration values in the gem's code like this:
50
+
51
+ ```ruby
52
+ Awesomeness.configuration.api_key # Whatever the user set
53
+ ```
54
+
55
+ ### As a gem user
56
+
57
+ Include and configure a gem like this:
58
+
59
+ ```ruby
60
+ # Gemfile
61
+ gem 'awesomeness'
62
+
63
+ # config/initializers/awesomeness.rb
64
+ Awesomeness.configure do |config|
65
+ config.api_key = 'foobarbaz'
66
+ config.format = :xml
67
+ config.region = 'eu'
68
+ end
69
+ # or
70
+ Awesomeness.configuration.api_key = 'foobarbaz'
71
+ ```
72
+
73
+ Of course configuration values are checked against the allowed `classes` and `values`, and the `default` is used if no value is provided.
27
74
 
28
75
  ## Contributing
29
76
 
@@ -12,7 +12,7 @@ module GemConfig
12
12
 
13
13
  def reset
14
14
  self.rules.keys.each do |key|
15
- set key, nil
15
+ unset key
16
16
  end
17
17
  end
18
18
 
@@ -29,12 +29,21 @@ module GemConfig
29
29
 
30
30
  private
31
31
 
32
+ def unset(key)
33
+ remove_instance_variable "@#{key}" if instance_variable_defined?("@#{key}")
34
+ end
35
+
32
36
  def set(key, value)
33
- self.instance_variable_set "@#{key}", value
37
+ self.rules.check(key, value)
38
+ instance_variable_set "@#{key}", value
34
39
  end
35
40
 
36
41
  def get(key)
37
- self.instance_variable_get("@#{key}") || self.rules[key.to_sym][:default]
42
+ if instance_variable_defined?("@#{key}")
43
+ instance_variable_get "@#{key}"
44
+ else
45
+ self.rules[key.to_sym][:default]
46
+ end
38
47
  end
39
48
  end
40
49
  end
@@ -2,11 +2,25 @@ require 'active_support/core_ext/hash/keys'
2
2
 
3
3
  module GemConfig
4
4
  class Rules < Hash
5
+ InvalidKeyError = Class.new(StandardError)
6
+
5
7
  def has(key, attrs = {})
6
8
  check_attributes attrs
7
9
  self[key.to_sym] = attrs
8
10
  end
9
11
 
12
+ def check(key, value)
13
+ error_message = case
14
+ when !self.has_key?(key.to_sym)
15
+ 'no rule found'
16
+ when self[key.to_sym].has_key?(:classes) && Array(self[key.to_sym][:classes]).none? { |klass| value.is_a?(klass) }
17
+ "must be an instance of one of the following classes: #{Array(self[key.to_sym][:classes]).join(', ')}"
18
+ when self[key.to_sym].has_key?(:values) && !Array(self[key.to_sym][:values]).include?(value)
19
+ "must be one of the following values: #{Array(self[key.to_sym][:values]).join(', ')}"
20
+ end
21
+ raise InvalidKeyError, "#{value} is not a valid value for #{key}: #{error_message}" unless error_message.nil?
22
+ end
23
+
10
24
  private
11
25
 
12
26
  def check_attributes(attrs)
@@ -1,3 +1,3 @@
1
1
  module GemConfig
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -3,9 +3,10 @@ require 'spec_helper'
3
3
  describe GemConfig::Configuration do
4
4
  subject do
5
5
  GemConfig::Configuration.new.tap do |configuration|
6
- configuration.rules.has :foo
6
+ configuration.rules.has :foo, default: 'bar'
7
7
  configuration.rules.has :count
8
- configuration.foo = 'bar'
8
+ configuration.rules.has :api_key, default: 'foobarbaz'
9
+ configuration.foo = 'pelle'
9
10
  configuration.count = 123
10
11
  configuration
11
12
  end
@@ -19,13 +20,53 @@ describe GemConfig::Configuration do
19
20
 
20
21
  describe '#current' do
21
22
  it 'returns the current configuration' do
22
- subject.current.should eq(foo: 'bar', count: 123)
23
+ subject.current.should eq(foo: 'pelle', count: 123, api_key: 'foobarbaz')
23
24
  end
24
25
  end
25
26
 
26
27
  describe '#reset' do
27
28
  it 'resets the configuration' do
28
- subject.tap(&:reset).current.should eq(foo: nil, count: nil)
29
+ subject.tap(&:reset).current.should eq(foo: 'bar', count: nil, api_key: 'foobarbaz')
30
+ end
31
+ end
32
+
33
+ describe 'setting a configuration option' do
34
+ it 'checks if the value is allowed' do
35
+ subject.rules.should_receive :check, with: [:foo, 'bar']
36
+ subject.foo = 'bar'
37
+ end
38
+
39
+ it 'sets the configuration option if the value is allowed' do
40
+ subject.rules.stub(:check, with: [:foo, 'bar'])
41
+ expect do
42
+ subject.foo = 'bar'
43
+ end.to change { subject.foo }.from('pelle').to('bar')
44
+ end
45
+
46
+ it 'does not set the configuration option if the value is not allowed' do
47
+ subject.rules.stub(:check, with: [:foo, 'bar']).and_raise(GemConfig::Rules::InvalidKeyError)
48
+ expect do
49
+ begin
50
+ subject.foo = 'bar'
51
+ rescue GemConfig::Rules::InvalidKeyError
52
+ end
53
+ end.to_not change { subject.foo }.from('bar')
54
+ end
55
+ end
56
+
57
+ describe 'getting a configuration option' do
58
+ it 'returns the value if it is set' do
59
+ subject.foo = 'bar'
60
+ subject.foo.should eq('bar')
61
+ end
62
+
63
+ it 'also accepts nil as a value' do
64
+ subject.foo = nil
65
+ subject.foo.should be_nil
66
+ end
67
+
68
+ it 'returns the default if no value but a default is set' do
69
+ subject.api_key.should eq('foobarbaz')
29
70
  end
30
71
  end
31
72
  end
@@ -109,4 +109,40 @@ describe GemConfig::Rules do
109
109
  end
110
110
  end
111
111
  end
112
+
113
+ describe '#check' do
114
+ it "raises an error if the value is not set as a rule" do
115
+ expect do
116
+ subject.check :foo, 1
117
+ end.to raise_error(GemConfig::Rules::InvalidKeyError)
118
+ end
119
+
120
+ it "raises an error if :classes are defined the the value's class is not included in them" do
121
+ subject.has :foo, classes: String
122
+ expect do
123
+ subject.check :foo, 1
124
+ end.to raise_error(GemConfig::Rules::InvalidKeyError)
125
+ end
126
+
127
+ it 'raises an error if :values are defined the the value is not included in them' do
128
+ subject.has :foo, values: ['foo', 'bar']
129
+ expect do
130
+ subject.check :foo, 'baz'
131
+ end.to raise_error(GemConfig::Rules::InvalidKeyError)
132
+ end
133
+
134
+ it "does not raise an error if :classes are defined the the value's class is included in them" do
135
+ subject.has :foo, classes: [String, Numeric]
136
+ expect do
137
+ subject.check :foo, 1
138
+ end.to_not raise_error(GemConfig::Rules::InvalidKeyError)
139
+ end
140
+
141
+ it 'does not raise an error if :values are defined the the value is included in them' do
142
+ subject.has :foo, values: ['foo', 'bar']
143
+ expect do
144
+ subject.check :foo, 'foo'
145
+ end.to_not raise_error(GemConfig::Rules::InvalidKeyError)
146
+ end
147
+ end
112
148
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Meurer