/* * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef TEST_NEAR_MATCHER_H_ #define TEST_NEAR_MATCHER_H_ #include #include "absl/strings/str_cat.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" namespace webrtc { template class NearMatcher { public: using is_gtest_matcher = void; NearMatcher(AbsoluteT expected, RelativeT max_error) : expected_(expected), max_error_(max_error) {} NearMatcher(const NearMatcher&) = default; NearMatcher& operator=(const NearMatcher&) = default; template bool MatchAndExplain(const T& value, std::ostream* os) const { AbsoluteT upper_bound = expected_ + max_error_; if (value >= upper_bound) { if (os != nullptr) { *os << " >= upper bound " << absl::StrCat(upper_bound); } return false; } if constexpr (std::is_same_v) { if (expected_ - AbsoluteT::Zero() < max_error_) { // Avoid negative `expected_ - max_error_`. bool in_range = value >= AbsoluteT::Zero(); if (os != nullptr) { if (in_range) { *os << " in range [" << absl::StrCat(AbsoluteT::Zero()) << "," << absl::StrCat(upper_bound) << ")"; } else { *os << " < lower bound " << absl::StrCat(AbsoluteT::Zero()); } } return in_range; } } AbsoluteT lower_bound = expected_ - max_error_; bool in_range = value > lower_bound; if (os != nullptr) { if (in_range) { *os << " in range (" << absl::StrCat(lower_bound) << "," << absl::StrCat(upper_bound) << ")"; } else { *os << " <= lower bound " << absl::StrCat(lower_bound); } } return in_range; } void DescribeTo(std::ostream* os) const { *os << "is approximately " << absl::StrCat(expected_) << " (absolute error < " << absl::StrCat(max_error_) << ")"; } void DescribeNegationTo(std::ostream* os) const { *os << "isn't approximately " << absl::StrCat(expected_) << " (absolute error >= " << absl::StrCat(max_error_) << ")"; } private: AbsoluteT expected_; RelativeT max_error_; }; // Generic 'Near' matcher template NearMatcher Near(AbsoluteT expected, RelativeT max_error) { return NearMatcher(expected, max_error); } // Specialization of 'Near' matcher for time types with default margin of 1ms. template requires(std::is_same_v || std::is_same_v) NearMatcher Near(T expected) { return Near(expected, /*max_error=*/TimeDelta::Millis(1)); } } // namespace webrtc #endif // TEST_NEAR_MATCHER_H_