fix(test): All tests are working with vitest [DXJ-306] (#291)

This commit is contained in:
Pavel 2023-03-23 16:10:51 +04:00 committed by GitHub
parent 9345040b87
commit 58ad3ca6f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 589 additions and 1011 deletions

View File

@ -19,3 +19,6 @@ node_modules/
jspm_packages/
.idea
# workaround to make integration tests work
src/marine/worker-script/index.js

View File

@ -1,6 +1,6 @@
module Export
import SignResult, Sig from "../../../aqua/services.aqua"
import SignResult, Sig from "../aqua/services.aqua"
export Sig, DataProvider, callSig
service DataProvider("data"):

View File

@ -1,7 +1,7 @@
module Export
import Srv from "../../../aqua/single-module-srv.aqua"
import NodeUtils from "../../../aqua/node-utils.aqua"
import Srv from "../aqua/single-module-srv.aqua"
import NodeUtils from "../aqua/node-utils.aqua"
export happy_path, list_services, file_not_found, service_removed, removing_non_exiting
service Greeting("greeting"):

View File

@ -0,0 +1,3 @@
import { copyFileSync } from 'fs';
copyFileSync('./dist/marine/worker-script/index.js', './src/marine/worker-script/index.js');

View File

@ -1,17 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
extensionsToTreatAsEsm: ['.ts'],
"preset": "ts-jest/presets/default-esm",
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.js$": "$1"
},
"transform": {
"^.+\\.tsx?$": [
"ts-jest",
{
"useESM": true
}
]
}
};

View File

@ -11,11 +11,8 @@
"type": "module",
"scripts": {
"build": "tsc",
"compile-aqua": "aqua -i ./aqua/ -o ./src/internal/_aqua",
"test:smoke": "node ./dist/js-peer/__test__/integration/smokeTest.js",
"test": "NODE_OPTIONS=--experimental-vm-modules pnpm jest",
"test:unit": "NODE_OPTIONS=--experimental-vm-modules pnpm jest --testPathPattern=src/__test__/unit",
"test:integration": "NODE_OPTIONS=--experimental-vm-modules pnpm jest --testPathPattern=src/__test__/integration"
"compile-aqua": "fluence aqua -i ./aqua/ -o ./aqua",
"test": "node ./copy-worker-script-workaround.mjs && vitest run"
},
"repository": "https://github.com/fluencelabs/fluence-js",
"author": "Fluence Labs",
@ -52,15 +49,13 @@
"@multiformats/multiaddr": "11.3.0"
},
"devDependencies": {
"@fluencelabs/aqua": "0.7.7-362",
"@fluencelabs/aqua-api": "0.9.1-373",
"@fluencelabs/cli": "0.3.9",
"@fluencelabs/aqua-api": "0.9.3",
"@fluencelabs/aqua-lib": "0.6.0",
"@fluencelabs/fluence-network-environment": "1.0.13",
"@types/bs58": "4.0.1",
"@types/uuid": "8.3.2",
"@types/jest": "29.4.0",
"@types/debug": "4.1.7",
"jest": "29.4.1",
"ts-jest": "next"
"vitest": "0.29.7"
}
}

View File

@ -1,3 +1,4 @@
import { it, describe, expect, test } from 'vitest';
import { aqua2ts, ts2aqua } from '../conversions.js';
const i32 = { tag: 'scalar', name: 'i32' } as const;

View File

@ -1,3 +1,5 @@
import { it, describe, expect } from 'vitest';
import { handleTimeout } from '../../utils.js';
import { registerHandlersHelper, withPeer } from '../util.js';

View File

@ -1,3 +1,5 @@
import { it, describe, expect, beforeEach, afterEach } from 'vitest';
import { Particle } from '../../Particle.js';
import { doNothing } from '../../utils.js';
import { FluencePeer } from '../../FluencePeer.js';

View File

@ -0,0 +1,31 @@
import { it, describe, expect, beforeAll } from 'vitest';
import * as fs from 'fs';
import * as url from 'url';
import * as path from 'path';
import { compileAqua, withPeer } from '../util.js';
let aqua: any;
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
describe('Marine js tests', () => {
beforeAll(async () => {
const pathToAquaFiles = path.join(__dirname, '../../../../aqua_test/marine-js.aqua');
const { services, functions } = await compileAqua(pathToAquaFiles);
aqua = functions;
});
it('should call marine service correctly', async () => {
await withPeer(async (peer) => {
// arrange
const wasm = await fs.promises.readFile(path.join(__dirname, '../data/greeting.wasm'));
await peer.registerMarineService(wasm, 'greeting');
// act
const res = await aqua.call(peer, { arg: 'test' });
// assert
expect(res).toBe('Hi, Hi, Hi, test');
});
});
});

View File

@ -1,53 +0,0 @@
import * as fs from 'fs';
import * as url from 'url';
import * as path from 'path';
import { compileAqua, withPeer } from '../util.js';
let aqua: any;
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
describe('Marine js tests', () => {
beforeAll(async () => {
const { services, functions } = await compileAqua(path.join(__dirname, '../data/marine-js.aqua'));
aqua = functions;
});
it('should call marine service correctly', async () => {
await withPeer(async (peer) => {
// arrange
const wasm = await fs.promises.readFile(path.join(__dirname, '../data/greeting.wasm'));
await peer.registerMarineService(wasm, 'greeting');
// act
const res = await aqua.call(peer, { arg: 'test' });
// assert
expect(res).toBe('Hi, Hi, Hi, test');
});
});
// TODO: console printouts are happening inside web-worker\worker threads.
// Find a way to mock functions in background thread
it.skip('logging should work', async () => {
await withPeer(async (peer) => {
// arrange
jest.spyOn(global.console, 'info').mockImplementation(() => {});
await peer.start({
debug: {
marineLogLevel: 'debug',
},
});
const wasm = await fs.promises.readFile(path.join(__dirname, '../data/greeting-record.wasm'));
await peer.registerMarineService(wasm, 'greeting');
// act
await aqua.call_info(peer, { arg: 'greeting' });
// assert
expect(console.info).toBeCalledTimes(1);
expect(console.info).toHaveBeenNthCalledWith(1, '[marine service "greeting"]: info');
});
});
});

View File

@ -1,7 +1,10 @@
import { it, describe, expect } from 'vitest';
import { nodes } from '../connection.js';
import { checkConnection, doNothing, handleTimeout } from '../../utils.js';
import { registerHandlersHelper, mkTestPeer, withPeer, withConnectedPeer } from '../util.js';
import { FluencePeer } from '../../FluencePeer.js';
import { isFluencePeer } from '@fluencelabs/interfaces';
describe('Typescript usage suite', () => {
it('should perform test for FluencePeer class correctly', () => {
@ -12,10 +15,10 @@ describe('Typescript usage suite', () => {
const undefinedVal = undefined;
// act
const isPeerPeer = FluencePeer.isInstance(peer);
const isNumberPeer = FluencePeer.isInstance(number);
const isObjectPeer = FluencePeer.isInstance(object);
const isUndefinedPeer = FluencePeer.isInstance(undefinedVal);
const isPeerPeer = isFluencePeer(peer);
const isNumberPeer = isFluencePeer(number);
const isObjectPeer = isFluencePeer(object);
const isUndefinedPeer = isFluencePeer(undefinedVal);
// act
expect(isPeerPeer).toBe(true);
@ -196,7 +199,7 @@ describe('Typescript usage suite', () => {
expect(isConnected).toBeTruthy();
},
{ connectTo: nodes[0], dialTimeoutMs: 100000 },
{ relay: nodes[0], connectionOptions: { dialTimeoutMs: 100000 } },
);
});
@ -207,18 +210,7 @@ describe('Typescript usage suite', () => {
expect(isConnected).toBeTruthy();
},
{ connectTo: nodes[0], skipCheckConnection: true },
);
});
it('With connection options: checkConnectionTTL', async () => {
await withPeer(
async (peer) => {
const isConnected = await checkConnection(peer);
expect(isConnected).toBeTruthy();
},
{ connectTo: nodes[0], checkConnectionTimeoutMs: 1000 },
{ relay: nodes[0], connectionOptions: { skipCheckConnection: true } },
);
});
@ -229,7 +221,7 @@ describe('Typescript usage suite', () => {
expect(isConnected).toBeFalsy();
},
{ connectTo: nodes[0], defaultTtlMs: 1 },
{ relay: nodes[0], defaultTtlMs: 1 },
);
});
});

View File

@ -1,10 +1,12 @@
import { it, describe, expect, beforeAll } from 'vitest';
import * as path from 'path';
import * as url from 'url';
import { KeyPair } from '../../../keypair/index.js';
import { allowServiceFn } from '../../builtins/securityGuard.js';
import { Sig } from '../../builtins/Sig.js';
import { compileAqua, withPeer } from '../util.js';
import { registerServiceImpl } from '../../compilerSupport/registerService.js';
import { registerService } from '../../../compilerSupport/registerService.js';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
@ -14,7 +16,9 @@ let dataProviderDef: any;
describe('Sig service test suite', () => {
beforeAll(async () => {
const { services, functions } = await compileAqua(path.join(__dirname, '../data/sigService.aqua'));
const pathToAquaFiles = path.join(__dirname, '../../../../aqua_test/sigService.aqua');
const { services, functions } = await compileAqua(pathToAquaFiles);
aqua = functions;
sigDef = services.Sig;
dataProviderDef = services.DataProvider;
@ -26,11 +30,16 @@ describe('Sig service test suite', () => {
const customSig = new Sig(customKeyPair);
const data = [1, 2, 3, 4, 5];
registerServiceImpl(peer, sigDef, 'CustomSig', customSig);
registerService({ peer, def: sigDef, serviceId: 'CustomSig', service: customSig });
registerServiceImpl(peer, dataProviderDef, 'data', {
provide_data: () => {
return data;
registerService({
peer,
def: dataProviderDef,
serviceId: 'data',
service: {
provide_data: () => {
return data;
},
},
});
@ -50,11 +59,16 @@ describe('Sig service test suite', () => {
const customSig = new Sig(customKeyPair);
const data = [1, 2, 3, 4, 5];
registerServiceImpl(peer, sigDef, 'CustomSig', customSig);
registerService({ peer, def: sigDef, serviceId: 'CustomSig', service: customSig });
registerServiceImpl(peer, dataProviderDef, 'data', {
provide_data: () => {
return data;
registerService({
peer,
def: dataProviderDef,
serviceId: 'data',
service: {
provide_data: () => {
return data;
},
},
});
@ -69,9 +83,14 @@ describe('Sig service test suite', () => {
const sig = peer.getServices().sig;
const data = [1, 2, 3, 4, 5];
registerServiceImpl(peer, dataProviderDef, 'data', {
provide_data: () => {
return data;
registerService({
peer: peer,
def: dataProviderDef,
serviceId: 'data',
service: {
provide_data: () => {
return data;
},
},
});

View File

@ -0,0 +1,61 @@
import { it, describe, expect } from 'vitest';
import { handleTimeout } from '../../utils.js';
import { nodes } from '../connection.js';
import { mkTestPeer, registerHandlersHelper } from '../util.js';
describe('Smoke test', () => {
it('Simple call', async () => {
// arrange
const peer = mkTestPeer();
await peer.start({
relay: nodes[0],
});
const result = await new Promise<string[]>((resolve, reject) => {
const script = `
(xor
(seq
(call %init_peer_id% ("load" "relay") [] init_relay)
(seq
(call init_relay ("op" "identity") ["hello world!"] result)
(call %init_peer_id% ("callback" "callback") [result])
)
)
(seq
(call init_relay ("op" "identity") [])
(call %init_peer_id% ("callback" "error") [%last_error%])
)
)`;
const particle = peer.internals.createNewParticle(script);
if (particle instanceof Error) {
return reject(particle.message);
}
registerHandlersHelper(peer, particle, {
load: {
relay: () => {
return peer.getStatus().relayPeerId;
},
},
callback: {
callback: (args: any) => {
const [val] = args;
resolve(val);
},
error: (args: any) => {
const [error] = args;
reject(error);
},
},
});
peer.internals.initiateParticle(particle, handleTimeout(reject));
});
await peer.stop();
expect(result).toBe('hello world!');
});
});

View File

@ -1,67 +0,0 @@
import { handleTimeout } from '../../utils.js';
import { nodes } from '../connection.js';
import { mkTestPeer, registerHandlersHelper } from '../util.js';
const smokeTest = async () => {
// arrange
const peer = mkTestPeer();
await peer.start({
relay: nodes[0],
});
const result = await new Promise<string[]>((resolve, reject) => {
const script = `
(xor
(seq
(call %init_peer_id% ("load" "relay") [] init_relay)
(seq
(call init_relay ("op" "identity") ["hello world!"] result)
(call %init_peer_id% ("callback" "callback") [result])
)
)
(seq
(call init_relay ("op" "identity") [])
(call %init_peer_id% ("callback" "error") [%last_error%])
)
)`;
const particle = peer.internals.createNewParticle(script);
if (particle instanceof Error) {
return reject(particle.message);
}
registerHandlersHelper(peer, particle, {
load: {
relay: () => {
return peer.getStatus().relayPeerId;
},
},
callback: {
callback: (args: any) => {
const [val] = args;
resolve(val);
},
error: (args: any) => {
const [error] = args;
reject(error);
},
},
});
peer.internals.initiateParticle(particle, handleTimeout(reject));
});
await peer.stop();
if (result[0] !== 'hello world!') {
throw new Error('Expecting "hello wrold!" got ' + result[0]);
}
};
smokeTest()
.then(() => {
console.log('Test passed');
})
.catch((err) => {
console.error('Test failed: ', err);
});

View File

@ -1,3 +1,4 @@
import { it, describe, expect, beforeAll } from 'vitest';
import * as path from 'path';
import * as url from 'url';
import { compileAqua, withPeer } from '../util.js';
@ -7,7 +8,8 @@ let aqua: any;
describe('Srv service test suite', () => {
beforeAll(async () => {
const { services, functions } = await compileAqua(path.join(__dirname, '../data/srv.aqua'));
const pathToAquaFiles = path.join(__dirname, '../../../../aqua_test/srv.aqua');
const { services, functions } = await compileAqua(pathToAquaFiles);
aqua = functions;
});

View File

@ -1,3 +1,5 @@
import { it, describe, expect, beforeAll, afterAll } from 'vitest';
import { mkTestPeer } from '../util.js';
const peer = mkTestPeer();

View File

@ -1,3 +1,5 @@
import { it, describe, expect, test } from 'vitest';
import { CallParams } from '@fluencelabs/interfaces';
import { toUint8Array } from 'js-base64';
import { CallServiceData } from '../../../interfaces/commonTypes.js';

View File

@ -36,6 +36,10 @@ export const compileAqua = async (aquaFile: string): Promise<CompiledFile> => {
const compilationResult = await api.Aqua.compile(new api.Path(aquaFile), [], undefined);
if (compilationResult.errors.length > 0) {
throw new Error('Aqua compilation failed. Error: ' + compilationResult.errors.join('/n'));
}
const functions = Object.entries(compilationResult.functions)
.map(([name, fnInfo]) => {
const callFn = (peer: FluencePeer, args: { [key: string]: any }) => {

View File

@ -1,3 +1,4 @@
import { it, describe, expect } from 'vitest';
import { toUint8Array } from 'js-base64';
import * as bs58 from 'bs58';
import { KeyPair } from '../index.js';

1253
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff