build(rust): vendor googletest crate
This commit was merged in pull request #76.
This commit is contained in:
1 parent
a6fe84190e
commit
6887b104d6
576 files changed
+284290
-2
No files matched your search
@@ -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.
|
||||
|
||||
use crate::{
|
||||
description::Description,
|
||||
matcher::{Matcher, MatcherBase, MatcherResult},
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
/// Matches a value greater (in the sense of `>`) than `expected`.
|
||||
///
|
||||
/// The types of `ActualT` of `actual` and `ExpectedT` of `expected` must be
|
||||
/// comparable via the `PartialOrd` trait. Namely, `ActualT` must implement
|
||||
/// `PartialOrd<ExpectedT>`.
|
||||
///
|
||||
/// ```
|
||||
/// # use googletest::prelude::*;
|
||||
/// # fn should_pass() -> Result<()> {
|
||||
/// verify_that!(38, gt(1))?; // Passes
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// # fn should_fail() -> Result<()> {
|
||||
/// verify_that!(234, gt(234))?; // Fails
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// # should_pass().unwrap();
|
||||
/// # should_fail().unwrap_err();
|
||||
/// ```
|
||||
///
|
||||
/// In most cases the params neeed to be the same type or they need to be cast
|
||||
/// explicitly. This can be surprising when comparing integer types or
|
||||
/// references:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// # use googletest::prelude::*;
|
||||
/// # fn should_not_compile() -> Result<()> {
|
||||
/// verify_that!(123u32, gt(0u64))?; // Does not compile
|
||||
/// verify_that!(123u32 as u64, gt(0u64))?; // Passes
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// # use googletest::prelude::*;
|
||||
/// # fn should_not_compile() -> Result<()> {
|
||||
/// let actual: &u32 = &2;
|
||||
/// let expected: u32 = 1;
|
||||
/// verify_that!(actual, gt(expected))?; // Does not compile
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use googletest::prelude::*;
|
||||
/// # fn should_pass() -> Result<()> {
|
||||
/// let actual: &u32 = &2;
|
||||
/// let expected: u32 = 1;
|
||||
/// verify_that!(actual, gt(&expected))?; // Compiles and passes
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// # should_pass().unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// You can find the standard library `PartialOrd` implementation in
|
||||
/// <https://doc.rust-lang.org/core/cmp/trait.PartialOrd.html#implementors>
|
||||
pub fn gt<ExpectedT: Debug>(expected: ExpectedT) -> GtMatcher<ExpectedT> {
|
||||
GtMatcher { expected }
|
||||
}
|
||||
|
||||
#[derive(MatcherBase)]
|
||||
pub struct GtMatcher<ExpectedT> {
|
||||
expected: ExpectedT,
|
||||
}
|
||||
|
||||
impl<ActualT: Debug + PartialOrd<ExpectedT> + Copy, ExpectedT: Debug> Matcher<ActualT>
|
||||
for GtMatcher<ExpectedT>
|
||||
{
|
||||
fn matches(&self, actual: ActualT) -> MatcherResult {
|
||||
(actual > self.expected).into()
|
||||
}
|
||||
|
||||
fn describe(&self, matcher_result: MatcherResult) -> Description {
|
||||
match matcher_result {
|
||||
MatcherResult::Match => format!("is greater than {:?}", self.expected).into(),
|
||||
MatcherResult::NoMatch => {
|
||||
format!("is less than or equal to {:?}", self.expected).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::matcher::MatcherResult;
|
||||
use crate::prelude::*;
|
||||
use crate::Result;
|
||||
use indoc::indoc;
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[test]
|
||||
fn gt_matches_i32_with_i32() -> Result<()> {
|
||||
let actual: i32 = 321;
|
||||
let expected: i32 = 123;
|
||||
verify_that!(actual, gt(expected))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_does_not_match_equal_i32() -> Result<()> {
|
||||
let matcher = gt(10);
|
||||
let result = matcher.matches(10);
|
||||
verify_that!(result, eq(MatcherResult::NoMatch))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_does_not_match_lower_i32() -> Result<()> {
|
||||
let matcher = gt(-50);
|
||||
let result = matcher.matches(-51);
|
||||
verify_that!(result, eq(MatcherResult::NoMatch))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_matches_greater_str() -> Result<()> {
|
||||
verify_that!("B", gt("A"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_does_not_match_lesser_str() -> Result<()> {
|
||||
let matcher = gt("B");
|
||||
let result = matcher.matches("A");
|
||||
verify_that!(result, eq(MatcherResult::NoMatch))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_mismatch_contains_actual_and_expected() -> Result<()> {
|
||||
let result = verify_that!(481, gt(632));
|
||||
|
||||
verify_that!(
|
||||
result,
|
||||
err(displays_as(contains_substring(indoc!(
|
||||
"
|
||||
Value of: 481
|
||||
Expected: is greater than 632
|
||||
Actual: 481,
|
||||
"
|
||||
))))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_mismatch_combined_with_each() -> Result<()> {
|
||||
let result = verify_that!(vec![19, 23, 11], each(gt(&15)));
|
||||
|
||||
verify_that!(
|
||||
result,
|
||||
err(displays_as(contains_substring(indoc!(
|
||||
"
|
||||
Value of: vec![19, 23, 11]
|
||||
Expected: only contains elements that is greater than 15
|
||||
Actual: [19, 23, 11],
|
||||
whose element #2 is 11, which is less than or equal to 15
|
||||
"
|
||||
))))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_describe_matches() -> Result<()> {
|
||||
verify_that!(
|
||||
Matcher::<i32>::describe(>(232), MatcherResult::Match),
|
||||
displays_as(eq("is greater than 232"))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_describe_does_not_match() -> Result<()> {
|
||||
verify_that!(
|
||||
Matcher::<i32>::describe(>(232), MatcherResult::NoMatch),
|
||||
displays_as(eq("is less than or equal to 232"))
|
||||
)
|
||||
}
|
||||
|
||||
// Test `gt` matcher where actual is `&OsString` and expected is `&str`.
|
||||
// Note that stdlib is a little bit inconsistent: `PartialOrd` exists for
|
||||
// `OsString` and `str`, but only in one direction: it's only possible to
|
||||
// compare `OsString` with `str` if `OsString` is on the left side of the
|
||||
// ">" operator (`impl PartialOrd<str> for OsString`).
|
||||
//
|
||||
// The comparison in the other direction is not defined.
|
||||
//
|
||||
// This means that the test case bellow effectively ensures that
|
||||
// `verify_that(actual, gt(expected))` works if `actual > expected` works
|
||||
// (regardless whether the `expected > actual` works`).
|
||||
#[test]
|
||||
fn gt_matches_owned_osstring_reference_with_string_reference() -> Result<()> {
|
||||
let expected = "A";
|
||||
let actual: OsString = "B".to_string().into();
|
||||
verify_that!(&actual, gt(expected))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_matches_ipv6addr_with_ipaddr() -> Result<()> {
|
||||
use std::net::IpAddr;
|
||||
use std::net::Ipv6Addr;
|
||||
let actual: Ipv6Addr = "2001:4860:4860::8888".parse().unwrap();
|
||||
let expected: IpAddr = "127.0.0.1".parse().unwrap();
|
||||
verify_that!(actual, gt(expected))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gt_matches_with_custom_partial_ord() -> Result<()> {
|
||||
/// A custom "number" that is smaller than all other numbers. The only
|
||||
/// things we define about this "special" number is `PartialOrd` and
|
||||
/// `PartialEq` against `u32`.
|
||||
#[derive(Debug)]
|
||||
struct VeryLowNumber {}
|
||||
|
||||
impl std::cmp::PartialEq<u32> for VeryLowNumber {
|
||||
fn eq(&self, _other: &u32) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// PartialOrd (required for >) requires PartialEq.
|
||||
impl std::cmp::PartialOrd<u32> for VeryLowNumber {
|
||||
fn partial_cmp(&self, _other: &u32) -> Option<std::cmp::Ordering> {
|
||||
Some(std::cmp::Ordering::Less)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq<VeryLowNumber> for u32 {
|
||||
fn eq(&self, _other: &VeryLowNumber) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd<VeryLowNumber> for u32 {
|
||||
fn partial_cmp(&self, _other: &VeryLowNumber) -> Option<std::cmp::Ordering> {
|
||||
Some(std::cmp::Ordering::Greater)
|
||||
}
|
||||
}
|
||||
|
||||
let actual: u32 = 42;
|
||||
let expected = VeryLowNumber {};
|
||||
|
||||
verify_that!(actual, gt(expected))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user