...

Text file src/github.com/google/flatbuffers/tests/json_test.cpp

Documentation: github.com/google/flatbuffers/tests

     1#include "json_test.h"
     2
     3#include "flatbuffers/flatbuffers.h"
     4#include "flatbuffers/idl.h"
     5#include "monster_test_bfbs_generated.h"
     6#include "monster_test_generated.h"
     7#include "optional_scalars_generated.h"
     8#include "test_assert.h"
     9
    10namespace flatbuffers {
    11namespace tests {
    12
    13using namespace MyGame::Example;
    14
    15// Check stringify of an default enum value to json
    16void JsonDefaultTest(const std::string &tests_data_path) {
    17  // load FlatBuffer schema (.fbs) from disk
    18  std::string schemafile;
    19  TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
    20                                false, &schemafile),
    21          true);
    22  // parse schema first, so we can use it to parse the data after
    23  flatbuffers::Parser parser;
    24  auto include_test_path =
    25      flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
    26  const char *include_directories[] = { tests_data_path.c_str(),
    27                                        include_test_path.c_str(), nullptr };
    28
    29  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
    30  // create incomplete monster and store to json
    31  parser.opts.output_default_scalars_in_json = true;
    32  parser.opts.output_enum_identifiers = true;
    33  flatbuffers::FlatBufferBuilder builder;
    34  auto name = builder.CreateString("default_enum");
    35  MonsterBuilder color_monster(builder);
    36  color_monster.add_name(name);
    37  FinishMonsterBuffer(builder, color_monster.Finish());
    38  std::string jsongen;
    39  auto result = GenText(parser, builder.GetBufferPointer(), &jsongen);
    40  TEST_NULL(result);
    41  // default value of the "color" field is Blue
    42  TEST_EQ(std::string::npos != jsongen.find("color: \"Blue\""), true);
    43  // default value of the "testf" field is 3.14159
    44  TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
    45}
    46
    47void JsonEnumsTest(const std::string &tests_data_path) {
    48  // load FlatBuffer schema (.fbs) from disk
    49  std::string schemafile;
    50  TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
    51                                false, &schemafile),
    52          true);
    53  // parse schema first, so we can use it to parse the data after
    54  flatbuffers::Parser parser;
    55  auto include_test_path =
    56      flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
    57  const char *include_directories[] = { tests_data_path.c_str(),
    58                                        include_test_path.c_str(), nullptr };
    59  parser.opts.output_enum_identifiers = true;
    60  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
    61  flatbuffers::FlatBufferBuilder builder;
    62  auto name = builder.CreateString("bitflag_enum");
    63  MonsterBuilder color_monster(builder);
    64  color_monster.add_name(name);
    65  color_monster.add_color(Color(Color_Blue | Color_Red));
    66  FinishMonsterBuffer(builder, color_monster.Finish());
    67  std::string jsongen;
    68  auto result = GenText(parser, builder.GetBufferPointer(), &jsongen);
    69  TEST_NULL(result);
    70  TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
    71  // Test forward compatibility with 'output_enum_identifiers = true'.
    72  // Current Color doesn't have '(1u << 2)' field, let's add it.
    73  builder.Clear();
    74  std::string future_json;
    75  auto future_name = builder.CreateString("future bitflag_enum");
    76  MonsterBuilder future_color(builder);
    77  future_color.add_name(future_name);
    78  future_color.add_color(
    79      static_cast<Color>((1u << 2) | Color_Blue | Color_Red));
    80  FinishMonsterBuffer(builder, future_color.Finish());
    81  result = GenText(parser, builder.GetBufferPointer(), &future_json);
    82  TEST_NULL(result);
    83  TEST_EQ(std::string::npos != future_json.find("color: 13"), true);
    84}
    85
    86void JsonOptionalTest(const std::string &tests_data_path,
    87                      bool default_scalars) {
    88  // load FlatBuffer schema (.fbs) and JSON from disk
    89  std::string schemafile;
    90  std::string jsonfile;
    91  TEST_EQ(
    92      flatbuffers::LoadFile((tests_data_path + "optional_scalars.fbs").c_str(),
    93                            false, &schemafile),
    94      true);
    95  TEST_EQ(flatbuffers::LoadFile((tests_data_path + "optional_scalars" +
    96                                 (default_scalars ? "_defaults" : "") + ".json")
    97                                    .c_str(),
    98                                false, &jsonfile),
    99          true);
   100
   101  auto include_test_path =
   102      flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
   103  const char *include_directories[] = { tests_data_path.c_str(),
   104                                        include_test_path.c_str(), nullptr };
   105
   106  // parse schema first, so we can use it to parse the data after
   107  flatbuffers::Parser parser;
   108  parser.opts.output_default_scalars_in_json = default_scalars;
   109  TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
   110  TEST_EQ(parser.ParseJson(jsonfile.c_str()), true);
   111
   112  // here, parser.builder_ contains a binary buffer that is the parsed data.
   113
   114  // First, verify it, just in case:
   115  flatbuffers::Verifier verifier(parser.builder_.GetBufferPointer(),
   116                                 parser.builder_.GetSize());
   117  TEST_EQ(optional_scalars::VerifyScalarStuffBuffer(verifier), true);
   118
   119  // to ensure it is correct, we now generate text back from the binary,
   120  // and compare the two:
   121  std::string jsongen;
   122  auto result = GenText(parser, parser.builder_.GetBufferPointer(), &jsongen);
   123  TEST_NULL(result);
   124  TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
   125}
   126
   127void ParseIncorrectMonsterJsonTest(const std::string &tests_data_path) {
   128  std::string schemafile;
   129  TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.bfbs").c_str(),
   130                                true, &schemafile),
   131          true);
   132  flatbuffers::Parser parser;
   133  flatbuffers::Verifier verifier(
   134      reinterpret_cast<const uint8_t *>(schemafile.c_str()), schemafile.size());
   135  TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
   136  TEST_EQ(
   137      parser.Deserialize(reinterpret_cast<const uint8_t *>(schemafile.c_str()),
   138                         schemafile.size()),
   139      true);
   140  TEST_EQ(parser.ParseJson("{name:\"monster\"}"), true);
   141  TEST_EQ(parser.ParseJson(""), false);
   142  TEST_EQ(parser.ParseJson("{name: 1}"), false);
   143  TEST_EQ(parser.ParseJson("{name:+1}"), false);
   144  TEST_EQ(parser.ParseJson("{name:-1}"), false);
   145  TEST_EQ(parser.ParseJson("{name:-f}"), false);
   146  TEST_EQ(parser.ParseJson("{name:+f}"), false);
   147}
   148
   149void JsonUnsortedArrayTest() {
   150  flatbuffers::Parser parser;
   151  TEST_EQ(parser.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
   152                             MyGame::Example::MonsterBinarySchema::size()),
   153          true);
   154  auto jsonStr = R"(
   155  {
   156    "name": "lookupTest",
   157    "testarrayoftables": [
   158      { "name": "aaa" },
   159      { "name": "ccc" },
   160      { "name": "bbb" }
   161    ]
   162  }
   163  )";
   164  TEST_EQ(parser.ParseJson(jsonStr), true);
   165  auto monster = flatbuffers::GetRoot<MyGame::Example::Monster>(
   166      parser.builder_.GetBufferPointer());
   167
   168  TEST_NOTNULL(monster->testarrayoftables()->LookupByKey("aaa"));
   169  TEST_NOTNULL(monster->testarrayoftables()->LookupByKey("bbb"));
   170  TEST_NOTNULL(monster->testarrayoftables()->LookupByKey("ccc"));
   171}
   172
   173void JsonUnionStructTest() {
   174  // schema to parse data
   175  auto schema = R"(
   176struct MyStruct { field: int; }
   177union UnionWithStruct { MyStruct }
   178table JsonUnionStructTest { union_with_struct: UnionWithStruct; }
   179root_type JsonUnionStructTest;
   180)";
   181  // source text to parse and expected result of generation text back
   182  auto json_source = R"({
   183  union_with_struct_type: "MyStruct",
   184  union_with_struct: {
   185    field: 12345
   186  }
   187}
   188)";
   189
   190  flatbuffers::Parser parser;
   191  // set output language to JSON, so we assure that is supported
   192  parser.opts.lang_to_generate = IDLOptions::kJson;
   193  // parse schema first, so we assure that output language is supported
   194  // and can use it to parse the data after
   195  TEST_EQ(true, parser.Parse(schema));
   196  TEST_EQ(true, parser.ParseJson(json_source));
   197
   198  // now generate text back from the binary, and compare the two:
   199  std::string json_generated;
   200  auto generate_result =
   201      GenText(parser, parser.builder_.GetBufferPointer(), &json_generated);
   202  TEST_NULL(generate_result);
   203  TEST_EQ_STR(json_source, json_generated.c_str());
   204}
   205
   206}  // namespace tests
   207}  // namespace flatbuffers

View as plain text