doodle 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/COPYING +18 -0
- data/README +57 -0
- data/examples/event.rb +30 -0
- data/examples/event1.rb +33 -0
- data/examples/event2.rb +21 -0
- data/examples/example-01.rb +16 -0
- data/examples/example-01.rdoc +16 -0
- data/examples/example-02.rb +61 -0
- data/examples/example-02.rdoc +62 -0
- data/lib/doodle.rb +800 -0
- data/lib/molic_orderedhash.rb +243 -0
- data/lib/spec_helper.rb +19 -0
- data/spec/arg_order_spec.rb +125 -0
- data/spec/attributes_spec.rb +106 -0
- data/spec/class_spec.rb +90 -0
- data/spec/conversion_spec.rb +59 -0
- data/spec/defaults_spec.rb +158 -0
- data/spec/doodle_spec.rb +297 -0
- data/spec/flatten_first_level_spec.rb +36 -0
- data/spec/required_spec.rb +25 -0
- data/spec/superclass_spec.rb +27 -0
- data/spec/validation_spec.rb +108 -0
- metadata +74 -0
data/spec/class_spec.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '../.'))
|
2
|
+
require 'lib/spec_helper'
|
3
|
+
|
4
|
+
describe Doodle, 'class attributes' do
|
5
|
+
after :each do
|
6
|
+
undefine_const(:Bar)
|
7
|
+
undefine_const(:Foo)
|
8
|
+
end
|
9
|
+
before(:each) do
|
10
|
+
raise_if_defined(:Foo, :Bar)
|
11
|
+
class Foo
|
12
|
+
include Doodle::Helper
|
13
|
+
class << self
|
14
|
+
has :metadata
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@foo = Foo.new
|
18
|
+
class Bar < Foo
|
19
|
+
include Doodle::Helper
|
20
|
+
class << self
|
21
|
+
has :doc
|
22
|
+
end
|
23
|
+
end
|
24
|
+
@foo = Foo.new
|
25
|
+
@bar = Bar.new
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should create class attribute' do
|
29
|
+
Foo.metadata = 'Foo metadata'
|
30
|
+
Foo.metadata.should == 'Foo metadata'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should access class attribute via self.class' do
|
34
|
+
@foo.class.metadata = '@foo metadata'
|
35
|
+
@foo.class.metadata.should == '@foo metadata'
|
36
|
+
Foo.metadata.should == '@foo metadata'
|
37
|
+
|
38
|
+
Foo.metadata = 'Foo metadata'
|
39
|
+
Foo.metadata.should == 'Foo metadata'
|
40
|
+
@foo.class.metadata.should == 'Foo metadata'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should list all class's own attributes" do
|
44
|
+
Foo.meta.attributes(false).keys.should == [:metadata]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should list all class's own attributes" do
|
48
|
+
Foo.meta.attributes.keys.should == [:metadata]
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should create Bar class attribute' do
|
52
|
+
Bar.metadata = 'Bar metadata'
|
53
|
+
Bar.metadata.should == 'Bar metadata'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should access class attribute via self.class' do
|
57
|
+
@bar.class.metadata = '@bar metadata'
|
58
|
+
@bar.class.metadata.should == '@bar metadata'
|
59
|
+
Bar.metadata.should == '@bar metadata'
|
60
|
+
|
61
|
+
Bar.metadata = 'Bar metadata'
|
62
|
+
Bar.metadata.should == 'Bar metadata'
|
63
|
+
@bar.class.metadata.should == 'Bar metadata'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should not allow inherited class attributes to interfere with each other' do
|
67
|
+
Foo.metadata = 'Foo metadata'
|
68
|
+
@bar.class.metadata = '@bar metadata'
|
69
|
+
@bar.class.metadata.should == '@bar metadata'
|
70
|
+
Bar.metadata.should == '@bar metadata'
|
71
|
+
|
72
|
+
Bar.metadata = 'Bar metadata'
|
73
|
+
Bar.metadata.should == 'Bar metadata'
|
74
|
+
@bar.class.metadata.should == 'Bar metadata'
|
75
|
+
|
76
|
+
Foo.metadata.should == 'Foo metadata'
|
77
|
+
@foo.class.metadata.should == 'Foo metadata'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should list all class's own attributes" do
|
81
|
+
Bar.meta.attributes(false).keys.should == [:doc]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should list all class's own attributes" do
|
85
|
+
Bar.meta.attributes.keys.should == [:metadata, :doc]
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
raise_if_defined(:Foo, :Bar)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '../.'))
|
2
|
+
|
3
|
+
require 'lib/spec_helper'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
describe Doodle, 'defaults which have not been set' do
|
7
|
+
after :each do
|
8
|
+
undefine_const(:Foo)
|
9
|
+
end
|
10
|
+
before(:each) do
|
11
|
+
raise_if_defined(:Foo)
|
12
|
+
class Foo < Doodle::Base
|
13
|
+
has :start do
|
14
|
+
default { Date.today }
|
15
|
+
from String do |s|
|
16
|
+
Doodle::Debug.d { [:converting_from, String, s] }
|
17
|
+
Date.parse(s)
|
18
|
+
end
|
19
|
+
from Integer do |jd|
|
20
|
+
Doodle::Debug.d { [:converting_from, Integer, jd] }
|
21
|
+
Date.new(*Date.jd_to_civil(jd))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
from String do |s|
|
25
|
+
Doodle::Debug.d { [:from, self, self.class] }
|
26
|
+
new(:start => s)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should have default date == today' do
|
32
|
+
foo = Foo.new
|
33
|
+
foo.start.should == Date.today
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should convert String to Date' do
|
37
|
+
foo = Foo.new(:start => '2007-12-31')
|
38
|
+
foo.start.should == Date.new(2007, 12, 31)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should convert Integer representing Julian date to Date' do
|
42
|
+
foo = Foo.new(:start => 2454428)
|
43
|
+
foo.start.should == Date.new(2007, 11, 23)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should allow from' do
|
47
|
+
foo = Foo.from("2007-12-31")
|
48
|
+
foo.start.should == Date.new(2007, 12, 31)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should allow factory function' do
|
52
|
+
# class Foo
|
53
|
+
# include Doodle::Factory
|
54
|
+
# end
|
55
|
+
foo = Foo("2007-12-31")
|
56
|
+
foo.start.should == Date.new(2007, 12, 31)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,158 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '../.'))
|
2
|
+
|
3
|
+
require 'lib/spec_helper'
|
4
|
+
require 'date'
|
5
|
+
raise_if_defined :Foo, :Text, :Text2, :KeyValue
|
6
|
+
|
7
|
+
describe Doodle, 'attributes with defaults' do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
raise_if_defined :Foo
|
11
|
+
class Foo
|
12
|
+
include Doodle::Helper
|
13
|
+
has :name, :default => 'D1'
|
14
|
+
class << self
|
15
|
+
has :metadata, :default => 'D2'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
@foo = Foo.new
|
19
|
+
class << @foo
|
20
|
+
has :special, :default => 'D3'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
after :each do
|
24
|
+
undefine_const :Foo
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should have instance attribute default via class' do
|
28
|
+
Foo.attributes[:name].default.should == 'D1'
|
29
|
+
end
|
30
|
+
it 'should have instance attribute default via instance' do
|
31
|
+
@foo.attributes[:name].default.should == 'D1'
|
32
|
+
end
|
33
|
+
it 'should have class attribute default via class.meta' do
|
34
|
+
Foo.meta.attributes(false)[:metadata].default.should == 'D2'
|
35
|
+
end
|
36
|
+
it 'should have class attribute default via class.meta' do
|
37
|
+
Foo.meta.attributes[:metadata].default.should == 'D2'
|
38
|
+
end
|
39
|
+
it 'should have singleton attribute default via instance.meta.attributes(false)' do
|
40
|
+
@foo.meta.attributes(false)[:special].default.should == 'D3'
|
41
|
+
end
|
42
|
+
it 'should have singleton attribute default via instance.meta.attributes' do
|
43
|
+
@foo.meta.attributes[:special].default.should == 'D3'
|
44
|
+
end
|
45
|
+
it 'should have singleton attribute name by default' do
|
46
|
+
@foo.name.should == 'D1'
|
47
|
+
end
|
48
|
+
it 'should have singleton attribute name by default' do
|
49
|
+
Foo.metadata.should == 'D2'
|
50
|
+
end
|
51
|
+
it 'should have singleton attribute special by default' do
|
52
|
+
@foo.special.should == 'D3'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not have a @name instance variable' do
|
56
|
+
@foo.instance_variables.include?("@name").should == false
|
57
|
+
@foo.instance_variables.sort.should == []
|
58
|
+
end
|
59
|
+
it 'should not have a @metadata class instance variable' do
|
60
|
+
Foo.instance_variables.include?("@metadata").should == false
|
61
|
+
Foo.instance_variables.sort.should == []
|
62
|
+
end
|
63
|
+
it 'should not have @special singleton instance variable' do
|
64
|
+
@foo.meta.instance_variables.include?("@special").should == false
|
65
|
+
@foo.meta.instance_variables.sort.should == []
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe Doodle, 'defaults which have not been set' do
|
70
|
+
before :each do
|
71
|
+
raise_if_defined :Foo
|
72
|
+
class Foo < Doodle::Base
|
73
|
+
has :baz
|
74
|
+
end
|
75
|
+
end
|
76
|
+
after :each do
|
77
|
+
undefine_const :Foo
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should raise error if required attributes not passed to new' do
|
81
|
+
proc { foo = Foo.new }.should raise_error(ArgumentError)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should not raise error if required attributes passed to new' do
|
85
|
+
proc { foo = Foo.new(:baz => 'Hi' ) }.should_not raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe Doodle, 'defaults which have been set' do
|
91
|
+
before :each do
|
92
|
+
raise_if_defined :Foo
|
93
|
+
class Foo < Doodle::Base
|
94
|
+
has :baz, :default => 'Hi!'
|
95
|
+
has :start do
|
96
|
+
default { Date.today }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
@foo = Foo.new
|
100
|
+
end
|
101
|
+
after :each do
|
102
|
+
undefine_const :Foo
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should have default value set from hash arg' do
|
106
|
+
@foo.baz.should == 'Hi!'
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should have default value set from block' do
|
110
|
+
@foo.start.should == Date.today
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe Doodle, "overriding inherited defaults" do
|
115
|
+
before :each do
|
116
|
+
raise_if_defined :Text, :Text2, :KeyValue
|
117
|
+
class KeyValue < Doodle::Base
|
118
|
+
has :name
|
119
|
+
has :value
|
120
|
+
def to_s
|
121
|
+
%[--#{name}="#{value}"]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
class Text < KeyValue
|
125
|
+
has :name, :default => "text"
|
126
|
+
end
|
127
|
+
class Text2 < Text
|
128
|
+
has :value, :default => "any2"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
after :each do
|
132
|
+
undefine_const :Text2
|
133
|
+
undefine_const :Text
|
134
|
+
undefine_const :KeyValue
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should not raise error if initialized with required values' do
|
138
|
+
proc { Text.new(:value => 'any') }.should_not raise_error
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should allow initialization using defaults' do
|
142
|
+
text = Text.new(:value => 'any')
|
143
|
+
text.name.should == 'text'
|
144
|
+
text.value.should == 'any'
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should raise NoDefaultError if initialized without all required values' do
|
148
|
+
proc { KeyValue.new(:value => 'Enter name:') }.should raise_error(Doodle::NoDefaultError)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should allow initialization using inherited defaults' do
|
152
|
+
text = Text2.new
|
153
|
+
text.name.should == 'text'
|
154
|
+
text.value.should == 'any2'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
raise_if_defined :Foo, :Text, :Text2, :KeyValue
|
data/spec/doodle_spec.rb
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '../.'))
|
2
|
+
|
3
|
+
# require 'relpath'
|
4
|
+
# loaddir_parent(__FILE__)
|
5
|
+
require 'lib/spec_helper'
|
6
|
+
|
7
|
+
describe Doodle, 'basics' do
|
8
|
+
after :each do
|
9
|
+
undefine_const(:Foo)
|
10
|
+
end
|
11
|
+
before(:each) do
|
12
|
+
raise_if_defined :Foo
|
13
|
+
class Foo
|
14
|
+
include Doodle::Helper
|
15
|
+
end
|
16
|
+
@foo = Foo.new
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should have meta as synonym for singleton_class' do
|
20
|
+
Foo.singleton_class.should == Foo.meta
|
21
|
+
@foo.singleton_class.should == @foo.meta
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Doodle, 'instance attributes' do
|
26
|
+
after :each do
|
27
|
+
undefine_const(:Foo)
|
28
|
+
end
|
29
|
+
before(:each) do
|
30
|
+
raise_if_defined :Foo
|
31
|
+
class Foo
|
32
|
+
include Doodle::Helper
|
33
|
+
has :name, :default => nil
|
34
|
+
end
|
35
|
+
@foo = Foo.new
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should create attribute' do
|
39
|
+
@foo.name = 'Smee'
|
40
|
+
@foo.name.should == 'Smee'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should create attribute using getter_setter' do
|
44
|
+
@foo.name 'Smee'
|
45
|
+
@foo.name.should == 'Smee'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should list instance attributes(false)' do
|
49
|
+
@foo.attributes(false).keys.should == []
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should list instance attributes' do
|
53
|
+
@foo.attributes.keys.should == [:name]
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should list all instance attributes(false) at class level' do
|
57
|
+
Foo.attributes(false).keys.should == [:name]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe Doodle, 'class attributes(false)' do
|
63
|
+
after :each do
|
64
|
+
undefine_const(:Foo)
|
65
|
+
end
|
66
|
+
before(:each) do
|
67
|
+
raise_if_defined :Foo
|
68
|
+
class Foo
|
69
|
+
include Doodle::Helper
|
70
|
+
class << self
|
71
|
+
has :metadata
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@foo = Foo.new
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should create class attribute' do
|
78
|
+
Foo.metadata = 'Foo metadata'
|
79
|
+
Foo.metadata.should == 'Foo metadata'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should access class attribute via self.class' do
|
83
|
+
@foo.class.metadata = '@foo metadata'
|
84
|
+
@foo.class.metadata.should == '@foo metadata'
|
85
|
+
Foo.metadata.should == '@foo metadata'
|
86
|
+
|
87
|
+
Foo.metadata = 'Foo metadata'
|
88
|
+
Foo.metadata.should == 'Foo metadata'
|
89
|
+
@foo.class.metadata.should == 'Foo metadata'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should list all class's own attributes" do
|
93
|
+
Foo.meta.attributes(false).keys.should == [:metadata]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should list all class's own attributes" do
|
97
|
+
Foo.meta.attributes.keys.should == [:metadata]
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
describe Doodle, 'inherited class attributes(false)' do
|
103
|
+
after :each do
|
104
|
+
undefine_const(:Foo)
|
105
|
+
undefine_const(:Bar)
|
106
|
+
end
|
107
|
+
before(:each) do
|
108
|
+
raise_if_defined :Foo, :Bar
|
109
|
+
|
110
|
+
class Foo
|
111
|
+
include Doodle::Helper
|
112
|
+
has :name, :default => nil
|
113
|
+
class << self
|
114
|
+
has :metadata
|
115
|
+
end
|
116
|
+
end
|
117
|
+
class Bar < Foo
|
118
|
+
has :location, :default => nil
|
119
|
+
class << self
|
120
|
+
has :doc
|
121
|
+
end
|
122
|
+
end
|
123
|
+
@foo = Foo.new
|
124
|
+
@bar = Bar.new
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should create inherited class attribute' do
|
128
|
+
Foo.metadata = 'Foo metadata'
|
129
|
+
Bar.metadata = 'Bar metadata'
|
130
|
+
Foo.metadata.should == 'Foo metadata'
|
131
|
+
Bar.metadata.should == 'Bar metadata'
|
132
|
+
Foo.metadata.should == 'Foo metadata'
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should access class attribute via self.class' do
|
136
|
+
@foo.class.metadata = '@foo metadata'
|
137
|
+
@foo.class.metadata.should == '@foo metadata'
|
138
|
+
Foo.metadata.should == '@foo metadata'
|
139
|
+
|
140
|
+
Foo.metadata = 'Foo metadata'
|
141
|
+
Bar.metadata = 'Bar metadata'
|
142
|
+
Foo.metadata.should == 'Foo metadata'
|
143
|
+
Bar.metadata.should == 'Bar metadata'
|
144
|
+
Foo.metadata.should == 'Foo metadata'
|
145
|
+
@foo.class.metadata.should == 'Foo metadata'
|
146
|
+
@bar.class.metadata.should == 'Bar metadata'
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should access inherited class attribute via self.class' do
|
150
|
+
@foo.class.metadata = '@foo metadata'
|
151
|
+
@foo.class.metadata.should == '@foo metadata'
|
152
|
+
Foo.metadata.should == '@foo metadata'
|
153
|
+
Foo.metadata = 'Foo metadata'
|
154
|
+
|
155
|
+
Bar.metadata = 'Bar metadata'
|
156
|
+
Bar.metadata.should == 'Bar metadata'
|
157
|
+
@bar.class.metadata.should == 'Bar metadata'
|
158
|
+
|
159
|
+
Foo.metadata.should == 'Foo metadata'
|
160
|
+
@foo.class.metadata.should == 'Foo metadata'
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should list class's own attributes" do
|
164
|
+
Foo.meta.attributes(false).keys.should == [:metadata]
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should list all class's own attributes" do
|
168
|
+
Foo.meta.attributes.keys.should == [:metadata]
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should list class's own attributes(false)" do
|
172
|
+
Bar.meta.attributes(false).keys.should == [:doc]
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should list all inherited meta class attributes" do
|
176
|
+
Bar.meta.attributes.keys.should == [:metadata, :doc]
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should list all inherited class's attributes" do
|
180
|
+
Bar.attributes.keys.should == [:name, :location]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe Doodle, 'singleton class attributes' do
|
185
|
+
after :each do
|
186
|
+
undefine_const(:Foo)
|
187
|
+
end
|
188
|
+
before(:each) do
|
189
|
+
raise_if_defined :Foo
|
190
|
+
|
191
|
+
class Foo
|
192
|
+
include Doodle::Helper
|
193
|
+
has :name, :default => nil
|
194
|
+
class << self
|
195
|
+
has :metadata
|
196
|
+
end
|
197
|
+
end
|
198
|
+
@foo = Foo.new
|
199
|
+
class << @foo
|
200
|
+
has :special, :default => nil
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should allow creation of singleton class attributes' do
|
205
|
+
@foo.special = 42
|
206
|
+
@foo.special.should == 42
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should list instance attributes' do
|
210
|
+
@foo.meta.attributes(false).keys.should == [:special]
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'should list instance attributes' do
|
214
|
+
@foo.meta.attributes.keys.should == [:metadata, :special]
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
describe Doodle, 'inherited singleton class attributes' do
|
220
|
+
after :each do
|
221
|
+
undefine_const(:Foo)
|
222
|
+
undefine_const(:Bar)
|
223
|
+
end
|
224
|
+
before(:each) do
|
225
|
+
raise_if_defined :Foo, :Bar
|
226
|
+
|
227
|
+
class Foo
|
228
|
+
include Doodle::Helper
|
229
|
+
has :name, :default => nil
|
230
|
+
class << self
|
231
|
+
has :metadata
|
232
|
+
end
|
233
|
+
end
|
234
|
+
class Bar < Foo
|
235
|
+
has :info, :default => nil
|
236
|
+
class << self
|
237
|
+
has :doc
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
@foo = Foo.new
|
242
|
+
class << @foo
|
243
|
+
has :special, :default => nil # must give default because already initialized
|
244
|
+
end
|
245
|
+
@bar = Bar.new
|
246
|
+
@bar2 = Bar.new
|
247
|
+
class << @bar
|
248
|
+
has :extra
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should allow creation of singleton class attributes' do
|
253
|
+
@foo.special = 42
|
254
|
+
@foo.special.should == 42
|
255
|
+
@bar.extra = 84
|
256
|
+
@bar.extra.should == 84
|
257
|
+
proc { @foo.extra = 1 }.should raise_error(NoMethodError)
|
258
|
+
proc { @bar2.extra = 1 }.should raise_error(NoMethodError)
|
259
|
+
proc { @bar.special = 1 }.should raise_error(NoMethodError)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should list instance attributes' do
|
263
|
+
@foo.class.attributes(false).keys.should == [:name]
|
264
|
+
@bar.class.attributes(false).keys.should == [:info]
|
265
|
+
@bar2.class.attributes(false).keys.should == [:info]
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should list instance meta attributes' do
|
269
|
+
@foo.meta.attributes(false).keys.should == [:special]
|
270
|
+
@bar.meta.attributes(false).keys.should == [:extra]
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should list instance attributes' do
|
274
|
+
@foo.meta.attributes.keys.should == [:metadata, :special]
|
275
|
+
@bar.meta.attributes.keys.should == [:metadata, :doc, :extra]
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should keep meta attributes separate' do
|
279
|
+
@foo.special = 'foo special'
|
280
|
+
@foo.meta.metadata = 'foo meta'
|
281
|
+
# @bar.meta.metadata = 'bar meta'
|
282
|
+
# @bar.meta.doc = 'bar doc'
|
283
|
+
# Foo.metadata = 'Foo meta'
|
284
|
+
# Bar.metadata = 'Bar meta'
|
285
|
+
# Bar.doc = 'Bar doc'
|
286
|
+
|
287
|
+
# @foo.meta.metadata.should == 'foo meta'
|
288
|
+
# @bar.meta.metadata.should == 'bar meta'
|
289
|
+
# @bar.meta.doc.should == 'bar doc'
|
290
|
+
# Foo.metadata.should == 'Foo meta'
|
291
|
+
# Bar.metadata.should == 'Bar meta'
|
292
|
+
# Bar.doc.should == 'Bar doc'
|
293
|
+
|
294
|
+
# proc { @foo.meta.doc = 1 }.should raise_error(NoMethodError)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|