Skip to content

Instantly share code, notes, and snippets.

@tgrecojs
Last active January 11, 2023 00:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tgrecojs/06335e4d910cde2777826628b63e7689 to your computer and use it in GitHub Desktop.
Save tgrecojs/06335e4d910cde2777826628b63e7689 to your computer and use it in GitHub Desktop.
riteway testing with agoric

Riteway test wrapper

  • Utility lib for using the riteway testing library with agoric.

Explicit test failure messages

  • forces you to write tests cases the "rite" way:
    • Readable
    • Integrated
    • Thorough
    • Explicit,

Failing test screenshot

  • Beautiful, clear test report for all failing tests. riteway-failing-test
import { test } from './prepare-test-env-ava.js';
// eslint-disable-next-line no-new-func
const noop = new Function();
const isPromise = x => x && typeof x.then === 'function';
const requiredKeys = ['given', 'should', 'actual', 'expected'];
const concatToString = (keys, key, index) => keys + (index ? ', ' : '') + key;
const withRiteway = TestFunction => t => {
const assert = (args = {}) => {
const missing = requiredKeys.filter(k => !Object.keys(args).includes(k));
if (missing.length) {
throw new Error(
`The following parameters are required by \`assert\`: ${missing.reduce(
concatToString,
''
)}`
);
}
const {
// initialize values to undefined so TypeScript doesn't complain
given = undefined,
should = '',
actual = undefined,
expected = undefined
} = args;
t.deepEqual(actual, expected, `Given ${given}: should ${should}`);
};
const end = () => ({});
const result = TestFunction(assert, end);
if (isPromise(result)) return result.then(end);
};
const withTestFramework =
tapeFn =>
(unit = '', TestFunction = noop) =>
tapeFn(unit, withRiteway(TestFunction));
const describe = Object.assign(withTestFramework(test), {
// is: withTestFramework(test.is),
// before: withTestFramework(test.before)
});
export { describe };
/**
* Like prepare-test-env but also sets up ses-ava and provides
* the ses-ava `test` function to be used as if it is the ava
* `test` function.
*/
import '@endo/init/pre-bundle-source.js';
import '@agoric/zoe/tools/prepare-test-env.js';
// eslint-disable-next-line import/no-unresolved -- https://github.com/avajs/ava/issues/2951
import rawTest from 'ava';
// XXX wrapTest not working https://github.com/endojs/endo/issues/1235
// import { wrapTest } from '@endo/ses-ava';
export const test = rawTest;
import { describe } from './prepare-riteway.js';
// eslint-disable-next-line import/order
import { defineDurableFarClassKit, M, makeKindHandle } from '@agoric/vat-data';
// from @agoric/vat-data
// https://github.com/Agoric/agoric-sdk/blob/master/packages/vat-data/test/test-durable-classes.js#L11-L23
const UpCounterI = M.interface('UpCounter', {
incr: M.call()
.optional(M.and(M.number(), M.gte(0)))
.returns(M.number())
});
const DownCounterI = M.interface('DownCounter', {
decr: M.call()
.optional(M.and(M.number(), M.gte(0)))
.returns(M.number())
});
const initState = (x = 0) => ({ x });
const counterKindHandle = makeKindHandle('Counter');
const makeCounterKit = defineDurableFarClassKit(
counterKindHandle,
{ up: UpCounterI, down: DownCounterI },
/** @param {number} x */
initState,
{
up: {
incr(y = 1) {
const { state, ...rest } = this;
state.x += y;
return state.x;
}
},
down: {
decr(y = 1) {
const { state } = this;
state.x -= y;
return state.x;
}
}
}
);
describe('makeCounterKit function', assert => {
const { up: upCounter, down: downCounter } = makeCounterKit(3);
assert({
given: 'a call to upCounter.incr()',
should: 'update the value of state.x by 1.',
actual: upCounter.incr(),
expected: 4
});
assert({
given: 'a call to downCounter.decr()',
should: 'update the value of state.x by -1.',
actual: downCounter.decr(),
expected: 3
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment