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.
- data/README.rdoc +36 -0
- data/Rakefile +54 -0
- data/lib/rocketamf.rb +12 -0
- data/lib/rocketamf/class_mapping.rb +211 -0
- data/lib/rocketamf/common.rb +35 -0
- data/lib/rocketamf/constants.rb +47 -0
- data/lib/rocketamf/pure.rb +30 -0
- data/lib/rocketamf/pure/deserializer.rb +361 -0
- data/lib/rocketamf/pure/io_helpers.rb +94 -0
- data/lib/rocketamf/pure/remoting.rb +89 -0
- data/lib/rocketamf/pure/serializer.rb +327 -0
- data/lib/rocketamf/remoting.rb +133 -0
- data/lib/rocketamf/values/array_collection.rb +9 -0
- data/lib/rocketamf/values/messages.rb +133 -0
- data/lib/rocketamf/values/typed_hash.rb +13 -0
- data/lib/rocketamf/version.rb +9 -0
- data/spec/amf/class_mapping_set_spec.rb +34 -0
- data/spec/amf/class_mapping_spec.rb +120 -0
- data/spec/amf/deserializer_spec.rb +311 -0
- data/spec/amf/request_spec.rb +25 -0
- data/spec/amf/response_spec.rb +68 -0
- data/spec/amf/serializer_spec.rb +328 -0
- data/spec/amf/values/array_collection_spec.rb +6 -0
- data/spec/amf/values/messages_spec.rb +31 -0
- data/spec/fixtures/objects/amf0-boolean.bin +1 -0
- data/spec/fixtures/objects/amf0-date.bin +0 -0
- data/spec/fixtures/objects/amf0-ecma-ordinal-array.bin +0 -0
- data/spec/fixtures/objects/amf0-hash.bin +0 -0
- data/spec/fixtures/objects/amf0-null.bin +1 -0
- data/spec/fixtures/objects/amf0-number.bin +0 -0
- data/spec/fixtures/objects/amf0-object.bin +0 -0
- data/spec/fixtures/objects/amf0-ref-test.bin +0 -0
- data/spec/fixtures/objects/amf0-strict-array.bin +0 -0
- data/spec/fixtures/objects/amf0-string.bin +0 -0
- data/spec/fixtures/objects/amf0-typed-object.bin +0 -0
- data/spec/fixtures/objects/amf0-undefined.bin +1 -0
- data/spec/fixtures/objects/amf0-untyped-object.bin +0 -0
- data/spec/fixtures/objects/amf3-0.bin +0 -0
- data/spec/fixtures/objects/amf3-arrayRef.bin +1 -0
- data/spec/fixtures/objects/amf3-bigNum.bin +0 -0
- data/spec/fixtures/objects/amf3-date.bin +0 -0
- data/spec/fixtures/objects/amf3-datesRef.bin +0 -0
- data/spec/fixtures/objects/amf3-dynObject.bin +2 -0
- data/spec/fixtures/objects/amf3-emptyArray.bin +1 -0
- data/spec/fixtures/objects/amf3-emptyArrayRef.bin +1 -0
- data/spec/fixtures/objects/amf3-emptyStringRef.bin +1 -0
- data/spec/fixtures/objects/amf3-false.bin +1 -0
- data/spec/fixtures/objects/amf3-graphMember.bin +0 -0
- data/spec/fixtures/objects/amf3-hash.bin +2 -0
- data/spec/fixtures/objects/amf3-largeMax.bin +0 -0
- data/spec/fixtures/objects/amf3-largeMin.bin +0 -0
- data/spec/fixtures/objects/amf3-max.bin +1 -0
- data/spec/fixtures/objects/amf3-min.bin +0 -0
- data/spec/fixtures/objects/amf3-mixedArray.bin +11 -0
- data/spec/fixtures/objects/amf3-null.bin +1 -0
- data/spec/fixtures/objects/amf3-objRef.bin +0 -0
- data/spec/fixtures/objects/amf3-primArray.bin +1 -0
- data/spec/fixtures/objects/amf3-string.bin +1 -0
- data/spec/fixtures/objects/amf3-stringRef.bin +0 -0
- data/spec/fixtures/objects/amf3-symbol.bin +1 -0
- data/spec/fixtures/objects/amf3-true.bin +1 -0
- data/spec/fixtures/objects/amf3-typedObject.bin +2 -0
- data/spec/fixtures/request/acknowledge-response.bin +0 -0
- data/spec/fixtures/request/amf0-error-response.bin +0 -0
- data/spec/fixtures/request/commandMessage.bin +0 -0
- data/spec/fixtures/request/remotingMessage.bin +0 -0
- data/spec/fixtures/request/simple-response.bin +0 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +32 -0
- 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
|