blob: 4a3e13df20bdcc97e014e2bf3f268dea78260d1d [file] [log] [blame]
// Copyright 2018 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/flat_ast.h>
#include <fidl/lexer.h>
#include <fidl/parser.h>
#include <fidl/source_file.h>
#include <zxtest/zxtest.h>
#include "error_test.h"
#include "test_library.h"
namespace {
static bool Compiles(const std::string& source_code) {
auto library = TestLibrary("test.fidl", source_code);
return library.Compile();
}
TEST(TableTests, compiling) {
// Populated fields.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 x;
};
)FIDL"));
// Reserved fields.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: reserved;
};
)FIDL"));
// Reserved and populated fields.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: reserved;
2: int64 x;
};
)FIDL"));
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 x;
2: reserved;
};
)FIDL"));
// Many reserved fields.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: reserved;
2: reserved;
3: reserved;
};
)FIDL"));
// Out of order fields.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
3: reserved;
1: reserved;
2: reserved;
};
)FIDL"));
// Duplicate ordinals.
EXPECT_FALSE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: reserved;
1: reserved;
};
)FIDL"));
// Missing ordinals.
EXPECT_FALSE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: reserved;
3: reserved;
};
)FIDL"));
// Empty tables are allowed.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
};
)FIDL"));
{
// Ordinals required.
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Foo {
int64 x;
};
)FIDL");
EXPECT_FALSE(library.Compile());
EXPECT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrExpectedOrdinalOrCloseBrace);
}
{
// Duplicate field names are invalid.
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Duplicates {
1: string field;
2: uint32 field;
};
)FIDL");
EXPECT_FALSE(library.Compile());
EXPECT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrDuplicateTableFieldName);
}
{
// Duplicate ordinals are invalid.
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Duplicates {
1: string foo;
1: uint32 bar;
};
)FIDL");
EXPECT_FALSE(library.Compile());
EXPECT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrDuplicateTableFieldOrdinal);
}
// Attributes on fields.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
[FooAttr="bar"]
1: int64 x;
[BarAttr]
2: bool bar;
};
)FIDL"));
// Attributes on tables.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
[FooAttr="bar"]
table Foo {
1: int64 x;
2: bool please;
};
)FIDL"));
// Attributes on reserved.
EXPECT_FALSE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
[Foo]
1: reserved;
};
)FIDL"));
// Keywords as field names.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
struct struct {
bool field;
};
table Foo {
1: int64 table;
2: bool library;
3: uint32 uint32;
4: struct member;
};
)FIDL"));
{
// Optional tables in structs are invalid.
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 t;
};
struct OptionalTableContainer {
Foo? foo;
};
)FIDL");
EXPECT_FALSE(library.Compile());
EXPECT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrCannotBeNullable);
}
{
// Optional tables in (static) unions are invalid.
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 t;
};
union OptionalTableContainer {
1: Foo? foo;
};
)FIDL");
EXPECT_FALSE(library.Compile());
EXPECT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrNullableUnionMember);
}
// Tables in tables are valid.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 t;
};
table Bar {
1: Foo foo;
};
)FIDL"));
// Tables in unions are valid.
EXPECT_TRUE(Compiles(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 t;
};
flexible union OptionalTableContainer {
1: Foo foo;
};
)FIDL"));
{
// Optional fields in tables are invalid.
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64? t;
};
)FIDL");
EXPECT_FALSE(library.Compile());
EXPECT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrNullableTableMember);
}
}
TEST(TableTests, default_not_allowed) {
auto library = TestLibrary(R"FIDL(
library fidl.test.tables;
table Foo {
1: int64 t = 1;
};
)FIDL");
EXPECT_FALSE(library.Compile());
ASSERT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrDefaultsOnTablesNotSupported);
}
TEST(TableTests, must_be_dense) {
auto library = TestLibrary(R"FIDL(
library example;
table Example {
1: int64 first;
3: int64 third;
};
)FIDL");
EXPECT_FALSE(library.Compile());
ASSERT_EQ(library.errors().size(), 1u);
ASSERT_ERR(library.errors().at(0), fidl::ErrNonDenseOrdinal);
ASSERT_SUBSTR(library.errors().at(0)->msg.c_str(), "2");
}
} // namespace