use crate::assertions::basic::EqualityAssertion;
use crate::base::{AssertionApi, AssertionResult, AssertionStrategy, Subject};
pub trait StringAssertion<R> {
#[track_caller]
fn is_same_string_to<E: Into<String>>(&self, expected: E) -> R;
#[track_caller]
fn contains<E: Into<String>>(&self, expected: E) -> R;
#[track_caller]
fn does_not_contain<E: Into<String>>(&self, value: E) -> R;
#[track_caller]
fn starts_with<E: Into<String>>(&self, expected: E) -> R;
#[track_caller]
fn ends_with<E: Into<String>>(&self, expected: E) -> R;
}
impl<R> StringAssertion<R> for Subject<'_, String, (), R>
where
AssertionResult: AssertionStrategy<R>,
{
fn is_same_string_to<E: Into<String>>(&self, expected: E) -> R {
let subject: Subject<String, (), R> = self.new_subject(self.actual(), None, ());
EqualityAssertion::is_equal_to(&subject, expected.into())
}
fn contains<E: Into<String>>(&self, expected: E) -> R {
let expected_str = expected.into();
if self.actual().contains(&expected_str) {
self.new_result().do_ok()
} else {
self.new_result()
.add_fact("expected a string that contains", expected_str)
.add_fact("but was", self.actual())
.do_fail()
}
}
fn does_not_contain<E: Into<String>>(&self, value: E) -> R {
let expected_str = value.into();
if self.actual().contains(&expected_str) {
self.new_result()
.add_fact("expected a string to not contain", expected_str)
.add_fact("but was", self.actual())
.do_fail()
} else {
self.new_result().do_ok()
}
}
fn starts_with<E: Into<String>>(&self, expected: E) -> R {
let expected_str = expected.into();
if self.actual().starts_with(&expected_str) {
self.new_result().do_ok()
} else {
self.new_result()
.add_fact("expected a string that starts with", expected_str)
.add_fact("but was", self.actual())
.do_fail()
}
}
fn ends_with<E: Into<String>>(&self, expected: E) -> R {
let expected_str = expected.into();
if self.actual().ends_with(&expected_str) {
self.new_result().do_ok()
} else {
self.new_result()
.add_fact("expected a string that ends with", expected_str)
.add_fact("but was", self.actual())
.do_fail()
}
}
}
impl<R> StringAssertion<R> for Subject<'_, &str, (), R>
where
AssertionResult: AssertionStrategy<R>,
{
#[track_caller]
fn is_same_string_to<E: Into<String>>(&self, expected: E) -> R {
self.new_owned_subject(self.actual().to_string(), None, ())
.is_same_string_to(expected)
}
#[track_caller]
fn contains<E: Into<String>>(&self, expected: E) -> R {
self.new_owned_subject(self.actual().to_string(), None, ())
.contains(expected)
}
#[track_caller]
fn does_not_contain<E: Into<String>>(&self, value: E) -> R {
self.new_owned_subject(self.actual().to_string(), None, ())
.does_not_contain(value)
}
#[track_caller]
fn starts_with<E: Into<String>>(&self, expected: E) -> R {
self.new_owned_subject(self.actual().to_string(), None, ())
.starts_with(expected)
}
#[track_caller]
fn ends_with<E: Into<String>>(&self, expected: E) -> R {
self.new_owned_subject(self.actual().to_string(), None, ())
.ends_with(expected)
}
}
#[cfg(test)]
mod tests {
use crate::testing::*;
use super::*;
#[test]
fn is_same_string_to() {
assert_that!("foo").is_same_string_to("foo");
assert_that!("").is_same_string_to("");
assert_that!("ninja".to_string()).is_same_string_to("ninja");
assert_that!("ninja".to_string()).is_same_string_to("ninja".to_string());
assert_that!(check_that!("ninja").is_same_string_to("bar")).facts_are(vec![
Fact::new("expected", r#""bar""#),
Fact::new("actual", r#""ninja""#),
]);
}
#[test]
fn starts_with() {
assert_that!("foobarbaz").starts_with("foo");
assert_that!(check_that!("foobarbaz").starts_with("baz")).facts_are(vec![
Fact::new("expected a string that starts with", "baz"),
Fact::new("but was", "foobarbaz"),
])
}
#[test]
fn ends_with() {
assert_that!("foobarbaz").ends_with("baz");
assert_that!(check_that!("foobarbaz").ends_with("foo")).facts_are(vec![
Fact::new("expected a string that ends with", "foo"),
Fact::new("but was", "foobarbaz"),
])
}
#[test]
fn contains() {
assert_that!("foobarbaz").contains("foo");
assert_that!("foobarbaz").contains("bar");
assert_that!("foobarbaz").contains("baz");
assert_that!("foobarbaz").contains("b");
assert_that!(check_that!("foo").contains("baz")).facts_are(vec![
Fact::new("expected a string that contains", "baz"),
Fact::new("but was", "foo"),
])
}
#[test]
fn does_not_contain() {
assert_that!("foobarbaz").does_not_contain("was");
assert_that!("foobarbaz").does_not_contain("bla");
assert_that!("foobarbaz").does_not_contain("up");
assert_that!("foobarbaz").does_not_contain("x");
assert_that!(check_that!("foo").does_not_contain("fo")).facts_are(vec![
Fact::new("expected a string to not contain", "fo"),
Fact::new("but was", "foo"),
])
}
}