Skip to content

Commit

Permalink
Merge eecb24e into b603f1a
Browse files Browse the repository at this point in the history
  • Loading branch information
alexjeffburke committed Jun 27, 2020
2 parents b603f1a + eecb24e commit a1edbd6
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 74 deletions.
11 changes: 8 additions & 3 deletions Makefile
Expand Up @@ -66,10 +66,15 @@ endif

.PHONY: test
test: test-sources
@./node_modules/.bin/mocha --opts $(MOCHA_OPTS) $(TEST_SOURCES)
make test-docs

.PHONY: test-docs
test-docs:
ifeq ($(MODERN_NODE), true)
@./node_modules/.bin/mocha --opts $(MOCHA_OPTS) --require unexpected-markdown $(TEST_SOURCES) $(TEST_SOURCES_MARKDOWN)
@./node_modules/.bin/mocha --opts $(MOCHA_OPTS) --no-check-leaks --require ./bootstrap-unexpected-markdown --require unexpected-markdown $(TEST_SOURCES_MARKDOWN)
else
@./node_modules/.bin/mocha --opts $(MOCHA_OPTS) $(TEST_SOURCES)
echo "testing documentation is not supported on this version of node"
endif

nyc-includes:
Expand All @@ -81,7 +86,7 @@ endif

.PHONY: coverage
coverage: nyc-includes test-sources
@./node_modules/.bin/nyc --include $(NYC_INCLUDES) --reporter=lcov --reporter=text --all -- mocha --opts $(MOCHA_OPTS) --require unexpected-markdown $(TEST_SOURCES) $(TEST_SOURCES_MARKDOWN)
@./node_modules/.bin/nyc --include $(NYC_INCLUDES) --reporter=lcov --reporter=text --all -- mocha --opts $(MOCHA_OPTS) $(TEST_SOURCES)
@echo google-chrome coverage/lcov-report/index.html

.PHONY: test-browser
Expand Down
6 changes: 3 additions & 3 deletions bootstrap-unexpected-markdown.js
@@ -1,4 +1,4 @@
/* global unexpected:true */
unexpected = require('./lib/');
unexpected.output.preferredWidth = 80;
/* global expect:true */
expect = require('./lib/').clone();
expect.output.preferredWidth = 80;
require('./test/promisePolyfill');
61 changes: 21 additions & 40 deletions documentation/api/addAssertion.md
Expand Up @@ -7,7 +7,7 @@ Signature:

```js
expect.addAssertion(pattern, handler);
expect.addAssertion([pattern, ...]], handler);
expect.addAssertion([pattern, ...], handler);
```

`expect.addAssertion` takes two arguments:
Expand Down Expand Up @@ -77,16 +77,18 @@ expect.addAssertion('<number> to be between <number> <number>', function (
) {
expect(subject, 'to be greater than', value1).and('to be less than', value2);
});
```

```js
expect(2, 'to be between', 1, 3);
```

Assertions that support different subject or value types can be defined as
follows:
Assertions that support specific subject or value types can be defined by
separating the permissible types with a `|` character.

We use this to redefine our earlier "to have item" assertion - doing so
makes the assertion more strict, only allowing number and string values
but not boolean values, for example:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> to have item <number|string>', function (
Expand All @@ -96,12 +98,7 @@ expect.addAssertion('<array> to have item <number|string>', function (
) {
expect(subject, 'to contain', value);
});
```

This would make the assertion more strict, only allowing number and string
values but not boolean values, for example:

```js
expect([1, 2, 3], 'to have item', 2);
expect(['a', 'b', 'c'], 'to have item', 'a');
expect([true, false], 'to have item', true);
Expand All @@ -120,7 +117,7 @@ expected [ true, false ] to have item true
Different versions of the same assertion, or different assertions that share the
same handler function, can be added using an array:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion(
Expand All @@ -129,17 +126,15 @@ expect.addAssertion(
expect(subject, 'to contain', value);
}
);
```

```js
expect([1, 2, 3], 'to have item', 2);
expect([1, 2, 3], 'to have value', 3);
```

However, when it's a small deviation, as in this case, an alternation is more
handy:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> to have (item|value) <any>', function (
Expand All @@ -149,9 +144,7 @@ expect.addAssertion('<array> to have (item|value) <any>', function (
) {
expect(subject, 'to contain', value);
});
```

```js
expect([1, 2, 3], 'to have item', 2);
expect([1, 2, 3], 'to have value', 3);
```
Expand All @@ -160,7 +153,7 @@ Alternations allow branching, similar to an `if..else` statement. They are made
available to the handler function as an `expect.alternations` array which
contains the word used when the assertion is invoked:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> to have (index|value) <any>', function (
Expand All @@ -174,19 +167,18 @@ expect.addAssertion('<array> to have (index|value) <any>', function (
expect(subject, 'to contain', value);
}
});
```

```js
expect(['a', 'b'], 'to have index', 1);
expect(['a', 'b'], 'to have value', 'b');
```

## Flags

Flags allow assertions to define modifiers which can alter the behaviour of the assertion. The most common example is the `not` flag which requests that
the assertion be negated:
Flags allow assertions to define modifiers which can alter the behaviour of the assertion.
The most common example is the `not` flag which requests that the assertion be negated,
which makes the following possible:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> [not] to have item <any>', function (
Expand All @@ -200,11 +192,7 @@ expect.addAssertion('<array> [not] to have item <any>', function (
expect(subject, 'to contain', value);
}
});
```

This makes the following assertions possible:

```js
expect([1, 2, 3], 'to have item', 2);
expect([1, 2, 3], 'not to have item', 4);
```
Expand All @@ -217,7 +205,7 @@ This example could be improved further. Since
[to contain](../../assertions/array-like/to-contain/) also supports the `not`
flag, one can propagate the flag to that assertion as follows:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> [not] to have item <any>', function (
Expand All @@ -232,9 +220,11 @@ expect.addAssertion('<array> [not] to have item <any>', function (
In this way, when `to have item` is invoked with the `not` flag, that flag will
be passed along to `to contain`.

When flags are propagated, one can also invert the flag as follows:
When flags are propagated, one can also invert the flag. This means that if
`to have item` is invoked with the `not` flag, that flag will not be propagated
to `to contain` - and vice versa:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> [not] to have item <any>', function (
Expand All @@ -244,20 +234,15 @@ expect.addAssertion('<array> [not] to have item <any>', function (
) {
expect(subject, '[!not] to contain', value);
});
```

This means that if `to have item` is invoked with the `not` flag, that flag will
not be propagated to `to contain` - and vice versa:

```js
expect([1, 2, 3], 'not to have item', 2);
expect([1, 2, 3], 'to have item', 4);
```

Fun with flags, right? Flags can also be used to define optional filler words
that make an assertion read better:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion('<array> to have [this] item <any>', function (
Expand All @@ -267,9 +252,7 @@ expect.addAssertion('<array> to have [this] item <any>', function (
) {
expect(subject, 'to contain', value);
});
```

```js
expect([1, 2, 3], 'to have item', 2);
expect([1, 2, 3], 'to have this item', 2);
```
Expand Down Expand Up @@ -534,9 +517,7 @@ expect.addType({
output.jsFunctionName('Timelock');
},
});
```

```js
expect.addAssertion('<Timelock> to satisfy <any>', function (
expect,
subject,
Expand Down
35 changes: 21 additions & 14 deletions documentation/api/addType.md
Expand Up @@ -45,6 +45,15 @@ Optional members:
Adding new types to the system is best explained by an example. Let's
say we wanted to add first class support for a `Person` type:

<!-- unexpected-markdown hide:true -->

```js
const originalExpect = expect;
expect = expect.clone();
```

<!-- unexpected-markdown persist:true -->

```js
function Person(name, age) {
this.name = name;
Expand Down Expand Up @@ -94,7 +103,7 @@ That is already quite helpful, but it would be even nicer if the
stringification of `Person` instances could read as valid calls to the
constructor. We can fix that by implementing an `inspect` method on the type.

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addType({
Expand All @@ -112,14 +121,12 @@ expect.addType({
.text(')');
},
});
```

Now we get the following output:

```js
expect(new Person('John Doe', 42), 'to equal', new Person('Jane Doe', 24));
```

Now we get the following output:

```output
expected new Person('John Doe', 42) to equal new Person('Jane Doe', 24)
Expand Down Expand Up @@ -150,7 +157,7 @@ same depth to the `inspect` function.
Let's say we wanted `Person` instances only to be compared by name and not by
age. Then we need to override the `equal` method:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addType({
Expand All @@ -177,7 +184,7 @@ This will produce the same output as above, but that means the diff if
wrong. It states that the age should be changed. We can fix that the
following way:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addType({
Expand Down Expand Up @@ -205,9 +212,7 @@ expect.addType({
);
},
});
```

```js
expect(new Person('John Doe', 42), 'to equal', new Person('Jane Doe', 24));
```

Expand All @@ -231,7 +236,11 @@ on the base directly when you know it is the one you need.

You could also do something really custom as seen below:

<!-- unexpected-markdown freshExpect:true -->
<!-- unexpected-markdown hide:true -->

```js
expect = originalExpect;
```

```js
var inlineDiff = true; // used to change inlining in a later example
Expand Down Expand Up @@ -281,14 +290,12 @@ expect.addType({
return output;
},
});
```

That would produce the following output.

```js
expect(new Person('John Doe', 42), 'to equal', new Person('Jane Doe', 24));
```

That produces the following output:

```output
expected new Person('John Doe', 42) to equal new Person('Jane Doe', 24)
Expand Down
8 changes: 3 additions & 5 deletions documentation/api/clone.md
Expand Up @@ -8,21 +8,19 @@ Adding new functionality to the cloned instance will not affect the
original instance:

```js
var originalExpect = expect;

expect = expect
var clonedExpect = expect
.clone()
.addAssertion('<number> to be an integer', function (expect, subject) {
expect(Math.round(subject), 'to be', subject);
});

expect(42, 'to be an integer');
clonedExpect(42, 'to be an integer');
```

If we try to use the new assertion on the original instance it fails:

```js
originalExpect(42, 'to be an integer');
expect(42, 'to be an integer');
```

```output
Expand Down
2 changes: 1 addition & 1 deletion documentation/api/shift.md
Expand Up @@ -32,7 +32,7 @@ optionally takes one via `<assertion?>` and is invoked without,
`expect.shift` will propagate its argument as the fulfillment value of the
promise returned from your assertion:

<!-- unexpected-markdown async:true, freshExpect:true -->
<!-- unexpected-markdown freshContext:true -->

```js
expect.addAssertion(
Expand Down
Expand Up @@ -40,13 +40,15 @@ The parameters passed to the callback (excluding the falsy error) are also
provided as the value of the returned promise, so you can do further
assertions like this:

<!-- unexpected-markdown async:true -->

```js
function asyncFn(cb) {
cb(null, 123, 456);
}
```

<!-- unexpected-markdown async:true -->

```js
return expect(asyncFn, 'to call the callback without error').then(function (
args
) {
Expand Down

0 comments on commit a1edbd6

Please sign in to comment.