classx 0.0.1
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/ChangeLog +4 -0
- data/README +39 -0
- data/Rakefile +52 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-block_rb.html +661 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-callbacks_rb.html +932 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-change_rb.html +779 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-hunk_rb.html +867 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs_rb.html +1715 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-rcov-0_8_1_2_0-lib-rcov_rb.html +1598 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-drb_rb.html +2373 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-eq_rb.html +626 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-invokemethod_rb.html +646 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-forwardable_rb.html +828 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-pp_rb.html +1257 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-prettyprint_rb.html +1506 -0
- data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-timeout_rb.html +715 -0
- data/doc/output/coverage/index.html +603 -0
- data/doc/output/coverage/lib-classx-validate_rb.html +645 -0
- data/doc/output/coverage/lib-classx_rb.html +752 -0
- data/lib/classx.rb +142 -0
- data/lib/classx.rb.new +102 -0
- data/lib/classx/attributes.rb +13 -0
- data/lib/classx/commandable.rb +8 -0
- data/lib/classx/validate.rb +35 -0
- data/spec/classx_spec.rb +261 -0
- data/spec/classx_validate_spec.rb +40 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +4 -0
- data/tasks/basic_config.rake +22 -0
- data/tasks/basic_tasks.rake +139 -0
- metadata +107 -0
data/lib/classx.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
|
2
|
+
class ClassX
|
3
|
+
class AttrRequiredError < Exception; end
|
4
|
+
class InvalidAttrArgument < Exception; end
|
5
|
+
class LazyOptionShouldHaveDefault < Exception; end
|
6
|
+
class OptionalAttrShouldBeWritable < Exception; end
|
7
|
+
class RequiredAttrShouldNotHaveDefault < Exception; end
|
8
|
+
class <<self
|
9
|
+
def has name, attrs={}
|
10
|
+
name = name.to_s
|
11
|
+
|
12
|
+
setter_definition = ''
|
13
|
+
if !attrs[:respond_to].nil?
|
14
|
+
setter_definition += <<-END_OF_RESPOND_TO
|
15
|
+
raise InvalidAttrArgument, "param :#{name}'s value \#{val.inspect} should respond_to #{attrs[:respond_to]}}" unless val.respond_to? #{attrs[:respond_to]}
|
16
|
+
END_OF_RESPOND_TO
|
17
|
+
end
|
18
|
+
if !attrs[:kind_of].nil?
|
19
|
+
setter_definition += <<-END_OF_KIND_OF
|
20
|
+
raise InvalidAttrArgument, "param :#{name}'s value \#{val.inspect} should kind_of #{attrs[:kind_of]}" unless val.kind_of? #{attrs[:kind_of]}
|
21
|
+
END_OF_KIND_OF
|
22
|
+
end
|
23
|
+
|
24
|
+
self.class_eval <<-END_OF_ACCESSOR
|
25
|
+
attr_reader "#{name}"
|
26
|
+
|
27
|
+
def #{name}= val
|
28
|
+
#{setter_definition}
|
29
|
+
@#{name} = val
|
30
|
+
end
|
31
|
+
END_OF_ACCESSOR
|
32
|
+
|
33
|
+
if attrs[:default].nil?
|
34
|
+
raise LazyOptionShouldHaveDefault, "in :#{name}: :lazy option need specifying :default" if attrs[:lazy]
|
35
|
+
else
|
36
|
+
# when you specify :optional to false explicitly, raise Error.
|
37
|
+
if attrs[:optional].nil?
|
38
|
+
attrs[:optional] = true
|
39
|
+
end
|
40
|
+
raise RequiredAttrShouldNotHaveDefault, "in :#{name}: required attribute should not have :default option" unless attrs[:optional]
|
41
|
+
case attrs[:default]
|
42
|
+
when Proc
|
43
|
+
register_attr_default_value_proc name, &attrs[:default]
|
44
|
+
else
|
45
|
+
register_attr_default_value name, attrs[:default]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if attrs[:optional]
|
50
|
+
if attrs[:writable].nil?
|
51
|
+
attrs[:writable] = true
|
52
|
+
else
|
53
|
+
raise OptionalAttrShouldBeWritable unless attrs[:writable]
|
54
|
+
end
|
55
|
+
else
|
56
|
+
register_attr_required name
|
57
|
+
end
|
58
|
+
|
59
|
+
unless attrs[:writable]
|
60
|
+
__send__ :private,"#{name}="
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
def register_attr_default_value name, value
|
66
|
+
self.class_eval do
|
67
|
+
define_method "set_attr_default_value_of[#{name}]" do
|
68
|
+
self.__send__ "#{name}=", value
|
69
|
+
end
|
70
|
+
|
71
|
+
private "set_attr_default_value_of[#{name}]"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def register_attr_default_value_proc name, &block
|
76
|
+
self.class_eval do
|
77
|
+
define_method "set_attr_default_value_of[#{name}]" do
|
78
|
+
self.__send__ "#{name}=", block.call(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
private "set_attr_default_value_of[#{name}]"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def register_attr_required name
|
86
|
+
define_method "attr_required[#{name}]" do
|
87
|
+
end
|
88
|
+
|
89
|
+
private "attr_required[#{name}]"
|
90
|
+
end
|
91
|
+
|
92
|
+
ATTR_REGEX = /^([^=]*?)=$/
|
93
|
+
def attributes
|
94
|
+
( public_instance_methods + private_instance_methods ).select {|meth|
|
95
|
+
meth.to_s =~ ATTR_REGEX
|
96
|
+
}.map {|item|
|
97
|
+
item.to_s.sub(ATTR_REGEX) { $1 }
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
ATTR_REQUIRED_REGEX = /^attr_required\[(.*?)\]/
|
102
|
+
def required_attributes
|
103
|
+
private_instance_methods.select {|meth|
|
104
|
+
meth.to_s =~ ATTR_REQUIRED_REGEX
|
105
|
+
}.map {|item|
|
106
|
+
item.sub(ATTR_REQUIRED_REGEX) { $1 }
|
107
|
+
}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def initialize hash={}
|
112
|
+
before_init hash
|
113
|
+
|
114
|
+
unless hash && hash.kind_of?(Hash)
|
115
|
+
raise ArgumentError, "#{hash.inspect} was wrong as arguments. please specify kind of Hash instance"
|
116
|
+
end
|
117
|
+
|
118
|
+
hash = hash.inject({}) {|h,item| h[item.first.to_s] = item.last; h } # allow String or Symbol for key
|
119
|
+
self.class.required_attributes.each do |name|
|
120
|
+
raise AttrRequiredError, "param :#{name} is required to #{hash.inspect}" unless hash.keys.include?(name)
|
121
|
+
end
|
122
|
+
hash.each do |key,val|
|
123
|
+
if respond_to? "#{key}=", true
|
124
|
+
__send__ "#{key}=", val
|
125
|
+
end
|
126
|
+
end
|
127
|
+
private_methods.select do |meth|
|
128
|
+
meth.to_s =~ /^set_attr_default_value_of\[(.*?)\]$/
|
129
|
+
end.each do |meth|
|
130
|
+
__send__ meth
|
131
|
+
end
|
132
|
+
after_init
|
133
|
+
end
|
134
|
+
|
135
|
+
# just extend point
|
136
|
+
def before_init hash
|
137
|
+
end
|
138
|
+
|
139
|
+
def after_init
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
data/lib/classx.rb.new
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
|
2
|
+
class ClassX
|
3
|
+
class AttrRequiredError < Exception; end
|
4
|
+
class InvalidSetterArgument < Exception; end
|
5
|
+
class LazyOptionShouldHaveDefault < Exception; end
|
6
|
+
class <<self
|
7
|
+
def has name, attrs={ :is => :ro, :required => false }
|
8
|
+
__send__ :attr_accessor, name
|
9
|
+
|
10
|
+
setter_definition = ''
|
11
|
+
if !attrs[:respond_to].nil?
|
12
|
+
setter_definition += <<-END_OF_RESPOND_TO
|
13
|
+
raise InvalidSetterArgument, "param :#{name}'s value \#{val.inspect} should respond_to #{attrs[:respond_to]}}" unless val.respond_to? #{attrs[:respond_to]}
|
14
|
+
END_OF_RESPOND_TO
|
15
|
+
end
|
16
|
+
if !attrs[:kind_of].nil?
|
17
|
+
setter_definition += <<-END_OF_KIND_OF
|
18
|
+
raise InvalidSetterArgument, "param :#{name}'s value \#{val.inspect} should kind_of #{attrs[:kind_of]}" unless val.kind_of? #{attrs[:kind_of]}
|
19
|
+
END_OF_KIND_OF
|
20
|
+
end
|
21
|
+
|
22
|
+
if !attrs[:default].nil?
|
23
|
+
case attrs[:default]
|
24
|
+
when Proc
|
25
|
+
register_attr_default_value_proc name, &attrs[:default]
|
26
|
+
else
|
27
|
+
register_attr_default_value name, attrs[:default]
|
28
|
+
end
|
29
|
+
else
|
30
|
+
raise LazyOptionShouldHaveDefault, "in :#{name}: :lazy option need specifying :default" if attrs[:lazy]
|
31
|
+
end
|
32
|
+
|
33
|
+
if attrs[:required]
|
34
|
+
register_attr_required name
|
35
|
+
end
|
36
|
+
|
37
|
+
self.class_eval <<-END_OF_ACCESSOR
|
38
|
+
attr_reader "#{name.to_s}"
|
39
|
+
|
40
|
+
def #{name.to_s}= val
|
41
|
+
#{setter_definition}
|
42
|
+
@#{name.to_s} = val
|
43
|
+
end
|
44
|
+
END_OF_ACCESSOR
|
45
|
+
|
46
|
+
if attrs[:is] == :ro
|
47
|
+
__send__ :private,"#{name.to_s}="
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def register_attr_default_value name, value
|
52
|
+
self.class_eval do
|
53
|
+
define_method "set_attr_default_value_of[#{name.to_s}]" do
|
54
|
+
self.__send__ "#{name.to_s}=", value
|
55
|
+
end
|
56
|
+
|
57
|
+
private "set_attr_default_value_of[#{name.to_s}]"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def register_attr_default_value_proc name, &block
|
62
|
+
self.class_eval do
|
63
|
+
define_method "set_attr_default_value_of[#{name.to_s}]" do
|
64
|
+
self.__send__ "#{name.to_s}=", block.call(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
private "set_attr_default_value_of[#{name.to_s}]"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def register_attr_required name
|
72
|
+
@@attr_required ||= {}
|
73
|
+
@@attr_required[name] = true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def initialize hash={}
|
78
|
+
before_init
|
79
|
+
@@attr_required ||= {}
|
80
|
+
@@attr_required.each do |req, is_required|
|
81
|
+
if is_required
|
82
|
+
raise AttrRequiredError, "param :#{req} is required to initialize #{self.class}" unless hash.keys.include?(req)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
hash.each do |key,val|
|
86
|
+
__send__ "#{key.to_s}=", val
|
87
|
+
end
|
88
|
+
private_methods.select do |meth|
|
89
|
+
meth.to_s =~ /^set_attr_default_value_of\[(.*?)\]$/
|
90
|
+
end.each do |meth|
|
91
|
+
__send__ meth
|
92
|
+
end
|
93
|
+
after_init
|
94
|
+
end
|
95
|
+
|
96
|
+
# just extend point
|
97
|
+
def before_init
|
98
|
+
end
|
99
|
+
|
100
|
+
def after_init
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ClassX::Validate
|
2
|
+
private
|
3
|
+
#
|
4
|
+
# for validatation Hash parameter declaretively.
|
5
|
+
#
|
6
|
+
# require 'classx/validate'
|
7
|
+
#
|
8
|
+
# class YourClass < ClassX
|
9
|
+
# include Validate
|
10
|
+
#
|
11
|
+
# def run params
|
12
|
+
# validate params do
|
13
|
+
# has :x
|
14
|
+
# has :y, :default => "hoge", :kind_of => Hash
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # do something with params
|
18
|
+
#
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# YourClass.new.run(:x => 10) # raise ClassX::AttrRequiredError
|
23
|
+
#
|
24
|
+
def validate hash, &block
|
25
|
+
# FIXME: it's experimental feature for caching validate class.
|
26
|
+
# it can use class variable because it use caller[0] as key.
|
27
|
+
@@__validate_cached ||= {}
|
28
|
+
uniq_key = caller[0]
|
29
|
+
unless @@__validate_cached[uniq_key]
|
30
|
+
@@__validate_cached[uniq_key] = Class.new(ClassX)
|
31
|
+
@@__validate_cached[uniq_key].class_eval &block
|
32
|
+
end
|
33
|
+
@@__validate_cached[uniq_key].new hash
|
34
|
+
end
|
35
|
+
end
|
data/spec/classx_spec.rb
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'classx'
|
3
|
+
|
4
|
+
describe ClassX do
|
5
|
+
describe '#has' do
|
6
|
+
describe 'without accessor' do
|
7
|
+
before do
|
8
|
+
@class = Class.new(ClassX)
|
9
|
+
@class.class_eval do
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should not raise_error' do
|
14
|
+
lambda { @class.new }.should_not raise_error(Exception)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should raise ArgumentError when recieved nil as initialize argument' do
|
18
|
+
lambda { @class.new(nil) }.should raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should raise ArgumentError when recieved not kind of Hash instance as initialize argument' do
|
22
|
+
lambda { @class.new([]) }.should raise_error(ArgumentError)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have empty attributes' do
|
26
|
+
@class.attributes.should be_empty
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'without any option' do
|
31
|
+
before do
|
32
|
+
@class = Class.new(ClassX)
|
33
|
+
@class.class_eval do
|
34
|
+
has :x
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should required :x on initialize' do
|
39
|
+
lambda { @class.new }.should raise_error(ClassX::AttrRequiredError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should define #x= private method to class' do
|
43
|
+
@class.private_instance_methods.map {|meth| meth.to_s }.should be_include("x=")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'with :writable option' do
|
48
|
+
describe 'when you specify false for attribute' do
|
49
|
+
before do
|
50
|
+
@class = Class.new(ClassX)
|
51
|
+
@class.class_eval do
|
52
|
+
has :x, :writable => false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should define #x public method to class' do
|
57
|
+
@class.instance_methods.map {|meth| meth.to_s }.should be_include('x')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should define #x= private method to class' do
|
61
|
+
@class.private_instance_methods.map {|meth| meth.to_s }.should be_include("x=")
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should have attributes [:x]' do
|
65
|
+
@class.attributes.should == ['x']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'when you specify true for attribute' do
|
70
|
+
before do
|
71
|
+
@class = Class.new(ClassX)
|
72
|
+
@class.class_eval do
|
73
|
+
has :x, :writable => true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should define #x public method to class' do
|
78
|
+
@class.instance_methods.map {|meth| meth.to_s }.should be_include('x')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should define #x= public method to class' do
|
82
|
+
@class.public_instance_methods.map {|meth| meth.to_s }.should be_include("x=")
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should have attributes [:x]' do
|
86
|
+
@class.attributes.should == ['x']
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'with :default option' do
|
92
|
+
describe 'when value is Proc' do
|
93
|
+
before do
|
94
|
+
@class = Class.new(ClassX)
|
95
|
+
@class.class_eval do
|
96
|
+
has :x, :default => proc { Object.new }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'shouold have any value when instanciate' do
|
101
|
+
@class.new.x.should_not be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should have difference of object_id between some instance' do
|
105
|
+
@class.new.x.should_not equal(@class.new.x)
|
106
|
+
end
|
107
|
+
|
108
|
+
# TODO: with lazy option
|
109
|
+
# it "can use self as Proc's argument" do
|
110
|
+
# @class.class_eval do
|
111
|
+
# has :y, :default => proc {|mine| mine.x }
|
112
|
+
# end
|
113
|
+
|
114
|
+
# @class.new.y.should equal(@class.new.x)
|
115
|
+
# end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'when value is not Proc' do
|
119
|
+
before do
|
120
|
+
@class = Class.new(ClassX)
|
121
|
+
@class.class_eval do
|
122
|
+
has :x, :default => []
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should have any value when instanciate' do
|
127
|
+
@class.new.x.should == []
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should have the same object_id between some instance' do
|
131
|
+
@class.new.x.should equal(@class.new.x)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'with :optional is false' do
|
137
|
+
before do
|
138
|
+
@class = Class.new(ClassX)
|
139
|
+
@class.class_eval do
|
140
|
+
has :x, :optional => false
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should raise AttrRequiredError without value" do
|
145
|
+
lambda { @class.new }.should raise_error(ClassX::AttrRequiredError)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should not raise AttrRequiredError with value" do
|
149
|
+
lambda { @class.new(:x => Object.new) }.should_not raise_error(ClassX::AttrRequiredError)
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should not raise AttrRequiredError with key as String' do
|
153
|
+
lambda { @class.new('x' => Object.new) }.should_not raise_error(ClassX::AttrRequiredError)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe ':optional is false and with :default option' do
|
158
|
+
it 'should raise ClassX::RequiredAttrShouldNotHaveDefault' do
|
159
|
+
lambda {
|
160
|
+
klass = Class.new(ClassX)
|
161
|
+
klass.class_eval do
|
162
|
+
has :x, :optional => false, :default => 1
|
163
|
+
end
|
164
|
+
}.should raise_error(ClassX::RequiredAttrShouldNotHaveDefault)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe 'declare attribute without :optional and :default option' do
|
169
|
+
before do
|
170
|
+
@class = Class.new(ClassX)
|
171
|
+
@class.class_eval do
|
172
|
+
has :x, :kind_of => Integer
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should be required attribute' do
|
177
|
+
lambda { @class.new }.should raise_error(ClassX::AttrRequiredError)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe ':optional is true and without :default option' do
|
182
|
+
before do
|
183
|
+
@class = Class.new(ClassX)
|
184
|
+
@class.class_eval do
|
185
|
+
has :x, :optional => true, :kind_of => Integer
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'should be required attribute' do
|
190
|
+
lambda { @class.new }.should_not raise_error(ClassX::AttrRequiredError)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe 'with multiple class' do
|
195
|
+
before do
|
196
|
+
@class1 = Class.new(ClassX)
|
197
|
+
@class1.class_eval do
|
198
|
+
has :x
|
199
|
+
end
|
200
|
+
@class2 = Class.new(ClassX)
|
201
|
+
@class2.class_eval do
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should not raise AttrRequiredError when initialized anothor class' do
|
206
|
+
lambda { @class2.new }.should_not raise_error(ClassX::AttrRequiredError)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe 'with :optional is true' do
|
211
|
+
describe 'without :writable option' do
|
212
|
+
before do
|
213
|
+
@class = Class.new(ClassX)
|
214
|
+
@class.class_eval do
|
215
|
+
has :x, :optional => true
|
216
|
+
end
|
217
|
+
end
|
218
|
+
it 'should not raise AttrRequiredError' do
|
219
|
+
lambda { @class.new }.should_not raise_error(ClassX::AttrRequiredError)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe 'with :writable is false' do
|
224
|
+
it 'should raise ClassX::OptionalAttrShouldBeWritable' do
|
225
|
+
lambda {
|
226
|
+
klass = Class.new(ClassX)
|
227
|
+
klass.class_eval do
|
228
|
+
has :x, :optional => true, :writable => false
|
229
|
+
end
|
230
|
+
}.should raise_error(ClassX::OptionalAttrShouldBeWritable)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe 'with :writable is true' do
|
235
|
+
it 'should raise ClassX::OptionalAttrShouldBeWritable' do
|
236
|
+
lambda {
|
237
|
+
klass = Class.new(ClassX)
|
238
|
+
klass.class_eval do
|
239
|
+
has :x, :optional => true, :writable => true
|
240
|
+
end
|
241
|
+
}.should_not raise_error(ClassX::OptionalAttrShouldBeWritable)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe 'not attribute param exist in #initialize argument' do
|
247
|
+
before do
|
248
|
+
@class = Class.new(ClassX)
|
249
|
+
@class.class_eval do
|
250
|
+
has :x
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# TODO: I'll change it to be able to choosee wheather check this strictly or not.
|
255
|
+
# In many case, lack argument cause any problem. On the other hand, extra argument does not cause any problem, I think.
|
256
|
+
it 'should be ignored' do
|
257
|
+
lambda { @class.new(:x => 10, :y => 20 ) }.should_not raise_error(Exception)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|