blob: 4db5d5a7b5fda9c4699f48005a09197df9f58e2d [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fidl/converter.h>
#include <fidl/conversion.h>
#include <zxtest/zxtest.h>
#include "error_test.h"
#include "test_library.h"
namespace {
std::string Convert(const std::string& in, fidl::ExperimentalFlags flags, fidl::conv::Conversion::Syntax syntax) {
TestLibrary library(in, flags);
std::unique_ptr<fidl::raw::File> ast;
library.Parse(&ast);
fidl::conv::ConvertingTreeVisitor visitor = fidl::conv::ConvertingTreeVisitor(syntax);
visitor.OnFile(ast);
return *visitor.converted_output();
}
std::string ToOldSyntax(const std::string& in) {
fidl::ExperimentalFlags flags;
return Convert(in, flags, fidl::conv::Conversion::Syntax::kOld);
}
std::string ToOldSyntax(const std::string& in, fidl::ExperimentalFlags flags) {
return Convert(in, flags, fidl::conv::Conversion::Syntax::kOld);
}
std::string ToNewSyntax(const std::string& in) {
fidl::ExperimentalFlags flags;
return Convert(in, flags, fidl::conv::Conversion::Syntax::kNew);
}
std::string ToNewSyntax(const std::string& in, fidl::ExperimentalFlags flags) {
return Convert(in, flags, fidl::conv::Conversion::Syntax::kNew);
}
TEST(ConverterTests, Consts) {
std::string old_version = R"FIDL(
library example;
const uint8 FOO = 34;
const string:3 BAR = "abc";
const bool BAZ = true;
)FIDL";
std::string new_version = R"FIDL(
library example;
const FOO uint8 = 34;
const BAR string:3 = "abc";
const BAZ bool = true;
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, Protocol) {
std::string old_version = R"FIDL(
library example;
protocol Foo {
DoFoo(string a, int32 b);
}
)FIDL";
std::string new_version = R"FIDL(
library example;
protocol Foo {
DoFoo(a string, b int32);
}
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, ProtocolWithResponse) {
std::string old_version = R"FIDL(
library example;
protocol Foo {
DoFoo(string a, int32 b) -> (bool c);
}
)FIDL";
std::string new_version = R"FIDL(
library example;
protocol Foo {
DoFoo(a string, b int32) -> (c bool);
}
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, ProtocolWithResponseAndError) {
std::string old_version = R"FIDL(
library example;
protocol Foo {
DoFoo(string a, int32 b) -> (bool c) error int32;
}
)FIDL";
std::string new_version = R"FIDL(
library example;
protocol Foo {
DoFoo(a string, b int32) -> (c bool) error int32;
}
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructEmpty) {
std::string old_version = R"FIDL(
library example;
struct S {};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = struct {};
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructWithMember) {
std::string old_version = R"FIDL(
library example;
struct S {
int32 a;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = struct {
a int32;
};
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructWithOptional) {
std::string old_version = R"FIDL(
library example;
struct O {};
struct S {
O? o;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type O = struct {};
type S = struct {
o O:optional;
};
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructWithVectors) {
std::string old_version = R"FIDL(
library example;
struct S {
vector<uint8> v1;
vector<uint8>? v2;
vector<uint8>:16? v3;
vector<vector<uint8>?>:16 v4;
vector<vector<vector<uint8>:16?>>? v5;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = struct {
v1 vector<uint8>;
v2 vector<uint8>:optional;
v3 vector<uint8>:<optional,16>;
v4 vector<vector<uint8>:optional>:16;
v5 vector<vector<vector<uint8>:<optional,16>>>:optional;
};
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructWithHandle) {
std::string old_version = R"FIDL(
library example;
resource struct S {
handle? h;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = resource struct {
h handle:optional;
};
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructWithHandleWithSubtype) {
std::string old_version = R"FIDL(
library example;
resource struct S {
handle:VMO h;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = resource struct {
h handle:VMO;
};
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
TEST(ConverterTests, StructWithHandleWithSubtypeAndRights) {
std::string old_version = R"FIDL(
library example;
resource struct S {
handle:<CHANNEL,7> h;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = resource struct {
h handle:<CHANNEL,7>;
};
)FIDL";
fidl::ExperimentalFlags flags;
flags.SetFlag(fidl::ExperimentalFlags::Flag::kEnableHandleRights);
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version, flags));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version, flags));
}
// This test case's purpose to verify that "nested conversions" work well. This
// particular case has four levels of nesting: the struct declaration at the top
// level, which contains an identifier/type order swap conversion, which
// contains an array type declaration, which itself contains a handle type
// declaration that needs to be converted as well.
TEST(ConverterTests, StructWithManyNestedConversions) {
std::string old_version = R"FIDL(
library example;
resource struct S {
array<handle:<PORT,7>?>:5 a;
};
)FIDL";
std::string new_version = R"FIDL(
library example;
type S = resource struct {
a array<handle:<optional,PORT,7>,5>;
};
)FIDL";
fidl::ExperimentalFlags flags;
flags.SetFlag(fidl::ExperimentalFlags::Flag::kEnableHandleRights);
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version, flags));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version, flags));
}
TEST(ConverterTests, StructWithComments) {
std::string old_version = R"FIDL(
library example;
// Top-level comments should be retained.
/// Top-level doc comments should be retained.
// Top-level comments after doc comments should be retained.
struct S {
// Inner comments should be retained.
/// So should inner doc comments.
string a;
// And leading blank lines.
// And multiline comments.
int32 b;
// Trailing inner comments should be retained.
};
// Trailing comments should be retained.
)FIDL";
std::string new_version = R"FIDL(
library example;
// Top-level comments should be retained.
/// Top-level doc comments should be retained.
// Top-level comments after doc comments should be retained.
type S = struct {
// Inner comments should be retained.
/// So should inner doc comments.
a string;
// And leading blank lines.
// And multiline comments.
b int32;
// Trailing inner comments should be retained.
};
// Trailing comments should be retained.
)FIDL";
ASSERT_STR_EQ(old_version, ToOldSyntax(old_version));
ASSERT_STR_EQ(new_version, ToNewSyntax(old_version));
}
} // namespace