diff --git a/testApp/package.json b/testApp/package.json index 05d76a8..eb699c8 100644 --- a/testApp/package.json +++ b/testApp/package.json @@ -21,10 +21,12 @@ }, "homepage": "https://ton.dev/node-se", "dependencies": { + "error-polyfill": "^0.1.2", + "javascript-biginteger": "^0.9.2", "jest-lite": "^1.0.0-alpha.4", "opentracing": "^0.14.4", - "ton-client-web-js": "../", - "ton-client-js": "^0" + "ton-client-js": "^0", + "ton-client-web-js": "../" }, "devDependencies": { "puppeteer": "^4.0.1", diff --git a/testApp/prepare-suite.js b/testApp/prepare-suite.js index f60eafd..0c27459 100644 --- a/testApp/prepare-suite.js +++ b/testApp/prepare-suite.js @@ -109,12 +109,17 @@ function rewriteRunScript() { } }); + const giverKeysPath = path.resolve(os.homedir(), 'giverKeys.json'); + const giverKeys = fs.existsSync(giverKeysPath) + ? JSON.parse(fs.readFileSync(giverKeysPath, { encoding: 'utf8' })) + : null; const assets = [ `export default {`, ` env: {`, ` USE_NODE_SE: '${process.env.USE_NODE_SE || 'true'}',`, ` TON_NETWORK_ADDRESS: '${replaceLocalhost(process.env.TON_NETWORK_ADDRESS || 'http://127.0.0.1:8080')}',`, ` },`, + ` giverKeys: ${JSON.stringify(giverKeys)},`, ` contracts: {`, ]; const collectContracts = (abiVersion) => { @@ -164,24 +169,32 @@ function copyTestSuite() { rewriteRunScript(); } - -(async () => { +function removeTgzFiles() { for (const tgz of getTgzNames()) { - console.log('Remove ', tgz); - fs.unlinkSync(path.resolve(__dirname, tgz)); - } - if (fs.existsSync(path.resolve(__dirname, '..', '..', 'ton-client-js'))) { - await run('npm', 'pack', '../../ton-client-js'); - } - await run('npm', 'pack', '../'); - for (const tgz of getTgzNames()) { - console.log('Install ', tgz); - await run('npm', 'install', tgz, '--no-save', '--force'); - console.log('Remove ', tgz); + console.log('Remove', tgz); fs.unlinkSync(path.resolve(__dirname, tgz)); } +} - copyTestSuite(); -})(); +(async () => { + console.log('Save', 'package.json'); + const packageJson = fs.readFileSync(path.resolve(__dirname, 'package.json')); + try { + removeTgzFiles(); + + if (fs.existsSync(path.resolve(__dirname, '..', '..', 'ton-client-js'))) { + await run('npm', 'pack', '../../ton-client-js'); + } + await run('npm', 'pack', '../'); + const tgzNames = getTgzNames(); + console.log('Install', tgzNames.join(' ')); + await run('npm', 'install', '--force', ...tgzNames); + removeTgzFiles(); + copyTestSuite(); + } finally { + console.log('Restore', 'package.json'); + fs.writeFileSync(path.resolve(__dirname, 'package.json'), packageJson); + } +})(); diff --git a/testApp/run-suite.js b/testApp/run-suite.js index d5cb81b..98a9cb9 100644 --- a/testApp/run-suite.js +++ b/testApp/run-suite.js @@ -86,6 +86,7 @@ function onOutputLine(line) { console.log(`failure: ${failure}`); process.exit(failure > 0 ? 1 : 0); } + console.log(line); } let logText = ''; @@ -101,7 +102,7 @@ function onTestLog(text) { } function startWebPackDevServer() { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { run( path.resolve(__dirname, 'node_modules', '.bin', 'webpack-dev-server'), ['-d', '--config', 'webpack.config.js', '--progress', '--colors', '--host', '127.0.0.1'], diff --git a/testApp/suite/_/run.js b/testApp/suite/_/run.js index e10ec25..b31288f 100644 --- a/testApp/suite/_/run.js +++ b/testApp/suite/_/run.js @@ -1,5 +1,5 @@ -import * as j from 'jest-lite'; -import {tests} from './init-tests'; +import { BigInteger as bigInt } from 'javascript-biginteger'; +import { tests } from './init-tests'; //IMPORTS import aggregations_suite from '../aggregations.js'; @@ -13,9 +13,26 @@ import run_local_suite from '../run-local.js'; import test_error_messages_suite from '../test-error-messages.js'; //IMPORTS + +function errorToJson(error) { + const json = {}; + Object.entries(error).forEach(([key, value]) => { + json[key] = value; + }); + if (error.message && !json.message) { + json.message = error.message; + } + if (Object.keys(json).length === 0) { + json.message = error.toString(); + } + return json; +} + export async function startTests(onStateChange) { try { await tests.init(); + jest.setTimeout(300000); + const state = { version: await tests.client.config.getVersion(), passed: 0, @@ -24,7 +41,7 @@ export async function startTests(onStateChange) { }; onStateChange(state); - j.addEventHandler((event) => { + jest.addEventHandler((event) => { if (event.name === 'test_start') { console.log(`[TEST_START] ${JSON.stringify({ name: event.test.name, @@ -38,8 +55,8 @@ export async function startTests(onStateChange) { state.failed += 1; console.log(`[TEST_FAILURE] ${JSON.stringify({ name: event.test.name, - error: event.error, - errors: event.test.errors, + error: errorToJson(event.error), + errors: event.test.errors && event.test.errors.map(errorToJson), })}`); } else { return; @@ -47,7 +64,7 @@ export async function startTests(onStateChange) { onStateChange(state); }); onStateChange(state); - j.run().then((results) => { + jest.run().then((results) => { results.forEach((result) => { result.errors = result.errors.map((e) => { return e.toString().replace(/\n\s+at\s+.*/gi, '') diff --git a/testApp/suite/_/testing-platform.js b/testApp/suite/_/testing-platform.js index 1dcac27..1a0b48c 100644 --- a/testApp/suite/_/testing-platform.js +++ b/testApp/suite/_/testing-platform.js @@ -1,22 +1,27 @@ -import {initTONClient as initTC} from 'ton-client-web-js'; -import * as j from 'jest-lite'; -// import {Buffer as buffer} from 'buffer'; -// import * as p1 from 'error-polyfill'; +import { initTONClient as initTC } from 'ton-client-web-js'; +import * as jestLite from 'jest-lite'; +import { Buffer as buffer } from 'buffer'; +import * as p1 from 'error-polyfill'; // import * as p2 from 'react-native-console-time-polyfill'; -// import bigInt from 'big-integer'; +import { BigInteger as bigInt } from 'javascript-biginteger'; import assets from './assets'; -// if (!global.BigInt) { -// global.BigInt = bigInt; -// } -// if (!global.Buffer) { -// global.Buffer = buffer; -// } +if (bigInt && !global.BigInt) { + global.BigInt = bigInt; +} +if (buffer && !global.Buffer) { + global.Buffer = buffer; +} -global.jest = j; +global.jest = jestLite.jest; ['test', 'expect', 'afterAll', 'afterEach', 'beforeAll', 'beforeEach'].forEach((name) => { - global[name] = j[name]; -}) + jestLite.jest[name] = jestLite[name]; + global[name] = jestLite[name]; +}); + +['addEventHandler', 'run'].forEach((name) => { + jestLite.jest[name] = jestLite[name]; +}); jest.test.each = variants => (title, fn) => variants.forEach((v) => { jest.test(title.replace(/%i/g, v), () => fn(v)); @@ -27,12 +32,99 @@ jest.setTimeout = (timeout) => { global[testTimeoutSymbol] = timeout; }; -j.setTimeout(200000); +jestLite.jest.setTimeout(200000); + +function isBigInt(a) { + return typeof a === 'bigint' || a instanceof BigInt; +} + +function compareBigInt(a, b) { + const bigA = BigInt(a); + const bigB = BigInt(b); + if (typeof bigA !== 'bigint') { + return bigA.compare(bigB); + } + if (bigA < bigB) { + return -1; + } + if (bigA > bigB) { + return 1; + } + return 0; +} + +const bigIntMatchers = { + toBeGreaterThan(received, other) { + return { + pass: compareBigInt(received, other) > 0, + message: () => `${received} must be greater than ${other}`, + }; + }, + toBeGreaterThanOrEqual(received, other) { + return { + pass: compareBigInt(received, other) >= 0, + message: () => `${received} must be greater than or equal to ${other}`, + }; + }, + toBeLessThan(received, other) { + return { + pass: compareBigInt(received, other) < 0, + message: () => `${received} must be less than ${other}`, + } + }, + toBeLessThanOrEqual(received, other) { + return { + pass: compareBigInt(received, other) <= 0, + message: () => `${received} must be less than or equal to ${other}`, + } + }, + toEqual(received, other) { + return { + pass: compareBigInt(received, other) === 0, + message: () => `${received} must be equal to ${other}`, + } + }, + // toBe: null, + // toBeCloseTo: null, + // toBeDefined: null, + // toBeFalsy: null, + // toBeInstanceOf: null, + // toBeNaN: null, + // toBeNull: null, + // toBeTruthy: null, + // toBeUndefined: null, + // toContain: null, + // toContainEqual: null, + // toHaveLength: null, + // toHaveProperty: null, + // toMatch: null, + // toMatchObject: null, + // lastCalledWith: null, + // toBeCalled: null, + // toBeCalledWith: null, + // toHaveBeenCalled: null, + // toHaveBeenCalledTimes: null, + // toHaveBeenCalledWith: null, + // toHaveBeenLastCalledWith: null, + // toThrow: null, + // toThrowError: null, +}; +const defaultExpect = jestLite.jest.expect; +global.expect = jestLite.jest.expect = (received) => { + const wrapped = defaultExpect(received); + if (isBigInt(received)) { + Object.entries(bigIntMatchers).forEach(([name, fn]) => { + wrapped[name] = (...args) => fn(received, ...args); + }) + } + return wrapped; +} + // platform async function findGiverKeys() { - return null; + return assets.giverKeys; } async function writeGiverKeys(keys) {