configuru 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5db1722e4793d1f8627e6c8c8b796cdac8e83d50
4
+ data.tar.gz: 9e45658f486a5d39da387eb2479c172b7aee5f4b
5
+ SHA512:
6
+ metadata.gz: 6e8073b7a2cbfd96c44f92ed190c796a7a61cfcbc7363ecca705521a517f5bca2c0a7fe6fd0d88258e5316e1f3cc6542f18d5ffb33f76cc5dd6e66e536104474
7
+ data.tar.gz: ef1b06f4d8c2238f7414538a2b54ddfe70e2c0d857c86f1bd1d388a0ab3a0c755aeef2078a499b247445c42a6402c52c55137679309f84ae380a05f852bbfb13
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .env
7
+ .rspec
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ *.bundle
21
+ *.so
22
+ *.o
23
+ *.a
24
+ mkmf.log
25
+ **/.DS_Store
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ rvm:
5
+ - 2.1.2
6
+
7
+ branches:
8
+ only:
9
+ - master
10
+
11
+ script: bundle exec rake spec
12
+
13
+ before_install:
14
+ - gem update --system
15
+ - gem --version
data/CHANGELOG.md ADDED
File without changes
data/CONTRIBUTORS.md ADDED
@@ -0,0 +1 @@
1
+ * Andrey Pronin <moonfly.msk@gmail.com> aka moonfly (https://github.com/moonfly)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in configuru.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2014 [CONTRIBUTORS.md](https://github.com/moonfly/configuru/master/CONTRIBUTORS.md)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Configuru
2
+
3
+ Provides convenient interface for managing configuration parameters for modules, classes and instances.
4
+ Requires Ruby version >= 2.1.
5
+
6
+ [![Build Status](https://travis-ci.org/moonfly/configuru.svg?branch=master)](https://travis-ci.org/moonfly/configuru)
7
+ [![Coverage Status](https://img.shields.io/coveralls/moonfly/configuru.svg)](https://coveralls.io/r/moonfly/configuru?branch=master)
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'configuru'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install configuru
24
+
25
+ ## Usage
26
+
27
+ The typical usage scenario is provided below:
28
+
29
+ ```ruby
30
+ require 'configuru'
31
+
32
+ class MyClass
33
+ include Configuru::Configurable
34
+ provide_configuration
35
+
36
+ def_config_param :secret_key, make_string: true, default: (ENV['SECRET_KEY_'] || '???')
37
+ def_config_param :color, default: :green,
38
+ convert: ->(val) { raise "Huh?" unless [:red,:green].include?(val); val }
39
+ def_config_param :percentage, make_float:true, min:0, max:100, default:100
40
+
41
+ def initialize(options,&block)
42
+ configure(options,&block)
43
+ configuration.lock
44
+ end
45
+ end
46
+
47
+ my_inst = MyClass.new do |config|
48
+ config.secret_key = "VERY-SECR-ETKY"
49
+ config.color = :red
50
+ config.options_source = "/my/path/to/file/with/options.yml"
51
+ end
52
+
53
+ my_inst.configuration.color #=> :red
54
+ my_inst.configuration.secret_key #=> "VERY-SECR-ETKY"
55
+ my_inst.configuration.percentage #=> 100
56
+ ```
57
+
58
+
59
+
60
+ ## Versioning
61
+
62
+ Semantic versioning (http://semver.org/spec/v2.0.0.html) is used.
63
+
64
+ For a version number MAJOR.MINOR.PATCH, unless MAJOR is 0:
65
+
66
+ 1. MAJOR version is incremented when incompatible API changes are made,
67
+ 2. MINOR version is incremented when functionality is added in a backwards-compatible manner,
68
+ 3. PATCH version is incremented when backwards-compatible bug fixes are made.
69
+
70
+ Major version "zero" (0.y.z) is for initial development. Anything may change at any time.
71
+ The public API should not be considered stable.
72
+
73
+ ## Dependencies
74
+
75
+ Requires Ruby version >= 2.1
76
+
77
+ ## Contributing
78
+
79
+ 1. Fork it ( https://github.com/[my-github-username]/configuru/fork )
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
82
+ 4. Push to the branch (`git push origin my-new-feature`)
83
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc "Run RSpec tests (use rake spec SPEC_OPTS='...' to pass rspec options)"
5
+ RSpec::Core::RakeTask.new(:spec)
data/configuru.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'configuru/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "configuru"
8
+ spec.version = Configuru::VERSION
9
+ spec.authors = ['moonfly (Andrey Pronin)']
10
+ spec.email = ['moonfly.msk@gmail.com']
11
+ spec.summary = %q{Configuration for your classes}
12
+ spec.description = %q{Provides convenient interface for managing configuration parameters for modules, classes and instances.}
13
+ spec.homepage = 'https://github.com/moonfly/configuru'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.rdoc_options = ['--charset=UTF-8']
22
+ spec.extra_rdoc_files = %w[README.md CONTRIBUTORS.md LICENSE.md]
23
+
24
+ spec.required_ruby_version = '>= 2.1.0'
25
+
26
+ spec.add_development_dependency 'bundler', '>= 1.6'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec', '~> 3.0'
29
+ spec.add_development_dependency 'coveralls'
30
+ end
data/lib/configuru.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'configuru/version'
2
+ require 'configuru/config_methods'
3
+ require 'configuru/configurable'
@@ -0,0 +1,117 @@
1
+ require 'yaml'
2
+
3
+ module Configuru
4
+ module ConfigMethods
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ # Class methods
10
+ module ClassMethods
11
+ def param_names
12
+ @param_names ||= []
13
+ end
14
+ def param(name,options={})
15
+ param_names << name.to_sym
16
+
17
+ inst_var = "@#{name.to_s}"
18
+ define_method(name) do
19
+ if !instance_variable_defined?(inst_var) && options.has_key?(:default)
20
+ instance_variable_set inst_var, options[:default]
21
+ end
22
+ instance_variable_get inst_var
23
+ end
24
+
25
+ define_method("#{name.to_s}=") do |value|
26
+ if options[:lockable] && is_locked
27
+ raise ArgumentError.new("'#{name.to_s}' cannot be set at this time")
28
+ end
29
+ if options[:not_nil] && value.nil?
30
+ raise ArgumentError.new("'#{name.to_s}' cannot be nil")
31
+ end
32
+ if options[:not_empty] && (value.nil? || value.empty?)
33
+ raise ArgumentError.new("'#{name.to_s}' cannot be empty")
34
+ end
35
+ if options.has_key?(:must_be) && !Array(options[:must_be]).include?(value.class)
36
+ valid_class = false
37
+ Array(options[:must_be]).each do |cname|
38
+ valid_class = true if value.is_a?(cname)
39
+ end
40
+ raise ArgumentError.new("Wrong class (#{value.class}) for '#{name.to_s}' value") unless valid_class
41
+ end
42
+ if options.has_key?(:must_respond_to)
43
+ Array(options[:must_respond_to]).each do |mname|
44
+ raise ArgumentError.new("'#{name.to_s}' must respond to '#{mname}'") unless value.respond_to?(mname)
45
+ end
46
+ end
47
+ value = Hash(value) if options[:make_hash]
48
+ value = Array(value) if options[:make_array]
49
+ value = String(value) if options[:make_string]
50
+ value = value.to_i if options[:make_int]
51
+ value = value.to_f if options[:make_float]
52
+ value = !!value if options[:make_bool]
53
+ if options.has_key?(:max) && (value > options[:max])
54
+ raise ArgumentError.new("'#{name.to_s}' must no be more than #{options[:max]}")
55
+ end
56
+ if options.has_key?(:min) && (value < options[:min])
57
+ raise ArgumentError.new("'#{name.to_s}' must no be less than #{options[:min]}")
58
+ end
59
+ if options.has_key?(:in) && !options[:in].include?(value)
60
+ raise ArgumentError.new("'#{name.to_s}' is out of range")
61
+ end
62
+ if options.has_key?(:convert)
63
+ if options[:convert].is_a? Symbol
64
+ value = send options[:convert], value
65
+ else
66
+ value = options[:convert].call( value )
67
+ end
68
+ end
69
+
70
+ instance_variable_set inst_var, value
71
+ end
72
+ name
73
+ end
74
+ end
75
+
76
+ # Instance methods
77
+ def lock(flag=true)
78
+ @locked = flag
79
+ end
80
+ def is_locked
81
+ @locked = false unless instance_variable_defined?(:@locked)
82
+ @locked
83
+ end
84
+
85
+ def configure(options={})
86
+ Hash(options).each_pair do |name,value|
87
+ if name.to_sym == :options_source
88
+ self.options_source = value
89
+ else
90
+ send("#{name.to_s}=",value)
91
+ end
92
+ end
93
+ yield self if block_given?
94
+ self
95
+ end
96
+ def options_source=(value)
97
+ sub_options = case value
98
+ when Hash, Array then value
99
+ when IO, StringIO, Tempfile then
100
+ YAML.load(value)
101
+ when String, Pathname
102
+ output = {}
103
+ File.open(value,"r") { |f| output = YAML.load(f) }
104
+ output
105
+ else
106
+ raise ArgumentError.new("Wrong argument class for options_source: #{value.class}")
107
+ end
108
+ if sub_options.is_a? Array
109
+ sub_options.each { |elem| self.options_source=elem }
110
+ else
111
+ configure(sub_options)
112
+ end
113
+ end
114
+
115
+
116
+ end
117
+ end
@@ -0,0 +1,45 @@
1
+ module Configuru
2
+ module Configurable
3
+
4
+ module ClassMethods
5
+ extend Forwardable
6
+ def_delegator :configuration_class, :param, :def_config_param
7
+ def configuration_class
8
+ @configuration_class ||= Class.new do
9
+ include Configuru::ConfigMethods
10
+ end
11
+ end
12
+ def provide_configuration(limit_to=false)
13
+ unless [:base,:class,:module].include?(limit_to)
14
+ # Add methods to instance
15
+ include MainMethods
16
+ include InstanceMethods
17
+ end
18
+ unless [:instance,:instances].include?(limit_to)
19
+ # Add methods to base
20
+ extend MainMethods
21
+ end
22
+ end
23
+ end
24
+
25
+ module MainMethods
26
+ def configuration
27
+ @configuruation ||= configuration_class.new
28
+ end
29
+ def configure(options,&block)
30
+ configuration.configure(options,&block)
31
+ end
32
+ end
33
+
34
+ module InstanceMethods
35
+ def configuration_class
36
+ self.class.configuration_class
37
+ end
38
+ end
39
+
40
+ def self.included(base)
41
+ base.extend(ClassMethods)
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module Configuru
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,287 @@
1
+ require 'spec_helper'
2
+
3
+ describe Configuru::ConfigMethods do
4
+ before(:each) {
5
+ class TestSubjectClass
6
+ include Configuru::ConfigMethods
7
+ end
8
+ class TestIoSubjectClass
9
+ include Configuru::ConfigMethods
10
+ param :test1
11
+ param :test2
12
+ end
13
+ }
14
+ let(:subject) { TestSubjectClass.new }
15
+ let(:opts_spec) { Hash("test1" => "something1", :test2 => "something2") }
16
+ let(:opts_sio) { StringIO.new(opts_spec.to_yaml) }
17
+
18
+ it 'includes class methods' do
19
+ expect(TestSubjectClass.methods).to include :param, :param_names
20
+ end
21
+ it 'returns itself from configure (smoke test)' do
22
+ expect(subject.configure).to eq subject
23
+ end
24
+ it 'allows defining parameters' do
25
+ class << subject
26
+ param :test
27
+ end
28
+ expect(subject).to respond_to :test
29
+ expect(subject).to respond_to :test=
30
+ end
31
+
32
+ it 'allows settings variables passed as a hash and/or block' do
33
+ class << subject
34
+ param :test1
35
+ param :test2
36
+ end
37
+ subject.configure({test1: "something1"}) do |cfg|
38
+ cfg.test2 = "something2"
39
+ end
40
+ expect(subject.test1).to eq "something1"
41
+ expect(subject.test2).to eq "something2"
42
+ end
43
+
44
+ it 'keeps track of parameters' do
45
+ expect(TestIoSubjectClass.param_names).to include :test1, :test2
46
+ end
47
+
48
+ it 'allows loading options from Hash' do
49
+ class << subject
50
+ param :test1
51
+ param :test2
52
+ end
53
+ subject.options_source = opts_spec
54
+ expect(subject.test1).to eq "something1"
55
+ expect(subject.test2).to eq "something2"
56
+ end
57
+
58
+ it 'allows loading options from StringIO' do
59
+ class << subject
60
+ param :test1
61
+ param :test2
62
+ end
63
+ subject.options_source = opts_sio
64
+ expect(subject.test1).to eq "something1"
65
+ expect(subject.test2).to eq "something2"
66
+ end
67
+
68
+ it 'allows loading options from an array of sources, later sources take precendence' do
69
+ class << subject
70
+ param :test1
71
+ param :test2
72
+ end
73
+ opts_spec1 = opts_spec.clone
74
+ opts_spec1.delete("test1")
75
+ opts_spec1[:test2] = "something3"
76
+
77
+ subject.options_source = [opts_sio, opts_spec1]
78
+ expect(subject.test1).to eq "something1"
79
+ expect(subject.test2).to eq "something3"
80
+ end
81
+
82
+ it 'allows loading options from sources several times, later sources take precendence' do
83
+ class << subject
84
+ param :test1
85
+ param :test2
86
+ end
87
+ opts_spec1 = opts_spec.clone
88
+ opts_spec1.delete("test1")
89
+ opts_spec1[:test2] = "something3"
90
+
91
+ subject.options_source = opts_sio
92
+ subject.options_source = opts_spec1
93
+ expect(subject.test1).to eq "something1"
94
+ expect(subject.test2).to eq "something3"
95
+ end
96
+
97
+ it 'does not allow loading options from an arbitrary value' do
98
+ class << subject
99
+ param :test1
100
+ param :test2
101
+ end
102
+ [10,"test1=1;test2=2",nil].each do |value|
103
+ expect{subject.options_source = value}.to raise_error
104
+ end
105
+ end
106
+
107
+ it 'allows loading options from File/IO' do
108
+ subject1 = nil
109
+ subject2 = nil
110
+ subject3 = nil
111
+ f = Tempfile.new("test_options.yaml")
112
+ begin
113
+ f << opts_spec.to_yaml
114
+ f.open
115
+ subject1 = TestIoSubjectClass.new.configure( options_source: f )
116
+ subject2 = TestIoSubjectClass.new.configure( options_source: f.path )
117
+ File.open( f.path ) do |real_f|
118
+ subject3 = TestIoSubjectClass.new.configure( options_source: real_f )
119
+ end
120
+ ensure
121
+ f.close
122
+ f.unlink
123
+ end
124
+ [
125
+ subject1,
126
+ subject2,
127
+ subject3
128
+ ].each do |s|
129
+ expect(s).not_to be_nil
130
+ expect(s.test1).to eq "something1"
131
+ expect(s.test2).to eq "something2"
132
+ end
133
+ end
134
+
135
+ it 'allows specifying defaults' do
136
+ class << subject
137
+ param :test, default: "something3"
138
+ end
139
+ expect(subject.test).to eq "something3"
140
+ end
141
+
142
+ it 'allows restriciting value classes' do
143
+ class << subject
144
+ param :test, must_be: [Array,Hash]
145
+ end
146
+ expect{subject.test=[]}.not_to raise_error
147
+ expect{subject.test={}}.not_to raise_error
148
+ expect{subject.test=nil}.to raise_error
149
+ expect{subject.test=""}.to raise_error
150
+ end
151
+ it 'allows restriciting value classes through duck typing' do
152
+ class << subject
153
+ param :test, must_respond_to: [:each_pair, :size]
154
+ end
155
+ expect{subject.test=[]}.to raise_error
156
+ expect{subject.test={}}.not_to raise_error # the only one to respond to both :each_pair AND :size
157
+ expect{subject.test=nil}.to raise_error
158
+ expect{subject.test=""}.to raise_error
159
+ end
160
+
161
+ it 'allows locking selected variables' do
162
+ class << subject
163
+ param :test1, lockable: true
164
+ param :test2
165
+ end
166
+ expect{subject.test1="1"}.not_to raise_error
167
+ expect{subject.test2="1"}.not_to raise_error
168
+ expect(subject.test1).to eq "1"
169
+ expect(subject.test2).to eq "1"
170
+
171
+ subject.lock
172
+ expect(subject.is_locked).to eq true
173
+ expect{subject.test1="2"}.to raise_error
174
+ expect{subject.test2="2"}.not_to raise_error
175
+ expect(subject.test1).to eq "1"
176
+ expect(subject.test2).to eq "2"
177
+
178
+ subject.lock(false)
179
+ expect(subject.is_locked).to eq false
180
+ expect{subject.test1="3"}.not_to raise_error
181
+ expect{subject.test2="3"}.not_to raise_error
182
+ expect(subject.test1).to eq "3"
183
+ expect(subject.test2).to eq "3"
184
+ end
185
+
186
+ it 'allows restricting setting nil or empty variables' do
187
+ class << subject
188
+ param :test1, not_nil: true
189
+ param :test2, not_empty: true
190
+ end
191
+ expect{subject.test1="1"}.not_to raise_error
192
+ expect{subject.test2="1"}.not_to raise_error
193
+ expect(subject.test1).to eq "1"
194
+ expect(subject.test2).to eq "1"
195
+
196
+ expect{subject.test1=nil}.to raise_error
197
+ expect{subject.test2=nil}.to raise_error
198
+ expect(subject.test1).to eq "1"
199
+ expect(subject.test2).to eq "1"
200
+
201
+ expect{subject.test1=""}.not_to raise_error
202
+ expect{subject.test2=""}.to raise_error
203
+ expect(subject.test1).to eq ""
204
+ expect(subject.test2).to eq "1"
205
+ end
206
+
207
+ it 'allows converting to pre-defined types' do
208
+ class << subject
209
+ param :test_s, make_string: true
210
+ param :test_a, make_array: true
211
+ param :test_h, make_hash: true
212
+ param :test_i, make_int: true
213
+ param :test_f, make_float: true
214
+ param :test_b, make_bool: true
215
+ end
216
+ expect{subject.test_s=nil}.not_to raise_error
217
+ expect(subject.test_s).to be_a String
218
+ expect(subject.test_s).to eq ""
219
+
220
+ expect{subject.test_a=nil}.not_to raise_error
221
+ expect(subject.test_a).to be_a Array
222
+ expect(subject.test_a).to eq []
223
+
224
+ expect{subject.test_h=nil}.not_to raise_error
225
+ expect(subject.test_h).to be_a Hash
226
+ expect(subject.test_h).to eq Hash.new
227
+
228
+ expect{subject.test_i=nil}.not_to raise_error
229
+ expect(subject.test_i).to be_a Integer
230
+ expect(subject.test_i).to eq 0
231
+
232
+ expect{subject.test_f=nil}.not_to raise_error
233
+ expect(subject.test_f).to be_a Float
234
+ expect(subject.test_f).to eq 0.0
235
+
236
+ expect{subject.test_b=nil}.not_to raise_error
237
+ expect(subject.test_b).to be_a FalseClass
238
+ expect(subject.test_b).to eq false
239
+ end
240
+
241
+ it 'allows defining min/max boundaries for values' do
242
+ class << subject
243
+ param :test1, min: 10
244
+ param :test2, max: 'c'
245
+ end
246
+
247
+ expect{subject.test1=11}.not_to raise_error
248
+ expect{subject.test1=10}.not_to raise_error
249
+ expect{subject.test1=9}.to raise_error
250
+
251
+ expect{subject.test2='b'}.not_to raise_error
252
+ expect{subject.test2='c'}.not_to raise_error
253
+ expect{subject.test2='d'}.to raise_error
254
+ end
255
+
256
+ it 'allows defining ranges for values' do
257
+ class << subject
258
+ param :test1, in: 3..7
259
+ param :test2, in: ['a','c']
260
+ end
261
+
262
+ expect{subject.test1=3}.not_to raise_error
263
+ expect{subject.test1=6}.not_to raise_error
264
+ expect{subject.test1=9}.to raise_error
265
+
266
+ expect{subject.test2='a'}.not_to raise_error
267
+ expect{subject.test2='c'}.not_to raise_error
268
+ expect{subject.test2='b'}.to raise_error
269
+ end
270
+
271
+ it 'allows specifying a custom conversion method' do
272
+ class << subject
273
+ def check_for_x(value)
274
+ raise "X is not allowed" if value == "x"
275
+ "ok"
276
+ end
277
+ param :test1, convert: :check_for_x
278
+ param :test2, convert: ->(value) { value+1 }
279
+ end
280
+ expect{subject.test1=3}.not_to raise_error
281
+ expect(subject.test1).to eq "ok"
282
+ expect{subject.test1="x"}.to raise_error
283
+
284
+ expect{subject.test2=7}.not_to raise_error
285
+ expect(subject.test2).to eq 8
286
+ end
287
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Configuru::Configurable do
4
+ before(:each) do
5
+ module TestConfigurableModule
6
+ include Configuru::Configurable
7
+ provide_configuration
8
+ def_config_param :test1
9
+ end
10
+ module TestConfigurableModuleBase
11
+ include Configuru::Configurable
12
+ provide_configuration :base
13
+ def_config_param :test1
14
+ end
15
+ module TestConfigurableModuleInst
16
+ include Configuru::Configurable
17
+ provide_configuration :instances
18
+ def_config_param :test1
19
+ end
20
+
21
+ class TestConfigurableClass
22
+ include Configuru::Configurable
23
+ provide_configuration
24
+ def_config_param :test1
25
+ end
26
+ class TestConfigurableClassBase
27
+ include Configuru::Configurable
28
+ provide_configuration :base
29
+ def_config_param :test1
30
+ end
31
+ class TestConfigurableClassInst
32
+ include Configuru::Configurable
33
+ provide_configuration :instances
34
+ def_config_param :test1
35
+ end
36
+ end
37
+
38
+ it 'works for modules at base-level' do
39
+ expect{TestConfigurableModuleBase.configure(test1: "1")}.not_to raise_error
40
+ expect(TestConfigurableModuleBase.configuration.test1).to eq "1"
41
+ end
42
+ it 'does not work for modules at instance-level' do
43
+ expect{TestConfigurableModuleInst.configure(test1: "1")}.to raise_error
44
+ end
45
+
46
+ it 'works for classes at base-level' do
47
+ expect{TestConfigurableClassBase.configure(test1: "1")}.not_to raise_error
48
+ expect(TestConfigurableClassBase.configuration.test1).to eq "1"
49
+ end
50
+ it 'does not work for classes at instance-level' do
51
+ expect{TestConfigurableClassInst.configure(test1: "1")}.to raise_error
52
+ end
53
+
54
+ it 'works for class instances at instance-level' do
55
+ subject = TestConfigurableClassInst.new
56
+ expect{subject.configure(test1: "1")}.not_to raise_error
57
+ expect(subject.configuration.test1).to eq "1"
58
+ end
59
+ it 'does not work for class instances at base-level' do
60
+ subject = TestConfigurableClassBase.new
61
+ expect{subject.configure(test1: "1")}.to raise_error
62
+ end
63
+
64
+ it 'provides a separate configuration for each instance and class' do
65
+ subject1 = TestConfigurableClass.new
66
+ subject2 = TestConfigurableClass.new
67
+
68
+ expect{TestConfigurableClass.configure(test1: "0")}.not_to raise_error
69
+ expect{subject1.configure(test1: "1")}.not_to raise_error
70
+ expect{subject2.configure(test1: "2")}.not_to raise_error
71
+
72
+ expect(TestConfigurableClass.configuration.test1).to eq "0"
73
+ expect(subject1.configuration.test1).to eq "1"
74
+ expect(subject2.configuration.test1).to eq "2"
75
+ end
76
+ end
@@ -0,0 +1,4 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'configuru'
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: configuru
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - moonfly (Andrey Pronin)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: coveralls
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Provides convenient interface for managing configuration parameters for
70
+ modules, classes and instances.
71
+ email:
72
+ - moonfly.msk@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files:
76
+ - README.md
77
+ - CONTRIBUTORS.md
78
+ - LICENSE.md
79
+ files:
80
+ - ".gitignore"
81
+ - ".travis.yml"
82
+ - CHANGELOG.md
83
+ - CONTRIBUTORS.md
84
+ - Gemfile
85
+ - LICENSE.md
86
+ - README.md
87
+ - Rakefile
88
+ - configuru.gemspec
89
+ - lib/configuru.rb
90
+ - lib/configuru/config_methods.rb
91
+ - lib/configuru/configurable.rb
92
+ - lib/configuru/version.rb
93
+ - spec/configuru/config_methods_spec.rb
94
+ - spec/configuru/configurable_spec.rb
95
+ - spec/spec_helper.rb
96
+ homepage: https://github.com/moonfly/configuru
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options:
102
+ - "--charset=UTF-8"
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 2.1.0
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.2.2
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: Configuration for your classes
121
+ test_files:
122
+ - spec/configuru/config_methods_spec.rb
123
+ - spec/configuru/configurable_spec.rb
124
+ - spec/spec_helper.rb