extendVisitor.test.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { numberTypeNode, publicKeyTypeNode, tupleTypeNode } from '@kinobi-so/nodes';
  2. import test from 'ava';
  3. import { extendVisitor, mergeVisitor, visit, voidVisitor } from '../src/index.js';
  4. test('it returns a new visitor that extends a subset of visits with a next function', t => {
  5. // Given the following 3-nodes tree.
  6. const node = tupleTypeNode([numberTypeNode('u32'), tupleTypeNode([numberTypeNode('u64'), publicKeyTypeNode()])]);
  7. // And an extended sum visitor that adds an extra 10 to tuple and public key nodes.
  8. const baseVisitor = mergeVisitor(
  9. () => 1,
  10. (_, values) => values.reduce((a, b) => a + b, 1),
  11. );
  12. const visitor = extendVisitor(baseVisitor, {
  13. visitPublicKeyType: (node, { next }) => next(node) + 10,
  14. visitTupleType: (node, { next }) => next(node) + 10,
  15. });
  16. // When we visit the tree using that visitor.
  17. const result = visit(node, visitor);
  18. // Then we expect the following count.
  19. t.is(result, 35);
  20. // And the extended visitor is a new instance.
  21. t.not(baseVisitor, visitor);
  22. });
  23. test('it can visit itself using the exposed self argument', t => {
  24. // Given the following 3-nodes tree.
  25. const node = tupleTypeNode([numberTypeNode('u32'), tupleTypeNode([numberTypeNode('u64'), publicKeyTypeNode()])]);
  26. // And an extended sum visitor that only visit the first item of tuple nodes.
  27. const baseVisitor = mergeVisitor(
  28. () => 1,
  29. (_, values) => values.reduce((a, b) => a + b, 1),
  30. );
  31. const visitor = extendVisitor(baseVisitor, {
  32. visitTupleType: (node, { self }) => (node.items.length > 1 ? visit(node.items[0], self) : 0) + 1,
  33. });
  34. // When we visit the tree using that visitor.
  35. const result = visit(node, visitor);
  36. // Then we expect the following count.
  37. t.is(result, 2);
  38. });
  39. test('it cannot extends nodes that are not supported by the base visitor', t => {
  40. // Given a base visitor that only supports tuple nodes.
  41. const baseVisitor = voidVisitor(['tupleTypeNode']);
  42. // Then we expect an error when we try to extend other nodes for that visitor.
  43. t.throws(
  44. () =>
  45. extendVisitor(baseVisitor, {
  46. // @ts-expect-error NumberTypeNode is not part of the base visitor.
  47. visitNumberType: () => undefined,
  48. }),
  49. {
  50. message: 'Cannot extend visitor with function "visitNumberType" as the base visitor does not support it.',
  51. },
  52. );
  53. });