Add a DistanceFrom() matcher for general distance comparison.

We have a bunch of matchers for asserting that a value is near the target value, e.g.
`DoubleNear()` and `FloatNear()`. These matchers only work for specific types (`double` and `float`). They are not flexible enough to support other types that have the notion of a "distance" (e.g. N-dimensional points and vectors, which are commonly used in ML).

In this diff, we generalize the idea to a `DistanceFrom(target, get_distance, m)` matcher that works on arbitrary types that have the "distance" concept (the `get_distance` argument is optional and can be omitted for types that support `-`, and `std::abs()`). What it does:

1. compute the distance between the value and the target using `get_distance(value, target)`; if `get_distance` is omitted, compute the distance as `std::abs(value - target)`.
2. match the distance against matcher `m`; if the match succeeds, the `DistanceFrom()` match succeeds.

Examples:

```
  // 0.5's distance from 0.6 should be <= 0.2.
  EXPECT_THAT(0.5, DistanceFrom(0.6, Le(0.2)));

  Vector2D v1(3.0, 4.0), v2(3.2, 6.0);
  // v1's distance from v2, as computed by EuclideanDistance(v1, v2),
  // should be >= 1.0.
  EXPECT_THAT(v1, DistanceFrom(v2, EuclideanDistance, Ge(1.0)));
```

PiperOrigin-RevId: 734593292
Change-Id: Id6bb7074dc4aa4d8abd78b57ad2426637e590de5
This commit is contained in:
Zhanyong Wan
2025-03-07 09:54:00 -08:00
committed by Copybara-Service
parent e88cb95b92
commit 0bdccf4aa2
3 changed files with 276 additions and 0 deletions
+2
View File
@@ -42,6 +42,8 @@ Matcher | Description
| `Lt(value)` | `argument < value` |
| `Ne(value)` | `argument != value` |
| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. |
| `DistanceFrom(target, m)` | The distance between `argument` and `target` (computed by `std::abs(argument - target)`) matches `m`. |
| `DistanceFrom(target, get_distance, m)` | The distance between `argument` and `target` (computed by `get_distance(argument, target)`) matches `m`. |
| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. |
| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). |
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |