TEST(NotMatchExpression, MatchesScalar) {
    BSONObj baseOperand = BSON("$lt" << 5);
    unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
    ASSERT(lt->init("a", baseOperand["$lt"]).isOK());
    NotMatchExpression notOp;
    ASSERT(notOp.init(lt.release()).isOK());
    ASSERT(notOp.matchesBSON(BSON("a" << 6), NULL));
    ASSERT(!notOp.matchesBSON(BSON("a" << 4), NULL));
}
TEST(NotMatchExpression, MatchesArray) {
    BSONObj baseOperand = BSON("$lt" << 5);
    unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
    ASSERT(lt->init("a", baseOperand["$lt"]).isOK());
    NotMatchExpression notOp;
    ASSERT(notOp.init(lt.release()).isOK());
    ASSERT(notOp.matchesBSON(BSON("a" << BSON_ARRAY(6)), NULL));
    ASSERT(!notOp.matchesBSON(BSON("a" << BSON_ARRAY(4)), NULL));
    // All array elements must match.
    ASSERT(!notOp.matchesBSON(BSON("a" << BSON_ARRAY(4 << 5 << 6)), NULL));
}
TEST(NotMatchExpression, ElemMatchKey) {
    BSONObj baseOperand = BSON("$lt" << 5);
    unique_ptr<ComparisonMatchExpression> lt(new LTMatchExpression());
    ASSERT(lt->init("a", baseOperand["$lt"]).isOK());
    NotMatchExpression notOp;
    ASSERT(notOp.init(lt.release()).isOK());
    MatchDetails details;
    details.requestElemMatchKey();
    ASSERT(!notOp.matchesBSON(BSON("a" << BSON_ARRAY(1)), &details));
    ASSERT(!details.hasElemMatchKey());
    ASSERT(notOp.matchesBSON(BSON("a" << 6), &details));
    ASSERT(!details.hasElemMatchKey());
    ASSERT(notOp.matchesBSON(BSON("a" << BSON_ARRAY(6)), &details));
    // elemMatchKey is not implemented for negative match operators.
    ASSERT(!details.hasElemMatchKey());
}