rack-amf 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.
@@ -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