#include "json.h" #include "proto.h" #include "proto2json.h" #include #include #include #include using namespace NProtobufJson; using namespace NProtobufJsonTest; struct TTestUnknownFieldsCollector : public IUnknownFieldsCollector { void OnEnterMapItem(const TString& key) override { CurrentPath.push_back(key); } void OnEnterArrayItem(ui64 id) override { CurrentPath.push_back(ToString(id)); } void OnLeaveMapItem() override { CurrentPath.pop_back(); } void OnLeaveArrayItem() override { CurrentPath.pop_back(); } void OnUnknownField(const TString& key, const google::protobuf::Descriptor& value) override { TString path; for (auto& piece : CurrentPath) { path.append("/"); path.append(piece); } path.append("/"); path.append(key); UnknownKeys.insert(std::move(path)); Y_UNUSED(value); } TVector CurrentPath; TSet UnknownKeys; }; Y_UNIT_TEST_SUITE(TUnknownFieldsCollectorTest) { Y_UNIT_TEST(TestFlatOptional) { TFlatOptional proto; TSimpleSharedPtr collector = new TTestUnknownFieldsCollector; TJson2ProtoConfig cfg; cfg.SetUnknownFieldsCollector(collector).SetAllowUnknownFields(true); Json2Proto(TStringBuf(R"({"42":42,"I32":11,"test":2,"string":"str","String":"string","obj":{"inner":{}},"arr":[1,2,3]})"), proto, cfg); TSet expectedKeys = { {"/42"}, {"/arr"}, {"/obj"}, {"/string"}, {"/test"}, }; UNIT_ASSERT(collector->CurrentPath.empty()); UNIT_ASSERT_VALUES_EQUAL(collector->UnknownKeys, expectedKeys); } Y_UNIT_TEST(TestFlatRepeated) { TFlatRepeated proto; TSimpleSharedPtr collector = new TTestUnknownFieldsCollector; TJson2ProtoConfig cfg; cfg.SetUnknownFieldsCollector(collector).SetAllowUnknownFields(true); Json2Proto(TStringBuf(R"({"42":42,"I32":[11,12],"test":12,"string":"str","String":["string1","string2"],"obj":{"inner":{}},"arr":[1,2,3]})"), proto, cfg); TSet expectedKeys = { {"/42"}, {"/arr"}, {"/obj"}, {"/string"}, {"/test"}, }; UNIT_ASSERT(collector->CurrentPath.empty()); UNIT_ASSERT_VALUES_EQUAL(collector->UnknownKeys, expectedKeys); } Y_UNIT_TEST(TestCompositeOptional) { TCompositeOptional proto; TSimpleSharedPtr collector = new TTestUnknownFieldsCollector; TJson2ProtoConfig cfg; cfg.SetUnknownFieldsCollector(collector).SetAllowUnknownFields(true); Json2Proto(TStringBuf(R"({"Part":{"42":42,"I32":11,"test":12,"string":"str","String":"string"},"string2":"str"})"), proto, cfg); TSet expectedKeys = { {"/Part/42"}, {"/Part/string"}, {"/Part/test"}, {"/string2"}, }; UNIT_ASSERT(collector->CurrentPath.empty()); UNIT_ASSERT_VALUES_EQUAL(collector->UnknownKeys, expectedKeys); } Y_UNIT_TEST(TestCompositeRepeated) { TCompositeRepeated proto; TSimpleSharedPtr collector = new TTestUnknownFieldsCollector; TJson2ProtoConfig cfg; cfg.SetUnknownFieldsCollector(collector).SetAllowUnknownFields(true); Json2Proto(TStringBuf(R"({"Part":[)" R"( {"42":42,"I32":11,"test":12,"string":"str","String":"string"},)" R"( {"abc":"d"})" R"(],)" R"("string2":"str"})"), proto, cfg); TSet expectedKeys = { {"/Part/0/42"}, {"/Part/0/string"}, {"/Part/0/test"}, {"/Part/1/abc"}, {"/string2"}, }; UNIT_ASSERT(collector->CurrentPath.empty()); UNIT_ASSERT_VALUES_EQUAL(collector->UnknownKeys, expectedKeys); } Y_UNIT_TEST(TestCompleMapType) { TComplexMapType proto; TSimpleSharedPtr collector = new TTestUnknownFieldsCollector; TJson2ProtoConfig cfg; cfg.SetUnknownFieldsCollector(collector).SetAllowUnknownFields(true); Json2Proto(TStringBuf(R"({"42":42,)" R"("Nested":[)" R"( {"key":"abc","value":{"string":"string","Nested":[{"key":"def","value":{"string2":"string2"}}]}},)" R"( {"key":"car","value":{"string3":"string3"}})" R"(]})"), proto, cfg); TSet expectedKeys = { {"/42"}, {"/Nested/0/value/Nested/0/value/string2"}, {"/Nested/0/value/string"}, {"/Nested/1/value/string3"}, }; UNIT_ASSERT(collector->CurrentPath.empty()); UNIT_ASSERT_VALUES_EQUAL(collector->UnknownKeys, expectedKeys); } Y_UNIT_TEST(TestCompleMapTypeMapAsObject) { TComplexMapType proto; TSimpleSharedPtr collector = new TTestUnknownFieldsCollector; TJson2ProtoConfig cfg; cfg.SetUnknownFieldsCollector(collector).SetAllowUnknownFields(true).SetMapAsObject(true); Json2Proto(TStringBuf(R"({"42":42,)" R"("Nested":{)" R"( "abc":{"string":"string","Nested":{"def":{"string2":"string2"}}},)" R"( "car":{"string3":"string3"})" R"(}})"), proto, cfg); TSet expectedKeys = { {"/42"}, {"/Nested/abc/Nested/def/string2"}, {"/Nested/abc/string"}, {"/Nested/car/string3"}, }; UNIT_ASSERT(collector->CurrentPath.empty()); UNIT_ASSERT_VALUES_EQUAL(collector->UnknownKeys, expectedKeys); } } // TJson2ProtoTest