From ab0cdaf652d355b770dd2b19a2fe2d48a50a58c8 Mon Sep 17 00:00:00 2001 From: David Neto Date: Tue, 10 Mar 2020 22:54:46 +0000 Subject: [PATCH] Add a FailStream error reporting helper Bug: tint:3 Change-Id: Ie0bb2365a7dd6b2a5e9d0960593fac7586b02922 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16640 Reviewed-by: dan sinclair --- src/CMakeLists.txt | 1 + src/reader/spv/fail_stream.h | 74 +++++++++++++++++++++++++++++ src/reader/spv/fail_stream_test.cc | 76 ++++++++++++++++++++++++++++++ src/reader/spv/parser_test.cc | 3 ++ 4 files changed, 154 insertions(+) create mode 100644 src/reader/spv/fail_stream.h create mode 100644 src/reader/spv/fail_stream_test.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a949180c97..b357bf3a3f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -312,6 +312,7 @@ endif() if(${TINT_BUILD_SPV_PARSER}) list (APPEND TINT_TEST_SRCS + reader/spv/fail_stream_test.cc reader/spv/parser_test.cc ) endif() diff --git a/src/reader/spv/fail_stream.h b/src/reader/spv/fail_stream.h new file mode 100644 index 0000000000..b9c4f370c8 --- /dev/null +++ b/src/reader/spv/fail_stream.h @@ -0,0 +1,74 @@ +// Copyright 2020 Google LLC +// +// 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. + +#ifndef SRC_READER_SPV_FAIL_STREAM_H_ +#define SRC_READER_SPV_FAIL_STREAM_H_ + +#include + +namespace tint { +namespace reader { +namespace spv { + +/// A FailStream object accumulates values onto a given std::ostream, +/// and can be used to record failure by writing the false value +/// to given a pointer-to-bool. +class FailStream { + public: + /// Creates a new fail stream + /// @param status_ptr where we will write false to indicate failure. Assumed + /// to be a valid pointer to bool. + /// @param out output stream where a message should be written to explain + /// the failure + FailStream(bool* status_ptr, std::ostream* out) + : status_ptr_(status_ptr), out_(out) {} + /// Copy constructor + /// @param other the fail stream to clone + FailStream(const FailStream& other) = default; + + /// Converts to a boolean status. A true result indicates success, + /// and a false result indicates failure. + /// @returns status + operator bool() const { return *status_ptr_; } + /// Returns the current status value. This can be more readable + /// the conversion operator. + /// @returns status + bool status() const { return *status_ptr_; } + + /// Records failure. + /// @returns a FailStream + FailStream& Fail() { + *status_ptr_ = false; + return *this; + } + + /// Appends the given value to the message output stream. + /// @param val the value to write to the output stream. + /// @returns this object + template + FailStream& operator<<(const T& val) { + *out_ << val; + return *this; + } + + private: + bool* status_ptr_; + std::ostream* out_; +}; + +} // namespace spv +} // namespace reader +} // namespace tint + +#endif // SRC_READER_SPV_FAIL_STREAM_H_ diff --git a/src/reader/spv/fail_stream_test.cc b/src/reader/spv/fail_stream_test.cc new file mode 100644 index 0000000000..394dc2c889 --- /dev/null +++ b/src/reader/spv/fail_stream_test.cc @@ -0,0 +1,76 @@ +// 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/reader/spv/fail_stream.h" + +#include +#include + +#include "gmock/gmock.h" + +namespace tint { +namespace reader { +namespace spv { +namespace { + +using ::testing::Eq; + +using FailStreamTest = ::testing::Test; + +TEST_F(FailStreamTest, ConversionToBoolIsSameAsStatusMethod) { + bool flag = true; + FailStream fs(&flag, nullptr); + + EXPECT_TRUE(fs.status()); + EXPECT_TRUE(bool(fs)); + flag = false; + EXPECT_FALSE(fs.status()); + EXPECT_FALSE(bool(fs)); + flag = true; + EXPECT_TRUE(fs.status()); + EXPECT_TRUE(bool(fs)); +} + +TEST_F(FailStreamTest, FailMethodChangesStatusToFalse) { + bool flag = true; + FailStream fs(&flag, nullptr); + EXPECT_TRUE(flag); + EXPECT_TRUE(bool(fs)); + fs.Fail(); + EXPECT_FALSE(flag); + EXPECT_FALSE(bool(fs)); +} + +TEST_F(FailStreamTest, FailMethodReturnsSelf) { + bool flag = true; + FailStream fs(&flag, nullptr); + FailStream& result = fs.Fail(); + EXPECT_THAT(&result, Eq(&fs)); +} + +TEST_F(FailStreamTest, ShiftOperatorAccumulatesValues) { + bool flag = true; + std::stringstream ss; + FailStream fs(&flag, &ss); + + ss << "prefix "; + fs << "cat " << 42; + + EXPECT_THAT(ss.str(), Eq("prefix cat 42")); +} + +} // namespace +} // namespace spv +} // namespace reader +} // namespace tint diff --git a/src/reader/spv/parser_test.cc b/src/reader/spv/parser_test.cc index c32a20c541..717034b9d9 100644 --- a/src/reader/spv/parser_test.cc +++ b/src/reader/spv/parser_test.cc @@ -24,6 +24,7 @@ namespace tint { namespace reader { namespace spv { +namespace { using ParserTest = testing::Test; TEST_F(ParserTest, Uint32VecEmpty) { @@ -36,6 +37,8 @@ TEST_F(ParserTest, Uint32VecEmpty) { // TODO(dneto): uint32 vec, valid SPIR-V // TODO(dneto): uint32 vec, invalid SPIR-V +} // namespace + } // namespace spv } // namespace reader } // namespace tint