@Test
  void not() {
    assertExpressional(person.fullName.not(n -> n.is("John")),
            "call op=NOT",
                    "  call op=EQUAL path=fullName constant=John");

    assertExpressional(person.not(f -> f.fullName.is("John").bestFriend.isPresent()),
            "call op=NOT",
                    "  call op=AND",
                    "    call op=EQUAL path=fullName constant=John",
                    "    call op=IS_PRESENT path=bestFriend");

    assertExpressional(PersonCriteria.person.age.atLeast(21).not(p -> p.isActive.isTrue()),
            "call op=AND",
            "  call op=GREATER_THAN_OR_EQUAL path=age constant=21",
            "  call op=NOT",
            "    call op=EQUAL path=isActive constant=true");
  }
Tests that expression is built correctly by "serializing" it to string.
It is easier to debug expression when it is presented as human-readable tree
criteria/common/test/org/immutables/criteria/ExpressionAsStringTest.java