-
Notifications
You must be signed in to change notification settings - Fork 264
Expand file tree
/
Copy pathkernel-host.test.ts
More file actions
87 lines (78 loc) · 3.05 KB
/
kernel-host.test.ts
File metadata and controls
87 lines (78 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import child = require('child_process');
import fs = require('fs');
import { api } from 'jsii-kernel';
import spec = require('jsii-spec');
import path = require('path');
import { KernelHost, InputOutput, Input, Output } from '../lib';
test('can load libraries from within a callback', () => {
const inout = new TestInputOutput(
[
{ api: 'load', ...loadRequest('@scope/jsii-calc-base') },
{ api: 'load', ...loadRequest('@scope/jsii-calc-lib') },
{ api: 'create', fqn: 'Object', interfaces: ['@scope/jsii-calc-lib.IFriendly'], overrides: [{ method: 'hello' }] },
{ api: 'invoke', objref: { [api.TOKEN_REF]: 'Object@10000' }, method: 'hello' },
{ api: 'load', ...loadRequest('jsii-calc') },
{ complete: { cbid: 'jsii::callback::20000', result: 'SUCCESS!' } },
]
);
const host = new KernelHost(inout, { noStack: true, debug: false });
return new Promise<void>(ok => {
host.on('exit', () => ok(inout.expectCompleted()));
host.run();
});
});
class TestInputOutput extends InputOutput {
private readonly inputCommands: Input[];
public constructor(inputCommands: Input[], private readonly allowErrors = false) {
super();
this.inputCommands = inputCommands.reverse();
}
public read(): Input | undefined {
return this.inputCommands.pop();
}
public write(obj: Output): void {
if (!this.allowErrors) {
expect(obj).not.toHaveProperty('error');
}
if ('ok' in obj && 'assembly' in obj.ok) {
// Removing the type count as this is subject to change!
(obj.ok as any).types = '*redacted*';
}
expect(obj).toMatchSnapshot();
}
/**
* Validates that all inputs have been consumed, and all expected outputs have been checked.
*/
public expectCompleted(): void {
expect(this.inputCommands).toEqual([]);
}
}
function loadRequest(library: string): api.LoadRequest {
const assembly = loadAssembly();
const tarball = path.join(__dirname, '_tarballs', library, `${assembly.fingerprint.replace('/', '_')}.tgz`);
if (!fs.existsSync(tarball)) {
packageLibrary(tarball);
}
return {
name: assembly.name,
version: assembly.version,
tarball,
};
function loadAssembly(): spec.Assembly {
const assemblyFile = path.resolve(require.resolve(`${library}/package.json`), '..', '.jsii');
return JSON.parse(fs.readFileSync(assemblyFile, { encoding: 'utf-8' }));
}
function packageLibrary(target: string): void {
const targetDir = path.dirname(target);
fs.mkdirSync(targetDir, { recursive: true });
const result = child.spawnSync('npm', ['pack', path.dirname(require.resolve(`${library}/package.json`))], { cwd: targetDir, stdio: ['inherit', 'pipe', 'pipe'] });
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
console.error(result.stderr.toString('utf-8'));
throw new Error(`Unable to 'npm pack' ${library}: process ${result.signal != null ? `killed by ${result.signal}` : `exited with code ${result.status}`}`);
}
fs.renameSync(path.join(targetDir, result.stdout.toString('utf-8').trim()), target);
}
}