Skip to content

Commit

Permalink
Merge pull request #83 from tommilligan/assert-eq-no-std
Browse files Browse the repository at this point in the history
feat: fix and test for no_std with alloc
  • Loading branch information
tommilligan committed Sep 28, 2021
2 parents 9ef3e0d + 659b66b commit 737c861
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 71 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Unreleased

# v1.0.0

## Removed

- `assert_ne` no longer warns if values match using `PartialEq` but not with `Debug`. This was noted as no longer being necessary after Rust 1.25 (current MSRV 1.35.0)

## Added

- Officially support `no_std` (thanks to [@Luro02](https://github.com/Luro02) for the report and reviews!). Adds the `std` and `alloc` features to the `pretty_assertions` crate, with `std` enabled by default ([#83](https://github.com/colin-kiegel/rust-pretty-assertions/pull/83), [@tommilligan](https://github.com/tommilligan))
- Adds the `unstable` feature to the `pretty_assertions` crate, for use with nightly rustc ([#81](https://github.com/colin-kiegel/rust-pretty-assertions/pull/81), [@tommilligan](https://github.com/tommilligan))
- Add a drop in replacement for the unstable stdlib `assert_matches` macro, behind the `unstable` flag - thanks [@gilescope](https://github.com/gilescope) for the suggestion! ([#81](https://github.com/colin-kiegel/rust-pretty-assertions/issues/81), [@tommilligan](https://github.com/tommilligan))

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ use pretty_assertions::{assert_eq, assert_ne};
escape sequences, which may break display for certain use cases.
- The minimum supported rust version (MSRV) is 1.35.0

### `no_std` support

For `no_std` support, disable the `std` feature and enable the `alloc` feature:

```toml
# Cargo.toml
pretty_assertions = { version= "...", default-features = false, features = ["alloc"] }
```

## License

Licensed under either of
Expand Down
13 changes: 10 additions & 3 deletions pretty_assertions/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pretty_assertions"
version = "0.7.2"
version = "1.0.0"
authors = [
"Colin Kiegel <kiegel@gmx.de>",
"Florent Fayolle <florent.fayolle69@gmail.com>",
Expand All @@ -18,9 +18,15 @@ keywords = ["assert", "diff", "pretty", "color"]
readme = "README.md"

[features]
default = []
default = ["std"]

# Enable unstable features requiring nightly rustc
# Use the Rust standard library.
# Exactly one of `std` and `alloc` is required.
std = []
# Use the `alloc` crate.
# Exactly one of `std` and `alloc` is required.
alloc = []
# Enable unstable features. Requires nightly rustc.
unstable = []

[dependencies]
Expand All @@ -30,3 +36,4 @@ diff = "0.1.12"
[target.'cfg(windows)'.dependencies]
output_vt100 = "0.1.2"
ctor = "0.1.9"

54 changes: 21 additions & 33 deletions pretty_assertions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,23 @@
//!
//! ## Features
//!
//! Features provided by the crate are as follows:
//! Features provided by the crate are:
//!
//! - `std`: Use the Rust standard library. Enabled by default.
//! Exactly one of `std` and `alloc` is required.
//! - `alloc`: Use the `alloc` crate.
//! Exactly one of `std` and `alloc` is required.
//! - `unstable`: opt-in to unstable features that may not follow Semantic Versioning.
//! Implmenetion behind this feature is subject to change without warning between patch versions.

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(clippy::all, missing_docs, unsafe_code)]

#[cfg(feature = "alloc")]
#[macro_use]
extern crate alloc;
pub use ansi_term::Style;
use std::fmt::{self, Debug, Display};
use core::fmt::{self, Debug, Display};

mod printer;

Expand Down Expand Up @@ -138,7 +146,7 @@ where
/// On panic, this macro will print a diff derived from [`Debug`] representation of
/// each value.
///
/// This is a drop in replacement for [`std::assert_eq!`].
/// This is a drop in replacement for [`core::assert_eq!`].
/// You can provide a custom panic message if desired.
///
/// # Examples
Expand All @@ -164,7 +172,7 @@ macro_rules! assert_eq {
match (&($left), &($right)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
::std::panic!("assertion failed: `(left == right)`{}{}\
::core::panic!("assertion failed: `(left == right)`{}{}\
\n\
\n{}\
\n",
Expand All @@ -183,7 +191,7 @@ macro_rules! assert_eq {
/// On panic, this macro will print the values of the expressions with their
/// [`Debug`] representations.
///
/// This is a drop in replacement for [`std::assert_ne!`].
/// This is a drop in replacement for [`core::assert_ne!`].
/// You can provide a custom panic message if desired.
///
/// # Examples
Expand All @@ -209,27 +217,7 @@ macro_rules! assert_ne {
match (&($left), &($right)) {
(left_val, right_val) => {
if *left_val == *right_val {
let left_dbg = ::std::format!("{:?}", &*left_val);
let right_dbg = ::std::format!("{:?}", &*right_val);
if left_dbg != right_dbg {
::std::panic!("assertion failed: `(left != right)`{}{}\
\n\
\n{}\
\n{}: According to the `PartialEq` implementation, both of the values \
are partially equivalent, even if the `Debug` outputs differ.\
\n\
\n",
$maybe_semicolon,
format_args!($($arg)+),
$crate::Comparison::new(left_val, right_val),
$crate::Style::new()
.bold()
.underline()
.paint("Note")
)
}

::std::panic!("assertion failed: `(left != right)`{}{}\
::core::panic!("assertion failed: `(left != right)`{}{}\
\n\
\n{}:\
\n{:#?}\
Expand All @@ -251,7 +239,7 @@ macro_rules! assert_ne {
/// On panic, this macro will print a diff derived from [`Debug`] representation of
/// the value, and a string representation of the pattern.
///
/// This is a drop in replacement for [`std::assert_matches::assert_matches!`].
/// This is a drop in replacement for [`core::assert_matches::assert_matches!`].
/// You can provide a custom panic message if desired.
///
/// # Examples
Expand Down Expand Up @@ -281,7 +269,7 @@ macro_rules! assert_matches {
$crate::assert_matches!(
@
left_val,
::std::stringify!($($pattern)|+ $(if $guard)?),
::core::stringify!($($pattern)|+ $(if $guard)?),
"",
""
);
Expand All @@ -295,7 +283,7 @@ macro_rules! assert_matches {
$crate::assert_matches!(
@
left_val,
::std::stringify!($($pattern)|+ $(if $guard)?),
::core::stringify!($($pattern)|+ $(if $guard)?),
": ",
$($arg)+
);
Expand All @@ -309,13 +297,13 @@ macro_rules! assert_matches {
// Use the Display implementation to display the pattern,
// as using Debug would add another layer of quotes to the output.
struct Pattern<'a>(&'a str);
impl ::std::fmt::Debug for Pattern<'_> {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::std::fmt::Display::fmt(self.0, f)
impl ::core::fmt::Debug for Pattern<'_> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
::core::fmt::Display::fmt(self.0, f)
}
}

::std::panic!("assertion failed: `(left matches right)`{}{}\
::core::panic!("assertion failed: `(left matches right)`{}{}\
\n\
\n{}\
\n",
Expand Down
9 changes: 8 additions & 1 deletion pretty_assertions/src/printer.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#[cfg(feature = "alloc")]
use alloc::format;
use ansi_term::{
Colour::{Fixed, Green, Red},
Style,
};
use std::fmt;
use core::fmt;

macro_rules! paint {
($f:expr, $colour:expr, $fmt:expr, $($args:tt)*) => (
Expand Down Expand Up @@ -210,6 +212,9 @@ fn write_inline_diff<TWrite: fmt::Write>(f: &mut TWrite, left: &str, right: &str
mod test {
use super::*;

#[cfg(feature = "alloc")]
use alloc::string::String;

// ANSI terminal codes used in our outputs.
//
// Interpolate these into test strings to make expected values easier to read.
Expand All @@ -230,6 +235,8 @@ mod test {
let mut actual = String::new();
printer(&mut actual, left, right).expect("printer function failed");

// Cannot use IO without stdlib
#[cfg(feature = "std")]
println!(
"## left ##\n\
{}\n\
Expand Down
43 changes: 11 additions & 32 deletions pretty_assertions/tests/macros.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![no_implicit_prelude]

#[cfg(feature = "alloc")]
extern crate alloc;

#[allow(clippy::eq_op)]
mod assert_eq {
#[cfg(feature = "alloc")]
use ::alloc::string::{String, ToString};
#[cfg(feature = "std")]
use ::std::string::{String, ToString};

#[test]
Expand Down Expand Up @@ -93,6 +100,9 @@ mod assert_eq {
}

mod assert_ne {
#[cfg(feature = "alloc")]
use ::alloc::string::{String, ToString};
#[cfg(feature = "std")]
use ::std::string::{String, ToString};

#[test]
Expand Down Expand Up @@ -177,37 +187,6 @@ mod assert_ne {
// If the values are equal but their debug outputs are not
// show a specific warning

#[test]
#[should_panic(expected = r#"assertion failed: `(left != right)`
Diff < left / right > :
<-0.0
>0.0
Note: According to the `PartialEq` implementation, both of the values are partially equivalent, even if the `Debug` outputs differ.
"#)]
fn assert_ne_partial() {
// Workaround for https://github.com/rust-lang/rust/issues/47619
// can be removed, when we require rust 1.25 or higher
struct Foo(f32);

use ::std::fmt;
impl fmt::Debug for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
::std::write!(f, "{:.1?}", self.0)
}
}

impl ::std::cmp::PartialEq for Foo {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}

::pretty_assertions::assert_ne!(Foo(-0.0), Foo(0.0));
}

// Regression tests

#[test]
Expand All @@ -223,7 +202,7 @@ mod assert_ne {

#[cfg(feature = "unstable")]
mod assert_matches {
use ::std::option::Option::{None, Some};
use ::core::option::Option::{None, Some};

#[test]
fn passes() {
Expand Down
19 changes: 17 additions & 2 deletions scripts/check
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,30 @@ cargo audit --deny warnings
eprintln "Linting sources"
cargo clippy --all-targets -- -D warnings

eprintln "Running unit tests"
# We cd to package directory as it's the only one with tests
# and cargo doesn't support feature flags in virtual workspaces
# https://github.com/rust-lang/cargo/issues/5364
pushd pretty_assertions

eprintln "Running tests (default)"
cargo test
eprintln "Running tests (alloc)"
cargo test --no-default-features --features alloc

eprintln "Running tests (nightly) (unstable)"
cargo +nightly test --features unstable
eprintln "Running tests (nightly) (alloc, unstable)"
cargo +nightly test --no-default-features --features alloc --features unstable

popd

eprintln "Running unit tests (unstable)"
cargo +nightly test --manifest-path pretty_assertions/Cargo.toml --all --features unstable

eprintln "Building documentation"
cargo doc --no-deps

eprintln "Running examples"
eprintln "Running examples (standard)"
cargo run --example standard_assertion
eprintln "Running examples (pretty)"
cargo run --example pretty_assertion

0 comments on commit 737c861

Please sign in to comment.