From 51c811bfa8cdbaf48f07f14074e0e5d2255fe4c2 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 5 Mar 2020 20:29:13 +0000 Subject: [PATCH] Add BreakStatement test This CL adds unit tests for the break statement. Change-Id: I78300ea6661e9c331795aedd344ac74c63dd8e25 Bug: tint:11 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16342 Reviewed-by: Sarah Mashayekhi Commit-Queue: Sarah Mashayekhi --- src/CMakeLists.txt | 1 + src/ast/break_statement.cc | 17 +++-- src/ast/break_statement.h | 3 + src/ast/break_statement_test.cc | 113 ++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 src/ast/break_statement_test.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a246ee2691..2a6a9be429 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,6 +198,7 @@ set(TINT_TEST_SRCS ast/assignment_statement_test.cc ast/binding_decoration_test.cc ast/bool_literal_test.cc + ast/break_statement_test.cc ast/builtin_decoration_test.cc ast/entry_point_test.cc ast/import_test.cc diff --git a/src/ast/break_statement.cc b/src/ast/break_statement.cc index a095e7df19..c3bcbe6100 100644 --- a/src/ast/break_statement.cc +++ b/src/ast/break_statement.cc @@ -17,6 +17,10 @@ namespace tint { namespace ast { +BreakStatement::BreakStatement() : Statement() {} + +BreakStatement::BreakStatement(const Source& source) : Statement(source) {} + BreakStatement::BreakStatement(StatementCondition condition, std::unique_ptr conditional) : Statement(), @@ -33,25 +37,26 @@ BreakStatement::BreakStatement(const Source& source, BreakStatement::~BreakStatement() = default; bool BreakStatement::IsValid() const { - return condition_ == StatementCondition::kNone || conditional_ != nullptr; + if (condition_ == StatementCondition::kNone) + return conditional_ == nullptr; + + return conditional_ != nullptr && conditional_->IsValid(); } void BreakStatement::to_str(std::ostream& out, size_t indent) const { make_indent(out, indent); - out << "Break"; + out << "Break{"; if (condition_ != StatementCondition::kNone) { - out << "{" << std::endl; + out << std::endl; make_indent(out, indent + 2); out << condition_ << std::endl; conditional_->to_str(out, indent + 2); make_indent(out, indent); - out << "}"; } - - out << std::endl; + out << "}" << std::endl; } } // namespace ast diff --git a/src/ast/break_statement.h b/src/ast/break_statement.h index 9795bd3551..aaa85267b0 100644 --- a/src/ast/break_statement.h +++ b/src/ast/break_statement.h @@ -31,6 +31,9 @@ class BreakStatement : public Statement { /// Constructor BreakStatement(); /// Constructor + /// @param source the initializer source + explicit BreakStatement(const Source& source); + /// Constructor /// @param condition the condition type /// @param conditional the condition expression BreakStatement(StatementCondition condition, diff --git a/src/ast/break_statement_test.cc b/src/ast/break_statement_test.cc new file mode 100644 index 0000000000..34305a11d3 --- /dev/null +++ b/src/ast/break_statement_test.cc @@ -0,0 +1,113 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/ast/break_statement.h" + +#include "gtest/gtest.h" +#include "src/ast/identifier_expression.h" +#include "src/ast/statement_condition.h" + +namespace tint { +namespace ast { + +using BreakStatementTest = testing::Test; + +TEST_F(BreakStatementTest, Creation) { + BreakStatement stmt; + EXPECT_EQ(stmt.condition(), StatementCondition::kNone); + EXPECT_EQ(stmt.conditional(), nullptr); +} + +TEST_F(BreakStatementTest, CreationWithConditional) { + auto expr = std::make_unique("expr"); + auto expr_ptr = expr.get(); + + BreakStatement stmt(StatementCondition::kIf, std::move(expr)); + EXPECT_EQ(stmt.condition(), StatementCondition::kIf); + EXPECT_EQ(stmt.conditional(), expr_ptr); +} + +TEST_F(BreakStatementTest, Creation_WithSource) { + BreakStatement stmt(Source{20, 2}); + auto src = stmt.source(); + EXPECT_EQ(src.line, 20); + EXPECT_EQ(src.column, 2); +} + +TEST_F(BreakStatementTest, Creation_WithSourceAndCondition) { + auto expr = std::make_unique("expr"); + + BreakStatement stmt(Source{20, 2}, StatementCondition::kUnless, + std::move(expr)); + auto src = stmt.source(); + EXPECT_EQ(src.line, 20); + EXPECT_EQ(src.column, 2); +} + +TEST_F(BreakStatementTest, IsBreak) { + BreakStatement stmt; + EXPECT_TRUE(stmt.IsBreak()); +} + +TEST_F(BreakStatementTest, IsValid_WithoutCondition) { + BreakStatement stmt; + EXPECT_TRUE(stmt.IsValid()); +} + +TEST_F(BreakStatementTest, IsValid_WithCondition) { + auto expr = std::make_unique("expr"); + BreakStatement stmt(StatementCondition::kIf, std::move(expr)); + EXPECT_TRUE(stmt.IsValid()); +} + +TEST_F(BreakStatementTest, IsValid_WithConditionAndConditionNone) { + auto expr = std::make_unique("expr"); + BreakStatement stmt(StatementCondition::kNone, std::move(expr)); + EXPECT_FALSE(stmt.IsValid()); +} + +TEST_F(BreakStatementTest, IsValid_WithCondition_MissingConditional) { + BreakStatement stmt; + stmt.set_condition(StatementCondition::kIf); + EXPECT_FALSE(stmt.IsValid()); +} + +TEST_F(BreakStatementTest, IsValid_InvalidConditional) { + auto expr = std::make_unique(""); + BreakStatement stmt(StatementCondition::kIf, std::move(expr)); + EXPECT_FALSE(stmt.IsValid()); +} + +TEST_F(BreakStatementTest, ToStr_WithoutCondition) { + BreakStatement stmt; + std::ostringstream out; + stmt.to_str(out, 2); + EXPECT_EQ(out.str(), R"( Break{} +)"); +} + +TEST_F(BreakStatementTest, ToStr_WithCondition) { + auto expr = std::make_unique("expr"); + BreakStatement stmt(StatementCondition::kUnless, std::move(expr)); + std::ostringstream out; + stmt.to_str(out, 2); + EXPECT_EQ(out.str(), R"( Break{ + unless + Identifier{expr} + } +)"); +} + +} // namespace ast +} // namespace tint