canfig 0.0.3 → 0.0.8

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
- SHA1:
3
- metadata.gz: 943269b9166513da09c866d6d4bae9e8bdb7f79c
4
- data.tar.gz: d1988d15d10df3182c134075461db5640f0bd595
2
+ SHA256:
3
+ metadata.gz: 28a747df13cf5c6c99fa96a201cb5f300b707a4642a63e5a65a943582a1fdde5
4
+ data.tar.gz: c917be14d97451e7615943952729ce00cc03b322c62536249a9a5859c88c63d0
5
5
  SHA512:
6
- metadata.gz: 23d2195e6ae6b208e3a411b2de8904bef726a15c8dc5a4bf06f787fede78161485e3c24404655e63adf450d7fb0a8c7302453f87ee659d87ed171b2f7b39c2b0
7
- data.tar.gz: d04944fa211c31db6f20df83f45824bf486c22de4568ce92b38860f875526edf197915d7619b6b07530948534c3449f747c423c6265c08e475eb90ff27de6444
6
+ metadata.gz: 4cf03ffeb05d41a42ef388d42013000cc62402befb390b1c188ac8a0acdda9c3e04fea5c63d47dd103258cedc5d36c9ce0d31ef14c079abbbd4842f4d5520589
7
+ data.tar.gz: 006e3e970b3aec9905abaa038bfca1f470f8b80ce6f8f2c743a729ebbf956d3a08425708d9aa0b486da58b6ea44178c69219c860edf40226bd999606d771aa1d
@@ -1,11 +1,20 @@
1
1
  require 'active_support/core_ext/array/extract_options'
2
2
  require 'active_support/core_ext/hash/keys'
3
+ require 'active_support/inflector'
3
4
  require 'canfig/version'
5
+ require 'canfig/yaml'
4
6
  require 'canfig/config'
5
7
  require 'canfig/open_config'
6
8
  require 'canfig/module'
7
9
  require 'canfig/class'
8
- require 'canfig/object'
10
+ require 'canfig/instance'
9
11
 
10
12
  module Canfig
13
+ def self.new(*args, &block)
14
+ Canfig::Config.new *args, &block
15
+ end
16
+
17
+ def self.open(*args, &block)
18
+ Canfig::OpenConfig.new *args, &block
19
+ end
11
20
  end
@@ -1,18 +1,24 @@
1
1
  module Canfig
2
2
  class Config
3
3
 
4
- def configure(argh={}, &block)
5
- @options ||= {}
4
+ def configure(argh={}, file=nil, &block)
6
5
  save_state! do
6
+ configure_with_file file unless file.nil?
7
7
  configure_with_args argh
8
8
  configure_with_block &block
9
9
  end
10
10
  self
11
11
  end
12
12
 
13
+ def configure_with_file(file)
14
+ save_state! do
15
+ configure_with_args(Canfig::YAML.new(file).load)
16
+ end
17
+ end
18
+
13
19
  def configure_with_args(argh)
14
20
  save_state! do
15
- argh.symbolize_keys.each { |key,val| configure_option(key, val) }
21
+ argh.symbolize_keys.each { |key,val| set(key, val) }
16
22
  end
17
23
  end
18
24
 
@@ -22,19 +28,44 @@ module Canfig
22
28
  end
23
29
  end
24
30
 
25
- def configure_option(key, val)
26
- raise ArgumentError, "#{key} is not an allowed configuration option" unless allowed?(key)
31
+ def set(key, val)
32
+ raise NoMethodError, "undefined method `#{key.to_s}=' for #{self.to_s}" unless allowed?(key)
33
+
34
+ save_state! do
35
+ @state[key] = val
36
+ end
37
+ end
38
+
39
+ def env(key, default=nil, &block)
40
+ val = ENV.fetch(key.to_s.underscore.upcase, default, &block)
41
+ val && ENV.key?(val) ? env(val, default, &block) : val
42
+ end
27
43
 
44
+ def clear(key)
28
45
  save_state! do
29
- @changed[key] = [@options[key], val]
30
- @options[key] = val
46
+ @state[key] = nil
31
47
  end
32
48
  end
33
49
 
50
+ def []=(key, val)
51
+ set key, val
52
+ end
53
+
54
+ def get(key, default=nil, &block)
55
+ raise NoMethodError, "undefined method `#{key.to_s}' for #{self.to_s}" unless allowed?(key)
56
+ @state[key] ||= env(key, default, &block)
57
+ end
58
+
59
+ def [](key)
60
+ get key
61
+ end
62
+
63
+ def to_h
64
+ Hash[@allowed.map { |key| [key, @state[key]] }]
65
+ end
66
+
34
67
  def changed
35
- @changed = {}
36
- @options.each { |key,val| @changed[key] = [@saved_state[key], val] if @saved_state[key] != val }
37
- @changed
68
+ Hash[@allowed.map { |key| [key, [@saved_state[key], @state[key]]] if @saved_state[key] != @state[key] }.compact]
38
69
  end
39
70
 
40
71
  def changed?(key)
@@ -43,8 +74,7 @@ module Canfig
43
74
 
44
75
  def save_state!(&block)
45
76
  if save_state?
46
- @saved_state = @options.dup
47
- @changed = {}
77
+ @saved_state = to_h
48
78
 
49
79
  if block_given?
50
80
  disable_state_saves!
@@ -78,9 +108,9 @@ module Canfig
78
108
  def method_missing(meth, *args, &block)
79
109
  if meth.to_s.match(/=\Z/)
80
110
  opt = meth.to_s.gsub(/=/,'').to_sym
81
- return configure_option(opt, args.first) if allowed?(meth)
111
+ return set(opt, args.first) if allowed?(opt)
82
112
  else
83
- return @options[meth] if allowed?(meth)
113
+ return get(meth, *args, &block) if allowed?(meth)
84
114
  end
85
115
 
86
116
  super
@@ -90,7 +120,8 @@ module Canfig
90
120
 
91
121
  def initialize(*args, &block)
92
122
  options = args.extract_options!
93
- @allowed = options.symbolize_keys.keys
123
+ @allowed = (args.map(&:to_sym) + options.symbolize_keys.keys).uniq
124
+ @state = {}
94
125
  enable_state_saves!
95
126
  configure options, &block
96
127
  end
@@ -1,11 +1,11 @@
1
1
  module Canfig
2
- module Object
2
+ module Instance
3
3
  def configuration
4
4
  @configuration ||= Canfig::OpenConfig.new
5
5
  end
6
6
 
7
7
  def configure(&block)
8
- @configuration.configure &block
8
+ configuration.configure &block
9
9
  end
10
10
  end
11
11
  end
@@ -3,7 +3,7 @@ require 'active_support/core_ext/module/attribute_accessors'
3
3
  module Canfig
4
4
  module Module
5
5
  def self.included(base)
6
- base.send :cattr_reader, :configuration
6
+ base.send :mattr_reader, :configuration
7
7
  base.send :class_variable_set, :@@configuration, Canfig::OpenConfig.new
8
8
  base.send :extend, ClassMethods
9
9
  end
@@ -1,5 +1,10 @@
1
1
  module Canfig
2
2
  class OpenConfig < Config
3
+ def set(key, val)
4
+ super(key, val)
5
+ @allowed << key unless @allowed.include?(key)
6
+ end
7
+
3
8
  def allowed?(opt)
4
9
  true
5
10
  end
@@ -1,3 +1,3 @@
1
1
  module Canfig
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.8'
3
3
  end
@@ -0,0 +1,25 @@
1
+ module Canfig
2
+ class YAML
3
+ attr_reader :file
4
+
5
+ def initialize(file)
6
+ @file = file
7
+ end
8
+
9
+ def load
10
+ @data ||= ::YAML.load_file(file).symbolize_keys
11
+ end
12
+ alias_method :data, :load
13
+
14
+ def reload
15
+ @data = nil
16
+ self.load
17
+ end
18
+
19
+ def write
20
+ File.open(file, 'w') do |f|
21
+ f.write(::YAML.dump(data))
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,222 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Canfig::Config do
4
+ describe '#initialize' do
5
+ context 'when passed a list of keys' do
6
+ subject { Canfig::Config.new(:foo, :bar, :baz) }
7
+
8
+ it 'adds those keys to the allowed keys' do
9
+ expect(subject.allowed?(:foo)).to be_true
10
+ expect(subject.allowed?(:bar)).to be_true
11
+ expect(subject.allowed?(:baz)).to be_true
12
+ end
13
+ end
14
+
15
+ context 'when passed a hash of keys and values' do
16
+ subject { Canfig::Config.new(foo: 'foo', bar: 'bar', baz: 'baz') }
17
+
18
+ it 'adds those keys to the allowed keys' do
19
+ expect(subject.allowed?(:foo)).to be_true
20
+ expect(subject.allowed?(:bar)).to be_true
21
+ expect(subject.allowed?(:baz)).to be_true
22
+ end
23
+ end
24
+
25
+ context 'when passed a list of keys and a hash of keys and values' do
26
+ subject { Canfig::Config.new(:foo, :bar, baz: 'baz') }
27
+
28
+ it 'adds those keys to the allowed keys' do
29
+ expect(subject.allowed?(:foo)).to be_true
30
+ expect(subject.allowed?(:bar)).to be_true
31
+ expect(subject.allowed?(:baz)).to be_true
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#set' do
37
+ context 'when the key is allowed' do
38
+ subject { Canfig::Config.new(:foo) }
39
+
40
+ it 'sets the key/value pair' do
41
+ subject.set(:foo, 'bar')
42
+ expect(subject.get(:foo)).to eql('bar')
43
+ end
44
+ end
45
+
46
+ context 'when the key is not allowed' do
47
+ subject { Canfig::Config.new(:baz) }
48
+
49
+ it 'raises a NoMethodError' do
50
+ expect { subject.set(:foo, 'bar') }.to raise_exception(NoMethodError)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#get' do
56
+ context 'when the key is allowed' do
57
+ subject { Canfig::Config.new(:baz, foo: 'bar') }
58
+
59
+ it 'returns the corresponding value' do
60
+ expect(subject.get(:foo)).to eql('bar')
61
+ end
62
+
63
+ context 'when the key is not set' do
64
+ it 'returns nil' do
65
+ expect(subject.get(:baz)).to be_nil
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'when the key is not allowed' do
71
+ subject { Canfig::Config.new(:baz) }
72
+
73
+ it 'raises a NoMethodError' do
74
+ expect { subject.get(:foo) }.to raise_exception(NoMethodError)
75
+ end
76
+ end
77
+ end
78
+
79
+ describe '#to_h' do
80
+ subject { Canfig::Config.new(:foo, bar: 'bar', baz: 'baz') }
81
+
82
+ it 'returns a hash' do
83
+ expect(subject.to_h).to be_an_instance_of(Hash)
84
+ end
85
+
86
+ it 'contain all allowed keys' do
87
+ [:foo, :bar, :baz].each do |key|
88
+ expect(subject.to_h.keys).to include(key)
89
+ end
90
+ end
91
+ end
92
+
93
+ describe '#configure_with_args' do
94
+ subject { Canfig::Config.new(:foo, bar: 'bar', baz: 'baz') }
95
+
96
+ context 'when the passed keys are allowed' do
97
+ it 'sets the key/value pairs passed the hash' do
98
+ subject.configure_with_args({foo: 1, bar: 2})
99
+ expect(subject.get(:foo)).to eql(1)
100
+ expect(subject.get(:bar)).to eql(2)
101
+ end
102
+ end
103
+
104
+ context 'when the passed keys are not allowed' do
105
+ it 'raises a NoMethodError' do
106
+ expect { subject.configure_with_args({abc: '123'}) }.to raise_exception(NoMethodError)
107
+ end
108
+ end
109
+ end
110
+
111
+ describe '#configure_with_block' do
112
+ subject { Canfig::Config.new(:foo, bar: 'bar', baz: 'baz') }
113
+
114
+ it 'accepts a block' do
115
+ expect { subject.configure_with_block { |config| } }.to_not raise_exception
116
+ end
117
+
118
+ it 'executes the block with instance_eval' do
119
+ conf = nil
120
+ subject.configure_with_block { |config| conf = config }
121
+ expect(conf).to eql(subject)
122
+ end
123
+ end
124
+
125
+ describe '#configure' do
126
+ subject { Canfig::Config.new(:foo, bar: 'bar', baz: 'baz') }
127
+
128
+ it 'returns self' do
129
+ expect(subject.configure).to eql(subject)
130
+ end
131
+
132
+ it 'accepts a hash and a block' do
133
+ subject.configure foo: 'foo' do |config|
134
+ config.bar = 'baz'
135
+ config.baz = 'bar'
136
+ end
137
+
138
+ expect(subject.get(:foo)).to eql('foo')
139
+ expect(subject.get(:bar)).to eql('baz')
140
+ expect(subject.get(:baz)).to eql('bar')
141
+ end
142
+ end
143
+
144
+ context 'when referencing option keys' do
145
+ subject { Canfig::Config.new(:foo, bar: 'bar', baz: 'baz') }
146
+
147
+ context 'that are allowed' do
148
+ context 'using getter methods' do
149
+ it 'returns the value' do
150
+ expect(subject.bar).to eql('bar')
151
+ end
152
+ end
153
+
154
+ context 'using setter methods' do
155
+ it 'sets the passed value to the key' do
156
+ subject.bar = 'foo'
157
+ expect(subject.bar).to eql('foo')
158
+ end
159
+ end
160
+ end
161
+
162
+ context 'that are not allowed' do
163
+ context 'using getter methods' do
164
+ it 'returns the value' do
165
+ expect { subject.abc }.to raise_exception(NoMethodError)
166
+ end
167
+ end
168
+
169
+ context 'using setter methods' do
170
+ it 'sets the passed value to the key' do
171
+ expect { subject.abc = 123 }.to raise_exception(NoMethodError)
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ context 'when saving state' do
178
+ subject { Canfig::Config.new(:foo, bar: 'bar', baz: 'baz') }
179
+
180
+ describe '#changed' do
181
+ it 'returns a hash' do
182
+ subject.configure do |config|
183
+ config.foo = 'test'
184
+ config.bar = 1
185
+ end
186
+
187
+ expect(subject.changed).to be_an_instance_of(Hash)
188
+ end
189
+
190
+ it 'contains the changed keys' do
191
+ subject.configure do |config|
192
+ config.foo = 'test'
193
+ config.bar = 1
194
+ end
195
+
196
+ [:foo, :bar].each do |key|
197
+ expect(subject.changed.keys).to include(key)
198
+ end
199
+ end
200
+
201
+ it 'contains only the changed keys' do
202
+ subject.configure do |config|
203
+ config.foo = 'test'
204
+ config.bar = 1
205
+ end
206
+
207
+ expect(subject.changed.keys).to_not include(:baz)
208
+ end
209
+
210
+ it 'contains the old and new values' do
211
+ subject.configure do |config|
212
+ config.foo = 'test'
213
+ config.bar = 1
214
+ end
215
+
216
+ expect(subject.changed[:foo]).to eql([nil,'test'])
217
+ expect(subject.changed[:bar]).to eql(['bar',1])
218
+ end
219
+ end
220
+ end
221
+
222
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Canfig::OpenConfig do
4
+ describe '#to_h' do
5
+ subject { Canfig::OpenConfig.new() }
6
+
7
+ it 'returns a hash' do
8
+ expect(subject.to_h).to be_an_instance_of(Hash)
9
+ end
10
+
11
+ it 'contain all set keys' do
12
+ subject.set :foo, 'foo'
13
+ subject.set :bar, 'bar'
14
+ subject.set :baz, 'baz'
15
+ [:foo, :bar, :baz].each do |key|
16
+ expect(subject.to_h.keys).to include(key)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Canfig::YAML do
4
+ subject { described_class.new('spec/fixtures/config.yml') }
5
+
6
+ describe '#load' do
7
+ it 'loads the file into a hash' do
8
+ expect(subject.load).to be_a(Hash)
9
+ end
10
+ end
11
+
12
+ describe '#write' do
13
+ subject { described_class.new('spec/fixtures/test.yml') }
14
+
15
+ before do
16
+ FileUtils.cp 'spec/fixtures/config.yml', 'spec/fixtures/test.yml'
17
+ end
18
+
19
+ it 'writes the hash back to the file in YAML' do
20
+ subject.data[:foo] = 'bar'
21
+ subject.write
22
+ subject.reload
23
+ expect(subject.data[:foo]).to eq('bar')
24
+ end
25
+
26
+ after do
27
+ FileUtils.rm 'spec/fixtures/test.yml'
28
+ end
29
+ end
30
+
31
+ describe '#reload' do
32
+ it 'reloads the data from the file' do
33
+ subject.data[:foo] = 'bar'
34
+ subject.reload
35
+ expect(subject.data[:foo]).to eq('foo')
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Canfig do
4
+ describe '.new' do
5
+ it 'returns a configuration object' do
6
+ expect(subject.new).to be_an_instance_of(Canfig::Config)
7
+ end
8
+ end
9
+
10
+ describe '.open' do
11
+ it 'returns an open configuration object' do
12
+ expect(subject.open).to be_an_instance_of(Canfig::OpenConfig)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ foo: 'foo'
2
+ bar: 'bar'
3
+ baz: 'baz'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Rebec
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-21 00:00:00.000000000 Z
11
+ date: 2020-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -62,15 +62,21 @@ files:
62
62
  - lib/canfig.rb
63
63
  - lib/canfig/class.rb
64
64
  - lib/canfig/config.rb
65
+ - lib/canfig/instance.rb
65
66
  - lib/canfig/module.rb
66
- - lib/canfig/object.rb
67
67
  - lib/canfig/open_config.rb
68
68
  - lib/canfig/version.rb
69
+ - lib/canfig/yaml.rb
70
+ - spec/canfig/config_spec.rb
71
+ - spec/canfig/open_config_spec.rb
72
+ - spec/canfig/yaml_spec.rb
73
+ - spec/canfig_spec.rb
74
+ - spec/fixtures/config.yml
69
75
  - spec/spec_helper.rb
70
76
  homepage: http://github.com/markrebec/canfig
71
77
  licenses: []
72
78
  metadata: {}
73
- post_install_message:
79
+ post_install_message:
74
80
  rdoc_options: []
75
81
  require_paths:
76
82
  - lib
@@ -85,10 +91,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
91
  - !ruby/object:Gem::Version
86
92
  version: '0'
87
93
  requirements: []
88
- rubyforge_project:
89
- rubygems_version: 2.2.2
90
- signing_key:
94
+ rubygems_version: 3.1.2
95
+ signing_key:
91
96
  specification_version: 4
92
97
  summary: Dead simple canned configuration for gems or whatever
93
98
  test_files:
94
99
  - spec/spec_helper.rb
100
+ - spec/fixtures/config.yml
101
+ - spec/canfig/config_spec.rb
102
+ - spec/canfig/open_config_spec.rb
103
+ - spec/canfig/yaml_spec.rb
104
+ - spec/canfig_spec.rb