scrypt-testgen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +7 -0
- package/README.md +17 -0
- package/bin/scrypt-testgen.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +48 -0
- package/dist/cli.js.map +1 -0
- package/dist/generator/index.d.ts +6 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +33 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/test-generator.d.ts +17 -0
- package/dist/generator/test-generator.d.ts.map +1 -0
- package/dist/generator/test-generator.js +177 -0
- package/dist/generator/test-generator.js.map +1 -0
- package/dist/generator/value-generator.d.ts +19 -0
- package/dist/generator/value-generator.d.ts.map +1 -0
- package/dist/generator/value-generator.js +130 -0
- package/dist/generator/value-generator.js.map +1 -0
- package/dist/model/contract-model.d.ts +42 -0
- package/dist/model/contract-model.d.ts.map +1 -0
- package/dist/model/contract-model.js +10 -0
- package/dist/model/contract-model.js.map +1 -0
- package/dist/parser/ast-utils.d.ts +7 -0
- package/dist/parser/ast-utils.d.ts.map +1 -0
- package/dist/parser/ast-utils.js +114 -0
- package/dist/parser/ast-utils.js.map +1 -0
- package/dist/parser/contract-parser.d.ts +18 -0
- package/dist/parser/contract-parser.d.ts.map +1 -0
- package/dist/parser/contract-parser.js +224 -0
- package/dist/parser/contract-parser.js.map +1 -0
- package/dist/parser/index.d.ts +3 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +6 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/utils/file-utils.d.ts +4 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +26 -0
- package/dist/utils/file-utils.js.map +1 -0
- package/package.json +30 -0
- package/src/cli.ts +51 -0
- package/src/generator/index.ts +45 -0
- package/src/generator/test-generator.ts +216 -0
- package/src/generator/value-generator.ts +138 -0
- package/src/model/contract-model.ts +46 -0
- package/src/parser/ast-utils.ts +75 -0
- package/src/parser/contract-parser.ts +246 -0
- package/src/parser/index.ts +2 -0
- package/src/utils/file-utils.ts +22 -0
- package/templates/test-template.ts +0 -0
- package/test/integration/demo.ts +16 -0
- package/tsconfig.json +21 -0
package/.prettierrc
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# scrypt-testgen
|
|
2
|
+
|
|
3
|
+
Automatic test generator for sCrypt-ts smart contracts. Generates comprehensive Mocha test files by analyzing contract structure using TypeScript Compiler API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ๐ Parses sCrypt-ts contracts using TypeScript AST
|
|
8
|
+
- ๐งช Generates ready-to-run Mocha test files
|
|
9
|
+
- โ
Includes happy-path tests for all public methods
|
|
10
|
+
- ๐ซ Generates revert tests for assertion failures
|
|
11
|
+
- ๐ฏ Creates edge-case tests for comprehensive coverage
|
|
12
|
+
- ๐จ Produces clean, readable, and idiomatic test code
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g scrypt-testgen
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const generator_1 = require("./generator");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const program = new commander_1.Command();
|
|
13
|
+
program
|
|
14
|
+
.name('scrypt-testgen')
|
|
15
|
+
.description('Generate Mocha tests for sCrypt-ts smart contracts')
|
|
16
|
+
.version('1.0.0');
|
|
17
|
+
program
|
|
18
|
+
.argument('<contract-path>', 'Path to the sCrypt contract TypeScript file')
|
|
19
|
+
.option('-m, --minimal', 'Generate only happy-path tests', false)
|
|
20
|
+
.option('-c, --coverage', 'Include revert and edge-case tests', false)
|
|
21
|
+
.option('-o, --overwrite', 'Replace existing test file', false)
|
|
22
|
+
.option('-o, --output <path>', 'Custom output path for test file')
|
|
23
|
+
.action(async (contractPath, options) => {
|
|
24
|
+
try {
|
|
25
|
+
const resolvedPath = (0, path_1.resolve)(process.cwd(), contractPath);
|
|
26
|
+
if (!(0, fs_1.existsSync)(resolvedPath)) {
|
|
27
|
+
console.error(chalk_1.default.red(`Error: Contract file not found: ${resolvedPath}`));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const outputPath = options.output
|
|
31
|
+
? (0, path_1.resolve)(process.cwd(), options.output)
|
|
32
|
+
: (0, path_1.join)((0, path_1.dirname)(resolvedPath), '..', 'test', (0, path_1.basename)(resolvedPath).replace('.ts', '.test.ts'));
|
|
33
|
+
// Ensure test directory exists
|
|
34
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(outputPath), { recursive: true });
|
|
35
|
+
await (0, generator_1.generateTests)(resolvedPath, outputPath, {
|
|
36
|
+
minimal: options.minimal,
|
|
37
|
+
coverage: options.coverage,
|
|
38
|
+
overwrite: options.overwrite
|
|
39
|
+
});
|
|
40
|
+
console.log(chalk_1.default.green(`โ Tests generated: ${outputPath}`));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error(chalk_1.default.red(`Error: ${error}`));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
program.parse();
|
|
48
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,2CAA4C;AAC5C,+BAAwD;AACxD,2BAA2C;AAC3C,kDAA0B;AAE1B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,QAAQ,CAAC,iBAAiB,EAAE,6CAA6C,CAAC;KAC1E,MAAM,CAAC,eAAe,EAAE,gCAAgC,EAAE,KAAK,CAAC;KAChE,MAAM,CAAC,gBAAgB,EAAE,oCAAoC,EAAE,KAAK,CAAC;KACrE,MAAM,CAAC,iBAAiB,EAAE,4BAA4B,EAAE,KAAK,CAAC;KAC9D,MAAM,CAAC,qBAAqB,EAAE,kCAAkC,CAAC;KACjE,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE;IACtC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;QAE1D,IAAI,CAAC,IAAA,eAAU,EAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,mCAAmC,YAAY,EAAE,CAAC,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM;YAC/B,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;YACxC,CAAC,CAAC,IAAA,WAAI,EAAC,IAAA,cAAO,EAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAA,eAAQ,EAAC,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;QAEjG,+BAA+B;QAC/B,IAAA,cAAS,EAAC,IAAA,cAAO,EAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpD,MAAM,IAAA,yBAAa,EAAC,YAAY,EAAE,UAAU,EAAE;YAC5C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IACP,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB,GACA,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateTests = generateTests;
|
|
4
|
+
const parser_1 = require("../parser");
|
|
5
|
+
const test_generator_1 = require("./test-generator");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
async function generateTests(contractPath, outputPath, options) {
|
|
8
|
+
// Check if output file exists
|
|
9
|
+
if ((0, fs_1.existsSync)(outputPath) && !options.overwrite) {
|
|
10
|
+
throw new Error(`Test file already exists: ${outputPath}. Use --overwrite to replace.`);
|
|
11
|
+
}
|
|
12
|
+
// Parse the contract
|
|
13
|
+
const parser = new parser_1.ContractParser(contractPath);
|
|
14
|
+
const model = parser.parse();
|
|
15
|
+
// Generate tests
|
|
16
|
+
const generator = new test_generator_1.TestGenerator();
|
|
17
|
+
const testCode = generator.generateTestFile(model, {
|
|
18
|
+
minimal: options.minimal,
|
|
19
|
+
coverage: options.coverage
|
|
20
|
+
});
|
|
21
|
+
// Format the output (simplified - in production, use prettier API)
|
|
22
|
+
const formattedCode = formatCode(testCode);
|
|
23
|
+
// Write to file
|
|
24
|
+
(0, fs_1.writeFileSync)(outputPath, formattedCode, 'utf-8');
|
|
25
|
+
}
|
|
26
|
+
function formatCode(code) {
|
|
27
|
+
// Simple formatting - in production, integrate with Prettier
|
|
28
|
+
return code
|
|
29
|
+
.replace(/\n\s*\n\s*\n/g, '\n\n')
|
|
30
|
+
.replace(/\s+$/gm, '')
|
|
31
|
+
.trim() + '\n';
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":";;AAKA,sCA+BC;AApCD,sCAA2C;AAC3C,qDAAiD;AACjD,2BAA6D;AAGtD,KAAK,UAAU,aAAa,CACjC,YAAoB,EACpB,UAAkB,EAClB,OAIC;IAGD,8BAA8B;IAC9B,IAAI,IAAA,eAAU,EAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,+BAA+B,CAAC,CAAC;IAC1F,CAAC;IAED,qBAAqB;IACrB,MAAM,MAAM,GAAG,IAAI,uBAAc,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAE7B,iBAAiB;IACjB,MAAM,SAAS,GAAG,IAAI,8BAAa,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE;QACjD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IAEH,mEAAmE;IACrE,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEzC,gBAAgB;IAChB,IAAA,kBAAa,EAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,6DAA6D;IAC7D,OAAO,IAAI;SACR,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC;SAChC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,IAAI,EAAE,GAAG,IAAI,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ContractModel } from '../model/contract-model';
|
|
2
|
+
export declare class TestGenerator {
|
|
3
|
+
private valueGenerator;
|
|
4
|
+
constructor();
|
|
5
|
+
generateTestFile(model: ContractModel, options: {
|
|
6
|
+
minimal: boolean;
|
|
7
|
+
coverage: boolean;
|
|
8
|
+
}): string;
|
|
9
|
+
private generateImports;
|
|
10
|
+
private getRelativeTestPath;
|
|
11
|
+
private generateTestSuite;
|
|
12
|
+
private generateMethodTests;
|
|
13
|
+
private generateHappyPathTest;
|
|
14
|
+
private generateRevertTest;
|
|
15
|
+
private generateEdgeCaseTests;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=test-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-generator.d.ts","sourceRoot":"","sources":["../../src/generator/test-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,yBAAyB,CAAC;AAGxE,qBAAa,aAAa;IACxB,OAAO,CAAC,cAAc,CAAiB;;IAMvC,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE;QAC9C,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KACnB,GAAG,MAAM;IASV,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,qBAAqB;IAsC7B,OAAO,CAAC,kBAAkB;IAqC1B,OAAO,CAAC,qBAAqB;CA+B9B"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestGenerator = void 0;
|
|
4
|
+
const value_generator_1 = require("./value-generator");
|
|
5
|
+
class TestGenerator {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.valueGenerator = new value_generator_1.ValueGenerator();
|
|
8
|
+
}
|
|
9
|
+
generateTestFile(model, options) {
|
|
10
|
+
this.valueGenerator.reset();
|
|
11
|
+
const imports = this.generateImports(model);
|
|
12
|
+
const testSuite = this.generateTestSuite(model, options);
|
|
13
|
+
return `${imports}\n\n${testSuite}`;
|
|
14
|
+
}
|
|
15
|
+
generateImports(model) {
|
|
16
|
+
const contractName = model.name;
|
|
17
|
+
const contractPath = this.getRelativeTestPath(model.filePath);
|
|
18
|
+
return `import { expect } from 'chai';
|
|
19
|
+
import { ${contractName} } from '${contractPath.replace('.ts', '')}';
|
|
20
|
+
import {
|
|
21
|
+
bsv,
|
|
22
|
+
TestWallet,
|
|
23
|
+
DefaultProvider,
|
|
24
|
+
sha256,
|
|
25
|
+
toByteString,
|
|
26
|
+
PubKey,
|
|
27
|
+
Sig,
|
|
28
|
+
findSig,
|
|
29
|
+
MethodCallOptions,
|
|
30
|
+
ContractTransaction,
|
|
31
|
+
getDefaultSigner
|
|
32
|
+
} from 'scrypt-ts';
|
|
33
|
+
|
|
34
|
+
describe('${contractName}', () => {
|
|
35
|
+
let signer: TestWallet;
|
|
36
|
+
let instance: ${contractName};`;
|
|
37
|
+
}
|
|
38
|
+
getRelativeTestPath(contractPath) {
|
|
39
|
+
// Convert absolute path to relative from test directory
|
|
40
|
+
const pathParts = contractPath.split('/');
|
|
41
|
+
const srcIndex = pathParts.lastIndexOf('src');
|
|
42
|
+
if (srcIndex !== -1) {
|
|
43
|
+
const relativeParts = pathParts.slice(srcIndex);
|
|
44
|
+
return `../${relativeParts.join('/')}`;
|
|
45
|
+
}
|
|
46
|
+
return contractPath;
|
|
47
|
+
}
|
|
48
|
+
generateTestSuite(model, options) {
|
|
49
|
+
let output = `
|
|
50
|
+
before(async () => {
|
|
51
|
+
await ${model.name}.loadArtifact();
|
|
52
|
+
|
|
53
|
+
signer = await getDefaultSigner();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
beforeEach(async () => {
|
|
57
|
+
instance = new ${model.name}(${this.valueGenerator.generateConstructorArgs(model.constructorArgs)});
|
|
58
|
+
await instance.connect(signer);
|
|
59
|
+
});
|
|
60
|
+
`;
|
|
61
|
+
// Generate tests for each method
|
|
62
|
+
for (const method of model.methods) {
|
|
63
|
+
output += this.generateMethodTests(method, model, options);
|
|
64
|
+
}
|
|
65
|
+
output += `});`;
|
|
66
|
+
return output;
|
|
67
|
+
}
|
|
68
|
+
generateMethodTests(method, model, options) {
|
|
69
|
+
let output = `\n\n describe('#${method.name}', () => {`;
|
|
70
|
+
// Happy path test
|
|
71
|
+
output += this.generateHappyPathTest(method, model);
|
|
72
|
+
// Revert test (unless minimal mode)
|
|
73
|
+
if (!options.minimal) {
|
|
74
|
+
output += this.generateRevertTest(method, model);
|
|
75
|
+
}
|
|
76
|
+
// Edge case tests (if coverage mode)
|
|
77
|
+
if (options.coverage) {
|
|
78
|
+
output += this.generateEdgeCaseTests(method, model);
|
|
79
|
+
}
|
|
80
|
+
output += `\n });`;
|
|
81
|
+
return output;
|
|
82
|
+
}
|
|
83
|
+
generateHappyPathTest(method, model) {
|
|
84
|
+
const args = this.valueGenerator.generateMethodArgs(method.parameters, method.name);
|
|
85
|
+
const methodCall = `instance.methods.${method.name}(${args})`;
|
|
86
|
+
let test = `
|
|
87
|
+
it('should succeed with valid parameters', async () => {
|
|
88
|
+
const deployTx = await instance.deploy(1)
|
|
89
|
+
const callTx = await ${methodCall};
|
|
90
|
+
|
|
91
|
+
console.log('Deploy TX:', deployTx.id);
|
|
92
|
+
console.log('Call TX:', callTx.tx.id);
|
|
93
|
+
});
|
|
94
|
+
`;
|
|
95
|
+
// Add assertions for state transitions
|
|
96
|
+
if (method.mutatesState) {
|
|
97
|
+
test = `
|
|
98
|
+
it('should succeed with valid parameters', async () => {
|
|
99
|
+
const deployTx = await instance.deploy(1)
|
|
100
|
+
const oldInstance = instance;
|
|
101
|
+
const callTx = await ${methodCall};
|
|
102
|
+
|
|
103
|
+
console.log('Deploy TX:', deployTx.id);
|
|
104
|
+
console.log('Call TX:', callTx.tx.id);
|
|
105
|
+
|
|
106
|
+
// Verify state transition if applicable
|
|
107
|
+
const result = await callTx.tx.id;
|
|
108
|
+
if (result.nexts && result.nexts.length > 0) {
|
|
109
|
+
const nextInstance = result.nexts[0].instance;
|
|
110
|
+
// Add state assertions here based on method logic
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
return test;
|
|
116
|
+
}
|
|
117
|
+
generateRevertTest(method, model) {
|
|
118
|
+
const args = this.valueGenerator.generateInvalidMethodArgs(method.parameters, method.name);
|
|
119
|
+
const methodCall = `instance.methods.${method.name}(${args})`;
|
|
120
|
+
let test = `
|
|
121
|
+
it('should revert with invalid parameters', async () => {
|
|
122
|
+
try {
|
|
123
|
+
const deployTx = await instance.deploy(1)
|
|
124
|
+
const callTx = await ${methodCall};
|
|
125
|
+
console.error('Expected method to revert, but it succeeded:', callTx.tx.id);
|
|
126
|
+
|
|
127
|
+
} catch (error) {
|
|
128
|
+
// Expected to throw an error
|
|
129
|
+
expect(error).to.be.an('error');
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
`;
|
|
133
|
+
// Special handling for assert statements
|
|
134
|
+
if (method.hasAssert) {
|
|
135
|
+
test = `
|
|
136
|
+
it('should revert when assertion fails', async () => {
|
|
137
|
+
// Use parameters that will cause assert() to fail
|
|
138
|
+
const deployTx = await instance.deploy(1)
|
|
139
|
+
const callTx = await ${methodCall};
|
|
140
|
+
|
|
141
|
+
console.log('Deploy TX:', deployTx.id);
|
|
142
|
+
console.log('Call TX:', callTx.tx.id);
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
});
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
return test;
|
|
149
|
+
}
|
|
150
|
+
generateEdgeCaseTests(method, model) {
|
|
151
|
+
let tests = '';
|
|
152
|
+
// Generate edge case for each parameter
|
|
153
|
+
method.parameters.forEach((param, index) => {
|
|
154
|
+
const edgeCaseValue = this.valueGenerator.getEdgeCaseValue(param.type);
|
|
155
|
+
const modifiedParams = method.parameters.map((p, i) => i === index ? { ...p, type: param.type } : p);
|
|
156
|
+
const args = this.valueGenerator.generateMethodArgs(modifiedParams, method.name).replace(this.valueGenerator.generateMethodArgs(method.parameters, method.name), '').trim() || edgeCaseValue;
|
|
157
|
+
const methodCall = `instance.methods.${method.name}(${args})`;
|
|
158
|
+
tests += `
|
|
159
|
+
it('should handle edge case for ${param.name} (${edgeCaseValue})', async () => {
|
|
160
|
+
try {
|
|
161
|
+
const deployTx = await instance.deploy(1)
|
|
162
|
+
const callTx = await ${methodCall};
|
|
163
|
+
// Edge case might succeed or fail depending on contract logic
|
|
164
|
+
console.log('Deploy TX:', deployTx.id);
|
|
165
|
+
console.log('Call TX:', callTx.tx.id);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
// Handle expected errors gracefully
|
|
168
|
+
expect(error).to.be.an('error');
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
`;
|
|
172
|
+
});
|
|
173
|
+
return tests;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.TestGenerator = TestGenerator;
|
|
177
|
+
//# sourceMappingURL=test-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-generator.js","sourceRoot":"","sources":["../../src/generator/test-generator.ts"],"names":[],"mappings":";;;AACA,uDAAmD;AAEnD,MAAa,aAAa;IAGxB;QACE,IAAI,CAAC,cAAc,GAAG,IAAI,gCAAc,EAAE,CAAC;IAC7C,CAAC;IAED,gBAAgB,CAAC,KAAoB,EAAE,OAGtC;QACC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEzD,OAAO,GAAG,OAAO,OAAO,SAAS,EAAE,CAAC;IACtC,CAAC;IAEO,eAAe,CAAC,KAAoB;QAC1C,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE9D,OAAO;WACA,YAAY,YAAY,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;;;;;;;;;;;;;;;YAetD,YAAY;;kBAEN,YAAY,GAAG,CAAC;IAChC,CAAC;IAEO,mBAAmB,CAAC,YAAoB;QAC9C,wDAAwD;QACxD,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAE9C,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAChD,OAAO,MAAM,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAEO,iBAAiB,CAAC,KAAoB,EAAE,OAG/C;QACC,IAAI,MAAM,GAAG;;YAEL,KAAK,CAAC,IAAI;;;;;;qBAMD,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,KAAK,CAAC,eAAe,CAAC;;;CAGpG,CAAC;QAEE,iCAAiC;QACjC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,IAAI,KAAK,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,mBAAmB,CAAC,MAAmC,EAAE,KAAoB,EAAE,OAGtF;QACC,IAAI,MAAM,GAAG,oBAAoB,MAAM,CAAC,IAAI,YAAY,CAAC;QAEzD,kBAAkB;QAClB,MAAM,IAAI,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEpD,oCAAoC;QACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;QAED,qCAAqC;QACrC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,IAAI,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,IAAI,SAAS,CAAC;QACpB,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,qBAAqB,CAAC,MAAmC,EAAE,KAAoB;QACrF,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACpF,MAAM,UAAU,GAAG,oBAAoB,MAAM,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC;QAE9D,IAAI,IAAI,GAAG;;;6BAGc,UAAU;;;;;CAKtC,CAAC;QAEE,uCAAuC;QACvC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,IAAI,GAAG;;;;6BAIgB,UAAU;;;;;;;;;;;;CAYtC,CAAC;QACE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,kBAAkB,CAAC,MAAmC,EAAE,KAAoB;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,yBAAyB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3F,MAAM,UAAU,GAAG,oBAAoB,MAAM,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC;QAE9D,IAAI,IAAI,GAAG;;;;+BAIgB,UAAU;;;;;;;;CAQxC,CAAC;QAEE,yCAAyC;QACzC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,IAAI,GAAG;;;;6BAIgB,UAAU;;;;;;;CAOtC,CAAC;QACE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,qBAAqB,CAAC,MAAmC,EAAE,KAAoB;QACrF,IAAI,KAAK,GAAG,EAAE,CAAC;QAEf,wCAAwC;QACxC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACzC,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvE,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACpD,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAC7C,CAAC;YACF,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC;YAE7L,MAAM,UAAU,GAAG,oBAAoB,MAAM,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC;YAE9D,KAAK,IAAI;sCACuB,KAAK,CAAC,IAAI,KAAK,aAAa;;;+BAGnC,UAAU;;;;;;;;;CASxC,CAAC;QACE,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AApND,sCAoNC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ConstructorArg, MethodParameter } from '../model/contract-model';
|
|
2
|
+
import { ContractModel } from '../model/contract-model';
|
|
3
|
+
export declare class ValueGenerator {
|
|
4
|
+
private usedVariableNames;
|
|
5
|
+
private testKeyPairs;
|
|
6
|
+
constructor();
|
|
7
|
+
generateConstructorArgs(args: ConstructorArg[]): string;
|
|
8
|
+
generateMethodArgs(parameters: MethodParameter[], methodName: string): string;
|
|
9
|
+
generateInvalidMethodArgs(parameters: MethodParameter[], methodName: string): string;
|
|
10
|
+
private generateValueForType;
|
|
11
|
+
private generateInvalidValueForType;
|
|
12
|
+
getTestKey(name?: string): {
|
|
13
|
+
pubKey: string;
|
|
14
|
+
privKey: string;
|
|
15
|
+
};
|
|
16
|
+
getEdgeCaseValue(type: string, model?: ContractModel): string;
|
|
17
|
+
reset(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=value-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-generator.d.ts","sourceRoot":"","sources":["../../src/generator/value-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,qBAAa,cAAc;IACzB,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,YAAY,CAA0D;;IAkB9E,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,MAAM;IAWvD,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAM7E,yBAAyB,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAMpF,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,2BAA2B;IAqBnC,UAAU,CAAC,IAAI,GAAE,MAAkB,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAQzE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,MAAM;IAoB7D,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValueGenerator = void 0;
|
|
4
|
+
class ValueGenerator {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.usedVariableNames = new Set();
|
|
7
|
+
this.testKeyPairs = new Map();
|
|
8
|
+
// Initialize with some test key pairs
|
|
9
|
+
this.testKeyPairs.set('default', {
|
|
10
|
+
pubKey: 'myPublicKey',
|
|
11
|
+
privKey: 'myPrivateKey'
|
|
12
|
+
});
|
|
13
|
+
this.testKeyPairs.set('alice', {
|
|
14
|
+
pubKey: 'alicePublicKey',
|
|
15
|
+
privKey: 'alicePrivateKey'
|
|
16
|
+
});
|
|
17
|
+
this.testKeyPairs.set('bob', {
|
|
18
|
+
pubKey: 'bobPublicKey',
|
|
19
|
+
privKey: 'bobPrivateKey'
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
generateConstructorArgs(args) {
|
|
23
|
+
if (args.length === 0)
|
|
24
|
+
return '';
|
|
25
|
+
return args.map(arg => {
|
|
26
|
+
if (arg.defaultValue) {
|
|
27
|
+
return arg.defaultValue;
|
|
28
|
+
}
|
|
29
|
+
return this.generateValueForType(arg.type, arg.name);
|
|
30
|
+
}).join(', ');
|
|
31
|
+
}
|
|
32
|
+
generateMethodArgs(parameters, methodName) {
|
|
33
|
+
return parameters.map(param => {
|
|
34
|
+
return this.generateValueForType(param.type, `${methodName}_${param.name}`);
|
|
35
|
+
}).join(', ');
|
|
36
|
+
}
|
|
37
|
+
generateInvalidMethodArgs(parameters, methodName) {
|
|
38
|
+
return parameters.map(param => {
|
|
39
|
+
return this.generateInvalidValueForType(param.type, `${methodName}_${param.name}`);
|
|
40
|
+
}).join(', ');
|
|
41
|
+
}
|
|
42
|
+
generateValueForType(type, variableName, model) {
|
|
43
|
+
// Ensure unique variable names
|
|
44
|
+
let uniqueName = variableName;
|
|
45
|
+
let counter = 1;
|
|
46
|
+
while (this.usedVariableNames.has(uniqueName)) {
|
|
47
|
+
uniqueName = `${variableName}${counter}`;
|
|
48
|
+
counter++;
|
|
49
|
+
}
|
|
50
|
+
this.usedVariableNames.add(uniqueName);
|
|
51
|
+
switch (type) {
|
|
52
|
+
case 'bigint':
|
|
53
|
+
return '1n';
|
|
54
|
+
case 'boolean':
|
|
55
|
+
return 'true';
|
|
56
|
+
case 'ByteString':
|
|
57
|
+
return `toByteString('00', false)`;
|
|
58
|
+
case 'PubKey':
|
|
59
|
+
return this.getTestKey('default').pubKey;
|
|
60
|
+
case 'Sig':
|
|
61
|
+
return ` (sigResps) => findSig(sigResps, myPublicKey)),
|
|
62
|
+
{
|
|
63
|
+
pubKeyOrAddrToSign: myPublicKey,
|
|
64
|
+
} as MethodCallOptions<${model?.name}>`;
|
|
65
|
+
case 'number':
|
|
66
|
+
return '42';
|
|
67
|
+
case 'string':
|
|
68
|
+
return `'test'`;
|
|
69
|
+
default:
|
|
70
|
+
if (type.includes('bigint[]')) {
|
|
71
|
+
return '[1n, 2n, 3n]';
|
|
72
|
+
}
|
|
73
|
+
if (type.includes('[]')) {
|
|
74
|
+
return `[]`;
|
|
75
|
+
}
|
|
76
|
+
return 'undefined';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
generateInvalidValueForType(type, variableName) {
|
|
80
|
+
switch (type) {
|
|
81
|
+
case 'bigint':
|
|
82
|
+
return '0n'; // Often invalid for amounts
|
|
83
|
+
case 'boolean':
|
|
84
|
+
return 'false';
|
|
85
|
+
case 'ByteString':
|
|
86
|
+
return `toByteString('', false)`; // Empty byte string
|
|
87
|
+
case 'PubKey':
|
|
88
|
+
return `PubKey(toByteString('00', false))`; // Invalid pubkey
|
|
89
|
+
case 'Sig':
|
|
90
|
+
return `Sig(toByteString('00', false))`; // Invalid signature
|
|
91
|
+
case 'number':
|
|
92
|
+
return '-1';
|
|
93
|
+
case 'string':
|
|
94
|
+
return `''`;
|
|
95
|
+
default:
|
|
96
|
+
return this.generateValueForType(type, variableName);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
getTestKey(name = 'default') {
|
|
100
|
+
const keyPair = this.testKeyPairs.get(name);
|
|
101
|
+
if (!keyPair) {
|
|
102
|
+
throw new Error(`Test key pair '${name}' not found`);
|
|
103
|
+
}
|
|
104
|
+
return keyPair;
|
|
105
|
+
}
|
|
106
|
+
getEdgeCaseValue(type, model) {
|
|
107
|
+
switch (type) {
|
|
108
|
+
case 'bigint':
|
|
109
|
+
return '0n';
|
|
110
|
+
case 'boolean':
|
|
111
|
+
return 'false';
|
|
112
|
+
case 'ByteString':
|
|
113
|
+
return `toByteString('ff', false)`;
|
|
114
|
+
case 'PubKey':
|
|
115
|
+
return `PubKey(toByteString('00'.repeat(33), false))`;
|
|
116
|
+
case 'Sig':
|
|
117
|
+
return ` (sigResps) => findSig(sigResps, myPublickey)),
|
|
118
|
+
{
|
|
119
|
+
pubKeyOrAddrToSign: myPublicKey,
|
|
120
|
+
} as MethodCallOptions<${model?.name}>`;
|
|
121
|
+
default:
|
|
122
|
+
return this.generateValueForType(type, 'edgeCase');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
reset() {
|
|
126
|
+
this.usedVariableNames.clear();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.ValueGenerator = ValueGenerator;
|
|
130
|
+
//# sourceMappingURL=value-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-generator.js","sourceRoot":"","sources":["../../src/generator/value-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ConstructorArg {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
defaultValue?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ContractProp {
|
|
7
|
+
name: string;
|
|
8
|
+
type: string;
|
|
9
|
+
isMutable: boolean;
|
|
10
|
+
decoratorText: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MethodParameter {
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
isOptional: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare enum MethodCategory {
|
|
18
|
+
PURE_VALIDATION = "pure-validation",
|
|
19
|
+
STATE_TRANSITION = "state-transition",
|
|
20
|
+
SPENDING_CONSTRAINT = "spending-constraint"
|
|
21
|
+
}
|
|
22
|
+
export interface ContractMethod {
|
|
23
|
+
name: string;
|
|
24
|
+
parameters: MethodParameter[];
|
|
25
|
+
returnType: string;
|
|
26
|
+
category: MethodCategory;
|
|
27
|
+
isPublic: boolean;
|
|
28
|
+
mutatesState: boolean;
|
|
29
|
+
usesHashOutputs: boolean;
|
|
30
|
+
hasAssert: boolean;
|
|
31
|
+
decoratorText: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ContractModel {
|
|
34
|
+
name: string;
|
|
35
|
+
filePath: string;
|
|
36
|
+
constructorArgs: ConstructorArg[];
|
|
37
|
+
props: ContractProp[];
|
|
38
|
+
methods: ContractMethod[];
|
|
39
|
+
imports: string[];
|
|
40
|
+
extendsClass: string;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=contract-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-model.d.ts","sourceRoot":"","sources":["../../src/model/contract-model.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,oBAAY,cAAc;IACxB,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MethodCategory = void 0;
|
|
4
|
+
var MethodCategory;
|
|
5
|
+
(function (MethodCategory) {
|
|
6
|
+
MethodCategory["PURE_VALIDATION"] = "pure-validation";
|
|
7
|
+
MethodCategory["STATE_TRANSITION"] = "state-transition";
|
|
8
|
+
MethodCategory["SPENDING_CONSTRAINT"] = "spending-constraint";
|
|
9
|
+
})(MethodCategory || (exports.MethodCategory = MethodCategory = {}));
|
|
10
|
+
//# sourceMappingURL=contract-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-model.js","sourceRoot":"","sources":["../../src/model/contract-model.ts"],"names":[],"mappings":";;;AAmBA,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,qDAAmC,CAAA;IACnC,uDAAqC,CAAA;IACrC,6DAA2C,CAAA;AAC7C,CAAC,EAJW,cAAc,8BAAd,cAAc,QAIzB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
export declare function getDecoratorText(decorator: ts.Decorator): string;
|
|
3
|
+
export declare function getTypeText(type: ts.TypeNode | undefined, checker: ts.TypeChecker): string;
|
|
4
|
+
export declare function getDefaultValueForType(type: string): string;
|
|
5
|
+
export declare function isSmartContractClass(node: ts.Node): boolean;
|
|
6
|
+
export declare function findDecorator(node: ts.Node, decoratorName: string): ts.Decorator | undefined;
|
|
7
|
+
//# sourceMappingURL=ast-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-utils.d.ts","sourceRoot":"","sources":["../../src/parser/ast-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,GAAG,MAAM,CAQhE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,GAAG,MAAM,CAc1F;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoB3D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAe3D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,EAAE,CAAC,SAAS,GAAG,SAAS,CAO5F"}
|