Skip to content

Conversation

@kammitama5
Copy link
Collaborator

No description provided.

@kammitama5 kammitama5 changed the title passes all test except one Eq_Predicate ensures equality Aug 3, 2018
Copy link
Contributor

@epage epage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this!

Couple of notes

  • When we eventually squash the commits, remember to clean up the commit messages to focus on what problem we are solving and any "why"s and not to focus on the "what", that is what the code is for
  • Be sure to reference #62 in the commit message
  • What is the title of the PR about? I don't understand how it relates to your changes.

src/path/fs.rs Outdated
use Predicate;

fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
fn read_file<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the top-level function should do this.

Its best to minimize what all code lives in generics because the compiler will "monomorphize" it, meaning, it will duplicate the code for every data type used with the generics.

See http://www.suspectsemantics.com/blog/2016/12/03/monomorphization-bloat/

src/path/fs.rs Outdated
}
}

impl Predicate<str> for BinaryFilePredicate {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this implementation being added?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage @kammitama5 and I had a look at this. You can't compare without this implementation. The example code will call Predicate<I: Item>::call(BinaryFilePredicate, I) so without this implementation you'll get the following errors.

error[E0277]: the trait bound `predicates::path::BinaryFilePredicate: predicates::Predicate<str>` is not satisfied
 --> src/path/fs.rs:110:34
  |
9 | assert_eq!(false, predicate_file.eval("src"));
  |                                  ^^^^ the trait `predicates::Predicate<str>` is not implemented for `predicates::path::BinaryFilePredicate`
  |
  = help: the following implementations were found:
            <predicates::path::BinaryFilePredicate as predicates::Predicate<std::path::Path>>
            <predicates::path::BinaryFilePredicate as predicates::Predicate<[u8]>>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is being used to try to emulate AsRef<Path> with eval?

The original issue was only about eq_file. In thinking about the trade offs of adding this extra functionality, I'm leaning against it. Without this, the type system enforces what categories of information a predicate can deal with. This change removes that and makes it easy to use a eq_file predicate with any string predicate situation causing problems.

It might seem nice to users but I am expecting the main use case of predicates is that users create them and other libraries (like assert_cmd) consume them, so improving usability for this side doesn't offer as much benefit.

Copy link

@XAMPPRocky XAMPPRocky Aug 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage I don't see why that use case would justify a more unintuitive API, I think assumes the people writing the predicates have a pre-existing level of familiarity with predicates, which will never always be the case. Since these predicates are mostly going to be used in tests, most of the time the paths are going to be str literals anyway, why add the extra noise of Path::new("…") to their tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said, my expectation is that the call to eval is not in the test but in a crate the test calls. In that case, string literals wouldn't be used and the crate author is probably dealing with a specific type anyways.

I also just checked the implementation. This conflicts with the intention of how the other predicate impls work:

impl Predicate<Path> for BinaryFilePredicate
impl Predicate<[u8]> for BinaryFilePredicate

impl Predicate<Path> for StrFilePredicate
impl Predicate<str> for StrFilePredicate

The non-path versions of the predicates allow using eq_file with in-memory test-values. Adding impl Predicate<str> for BinaryFilePredicate then has a different meaning then impl Predicate<[u8]> for BinaryFilePredicate and cannot be added to StrFilePredicate

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage I can agree that with that inconsistency would make it less than ideal, and I can't really find a better alternative.So I'm fine with that being removed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will be sure to reference the issue and squash when given the ok. Thank you so much, both of you! :)

src/path/fs.rs Outdated
use std::path;

use std::path::PathBuf;
use std::path::Path;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I know its common practice in Rust, I personally don't like useing concrete types.

The more interesting aspect is the inconsistency, there is both "use std::path" and using of concrete types. We should only do one or the other.

@kammitama5 kammitama5 changed the title Eq_Predicate ensures equality Added AsPath to eq_file Aug 3, 2018
@kammitama5 kammitama5 changed the title Added AsPath to eq_file Add AsPath to eq_file Aug 3, 2018
@kammitama5 kammitama5 changed the title Add AsPath to eq_file Add AsRef<Path> to eq_file Aug 3, 2018
src/path/fs.rs Outdated
impl BinaryFilePredicate {
fn eval(&self, path: &path::Path) -> io::Result<bool> {
let content = read_file(path)?;
fn eval<P: AsRef<path::Path>>(&self, path: P) -> io::Result<bool> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm..I guess not.

@epage
Copy link
Contributor

epage commented Aug 3, 2018

Looks good. Feel free to squash.

to avoid Monomorphism bloating.

Fixes Issue assert-rs#62

Use Predicate file path to compare strings in path

Eq Predicate ensures equality in string path

Change eq_file function to use Predicate directly
Change tests to verify that function works

Change read_file to use AsRef<Path>
Correct fs::read to be compatible with compiler

Change to read_file so not using fs::read

remove .into()

replace path:path with path

Minimalize monomorphization bloat by using changed data type in one function
Replace concrete types for consistency with rest of code base

Does not require AsRef<Path> except in top-level function.
This is for consistency with the rest of the codebase and
minimalism of monomorphism bloat
@epage epage merged commit 303e768 into assert-rs:master Aug 3, 2018
@kammitama5 kammitama5 deleted the asPathtoeq branch August 3, 2018 21:35
@epage epage mentioned this pull request Aug 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants