Skip to content

Commit

Permalink
Finish the implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
rzadp committed Jul 21, 2022
1 parent 9fe3c84 commit 5fdbead
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 74 deletions.
20 changes: 20 additions & 0 deletions waffle-chai/src/matchers/misc/struct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const isStruct = (arr: any[]) => {
if (!Array.isArray(arr)) return false;
const keys = Object.keys(arr);
const hasAlphaNumericKeys = keys.some((key) => key.match(/^[a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*$/));
const hasNumericKeys = keys.some((key) => key.match(/^\d+$/));
return hasAlphaNumericKeys && hasNumericKeys;
};

export const convertStructToPlainObject = (struct: any[]): any => {
const keys = Object.keys(struct).filter((key: any) => isNaN(key));
return keys.reduce(
(acc: any, key: any) => ({
...acc,
[key]: isStruct(struct[key])
? convertStructToPlainObject(struct[key])
: struct[key]
}),
{}
);
};
22 changes: 1 addition & 21 deletions waffle-chai/src/matchers/withArgs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {utils} from 'ethers';
import {convertStructToPlainObject, isStruct} from './misc/struct';

/**
* Used for testing the arguments of events or custom errors.
Expand Down Expand Up @@ -74,27 +75,6 @@ export function supportWithArgs(Assertion: Chai.AssertionStatic) {
);
};

const isStruct = (arr: any[]) => {
if (!Array.isArray(arr)) return false;
const keys = Object.keys(arr);
const hasAlphaNumericKeys = keys.some((key) => key.match(/^[a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*$/));
const hasNumericKeys = keys.some((key) => key.match(/^\d+$/));
return hasAlphaNumericKeys && hasNumericKeys;
};

const convertStructToPlainObject = (struct: any[]): any => {
const keys = Object.keys(struct).filter((key: any) => isNaN(key));
return keys.reduce(
(acc: any, key: any) => ({
...acc,
[key]: isStruct(struct[key])
? convertStructToPlainObject(struct[key])
: struct[key]
}),
{}
);
};

Assertion.addMethod('withArgs', function (this: any, ...expectedArgs: any[]) {
if (!('txMatcher' in this) || !('callPromise' in this)) {
throw new Error('withArgs() must be used after emit() or revertedWith()');
Expand Down
58 changes: 7 additions & 51 deletions waffle-chai/src/matchers/withNamedArgs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {BytesLike, utils} from 'ethers';
import {Hexable} from 'ethers/lib/utils';
import {convertStructToPlainObject, isStruct} from './misc/struct';

/**
* Used for testing the arguments of events or custom errors, naming the arguments.
Expand Down Expand Up @@ -32,42 +33,18 @@ export function supportWithNamedArgs(Assertion: Chai.AssertionStatic) {
`to be hash of or equal to "${expectedValue}"`
).to.be.oneOf([expectedValue, utils.keccak256(expectedArgBytes)]);
} else {
if (isStruct(actualArgs[paramIndex])) {
new Assertion(
convertStructToPlainObject(actualArgs[paramIndex])
).to.deep.equal(expectedValue);
return;
}
new Assertion(actualArgs[paramIndex],
`value of "${key}" argument in the "${context.eventName}" event`)
.equal(expectedValue);
}
}
}

// for (let index = 0; index < expectedArgs.length; index++) {
// if (expectedArgs[index]?.length !== undefined && typeof expectedArgs[index] !== 'string') {
// context.assert(
// actualArgs[index].length === expectedArgs[index].length,
// `Expected ${actualArgs[index]} to equal ${expectedArgs[index]}, ` +
// 'but they have different lengths',
// 'Do not combine .not. with .withArgs()'
// );
// for (let j = 0; j < expectedArgs[index].length; j++) {
// new Assertion(actualArgs[index][j]).equal(expectedArgs[index][j]);
// }
// } else {
// if (actualArgs[index].hash !== undefined && actualArgs[index]._isIndexed === true) {
// const expectedArgBytes = utils.isHexString(expectedArgs[index])
// ? utils.arrayify(expectedArgs[index]) : utils.toUtf8Bytes(expectedArgs[index]);
// new Assertion(actualArgs[index].hash).to.be.oneOf(
// [expectedArgs[index], utils.keccak256(expectedArgBytes)]
// );
// } else {
// if (isStruct(actualArgs[index])) {
// new Assertion(
// convertStructToPlainObject(actualArgs[index])
// ).to.deep.equal(expectedArgs[index]);
// return;
// }
// new Assertion(actualArgs[index]).equal(expectedArgs[index]);
// }
// }
// }
};

const tryAssertArgsObjectEqual = (context: any, expectedArgs: Record<string, unknown>, args: any[]) => {
Expand All @@ -87,27 +64,6 @@ export function supportWithNamedArgs(Assertion: Chai.AssertionStatic) {
);
};

const isStruct = (arr: any[]) => {
if (!Array.isArray(arr)) return false;
const keys = Object.keys(arr);
const hasAlphaNumericKeys = keys.some((key) => key.match(/^[a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*$/));
const hasNumericKeys = keys.some((key) => key.match(/^\d+$/));
return hasAlphaNumericKeys && hasNumericKeys;
};

const convertStructToPlainObject = (struct: any[]): any => {
const keys = Object.keys(struct).filter((key: any) => isNaN(key));
return keys.reduce(
(acc: any, key: any) => ({
...acc,
[key]: isStruct(struct[key])
? convertStructToPlainObject(struct[key])
: struct[key]
}),
{}
);
};

Assertion.addMethod('withNamedArgs', function (this: any, expectedArgs: Record<string, unknown>) {
if (!('txMatcher' in this) || !('callPromise' in this)) {
throw new Error('withNamedArgs() must be used after emit()');
Expand Down
45 changes: 43 additions & 2 deletions waffle-chai/test/matchers/eventsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ export const eventsTest = (provider: TestProvider) => {
it('Emit struct: fail', async () => {
const struct = {
...emittedStruct,
value: BigNumber.from(2) // different
value: emittedStruct.value.add('1')
};
await expect(
expect(events.emitStruct()).to.emit(events, 'Struct').withArgs(struct)
Expand All @@ -519,7 +519,7 @@ export const eventsTest = (provider: TestProvider) => {
...emittedNestedStruct,
task: {
...emittedStruct,
value: BigNumber.from(2) // different
value: emittedStruct.value.add('1')
}
};
await expect(
Expand Down Expand Up @@ -657,5 +657,46 @@ export const eventsWithNamedArgs = (provider: TestProvider) => {
'"invalid" argument in the "Index" event not found: expected -1 to be at least 0'
);
});

it('Emit struct: success', async () => {
await expect(events.emitStruct())
.to.emit(events, 'Struct')
.withNamedArgs({task: emittedStruct});
});

it('Emit struct: fail', async () => {
const struct = {
...emittedStruct,
value: emittedStruct.value.add('1')
};
await expect(
expect(events.emitStruct()).to.emit(events, 'Struct').withNamedArgs({task: struct})
).to.be.eventually.rejectedWith(
AssertionError,
'expected { Object (hash, value, ...) } to deeply equal { Object (hash, value, ...) }'
);
});

it('Emit nested struct: success', async () => {
await expect(events.emitNestedStruct())
.to.emit(events, 'NestedStruct')
.withNamedArgs({nested: emittedNestedStruct});
});

it('Emit nested struct: fail', async () => {
const nestedStruct = {
...emittedNestedStruct,
task: {
...emittedStruct,
value: emittedStruct.value.add('1')
}
};
await expect(
expect(events.emitNestedStruct()).to.emit(events, 'NestedStruct').withNamedArgs({nested: nestedStruct})
).to.be.eventually.rejectedWith(
AssertionError,
'{ Object (hash, value, ...) } to deeply equal { Object (hash, value, ...) }'
);
});
});
};

0 comments on commit 5fdbead

Please sign in to comment.