| // 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 { |
| |
| void invalid_strictness(const std::string& type, const std::string& definition) { |
| std::string fidl_library = "library example;\n\n" + definition + "\n"; |
| |
| TestLibrary library(fidl_library); |
| EXPECT_FALSE(library.Compile()); |
| |
| const auto& errors = library.errors(); |
| ASSERT_EQ(errors.size(), 1); |
| ASSERT_ERR(errors[0], fidl::ErrCannotSpecifyModifier); |
| ASSERT_SUBSTR(errors[0]->msg.c_str(), "strict"); |
| ASSERT_SUBSTR(errors[0]->msg.c_str(), type.c_str()); |
| } |
| |
| TEST(StrictnessTests, bad_duplicate_modifier) { |
| TestLibrary library(R"FIDL( |
| library example; |
| |
| strict union One { 1: bool b; }; |
| strict strict union Two { 1: bool b; }; // line 5 |
| strict strict strict union Three { 1: bool b; }; // line 6 |
| )FIDL"); |
| ASSERT_FALSE(library.Compile()); |
| |
| const auto& errors = library.errors(); |
| ASSERT_EQ(errors.size(), 3); |
| ASSERT_ERR(errors[0], fidl::ErrDuplicateModifier); |
| EXPECT_EQ(errors[0]->span->position().line, 5); |
| ASSERT_SUBSTR(errors[0]->msg.c_str(), "strict"); |
| ASSERT_ERR(errors[1], fidl::ErrDuplicateModifier); |
| EXPECT_EQ(errors[1]->span->position().line, 6); |
| ASSERT_SUBSTR(errors[1]->msg.c_str(), "strict"); |
| ASSERT_ERR(errors[2], fidl::ErrDuplicateModifier); |
| EXPECT_EQ(errors[2]->span->position().line, 6); |
| ASSERT_SUBSTR(errors[2]->msg.c_str(), "strict"); |
| } |
| |
| TEST(StrictnessTests, bad_conflicting_modifiers) { |
| TestLibrary library(R"FIDL( |
| library example; |
| |
| strict flexible union SF { 1: bool b; }; // line 4 |
| flexible strict union FS { 1: bool b; }; // line 5 |
| )FIDL"); |
| ASSERT_FALSE(library.Compile()); |
| |
| const auto& errors = library.errors(); |
| ASSERT_EQ(errors.size(), 2); |
| ASSERT_ERR(errors[0], fidl::ErrConflictingModifier); |
| EXPECT_EQ(errors[0]->span->position().line, 4); |
| ASSERT_SUBSTR(errors[0]->msg.c_str(), "strict"); |
| ASSERT_SUBSTR(errors[0]->msg.c_str(), "flexible"); |
| ASSERT_ERR(errors[1], fidl::ErrConflictingModifier); |
| EXPECT_EQ(errors[1]->span->position().line, 5); |
| ASSERT_SUBSTR(errors[1]->msg.c_str(), "strict"); |
| ASSERT_SUBSTR(errors[1]->msg.c_str(), "flexible"); |
| } |
| |
| TEST(StrictnessTests, bits_strictness) { |
| TestLibrary library( |
| R"FIDL( |
| library example; |
| |
| bits DefaultStrictFoo { |
| BAR = 0x1; |
| }; |
| |
| strict bits StrictFoo { |
| BAR = 0x1; |
| }; |
| |
| flexible bits FlexibleFoo { |
| BAR = 0x1; |
| }; |
| |
| )FIDL"); |
| ASSERT_TRUE(library.Compile()); |
| EXPECT_EQ(library.LookupBits("FlexibleFoo")->strictness, fidl::types::Strictness::kFlexible); |
| EXPECT_EQ(library.LookupBits("StrictFoo")->strictness, fidl::types::Strictness::kStrict); |
| EXPECT_EQ(library.LookupBits("DefaultStrictFoo")->strictness, fidl::types::Strictness::kStrict); |
| } |
| |
| TEST(StrictnessTests, enum_strictness) { |
| TestLibrary library( |
| R"FIDL( |
| library example; |
| |
| enum DefaultStrictFoo { |
| BAR = 1; |
| }; |
| |
| strict enum StrictFoo { |
| BAR = 1; |
| }; |
| |
| flexible enum FlexibleFoo { |
| BAR = 1; |
| }; |
| |
| )FIDL"); |
| ASSERT_TRUE(library.Compile()); |
| EXPECT_EQ(library.LookupEnum("FlexibleFoo")->strictness, fidl::types::Strictness::kFlexible); |
| EXPECT_EQ(library.LookupEnum("StrictFoo")->strictness, fidl::types::Strictness::kStrict); |
| EXPECT_EQ(library.LookupEnum("DefaultStrictFoo")->strictness, fidl::types::Strictness::kStrict); |
| } |
| |
| TEST(StrictnessTests, flexible_enum_redundant) { |
| // TODO(fxbug.dev/7847): Once flexible is the default, we should test that |
| // the keyword causes an error because it is redundant. |
| TestLibrary library(R"FIDL( |
| library example; |
| |
| flexible enum Foo { |
| BAR = 1; |
| }; |
| )FIDL"); |
| ASSERT_TRUE(library.Compile()); |
| } |
| |
| TEST(StrictnessTests, flexible_bits_redundant) { |
| // TODO(fxbug.dev/7847): Once flexible is the default, we should test that |
| // the keyword causes an error because it is redundant. |
| TestLibrary library(R"FIDL( |
| library example; |
| |
| flexible bits Foo { |
| BAR = 0x1; |
| }; |
| )FIDL"); |
| ASSERT_TRUE(library.Compile()); |
| } |
| |
| TEST(StrictnessTests, invalid_strictness_struct) { |
| invalid_strictness("struct", R"FIDL( |
| strict struct Foo { |
| int32 i; |
| }; |
| )FIDL"); |
| } |
| |
| TEST(StrictnessTests, invalid_strictness_table) { |
| invalid_strictness("table", R"FIDL( |
| strict table StrictFoo { |
| }; |
| )FIDL"); |
| } |
| |
| TEST(StrictnessTests, union_strictness) { |
| TestLibrary library(R"FIDL( |
| library example; |
| |
| union Foo { |
| 1: int32 i; |
| }; |
| |
| flexible union FlexibleFoo { |
| 1: int32 i; |
| }; |
| |
| strict union StrictFoo { |
| 1: int32 i; |
| }; |
| |
| )FIDL"); |
| ASSERT_TRUE(library.Compile()); |
| EXPECT_EQ(library.LookupUnion("Foo")->strictness, fidl::types::Strictness::kStrict); |
| EXPECT_EQ(library.LookupUnion("FlexibleFoo")->strictness, fidl::types::Strictness::kFlexible); |
| EXPECT_EQ(library.LookupUnion("StrictFoo")->strictness, fidl::types::Strictness::kStrict); |
| } |
| |
| TEST(StrictnessTests, strict_union_redundant) { |
| TestLibrary library(R"FIDL( |
| library example; |
| |
| strict union Foo { |
| 1: int32 i; |
| }; |
| |
| )FIDL"); |
| ASSERT_TRUE(library.Compile()); |
| ASSERT_EQ(library.LookupUnion("Foo")->strictness, fidl::types::Strictness::kStrict); |
| } |
| |
| } // namespace |