require "./spec_helper" class Location include CBOR::Serializable @[CBOR::Field(key: "lat")] property latitude : Float64 @[CBOR::Field(key: "lng")] property longitude : Float64 def initialize(@latitude, @longitude) end end class House include CBOR::Serializable property address : String property location : Location? def initialize(@address) end end class Person include CBOR::Serializable include CBOR::Serializable::Unmapped property name : String? def initialize(@name = nil) end end class Game include CBOR::Serializable abstract class Player include CBOR::Serializable @[CBOR::Field(key: "hp")] property health_points : Int32 = 100 @[CBOR::Field(key: "dp")] property defense_points : Int32 = 5 use_cbor_discriminator "type", { magician: Magician, warrior: Warrior } def initialize end end class Magician < Player property wand_level : Int32 = 1 def initialize @type = "magician" end end class Warrior < Player def initialize @defense_points = 20 @type = "warrior" end end property players : Array(Magician | Warrior) def initialize @players = [] of (Magician | Warrior) end end describe CBOR do describe "basics: to_cbor" do it "empty array" do empty_array_cbor = [] of Nil empty_array_cbor.to_cbor.hexstring.should eq "80" end it "array - strings" do ["a", "b", "c"].to_cbor.hexstring.should eq "83616161626163" end it "empty hash" do empty = {} of Nil => Nil cbor_stuff = empty.to_cbor cbor_stuff.hexstring.should eq "a0" end it "hash" do {"a" => 10, "b" => true, "c" => nil}.to_cbor.hexstring.should eq "a361610a6162f56163f6" end it "union String | Int32" do value = (String | Int32).from_cbor(30.to_cbor).to_cbor value.hexstring.should eq "181e" end it "union (String | Int32)" do value = (String | Int32).from_cbor("blah".to_cbor).to_cbor value.hexstring.should eq "64626c6168" end it "union (Bool | Int32)" do value = (Bool | Int32).from_cbor(30.to_cbor).to_cbor value.hexstring.should eq "181e" end it "union (Bool | Int32)" do value = (Bool | Int32).from_cbor(false.to_cbor).to_cbor value.hexstring.should eq "f4" end it "union (String | Bool | Int32)" do value = (String | Bool | Int32).from_cbor("hello".to_cbor).to_cbor value.hexstring.should eq "6568656c6c6f" end it "union (String | Nil | Int32)" do value = (String | Nil | Int32).from_cbor(nil.to_cbor).to_cbor value.hexstring.should eq "f6" end end describe "Time" do it "Time#to_cbor" do time = Time.utc(2016, 2, 15, 10, 20, 30) time.to_cbor.hexstring.should eq "c074323031362d30322d31355431303a32303a33305a" end it "Time#from_cbor" do time = Time.from_cbor Time.utc(2016, 2, 15, 10, 20, 30).to_cbor time.to_cbor.hexstring.should eq "c074323031362d30322d31355431303a32303a33305a" end end describe "UUID" do it "UUID#to_cbor" do uuid = UUID.new "fc47eb8e-b13c-481e-863a-8f8c47a550f2" uuid.to_cbor.hexstring.should eq "50fc47eb8eb13c481e863a8f8c47a550f2" end it "UUID#from_cbor" do uuid = UUID.from_cbor "50fc47eb8eb13c481e863a8f8c47a550f2".hexbytes uuid.to_cbor.hexstring.should eq "50fc47eb8eb13c481e863a8f8c47a550f2" end end describe "CBOR library annotations and features" do it "House#to_cbor with CBOR::Field annotations" do house = House.new "my address" house.location = Location.new 1.1, 1.2 house.to_cbor.hexstring.should eq "a267616464726573736a6d792061646472657373686c6f636174696f6ea2636c6174fb3ff199999999999a636c6e67fb3ff3333333333333" end it "House#from_cbor with CBOR::Field annotations" do other_house = House.new "my address" other_house.location = Location.new 1.1, 1.2 house = House.from_cbor other_house.to_cbor house.to_cbor.hexstring.should eq "a267616464726573736a6d792061646472657373686c6f636174696f6ea2636c6174fb3ff199999999999a636c6e67fb3ff3333333333333" end it "Person#from_cbor with unmapped values" do h = Hash(String | Int32, String | Int32).new h["name"] = "Alice" h["age"] = 30 h["size"] = 160 alice = Person.from_cbor h.to_cbor alice.to_cbor.hexstring.should eq "a3646e616d6565416c69636563616765181e6473697a6518a0" end it "Person#to_cbor with unmapped values" do alice = Person.new "Alice" alice.cbor_unmapped["age"] = 30 alice.cbor_unmapped["size"] = 160 alice.to_cbor.hexstring.should eq "a3646e616d6565416c69636563616765181e6473697a6518a0" end end describe "CBOR::Any" do it "from JSON::Any - 1" do h_any = {"a" => "b", "c" => "d", "e" => true, "f" => 10} json_any = JSON.parse h_any.to_json cbor_any = CBOR::Any.new json_any cbor_any.to_cbor.hexstring.should eq "a461616162616361646165f561660a" end it "from JSON::Any - 2" do h_any = {"a" => "b", "c" => "d", "e" => true, "f" => 10} json_any = JSON.parse h_any.to_json cbor_any = CBOR::Any.new json_any cbor_any["f"].should eq 10 end it "from array" do array = CBOR::Any.from_cbor [ "a", "b", "c", "d" ].to_cbor array.to_cbor.hexstring.should eq "846161616261636164" end it "from hash" do h_cany = Hash(String | Int32, String | Int32).new h_cany["name"] = "Alice" h_cany["age"] = 30 h_cany["size"] = 160 cbor_any_hash = CBOR::Any.from_cbor h_cany.to_cbor cbor_any_hash.to_cbor.hexstring.should eq "a3646e616d6565416c69636563616765181e6473697a6518a0" end end # db[i]?.should be_nil describe "Complex object representations" do it "Game#to_cbor with use_cbor_discriminator" do game = Game.new magician = Game::Magician.new magician.wand_level = 5 game.players << magician game.players << Game::Warrior.new game.to_cbor.hexstring.should eq "a167706c617965727382a46268701864626470056a77616e645f6c6576656c056474797065686d6167696369616ea362687018646264701464747970656777617272696f72" end it "Game#from_cbor with use_cbor_discriminator" do game = Game.new magician = Game::Magician.new magician.wand_level = 5 game.players << magician game.players << Game::Warrior.new new_game = Game.from_cbor game.to_cbor new_game.to_cbor.hexstring.should eq "a167706c617965727382a46268701864626470056a77616e645f6c6576656c056474797065686d6167696369616ea362687018646264701464747970656777617272696f72" end end end