Skip to content

Commit

Permalink
refactor: improved matchers with more natural patterns and checks
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanVerbner committed Aug 15, 2023
1 parent 1cc2e47 commit 55355e5
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 58 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ npm --save-dev install mina-jest-matchers #TODO

## Using Jest matchers

Import it in your tests as:
Import it in your tests as follows:

```typescript
// Impor to extend the matchers
Expand All @@ -26,10 +26,12 @@ describe('my test', () => {

// Matchers are automatically recognized by jest
expect(Field(19)).toEqual(19);
expect(app.someBooleanState.get()).toBeFalse()
expect(app.someBooleanState).toBeFalse()
})
```
You can refer to [contract.test.ts](./test/contract/test-contract.ts) for a running example.
# Development
## Requirements
Expand Down
2 changes: 1 addition & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import configFieldMatchers from "./matchers/field";
import configFieldMatchers from "./matchers/common-types";
import configBoolMatchers from "./matchers/bool";

configFieldMatchers();
Expand Down
53 changes: 53 additions & 0 deletions lib/matchers/common-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* This module exports a Jest matcher that extends the expect object with a custom matcher called "toEqual".
* The "toEqual" matcher is used to compare two snarkyjs Field objects, or a Field object with a string or number.
*/
import { expect } from "@jest/globals";
import { Bool, Field, State } from "snarkyjs";
import { BoolLike, FieldLike } from "../types";

function extractFromState<T extends BoolLike | FieldLike>(
val: T & State<T>
): T {
return val.get ? val.get() : val;
}

export default () => {
expect.extend({
toEqualBool<T extends Bool>(actual: T & State<T>, value: BoolLike) {
/* Check if actual is a State object */
const toMatch: Bool = extractFromState(actual);

if (!toMatch.toBoolean) {
return {
message: () => `Expected ${actual} to be a Bool`,
pass: false,
};
}
const pass: boolean = toMatch.equals(Bool(value)).toBoolean();
const message = () => `Expected ${actual} to equal ${value}`;
return {
message,
pass,
};
},
toEqualField<T extends Field>(actual: T & State<T>, value: FieldLike) {
/* Check if actual is a State object */
const toMatch: Field = extractFromState(actual);

if (!toMatch.toFields) {
return {
message: () => `Expected ${actual} to be a Field`,
pass: false,
};
}

const pass: boolean = toMatch.equals(Field(value)).toBoolean();
const message = () => `Expected ${actual} to equal ${value}`;
return {
message,
pass,
};
},
});
};
22 changes: 0 additions & 22 deletions lib/matchers/field.ts

This file was deleted.

14 changes: 11 additions & 3 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
export declare namespace jest {
interface Matchers<R> {
toEqual(value: number): R;
import { Bool, Field, SmartContract } from "snarkyjs";

export type BoolLike = Bool | boolean;
export type FieldLike = Field | string | number | bigint;

declare global {
namespace jest {
interface Matchers<R> {
toEqualBool(value: Bool | boolean): R;
toEqualField(value: FieldLike): R;
}
}
}

Expand Down
16 changes: 8 additions & 8 deletions test/integration/contract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { TestContract } from "../contract/test-contract";
import "../../lib/index";

describe("readState", () => {
let zkApp: TestContract,
zkAppPrivateKey: PrivateKey,
zkAppAddress: PublicKey,
sender: PublicKey,
senderKey: PrivateKey;
let zkApp: TestContract;
let zkAppPrivateKey: PrivateKey;
let zkAppAddress: PublicKey;
let sender: PublicKey;
let senderKey: PrivateKey;

beforeEach(async () => {
let Local = Mina.LocalBlockchain({ proofsEnabled: false });
const Local = Mina.LocalBlockchain({ proofsEnabled: false });
Mina.setActiveInstance(Local);
sender = Local.testAccounts[0].publicKey;
senderKey = Local.testAccounts[0].privateKey;
Expand All @@ -21,7 +21,7 @@ describe("readState", () => {

it("should read a boolean state", async () => {
await deploy(zkApp, zkAppPrivateKey, true, sender, senderKey);
expect(zkApp.boolState.get()).toBeTrue();
expect(zkApp.boolState).toEqualBool(true);
});
});

Expand All @@ -32,7 +32,7 @@ async function deploy(
sender: PublicKey,
senderKey: PrivateKey
) {
let tx = await Mina.transaction(sender, () => {
const tx = await Mina.transaction(sender, () => {
AccountUpdate.fundNewAccount(sender);
zkApp.deploy();
zkApp.update(Bool(bool));
Expand Down
52 changes: 52 additions & 0 deletions test/matchers/common-types.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Bool, Field } from "snarkyjs";
import configFieldMatchers from "../../lib/matchers/common-types";

configFieldMatchers();

describe("Common Types", () => {
describe("toEqualField", () => {
it("should pass when fields are equal", () => {
expect(Field(42)).toEqualField(Field(42));
});

it("should pass when fields are equal if using a string", () => {
expect(Field(42)).toEqualField("42");
});

it("should fail when fields are not equal", () => {
expect(Field(42)).not.toEqual(Field(43));
});

it("Should fail if not proper type", () => {
try {
expect("invalid").toEqualField(Field(1));
fail("Should have thrown");
} catch (e) {
expect(e.message).toBe("Expected invalid to be a Field");
}
})
});

describe("toEqualBool", () => {
it("should pass when booleans are equal", () => {
expect(Bool(true)).toEqualBool(Bool(true));
});

it("should fail when booleans are not equal", () => {
expect(Bool(true)).not.toEqualBool(Bool(false));
});

it("should fail when booleans are not equal if using native type", () => {
expect(Bool(true)).toEqualBool(true);
});

it("Should fail if not proper type", () => {
try {
expect("invalid").toEqualBool(false);
fail("Should have thrown");
} catch (e) {
expect(e.message).toBe("Expected invalid to be a Bool");
}
})
});
});
22 changes: 0 additions & 22 deletions test/matchers/field.spec.ts

This file was deleted.

0 comments on commit 55355e5

Please sign in to comment.