constructable 0.2.5 → 0.3.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.
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/constructable.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{constructable}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Manuel Korfmann"]
|
12
|
-
s.date = %q{2011-06-
|
12
|
+
s.date = %q{2011-06-15}
|
13
13
|
s.description = %q{
|
14
14
|
Adds the class macro Class#constructable to easily define what attributes a Class accepts provided as a hash to Class#new.
|
15
15
|
Attributes can be configured in their behaviour in case they are not provided or are in the wrong format.
|
@@ -4,12 +4,6 @@ module Constructable
|
|
4
4
|
attr_accessor *ATTRIBUTES, :name
|
5
5
|
attr_reader :value
|
6
6
|
|
7
|
-
REQUIRED_REQUIREMENT = {
|
8
|
-
name: :required,
|
9
|
-
message: proc {":#{self.name} is a required attribute"},
|
10
|
-
check: ->(hash) { hash[self.name] }
|
11
|
-
}
|
12
|
-
|
13
7
|
REQUIREMENTS = [
|
14
8
|
{
|
15
9
|
name: :validate,
|
@@ -55,10 +49,11 @@ module Constructable
|
|
55
49
|
REQUIREMENTS.each do |requirement|
|
56
50
|
check_for_requirement(requirement, constructor_hash)
|
57
51
|
end
|
52
|
+
|
58
53
|
value = constructor_hash[self.name]
|
59
54
|
self.converter ? converter.(value) : value
|
60
55
|
else
|
61
|
-
|
56
|
+
raise AttributeError, ":#{self.name} is a required attribute" if self.required
|
62
57
|
self.default
|
63
58
|
end
|
64
59
|
end
|
@@ -2,11 +2,12 @@ module Constructable
|
|
2
2
|
class Constructor
|
3
3
|
attr_accessor :attributes
|
4
4
|
|
5
|
-
def initialize(
|
5
|
+
def initialize(base)
|
6
6
|
@attributes = []
|
7
|
-
@
|
8
|
-
|
9
|
-
|
7
|
+
@module = Module.new
|
8
|
+
@base = base
|
9
|
+
@base.send :include, @module
|
10
|
+
self.define_concstructable_attributes_method
|
10
11
|
end
|
11
12
|
|
12
13
|
def redefine_new(klass)
|
@@ -20,14 +21,13 @@ module Constructable
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
24
|
def define_attributes(attributes)
|
25
25
|
attributes = generate_attributes(attributes)
|
26
26
|
@attributes.concat attributes
|
27
27
|
|
28
28
|
attributes = @attributes
|
29
29
|
attributes.each do |attribute|
|
30
|
-
@
|
30
|
+
@module.module_eval do
|
31
31
|
attr_reader attribute.name if attribute.readable
|
32
32
|
|
33
33
|
define_method(:"#{attribute.name}=") do |value|
|
@@ -50,10 +50,10 @@ module Constructable
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
53
|
+
def define_concstructable_attributes_method
|
54
54
|
constructor = self
|
55
|
-
@
|
56
|
-
define_method :
|
55
|
+
@base.module_eval do
|
56
|
+
define_method :constructable_attributes do
|
57
57
|
Hash[
|
58
58
|
constructor.attributes
|
59
59
|
.map { |a| [a.name,instance_variable_get(a.ivar_symbol)] }
|
@@ -34,16 +34,17 @@ module Constructable
|
|
34
34
|
#
|
35
35
|
# @param [Array<[Array<Symbol, Hash>]>] args an array of symbols or arrays: the name of the attribute and it's configuration
|
36
36
|
def constructable(*args)
|
37
|
+
@constructor ||= Constructor.new(self)
|
38
|
+
@constructor.define_attributes(args)
|
37
39
|
case self
|
38
40
|
when Class
|
39
|
-
@constructor
|
40
|
-
@constructor.define_attributes(args)
|
41
|
-
return nil
|
41
|
+
@constructor.redefine_new(self)
|
42
42
|
when Module
|
43
|
-
define_singleton_method :included do |
|
44
|
-
|
43
|
+
define_singleton_method :included do |base|
|
44
|
+
@constructor.redefine_new(base) if Class === base
|
45
45
|
end
|
46
46
|
end
|
47
|
+
return nil
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
@@ -2,13 +2,6 @@ require 'helper'
|
|
2
2
|
describe 'integration' do
|
3
3
|
describe 'Class' do
|
4
4
|
describe 'constructable' do
|
5
|
-
it 'should define attr_accessors' do
|
6
|
-
klass = Class.new
|
7
|
-
klass.constructable([:foo, accessible: true])
|
8
|
-
assert_respond_to klass.new, :foo
|
9
|
-
assert_respond_to klass.new, :foo=
|
10
|
-
end
|
11
|
-
|
12
5
|
it 'should assign values found in the constructer hash' do
|
13
6
|
klass = Class.new
|
14
7
|
klass.constructable([:foo, readable: true])
|
@@ -45,17 +38,19 @@ describe 'integration' do
|
|
45
38
|
assert_equal 20, instance.bar
|
46
39
|
end
|
47
40
|
|
48
|
-
it 'works for methods with
|
41
|
+
it 'works for initialize methods with arguments' do
|
49
42
|
klass = Class.new
|
50
43
|
klass.constructable [:bar, accessible: true]
|
44
|
+
klass.send :attr_accessor, :baz
|
51
45
|
klass.class_eval do
|
52
|
-
def initialize(
|
53
|
-
self.
|
46
|
+
def initialize(baz, options = {})
|
47
|
+
self.baz = baz
|
54
48
|
end
|
55
49
|
end
|
56
50
|
|
57
|
-
instance = klass.new(1)
|
58
|
-
assert_equal 1, instance.
|
51
|
+
instance = klass.new(1, bar: 5)
|
52
|
+
assert_equal 1, instance.baz
|
53
|
+
assert_equal 5, instance.bar
|
59
54
|
end
|
60
55
|
end
|
61
56
|
|
@@ -2,9 +2,17 @@ require 'helper'
|
|
2
2
|
describe 'Constructor' do
|
3
3
|
before do
|
4
4
|
@klass = Class.new
|
5
|
+
@module = Module.new
|
5
6
|
end
|
6
7
|
|
7
8
|
describe 'define_attributes' do
|
9
|
+
it 'should define attr_accessors' do
|
10
|
+
klass = Class.new
|
11
|
+
klass.constructable([:foo, accessible: true])
|
12
|
+
assert_respond_to klass.new, :foo
|
13
|
+
assert_respond_to klass.new, :foo=
|
14
|
+
end
|
15
|
+
|
8
16
|
it 'defines public setters validating like in the constructor' do
|
9
17
|
@klass.constructable [:integer, validate_type: Integer, writable: true]
|
10
18
|
instance = @klass.new
|
@@ -12,13 +20,82 @@ describe 'Constructor' do
|
|
12
20
|
instance.integer = 6.6
|
13
21
|
end
|
14
22
|
end
|
23
|
+
|
24
|
+
describe 'redefining' do
|
25
|
+
|
26
|
+
describe 'class' do
|
27
|
+
it 'getters ' do
|
28
|
+
@klass.constructable [:integer, validate_type: Integer, accessible: true]
|
29
|
+
@klass.class_eval { define_method(:integer){ 1 } }
|
30
|
+
instance = @klass.new(integer: 2)
|
31
|
+
assert_equal 1, instance.integer
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'setters ' do
|
35
|
+
@klass.constructable [:integer, validate_type: Integer, accessible: true]
|
36
|
+
@klass.class_eval { def integer=(foo);@integer = 1;end }
|
37
|
+
instance = @klass.new(integer: 4)
|
38
|
+
instance.integer = 5
|
39
|
+
assert_equal 1, instance.integer
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'module' do
|
44
|
+
before do
|
45
|
+
@module.constructable [:integer, validate_type: Integer, accessible: true]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'getters ' do
|
49
|
+
@module.module_eval { def integer;1;end }
|
50
|
+
@klass.send :include,@module
|
51
|
+
instance = @klass.new(integer: 2)
|
52
|
+
assert_equal 1, instance.integer
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'setters ' do
|
56
|
+
@module.module_eval { def integer=(foo);@integer = 1;end }
|
57
|
+
@klass.send :include,@module
|
58
|
+
instance = @klass.new(integer: 4)
|
59
|
+
instance.integer = 5
|
60
|
+
assert_equal 1, instance.integer
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'also works for multiple inclusion' do
|
64
|
+
@module.module_eval { def integer=(foo);@integer = 1;end }
|
65
|
+
other_module = Module.new
|
66
|
+
other_module.send :include, @module
|
67
|
+
@klass.send :include, other_module
|
68
|
+
instance = @klass.new(integer: 4)
|
69
|
+
instance.integer = 5
|
70
|
+
assert_equal 1, instance.integer
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'allows to super to the generated method' do
|
75
|
+
it 'gets' do
|
76
|
+
@klass.constructable [:integer, validate_type: Integer, accessible: true]
|
77
|
+
@klass.class_eval { def integer; super ;end }
|
78
|
+
instance = @klass.new(integer: 2)
|
79
|
+
assert_equal 2, instance.integer
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'sets' do
|
83
|
+
@klass.constructable [:integer, validate_type: Integer, accessible: true]
|
84
|
+
@klass.class_eval { def integer=(value); super ;end }
|
85
|
+
instance = @klass.new(integer: 2)
|
86
|
+
assert_raises Constructable::AttributeError do
|
87
|
+
instance.integer = :not_an_integer
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
15
92
|
end
|
16
93
|
|
17
|
-
describe 'Class#
|
94
|
+
describe 'Class#constructable_attributes' do
|
18
95
|
it 'returns the attribute matching the symbol' do
|
19
96
|
@klass.constructable :foo, :bar
|
20
97
|
instance = @klass.new(foo: 6)
|
21
|
-
assert_equal({ foo: 6 }, instance.
|
98
|
+
assert_equal({ foo: 6 }, instance.constructable_attributes)
|
22
99
|
end
|
23
100
|
end
|
24
101
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: constructable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Manuel Korfmann
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-06-
|
13
|
+
date: 2011-06-15 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -103,7 +103,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
103
|
requirements:
|
104
104
|
- - ">="
|
105
105
|
- !ruby/object:Gem::Version
|
106
|
-
hash:
|
106
|
+
hash: 830416941491402705
|
107
107
|
segments:
|
108
108
|
- 0
|
109
109
|
version: "0"
|