configuru 0.1.0

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