doodle 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/History.txt +24 -0
  2. data/Manifest.txt +26 -1
  3. data/README.txt +9 -8
  4. data/lib/doodle.rb +43 -1496
  5. data/lib/doodle/app.rb +6 -0
  6. data/lib/doodle/attribute.rb +165 -0
  7. data/lib/doodle/base.rb +180 -0
  8. data/lib/doodle/collector-1.9.rb +72 -0
  9. data/lib/doodle/collector.rb +191 -0
  10. data/lib/doodle/comparable.rb +8 -0
  11. data/lib/doodle/conversion.rb +80 -0
  12. data/lib/doodle/core.rb +42 -0
  13. data/lib/doodle/datatype-holder.rb +39 -0
  14. data/lib/doodle/debug.rb +20 -0
  15. data/lib/doodle/deferred.rb +13 -0
  16. data/lib/doodle/equality.rb +21 -0
  17. data/lib/doodle/exceptions.rb +29 -0
  18. data/lib/doodle/factory.rb +91 -0
  19. data/lib/doodle/getter-setter.rb +154 -0
  20. data/lib/doodle/info.rb +298 -0
  21. data/lib/doodle/inherit.rb +40 -0
  22. data/lib/doodle/json.rb +38 -0
  23. data/lib/doodle/marshal.rb +16 -0
  24. data/lib/doodle/normalized_array.rb +512 -0
  25. data/lib/doodle/normalized_hash.rb +356 -0
  26. data/lib/doodle/ordered-hash.rb +8 -0
  27. data/lib/doodle/singleton.rb +23 -0
  28. data/lib/doodle/smoke-and-mirrors.rb +23 -0
  29. data/lib/doodle/to_hash.rb +17 -0
  30. data/lib/doodle/utils.rb +173 -11
  31. data/lib/doodle/validation.rb +122 -0
  32. data/lib/doodle/version.rb +1 -1
  33. data/lib/molic_orderedhash.rb +24 -10
  34. data/spec/assigned_spec.rb +45 -0
  35. data/spec/attributes_spec.rb +7 -7
  36. data/spec/collector_spec.rb +100 -13
  37. data/spec/doodle_context_spec.rb +5 -5
  38. data/spec/from_spec.rb +43 -3
  39. data/spec/json_spec.rb +232 -0
  40. data/spec/member_init_spec.rb +11 -11
  41. data/spec/modules_spec.rb +4 -4
  42. data/spec/multi_collector_spec.rb +91 -0
  43. data/spec/must_spec.rb +32 -0
  44. data/spec/spec_helper.rb +14 -4
  45. data/spec/specialized_attribute_class_spec.rb +2 -2
  46. data/spec/typed_collector_spec.rb +57 -0
  47. data/spec/xml_spec.rb +8 -8
  48. metadata +33 -3
@@ -11,15 +11,15 @@ describe Doodle, "doodle_context" do
11
11
  # - a proc/lamba is treated as a literal argument, i.e. the
12
12
  # - value is set to a Proc
13
13
  # - a block argument, on the other hand, is instance
14
- # - evaluated during initialization
14
+ # evaluated during initialization
15
15
  # - consequences
16
16
  # - can only be done in init block
17
17
  # - somewhat subtle difference (from programmer's point of
18
- # - view) between a proc and a block
18
+ # view) between a proc and a block
19
19
  # Also note re: Doodle.parent - its value is only valid
20
20
  # during initialization - this is a way to capture that
21
- # value for ues later
22
-
21
+ # value for use later
22
+
23
23
  init { doodle.parent }
24
24
  end
25
25
  end
@@ -29,7 +29,7 @@ describe Doodle, "doodle_context" do
29
29
  end
30
30
 
31
31
  end
32
-
32
+
33
33
  it 'should provide a means to find out the current parent of an item in initialization block' do
34
34
  dad = Parent 'Conn' do
35
35
  child 'Sean'
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper.rb'
2
2
 
3
- describe 'Doodle', 'applying Doodle type conversions' do
3
+ describe 'Doodle', 'from' do
4
4
  temporary_constant :Foo, :Name do
5
5
  before :each do
6
6
  class Name < String
@@ -25,7 +25,7 @@ describe 'Doodle', 'applying Doodle type conversions' do
25
25
  it 'should convert a value based on conversions in doodle class' do
26
26
  proc { foo = Foo 'Arthur' }.should_not raise_error
27
27
  end
28
-
28
+
29
29
  it 'should convert a value based on conversions in doodle class to the correct class' do
30
30
  foo = Foo 'Arthur'
31
31
  foo.name.class.should_be Name
@@ -38,6 +38,46 @@ describe 'Doodle', 'applying Doodle type conversions' do
38
38
  it 'should apply validations from doodle type' do
39
39
  proc { Foo 'Art' }.should raise_error(Doodle::ConversionError)
40
40
  end
41
-
41
+
42
+ end
43
+ end
44
+
45
+ describe 'Doodle', 'from' do
46
+ temporary_constant :Answer do
47
+ before :each do
48
+ end
49
+
50
+ it 'should allow specifying from in has params' do
51
+ class Answer < Doodle
52
+ has :value, :from => { Integer => proc {|i| i.to_s }}
53
+ end
54
+ name = Answer.new(42)
55
+ name.value.should_be "42"
56
+ end
57
+
58
+ it 'should allow specifying from in has params with kind specified' do
59
+ class Answer < Doodle
60
+ has :value, :kind => String, :from => { Integer => proc {|i| i.to_s }}
61
+ end
62
+ name = Answer.new(42)
63
+ name.value.should_be "42"
64
+ end
65
+
66
+ it 'should override from clause in has params with one defined in block' do
67
+ class Answer < Doodle
68
+ has :value, :kind => String, :from => { Integer => proc {|i| i.to_s }} do
69
+ # this should override :from clause in has params
70
+ from Float do |i|
71
+ (Integer(i + 20)).to_s
72
+ end
73
+ end
74
+ end
75
+
76
+ name = Answer.new(22.0)
77
+ name.value.should_be "42"
78
+
79
+ name = Answer.new(42)
80
+ name.value.should_be "42"
81
+ end
42
82
  end
43
83
  end
@@ -0,0 +1,232 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'doodle/json'
3
+
4
+ def compare_json(data, json)
5
+ JSON.parse(data.to_json, :create_additions => false).should_be JSON.parse(json, :create_additions => false)
6
+ end
7
+
8
+ describe Doodle, 'JSON serialization within a module' do
9
+ temporary_constants :Container, :Base, :Slideshow, :Layout do
10
+ before(:each) do
11
+ @json_source = <<EOT
12
+ {
13
+ "json_class":"Container::Slideshow",
14
+ "data":{
15
+ "name":"test",
16
+ "layout":{
17
+ "json_class":"Container::Layout",
18
+ "data":{
19
+ "template":"generic"
20
+ }
21
+ },
22
+ "id":1
23
+ }
24
+ }
25
+ EOT
26
+ @json_data = JSON.parse(@json_source, :create_additions => false)
27
+
28
+ module ::Container
29
+ class Base < Doodle
30
+ include Doodle::JSON
31
+ end
32
+ class Layout < Base
33
+ has :template
34
+ end
35
+ class Slideshow < Base
36
+ has :id, :kind => Integer do
37
+ from String do |s|
38
+ s.to_i
39
+ end
40
+ end
41
+ has :name, :kind => String
42
+ has Layout
43
+ end
44
+ end
45
+ end
46
+ it 'should serialize to json' do
47
+ slideshow = Container::Slideshow.new do
48
+ id 1
49
+ name "test"
50
+ layout "generic"
51
+ end
52
+ compare_json(slideshow, @json_source)
53
+ end
54
+ it 'should serialize from json' do
55
+ slideshow = Container::Slideshow.new do
56
+ id 1
57
+ name "test"
58
+ layout "generic"
59
+ end
60
+ ss2 = Doodle.from_json(@json_source)
61
+ ss2.should_be slideshow
62
+ end
63
+ end
64
+ end
65
+
66
+ describe Doodle, 'JSON serialization at top level' do
67
+ temporary_constants :Base, :Slideshow, :Layout do
68
+ before(:each) do
69
+ @json_source = <<EOT
70
+ {
71
+ "json_class":"Slideshow",
72
+ "data":{
73
+ "name":"test",
74
+ "layout":{
75
+ "json_class":"Layout",
76
+ "data":{
77
+ "template":"generic"
78
+ }
79
+ },
80
+ "id":1
81
+ }
82
+ }
83
+ EOT
84
+ class ::Base < Doodle
85
+ include Doodle::JSON
86
+ end
87
+ class ::Layout < Base
88
+ has :template
89
+ end
90
+ class ::Slideshow < Base
91
+ has :id, :kind => Integer do
92
+ from String do |s|
93
+ s.to_i
94
+ end
95
+ end
96
+ has :name, :kind => String
97
+ has Layout
98
+ end
99
+ end
100
+ it 'should serialize to json' do
101
+ slideshow = ::Slideshow.new do
102
+ id 1
103
+ name "test"
104
+ layout "generic"
105
+ end
106
+ compare_json(slideshow, @json_source)
107
+ end
108
+ it 'should serialize from json' do
109
+ slideshow = ::Slideshow.new do
110
+ id 1
111
+ name "test"
112
+ layout "generic"
113
+ end
114
+ ss2 = Doodle.from_json(@json_source)
115
+ ss2.should_be slideshow
116
+ end
117
+ end
118
+ end
119
+
120
+ describe Doodle, 'JSON' do
121
+ temporary_constant :Address do
122
+ before :each do
123
+ class ::Address < Doodle
124
+ include Doodle::JSON
125
+ has :where, :default => "home"
126
+ has :city
127
+ end
128
+ end
129
+
130
+ it 'should not raise an error when supplying attribute values' do
131
+ proc {
132
+ Address do
133
+ city "London"
134
+ end
135
+ }.should_not raise_error
136
+ end
137
+
138
+ it 'should accept attributes defined in block' do
139
+ a = Address do
140
+ city "London"
141
+ end
142
+ a.city.should_be "London"
143
+ end
144
+
145
+ it 'should output non-doodle attributes as JSON attributes' do
146
+ a = Address do
147
+ city "London"
148
+ end
149
+ compare_json(a, <<EOT)
150
+ {
151
+ "json_class":"Address",
152
+ "data":{
153
+ "city":"London"
154
+ }
155
+ }
156
+ EOT
157
+ end
158
+ end
159
+ end
160
+
161
+ describe Doodle, 'JSON' do
162
+ temporary_constant :Base, :City, :Address do
163
+ before :each do
164
+ class ::Base < Doodle
165
+ include Doodle::JSON
166
+ end
167
+ class ::City < Base
168
+ has :_text_
169
+ has :country, :default => "UK"
170
+ end
171
+ class ::Address < Base
172
+ has :where, :default => "home"
173
+ has City
174
+ end
175
+ end
176
+
177
+ it 'should output required tags in JSON' do
178
+ a = Address do
179
+ city "London"
180
+ end
181
+ compare_json(a, <<EOT)
182
+ {
183
+ "json_class":"Address",
184
+ "data":{
185
+ "city":{
186
+ "json_class":"City",
187
+ "data":{"_text_":"London"}
188
+ }
189
+ }
190
+ }
191
+ EOT
192
+ end
193
+
194
+ it 'should output specified optional attributes as json attributes if kind not a doodle class' do
195
+ a = Address :where => 'home' do
196
+ city "London"
197
+ end
198
+ compare_json(a, <<EOT)
199
+ {
200
+ "json_class":"Address",
201
+ "data":{
202
+ "city":{
203
+ "json_class":"City",
204
+ "data":{"_text_":"London"}
205
+ },
206
+ "where":"home"
207
+ }
208
+ }
209
+ EOT
210
+ end
211
+
212
+ it 'should output specified optional attributes' do
213
+ a = Address :where => 'home' do
214
+ city "London", :country => "England" do
215
+ country "UK"
216
+ end
217
+ end
218
+ compare_json(a, <<EOT)
219
+ {
220
+ "json_class":"Address",
221
+ "data":{
222
+ "city":{"json_class":"City", "data":{"_text_":"London", "country":"UK"}},
223
+ "where":"home"
224
+ }
225
+ }
226
+ EOT
227
+ end
228
+
229
+ end
230
+
231
+ end
232
+
@@ -13,16 +13,16 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
13
13
  has :v2, :kind => String, :default => "bar"
14
14
  end
15
15
  end
16
-
16
+
17
17
  it 'should initialize an attribute from a hash' do
18
18
  foo = Foo do
19
- bar :name => "hello", :count => 1
19
+ bar :name => "hello", :count => 1
20
20
  end
21
21
  foo.bar.name.should_be "hello"
22
22
  foo.bar.count.should_be 1
23
23
  end
24
24
  it 'should fail trying to initialize with incorrect keyword values' do
25
- proc {
25
+ proc {
26
26
  foo = Foo do
27
27
  bar :name => 1, :count => "hello"
28
28
  end
@@ -30,7 +30,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
30
30
  end
31
31
  it 'should work with positional args' do
32
32
  foo = nil
33
- proc {
33
+ proc {
34
34
  foo = Foo do
35
35
  bar "hello", 1
36
36
  end
@@ -40,7 +40,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
40
40
  end
41
41
  it 'should work with block initialization' do
42
42
  foo = nil
43
- proc {
43
+ proc {
44
44
  foo = Foo do
45
45
  bar do
46
46
  name "hello"
@@ -53,7 +53,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
53
53
  end
54
54
  it 'should work with arg and block initialization' do
55
55
  foo = nil
56
- proc {
56
+ proc {
57
57
  foo = Foo do
58
58
  bar "hello" do
59
59
  count 1
@@ -65,7 +65,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
65
65
  end
66
66
  it 'should work with keyword and block initialization' do
67
67
  foo = nil
68
- proc {
68
+ proc {
69
69
  foo = Foo do
70
70
  bar :name => "hello" do
71
71
  count 1
@@ -77,7 +77,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
77
77
  end
78
78
  it 'should raise error with invalid keyword and block initialization' do
79
79
  foo = nil
80
- proc {
80
+ proc {
81
81
  foo = Foo do
82
82
  bar :name => 1 do
83
83
  count "hello"
@@ -87,7 +87,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
87
87
  end
88
88
  it 'should raise error with keyword and invalid block initialization' do
89
89
  foo = nil
90
- proc {
90
+ proc {
91
91
  foo = Foo do
92
92
  bar :name => "hello" do
93
93
  count "hello"
@@ -97,7 +97,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
97
97
  end
98
98
  it 'should initialize non-Doodle or Proc with simple value' do
99
99
  foo = nil
100
- proc {
100
+ proc {
101
101
  foo = Foo do
102
102
  bar :name => "hello", :count => 1
103
103
  v2 "Hello"
@@ -108,7 +108,7 @@ describe 'Doodle', 'initialization of scalar attributes from hash' do
108
108
  foo.v2.should_be "Hello"
109
109
  end
110
110
  it 'should fail trying to initialize an inappropriate attribute (not a Doodle or Proc) from a block' do
111
- proc {
111
+ proc {
112
112
  foo = Foo do
113
113
  bar :name => "hello", :count => 1
114
114
  v2 do
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper.rb'
2
2
 
3
- describe Doodle, "Definitions within rspec" do
3
+ describe Doodle, "definitions within rspec" do
4
4
  temporary_constant :Foo1 do
5
5
  before :each do
6
6
  class Foo1 < Doodle
@@ -13,7 +13,7 @@ describe Doodle, "Definitions within rspec" do
13
13
  end
14
14
  end
15
15
 
16
- describe Doodle, "Definitions at top level" do
16
+ describe Doodle, "definitions at top level" do
17
17
  temporary_constant :Foo2 do
18
18
  before :each do
19
19
  class ::Object
@@ -28,7 +28,7 @@ describe Doodle, "Definitions at top level" do
28
28
  end
29
29
  end
30
30
 
31
- describe Doodle, "Definitions in modules" do
31
+ describe Doodle, "definitions in modules" do
32
32
  temporary_constant :Foo3, :Bar3 do
33
33
  before :each do
34
34
  module ::Bar3
@@ -43,7 +43,7 @@ describe Doodle, "Definitions in modules" do
43
43
  end
44
44
  end
45
45
 
46
- describe Doodle, "Definitions in module_eval" do
46
+ describe Doodle, "definitions in module_eval" do
47
47
  temporary_constant :Foo4, :Bar4 do
48
48
  before :each do
49
49
  module Bar4
@@ -0,0 +1,91 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Doodle, 'multiple collector' do
4
+ temporary_constants :Text, :Item, :List do
5
+ before :each do
6
+ #: definition
7
+ class ::Item < Doodle
8
+ has :name, :kind => String
9
+ end
10
+ class ::Text < Doodle
11
+ has :body, :kind => String
12
+ end
13
+ class ::List < Doodle
14
+ has :items, :collect => [Item, Text]
15
+ end
16
+ end
17
+
18
+ it 'should accept convertible values in collector' do
19
+ list = nil
20
+ no_error {
21
+ list = List do
22
+ item "Hello"
23
+ text "World"
24
+ end
25
+ }
26
+ list.items.size.should_be 2
27
+ list.items[0].should_be Item("Hello")
28
+ list.items[1].should_be Text("World")
29
+ end
30
+ end
31
+ end
32
+
33
+ describe Doodle, 'multiple collector' do
34
+ temporary_constants :Text, :Item, :List do
35
+ before :each do
36
+ #: definition
37
+ class ::Item < Doodle
38
+ has :name, :kind => String
39
+ end
40
+ class ::Text < Doodle
41
+ has :body, :kind => String
42
+ end
43
+ class ::List < Doodle
44
+ has :items, :collect => [ { :foo => Item }, { :bar => Text } ]
45
+ end
46
+ end
47
+
48
+ it 'should accept convertible values in collector using specified collector methods' do
49
+ list = nil
50
+ no_error {
51
+ list = List do
52
+ foo "Hello"
53
+ bar "World"
54
+ end
55
+ }
56
+ list.items.size.should_be 2
57
+ list.items[0].should_be Item("Hello")
58
+ list.items[1].should_be Text("World")
59
+ end
60
+ end
61
+ end
62
+
63
+ describe Doodle, 'multiple collector' do
64
+ temporary_constants :Text, :Item, :List do
65
+ before :each do
66
+ #: definition
67
+ class ::Item < Doodle
68
+ has :name, :kind => String
69
+ end
70
+ class ::Text < Doodle
71
+ has :body, :kind => String
72
+ end
73
+ class ::List < Doodle
74
+ has :items, :collect => { :foo => Item, :bar => Text }
75
+ end
76
+ end
77
+
78
+ it 'should accept convertible values in collector using specified collector methods' do
79
+ list = nil
80
+ no_error {
81
+ list = List do
82
+ foo "Hello"
83
+ bar "World"
84
+ end
85
+ }
86
+ list.items.size.should_be 2
87
+ list.items[0].should_be Item("Hello")
88
+ list.items[1].should_be Text("World")
89
+ end
90
+ end
91
+ end