Why does this assertion fail?


#1

Hello, I have a test which fails but I can’t understand why.

#[derive(PartialEq)]
pub enum Expr {
    Value(Filter),
    Or(Box<Expr>, Box<Expr>),
    And(Box<Expr>, Box<Expr>),
    Parenthesis(Box<Expr>),
}

impl fmt::Debug for Expr {
    fn fmt(&self, format: &mut fmt::Formatter) -> fmt::Result {
        use self::Expr::*;
        match *self {
            Value(ref val) => write!(format, "{:?}", val),
            Or(ref left, ref right) => write!(format, "({:?} OR {:?})", left, right),
            And(ref left, ref right) => write!(format, "({:?} AND {:?})", left, right),
            Parenthesis(ref expr) => write!(format, "{:?}", expr),
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum Oper {
    Or,
    And,
}

#[derive(Debug, PartialEq)]
pub enum Filter {
    RoomId(Uuid),
    OwnerId(Uuid),
    HolderId(Uuid),
}

    #[test]
    fn parse_parenthesis() {
        let room_id = Uuid::parse_str("7945cf5b-2c73-4936-80cb-5cce27e9950d").unwrap();
        let owner_id = Uuid::parse_str("55e813bc-0c9b-4270-9f7f-81e5ffcfc9ff").unwrap();
        let holder_id = Uuid::parse_str("30ae48f8-57c1-4704-ba48-19edb3c22b09").unwrap();

        let input = format!(
            " ( owner_id:{}  OR holders.id:{} ) AND room_id:{} ",
            owner_id, holder_id, room_id
        );
        let expected = Expr::And(
            Box::new(Expr::Or(
                Box::new(Expr::Value(Filter::OwnerId(owner_id))),
                Box::new(Expr::Value(Filter::HolderId(holder_id))),
            )),
            Box::new(Expr::Value(Filter::RoomId(room_id))),
        );

        assert_eq!(expr(CompleteStr(&input)), Ok((CompleteStr(""), expected)));
    }
---- messages::query_parameters::tests::parse_parenthesis stdout ----
	thread 'messages::query_parameters::tests::parse_parenthesis' panicked at 'assertion failed: `(left == right)`
  left: `Ok((CompleteStr(""), ((OwnerId(Uuid("55e813bc-0c9b-4270-9f7f-81e5ffcfc9ff")) OR HolderId(Uuid("30ae48f8-57c1-4704-ba48-19edb3c22b09"))) AND RoomId(Uuid("7945cf5b-2c73-4936-80cb-5cce27e9950d")))))`,
 right: `Ok((CompleteStr(""), ((OwnerId(Uuid("55e813bc-0c9b-4270-9f7f-81e5ffcfc9ff")) OR HolderId(Uuid("30ae48f8-57c1-4704-ba48-19edb3c22b09"))) AND RoomId(Uuid("7945cf5b-2c73-4936-80cb-5cce27e9950d")))))`', src/messages/query_parameters.rs:244:9

As far as I can see left and right are equal.
Is there any trick here or I am missing something?


#2

I do not see a difference at well, but the output seems not to be something I’d use as a format for Debug.

My first shot to debug this were to actually compare proper Debug output (something that show the true data as it would have been formatted by a derive) and then digging into the implementation of (Partial)Eq.

Please remember, we do not know anything about your Expr-type, except that it probably has some impl of at least PartialEq and seems to be an enum with at least And, Or and Value variants.


#3

Thanks for the reply @NobbZ. I have added information about these types to the question.


#4

It turns out there was Expr::Parenthesis node missing.
It should be

let expected = Expr::And(
            Box::new(Expr::Parenthesis(
                Box::new(Expr::Or(
                    Box::new(Expr::Value(Filter::OwnerId(owner_id))),
                    Box::new(Expr::Value(Filter::HolderId(holder_id))),
                ))
            )),
            Box::new(Expr::Value(Filter::RoomId(room_id))),
        );

Totally my bad. I definitely should inspect it with derive(Debug).

Thanks once again!


#5

Still an assumption, but maybe your visual problem is related to the fact that you completely omit parenthesis in your debug where you have them in your AST, but print them when there are non in your AST. That’s why I said it’s best to use derived Debug for such things.