blob: 3a2ec6e31eac5b4ba85d3fdc91073d6c0dd86b62 [file] [log] [blame]
// Copyright 2020 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 <zxtest/zxtest.h>
#include "error_test.h"
#include "test_library.h"
namespace {
// Tests that use handles need to define a "fake" zx dependency, written in the
// old syntax. This helper function streamlines that process. It also serves as
// a good psuedo-test for situations where a library written in the new syntax
// depends on one written in the old.
TestLibrary with_fake_zx(SharedAmongstLibraries& shared, const std::string& in,
const fidl::ExperimentalFlags flags) {
TestLibrary main_lib("example.fidl", in, &shared, flags);
fidl::ExperimentalFlags zx_flags;
zx_flags.SetFlag(fidl::ExperimentalFlags::Flag::kEnableHandleRights);
std::string zx = R"FIDL(
library zx;
enum obj_type : uint32 {
NONE = 0;
PROCESS = 1;
THREAD = 2;
VMO = 3;
CHANNEL = 4;
EVENT = 5;
PORT = 6;
};
resource_definition handle : uint32 {
properties {
obj_type subtype;
};
};
)FIDL";
TestLibrary zx_lib("zx.fidl", zx, &shared, zx_flags);
zx_lib.Compile();
main_lib.AddDependentLibrary(std::move(zx_lib));
return main_lib;
}
TEST(NewSyntaxTests, TypeDeclOfStructLayout) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
TestLibrary library(R"FIDL(
library example;
type TypeDecl = struct {
field1 uint16;
field2 uint16;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupStruct("TypeDecl");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->members.size(), 2);
}
TEST(NewSyntaxTests, TypeDeclOfUnionLayout) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
TestLibrary library(R"FIDL(
library example;
type TypeDecl = union {
1: variant1 uint16;
2: variant2 uint16;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupUnion("TypeDecl");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->members.size(), 2);
}
TEST(NewSyntaxTests, TypeDeclOfStructLayoutWithResourceness) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
SharedAmongstLibraries shared;
auto library = with_fake_zx(shared, R"FIDL(
library example;
using zx;
type t1 = struct {
f1 uint8;
};
type t2 = resource struct {
f1 zx.handle;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupStruct("t1");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kValue);
type_decl = library.LookupStruct("t2");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kResource);
}
TEST(NewSyntaxTests, TypeDeclOfUnionLayoutWithResourceness) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
SharedAmongstLibraries shared;
auto library = with_fake_zx(shared, R"FIDL(
library example;
using zx;
type t1 = union {
1: v1 uint8;
};
type t2 = resource union {
1: v1 zx.handle;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupUnion("t1");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kFlexible);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kValue);
type_decl = library.LookupUnion("t2");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kFlexible);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kResource);
}
TEST(NewSyntaxTests, TypeDeclOfUnionLayoutWithStrictnesss) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
TestLibrary library(R"FIDL(
library example;
type t1 = union {
1: v1 uint8;
};
type t2 = flexible union {
1: v1 uint8;
};
type t3 = strict union {
1: v1 uint8;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupUnion("t1");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kFlexible);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kValue);
type_decl = library.LookupUnion("t2");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kFlexible);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kValue);
type_decl = library.LookupUnion("t3");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kStrict);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kValue);
}
TEST(NewSyntaxTests, TypeDeclOfUnionLayoutWithResourcenessAndStrictness) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
SharedAmongstLibraries shared;
auto library = with_fake_zx(shared, R"FIDL(
library example;
using zx;
type t1 = resource flexible union {
1: v1 zx.handle;
};
type t2 = flexible resource union {
1: v1 zx.handle;
};
type t3 = resource strict union {
1: v1 zx.handle;
};
type t4 = strict resource union {
1: v1 zx.handle;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupUnion("t1");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kFlexible);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kResource);
type_decl = library.LookupUnion("t2");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kFlexible);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kResource);
type_decl = library.LookupUnion("t3");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kStrict);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kResource);
type_decl = library.LookupUnion("t4");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->strictness, fidl::types::Strictness::kStrict);
EXPECT_EQ(type_decl->resourceness, fidl::types::Resourceness::kResource);
}
TEST(NewSyntaxTests, TypeDeclDisallowPartialModifiers) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
TestLibrary library(R"FIDL(
library example;
type t1 = union{};
type t2 = strict t1;
)FIDL",
std::move(experimental_flags));
ASSERT_FALSE(library.Compile());
const auto& errors = library.errors();
EXPECT_EQ(errors.size(), 1);
ASSERT_ERR(errors[0], fidl::ErrCannotSpecifyModifier);
}
TEST(NewSyntaxTests, TypeDeclOfStructLayoutWithAnonymousStruct) {
fidl::ExperimentalFlags experimental_flags;
experimental_flags.SetFlag(fidl::ExperimentalFlags::Flag::kAllowNewSyntax);
TestLibrary library(R"FIDL(
library example;
type TypeDecl = struct {
field1 struct {
data array<uint8>:16;
};
field2 uint16;
};
)FIDL",
std::move(experimental_flags));
ASSERT_COMPILED(library);
auto type_decl = library.LookupStruct("TypeDecl");
ASSERT_NOT_NULL(type_decl);
EXPECT_EQ(type_decl->members.size(), 2);
auto type_decl_field1 = library.LookupStruct("TypeDeclField1");
ASSERT_NOT_NULL(type_decl_field1);
EXPECT_EQ(type_decl_field1->members.size(), 1);
}
} // namespace