/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #define PVXS_ENABLE_EXPERT_API #include #include #include #include #include "utilpvt.h" using namespace pvxs; namespace { void testBad() { testDiag("%s", __func__); static const char* inputs[] = { "", " 14 x", " {", " {} extra", R"({"value":{"A":[1,2], "B":"[1.5, 2.5]}}")", }; for(size_t i=0; i([inp](){ Value empty; json::Parse(inp).into(empty); })<<" Expected error from "<(), "hello"); } { Value val(TypeDef(TypeCode::Int16).create()); json::Parse("42").into(val); testEq(val.as(), 42); } { Value val(TypeDef(TypeCode::Int64).create()); json::Parse(" -42 ").into(val); testEq(val.as(), -42); } { Value val(TypeDef(TypeCode::Float64).create()); json::Parse(" -42.5 ").into(val); testEq(val.as(), -42.5); } } void testStruct() { testDiag("%s", __func__); { Value top(nt::NTScalar{TypeCode::UInt16, true}.create()); json::Parse(R"( {"value":43, "alarm":{"severity":1, "status":2, "message":"hello"}, "display":{}} )").into(top); testEq(top["value"].as(), 43); testEq(top["alarm.severity"].as(), 1); testEq(top["alarm.status"].as(), 2); testEq(top["alarm.message"].as(), "hello"); } } void testArrayOfScalar() { testDiag("%s", __func__); { Value val(TypeDef(TypeCode::Int32A).create()); json::Parse(R"( [1, 2,3 ] )").into(val); shared_array expect({1, 2, 3}); testArrEq(val.as>(), expect); } { Value val(TypeDef(TypeCode::Int32A).create()); json::Parse(R"( [1, 2.5,3 ] )").into(val); shared_array expect({1, 2, 3}); testArrEq(val.as>(), expect); } { Value val(TypeDef(TypeCode::Float64A).create()); json::Parse(R"( [1.5, 2,3 ] )").into(val); shared_array expect({1.5, 2.0, 3.0}); testArrEq(val.as>(), expect); } { Value val(TypeDef(TypeCode::StringA).create()); json::Parse(R"( ["1", "hello", "world" ] )").into(val); shared_array expect({"1", "hello", "world"}); testArrEq(val.as>(), expect); } } void testStructArray() { using namespace pvxs::members; testDiag("%s", __func__); { Value val(TypeDef(TypeCode::StructA, { Int32("ival"), String("sval"), Int32A("aval"), }).create()); json::Parse("[" "{\"ival\":1, \"sval\":\"hello\"}," "null," "{\"aval\": [4,5,6]}" "]").into(val); testStrEq(std::string(SB()<(), 42); } { auto val(json::Parse(R"(42.5)").as()); testEq(val.type(), TypeCode::Float64); testEq(val.as(), 42.5); } { auto val(json::Parse(R"("foo")").as()); testEq(val.type(), TypeCode::String); testEq(val.as(), "foo"); } { auto val(json::Parse(R"([])").as()); testEq(val.type(), TypeCode::Float64A); testEq(val.as>().size(), 0u); } { auto val(json::Parse(R"([1,2])").as()); testEq(val.type(), TypeCode::Int64A); shared_array expect({1,2}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"([1,2.0])").as()); testEq(val.type(), TypeCode::Float64A); shared_array expect({1,2}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"([2.0,1])").as()); testEq(val.type(), TypeCode::Float64A); shared_array expect({2,1}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"([1,false])").as()); testEq(val.type(), TypeCode::Int64A); shared_array expect({1,0}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"([false,1])").as()); testEq(val.type(), TypeCode::Int64A); shared_array expect({0,1}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"([true, false])").as()); testEq(val.type(), TypeCode::BoolA); shared_array expect({true, false}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"(["hello", "world"])").as()); testEq(val.type(), TypeCode::StringA); shared_array expect({"hello", "world"}); testArrEq(val.as>(), expect); } { auto val(json::Parse(R"({"foo":1, "bar":{"a":"blah", "b":null, "c":false}})").as()); testStrEq((SB()<