blob: e45b5745e2210c2042be06f2c06a40808b9fe990 [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 <gtest/gtest.h>
#include "tools/fidl/fidlc/src/diagnostics.h"
#include "tools/fidl/fidlc/tests/test_library.h"
namespace fidlc {
namespace {
TEST(RecoverableCompilationTests, BadRecoverInLibraryConsume) {
TestLibrary library(R"FIDL(
library example;
protocol P {};
protocol P {}; // Error: name collision
type foo = struct {};
type Foo = struct {}; // Error: canonical name collision
)FIDL");
library.ExpectFail(ErrNameCollision, Element::Kind::kProtocol, "P", Element::Kind::kProtocol,
"example.fidl:4:10");
library.ExpectFail(ErrNameCollisionCanonical, Element::Kind::kStruct, "foo",
Element::Kind::kStruct, "Foo", "example.fidl:8:6", "foo");
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInLibraryCompile) {
TestLibrary library(R"FIDL(
library example;
type Union = union {
1: string_value string;
2: unknown_value vector; // Error: expected 1 layout parameter
};
type Enum = enum {
ZERO = 0;
ONE = 1;
TWO = 1; // Error: duplicate value
THREE = 3;
};
type OtherEnum = enum {
NONE = 0;
ONE = 1;
TWO = "2"; // Error: invalid type
};
type NonDenseTable = table {
65: s string; // Error: too many ordinals
};
)FIDL");
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "vector", 1, 0);
library.ExpectFail(ErrDuplicateMemberValue, Decl::Kind::kEnum, "TWO", "ONE", "example.fidl:11:5");
library.ExpectFail(ErrCouldNotResolveMember, Decl::Kind::kEnum);
library.ExpectFail(ErrTypeCannotBeConvertedToType, "\"2\"", "string:1", "uint32");
library.ExpectFail(ErrTableOrdinalTooLarge);
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInLibraryVerifyAttributePlacement) {
TestLibrary library(R"FIDL(
library example;
@unknown // Error: invalid placement
type Table = table {
1: foo string;
};
type Struct = struct {
foo uint16;
};
)FIDL");
library.ExpectFail(ErrInvalidAttributePlacement, "unknown");
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInAttributeCompile) {
TestLibrary library(R"FIDL(
library example;
@foo(first="a", first="b") // Error: duplicate args
@bar(first=3, second=4) // Error: x2 can only use string or bool
@foo // Error: duplicate attribute
type Enum = enum {
FOO // Error: cannot resolve enum member
= "not a number"; // Error: cannot be interpreted as uint32
};
)FIDL");
library.ExpectFail(ErrDuplicateAttributeArg, "foo", "first", "example.fidl:4:6");
library.ExpectFail(ErrCanOnlyUseStringOrBool, "first", "bar");
library.ExpectFail(ErrCanOnlyUseStringOrBool, "second", "bar");
library.ExpectFail(ErrDuplicateAttribute, "foo", "example.fidl:4:2");
library.ExpectFail(ErrCouldNotResolveMember, Decl::Kind::kEnum);
library.ExpectFail(ErrTypeCannotBeConvertedToType, "\"not a number\"", "string:12", "uint32");
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInConst) {
TestLibrary library(R"FIDL(
library example;
@attr(1)
const FOO string = 2;
)FIDL");
library.ExpectFail(ErrCanOnlyUseStringOrBool, "value", "attr");
library.ExpectFail(ErrCannotResolveConstantValue);
library.ExpectFail(ErrTypeCannotBeConvertedToType, "2", "untyped numeric", "string");
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInBits) {
TestLibrary library(R"FIDL(
library example;
type Foo = bits {
BAR // Error: cannot resolve bits member
= "not a number"; // Error: cannot interpret as uint32
QUX = vector; // Error: cannot resolve bits member
TWO = 2;
BAZ = 2; // Error: duplicate value 2
XYZ = 3; // Error: not a power of two
};
)FIDL");
library.ExpectFail(ErrCouldNotResolveMember, Decl::Kind::kBits);
library.ExpectFail(ErrTypeCannotBeConvertedToType, "\"not a number\"", "string:12", "uint32");
library.ExpectFail(ErrCouldNotResolveMember, Decl::Kind::kBits);
library.ExpectFail(ErrDuplicateMemberValue, Decl::Kind::kBits, "BAZ", "TWO", "example.fidl:8:5");
library.ExpectFail(ErrBitsMemberMustBePowerOfTwo);
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInEnum) {
TestLibrary library(R"FIDL(
library example;
type Foo = flexible enum : uint8 {
BAR // Error: cannot resolve enum member
= "not a number"; // Error: cannot interpret as uint32
QUX = vector; // Error: cannot resolve enum member
TWO = 2;
BAZ = 2; // Error: duplicate value 2
XYZ = 255; // Error: max value on flexible enum
};
)FIDL");
library.ExpectFail(ErrCouldNotResolveMember, Decl::Kind::kEnum);
library.ExpectFail(ErrTypeCannotBeConvertedToType, "\"not a number\"", "string:12", "uint8");
library.ExpectFail(ErrCouldNotResolveMember, Decl::Kind::kEnum);
library.ExpectFail(ErrDuplicateMemberValue, Decl::Kind::kEnum, "BAZ", "TWO", "example.fidl:8:5");
library.ExpectFail(ErrFlexibleEnumMemberWithMaxValue, "255");
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInStruct) {
TestLibrary library(R"FIDL(
library example;
type Foo = struct {
bar string<1>; // Error: unexpected layout parameter
qux vector; // Error: expected 1 layout parameter
@allow_deprecated_struct_defaults
baz bool // Error: cannot resolve default value
= "not bool"; // Error: cannot interpret as bool
};
)FIDL");
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "string", 0, 1);
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "vector", 1, 0);
library.ExpectFail(ErrCouldNotResolveMemberDefault, "baz");
library.ExpectFail(ErrTypeCannotBeConvertedToType, "\"not bool\"", "string:8", "bool");
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInTable) {
TestLibrary library(R"FIDL(
library example;
type Foo = table {
1: bar string:optional; // Error: table member cannot be optional
1: qux // Error: duplicate ordinal
vector; // Error: expected 1 layout parameter
65: s string; // Error: too many ordinals
};
)FIDL");
library.ExpectFail(ErrOptionalTableMember);
library.ExpectFail(ErrDuplicateTableFieldOrdinal, "example.fidl:5:5");
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "vector", 1, 0);
library.ExpectFail(ErrTableOrdinalTooLarge);
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInUnion) {
TestLibrary library(R"FIDL(
library example;
type Foo = union {
1: bar string:optional; // Error: union member cannot be optional
1: qux // Error: duplicate ordinal
vector; // Error: expected 1 layout parameter
};
)FIDL");
library.ExpectFail(ErrOptionalUnionMember);
library.ExpectFail(ErrDuplicateUnionMemberOrdinal, "example.fidl:5:5");
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "vector", 1, 0);
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInProtocol) {
TestLibrary library(R"FIDL(
library example;
protocol Foo {
compose vector; // Error: expected protocol
@selector("not good") // Error: invalid selector
Bar(struct {}) -> (struct { // Error: empty struct invalid
b bool:optional; // Error: bool cannot be optional
}) error vector; // Error: expected 1 layout parameter
};
)FIDL");
library.ExpectFail(ErrComposingNonProtocol);
library.ExpectFail(ErrInvalidSelectorValue);
library.ExpectFail(ErrEmptyPayloadStructs);
library.ExpectFail(ErrCannotBeOptional, "bool");
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "vector", 1, 0);
ASSERT_COMPILER_DIAGNOSTICS(library);
}
TEST(RecoverableCompilationTests, BadRecoverInService) {
TestLibrary library(R"FIDL(
library example;
protocol P {};
service Foo {
bar string; // Error: must be client_end
baz vector; // Error: expected 1 layout parameter
qux server_end:P; // Error: must be client_end
opt client_end:<P,optional>; // Error: cannot be optional
};
)FIDL");
library.ExpectFail(ErrOnlyClientEndsInServices);
library.ExpectFail(ErrWrongNumberOfLayoutParameters, "vector", 1, 0);
library.ExpectFail(ErrOnlyClientEndsInServices);
library.ExpectFail(ErrOptionalServiceMember);
ASSERT_COMPILER_DIAGNOSTICS(library);
}
} // namespace
} // namespace fidlc