UNPKG

@graphprotocol/graph-cli

Version:

CLI for building for and deploying to The Graph

240 lines (239 loc) • 10.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const vitest_1 = require("vitest"); const abi_1 = __importDefault(require("../abi")); const abi_2 = __importDefault(require("./abi")); let tempdir; let abi; let generatedTypes; vitest_1.describe.concurrent('ABI code generation', () => { (0, vitest_1.beforeAll)(async () => { tempdir = await fs_extra_1.default.mkdtemp('abi-codegen'); try { const filename = path_1.default.join(tempdir, 'ABI.json'); await fs_extra_1.default.writeFile(filename, JSON.stringify([ { constant: true, inputs: [], name: 'read', outputs: [{ name: '', type: 'bytes32' }], payable: false, type: 'function', }, { constant: true, inputs: [ { name: 'proposalId', type: 'uint256', }, { components: [ { name: 'foo', type: 'uint8', }, { name: 'bar', type: 'tuple', components: [{ name: 'baz', type: 'address' }], }, ], name: '', type: 'tuple', }, ], name: 'getProposal', outputs: [ { components: [ { name: 'result', type: 'uint8', }, { name: 'target', type: 'address', }, { name: 'data', type: 'bytes', }, { name: 'proposer', type: 'address', }, { name: 'feeRecipient', type: 'address', }, { name: 'fee', type: 'uint256', }, { name: 'startTime', type: 'uint256', }, { name: 'yesCount', type: 'uint256', }, { name: 'noCount', type: 'uint256', }, ], name: '', type: 'tuple', }, ], payable: false, stateMutability: 'view', type: 'function', }, { type: 'function', stateMutability: 'view', payable: 'false', name: 'getProposals', outputs: [ { type: 'uint256', name: 'size', }, { type: 'tuple[]', components: [ { name: 'first', type: 'uint256' }, { name: 'second', type: 'string' }, ], }, ], }, { type: 'function', stateMutability: 'view', name: 'overloaded', inputs: [ { type: 'string', }, ], outputs: [ { type: 'string', }, ], }, { type: 'function', stateMutability: 'view', name: 'overloaded', inputs: [ { type: 'uint256', }, ], outputs: [ { type: 'string', }, ], }, { type: 'function', stateMutability: 'view', name: 'overloaded', inputs: [ { type: 'bytes32', }, ], outputs: [ { type: 'string', }, ], }, ]), 'utf-8'); abi = abi_1.default.load('Contract', filename); const codegen = new abi_2.default(abi); generatedTypes = codegen.generateTypes(); } finally { await fs_extra_1.default.remove(tempdir); } }); (0, vitest_1.afterAll)(async () => { await fs_extra_1.default.remove(tempdir); }); (0, vitest_1.describe)('Generated types', () => { (0, vitest_1.test)('All expected types are generated', () => { (0, vitest_1.expect)(generatedTypes.map(type => type.name)).toMatchSnapshot(); }); }); (0, vitest_1.describe)('Contract class', () => { (0, vitest_1.test)('Exists', () => { (0, vitest_1.expect)(generatedTypes.find(type => type.name === 'Contract')).toBeDefined(); }); (0, vitest_1.test)('Has methods', () => { const contract = generatedTypes.find(type => type.name === 'Contract'); (0, vitest_1.expect)(contract.methods).toBeInstanceOf(Array); }); (0, vitest_1.test)('Has `bind` method', () => { const contract = generatedTypes.find(type => type.name === 'Contract'); (0, vitest_1.expect)(contract.methods.find((method) => method.name === 'bind')).toBeDefined(); }); (0, vitest_1.test)('Has methods for all callable functions', () => { const contract = generatedTypes.find(type => type.name === 'Contract'); (0, vitest_1.expect)(contract.methods.map((method) => method.name)).toContain('getProposal'); }); }); (0, vitest_1.describe)('Methods for callable functions', () => { (0, vitest_1.test)('Have correct parameters', () => { const contract = generatedTypes.find(type => type.name === 'Contract'); (0, vitest_1.expect)(contract.methods.map((method) => [method.name, method.params])).toMatchSnapshot(); }); (0, vitest_1.test)('Have correct return types', () => { const contract = generatedTypes.find(type => type.name === 'Contract'); (0, vitest_1.expect)(contract.methods.map((method) => [method.name, method.returnType])).toMatchSnapshot(); }); }); (0, vitest_1.describe)('Tuples', () => { (0, vitest_1.test)('Tuple types exist for function parameters', () => { let tupleType = generatedTypes.find(type => type.name === 'Contract__getProposalInputParam1Struct'); // Verify that the tuple type has methods (0, vitest_1.expect)(tupleType.methods).toBeDefined(); // Verify that the tuple type has getters for all tuple fields with // the right return types (0, vitest_1.expect)(tupleType.methods.map((method) => [method.name, method.returnType])).toMatchSnapshot(); // Inner tuple: tupleType = generatedTypes.find(type => type.name === 'Contract__getProposalInputParam1BarStruct'); // Verify that the tuple type has methods (0, vitest_1.expect)(tupleType.methods).toBeDefined(); // Verify that the tuple type has getters for all tuple fields with // the right return types (0, vitest_1.expect)(tupleType.methods.map((method) => [method.name, method.returnType])).toMatchSnapshot(); }); (0, vitest_1.test)('Tuple types exist for function return values', () => { const tupleType = generatedTypes.find(type => type.name === 'Contract__getProposalResultValue0Struct'); // Verify that the tuple type has methods (0, vitest_1.expect)(tupleType.methods).toBeDefined(); // Verify that the tuple type has getters for all tuple fields with // the right return types (0, vitest_1.expect)(tupleType.methods.map((method) => [method.name, method.returnType])).toMatchSnapshot(); }); (0, vitest_1.test)('Function bodies are generated correctly for tuple arrays', () => { const contract = generatedTypes.find(type => type.name === 'Contract'); const getter = contract.methods.find((method) => method.name === 'getProposals'); (0, vitest_1.expect)(getter.body).not.toContain('toTupleArray<undefined>'); (0, vitest_1.expect)(getter.body).toContain('result[1].toTupleArray<Contract__getProposalsResultValue1Struct>()'); }); }); });