require "../spec_helper" require "json" require "yaml" describe JSON::Any do it ".new" do JSON::Any.new(nil).raw.should be_nil JSON::Any.new(true).raw.should be_true JSON::Any.new(1_i64).raw.should eq 1_i64 JSON::Any.new(1).raw.should eq 1 JSON::Any.new(1_u8).raw.should eq 1 JSON::Any.new(0.0).raw.should eq 0.0 JSON::Any.new(0.0_f32).raw.should eq 0.0 JSON::Any.new("foo").raw.should eq "foo" JSON::Any.new([] of JSON::Any).raw.should eq [] of JSON::Any JSON::Any.new({} of String => JSON::Any).raw.should eq({} of String => JSON::Any) end describe "casts" do it "gets nil" do JSON.parse("null").as_nil.should be_nil end it "gets bool" do JSON.parse("true").as_bool.should be_true JSON.parse("false").as_bool.should be_false JSON.parse("true").as_bool?.should be_true JSON.parse("false").as_bool?.should be_false JSON.parse("2").as_bool?.should be_nil end it "gets int32" do JSON.parse("123").as_i.should eq(123) JSON.parse("123").as_i?.should eq(123) JSON.parse("true").as_i?.should be_nil end it "gets int64" do JSON.parse("123456789123456").as_i64.should eq(123456789123456) JSON.parse("123456789123456").as_i64?.should eq(123456789123456) JSON.parse("true").as_i64?.should be_nil end it "gets float32" do JSON.parse("123.45").as_f32.should eq(123.45_f32) expect_raises(TypeCastError) { JSON.parse("true").as_f32 } JSON.parse("123.45").as_f32?.should eq(123.45_f32) JSON.parse("true").as_f32?.should be_nil end it "gets float32 from JSON integer (#8618)" do value = JSON.parse("123").as_f32 value.should eq(123.0) value.should be_a(Float32) value = JSON.parse("123").as_f32? value.should eq(123.0) value.should be_a(Float32) end it "gets float64" do JSON.parse("123.45").as_f.should eq(123.45) expect_raises(TypeCastError) { JSON.parse("true").as_f } JSON.parse("123.45").as_f?.should eq(123.45) JSON.parse("true").as_f?.should be_nil end it "gets float64 from JSON integer (#8618)" do value = JSON.parse("123").as_f value.should eq(123.0) value.should be_a(Float64) value = JSON.parse("123").as_f? value.should eq(123.0) value.should be_a(Float64) end it "gets string" do JSON.parse(%("hello")).as_s.should eq("hello") JSON.parse(%("hello")).as_s?.should eq("hello") JSON.parse("true").as_s?.should be_nil end it "gets array" do JSON.parse(%([1, 2, 3])).as_a.should eq([1, 2, 3]) JSON.parse(%([1, 2, 3])).as_a?.should eq([1, 2, 3]) JSON.parse("true").as_a?.should be_nil end it "gets hash" do JSON.parse(%({"foo": "bar"})).as_h.should eq({"foo" => "bar"}) JSON.parse(%({"foo": "bar"})).as_h?.should eq({"foo" => "bar"}) JSON.parse("true").as_h?.should be_nil end end describe "#size" do it "of array" do JSON.parse("[1, 2, 3]").size.should eq(3) end it "of hash" do JSON.parse(%({"foo": "bar"})).size.should eq(1) end end describe "#[]" do it "of array" do JSON.parse("[1, 2, 3]")[1].raw.should eq(2) end it "of hash" do JSON.parse(%({"foo": "bar"}))["foo"].raw.should eq("bar") end end describe "#[]?" do it "of array" do JSON.parse("[1, 2, 3]")[1]?.not_nil!.raw.should eq(2) JSON.parse("[1, 2, 3]")[3]?.should be_nil JSON.parse("[true, false]")[1]?.should be_false end it "of hash" do JSON.parse(%({"foo": "bar"}))["foo"]?.not_nil!.raw.should eq("bar") JSON.parse(%({"foo": "bar"}))["fox"]?.should be_nil JSON.parse(%q<{"foo": false}>)["foo"]?.should be_false end end describe "#dig?" do it "gets the value at given path given splat" do obj = JSON.parse(%({"foo": [1, {"bar": [2, 3]}]})) obj.dig?("foo", 0).should eq(1) obj.dig?("foo", 1, "bar", 1).should eq(3) end it "returns nil if not found" do obj = JSON.parse(%({"foo": [1, {"bar": [2, 3]}]})) obj.dig?("foo", 10).should be_nil obj.dig?("bar", "baz").should be_nil obj.dig?("").should be_nil end it "returns nil for non-Hash/Array intermediary values" do JSON::Any.new(nil).dig?("foo").should be_nil JSON::Any.new(0.0).dig?("foo").should be_nil end end describe "dig" do it "gets the value at given path given splat" do obj = JSON.parse(%({"foo": [1, {"bar": [2, 3]}]})) obj.dig("foo", 0).should eq(1) obj.dig("foo", 1, "bar", 1).should eq(3) end it "raises if not found" do obj = JSON.parse(%({"foo": [1, {"bar": [2, 3]}]})) expect_raises Exception, %(Expected Hash for #[](key : String), not Array(JSON::Any)) do obj.dig("foo", 1, "bar", "baz") end expect_raises KeyError, %(Missing hash key: "z") do obj.dig("z") end expect_raises KeyError, %(Missing hash key: "") do obj.dig("") end end end it "traverses big structure" do obj = JSON.parse(%({"foo": [1, {"bar": [2, 3]}]})) obj["foo"][1]["bar"][1].as_i.should eq(3) end it "compares to other objects" do obj = JSON.parse(%([1, 2])) obj.should eq([1, 2]) obj[0].should eq(1) end it "can compare with ===" do (1 === JSON.parse("1")).should be_truthy end it "exposes $~ when doing Regex#===" do (/o+/ === JSON.parse(%("foo"))).should be_truthy $~[0].should eq("oo") end it "dups" do any = JSON.parse("[1, 2, 3]") any2 = any.dup any2.as_a.should_not be(any.as_a) end it "clones" do any = JSON.parse("[[1], 2, 3]") any2 = any.clone any2.as_a[0].as_a.should_not be(any.as_a[0].as_a) end it "#to_yaml" do any = JSON.parse <<-JSON { "foo": "bar", "baz": [1, 2.3, true, "qux", {"qax": "qox"}] } JSON any.to_yaml.should eq <<-YAML --- foo: bar baz: - 1 - 2.3 - true - qux - qax: qox YAML end it "#inspect" do any = JSON.parse <<-JSON { "foo": "bar", "baz": [1, 2.3, true, "qux", {"qax": "qox"}] } JSON any.inspect.should eq %(JSON::Any({"foo" => "bar", "baz" => [1, 2.3, true, "qux", {"qax" => "qox"}]})) # call multiple times to ensure state is reset properly JSON.parse("null").inspect.should eq "JSON::Any(nil)" JSON.parse("true").inspect.should eq "JSON::Any(true)" end end