Negation

When using .not in an expression we are not actually mutating the subject, what it does is allow the resolver to continue and when a result has finally been found it'll inverse it before we obtain it. It's indeed negating the result of the expression.

ass('foo').not.number;
// It even supports async expressions
ass(promise).not.resolves.string.equal('foo');

Caution

Negating an initialized expression may produce unexpected effects, basically for synchronous initialized expressions the evaluator runs for every new expectation we attach to it.

// This one won't work since .string is true and will be evaluated before
// we can reach the .equal that would resolve as false.
ass('foo').not.string.equal('bar')

// Here it works because we only have one expectation after .not
ass('foo').not.equal('bar')

// In some scenarios we can solve it by moving the `.not` to the right
ass('foo').string.not.equal('bar')

// By using composition we can also work around it
ass('foo').not.eq( ass.string.equal('bar') )

// And obviously it's always possible to avoid using an initialized expression
ass.not.string.equal('bar').assert('foo')