diff options
Diffstat (limited to 'ink_stroke_modeler/params_test.cc')
-rw-r--r-- | ink_stroke_modeler/params_test.cc | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/ink_stroke_modeler/params_test.cc b/ink_stroke_modeler/params_test.cc new file mode 100644 index 0000000..1f53aa8 --- /dev/null +++ b/ink_stroke_modeler/params_test.cc @@ -0,0 +1,258 @@ +// Copyright 2022 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. + +#include "ink_stroke_modeler/params.h" + +#include <limits> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/status/status.h" + +namespace ink { +namespace stroke_model { +namespace { + +const KalmanPredictorParams kGoodKalmanParams{ + .process_noise = .01, + .measurement_noise = .1, + .min_stable_iteration = 2, + .max_time_samples = 10, + .min_catchup_velocity = 1, + .acceleration_weight = -1, + .jerk_weight = 200, + .prediction_interval{1}, + .confidence_params{.desired_number_of_samples = 10, + .max_estimation_distance = 1, + .min_travel_speed = 6, + .max_travel_speed = 50, + .max_linear_deviation = 2, + .baseline_linearity_confidence = .5}}; + +const StrokeModelParams kGoodStrokeModelParams{ + .wobble_smoother_params{ + .timeout{.5}, .speed_floor = 1, .speed_ceiling = 20}, + .position_modeler_params{.spring_mass_constant = .2, .drag_constant = 4}, + .sampling_params{.min_output_rate = 3, + .end_of_stroke_stopping_distance = 1e-6, + .end_of_stroke_max_iterations = 1}, + .stylus_state_modeler_params{.max_input_samples = 7}, + .prediction_params = StrokeEndPredictorParams{}}; + +TEST(ParamsTest, ValidatePositionModelerParams) { + EXPECT_TRUE(ValidatePositionModelerParams( + {.spring_mass_constant = 1, .drag_constant = 3}) + .ok()); + + EXPECT_EQ(ValidatePositionModelerParams( + {.spring_mass_constant = 0, .drag_constant = 1}) + .code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(ValidatePositionModelerParams( + {.spring_mass_constant = 1, .drag_constant = 0}) + .code(), + absl::StatusCode::kInvalidArgument); +} + +TEST(ParamsTest, ValidateSamplingParams) { + EXPECT_TRUE(ValidateSamplingParams({.min_output_rate = 10, + .end_of_stroke_stopping_distance = .1, + .end_of_stroke_max_iterations = 3}) + .ok()); + + EXPECT_EQ(ValidateSamplingParams({.min_output_rate = 0, + .end_of_stroke_stopping_distance = .1, + .end_of_stroke_max_iterations = 3}) + .code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(ValidateSamplingParams({.min_output_rate = 1, + .end_of_stroke_stopping_distance = 0, + .end_of_stroke_max_iterations = 3}) + .code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(ValidateSamplingParams({.min_output_rate = 1, + .end_of_stroke_stopping_distance = 5, + .end_of_stroke_max_iterations = 0}) + .code(), + absl::StatusCode::kInvalidArgument); +} + +TEST(ParamsTest, ValidateStylusStateModelerParams) { + EXPECT_TRUE(ValidateStylusStateModelerParams({.max_input_samples = 1}).ok()); + + EXPECT_EQ(ValidateStylusStateModelerParams({.max_input_samples = 0}).code(), + absl::StatusCode::kInvalidArgument); +} + +TEST(ParamsTest, ValidateWobbleSmootherParams) { + EXPECT_TRUE(ValidateWobbleSmootherParams( + {.timeout{1}, .speed_floor = 2, .speed_ceiling = 3}) + .ok()); + EXPECT_TRUE(ValidateWobbleSmootherParams( + {.timeout{0}, .speed_floor = 0, .speed_ceiling = 0}) + .ok()); + + EXPECT_EQ(ValidateWobbleSmootherParams( + {.timeout{-1}, .speed_floor = 2, .speed_ceiling = 5}) + .code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(ValidateWobbleSmootherParams( + {.timeout{1}, .speed_floor = -2, .speed_ceiling = 1}) + .code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(ValidateWobbleSmootherParams( + {.timeout{1}, .speed_floor = 7, .speed_ceiling = 4}) + .code(), + absl::StatusCode::kInvalidArgument); +} + +TEST(ParamsTest, ValidateStrokeEndPredictorParams) { + EXPECT_TRUE(ValidatePredictionParams(StrokeEndPredictorParams()).ok()); +} + +TEST(ParamsTest, ValidateKalmanPredictorParams) { + EXPECT_TRUE(ValidatePredictionParams(kGoodKalmanParams).ok()); + { + auto bad_params = kGoodKalmanParams; + bad_params.process_noise = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.measurement_noise = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.min_stable_iteration = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.max_time_samples = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.prediction_interval = Duration(0); + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } +} + +TEST(ParamsTest, ValidateKalmanPredictorConfidenceParams) { + EXPECT_TRUE(ValidatePredictionParams(kGoodKalmanParams).ok()); + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.desired_number_of_samples = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.max_estimation_distance = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.min_travel_speed = -1; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.min_travel_speed = 10; + bad_params.confidence_params.max_travel_speed = 1; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.max_linear_deviation = 0; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.baseline_linearity_confidence = -.3; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodKalmanParams; + bad_params.confidence_params.baseline_linearity_confidence = 1.01; + EXPECT_EQ(ValidatePredictionParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } +} + +TEST(ParamsTest, ValidateStrokeModelParams) { + EXPECT_TRUE(ValidateStrokeModelParams(kGoodStrokeModelParams).ok()); + { + auto bad_params = kGoodStrokeModelParams; + bad_params.wobble_smoother_params.timeout = Duration(-10); + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodStrokeModelParams; + bad_params.position_modeler_params.spring_mass_constant = -1; + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodStrokeModelParams; + bad_params.stylus_state_modeler_params.max_input_samples = 0; + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodStrokeModelParams; + bad_params.sampling_params.end_of_stroke_max_iterations = -3; + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } + { + auto bad_params = kGoodStrokeModelParams; + bad_params.prediction_params = + KalmanPredictorParams{.prediction_interval{-1}}; + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); + } +} + +TEST(ParamsTest, NaNIsNotAValidValue) { + auto bad_params = kGoodStrokeModelParams; + bad_params.position_modeler_params.spring_mass_constant = + std::numeric_limits<float>::quiet_NaN(); + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); +} + +TEST(ParamsTest, InfinityIsNotAValidValue) { + auto bad_params = kGoodStrokeModelParams; + bad_params.position_modeler_params.spring_mass_constant = + std::numeric_limits<float>::infinity(); + EXPECT_EQ(ValidateStrokeModelParams(bad_params).code(), + absl::StatusCode::kInvalidArgument); +} + +} // namespace +} // namespace stroke_model +} // namespace ink |