Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented new semantics for the 'was called with' assertion. #29

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
81 changes: 11 additions & 70 deletions documentation/assertions/spy/was-called-with.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@ Passes if the spy was called with the provided arguments.

```js
var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
expect(mySpy, 'was called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
mySpy({ foo: 'bar' }, 'baz', 'quux');
expect(mySpy, 'was called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);
```

In case of a failing expectation you get the following output:

```js
expect(mySpy, 'was called with', 'baz', { foo: 'bar' });
expect(mySpy, 'was called with', [ 'baz', { foo: 'bar' }, 'quux' ]);
```

```output
expected mySpy was called with 'baz', { foo: 'bar' }
expected mySpy was called with [ 'baz', { foo: 'bar' }, 'quux' ]

mySpy(
{ foo: 'bar' }, // should equal 'baz'
'baz', // should equal { foo: 'bar' }
'qux',
'quux'
); at theFunction (theFileName:xx:yy)
```
Expand All @@ -28,82 +27,24 @@ passes if the spy was always called with the provided arguments.

```js
var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
expect(mySpy, 'was always called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
mySpy({ foo: 'bar' }, 'baz', true);
mySpy({ foo: 'bar' }, 'baz', true);
expect(mySpy, 'was always called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);
```

In case of a failing expectation you get the following output:

```js
mySpy({ foo: 'bar' }, 'baz');
expect(mySpy, 'was always called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
expect(mySpy, 'was always called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);
```

```output
expected mySpy
was always called with { foo: 'bar' }, 'baz', expect.it('to be truthy')
was always called with [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]

mySpy( { foo: 'bar' }, 'baz', 'qux', 'quux' ); at theFunction (theFileName:xx:yy)
mySpy( { foo: 'bar' }, 'baz', 'qux', 'quux' ); at theFunction (theFileName:xx:yy)
mySpy(
{ foo: 'bar' },
'baz'
// missing: should be truthy
); at theFunction (theFileName:xx:yy)
```

I case you want to ensure that the spy was called with the provided
arguments and no others, you can use the `exactly` flag.

```js
var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
expect(mySpy, 'was called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'), 'quux');
```

In case of a failing expectation you get the following output:

```js
expect(mySpy, 'was called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
```

```output
expected mySpy
was called with exactly { foo: 'bar' }, 'baz', expect.it('to be truthy')

mySpy(
{ foo: 'bar' },
'baz',
'qux',
'quux' // should be removed
); at theFunction (theFileName:xx:yy)
```

It is of course also possible to combine the two flags, that will then
pass if the spy was always called with the provided arguments and no
others.

```js
var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux');
mySpy({ foo: 'bar' }, 'baz', 'qux');
expect(mySpy, 'was always called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
```

In case of a failing expectation you get the following output:

```js
mySpy({ foo: 'bar' }, 'baz');
expect(mySpy, 'was always called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
```

```output
expected mySpy
was always called with exactly { foo: 'bar' }, 'baz', expect.it('to be truthy')

mySpy( { foo: 'bar' }, 'baz', 'qux' ); at theFunction (theFileName:xx:yy)
mySpy( { foo: 'bar' }, 'baz', 'qux' ); at theFunction (theFileName:xx:yy)
mySpy( { foo: 'bar' }, 'baz', true ); at theFunction (theFileName:xx:yy)
mySpy( { foo: 'bar' }, 'baz', true ); at theFunction (theFileName:xx:yy)
mySpy(
{ foo: 'bar' },
'baz'
Expand Down
2 changes: 1 addition & 1 deletion documentation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var obj = { spy: sinon.spy() };
obj.spy(42);
obj.spy({ foo: 'bar' }, 'baz', "qux");
expect(obj.spy, "was called twice");
expect(obj.spy, 'was called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
expect(obj.spy, 'was called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);
expect(obj.spy, 'was always called on', obj);
```

Expand Down
19 changes: 2 additions & 17 deletions lib/unexpected-sinon.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,18 +497,8 @@
}
});

expect.addAssertion('<spy> was [always] called with [exactly] <any*>', function (expect, subject) {
expect.addAssertion('<spy> was [always] called with <array>', function (expect, subject, args) {
expect.errorMode = 'defaultOrNested';
var args;
if (expect.flags.exactly) {
args = Array.prototype.slice.call(arguments, 2);
} else {
args = {};
for (var i = 2; i < arguments.length; i += 1) {
args[i - 2] = arguments[i];
}
}

var calls = getCalls(subject);
if (expect.flags.always) {
return expect(calls, 'to have items satisfying', { args: args });
Expand All @@ -530,13 +520,8 @@
}
});

expect.addAssertion('<spy> was never called with <any*>', function (expect, subject) {
expect.addAssertion('<spy> was never called with <any*>', function (expect, subject, args) {
expect.errorMode = 'defaultOrNested';
var args = {};
for (var i = 2; i < arguments.length; i += 1) {
args[i - 2] = arguments[i];
}

var calls = getCalls(subject);

var promises = calls.map(function (call) {
Expand Down
83 changes: 14 additions & 69 deletions test/documentation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,104 +511,49 @@ describe("documentation tests", function () {
it("assertions/spy/was-called-with.md contains correct examples", function () {
var testPromises = [];
var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
expect(mySpy, 'was called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
mySpy({ foo: 'bar' }, 'baz', 'quux');
expect(mySpy, 'was called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);

try {
expect(mySpy, 'was called with', 'baz', { foo: 'bar' });
expect(mySpy, 'was called with', [ 'baz', { foo: 'bar' }, 'quux' ]);
expect.fail(function (output) {
output.error("expected:").nl();
output.code("expect(mySpy, 'was called with', 'baz', { foo: 'bar' });").nl();
output.code("expect(mySpy, 'was called with', [ 'baz', { foo: 'bar' }, 'quux' ]);").nl();
output.error("to throw");
});
} catch (e) {
expect(e, "to have message",
"expected mySpy was called with 'baz', { foo: 'bar' }\n" +
"expected mySpy was called with [ 'baz', { foo: 'bar' }, 'quux' ]\n" +
"\n" +
"mySpy(\n" +
" { foo: 'bar' }, // should equal 'baz'\n" +
" 'baz', // should equal { foo: 'bar' }\n" +
" 'qux',\n" +
" 'quux'\n" +
"); at theFunction (theFileName:xx:yy)"
);
}

var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
expect(mySpy, 'was always called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
mySpy({ foo: 'bar' }, 'baz', true);
mySpy({ foo: 'bar' }, 'baz', true);
expect(mySpy, 'was always called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);

try {
mySpy({ foo: 'bar' }, 'baz');
expect(mySpy, 'was always called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
expect(mySpy, 'was always called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);
expect.fail(function (output) {
output.error("expected:").nl();
output.code("mySpy({ foo: 'bar' }, 'baz');").nl();
output.code("expect(mySpy, 'was always called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));").nl();
output.code("expect(mySpy, 'was always called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);").nl();
output.error("to throw");
});
} catch (e) {
expect(e, "to have message",
"expected mySpy\n" +
"was always called with { foo: 'bar' }, 'baz', expect.it('to be truthy')\n" +
"was always called with [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]\n" +
"\n" +
"mySpy( { foo: 'bar' }, 'baz', 'qux', 'quux' ); at theFunction (theFileName:xx:yy)\n" +
"mySpy( { foo: 'bar' }, 'baz', 'qux', 'quux' ); at theFunction (theFileName:xx:yy)\n" +
"mySpy(\n" +
" { foo: 'bar' },\n" +
" 'baz'\n" +
" // missing: should be truthy\n" +
"); at theFunction (theFileName:xx:yy)"
);
}

var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux', 'quux');
expect(mySpy, 'was called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'), 'quux');

try {
expect(mySpy, 'was called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
expect.fail(function (output) {
output.error("expected:").nl();
output.code("expect(mySpy, 'was called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));").nl();
output.error("to throw");
});
} catch (e) {
expect(e, "to have message",
"expected mySpy\n" +
"was called with exactly { foo: 'bar' }, 'baz', expect.it('to be truthy')\n" +
"\n" +
"mySpy(\n" +
" { foo: 'bar' },\n" +
" 'baz',\n" +
" 'qux',\n" +
" 'quux' // should be removed\n" +
"); at theFunction (theFileName:xx:yy)"
);
}

var mySpy = sinon.spy().named('mySpy');
mySpy({ foo: 'bar' }, 'baz', 'qux');
mySpy({ foo: 'bar' }, 'baz', 'qux');
expect(mySpy, 'was always called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));

try {
mySpy({ foo: 'bar' }, 'baz');
expect(mySpy, 'was always called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
expect.fail(function (output) {
output.error("expected:").nl();
output.code("mySpy({ foo: 'bar' }, 'baz');").nl();
output.code("expect(mySpy, 'was always called with exactly', { foo: 'bar' }, 'baz', expect.it('to be truthy'));").nl();
output.error("to throw");
});
} catch (e) {
expect(e, "to have message",
"expected mySpy\n" +
"was always called with exactly { foo: 'bar' }, 'baz', expect.it('to be truthy')\n" +
"\n" +
"mySpy( { foo: 'bar' }, 'baz', 'qux' ); at theFunction (theFileName:xx:yy)\n" +
"mySpy( { foo: 'bar' }, 'baz', 'qux' ); at theFunction (theFileName:xx:yy)\n" +
"mySpy( { foo: 'bar' }, 'baz', true ); at theFunction (theFileName:xx:yy)\n" +
"mySpy( { foo: 'bar' }, 'baz', true ); at theFunction (theFileName:xx:yy)\n" +
"mySpy(\n" +
" { foo: 'bar' },\n" +
" 'baz'\n" +
Expand Down Expand Up @@ -726,7 +671,7 @@ describe("documentation tests", function () {
obj.spy(42);
obj.spy({ foo: 'bar' }, 'baz', "qux");
expect(obj.spy, "was called twice");
expect(obj.spy, 'was called with', { foo: 'bar' }, 'baz', expect.it('to be truthy'));
expect(obj.spy, 'was called with', [ { foo: 'bar' }, 'baz', expect.it('to be truthy') ]);
expect(obj.spy, 'was always called on', obj);

var spy = sinon.spy();
Expand Down