Skip to content

Commit c482f76

Browse files
committed
Add tests for unwrapInstructionArgsDefinedTypesVisitor
Including a failing one to fix.
1 parent e24b822 commit c482f76

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
import {
2+
arrayTypeNode,
3+
definedTypeLinkNode,
4+
definedTypeNode,
5+
fixedCountNode,
6+
instructionArgumentNode,
7+
instructionNode,
8+
numberTypeNode,
9+
programNode,
10+
rootNode,
11+
structFieldTypeNode,
12+
structTypeNode,
13+
} from '@codama/nodes';
14+
import { visit } from '@codama/visitors-core';
15+
import { expect, test } from 'vitest';
16+
17+
import { unwrapInstructionArgsDefinedTypesVisitor } from '../src';
18+
19+
test('it unwraps defined type link nodes used as instruction arguments', () => {
20+
// Given a program with a type used only once as a direct instruction argument.
21+
const node = rootNode(
22+
programNode({
23+
definedTypes: [
24+
definedTypeNode({
25+
name: 'typeA',
26+
type: structTypeNode([structFieldTypeNode({ name: 'foo', type: numberTypeNode('u8') })]),
27+
}),
28+
definedTypeNode({
29+
name: 'typeB',
30+
type: structTypeNode([structFieldTypeNode({ name: 'bar', type: numberTypeNode('u8') })]),
31+
}),
32+
],
33+
instructions: [
34+
instructionNode({
35+
arguments: [instructionArgumentNode({ name: 'argA', type: definedTypeLinkNode('typeA') })],
36+
name: 'myInstruction',
37+
}),
38+
],
39+
name: 'MyProgram',
40+
publicKey: '1111',
41+
version: '1.2.3',
42+
}),
43+
);
44+
45+
// When the defined type link nodes are unwrapped.
46+
const result = visit(node, unwrapInstructionArgsDefinedTypesVisitor());
47+
48+
// Then we expect the following node.
49+
expect(result).toStrictEqual(
50+
rootNode(
51+
programNode({
52+
definedTypes: [
53+
definedTypeNode({
54+
name: 'typeB',
55+
type: structTypeNode([structFieldTypeNode({ name: 'bar', type: numberTypeNode('u8') })]),
56+
}),
57+
],
58+
instructions: [
59+
instructionNode({
60+
arguments: [
61+
instructionArgumentNode({
62+
name: 'argA',
63+
type: structTypeNode([
64+
structFieldTypeNode({ name: 'foo', type: numberTypeNode('u8') }),
65+
]),
66+
}),
67+
],
68+
name: 'myInstruction',
69+
}),
70+
],
71+
name: 'MyProgram',
72+
publicKey: '1111',
73+
version: '1.2.3',
74+
}),
75+
),
76+
);
77+
});
78+
79+
test('it does not unwrap defined type link nodes that are used in more than one place.', () => {
80+
// Given a link node used in an instruction argument and in another place.
81+
const node = rootNode(
82+
programNode({
83+
definedTypes: [
84+
definedTypeNode({
85+
name: 'myType',
86+
type: structTypeNode([structFieldTypeNode({ name: 'foo', type: numberTypeNode('u8') })]),
87+
}),
88+
definedTypeNode({ name: 'myCopyType', type: definedTypeLinkNode('myType') }),
89+
],
90+
instructions: [
91+
instructionNode({
92+
arguments: [instructionArgumentNode({ name: 'myArg', type: definedTypeLinkNode('myType') })],
93+
name: 'myInstruction',
94+
}),
95+
],
96+
name: 'MyProgram',
97+
publicKey: '1111',
98+
version: '1.2.3',
99+
}),
100+
);
101+
102+
// When we try to unwrap defined type link nodes for instruction arguments.
103+
const result = visit(node, unwrapInstructionArgsDefinedTypesVisitor());
104+
105+
// Then we expect the same node.
106+
expect(result).toStrictEqual(node);
107+
});
108+
109+
test('it only unwraps defined type link nodes if they are direct instruction arguments', () => {
110+
// Given a link node used in an instruction argument but not as a direct argument.
111+
const node = rootNode(
112+
programNode({
113+
definedTypes: [
114+
definedTypeNode({
115+
name: 'myType',
116+
type: structTypeNode([structFieldTypeNode({ name: 'foo', type: numberTypeNode('u8') })]),
117+
}),
118+
],
119+
instructions: [
120+
instructionNode({
121+
arguments: [
122+
instructionArgumentNode({
123+
name: 'myArg',
124+
type: arrayTypeNode(definedTypeLinkNode('myType'), fixedCountNode(3)),
125+
}),
126+
],
127+
name: 'myInstruction',
128+
}),
129+
],
130+
name: 'MyProgram',
131+
publicKey: '1111',
132+
version: '1.2.3',
133+
}),
134+
);
135+
136+
// When we try to unwrap defined type link nodes for instruction arguments.
137+
const result = visit(node, unwrapInstructionArgsDefinedTypesVisitor());
138+
139+
// Then we expect the same node.
140+
expect(result).toStrictEqual(node);
141+
});
142+
143+
test('it does not unwrap defined type link nodes from other programs', () => {
144+
// Given a program that defines the
145+
const programA = programNode({
146+
definedTypes: [definedTypeNode({ name: 'myType', type: numberTypeNode('u8') })],
147+
instructions: [
148+
instructionNode({
149+
arguments: [instructionArgumentNode({ name: 'myArg', type: definedTypeLinkNode('myType') })],
150+
name: 'myInstruction',
151+
}),
152+
],
153+
name: 'programA',
154+
publicKey: '1111',
155+
version: '1.2.3',
156+
});
157+
158+
// And another program with a defined type sharing the same name.
159+
const programB = programNode({
160+
definedTypes: [
161+
definedTypeNode({ name: 'myType', type: numberTypeNode('u16') }),
162+
definedTypeNode({ name: 'myCopyType', type: definedTypeLinkNode('myType') }),
163+
],
164+
name: 'programB',
165+
publicKey: '2222',
166+
version: '1.2.3',
167+
});
168+
169+
// When we unwrap defined type link nodes for instruction arguments for both of them.
170+
const node = rootNode(programA, [programB]);
171+
const result = visit(node, unwrapInstructionArgsDefinedTypesVisitor());
172+
173+
// Then we expect program A to have been modified but not program B.
174+
expect(result).toStrictEqual(
175+
rootNode(
176+
programNode({
177+
instructions: [
178+
instructionNode({
179+
arguments: [instructionArgumentNode({ name: 'myArg', type: numberTypeNode('u8') })],
180+
name: 'myInstruction',
181+
}),
182+
],
183+
name: 'programA',
184+
publicKey: '1111',
185+
version: '1.2.3',
186+
}),
187+
[programB],
188+
),
189+
);
190+
});

0 commit comments

Comments
 (0)