# encoding: UTF-8
require "spec_helper.rb"
describe "when deserializing" do
before :each do
RocketAMF::ClassMapper.reset
end
it "should raise exception with invalid version number" do
lambda {
RocketAMF.deserialize("", 5)
}.should raise_error("unsupported version 5")
end
describe "AMF0" do
it "should update source pos if source is a StringIO object" do
input = StringIO.new(object_fixture('amf0-number.bin'))
input.pos.should == 0
output = RocketAMF.deserialize(input, 0)
input.pos.should == 9
end
it "should deserialize numbers" do
input = object_fixture('amf0-number.bin')
output = RocketAMF.deserialize(input, 0)
output.should == 3.5
end
it "should deserialize booleans" do
input = object_fixture('amf0-boolean.bin')
output = RocketAMF.deserialize(input, 0)
output.should === true
end
it "should deserialize UTF8 strings" do
input = object_fixture('amf0-string.bin')
output = RocketAMF.deserialize(input, 0)
output.should == "this is a テスト"
end
it "should deserialize nulls" do
input = object_fixture('amf0-null.bin')
output = RocketAMF.deserialize(input, 0)
output.should == nil
end
it "should deserialize undefineds" do
input = object_fixture('amf0-undefined.bin')
output = RocketAMF.deserialize(input, 0)
output.should == nil
end
it "should deserialize hashes" do
input = object_fixture('amf0-hash.bin')
output = RocketAMF.deserialize(input, 0)
output.should == {'a' => 'b', 'c' => 'd'}
end
it "should deserialize arrays from flash player" do
# Even Array is serialized as a "hash"
input = object_fixture('amf0-ecma-ordinal-array.bin')
output = RocketAMF.deserialize(input, 0)
output.should == {'0' => 'a', '1' => 'b', '2' => 'c', '3' => 'd'}
end
it "should deserialize strict arrays" do
input = object_fixture('amf0-strict-array.bin')
output = RocketAMF.deserialize(input, 0)
output.should == ['a', 'b', 'c', 'd']
end
it "should deserialize dates" do
input = object_fixture('amf0-time.bin')
output = RocketAMF.deserialize(input, 0)
output.should == Time.utc(2003, 2, 13, 5)
end
it "should deserialize an XML document" do
input = object_fixture('amf0-xml-doc.bin')
output = RocketAMF.deserialize(input, 0)
output.should == ''
end
it "should deserialize anonymous objects" do
input = object_fixture('amf0-object.bin')
output = RocketAMF.deserialize(input, 0)
output.should == {'foo' => 'baz', 'bar' => 3.14}
output.type.should == ""
end
it "should deserialize an unmapped object as a dynamic anonymous object" do
input = object_fixture("amf0-typed-object.bin")
output = RocketAMF.deserialize(input, 0)
output.type.should == 'org.amf.ASClass'
output.should == {'foo' => 'bar', 'baz' => nil}
end
it "should deserialize a mapped object as a mapped ruby class instance" do
RocketAMF::ClassMapper.define {|m| m.map :as => 'org.amf.ASClass', :ruby => 'RubyClass'}
input = object_fixture("amf0-typed-object.bin")
output = RocketAMF.deserialize(input, 0)
output.should be_a(RubyClass)
output.foo.should == 'bar'
output.baz.should == nil
end
it "should deserialize references properly" do
input = object_fixture('amf0-ref-test.bin')
output = RocketAMF.deserialize(input, 0)
output.length.should == 2
output["0"].should === output["1"]
end
end
describe "AMF3" do
it "should update source pos if source is a StringIO object" do
input = StringIO.new(object_fixture('amf3-null.bin'))
input.pos.should == 0
output = RocketAMF.deserialize(input, 3)
input.pos.should == 1
end
describe "simple messages" do
it "should deserialize a null" do
input = object_fixture("amf3-null.bin")
output = RocketAMF.deserialize(input, 3)
output.should == nil
end
it "should deserialize a false" do
input = object_fixture("amf3-false.bin")
output = RocketAMF.deserialize(input, 3)
output.should == false
end
it "should deserialize a true" do
input = object_fixture("amf3-true.bin")
output = RocketAMF.deserialize(input, 3)
output.should == true
end
it "should deserialize integers" do
input = object_fixture("amf3-max.bin")
output = RocketAMF.deserialize(input, 3)
output.should == RocketAMF::MAX_INTEGER
input = object_fixture("amf3-0.bin")
output = RocketAMF.deserialize(input, 3)
output.should == 0
input = object_fixture("amf3-min.bin")
output = RocketAMF.deserialize(input, 3)
output.should == RocketAMF::MIN_INTEGER
end
it "should deserialize large integers" do
input = object_fixture("amf3-large-max.bin")
output = RocketAMF.deserialize(input, 3)
output.should == RocketAMF::MAX_INTEGER + 1
input = object_fixture("amf3-large-min.bin")
output = RocketAMF.deserialize(input, 3)
output.should == RocketAMF::MIN_INTEGER - 1
end
it "should deserialize BigNums" do
input = object_fixture("amf3-bignum.bin")
output = RocketAMF.deserialize(input, 3)
output.should == 2**1000
end
it "should deserialize a simple string" do
input = object_fixture("amf3-string.bin")
output = RocketAMF.deserialize(input, 3)
output.should == "String . String"
end
it "should deserialize a symbol as a string" do
input = object_fixture("amf3-symbol.bin")
output = RocketAMF.deserialize(input, 3)
output.should == "foo"
end
it "should deserialize dates" do
input = object_fixture("amf3-date.bin")
output = RocketAMF.deserialize(input, 3)
output.should == Time.at(0)
end
it "should deserialize XML" do
# XMLDocument tag
input = object_fixture("amf3-xml-doc.bin")
output = RocketAMF.deserialize(input, 3)
output.should == ''
# XML tag
input = object_fixture("amf3-xml.bin")
output = RocketAMF.deserialize(input, 3)
output.should == ''
end
end
describe "objects" do
it "should deserialize an unmapped object as a dynamic anonymous object" do
input = object_fixture("amf3-dynamic-object.bin")
output = RocketAMF.deserialize(input, 3)
expected = {
'property_one' => 'foo',
'nil_property' => nil,
'another_public_property' => 'a_public_value'
}
output.should == expected
output.type.should == ""
end
it "should deserialize a mapped object as a mapped ruby class instance" do
RocketAMF::ClassMapper.define {|m| m.map :as => 'org.amf.ASClass', :ruby => 'RubyClass'}
input = object_fixture("amf3-typed-object.bin")
output = RocketAMF.deserialize(input, 3)
output.should be_a(RubyClass)
output.foo.should == 'bar'
output.baz.should == nil
end
it "should deserialize externalizable objects" do
RocketAMF::ClassMapper.define {|m| m.map :as => 'ExternalizableTest', :ruby => 'ExternalizableTest'}
input = object_fixture("amf3-externalizable.bin")
output = RocketAMF.deserialize(input, 3)
output.length.should == 2
output[0].one.should == 5
output[1].two.should == 5
end
it "should deserialize a hash as a dynamic anonymous object" do
input = object_fixture("amf3-hash.bin")
output = RocketAMF.deserialize(input, 3)
output.should == {'foo' => "bar", 'answer' => 42}
end
it "should deserialize an empty array" do
input = object_fixture("amf3-empty-array.bin")
output = RocketAMF.deserialize(input, 3)
output.should == []
end
it "should deserialize an array of primitives" do
input = object_fixture("amf3-primitive-array.bin")
output = RocketAMF.deserialize(input, 3)
output.should == [1,2,3,4,5]
end
it "should deserialize an associative array" do
input = object_fixture("amf3-associative-array.bin")
output = RocketAMF.deserialize(input, 3)
output.should == {0=>"bar1", 1=>"bar2", 2=>"bar3", "asdf"=>"fdsa", "foo"=>"bar", "42"=>"bar"}
end
it "should deserialize an array of mixed objects" do
input = object_fixture("amf3-mixed-array.bin")
output = RocketAMF.deserialize(input, 3)
h1 = {'foo_one' => "bar_one"}
h2 = {'foo_two' => ""}
so1 = {'foo_three' => 42}
output.should == [h1, h2, so1, {}, [h1, h2, so1], [], 42, "", [], "", {}, "bar_one", so1]
end
it "should deserialize an array collection as an array" do
input = object_fixture("amf3-array-collection.bin")
output = RocketAMF.deserialize(input, 3)
output.class.should == Array
output.should == ["foo", "bar"]
end
it "should deserialize a complex set of array collections" do
RocketAMF::ClassMapper.define {|m| m.map :as => 'org.amf.ASClass', :ruby => 'RubyClass'}
input = object_fixture('amf3-complex-array-collection.bin')
output = RocketAMF.deserialize(input, 3)
output[0].should == ["foo", "bar"]
output[1][0].should be_a(RubyClass)
output[1][1].should be_a(RubyClass)
output[2].should === output[1]
end
it "should deserialize a byte array" do
input = object_fixture("amf3-byte-array.bin")
output = RocketAMF.deserialize(input, 3)
output.should be_a(StringIO)
expected = "\000\003これtest\100"
expected.force_encoding("ASCII-8BIT") if expected.respond_to?(:force_encoding)
output.string.should == expected
end
it "should deserialize an empty dictionary" do
input = object_fixture("amf3-empty-dictionary.bin")
output = RocketAMF.deserialize(input, 3)
output.should == {}
end
it "should deserialize a dictionary" do
input = object_fixture("amf3-dictionary.bin")
output = RocketAMF.deserialize(input, 3)
keys = output.keys
keys.length.should == 2
obj_key, str_key = keys[0].is_a?(RocketAMF::Values::TypedHash) ? [keys[0], keys[1]] : [keys[1], keys[0]]
obj_key.type.should == 'org.amf.ASClass'
output[obj_key].should == "asdf2"
str_key.should == "bar"
output[str_key].should == "asdf1"
end
it "should deserialize Vector." do
input = object_fixture('amf3-vector-int.bin')
output = RocketAMF.deserialize(input, 3)
output.should == [4, -20, 12]
end
it "should deserialize Vector." do
input = object_fixture('amf3-vector-uint.bin')
output = RocketAMF.deserialize(input, 3)
output.should == [4, 20, 12]
end
it "should deserialize Vector." do
input = object_fixture('amf3-vector-double.bin')
output = RocketAMF.deserialize(input, 3)
output.should == [4.3, -20.6]
end
it "should deserialize Vector.