Skip to content

Commit

Permalink
Merge pull request #6 from stschulte/new-matcher
Browse files Browse the repository at this point in the history
Add new matcher toHaveReceivedCommandExactlyOnceWith
  • Loading branch information
stschulte authored Jan 17, 2025
2 parents 65bf09e + 38bd57f commit 32a1b6d
Show file tree
Hide file tree
Showing 9 changed files with 1,478 additions and 802 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- matcher `toHaveReceivedCommandExactlyOnceWith` can be used to verify there are
no additional calls

### Changed

- Update dependencies. This bumps `@vitest/expect` dependency to `^3.0.1`

## [5.1.0] - 2025-01-11

### Changed
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ You must register the new matchers explicity (think about putting this to a [set
},
});
to add the custom mat chers before each test run
to add the custom matchers before each test run
*/
import { expect } from "vitest";
import {
Expand All @@ -57,6 +57,8 @@ import {
toHaveReceivedLastCommandWith,
toReceiveAnyCommand,
toHaveReceivedAnyCommand,
toReceiveCommandExactlyOnceWith,
toHaveReceivedCommandExactlyOnceWith,
} from "aws-sdk-client-mock-vitest";

expect.extend({
Expand All @@ -74,6 +76,8 @@ expect.extend({
toHaveReceivedLastCommandWith,
toReceiveAnyCommand,
toHaveReceivedAnyCommand,
toReceiveCommandExactlyOnceWith,
toHaveReceivedCommandExactlyOnceWith,
});
```

Expand Down
1,047 changes: 516 additions & 531 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,24 @@
"aws-sdk-client-mock": ">=2.2.0"
},
"dependencies": {
"@vitest/expect": "^2.1.3",
"tslib": "^2.8.0"
"@vitest/expect": "^3.0.2",
"tslib": "^2.8.1"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.726.1",
"@aws-sdk/client-secrets-manager": "^3.726.1",
"@aws-sdk/client-s3": "^3.730.0",
"@aws-sdk/client-secrets-manager": "^3.730.0",
"@eslint/js": "^9.18.0",
"@stylistic/eslint-plugin": "^2.12.1",
"@stylistic/eslint-plugin": "^2.13.0",
"@types/eslint__js": "^8.42.3",
"@types/node": "^22.10.5",
"@vitest/coverage-v8": "^2.1.8",
"@vitest/eslint-plugin": "^1.1.24",
"@types/node": "^22.10.7",
"@vitest/coverage-v8": "^3.0.2",
"@vitest/eslint-plugin": "^1.1.25",
"aws-sdk-client-mock": "^4.1.0",
"eslint": "^9.18.0",
"eslint-config-flat-gitignore": "^1.0.0",
"eslint-plugin-perfectionist": "^4.6.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.19.1",
"vitest": "^2.1.8"
"typescript-eslint": "^8.20.0",
"vitest": "^3.0.2"
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ export type { CustomMatcher } from './matcher.js';
export {
toHaveReceivedAnyCommand,
toHaveReceivedCommand,
toHaveReceivedCommandExactlyOnceWith,
toHaveReceivedCommandOnce,
toHaveReceivedCommandTimes,
toHaveReceivedCommandWith,
toHaveReceivedLastCommandWith,
toHaveReceivedNthCommandWith,
toReceiveAnyCommand,
toReceiveCommand,
toReceiveCommandExactlyOnceWith,
toReceiveCommandOnce,
toReceiveCommandTimes,
toReceiveCommandWith,
Expand Down
40 changes: 38 additions & 2 deletions src/matcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { notNull, ordinalOf } from './utils.js';
interface AliasMatcher<R> {
toReceiveAnyCommand: BaseMatcher<R>['toHaveReceivedAnyCommand'];
toReceiveCommand: BaseMatcher<R>['toHaveReceivedCommand'];
toReceiveCommandExactlyOnceWith: BaseMatcher<R>['toHaveReceivedCommandExactlyOnceWith'];
toReceiveCommandOnce: BaseMatcher<R>['toHaveReceivedCommandOnce'];
toReceiveCommandTimes: BaseMatcher<R>['toHaveReceivedCommandTimes'];
toReceiveCommandWith: BaseMatcher<R>['toHaveReceivedCommandWith'];
Expand All @@ -39,6 +40,14 @@ interface BaseMatcher<R> {
command: AwsCommandConstructur<Input, Output>
): R;

toHaveReceivedCommandExactlyOnceWith<
Input extends object,
Output extends MetadataBearer,
>(
command: AwsCommandConstructur<Input, Output>,
input: Partial<Input>
): R;

toHaveReceivedCommandOnce<
Input extends object,
Output extends MetadataBearer,
Expand Down Expand Up @@ -209,9 +218,34 @@ function toHaveReceivedCommandWith(
};
};
const toReceiveCommandWith = toHaveReceivedCommandWith;
/*

*/
function toHaveReceivedCommandExactlyOnceWith(
this: MatcherState,
client: AwsStub<any, any, any>,
command: AwsCommandConstructur<any, any>,
input: Record<string, any>,
): ExpectationResult {
const { isNot, utils } = this;
const calls = client.commandCalls(command);

const hasCallWithArgs = calls.some(call =>
new ObjectContaining(input).asymmetricMatch(call.args[0].input),
);

const pass = calls.length === 1 && hasCallWithArgs;

return {
message: () => {
const message = isNot
? `expected "${command.name}" to not be called once with arguments: ${utils.printExpected(input)}`
: `expected "${command.name}" to be called once with arguments: ${utils.printExpected(input)}`;
return formatCalls(this, client, command, input, message);
},
pass,
};
};
const toReceiveCommandExactlyOnceWith = toHaveReceivedCommandExactlyOnceWith;

function toHaveReceivedNthCommandWith(
this: MatcherState,
client: AwsStub<any, any, any>,
Expand Down Expand Up @@ -289,13 +323,15 @@ export type { CustomMatcher };
export {
toHaveReceivedAnyCommand,
toHaveReceivedCommand,
toHaveReceivedCommandExactlyOnceWith,
toHaveReceivedCommandOnce,
toHaveReceivedCommandTimes,
toHaveReceivedCommandWith,
toHaveReceivedLastCommandWith,
toHaveReceivedNthCommandWith,
toReceiveAnyCommand,
toReceiveCommand,
toReceiveCommandExactlyOnceWith,
toReceiveCommandOnce,
toReceiveCommandTimes,
toReceiveCommandWith,
Expand Down
8 changes: 7 additions & 1 deletion tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { describe, expect, it } from 'vitest';
import {
toHaveReceivedAnyCommand,
toHaveReceivedCommand,
toHaveReceivedCommandExactlyOnceWith,
toHaveReceivedCommandOnce,
toHaveReceivedCommandTimes,
toHaveReceivedCommandWith,
toHaveReceivedLastCommandWith,
toHaveReceivedNthCommandWith,
toReceiveAnyCommand,
toReceiveCommand,
toReceiveCommandExactlyOnceWith,
toReceiveCommandOnce,
toReceiveCommandTimes,
toReceiveCommandWith,
Expand All @@ -22,13 +24,15 @@ import {
expect.extend({
toHaveReceivedAnyCommand,
toHaveReceivedCommand,
toHaveReceivedCommandExactlyOnceWith,
toHaveReceivedCommandOnce,
toHaveReceivedCommandTimes,
toHaveReceivedCommandWith,
toHaveReceivedLastCommandWith,
toHaveReceivedNthCommandWith,
toReceiveAnyCommand,
toReceiveCommand,
toReceiveCommandExactlyOnceWith,
toReceiveCommandOnce,
toReceiveCommandTimes,
toReceiveCommandWith,
Expand All @@ -52,7 +56,9 @@ describe('aws-sdk-client-mock-vitest', () => {
'toReceiveLastCommandWith',
'toReceiveNthCommandWith',
'toReceiveAnyCommand',
])('should be able to extend with %s', (matcher) => {
'toReceiveCommandExactlyOnceWith',
'toHaveReceivedCommandExactlyOnceWith',
])('extend matcher to extend with %s', (matcher) => {
expect(expect('something')).toHaveProperty(matcher);
});

Expand Down
Loading

0 comments on commit 32a1b6d

Please sign in to comment.