#include "proto_test.h"
#include "flatbuffers/code_generator.h"
#include "idl_gen_fbs.h"
#include "test_assert.h"
namespace flatbuffers {
namespace tests {
void RunTest(const flatbuffers::IDLOptions &opts, const std::string &proto_path,
const std::string &proto_file, const std::string &golden_file,
const std::string import_proto_file) {
const char *include_directories[] = { proto_path.c_str(), nullptr };
flatbuffers::Parser parser(opts);
TEST_EQ(parser.Parse(proto_file.c_str(), include_directories), true);
std::unique_ptr<CodeGenerator> fbs_generator = NewFBSCodeGenerator(true);
std::string fbs;
TEST_EQ(fbs_generator->GenerateCodeString(parser, "test", fbs),
CodeGenerator::Status::OK);
flatbuffers::Parser parser2;
if (!import_proto_file.empty()) {
flatbuffers::Parser import_parser(opts);
TEST_EQ(import_parser.Parse(import_proto_file.c_str(), include_directories),
true);
std::string import_fbs;
TEST_EQ(
fbs_generator->GenerateCodeString(import_parser, "test", import_fbs),
CodeGenerator::Status::OK);
std::string imported_fbs = flatbuffers::PosixPath(
flatbuffers::AbsolutePath(proto_path) + "/imported.fbs");
TEST_EQ(parser2.Parse(import_fbs.c_str(), include_directories,
imported_fbs.c_str()),
true);
}
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
TEST_EQ_STR(fbs.c_str(), golden_file.c_str());
}
void proto_test(const std::string &proto_path, const std::string &proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile((proto_path + "test.golden.fbs").c_str(), false,
&golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file);
}
void proto_test_id(const std::string &proto_path,
const std::string &proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
opts.keep_proto_id = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile((proto_path + "test_id.golden.fbs").c_str(),
false, &golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file);
}
void proto_test_union(const std::string &proto_path,
const std::string &proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
opts.proto_oneof_union = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile((proto_path + "test_union.golden.fbs").c_str(),
false, &golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file);
}
void proto_test_union_id(const std::string &proto_path,
const std::string &proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
opts.proto_oneof_union = true;
opts.keep_proto_id = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(
flatbuffers::LoadFile((proto_path + "test_union_id.golden.fbs").c_str(),
false, &golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file);
}
void proto_test_union_suffix(const std::string &proto_path,
const std::string &proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
opts.proto_namespace_suffix = "test_namespace_suffix";
opts.proto_oneof_union = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile(
(proto_path + "test_union_suffix.golden.fbs").c_str(), false,
&golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file);
}
void proto_test_union_suffix_id(const std::string &proto_path,
const std::string &proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
opts.proto_namespace_suffix = "test_namespace_suffix";
opts.proto_oneof_union = true;
opts.keep_proto_id = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile(
(proto_path + "test_union_suffix_id.golden.fbs").c_str(), false,
&golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file);
}
void proto_test_include(const std::string &proto_path,
const std::string &proto_file,
const std::string &import_proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = true;
opts.proto_mode = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(
flatbuffers::LoadFile((proto_path + "test_include.golden.fbs").c_str(),
false, &golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
}
void proto_test_include_id(const std::string &proto_path,
const std::string &proto_file,
const std::string &import_proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = true;
opts.proto_mode = true;
opts.keep_proto_id = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(
flatbuffers::LoadFile((proto_path + "test_include_id.golden.fbs").c_str(),
false, &golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
}
void proto_test_include_union(const std::string &proto_path,
const std::string &proto_file,
const std::string &import_proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = true;
opts.proto_mode = true;
opts.proto_oneof_union = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile(
(proto_path + "test_union_include.golden.fbs").c_str(), false,
&golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
}
void proto_test_include_union_id(const std::string &proto_path,
const std::string &proto_file,
const std::string &import_proto_file) {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = true;
opts.proto_mode = true;
opts.proto_oneof_union = true;
opts.keep_proto_id = true;
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
std::string golden_file;
TEST_EQ(flatbuffers::LoadFile(
(proto_path + "test_union_include_id.golden.fbs").c_str(), false,
&golden_file),
true);
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
}
void ParseCorruptedProto(const std::string &proto_path) {
const char *include_directories[] = { proto_path.c_str(), nullptr };
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = true;
opts.proto_mode = true;
opts.proto_oneof_union = true;
std::string proto_file;
std::unique_ptr<CodeGenerator> fbs_generator = NewFBSCodeGenerator(true);
{
flatbuffers::Parser parser(opts);
TEST_EQ(
flatbuffers::LoadFile((proto_path + "non-positive-id.proto").c_str(),
false, &proto_file),
true);
TEST_EQ(parser.Parse(proto_file.c_str(), include_directories), true);
TEST_NE(fbs_generator->GenerateCode(parser, "temp.fbs", "test"),
CodeGenerator::Status::OK);
}
{
flatbuffers::Parser parser(opts);
TEST_EQ(flatbuffers::LoadFile((proto_path + "twice-id.proto").c_str(),
false, &proto_file),
true);
TEST_EQ(parser.Parse(proto_file.c_str(), include_directories), true);
TEST_NE(fbs_generator->GenerateCode(parser, "temp.fbs", "test"),
CodeGenerator::Status::OK);
}
{
flatbuffers::Parser parser(opts);
TEST_EQ(flatbuffers::LoadFile((proto_path + "twice-id.proto").c_str(),
false, &proto_file),
true);
TEST_EQ(parser.Parse(proto_file.c_str(), include_directories), true);
TEST_NE(fbs_generator->GenerateCode(parser, "temp.fbs", "test"),
CodeGenerator::Status::OK);
}
{
opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::ERROR;
flatbuffers::Parser parser(opts);
TEST_EQ(flatbuffers::LoadFile((proto_path + "test.proto").c_str(), false,
&proto_file),
true);
TEST_EQ(parser.Parse(proto_file.c_str(), include_directories), true);
TEST_NE(fbs_generator->GenerateCode(parser, "temp.fbs", "test"),
CodeGenerator::Status::OK);
}
}
void ParseProtoTest(const std::string &tests_data_path) {
auto proto_path = tests_data_path + "prototest/";
std::string proto_file;
TEST_EQ(
flatbuffers::LoadFile((tests_data_path + "prototest/test.proto").c_str(),
false, &proto_file),
true);
std::string import_proto_file;
TEST_EQ(flatbuffers::LoadFile(
(tests_data_path + "prototest/imported.proto").c_str(), false,
&import_proto_file),
true);
proto_test(proto_path, proto_file);
proto_test_union(proto_path, proto_file);
proto_test_union_suffix(proto_path, proto_file);
proto_test_include(proto_path, proto_file, import_proto_file);
proto_test_include_union(proto_path, proto_file, import_proto_file);
proto_test_id(proto_path, proto_file);
proto_test_union_id(proto_path, proto_file);
proto_test_union_suffix_id(proto_path, proto_file);
proto_test_include_id(proto_path, proto_file, import_proto_file);
proto_test_include_union_id(proto_path, proto_file, import_proto_file);
ParseCorruptedProto(proto_path);
}
void ParseProtoBufAsciiTest() {
flatbuffers::Parser parser;
parser.opts.protobuf_ascii_alike = true;
TEST_EQ(
parser.Parse("table S { B:int; } table T { A:[int]; C:S; } root_type T;"),
true);
TEST_EQ(parser.Parse("{ A [1 2] C { B:2 }}"), true);
std::string text;
auto err =
flatbuffers::GenText(
parser, parser.builder_.GetBufferPointer(), &text);
TEST_NULL(err);
TEST_EQ_STR(text.c_str(),
"{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n");
}
} }