UNPKG

@patchworkdev/common

Version:

Patchwork Development Kit

182 lines (181 loc) 8.65 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const types_1 = require("../../types"); const contractSchema_1 = require("../contractSchema"); const mainContractGen_1 = require("../mainContractGen"); const userContractGen_1 = require("../userContractGen"); function removeDirectoryRecursive(dirPath) { if (fs_1.default.existsSync(dirPath)) { fs_1.default.readdirSync(dirPath).forEach((file) => { const curPath = path_1.default.join(dirPath, file); if (fs_1.default.lstatSync(curPath).isDirectory()) { // Recursive call for directories removeDirectoryRecursive(curPath); } else { // Delete file fs_1.default.unlinkSync(curPath); } }); fs_1.default.rmdirSync(dirPath); } } function generateFieldPermutations() { const fieldTypes = Object.values(types_1.FieldTypeEnum) .filter(value => typeof value === 'string' && value !== 'empty' && value !== 'CHAR64'); let permutations = []; fieldTypes.forEach((fieldType, index) => { let actualFieldType = (fieldType.toLowerCase()); actualFieldType = actualFieldType.toLowerCase(); // Single field permutations.push([{ id: 1, key: `field_${actualFieldType}`, type: actualFieldType, description: `A single ${actualFieldType} field`, }]); // Array field (exclude for 'string' type) if (actualFieldType !== 'string') { permutations.push([{ id: 1, key: `array_${actualFieldType}`, type: actualFieldType, arrayLength: 4, description: `An array of ${actualFieldType} fields`, }]); } }); return permutations; } function generateContractSchemaPermutations() { const baseConfig = { scopeName: "TestScope", name: "TestContract", symbol: "TST", baseURI: "https://example.com/", schemaURI: "https://example.com/schema", imageURI: "https://example.com/image", fields: [], features: [types_1.Feature.MINTABLE, types_1.Feature.LITEREF], fragments: [] }; const fieldPermutations = generateFieldPermutations(); return fieldPermutations.map((fields) => ({ ...baseConfig, fields, })); } describe("Generate and Build Contract Schema Field Permutations", () => { const outputDir = path_1.default.join(__dirname, "generated_contracts"); const schemaNoVerifyDir = path_1.default.join(__dirname, "schema_noverify"); const schemaNoBuildDir = path_1.default.join(__dirname, "schema_nobuild"); beforeAll(() => { // Create directories if they don't exist [outputDir, schemaNoVerifyDir, schemaNoBuildDir].forEach(dir => { if (!fs_1.default.existsSync(dir)) { fs_1.default.mkdirSync(dir, { recursive: true }); } }); // Clear contents of schema_noverify and schema_nobuild [schemaNoVerifyDir, schemaNoBuildDir].forEach(dir => { removeDirectoryRecursive(dir); fs_1.default.mkdirSync(dir); }); // Clear contents of generated_contracts, preserving remappings.txt and foundry.toml fs_1.default.readdirSync(outputDir).forEach(file => { const filePath = path_1.default.join(outputDir, file); if (file !== 'remappings.txt' && file !== 'foundry.toml') { if (fs_1.default.lstatSync(filePath).isDirectory()) { removeDirectoryRecursive(filePath); } else { fs_1.default.unlinkSync(filePath); } } }); }); it("should generate, save, and build all contract schema field permutations", async () => { console.log("Generating contract schema field permutations..."); const permutations = generateContractSchemaPermutations(); const mainContractGen = new mainContractGen_1.MainContractGen(); const userContractGen = new userContractGen_1.UserContractGen(); let errors = []; for (let index = 0; index < permutations.length; index++) { const config = permutations[index]; console.log(`Processing field permutation ${index}:`, config); const schema = new contractSchema_1.ContractSchemaImpl(config); try { schema.validate(); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`Schema validation failed for contract ${index}:`, errorMessage); fs_1.default.writeFileSync(path_1.default.join(schemaNoVerifyDir, `schema_${index}.json`), JSON.stringify(config, null, 2)); errors.push(`Schema validation failed for contract ${index}: ${errorMessage}`); continue; // Skip to the next permutation } try { const mainCode = mainContractGen.gen(schema); const userCode = userContractGen.gen(schema); const mainFileName = path_1.default.join(outputDir, `TestContractGenerated.sol`); const userFileName = path_1.default.join(outputDir, `TestContract.sol`); fs_1.default.writeFileSync(mainFileName, mainCode); fs_1.default.writeFileSync(userFileName, userCode); console.log(`Generated contract ${index}`); // Call forge build await new Promise((resolve, reject) => { (0, child_process_1.exec)('forge build', { cwd: outputDir }, (error, stdout, stderr) => { if (error) { console.error(`forge build failed for contract ${index}:`); console.error(stderr); fs_1.default.writeFileSync(path_1.default.join(schemaNoBuildDir, `schema_${index}.json`), JSON.stringify(config, null, 2)); errors.push(`forge build failed for contract ${index}: ${stderr}`); resolve(); // Resolve even on error to continue processing } else { console.log(`Successfully built contract ${index}`); resolve(); } }); }); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`Error in contract ${index}:`, errorMessage); errors.push(`Error in contract ${index}: ${errorMessage}`); } finally { // Clean up .sol files after each attempt const mainFileName = path_1.default.join(outputDir, `TestContractGenerated.sol`); const userFileName = path_1.default.join(outputDir, `TestContract.sol`); if (fs_1.default.existsSync(mainFileName)) fs_1.default.unlinkSync(mainFileName); if (fs_1.default.existsSync(userFileName)) fs_1.default.unlinkSync(userFileName); } // Add a small delay between iterations to allow for any pending I/O operations await new Promise(resolve => setTimeout(resolve, 100)); } console.log(`Total field permutations processed: ${permutations.length}`); console.log(`Total errors encountered: ${errors.length}`); if (errors.length > 0) { console.error("Errors encountered during processing:"); errors.forEach((error, index) => { console.error(`${index + 1}: ${error}`); }); throw new Error(`${errors.length} errors encountered during processing`); } expect(permutations.length).toBeGreaterThan(0); }); afterAll(() => { // Clean up after all tests removeDirectoryRecursive(path_1.default.join(outputDir, 'out')); removeDirectoryRecursive(path_1.default.join(outputDir, 'cache')); }); });