Skip to content

Commit

Permalink
Merge pull request #1 from hauju/feature/option-result
Browse files Browse the repository at this point in the history
Feature/option result
  • Loading branch information
hauju committed Jan 9, 2024
2 parents 00fe7cf + d8a5221 commit 85f6c5f
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 69 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fluent-assertions"
version = "0.2.0"
version = "0.3.0"
authors = ["Hauke Jung <hauke.jung@outlook.de>"]
documentation = "https://docs.rs/fluent-assertions"
repository = "https://github.com/hauju/fluent-assertions-rs.git"
Expand All @@ -14,4 +14,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
num-traits = "0.2"
num-traits = "0.2"

[dev-dependencies]
rstest = "0.18.2"
9 changes: 9 additions & 0 deletions examples/asserts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,13 @@ fn main() {

let is_verified = true;
is_verified.should().be_true();

let anwser: i32 = 42;
anwser.should().be_greater_than(40);

let anwser: f64 = 42.0;
anwser.should().be_greater_than(40.0);

let result: Result<f64, String> = Ok(42f64);
result.should().be_ok();
}
12 changes: 11 additions & 1 deletion src/assertions/bool_assertion.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
use crate::Should;

pub struct BoolAssertion {
value: bool,
}

impl Should for bool {
type Assertion = BoolAssertion;

fn should(self) -> BoolAssertion {
BoolAssertion::new(self)
}
}

impl BoolAssertion {
pub fn new(value: bool) -> Self {
BoolAssertion { value }
Expand Down Expand Up @@ -40,7 +50,7 @@ impl BoolAssertion {

#[cfg(test)]
mod tests {
use crate::assertions::ShouldBool;
use crate::assertions::*;

#[test]
fn test_bool_assertions() {
Expand Down
29 changes: 3 additions & 26 deletions src/assertions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,13 @@
use self::bool_assertion::BoolAssertion;
use crate::assertions::string_assertion::StringAssertion;


pub mod bool_assertion;
pub mod string_assertion;
pub mod numeric_assertion;
pub mod option_assertion;
pub mod result_assertion;


pub trait ShouldString {
type Assertion;
fn should(self) -> Self::Assertion;
}

impl<T: AsRef<str>> ShouldString for T {
type Assertion = StringAssertion<T>;

fn should(self) -> StringAssertion<T>{
StringAssertion::new(self)
}
}


pub trait ShouldBool {
pub trait Should {
type Assertion;
fn should(self) -> Self::Assertion;
}

impl ShouldBool for bool {
type Assertion = BoolAssertion;

fn should(self) -> BoolAssertion {
BoolAssertion::new(self)
}
}

155 changes: 117 additions & 38 deletions src/assertions/numeric_assertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,106 @@ use std::cmp::PartialOrd;
use std::fmt::Display;
use num_traits::Zero;

pub trait ShouldNumeric {
type Assertion;
fn should(self) -> Self::Assertion;
use crate::Should;

pub struct NumericAssertion<T: PartialOrd + Display> {
value: T,
}

impl<T> ShouldNumeric for T
where
T: PartialOrd + Display + Copy + num_traits::Zero,
{
type Assertion = NumericAssertion<T>;
impl Should for f64 {
type Assertion = NumericAssertion<f64>;

fn should(self) -> NumericAssertion<T> {
fn should(self) -> NumericAssertion<f64> {
NumericAssertion::new(self)
}
}

pub struct NumericAssertion<T: PartialOrd + Display> {
value: T,
impl Should for f32 {
type Assertion = NumericAssertion<f32>;

fn should(self) -> NumericAssertion<f32> {
NumericAssertion::new(self)
}
}

impl Should for usize {
type Assertion = NumericAssertion<usize>;

fn should(self) -> NumericAssertion<usize> {
NumericAssertion::new(self)
}
}

impl Should for u64 {
type Assertion = NumericAssertion<u64>;

fn should(self) -> NumericAssertion<u64> {
NumericAssertion::new(self)
}
}

impl Should for u32 {
type Assertion = NumericAssertion<u32>;

fn should(self) -> NumericAssertion<u32> {
NumericAssertion::new(self)
}
}

impl Should for u16 {
type Assertion = NumericAssertion<u16>;

fn should(self) -> NumericAssertion<u16> {
NumericAssertion::new(self)
}
}

impl Should for u8 {
type Assertion = NumericAssertion<u8>;

fn should(self) -> NumericAssertion<u8> {
NumericAssertion::new(self)
}
}

impl Should for isize {
type Assertion = NumericAssertion<isize>;

fn should(self) -> NumericAssertion<isize> {
NumericAssertion::new(self)
}
}

impl Should for i64 {
type Assertion = NumericAssertion<i64>;

fn should(self) -> NumericAssertion<i64> {
NumericAssertion::new(self)
}
}

impl Should for i32 {
type Assertion = NumericAssertion<i32>;

fn should(self) -> NumericAssertion<i32> {
NumericAssertion::new(self)
}
}

impl Should for i16 {
type Assertion = NumericAssertion<i16>;

fn should(self) -> NumericAssertion<i16> {
NumericAssertion::new(self)
}
}

impl Should for i8 {
type Assertion = NumericAssertion<i8>;

fn should(self) -> NumericAssertion<i8> {
NumericAssertion::new(self)
}
}

impl<T> NumericAssertion<T>
Expand Down Expand Up @@ -89,41 +171,38 @@ T: PartialOrd + Display + Zero + Copy,

#[cfg(test)]
mod tests {
use crate::numeric_assertion::ShouldNumeric;
use rstest::*;
use crate::assertions::*;

#[rstest]
#[case(43, 42)]
#[case(1, 0)]
fn should_be_greater_and_positive(#[case] input: isize, #[case] value: isize) {
input.should()
.be_greater_than(value)
.be_positive();
}

#[test]
fn test_num_assertions() {
let actual = 42_u8;
actual
#[rstest]
#[case(42.0, 41.99)]
#[case(1.0, 0.9)]
fn should_be_greater_f64(#[case] input: f64, #[case] value: f64) {
input
.should()
.be_greater_than(42)
.be_positive();
.be_greater_than(value);
}

#[test]
fn test_negativ_num_assertions() {
let actual = -42_i8;
actual
#[rstest]
#[case(-42)]
#[case(-3)]
fn should_be_negative_i8(#[case] input: i8) {
input
.should()
.be_greater_than(-43)
.be_negative()
.not_be(32)
.be(-42);
}

#[test]
fn test_int_assertions() {
let actual = 42_i32;
actual
.should()
.be_greater_than(42);
.be(input);
}

#[test]
fn test_float_assertions() {
let actual = 42.0;
actual
.should()
.be_greater_than(41.99);
}

}
50 changes: 50 additions & 0 deletions src/assertions/option_assertion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use crate::Should;

pub struct OptionAssertion<T> {
value: Option<T>,
}

impl <T> Should for Option<T> {
type Assertion = OptionAssertion<T>;

fn should(self) -> OptionAssertion<T> {
OptionAssertion::new(self)
}
}

impl <T> OptionAssertion<T> {
pub fn new(value: Option<T>) -> Self {
OptionAssertion { value }
}

pub fn be_some(&self) -> &Self {
assert!(self.value.is_some(), "Expected Some, but got None");
self
}

pub fn be_none(&self) -> &Self {
assert!(self.value.is_none(), "Expected None, but got Some");
self
}
}

#[cfg(test)]
mod tests {
use rstest::*;
use crate::assertions::*;

#[rstest]
#[case(None)]
fn should_be_none(#[case] input: Option<String>) {
input.should()
.be_none();
}

#[rstest]
#[case(Some(42f64))]
#[case(Some(0.0))]
fn should_be_some(#[case] input: Option<f64>) {
input.should()
.be_some();
}
}
50 changes: 50 additions & 0 deletions src/assertions/result_assertion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use crate::Should;



pub struct ResultAssertion<T, E> {
value: Result<T, E>,
}

impl <T, E> Should for Result<T, E> {
type Assertion = ResultAssertion<T, E>;

fn should(self) -> ResultAssertion<T, E> {
ResultAssertion::new(self)
}
}

impl <T, E> ResultAssertion<T, E> {
pub fn new(value: Result<T, E>) -> Self {
ResultAssertion { value }
}

pub fn be_ok(&self) -> &Self {
assert!(self.value.is_ok(), "Expected Ok, but got Err");
self
}

pub fn be_err(&self) -> &Self {
assert!(self.value.is_err(), "Expected Err, but got Ok");
self
}

}



#[cfg(test)]
mod tests {
use rstest::*;
use crate::assertions::*;


#[rstest]
#[case(Ok(42))]
#[case(Ok(0))]
fn should_be_ok(#[case] input: Result<i32, String>) {
input.should()
.be_ok();
}

}
Loading

0 comments on commit 85f6c5f

Please sign in to comment.