From 0a7834f117ae624c25af269aec20fdc7ddf738da Mon Sep 17 00:00:00 2001 From: Samuel Freilich Date: Tue, 22 Mar 2022 11:07:54 -0700 Subject: Factor out validation utility functions into separate target And add unit tests. PiperOrigin-RevId: 436519937 --- ink_stroke_modeler/BUILD.bazel | 1 + ink_stroke_modeler/CMakeLists.txt | 1 + ink_stroke_modeler/internal/BUILD.bazel | 18 ++++++ ink_stroke_modeler/internal/CMakeLists.txt | 20 +++++++ ink_stroke_modeler/internal/validation.h | 48 +++++++++++++++ ink_stroke_modeler/internal/validation_test.cc | 82 ++++++++++++++++++++++++++ ink_stroke_modeler/params.cc | 40 +------------ 7 files changed, 171 insertions(+), 39 deletions(-) create mode 100644 ink_stroke_modeler/internal/validation.h create mode 100644 ink_stroke_modeler/internal/validation_test.cc diff --git a/ink_stroke_modeler/BUILD.bazel b/ink_stroke_modeler/BUILD.bazel index f0c00c1..68b9849 100644 --- a/ink_stroke_modeler/BUILD.bazel +++ b/ink_stroke_modeler/BUILD.bazel @@ -23,6 +23,7 @@ cc_library( visibility = ["//visibility:public"], deps = [ ":types", + "//ink_stroke_modeler/internal:validation", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:variant", diff --git a/ink_stroke_modeler/CMakeLists.txt b/ink_stroke_modeler/CMakeLists.txt index b31e9c7..2d02271 100644 --- a/ink_stroke_modeler/CMakeLists.txt +++ b/ink_stroke_modeler/CMakeLists.txt @@ -26,6 +26,7 @@ ink_cc_library( absl::status absl::strings absl::variant + InkStrokeModeler::validation ) ink_cc_test( diff --git a/ink_stroke_modeler/internal/BUILD.bazel b/ink_stroke_modeler/internal/BUILD.bazel index bf76f70..f4e1d98 100644 --- a/ink_stroke_modeler/internal/BUILD.bazel +++ b/ink_stroke_modeler/internal/BUILD.bazel @@ -123,3 +123,21 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_library( + name = "validation", + hdrs = ["validation.h"], + deps = [ + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + ], +) + +cc_test( + name = "validaiton_test", + srcs = ["validation_test.cc"], + deps = [ + ":validation", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/ink_stroke_modeler/internal/CMakeLists.txt b/ink_stroke_modeler/internal/CMakeLists.txt index b2f04c1..12e2ba8 100644 --- a/ink_stroke_modeler/internal/CMakeLists.txt +++ b/ink_stroke_modeler/internal/CMakeLists.txt @@ -134,3 +134,23 @@ ink_cc_test( InkStrokeModeler::types GTest::gmock_main ) + +ink_cc_library( + NAME + validation + HDRS + validation.h + DEPS + absl::status + absl::strings +) + +ink_cc_test( + NAME + validation_test + SRCS + validation_test.cc + DEPS + InkStrokeModeler::validation + GTest::gtest_main +) diff --git a/ink_stroke_modeler/internal/validation.h b/ink_stroke_modeler/internal/validation.h new file mode 100644 index 0000000..e01aa1a --- /dev/null +++ b/ink_stroke_modeler/internal/validation.h @@ -0,0 +1,48 @@ +#ifndef INK_STROKE_MODELER_INTERNAL_VALIDATION_H_ +#define INK_STROKE_MODELER_INTERNAL_VALIDATION_H_ + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "absl/strings/substitute.h" + +template +absl::Status ValidateIsFiniteNumber(T value, absl::string_view label) { + if (std::isnan(value)) { + return absl::InvalidArgumentError(absl::Substitute("$0 is NaN", label)); + } + if (std::isinf(value)) { + return absl::InvalidArgumentError( + absl::Substitute("$0 is infinite", label)); + } + return absl::OkStatus(); +} + +template +absl::Status ValidateGreaterThanZero(T value, absl::string_view label) { + if (absl::Status status = ValidateIsFiniteNumber(value, label); + !status.ok()) { + return status; + } + if (value <= 0) { + return absl::InvalidArgumentError(absl::Substitute( + "$0 must be greater than zero. Actual value: $1", label, value)); + } + return absl::OkStatus(); +} + +template +absl::Status ValidateGreaterThanOrEqualToZero(T value, + absl::string_view label) { + if (absl::Status status = ValidateIsFiniteNumber(value, label); + !status.ok()) { + return status; + } + if (value < 0) { + return absl::InvalidArgumentError(absl::Substitute( + "$0 must be greater than or equal to zero. Actual value: $1", label, + value)); + } + return absl::OkStatus(); +} + +#endif // INK_STROKE_MODELER_INTERNAL_VALIDATION_H_ diff --git a/ink_stroke_modeler/internal/validation_test.cc b/ink_stroke_modeler/internal/validation_test.cc new file mode 100644 index 0000000..51482ff --- /dev/null +++ b/ink_stroke_modeler/internal/validation_test.cc @@ -0,0 +1,82 @@ +#include "ink_stroke_modeler/internal/validation.h" + +#include + +#include "gtest/gtest.h" + +namespace { + +TEST(ValidateIsFiniteNumberTest, AcceptFinite) { + ASSERT_TRUE(ValidateIsFiniteNumber(1, "foo").ok()); +} + +TEST(ValidateIsFiniteNumberTest, RejectNan) { + absl::Status status = ValidateIsFiniteNumber(NAN, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo is NaN"); +} + +TEST(ValidateIsFiniteNumberTest, RejectInf) { + absl::Status status = ValidateIsFiniteNumber(INFINITY, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo is infinite"); +} + +TEST(ValidateGreaterThanZeroTest, AcceptPositive) { + ASSERT_TRUE(ValidateGreaterThanZero(1, "foo").ok()); +} + +TEST(ValidateGreaterThanZeroTest, RejectZero) { + absl::Status status = ValidateGreaterThanZero(0, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo must be greater than zero. Actual value: 0"); +} + +TEST(ValidateGreaterThanZeroTest, RejectNegative) { + absl::Status status = ValidateGreaterThanZero(-1, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), + "foo must be greater than zero. Actual value: -1"); +} + +TEST(ValidateGreaterThanZeroTest, RejectNan) { + absl::Status status = ValidateGreaterThanZero(NAN, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo is NaN"); +} + +TEST(ValidateGreaterThanZeroTest, RejectInf) { + absl::Status status = ValidateGreaterThanZero(INFINITY, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo is infinite"); +} + +TEST(ValidateGreaterThanOrEqualToZeroTest, AcceptPositive) { + ASSERT_TRUE(ValidateGreaterThanOrEqualToZero(1, "foo").ok()); +} + +TEST(ValidateGreaterThanOrEqualToZeroTest, AcceptZero) { + absl::Status status = ValidateGreaterThanOrEqualToZero(0, "foo"); + ASSERT_TRUE(ValidateGreaterThanOrEqualToZero(0, "foo").ok()); +} + +TEST(ValidateGreaterThanOrEqualToZeroTest, RejectNegative) { + absl::Status status = ValidateGreaterThanOrEqualToZero(-1, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), + "foo must be greater than or equal to zero. Actual value: -1"); +} + +TEST(ValidateGreaterThanOrEqualToZeroTest, RejectNan) { + absl::Status status = ValidateGreaterThanOrEqualToZero(NAN, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo is NaN"); +} + +TEST(ValidateGreaterThanOrEqualToZeroTest, RejectInf) { + absl::Status status = ValidateGreaterThanOrEqualToZero(INFINITY, "foo"); + ASSERT_FALSE(status.ok()); + ASSERT_EQ(status.message(), "foo is infinite"); +} + +} // namespace diff --git a/ink_stroke_modeler/params.cc b/ink_stroke_modeler/params.cc index 927ba5d..99542e1 100644 --- a/ink_stroke_modeler/params.cc +++ b/ink_stroke_modeler/params.cc @@ -20,6 +20,7 @@ #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "absl/types/variant.h" +#include "ink_stroke_modeler/internal/validation.h" // This convenience macro evaluates the given expression, and if it does not // return an OK status, returns and propagates the status. @@ -30,45 +31,6 @@ namespace ink { namespace stroke_model { -namespace { - -// Some helper functions for validating values. - -template -absl::Status ValidateIsFiniteNumber(T value, absl::string_view label) { - if (std::isnan(value)) { - return absl::InvalidArgumentError(absl::Substitute("$0 is NaN", label)); - } - if (std::isinf(value)) { - return absl::InvalidArgumentError( - absl::Substitute("$0 is infinite", label)); - } - return absl::OkStatus(); -} - -template -absl::Status ValidateGreaterThanZero(T value, absl::string_view label) { - RETURN_IF_ERROR(ValidateIsFiniteNumber(value, label)); - if (value <= 0) { - return absl::InvalidArgumentError(absl::Substitute( - "$0 must be greater than zero. Actual value: $1", label, value)); - } - return absl::OkStatus(); -} - -template -absl::Status ValidateGreaterThanOrEqualToZero(T value, - absl::string_view label) { - RETURN_IF_ERROR(ValidateIsFiniteNumber(value, label)); - if (value < 0) { - return absl::InvalidArgumentError(absl::Substitute( - "$0 must be greater than or equal to zero. Actual value: $1", label, - value)); - } - return absl::OkStatus(); -} - -} // namespace absl::Status ValidatePositionModelerParams( const PositionModelerParams& params) { -- cgit v1.2.3