canfig 0.0.3 → 0.0.8

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
- 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