rack-amf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,109 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe AMF::ClassMapping do
4
+ before(:all) do
5
+ class RubyClass
6
+ attr_accessor :prop_a
7
+ attr_accessor :prop_b
8
+ attr_accessor :prop_c
9
+ end
10
+ end
11
+
12
+ before :each do
13
+ @mapper = AMF::ClassMapping.new
14
+ @mapper.define do |m|
15
+ m.map :as => 'ASClass', :ruby => 'RubyClass'
16
+ end
17
+ end
18
+
19
+ it "should return AS class name for ruby objects" do
20
+ @mapper.get_as_class_name(RubyClass.new).should == 'ASClass'
21
+ @mapper.get_as_class_name('RubyClass').should == 'ASClass'
22
+ end
23
+
24
+ it "should allow config modification" do
25
+ @mapper.define do |m|
26
+ m.map :as => 'SecondClass', :ruby => 'RubyClass'
27
+ end
28
+ @mapper.get_as_class_name(RubyClass.new).should == 'SecondClass'
29
+ end
30
+
31
+ describe "ruby object generator" do
32
+ it "should instantiate a ruby class" do
33
+ @mapper.get_ruby_obj('ASClass').should be_a(RubyClass)
34
+ end
35
+
36
+ it "should properly instantiate namespaced classes" do
37
+ module ANamespace; class TestRubyClass; end; end
38
+ @mapper.define {|m| m.map :as => 'ASClass', :ruby => 'ANamespace::TestRubyClass'}
39
+ @mapper.get_ruby_obj('ASClass').should be_a(ANamespace::TestRubyClass)
40
+ end
41
+
42
+ it "should return a hash with original type if not mapped" do
43
+ obj = @mapper.get_ruby_obj('UnmappedClass')
44
+ obj.should be_a(AMF::Values::TypedHash)
45
+ obj.type.should == 'UnmappedClass'
46
+ end
47
+ end
48
+
49
+ describe "ruby object populator" do
50
+ it "should populate a ruby class" do
51
+ obj = @mapper.populate_ruby_obj RubyClass.new, {:prop_a => 'Data'}
52
+ obj.prop_a.should == 'Data'
53
+ end
54
+
55
+ it "should populate a typed hash" do
56
+ obj = @mapper.populate_ruby_obj AMF::Values::TypedHash.new('UnmappedClass'), {:prop_a => 'Data'}
57
+ obj[:prop_a].should == 'Data'
58
+ end
59
+
60
+ it "should allow custom populators" do
61
+ class CustomPopulator
62
+ def can_handle? obj
63
+ true
64
+ end
65
+ def populate obj, props, dynamic_props
66
+ obj[:populated] = true
67
+ obj.merge! props
68
+ obj.merge! dynamic_props if dynamic_props
69
+ end
70
+ end
71
+
72
+ @mapper.object_populators << CustomPopulator.new
73
+ obj = @mapper.populate_ruby_obj({}, {:prop_a => 'Data'})
74
+ obj[:populated].should == true
75
+ obj[:prop_a].should == 'Data'
76
+ end
77
+ end
78
+
79
+ describe "property extractor" do
80
+ it "should extract hash properties" do
81
+ hash = {:a => 'test1', :b => 'test2'}
82
+ props = @mapper.props_for_serialization(hash)
83
+ props.should == {'a' => 'test1', 'b' => 'test2'}
84
+ end
85
+
86
+ it "should extract object properties" do
87
+ obj = RubyClass.new
88
+ obj.prop_a = 'Test A'
89
+ obj.prop_b = 'Test B'
90
+
91
+ hash = @mapper.props_for_serialization obj
92
+ hash.should == {'prop_a' => 'Test A', 'prop_b' => 'Test B', 'prop_c' => nil}
93
+ end
94
+
95
+ it "should allow custom serializers" do
96
+ class CustomSerializer
97
+ def can_handle? obj
98
+ true
99
+ end
100
+ def serialize obj
101
+ {:success => true}
102
+ end
103
+ end
104
+
105
+ @mapper.object_serializers << CustomSerializer.new
106
+ @mapper.props_for_serialization(nil).should == {:success => true}
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,301 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "when deserializing" do
4
+ describe "AMF0" do
5
+ it "should deserialize numbers" do
6
+ input = object_fixture('amf0-number.bin')
7
+ output = AMF.deserialize(input, 0)
8
+ output.should == 3.5
9
+ end
10
+
11
+ it "should deserialize booleans" do
12
+ input = object_fixture('amf0-boolean.bin')
13
+ output = AMF.deserialize(input, 0)
14
+ output.should === true
15
+ end
16
+
17
+ it "should deserialize strings" do
18
+ input = object_fixture('amf0-string.bin')
19
+ output = AMF.deserialize(input, 0)
20
+ output.should == "this is a テスト"
21
+ end
22
+
23
+ it "should deserialize anonymous objects" do
24
+ input = object_fixture('amf0-object.bin')
25
+ output = AMF.deserialize(input, 0)
26
+ output.should == {:foo => 'baz', :bar => 3.14}
27
+ end
28
+
29
+ it "should deserialize nulls" do
30
+ input = object_fixture('amf0-null.bin')
31
+ output = AMF.deserialize(input, 0)
32
+ output.should == nil
33
+ end
34
+
35
+ it "should deserialize undefineds" do
36
+ input = object_fixture('amf0-undefined.bin')
37
+ output = AMF.deserialize(input, 0)
38
+ output.should == nil
39
+ end
40
+
41
+ it "should deserialize references properly" do
42
+ input = object_fixture('amf0-ref-test.bin')
43
+ output = AMF.deserialize(input, 0)
44
+ output.length.should == 2
45
+ output[0].should === output[1]
46
+ end
47
+
48
+ it "should deserialize hashes" do
49
+ input = object_fixture('amf0-hash.bin')
50
+ output = AMF.deserialize(input, 0)
51
+ output.should == {:a => 'b', :c => 'd'}
52
+ end
53
+
54
+ it "should deserialize arrays from flash player" do
55
+ # Even Array is serialized as a "hash", so check that deserializer converts to array
56
+ input = object_fixture('amf0-ecma-ordinal-array.bin')
57
+ output = AMF.deserialize(input, 0)
58
+ output.should == ['a', 'b', 'c', 'd']
59
+ end
60
+
61
+ it "should deserialize dates" do
62
+ input = object_fixture('amf0-date.bin')
63
+ output = AMF.deserialize(input, 0)
64
+ output.should == Time.utc(2003, 2, 13, 5)
65
+ end
66
+
67
+ it "should deserialize an unmapped object as a dynamic anonymous object" do
68
+ input = object_fixture("amf0-typed-object.bin")
69
+ output = AMF.deserialize(input, 0)
70
+
71
+ output.type.should == 'org.rackAMF.ASClass'
72
+ output.should == {:foo => 'bar', :baz => nil}
73
+ end
74
+
75
+ it "should deserialize a mapped object as a mapped ruby class instance" do
76
+ class RubyClass
77
+ attr_accessor :foo, :baz
78
+ end
79
+ AMF::ClassMapper.define {|m| m.map :as => 'org.rackAMF.ASClass', :ruby => 'RubyClass'}
80
+
81
+ input = object_fixture("amf0-typed-object.bin")
82
+ output = AMF.deserialize(input, 0)
83
+
84
+ output.should be_a(RubyClass)
85
+ output.foo.should == 'bar'
86
+ output.baz.should == nil
87
+ end
88
+ end
89
+
90
+ describe "AMF3" do
91
+ describe "simple messages" do
92
+ it "should deserialize a null" do
93
+ input = object_fixture("amf3-null.bin")
94
+ output = AMF.deserialize(input, 3)
95
+ output.should == nil
96
+ end
97
+
98
+ it "should deserialize a false" do
99
+ input = object_fixture("amf3-false.bin")
100
+ output = AMF.deserialize(input, 3)
101
+ output.should == false
102
+ end
103
+
104
+ it "should deserialize a true" do
105
+ input = object_fixture("amf3-true.bin")
106
+ output = AMF.deserialize(input, 3)
107
+ output.should == true
108
+ end
109
+
110
+ it "should deserialize integers" do
111
+ input = object_fixture("amf3-max.bin")
112
+ output = AMF.deserialize(input, 3)
113
+ output.should == AMF::MAX_INTEGER
114
+
115
+ input = object_fixture("amf3-0.bin")
116
+ output = AMF.deserialize(input, 3)
117
+ output.should == 0
118
+
119
+ input = object_fixture("amf3-min.bin")
120
+ output = AMF.deserialize(input, 3)
121
+ output.should == AMF::MIN_INTEGER
122
+ end
123
+
124
+ it "should deserialize large integers" do
125
+ input = object_fixture("amf3-largeMax.bin")
126
+ output = AMF.deserialize(input, 3)
127
+ output.should == AMF::MAX_INTEGER + 1
128
+
129
+ input = object_fixture("amf3-largeMin.bin")
130
+ output = AMF.deserialize(input, 3)
131
+ output.should == AMF::MIN_INTEGER - 1
132
+ end
133
+
134
+ it "should deserialize BigNums" do
135
+ input = object_fixture("amf3-bigNum.bin")
136
+ output = AMF.deserialize(input, 3)
137
+ output.should == 2**1000
138
+ end
139
+
140
+ it "should deserialize a simple string" do
141
+ input = object_fixture("amf3-string.bin")
142
+ output = AMF.deserialize(input, 3)
143
+ output.should == "String . String"
144
+ end
145
+
146
+ it "should deserialize a symbol as a string" do
147
+ input = object_fixture("amf3-symbol.bin")
148
+ output = AMF.deserialize(input, 3)
149
+ output.should == "foo"
150
+ end
151
+
152
+ it "should deserialize dates" do
153
+ input = object_fixture("amf3-date.bin")
154
+ output = AMF.deserialize(input, 3)
155
+ output.should == Time.at(0)
156
+ end
157
+
158
+ #BAH! Who sends XML over AMF?
159
+ it "should deserialize a REXML document"
160
+ end
161
+
162
+ describe "objects" do
163
+ it "should deserialize an unmapped object as a dynamic anonymous object" do
164
+ input = object_fixture("amf3-dynObject.bin")
165
+ output = AMF.deserialize(input, 3)
166
+
167
+ expected = {
168
+ :property_one => 'foo',
169
+ :property_two => 1,
170
+ :nil_property => nil,
171
+ :another_public_property => 'a_public_value'
172
+ }
173
+ output.should == expected
174
+ end
175
+
176
+ it "should deserialize a mapped object as a mapped ruby class instance" do
177
+ class RubyClass
178
+ attr_accessor :foo, :baz
179
+ end
180
+ AMF::ClassMapper.define {|m| m.map :as => 'org.rackAMF.ASClass', :ruby => 'RubyClass'}
181
+
182
+ input = object_fixture("amf3-typedObject.bin")
183
+ output = AMF.deserialize(input, 3)
184
+
185
+ output.should be_a(RubyClass)
186
+ output.foo.should == 'bar'
187
+ output.baz.should == nil
188
+ end
189
+
190
+ it "should deserialize a hash as a dynamic anonymous object" do
191
+ input = object_fixture("amf3-hash.bin")
192
+ output = AMF.deserialize(input, 3)
193
+ output.should == {:foo => "bar", :answer => 42}
194
+ end
195
+
196
+ it "should deserialize an open struct as a dynamic anonymous object"
197
+
198
+ it "should deserialize an empty array" do
199
+ input = object_fixture("amf3-emptyArray.bin")
200
+ output = AMF.deserialize(input, 3)
201
+ output.should == []
202
+ end
203
+
204
+ it "should deserialize an array of primatives" do
205
+ input = object_fixture("amf3-primArray.bin")
206
+ output = AMF.deserialize(input, 3)
207
+ output.should == [1,2,3,4,5]
208
+ end
209
+
210
+ it "should deserialize an array of mixed objects" do
211
+ input = object_fixture("amf3-mixedArray.bin")
212
+ output = AMF.deserialize(input, 3)
213
+
214
+ h1 = {:foo_one => "bar_one"}
215
+ h2 = {:foo_two => ""}
216
+ so1 = {:foo_three => 42}
217
+ output.should == [h1, h2, so1, {:foo_three => nil}, {}, [h1, h2, so1], [], 42, "", [], "", {}, "bar_one", so1]
218
+ end
219
+
220
+ it "should deserialize a byte array"
221
+ end
222
+
223
+ describe "and implementing the AMF Spec" do
224
+ it "should keep references of duplicate strings" do
225
+ input = object_fixture("amf3-stringRef.bin")
226
+ output = AMF.deserialize(input, 3)
227
+
228
+ class StringCarrier; attr_accessor :str; end
229
+ foo = "foo"
230
+ bar = "str"
231
+ sc = StringCarrier.new
232
+ sc = {:str => foo}
233
+ output.should == [foo, bar, foo, bar, foo, sc]
234
+ end
235
+
236
+ it "should not reference the empty string" do
237
+ input = object_fixture("amf3-emptyStringRef.bin")
238
+ output = AMF.deserialize(input, 3)
239
+ output.should == ["",""]
240
+ end
241
+
242
+ it "should keep references of duplicate dates" do
243
+ input = object_fixture("amf3-datesRef.bin")
244
+ output = AMF.deserialize(input, 3)
245
+
246
+ output[0].should equal(output[1])
247
+ # Expected object:
248
+ # [DateTime.parse "1/1/1970", DateTime.parse "1/1/1970"]
249
+ end
250
+
251
+ it "should keep reference of duplicate objects" do
252
+ input = object_fixture("amf3-objRef.bin")
253
+ output = AMF.deserialize(input, 3)
254
+
255
+ obj1 = {:foo => "bar"}
256
+ obj2 = {:foo => obj1[:foo]}
257
+ output.should == [[obj1, obj2], "bar", [obj1, obj2]]
258
+ end
259
+
260
+ it "should keep references of duplicate arrays" do
261
+ input = object_fixture("amf3-arrayRef.bin")
262
+ output = AMF.deserialize(input, 3)
263
+
264
+ a = [1,2,3]
265
+ b = %w{ a b c }
266
+ output.should == [a, b, a, b]
267
+ end
268
+
269
+ it "should not keep references of duplicate empty arrays unless the object_id matches" do
270
+ input = object_fixture("amf3-emptyArrayRef.bin")
271
+ output = AMF.deserialize(input, 3)
272
+
273
+ a = []
274
+ b = []
275
+ output.should == [a,b,a,b]
276
+ end
277
+
278
+ it "should keep references of duplicate XML and XMLDocuments"
279
+ it "should keep references of duplicate byte arrays"
280
+
281
+ it "should deserialize a deep object graph with circular references" do
282
+ input = object_fixture("amf3-graphMember.bin")
283
+ output = AMF.deserialize(input, 3)
284
+
285
+ output[:children][0][:parent].should === output
286
+ output[:parent].should === nil
287
+ output[:children].length.should == 2
288
+ # Expected object:
289
+ # parent = Hash.new
290
+ # child1 = Hash.new
291
+ # child1[:parent] = parent
292
+ # child1[:children] = []
293
+ # child2 = Hash.new
294
+ # child2[:parent] = parent
295
+ # child2[:children] = []
296
+ # parent[:parent] = nil
297
+ # parent[:children] = [child1, child2]
298
+ end
299
+ end
300
+ end
301
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "when handling requests" do
4
+ it "should handle remoting message from remote object" do
5
+ input = request_fixture("remotingMessage.bin")
6
+ req = AMF::Request.new.populate_from_stream(input)
7
+
8
+ req.headers.length.should == 0
9
+ req.messages.length.should == 1
10
+ message = req.messages[0].data
11
+ message.should be_a(AMF::Values::RemotingMessage)
12
+ message.messageId.should == "FE4AF2BC-DD3C-5470-05D8-9971D51FF89D"
13
+ message.body.should == [true]
14
+ end
15
+
16
+ it "should handle command message from remote object" do
17
+ input = request_fixture("commandMessage.bin")
18
+ req = AMF::Request.new.populate_from_stream(input)
19
+
20
+ req.headers.length.should == 0
21
+ req.messages.length.should == 1
22
+ message = req.messages[0].data
23
+ message.should be_a(AMF::Values::CommandMessage)
24
+ message.messageId.should == "7B0ACE15-8D57-6AE5-B9D4-99C2D32C8246"
25
+ message.body.should == {}
26
+ end
27
+ end
28
+
29
+ describe "when handling responses" do
30
+ it "should serialize a simple call" do
31
+ resp = AMF::Response.new
32
+ resp.messages << AMF::Message.new('/1/onResult', '', 'hello')
33
+
34
+ expected = request_fixture('simple-response.bin')
35
+ resp.serialize.should == expected
36
+ end
37
+ end
@@ -0,0 +1,254 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'rexml/document'
4
+
5
+ describe "when serializing" do
6
+ describe "AMF3" do
7
+ describe "simple messages" do
8
+ it "should serialize a null" do
9
+ expected = object_fixture("amf3-null.bin")
10
+ output = AMF.serialize(nil, 3)
11
+ output.should == expected
12
+ end
13
+
14
+ it "should serialize a false" do
15
+ expected = object_fixture("amf3-false.bin")
16
+ output = AMF.serialize(false, 3)
17
+ output.should == expected
18
+ end
19
+
20
+ it "should serialize a true" do
21
+ expected = object_fixture("amf3-true.bin")
22
+ output = AMF.serialize(true, 3)
23
+ output.should == expected
24
+ end
25
+
26
+ it "should serialize integers" do
27
+ expected = object_fixture("amf3-max.bin")
28
+ input = AMF::MAX_INTEGER
29
+ output = AMF.serialize(input, 3)
30
+ output.should == expected
31
+
32
+ expected = object_fixture("amf3-0.bin")
33
+ output = AMF.serialize(0, 3)
34
+ output.should == expected
35
+
36
+ expected = object_fixture("amf3-min.bin")
37
+ input = AMF::MIN_INTEGER
38
+ output = AMF.serialize(input, 3)
39
+ output.should == expected
40
+ end
41
+
42
+ it "should serialize large integers" do
43
+ expected = object_fixture("amf3-largeMax.bin")
44
+ input = AMF::MAX_INTEGER + 1
45
+ output = AMF.serialize(input, 3)
46
+ output.should == expected
47
+
48
+ expected = object_fixture("amf3-largeMin.bin")
49
+ input = AMF::MIN_INTEGER - 1
50
+ output = AMF.serialize(input, 3)
51
+ output.should == expected
52
+ end
53
+
54
+ it "should serialize BigNums" do
55
+ expected = object_fixture("amf3-bigNum.bin")
56
+ input = 2**1000
57
+ output = AMF.serialize(input, 3)
58
+ output.should == expected
59
+ end
60
+
61
+ it "should serialize a simple string" do
62
+ expected = object_fixture("amf3-string.bin")
63
+ input = "String . String"
64
+ output = AMF.serialize(input, 3)
65
+ output.should == expected
66
+ end
67
+
68
+ it "should serialize a symbol as a string" do
69
+ expected = object_fixture("amf3-symbol.bin")
70
+ output = AMF.serialize(:foo, 3)
71
+ output.should == expected
72
+ end
73
+
74
+ it "should serialize Times" do
75
+ expected = object_fixture("amf3-date.bin")
76
+ input = Time.utc 1970, 1, 1, 0
77
+ output = AMF.serialize(input, 3)
78
+ output.should == expected
79
+ end
80
+
81
+ #BAH! Who sends XML over AMF?
82
+ it "should serialize a REXML document"
83
+ end
84
+
85
+ describe "objects" do
86
+ it "should serialize an unmapped object as a dynamic anonymous object" do
87
+ class NonMappedObject
88
+ attr_accessor :property_one
89
+ attr_accessor :property_two
90
+ attr_accessor :nil_property
91
+ attr_writer :read_only_prop
92
+
93
+ def another_public_property
94
+ 'a_public_value'
95
+ end
96
+
97
+ def method_with_arg arg='foo'
98
+ arg
99
+ end
100
+ end
101
+ obj = NonMappedObject.new
102
+ obj.property_one = 'foo'
103
+ obj.property_two = 1
104
+ obj.nil_property = nil
105
+
106
+ expected = object_fixture("amf3-dynObject.bin")
107
+ input = obj
108
+ output = AMF.serialize(input, 3)
109
+ output.should == expected
110
+ end
111
+
112
+ it "should serialize a hash as a dynamic anonymous object" do
113
+ hash = {}
114
+ hash[:answer] = 42
115
+ hash[:foo] = "bar"
116
+
117
+ expected = object_fixture("amf3-hash.bin")
118
+ input = hash
119
+ output = AMF.serialize(input, 3)
120
+ output.should == expected
121
+ end
122
+
123
+ it "should serialize an open struct as a dynamic anonymous object"
124
+
125
+ it "should serialize an empty array" do
126
+ expected = object_fixture("amf3-emptyArray.bin")
127
+ input = []
128
+ output = AMF.serialize(input, 3)
129
+ output.should == expected
130
+ end
131
+
132
+ it "should serialize an array of primatives" do
133
+ expected = object_fixture("amf3-primArray.bin")
134
+ input = [1, 2, 3, 4, 5]
135
+ output = AMF.serialize(input, 3)
136
+ output.should == expected
137
+ end
138
+
139
+ it "should serialize an array of mixed objects" do
140
+ h1 = {:foo_one => "bar_one"}
141
+ h2 = {:foo_two => ""}
142
+ class SimpleObj
143
+ attr_accessor :foo_three
144
+ end
145
+ so1 = SimpleObj.new
146
+ so1.foo_three = 42
147
+
148
+ expected = object_fixture("amf3-mixedArray.bin")
149
+ input = [h1, h2, so1, SimpleObj.new, {}, [h1, h2, so1], [], 42, "", [], "", {}, "bar_one", so1]
150
+ output = AMF.serialize(input, 3)
151
+ output.should == expected
152
+ end
153
+
154
+ it "should serialize a byte array"
155
+ end
156
+
157
+ describe "and implementing the AMF Spec" do
158
+ it "should keep references of duplicate strings" do
159
+ class StringCarrier
160
+ attr_accessor :str
161
+ end
162
+ foo = "foo"
163
+ bar = "str"
164
+ sc = StringCarrier.new
165
+ sc.str = foo
166
+
167
+ expected = object_fixture("amf3-stringRef.bin")
168
+ input = [foo, bar, foo, bar, foo, sc]
169
+ output = AMF.serialize(input, 3)
170
+ output.should == expected
171
+ end
172
+
173
+ it "should not reference the empty string" do
174
+ expected = object_fixture("amf3-emptyStringRef.bin")
175
+ input = ""
176
+ output = AMF.serialize([input,input], 3)
177
+ output.should == expected
178
+ end
179
+
180
+ it "should keep references of duplicate dates" do
181
+ expected = object_fixture("amf3-datesRef.bin")
182
+ input = Time.utc 1970, 1, 1, 0
183
+ output = AMF.serialize([input,input], 3)
184
+ output.should == expected
185
+ end
186
+
187
+ it "should keep reference of duplicate objects" do
188
+ class SimpleReferenceableObj
189
+ attr_accessor :foo
190
+ end
191
+ obj1 = SimpleReferenceableObj.new
192
+ obj1.foo = :bar
193
+ obj2 = SimpleReferenceableObj.new
194
+ obj2.foo = obj1.foo
195
+
196
+ expected = object_fixture("amf3-objRef.bin")
197
+ input = [[obj1, obj2], "bar", [obj1, obj2]]
198
+ output = AMF.serialize(input, 3)
199
+ output.should == expected
200
+ end
201
+
202
+ it "should keep references of duplicate arrays" do
203
+ a = [1,2,3]
204
+ b = %w{ a b c }
205
+
206
+ expected = object_fixture("amf3-arrayRef.bin")
207
+ input = [a, b, a, b]
208
+ output = AMF.serialize(input, 3)
209
+ output.should == expected
210
+ end
211
+
212
+ it "should not keep references of duplicate empty arrays unless the object_id matches" do
213
+ a = []
214
+ b = []
215
+ a.should == b
216
+ a.object_id.should_not == b.object_id
217
+
218
+ expected = object_fixture("amf3-emptyArrayRef.bin")
219
+ input = [a,b,a,b]
220
+ output = AMF.serialize(input, 3)
221
+ output.should == expected
222
+ end
223
+
224
+ it "should keep references of duplicate XML and XMLDocuments"
225
+ it "should keep references of duplicate byte arrays"
226
+
227
+ it "should serialize a deep object graph with circular references" do
228
+ class GraphMember
229
+ attr_accessor :parent
230
+ attr_accessor :children
231
+
232
+ def initialize
233
+ self.children = []
234
+ end
235
+
236
+ def add_child child
237
+ children << child
238
+ child.parent = self
239
+ child
240
+ end
241
+ end
242
+
243
+ parent = GraphMember.new
244
+ level_1_child_1 = parent.add_child GraphMember.new
245
+ level_1_child_2 = parent.add_child GraphMember.new
246
+
247
+ expected = object_fixture("amf3-graphMember.bin")
248
+ input = parent
249
+ output = AMF.serialize(input, 3)
250
+ output.should == expected
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ describe AMF::Values::ArrayCollection do
4
+ it "should deserialize properly"
5
+ it "should serialize properly"
6
+ end