Skip to content

Commit 2108291

Browse files
satylogincopybara-github
authored andcommitted
float_eq family of assertions
PiperOrigin-RevId: 652899702
1 parent 01e054f commit 2108291

8 files changed

+267
-4
lines changed

googletest/src/assertions.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,101 @@ macro_rules! expect_ge {
10461046
}};
10471047
}
10481048

1049+
/// Checks whether the float given by first argument is approximately
1050+
/// equal to second argument.
1051+
///
1052+
/// This automatically computes a tolerance from the magnitude of `expected` and
1053+
/// matches any actual value within this tolerance of the expected value. The
1054+
/// tolerance is chosen to account for the inaccuracies in most ordinary
1055+
/// floating point calculations. To see details of how the tolerance is
1056+
/// calculated look at the implementation of
1057+
/// [`googletest::approx_eq`][crate::matchers::approx_eq].
1058+
///
1059+
/// Evaluates to `Result::Ok(())` if the first argument is approximately equal
1060+
/// to the second and `Result::Err(TestAssertionFailure)` if it is not. The
1061+
/// caller must then decide how to handle the `Err` variant. It has a few
1062+
/// options:
1063+
/// * Abort the current function with the `?` operator. This requires that the
1064+
/// function return a suitable `Result`.
1065+
/// * Log the test failure and continue by calling the method
1066+
/// `and_log_failure`.
1067+
///
1068+
/// Of course, one can also use all other standard methods on `Result`.
1069+
///
1070+
/// **Invoking this macro by itself does not cause a test failure to be recorded
1071+
/// or output.** The resulting `Result` must be handled as described above to
1072+
/// cause the test to be recorded as a failure.
1073+
///
1074+
/// Example:
1075+
/// ```ignore
1076+
/// use googletest::prelude::*;
1077+
///
1078+
/// #[test]
1079+
/// fn should_fail() -> Result<()> {
1080+
/// verify_float_eq!(1.0, 2.0)
1081+
/// }
1082+
/// ```
1083+
#[macro_export]
1084+
macro_rules! verify_float_eq {
1085+
($actual:expr, $expected:expr $(,)?) => {
1086+
verify_that!($actual, $crate::matchers::approx_eq($expected))
1087+
};
1088+
}
1089+
1090+
/// Marks test as failed and continues execution if the float given by the first
1091+
/// argument is not approximately equal to the float given by the second
1092+
/// argument.
1093+
///
1094+
/// This automatically computes a tolerance from the magnitude of `expected` and
1095+
/// matches any actual value within this tolerance of the expected value. The
1096+
/// tolerance is chosen to account for the inaccuracies in most ordinary
1097+
/// floating point calculations. To see details of how the tolerance is
1098+
/// calculated look at the implementation of
1099+
/// [`googletest::approx_eq`][crate::matchers::approx_eq].
1100+
///
1101+
/// This is a **not-fatal** failure. The test continues execution even after the
1102+
/// macro execution.
1103+
///
1104+
/// This can only be invoked inside tests with the
1105+
/// [`googletest::test`][crate::test] attribute. The failure must be generated
1106+
/// in the same thread as that running the test itself.
1107+
///
1108+
/// Example:
1109+
/// ```ignore
1110+
/// use googletest::prelude::*;
1111+
///
1112+
/// #[googletest::test]
1113+
/// fn should_fail() {
1114+
/// expect_float_eq!(1.0, 2.0);
1115+
/// println!("This will print!");
1116+
/// }
1117+
/// ```
1118+
///
1119+
/// One may include formatted arguments in the failure message:
1120+
///```ignore
1121+
/// use googletest::prelude::*;
1122+
///
1123+
/// #[googletest::test]
1124+
/// fn should_fail() {
1125+
/// let argument = "argument"
1126+
/// expect_float_eq!(1.0, 2.0, "custom failure message: {argument}");
1127+
/// println!("This will print!");
1128+
/// }
1129+
/// ```
1130+
#[macro_export]
1131+
macro_rules! expect_float_eq {
1132+
($actual:expr, $expected:expr, $($format_args:expr),+ $(,)?) => {{
1133+
use $crate::GoogleTestSupport;
1134+
verify_float_eq!($actual, $expected)
1135+
.with_failure_message(|| format!($($format_args),*))
1136+
.and_log_failure();
1137+
}};
1138+
($actual:expr, $expected:expr $(,)?) => {{
1139+
use $crate::GoogleTestSupport;
1140+
verify_float_eq!($actual, $expected).and_log_failure();
1141+
}};
1142+
}
1143+
10491144
/// Matches the given value against the given matcher, panicking if it does not
10501145
/// match.
10511146
///

googletest/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ pub mod prelude {
5050
pub use super::Result;
5151
// Assert macros
5252
pub use super::{
53-
add_failure, add_failure_at, assert_that, expect_eq, expect_false, expect_ge, expect_gt,
54-
expect_le, expect_lt, expect_ne, expect_pred, expect_that, expect_true, fail, succeed,
55-
verify_eq, verify_false, verify_ge, verify_gt, verify_le, verify_lt, verify_ne,
56-
verify_pred, verify_that, verify_true,
53+
add_failure, add_failure_at, assert_that, expect_eq, expect_false, expect_float_eq,
54+
expect_ge, expect_gt, expect_le, expect_lt, expect_ne, expect_pred, expect_that,
55+
expect_true, fail, succeed, verify_eq, verify_false, verify_float_eq, verify_ge, verify_gt,
56+
verify_le, verify_lt, verify_ne, verify_pred, verify_that, verify_true,
5757
};
5858
}
5959

integration_tests/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,21 @@ name = "expect_ge_supports_custom_message"
290290
path = "src/expect_ge_supports_custom_message.rs"
291291
test = false
292292

293+
[[bin]]
294+
name = "verify_float_eq_when_not_equal_returns_error"
295+
path = "src/verify_float_eq_when_not_equal_returns_error.rs"
296+
test = false
297+
298+
[[bin]]
299+
name = "expect_float_eq_when_not_equal_marks_failed"
300+
path = "src/expect_float_eq_when_not_equal_marks_failed.rs"
301+
test = false
302+
303+
[[bin]]
304+
name = "expect_float_eq_supports_custom_message"
305+
path = "src/expect_float_eq_supports_custom_message.rs"
306+
test = false
307+
293308
[[bin]]
294309
name = "failure_due_to_returned_error_with_line_numbers"
295310
path = "src/failure_due_to_returned_error_with_line_numbers.rs"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
fn main() {}
15+
#[cfg(test)]
16+
mod tests {
17+
use googletest::prelude::*;
18+
#[googletest::test]
19+
fn should_fail() {
20+
let arg = "argument";
21+
expect_float_eq!(1.0, 2.0, "Failure message with argument: {arg}");
22+
println!("This will print");
23+
}
24+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
fn main() {}
15+
#[cfg(test)]
16+
mod tests {
17+
use googletest::prelude::*;
18+
#[googletest::test]
19+
fn should_fail() {
20+
expect_float_eq!(1.0, 2.0);
21+
println!("This will print");
22+
}
23+
}

integration_tests/src/integration_tests.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,84 @@ mod tests {
14641464
verify_that!(output, contains_regex("This will print"))
14651465
}
14661466

1467+
#[test]
1468+
fn verify_float_eq_should_pass() -> Result<()> {
1469+
verify_float_eq!(1.0, 1.0)
1470+
}
1471+
1472+
#[test]
1473+
fn verify_float_eq_supports_trailing_comma() -> Result<()> {
1474+
verify_float_eq!(1.0, 1.0,)
1475+
}
1476+
1477+
#[googletest::test]
1478+
fn verify_float_eq_when_not_equal_returns_error() -> Result<()> {
1479+
let output = run_external_process_in_tests_directory(
1480+
"verify_float_eq_when_not_equal_returns_error",
1481+
)?;
1482+
1483+
verify_that!(
1484+
output,
1485+
contains_regex(indoc! {"
1486+
Expected: is within 1.[0-9]+e-[0-9]+ of 2.0
1487+
Actual: 1.0,
1488+
which isn't within 1.[0-9]+e-[0-9]+ of 2.0
1489+
at .*verify_float_eq_when_not_equal_returns_error.rs:[0-9]+:[0-9]
1490+
"})
1491+
)
1492+
}
1493+
1494+
#[googletest::test]
1495+
fn expect_float_eq_should_pass() {
1496+
expect_float_eq!(1.0, 1.0);
1497+
}
1498+
1499+
#[googletest::test]
1500+
fn expect_float_eq_supports_trailing_comma() {
1501+
expect_float_eq!(1.0, 1.0,);
1502+
}
1503+
1504+
#[googletest::test]
1505+
fn expect_float_eq_allows_multiple_invocations() {
1506+
expect_float_eq!(1.0, 1.0);
1507+
expect_float_eq!(2.0, 2.0);
1508+
}
1509+
1510+
#[googletest::test]
1511+
fn expect_float_eq_when_not_equal_marks_failed() -> Result<()> {
1512+
let output =
1513+
run_external_process_in_tests_directory("expect_float_eq_when_not_equal_marks_failed")?;
1514+
1515+
expect_that!(
1516+
output,
1517+
contains_regex(indoc! {"
1518+
Expected: is within 1.[0-9]+e-[0-9]+ of 2.0
1519+
Actual: 1.0,
1520+
which isn't within 1.[0-9]+e-[0-9]+ of 2.0
1521+
at .*expect_float_eq_when_not_equal_marks_failed.rs:[0-9]+:[0-9]
1522+
"})
1523+
);
1524+
verify_that!(output, contains_regex("This will print"))
1525+
}
1526+
1527+
#[googletest::test]
1528+
fn expect_float_eq_supports_custom_message() -> Result<()> {
1529+
let output =
1530+
run_external_process_in_tests_directory("expect_float_eq_supports_custom_message")?;
1531+
1532+
expect_that!(
1533+
output,
1534+
contains_regex(indoc! {"
1535+
Expected: is within 1.[0-9]+e-[0-9]+ of 2.0
1536+
Actual: 1.0,
1537+
which isn't within 1.[0-9]+e-[0-9]+ of 2.0
1538+
Failure message with argument: argument
1539+
at .*expect_float_eq_supports_custom_message.rs:[0-9]+:[0-9]
1540+
"})
1541+
);
1542+
verify_that!(output, contains_regex("This will print"))
1543+
}
1544+
14671545
#[test]
14681546
fn test_using_normal_test_attribute_macro_formats_failure_message_correctly() -> Result<()> {
14691547
let result = should_display_error_correctly_without_google_test_macro();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
fn main() {}
16+
17+
#[cfg(test)]
18+
mod tests {
19+
use googletest::prelude::*;
20+
21+
#[test]
22+
fn should_fail() -> Result<()> {
23+
verify_float_eq!(1.0, 2.0)
24+
}
25+
}

run_integration_tests.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ INTEGRATION_TEST_BINARIES=(
7575
"verify_ge_when_less_returns_error"
7676
"expect_ge_when_less_marks_failed"
7777
"expect_ge_supports_custom_message"
78+
"verify_float_eq_when_not_equal_returns_error"
79+
"expect_float_eq_when_not_equal_marks_failed"
80+
"expect_float_eq_supports_custom_message"
7881
"fatal_and_non_fatal_failure"
7982
"first_failure_aborts"
8083
"google_test_with_rstest"

0 commit comments

Comments
 (0)