RocketAMF 0.0.5

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.
Files changed (70) hide show
  1. data/README.rdoc +36 -0
  2. data/Rakefile +54 -0
  3. data/lib/rocketamf.rb +12 -0
  4. data/lib/rocketamf/class_mapping.rb +211 -0
  5. data/lib/rocketamf/common.rb +35 -0
  6. data/lib/rocketamf/constants.rb +47 -0
  7. data/lib/rocketamf/pure.rb +30 -0
  8. data/lib/rocketamf/pure/deserializer.rb +361 -0
  9. data/lib/rocketamf/pure/io_helpers.rb +94 -0
  10. data/lib/rocketamf/pure/remoting.rb +89 -0
  11. data/lib/rocketamf/pure/serializer.rb +327 -0
  12. data/lib/rocketamf/remoting.rb +133 -0
  13. data/lib/rocketamf/values/array_collection.rb +9 -0
  14. data/lib/rocketamf/values/messages.rb +133 -0
  15. data/lib/rocketamf/values/typed_hash.rb +13 -0
  16. data/lib/rocketamf/version.rb +9 -0
  17. data/spec/amf/class_mapping_set_spec.rb +34 -0
  18. data/spec/amf/class_mapping_spec.rb +120 -0
  19. data/spec/amf/deserializer_spec.rb +311 -0
  20. data/spec/amf/request_spec.rb +25 -0
  21. data/spec/amf/response_spec.rb +68 -0
  22. data/spec/amf/serializer_spec.rb +328 -0
  23. data/spec/amf/values/array_collection_spec.rb +6 -0
  24. data/spec/amf/values/messages_spec.rb +31 -0
  25. data/spec/fixtures/objects/amf0-boolean.bin +1 -0
  26. data/spec/fixtures/objects/amf0-date.bin +0 -0
  27. data/spec/fixtures/objects/amf0-ecma-ordinal-array.bin +0 -0
  28. data/spec/fixtures/objects/amf0-hash.bin +0 -0
  29. data/spec/fixtures/objects/amf0-null.bin +1 -0
  30. data/spec/fixtures/objects/amf0-number.bin +0 -0
  31. data/spec/fixtures/objects/amf0-object.bin +0 -0
  32. data/spec/fixtures/objects/amf0-ref-test.bin +0 -0
  33. data/spec/fixtures/objects/amf0-strict-array.bin +0 -0
  34. data/spec/fixtures/objects/amf0-string.bin +0 -0
  35. data/spec/fixtures/objects/amf0-typed-object.bin +0 -0
  36. data/spec/fixtures/objects/amf0-undefined.bin +1 -0
  37. data/spec/fixtures/objects/amf0-untyped-object.bin +0 -0
  38. data/spec/fixtures/objects/amf3-0.bin +0 -0
  39. data/spec/fixtures/objects/amf3-arrayRef.bin +1 -0
  40. data/spec/fixtures/objects/amf3-bigNum.bin +0 -0
  41. data/spec/fixtures/objects/amf3-date.bin +0 -0
  42. data/spec/fixtures/objects/amf3-datesRef.bin +0 -0
  43. data/spec/fixtures/objects/amf3-dynObject.bin +2 -0
  44. data/spec/fixtures/objects/amf3-emptyArray.bin +1 -0
  45. data/spec/fixtures/objects/amf3-emptyArrayRef.bin +1 -0
  46. data/spec/fixtures/objects/amf3-emptyStringRef.bin +1 -0
  47. data/spec/fixtures/objects/amf3-false.bin +1 -0
  48. data/spec/fixtures/objects/amf3-graphMember.bin +0 -0
  49. data/spec/fixtures/objects/amf3-hash.bin +2 -0
  50. data/spec/fixtures/objects/amf3-largeMax.bin +0 -0
  51. data/spec/fixtures/objects/amf3-largeMin.bin +0 -0
  52. data/spec/fixtures/objects/amf3-max.bin +1 -0
  53. data/spec/fixtures/objects/amf3-min.bin +0 -0
  54. data/spec/fixtures/objects/amf3-mixedArray.bin +11 -0
  55. data/spec/fixtures/objects/amf3-null.bin +1 -0
  56. data/spec/fixtures/objects/amf3-objRef.bin +0 -0
  57. data/spec/fixtures/objects/amf3-primArray.bin +1 -0
  58. data/spec/fixtures/objects/amf3-string.bin +1 -0
  59. data/spec/fixtures/objects/amf3-stringRef.bin +0 -0
  60. data/spec/fixtures/objects/amf3-symbol.bin +1 -0
  61. data/spec/fixtures/objects/amf3-true.bin +1 -0
  62. data/spec/fixtures/objects/amf3-typedObject.bin +2 -0
  63. data/spec/fixtures/request/acknowledge-response.bin +0 -0
  64. data/spec/fixtures/request/amf0-error-response.bin +0 -0
  65. data/spec/fixtures/request/commandMessage.bin +0 -0
  66. data/spec/fixtures/request/remotingMessage.bin +0 -0
  67. data/spec/fixtures/request/simple-response.bin +0 -0
  68. data/spec/spec.opts +1 -0
  69. data/spec/spec_helper.rb +32 -0
  70. metadata +133 -0
@@ -0,0 +1,311 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "when deserializing" do
4
+ before :each do
5
+ RocketAMF::ClassMapper.reset
6
+ end
7
+
8
+ describe "AMF0" do
9
+ it "should deserialize numbers" do
10
+ input = object_fixture('amf0-number.bin')
11
+ output = RocketAMF.deserialize(input, 0)
12
+ output.should == 3.5
13
+ end
14
+
15
+ it "should deserialize booleans" do
16
+ input = object_fixture('amf0-boolean.bin')
17
+ output = RocketAMF.deserialize(input, 0)
18
+ output.should === true
19
+ end
20
+
21
+ it "should deserialize strings" do
22
+ input = object_fixture('amf0-string.bin')
23
+ output = RocketAMF.deserialize(input, 0)
24
+ output.should == "this is a テスト"
25
+ end
26
+
27
+ it "should deserialize anonymous objects" do
28
+ input = object_fixture('amf0-object.bin')
29
+ output = RocketAMF.deserialize(input, 0)
30
+ output.should == {:foo => 'baz', :bar => 3.14}
31
+ end
32
+
33
+ it "should deserialize nulls" do
34
+ input = object_fixture('amf0-null.bin')
35
+ output = RocketAMF.deserialize(input, 0)
36
+ output.should == nil
37
+ end
38
+
39
+ it "should deserialize undefineds" do
40
+ input = object_fixture('amf0-undefined.bin')
41
+ output = RocketAMF.deserialize(input, 0)
42
+ output.should == nil
43
+ end
44
+
45
+ it "should deserialize references properly" do
46
+ input = object_fixture('amf0-ref-test.bin')
47
+ output = RocketAMF.deserialize(input, 0)
48
+ output.length.should == 2
49
+ output[0].should === output[1]
50
+ end
51
+
52
+ it "should deserialize hashes" do
53
+ input = object_fixture('amf0-hash.bin')
54
+ output = RocketAMF.deserialize(input, 0)
55
+ output.should == {:a => 'b', :c => 'd'}
56
+ end
57
+
58
+ it "should deserialize arrays from flash player" do
59
+ # Even Array is serialized as a "hash", so check that deserializer converts to array
60
+ input = object_fixture('amf0-ecma-ordinal-array.bin')
61
+ output = RocketAMF.deserialize(input, 0)
62
+ output.should == ['a', 'b', 'c', 'd']
63
+ end
64
+
65
+ it "should serialize strict arrays" do
66
+ input = object_fixture('amf0-strict-array.bin')
67
+ output = RocketAMF.deserialize(input, 0)
68
+ output.should == ['a', 'b', 'c', 'd']
69
+ end
70
+
71
+ it "should deserialize dates" do
72
+ input = object_fixture('amf0-date.bin')
73
+ output = RocketAMF.deserialize(input, 0)
74
+ output.should == Time.utc(2003, 2, 13, 5)
75
+ end
76
+
77
+ it "should deserialize XML"
78
+
79
+ it "should deserialize an unmapped object as a dynamic anonymous object" do
80
+ input = object_fixture("amf0-typed-object.bin")
81
+ output = RocketAMF.deserialize(input, 0)
82
+
83
+ output.type.should == 'org.rocketAMF.ASClass'
84
+ output.should == {:foo => 'bar', :baz => nil}
85
+ end
86
+
87
+ it "should deserialize a mapped object as a mapped ruby class instance" do
88
+ class RubyClass
89
+ attr_accessor :foo, :baz
90
+ end
91
+ RocketAMF::ClassMapper.define {|m| m.map :as => 'org.rocketAMF.ASClass', :ruby => 'RubyClass'}
92
+
93
+ input = object_fixture("amf0-typed-object.bin")
94
+ output = RocketAMF.deserialize(input, 0)
95
+
96
+ output.should be_a(RubyClass)
97
+ output.foo.should == 'bar'
98
+ output.baz.should == nil
99
+ end
100
+ end
101
+
102
+ describe "AMF3" do
103
+ describe "simple messages" do
104
+ it "should deserialize a null" do
105
+ input = object_fixture("amf3-null.bin")
106
+ output = RocketAMF.deserialize(input, 3)
107
+ output.should == nil
108
+ end
109
+
110
+ it "should deserialize a false" do
111
+ input = object_fixture("amf3-false.bin")
112
+ output = RocketAMF.deserialize(input, 3)
113
+ output.should == false
114
+ end
115
+
116
+ it "should deserialize a true" do
117
+ input = object_fixture("amf3-true.bin")
118
+ output = RocketAMF.deserialize(input, 3)
119
+ output.should == true
120
+ end
121
+
122
+ it "should deserialize integers" do
123
+ input = object_fixture("amf3-max.bin")
124
+ output = RocketAMF.deserialize(input, 3)
125
+ output.should == RocketAMF::MAX_INTEGER
126
+
127
+ input = object_fixture("amf3-0.bin")
128
+ output = RocketAMF.deserialize(input, 3)
129
+ output.should == 0
130
+
131
+ input = object_fixture("amf3-min.bin")
132
+ output = RocketAMF.deserialize(input, 3)
133
+ output.should == RocketAMF::MIN_INTEGER
134
+ end
135
+
136
+ it "should deserialize large integers" do
137
+ input = object_fixture("amf3-largeMax.bin")
138
+ output = RocketAMF.deserialize(input, 3)
139
+ output.should == RocketAMF::MAX_INTEGER + 1
140
+
141
+ input = object_fixture("amf3-largeMin.bin")
142
+ output = RocketAMF.deserialize(input, 3)
143
+ output.should == RocketAMF::MIN_INTEGER - 1
144
+ end
145
+
146
+ it "should deserialize BigNums" do
147
+ input = object_fixture("amf3-bigNum.bin")
148
+ output = RocketAMF.deserialize(input, 3)
149
+ output.should == 2**1000
150
+ end
151
+
152
+ it "should deserialize a simple string" do
153
+ input = object_fixture("amf3-string.bin")
154
+ output = RocketAMF.deserialize(input, 3)
155
+ output.should == "String . String"
156
+ end
157
+
158
+ it "should deserialize a symbol as a string" do
159
+ input = object_fixture("amf3-symbol.bin")
160
+ output = RocketAMF.deserialize(input, 3)
161
+ output.should == "foo"
162
+ end
163
+
164
+ it "should deserialize dates" do
165
+ input = object_fixture("amf3-date.bin")
166
+ output = RocketAMF.deserialize(input, 3)
167
+ output.should == Time.at(0)
168
+ end
169
+
170
+ #BAH! Who sends XML over AMF?
171
+ it "should deserialize a REXML document"
172
+ end
173
+
174
+ describe "objects" do
175
+ it "should deserialize an unmapped object as a dynamic anonymous object" do
176
+ input = object_fixture("amf3-dynObject.bin")
177
+ output = RocketAMF.deserialize(input, 3)
178
+
179
+ expected = {
180
+ :property_one => 'foo',
181
+ :property_two => 1,
182
+ :nil_property => nil,
183
+ :another_public_property => 'a_public_value'
184
+ }
185
+ output.should == expected
186
+ end
187
+
188
+ it "should deserialize a mapped object as a mapped ruby class instance" do
189
+ class RubyClass
190
+ attr_accessor :foo, :baz
191
+ end
192
+ RocketAMF::ClassMapper.define {|m| m.map :as => 'org.rocketAMF.ASClass', :ruby => 'RubyClass'}
193
+
194
+ input = object_fixture("amf3-typedObject.bin")
195
+ output = RocketAMF.deserialize(input, 3)
196
+
197
+ output.should be_a(RubyClass)
198
+ output.foo.should == 'bar'
199
+ output.baz.should == nil
200
+ end
201
+
202
+ it "should deserialize a hash as a dynamic anonymous object" do
203
+ input = object_fixture("amf3-hash.bin")
204
+ output = RocketAMF.deserialize(input, 3)
205
+ output.should == {:foo => "bar", :answer => 42}
206
+ end
207
+
208
+ it "should deserialize an empty array" do
209
+ input = object_fixture("amf3-emptyArray.bin")
210
+ output = RocketAMF.deserialize(input, 3)
211
+ output.should == []
212
+ end
213
+
214
+ it "should deserialize an array of primatives" do
215
+ input = object_fixture("amf3-primArray.bin")
216
+ output = RocketAMF.deserialize(input, 3)
217
+ output.should == [1,2,3,4,5]
218
+ end
219
+
220
+ it "should deserialize an array of mixed objects" do
221
+ input = object_fixture("amf3-mixedArray.bin")
222
+ output = RocketAMF.deserialize(input, 3)
223
+
224
+ h1 = {:foo_one => "bar_one"}
225
+ h2 = {:foo_two => ""}
226
+ so1 = {:foo_three => 42}
227
+ output.should == [h1, h2, so1, {:foo_three => nil}, {}, [h1, h2, so1], [], 42, "", [], "", {}, "bar_one", so1]
228
+ end
229
+
230
+ it "should deserialize a byte array"
231
+ end
232
+
233
+ describe "and implementing the AMF Spec" do
234
+ it "should keep references of duplicate strings" do
235
+ input = object_fixture("amf3-stringRef.bin")
236
+ output = RocketAMF.deserialize(input, 3)
237
+
238
+ class StringCarrier; attr_accessor :str; end
239
+ foo = "foo"
240
+ bar = "str"
241
+ sc = StringCarrier.new
242
+ sc = {:str => foo}
243
+ output.should == [foo, bar, foo, bar, foo, sc]
244
+ end
245
+
246
+ it "should not reference the empty string" do
247
+ input = object_fixture("amf3-emptyStringRef.bin")
248
+ output = RocketAMF.deserialize(input, 3)
249
+ output.should == ["",""]
250
+ end
251
+
252
+ it "should keep references of duplicate dates" do
253
+ input = object_fixture("amf3-datesRef.bin")
254
+ output = RocketAMF.deserialize(input, 3)
255
+
256
+ output[0].should equal(output[1])
257
+ # Expected object:
258
+ # [DateTime.parse "1/1/1970", DateTime.parse "1/1/1970"]
259
+ end
260
+
261
+ it "should keep reference of duplicate objects" do
262
+ input = object_fixture("amf3-objRef.bin")
263
+ output = RocketAMF.deserialize(input, 3)
264
+
265
+ obj1 = {:foo => "bar"}
266
+ obj2 = {:foo => obj1[:foo]}
267
+ output.should == [[obj1, obj2], "bar", [obj1, obj2]]
268
+ end
269
+
270
+ it "should keep references of duplicate arrays" do
271
+ input = object_fixture("amf3-arrayRef.bin")
272
+ output = RocketAMF.deserialize(input, 3)
273
+
274
+ a = [1,2,3]
275
+ b = %w{ a b c }
276
+ output.should == [a, b, a, b]
277
+ end
278
+
279
+ it "should not keep references of duplicate empty arrays unless the object_id matches" do
280
+ input = object_fixture("amf3-emptyArrayRef.bin")
281
+ output = RocketAMF.deserialize(input, 3)
282
+
283
+ a = []
284
+ b = []
285
+ output.should == [a,b,a,b]
286
+ end
287
+
288
+ it "should keep references of duplicate XML and XMLDocuments"
289
+ it "should keep references of duplicate byte arrays"
290
+
291
+ it "should deserialize a deep object graph with circular references" do
292
+ input = object_fixture("amf3-graphMember.bin")
293
+ output = RocketAMF.deserialize(input, 3)
294
+
295
+ output[:children][0][:parent].should === output
296
+ output[:parent].should === nil
297
+ output[:children].length.should == 2
298
+ # Expected object:
299
+ # parent = Hash.new
300
+ # child1 = Hash.new
301
+ # child1[:parent] = parent
302
+ # child1[:children] = []
303
+ # child2 = Hash.new
304
+ # child2[:parent] = parent
305
+ # child2[:children] = []
306
+ # parent[:parent] = nil
307
+ # parent[:children] = [child1, child2]
308
+ end
309
+ end
310
+ end
311
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe RocketAMF::Request do
4
+ it "should handle remoting message from remote object" do
5
+ req = create_request("remotingMessage.bin")
6
+
7
+ req.headers.length.should == 0
8
+ req.messages.length.should == 1
9
+ message = req.messages[0].data
10
+ message.should be_a(RocketAMF::Values::RemotingMessage)
11
+ message.messageId.should == "FE4AF2BC-DD3C-5470-05D8-9971D51FF89D"
12
+ message.body.should == [true]
13
+ end
14
+
15
+ it "should handle command message from remote object" do
16
+ req = create_request("commandMessage.bin")
17
+
18
+ req.headers.length.should == 0
19
+ req.messages.length.should == 1
20
+ message = req.messages[0].data
21
+ message.should be_a(RocketAMF::Values::CommandMessage)
22
+ message.messageId.should == "7B0ACE15-8D57-6AE5-B9D4-99C2D32C8246"
23
+ message.body.should == {}
24
+ end
25
+ end
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe RocketAMF::Response do
4
+ it "should serialize response when converted to string" do
5
+ res = RocketAMF::Response.new
6
+ res.should_receive(:serialize).and_return('serialized')
7
+ res.to_s.should == 'serialized'
8
+ end
9
+
10
+ it "should serialize a simple call" do
11
+ res = RocketAMF::Response.new
12
+ res.amf_version = 3
13
+ res.messages << RocketAMF::Message.new('/1/onResult', '', 'hello')
14
+
15
+ expected = request_fixture('simple-response.bin')
16
+ res.serialize.should == expected
17
+ end
18
+
19
+ it "should serialize a AcknowledgeMessage response" do
20
+ ak = RocketAMF::Values::AcknowledgeMessage.new
21
+ ak.clientId = "7B0ACE15-8D57-6AE5-B9D4-99C2D32C8246"
22
+ ak.messageId = "7B0ACE15-8D57-6AE5-B9D4-99C2D32C8246"
23
+ ak.timestamp = 0
24
+ res = RocketAMF::Response.new
25
+ res.amf_version = 3
26
+ res.messages << RocketAMF::Message.new('/1/onResult', '', ak)
27
+
28
+ expected = request_fixture('acknowledge-response.bin')
29
+ res.serialize.should == expected
30
+ end
31
+
32
+ it "should respond to ping command" do
33
+ res = RocketAMF::Response.new
34
+ req = create_request('commandMessage.bin')
35
+ res.each_method_call req do |method, args|
36
+ nil
37
+ end
38
+
39
+ res.messages.length.should == 1
40
+ res.messages[0].data.should be_a(RocketAMF::Values::AcknowledgeMessage)
41
+ end
42
+
43
+ it "should handle RemotingMessages properly" do
44
+ res = RocketAMF::Response.new
45
+ req = create_request('remotingMessage.bin')
46
+ res.each_method_call req do |method, args|
47
+ method.should == 'WritesController.save'
48
+ args.should == [true]
49
+ true
50
+ end
51
+
52
+ res.messages.length.should == 1
53
+ res.messages[0].data.should be_a(RocketAMF::Values::AcknowledgeMessage)
54
+ res.messages[0].data.body.should == true
55
+ end
56
+
57
+ it "should catch exceptions properly" do
58
+ res = RocketAMF::Response.new
59
+ req = create_request('remotingMessage.bin')
60
+ res.each_method_call req do |method, args|
61
+ raise 'Error in call'
62
+ end
63
+
64
+ res.messages.length.should == 1
65
+ res.messages[0].data.should be_a(RocketAMF::Values::ErrorMessage)
66
+ res.messages[0].target_uri.should =~ /onStatus$/
67
+ end
68
+ end
@@ -0,0 +1,328 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'rexml/document'
4
+
5
+ describe "when serializing" do
6
+ before :each do
7
+ RocketAMF::ClassMapper.reset
8
+ end
9
+
10
+ describe "AMF0" do
11
+ it "should serialize nils" do
12
+ output = RocketAMF.serialize(nil, 0)
13
+ output.should == object_fixture('amf0-null.bin')
14
+ end
15
+
16
+ it "should serialize booleans" do
17
+ output = RocketAMF.serialize(true, 0)
18
+ output.should === object_fixture('amf0-boolean.bin')
19
+ end
20
+
21
+ it "should serialize numbers" do
22
+ output = RocketAMF.serialize(3.5, 0)
23
+ output.should == object_fixture('amf0-number.bin')
24
+ end
25
+
26
+ it "should serialize strings" do
27
+ output = RocketAMF.serialize("this is a テスト", 0)
28
+ output.should == object_fixture('amf0-string.bin')
29
+ end
30
+
31
+ it "should serialize arrays" do
32
+ output = RocketAMF.serialize(['a', 'b', 'c', 'd'], 0)
33
+ output.should == object_fixture('amf0-strict-array.bin')
34
+ end
35
+
36
+ it "should serialize references" do
37
+ class OtherClass
38
+ attr_accessor :foo, :bar
39
+ end
40
+ obj = OtherClass.new
41
+ obj.foo = "baz"
42
+ obj.bar = 3.14
43
+
44
+ output = RocketAMF.serialize({'0' => obj, '1' => obj}, 0)
45
+ output.should == object_fixture('amf0-ref-test.bin')
46
+ end
47
+
48
+ it "should serialize dates" do
49
+ output = RocketAMF.serialize(Time.utc(2003, 2, 13, 5), 0)
50
+ output.should == object_fixture('amf0-date.bin')
51
+ end
52
+
53
+ it "should serialize hashes" do
54
+ output = RocketAMF.serialize({:a => 'b', :c => 'd'}, 0)
55
+ output.should == object_fixture('amf0-hash.bin')
56
+ end
57
+
58
+ it "should serialize unmapped objects" do
59
+ class RubyClass
60
+ attr_accessor :foo, :baz
61
+ end
62
+ obj = RubyClass.new
63
+ obj.foo = "bar"
64
+
65
+ output = RocketAMF.serialize(obj, 0)
66
+ output.should == object_fixture('amf0-untyped-object.bin')
67
+ end
68
+
69
+ it "should serialize mapped objects" do
70
+ class RubyClass
71
+ attr_accessor :foo, :baz
72
+ end
73
+ obj = RubyClass.new
74
+ obj.foo = "bar"
75
+ RocketAMF::ClassMapper.define {|m| m.map :as => 'org.rocketAMF.ASClass', :ruby => 'RubyClass'}
76
+
77
+ output = RocketAMF.serialize(obj, 0)
78
+ output.should == object_fixture('amf0-typed-object.bin')
79
+ end
80
+ end
81
+
82
+ describe "AMF3" do
83
+ describe "simple messages" do
84
+ it "should serialize a null" do
85
+ expected = object_fixture("amf3-null.bin")
86
+ output = RocketAMF.serialize(nil, 3)
87
+ output.should == expected
88
+ end
89
+
90
+ it "should serialize a false" do
91
+ expected = object_fixture("amf3-false.bin")
92
+ output = RocketAMF.serialize(false, 3)
93
+ output.should == expected
94
+ end
95
+
96
+ it "should serialize a true" do
97
+ expected = object_fixture("amf3-true.bin")
98
+ output = RocketAMF.serialize(true, 3)
99
+ output.should == expected
100
+ end
101
+
102
+ it "should serialize integers" do
103
+ expected = object_fixture("amf3-max.bin")
104
+ input = RocketAMF::MAX_INTEGER
105
+ output = RocketAMF.serialize(input, 3)
106
+ output.should == expected
107
+
108
+ expected = object_fixture("amf3-0.bin")
109
+ output = RocketAMF.serialize(0, 3)
110
+ output.should == expected
111
+
112
+ expected = object_fixture("amf3-min.bin")
113
+ input = RocketAMF::MIN_INTEGER
114
+ output = RocketAMF.serialize(input, 3)
115
+ output.should == expected
116
+ end
117
+
118
+ it "should serialize large integers" do
119
+ expected = object_fixture("amf3-largeMax.bin")
120
+ input = RocketAMF::MAX_INTEGER + 1
121
+ output = RocketAMF.serialize(input, 3)
122
+ output.should == expected
123
+
124
+ expected = object_fixture("amf3-largeMin.bin")
125
+ input = RocketAMF::MIN_INTEGER - 1
126
+ output = RocketAMF.serialize(input, 3)
127
+ output.should == expected
128
+ end
129
+
130
+ it "should serialize BigNums" do
131
+ expected = object_fixture("amf3-bigNum.bin")
132
+ input = 2**1000
133
+ output = RocketAMF.serialize(input, 3)
134
+ output.should == expected
135
+ end
136
+
137
+ it "should serialize a simple string" do
138
+ expected = object_fixture("amf3-string.bin")
139
+ input = "String . String"
140
+ output = RocketAMF.serialize(input, 3)
141
+ output.should == expected
142
+ end
143
+
144
+ it "should serialize a symbol as a string" do
145
+ expected = object_fixture("amf3-symbol.bin")
146
+ output = RocketAMF.serialize(:foo, 3)
147
+ output.should == expected
148
+ end
149
+
150
+ it "should serialize Times" do
151
+ expected = object_fixture("amf3-date.bin")
152
+ input = Time.utc 1970, 1, 1, 0
153
+ output = RocketAMF.serialize(input, 3)
154
+ output.should == expected
155
+ end
156
+
157
+ #BAH! Who sends XML over AMF?
158
+ it "should serialize a REXML document"
159
+ end
160
+
161
+ describe "objects" do
162
+ it "should serialize an unmapped object as a dynamic anonymous object" do
163
+ class NonMappedObject
164
+ attr_accessor :property_one
165
+ attr_accessor :property_two
166
+ attr_accessor :nil_property
167
+ attr_writer :read_only_prop
168
+
169
+ def another_public_property
170
+ 'a_public_value'
171
+ end
172
+
173
+ def method_with_arg arg='foo'
174
+ arg
175
+ end
176
+ end
177
+ obj = NonMappedObject.new
178
+ obj.property_one = 'foo'
179
+ obj.property_two = 1
180
+ obj.nil_property = nil
181
+
182
+ expected = object_fixture("amf3-dynObject.bin")
183
+ input = obj
184
+ output = RocketAMF.serialize(input, 3)
185
+ output.should == expected
186
+ end
187
+
188
+ it "should serialize a hash as a dynamic anonymous object" do
189
+ hash = {}
190
+ hash[:answer] = 42
191
+ hash[:foo] = "bar"
192
+
193
+ expected = object_fixture("amf3-hash.bin")
194
+ input = hash
195
+ output = RocketAMF.serialize(input, 3)
196
+ output.should == expected
197
+ end
198
+
199
+ it "should serialize an empty array" do
200
+ expected = object_fixture("amf3-emptyArray.bin")
201
+ input = []
202
+ output = RocketAMF.serialize(input, 3)
203
+ output.should == expected
204
+ end
205
+
206
+ it "should serialize an array of primatives" do
207
+ expected = object_fixture("amf3-primArray.bin")
208
+ input = [1, 2, 3, 4, 5]
209
+ output = RocketAMF.serialize(input, 3)
210
+ output.should == expected
211
+ end
212
+
213
+ it "should serialize an array of mixed objects" do
214
+ h1 = {:foo_one => "bar_one"}
215
+ h2 = {:foo_two => ""}
216
+ class SimpleObj
217
+ attr_accessor :foo_three
218
+ end
219
+ so1 = SimpleObj.new
220
+ so1.foo_three = 42
221
+
222
+ expected = object_fixture("amf3-mixedArray.bin")
223
+ input = [h1, h2, so1, SimpleObj.new, {}, [h1, h2, so1], [], 42, "", [], "", {}, "bar_one", so1]
224
+ output = RocketAMF.serialize(input, 3)
225
+ output.should == expected
226
+ end
227
+
228
+ it "should serialize a byte array"
229
+ end
230
+
231
+ describe "and implementing the AMF Spec" do
232
+ it "should keep references of duplicate strings" do
233
+ class StringCarrier
234
+ attr_accessor :str
235
+ end
236
+ foo = "foo"
237
+ bar = "str"
238
+ sc = StringCarrier.new
239
+ sc.str = foo
240
+
241
+ expected = object_fixture("amf3-stringRef.bin")
242
+ input = [foo, bar, foo, bar, foo, sc]
243
+ output = RocketAMF.serialize(input, 3)
244
+ output.should == expected
245
+ end
246
+
247
+ it "should not reference the empty string" do
248
+ expected = object_fixture("amf3-emptyStringRef.bin")
249
+ input = ""
250
+ output = RocketAMF.serialize([input,input], 3)
251
+ output.should == expected
252
+ end
253
+
254
+ it "should keep references of duplicate dates" do
255
+ expected = object_fixture("amf3-datesRef.bin")
256
+ input = Time.utc 1970, 1, 1, 0
257
+ output = RocketAMF.serialize([input,input], 3)
258
+ output.should == expected
259
+ end
260
+
261
+ it "should keep reference of duplicate objects" do
262
+ class SimpleReferenceableObj
263
+ attr_accessor :foo
264
+ end
265
+ obj1 = SimpleReferenceableObj.new
266
+ obj1.foo = :bar
267
+ obj2 = SimpleReferenceableObj.new
268
+ obj2.foo = obj1.foo
269
+
270
+ expected = object_fixture("amf3-objRef.bin")
271
+ input = [[obj1, obj2], "bar", [obj1, obj2]]
272
+ output = RocketAMF.serialize(input, 3)
273
+ output.should == expected
274
+ end
275
+
276
+ it "should keep references of duplicate arrays" do
277
+ a = [1,2,3]
278
+ b = %w{ a b c }
279
+
280
+ expected = object_fixture("amf3-arrayRef.bin")
281
+ input = [a, b, a, b]
282
+ output = RocketAMF.serialize(input, 3)
283
+ output.should == expected
284
+ end
285
+
286
+ it "should not keep references of duplicate empty arrays unless the object_id matches" do
287
+ a = []
288
+ b = []
289
+ a.should == b
290
+ a.object_id.should_not == b.object_id
291
+
292
+ expected = object_fixture("amf3-emptyArrayRef.bin")
293
+ input = [a,b,a,b]
294
+ output = RocketAMF.serialize(input, 3)
295
+ output.should == expected
296
+ end
297
+
298
+ it "should keep references of duplicate XML and XMLDocuments"
299
+ it "should keep references of duplicate byte arrays"
300
+
301
+ it "should serialize a deep object graph with circular references" do
302
+ class GraphMember
303
+ attr_accessor :parent
304
+ attr_accessor :children
305
+
306
+ def initialize
307
+ self.children = []
308
+ end
309
+
310
+ def add_child child
311
+ children << child
312
+ child.parent = self
313
+ child
314
+ end
315
+ end
316
+
317
+ parent = GraphMember.new
318
+ level_1_child_1 = parent.add_child GraphMember.new
319
+ level_1_child_2 = parent.add_child GraphMember.new
320
+
321
+ expected = object_fixture("amf3-graphMember.bin")
322
+ input = parent
323
+ output = RocketAMF.serialize(input, 3)
324
+ output.should == expected
325
+ end
326
+ end
327
+ end
328
+ end