@5ive-tech/sdk 1.1.7 → 1.1.9

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.
@@ -76,6 +76,7 @@ export interface TestRunnerOptions {
76
76
  */
77
77
  export declare class FiveTestRunner {
78
78
  private options;
79
+ private compilationCache;
79
80
  constructor(options?: TestRunnerOptions);
80
81
  /**
81
82
  * Run a single test case
@@ -111,7 +112,6 @@ export declare class FiveTestRunner {
111
112
  private getValidationError;
112
113
  private matchesPattern;
113
114
  private chunkArray;
114
- private findTestFiles;
115
115
  private formatTestResult;
116
116
  private formatSuiteResult;
117
117
  }
@@ -4,14 +4,16 @@
4
4
  * SDK-based test utilities that replace shell script approaches with programmatic
5
5
  * Five SDK usage. Provides comprehensive testing capabilities for Five VM scripts.
6
6
  */
7
- import { readFile, readdir } from 'fs/promises';
8
- import { join, basename } from 'path';
7
+ import { readFile } from 'fs/promises';
8
+ import { basename } from 'path';
9
9
  import { FiveSDK } from '../FiveSDK.js';
10
+ import { TestDiscovery } from './TestDiscovery.js';
10
11
  /**
11
12
  * Five SDK-based test runner
12
13
  */
13
14
  export class FiveTestRunner {
14
15
  constructor(options = {}) {
16
+ this.compilationCache = new Map();
15
17
  this.options = {
16
18
  timeout: 30000,
17
19
  maxComputeUnits: 1000000,
@@ -40,13 +42,22 @@ export class FiveTestRunner {
40
42
  };
41
43
  }
42
44
  let bytecode;
45
+ let abi;
43
46
  // Get bytecode (compile source or load existing)
44
47
  if (testCase.source) {
45
- const result = await this.compileToBytecode(testCase.source);
46
- if (!result.success || !result.bytecode) {
47
- throw new Error(`Compilation failed: ${result.errors?.join(', ')}`);
48
+ if (!this.compilationCache.has(testCase.source)) {
49
+ const result = await this.compileToBytecode(testCase.source);
50
+ if (!result.success || !result.bytecode) {
51
+ throw new Error(`Compilation failed: ${result.errors?.join(', ')}`);
52
+ }
53
+ this.compilationCache.set(testCase.source, {
54
+ bytecode: result.bytecode,
55
+ abi: result.abi
56
+ });
48
57
  }
49
- bytecode = result.bytecode;
58
+ const cached = this.compilationCache.get(testCase.source);
59
+ bytecode = cached.bytecode;
60
+ abi = cached.abi;
50
61
  }
51
62
  else if (testCase.bytecode) {
52
63
  const data = await readFile(testCase.bytecode);
@@ -67,7 +78,8 @@ export class FiveTestRunner {
67
78
  const executionPromise = FiveSDK.executeLocally(bytecode, testCase.function || 0, testCase.parameters || [], {
68
79
  debug: this.options.debug,
69
80
  trace: this.options.trace,
70
- computeUnitLimit: this.options.maxComputeUnits
81
+ computeUnitLimit: this.options.maxComputeUnits,
82
+ abi
71
83
  });
72
84
  const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Test timeout')), executionTimeout));
73
85
  const result = await Promise.race([executionPromise, timeoutPromise]);
@@ -187,23 +199,52 @@ export class FiveTestRunner {
187
199
  * Discover and load test suites from directory
188
200
  */
189
201
  async discoverTestSuites(directory, pattern = '**/*.test.json') {
190
- const testFiles = await this.findTestFiles(directory, pattern);
202
+ const discovered = await TestDiscovery.discoverTests(directory, { verbose: this.options.verbose });
191
203
  const suites = [];
192
- for (const file of testFiles) {
193
- try {
194
- const content = await readFile(file, 'utf8');
195
- const data = JSON.parse(content);
196
- const suite = {
197
- name: data.name || basename(file, '.test.json'),
198
- description: data.description,
199
- testCases: data.tests || data.testCases || []
200
- };
201
- suites.push(suite);
204
+ const byFile = new Map();
205
+ const loadedJsonSuites = new Set();
206
+ for (const test of discovered) {
207
+ if (test.type === 'json-suite') {
208
+ if (loadedJsonSuites.has(test.path)) {
209
+ continue;
210
+ }
211
+ try {
212
+ const content = await readFile(test.path, 'utf8');
213
+ const data = JSON.parse(content);
214
+ suites.push({
215
+ name: data.name || basename(test.path, '.test.json'),
216
+ description: data.description,
217
+ testCases: data.tests || data.testCases || []
218
+ });
219
+ loadedJsonSuites.add(test.path);
220
+ }
221
+ catch (error) {
222
+ console.warn(`Failed to load test suite ${test.path}: ${error}`);
223
+ }
224
+ continue;
202
225
  }
203
- catch (error) {
204
- console.warn(`Failed to load test suite ${file}: ${error}`);
226
+ if (test.type === 'v-source' && test.source) {
227
+ const cases = byFile.get(test.path) || [];
228
+ cases.push({
229
+ name: test.name,
230
+ source: test.path,
231
+ function: test.source.functionName,
232
+ parameters: test.parameters || [],
233
+ expected: {
234
+ success: true,
235
+ result: test.expectsResult ? test.expectedResult : undefined
236
+ }
237
+ });
238
+ byFile.set(test.path, cases);
205
239
  }
206
240
  }
241
+ for (const [file, testCases] of byFile.entries()) {
242
+ suites.push({
243
+ name: basename(file, '.v'),
244
+ description: `Tests from ${file}`,
245
+ testCases
246
+ });
247
+ }
207
248
  return suites;
208
249
  }
209
250
  /**
@@ -245,7 +286,7 @@ export class FiveTestRunner {
245
286
  // Private helper methods
246
287
  async compileToBytecode(sourcePath) {
247
288
  const source = await readFile(sourcePath, 'utf8');
248
- return FiveSDK.compile(source, { debug: this.options.debug });
289
+ return FiveSDK.compile({ filename: sourcePath, content: source }, { debug: this.options.debug });
249
290
  }
250
291
  validateResult(result, expected) {
251
292
  // Check success/failure
@@ -298,26 +339,6 @@ export class FiveTestRunner {
298
339
  }
299
340
  return chunks;
300
341
  }
301
- async findTestFiles(directory, pattern) {
302
- const files = [];
303
- try {
304
- const entries = await readdir(directory, { withFileTypes: true });
305
- for (const entry of entries) {
306
- const fullPath = join(directory, entry.name);
307
- if (entry.isDirectory()) {
308
- const subFiles = await this.findTestFiles(fullPath, pattern);
309
- files.push(...subFiles);
310
- }
311
- else if (entry.isFile() && entry.name.endsWith('.test.json')) {
312
- files.push(fullPath);
313
- }
314
- }
315
- }
316
- catch (error) {
317
- // Directory doesn't exist or not accessible
318
- }
319
- return files;
320
- }
321
342
  formatTestResult(result) {
322
343
  const icon = result.passed ? '✅' : '❌';
323
344
  const duration = `${result.duration}ms`;
package/dist/types.d.ts CHANGED
@@ -203,7 +203,7 @@ export interface CLIError extends Error {
203
203
  category: string;
204
204
  details?: any;
205
205
  }
206
- export declare const FIVE_VM_PROGRAM_ID = "Five111111111111111111111111111111111111111";
206
+ export declare const FIVE_VM_PROGRAM_ID = "4Qxf3pbCse2veUgZVMiAm3nWqJrYo2pT4suxHKMJdK1d";
207
207
  export interface FiveSDKConfig {
208
208
  network?: string;
209
209
  connection?: any;
package/dist/types.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Type definitions for Five SDK.
3
3
  */
4
4
  // ==================== Legacy SDK Types (for compatibility) ====================
5
- export const FIVE_VM_PROGRAM_ID = "Five111111111111111111111111111111111111111";
5
+ export const FIVE_VM_PROGRAM_ID = "4Qxf3pbCse2veUgZVMiAm3nWqJrYo2pT4suxHKMJdK1d";
6
6
  export class FiveSDKError extends Error {
7
7
  constructor(message, code, details) {
8
8
  super(message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5ive-tech/sdk",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "Client-agnostic TypeScript SDK for Five VM scripts on Solana",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,6 +36,7 @@
36
36
  "copy-assets": "mkdir -p dist/assets/vm && COPYFILE_DISABLE=1 cp src/assets/vm/* dist/assets/vm/",
37
37
  "test": "node examples/basic-usage.js",
38
38
  "test:jest": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand",
39
+ "test:localnet": "USE_SOLANA_MOCKS=0 RUN_LOCALNET_VALIDATOR_TESTS=1 NODE_OPTIONS=--experimental-vm-modules jest --runInBand src/__tests__/integration/localnet-fee-vault.test.ts",
39
40
  "gen-types": "node ./node_modules/typescript/bin/tsc && node dist/bin/gen-types.js",
40
41
  "prepublishOnly": "npm run build"
41
42
  },
File without changes