From 5ced2178a604511e01ff1b9afff649126c0b72a0 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 17 Mar 2020 03:54:07 +0000 Subject: [PATCH] Add TypeInitializerExpression tests This CL adds unit tests for the TypeInitializerExpression AST element. Bug: tint:11 Change-Id: I92790563c995038cc5a09afd03e84496b8f41487 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16672 Reviewed-by: Sarah Mashayekhi --- src/CMakeLists.txt | 1 + src/ast/type_initializer_expression.cc | 16 ++- src/ast/type_initializer_expression.h | 3 +- src/ast/type_initializer_expression_test.cc | 123 ++++++++++++++++++++ 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/ast/type_initializer_expression_test.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e97f9aaafc..4be66dac44 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -243,6 +243,7 @@ set(TINT_TEST_SRCS ast/type/struct_type_test.cc ast/type/u32_type_test.cc ast/type/vector_type_test.cc + ast/type_initializer_expression_test.cc ast/uint_literal_test.cc ast/variable_test.cc reader/wgsl/lexer_test.cc diff --git a/src/ast/type_initializer_expression.cc b/src/ast/type_initializer_expression.cc index 0b092f3e54..5b47387f16 100644 --- a/src/ast/type_initializer_expression.cc +++ b/src/ast/type_initializer_expression.cc @@ -17,6 +17,9 @@ namespace tint { namespace ast { +TypeInitializerExpression::TypeInitializerExpression() + : InitializerExpression() {} + TypeInitializerExpression::TypeInitializerExpression( type::Type* type, std::vector> values) @@ -31,7 +34,18 @@ TypeInitializerExpression::TypeInitializerExpression( TypeInitializerExpression::~TypeInitializerExpression() = default; bool TypeInitializerExpression::IsValid() const { - return values_.size() > 0; + if (values_.empty()) { + return false; + } + if (type_ == nullptr) { + return false; + } + for (const auto& val : values_) { + if (val == nullptr || !val->IsValid()) { + return false; + } + } + return true; } void TypeInitializerExpression::to_str(std::ostream& out, size_t indent) const { diff --git a/src/ast/type_initializer_expression.h b/src/ast/type_initializer_expression.h index 9b7af2f54f..118eac4fe4 100644 --- a/src/ast/type_initializer_expression.h +++ b/src/ast/type_initializer_expression.h @@ -28,6 +28,7 @@ namespace ast { /// A type specific initializer class TypeInitializerExpression : public InitializerExpression { public: + TypeInitializerExpression(); /// Constructor /// @param type the type /// @param values the values @@ -75,7 +76,7 @@ class TypeInitializerExpression : public InitializerExpression { private: TypeInitializerExpression(const TypeInitializerExpression&) = delete; - type::Type* type_; + type::Type* type_ = nullptr; std::vector> values_; }; diff --git a/src/ast/type_initializer_expression_test.cc b/src/ast/type_initializer_expression_test.cc new file mode 100644 index 0000000000..96b8c30d03 --- /dev/null +++ b/src/ast/type_initializer_expression_test.cc @@ -0,0 +1,123 @@ +// 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/type_initializer_expression.h" + +#include + +#include "gtest/gtest.h" +#include "src/ast/identifier_expression.h" +#include "src/ast/type/f32_type.h" +#include "src/ast/type/vector_type.h" + +namespace tint { +namespace ast { + +using TypeInitializerExpressionTest = testing::Test; + +TEST_F(TypeInitializerExpressionTest, Creation) { + type::F32Type f32; + std::vector> expr; + expr.push_back(std::make_unique("expr")); + auto expr_ptr = expr[0].get(); + + TypeInitializerExpression t(&f32, std::move(expr)); + EXPECT_EQ(t.type(), &f32); + ASSERT_EQ(t.values().size(), 1); + EXPECT_EQ(t.values()[0].get(), expr_ptr); +} + +TEST_F(TypeInitializerExpressionTest, Creation_WithSource) { + type::F32Type f32; + std::vector> expr; + expr.push_back(std::make_unique("expr")); + + TypeInitializerExpression t(Source{20, 2}, &f32, std::move(expr)); + auto src = t.source(); + EXPECT_EQ(src.line, 20); + EXPECT_EQ(src.column, 2); +} + +TEST_F(TypeInitializerExpressionTest, IsTypeInitializer) { + TypeInitializerExpression t; + EXPECT_TRUE(t.IsTypeInitializer()); +} + +TEST_F(TypeInitializerExpressionTest, IsValid) { + type::F32Type f32; + std::vector> expr; + expr.push_back(std::make_unique("expr")); + + TypeInitializerExpression t(&f32, std::move(expr)); + EXPECT_TRUE(t.IsValid()); +} + +TEST_F(TypeInitializerExpressionTest, IsValid_NullType) { + std::vector> expr; + expr.push_back(std::make_unique("expr")); + + TypeInitializerExpression t; + t.set_values(std::move(expr)); + EXPECT_FALSE(t.IsValid()); +} + +TEST_F(TypeInitializerExpressionTest, IsValid_NullValue) { + type::F32Type f32; + std::vector> expr; + expr.push_back(std::make_unique("expr")); + expr.push_back(nullptr); + + TypeInitializerExpression t(&f32, std::move(expr)); + EXPECT_FALSE(t.IsValid()); +} + +TEST_F(TypeInitializerExpressionTest, IsValid_InvalidValue) { + type::F32Type f32; + std::vector> expr; + expr.push_back(std::make_unique("")); + + TypeInitializerExpression t(&f32, std::move(expr)); + EXPECT_FALSE(t.IsValid()); +} + +TEST_F(TypeInitializerExpressionTest, IsValid_EmptyValue) { + type::F32Type f32; + std::vector> expr; + + TypeInitializerExpression t(&f32, std::move(expr)); + EXPECT_FALSE(t.IsValid()); +} + +TEST_F(TypeInitializerExpressionTest, ToStr) { + type::F32Type f32; + type::VectorType vec(&f32, 3); + std::vector> expr; + expr.push_back(std::make_unique("expr_1")); + expr.push_back(std::make_unique("expr_2")); + expr.push_back(std::make_unique("expr_3")); + + TypeInitializerExpression t(&vec, std::move(expr)); + std::ostringstream out; + t.to_str(out, 2); + EXPECT_EQ(out.str(), R"( TypeInitializer{ + __vec_3__f32 + Identifier{expr_1} + Identifier{expr_2} + Identifier{expr_3} + } +)"); +} + +} // namespace ast +} // namespace tint