Skip to content

Commit 95a9c25

Browse files
committed
add tests
1 parent 04c9ec4 commit 95a9c25

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

tests/TscBasedCompiler.spec.ts

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import { expect } from 'chai';
2+
import { describe, it, beforeEach, afterEach } from 'mocha';
3+
import { promises as fs } from 'fs';
4+
import os from 'os';
5+
import path from 'path';
6+
7+
import { IAppSource, ICompilerFile } from '../src/definition';
8+
import { AppsEngineValidator } from '../src/compiler/AppsEngineValidator';
9+
import { TscBasedCompiler } from '../src/compiler/TscBasedCompiler';
10+
11+
describe('TscBasedCompiler', () => {
12+
let tmpDir: string;
13+
let validator: AppsEngineValidator;
14+
let compiler: TscBasedCompiler;
15+
16+
// minimal appInfo shape
17+
const baseAppInfo: IAppSource['appInfo'] = {
18+
id: '4f7788b8-efe7-47aa-8284-4b59f65ea034',
19+
nameSlug: 'test',
20+
author: {
21+
name: 'Test Author',
22+
support: '',
23+
homepage: '',
24+
},
25+
description: 'Test App',
26+
iconFile: 'icon.png',
27+
implements: [],
28+
name: 'test',
29+
version: '1.0.0',
30+
classFile: 'Foo.ts', // default; tests will override as needed
31+
permissions: [],
32+
requiredApiVersion: '',
33+
};
34+
35+
beforeEach(async () => {
36+
// 1) create a fresh temp dir
37+
const prefix = path.join(os.tmpdir(), 'rc-test-');
38+
tmpDir = await fs.mkdtemp(prefix);
39+
40+
// 2) write a minimal app.json so createRequire() works
41+
const appJson = {
42+
id: baseAppInfo.id,
43+
version: baseAppInfo.version,
44+
classFile: baseAppInfo.classFile,
45+
permissions: baseAppInfo.permissions,
46+
};
47+
await fs.writeFile(
48+
path.join(tmpDir, 'app.json'),
49+
JSON.stringify(appJson),
50+
'utf8',
51+
);
52+
53+
// 3) instantiate and stub out inheritance checking
54+
validator = new AppsEngineValidator(require);
55+
// skip the real inheritance check in tests
56+
validator.checkInheritance = () => {};
57+
58+
compiler = new TscBasedCompiler(tmpDir, validator);
59+
});
60+
61+
afterEach(async () => {
62+
// clean up
63+
await fs.rm(tmpDir, { recursive: true, force: true });
64+
});
65+
66+
it('compiles a simple class with no errors', async () => {
67+
// we only care here that TS compiles and interfaces are extracted
68+
const sourceFiles: Record<string, ICompilerFile> = {
69+
'Foo.ts': {
70+
name: 'Foo.ts',
71+
content: `
72+
export interface IWidget { run(): void }
73+
export class Foo implements IWidget {
74+
public run(): void {
75+
// nothing
76+
}
77+
}
78+
`,
79+
version: 1,
80+
},
81+
};
82+
83+
const result = await compiler.transpileSource({
84+
appInfo: baseAppInfo,
85+
sourceFiles,
86+
});
87+
88+
expect(result.diagnostics).to.be.empty;
89+
expect(Object.keys(result.files)).to.include('Foo.js');
90+
expect(result.implemented).to.deep.equal(['IWidget']);
91+
expect(result.mainFile?.name).to.equal('Foo.js');
92+
});
93+
94+
it('produces diagnostics on invalid TS', async () => {
95+
// override to point at Bad.ts
96+
const badAppInfo = { ...baseAppInfo, classFile: 'Bad.ts' };
97+
await fs.writeFile(
98+
path.join(tmpDir, 'app.json'),
99+
JSON.stringify({
100+
id: badAppInfo.id,
101+
version: badAppInfo.version,
102+
classFile: badAppInfo.classFile,
103+
permissions: badAppInfo.permissions,
104+
}),
105+
'utf8',
106+
);
107+
108+
const sourceFiles: Record<string, ICompilerFile> = {
109+
'Bad.ts': {
110+
name: 'Bad.ts',
111+
content: 'const x: string = 123;',
112+
version: 1,
113+
},
114+
};
115+
116+
const { diagnostics } = await compiler.transpileSource({
117+
appInfo: badAppInfo,
118+
sourceFiles,
119+
});
120+
121+
expect(diagnostics).to.not.be.empty;
122+
expect(diagnostics[0]).to.have.property('filename', 'Bad.ts');
123+
});
124+
125+
it('detects implemented interfaces in a “real” App class', async () => {
126+
// override to point at TestApp.ts
127+
const testAppInfo = { ...baseAppInfo, classFile: 'TestApp.ts' };
128+
await fs.writeFile(
129+
path.join(tmpDir, 'app.json'),
130+
JSON.stringify({
131+
id: testAppInfo.id,
132+
version: testAppInfo.version,
133+
classFile: testAppInfo.classFile,
134+
permissions: testAppInfo.permissions,
135+
}),
136+
'utf8',
137+
);
138+
139+
const sourceFiles: Record<string, ICompilerFile> = {
140+
'TestApp.ts': {
141+
name: 'TestApp.ts',
142+
content: `
143+
export abstract class App {}
144+
145+
export interface IPostMessageSent {
146+
executePostMessageSent(): void;
147+
}
148+
149+
export class TestApp
150+
extends App
151+
implements IPostMessageSent
152+
{
153+
public executePostMessageSent(): void {
154+
// no-op
155+
}
156+
}
157+
`,
158+
version: 1,
159+
},
160+
};
161+
162+
const result = await compiler.transpileSource({
163+
appInfo: testAppInfo,
164+
sourceFiles,
165+
});
166+
167+
expect(result.diagnostics).to.be.empty;
168+
expect(result.implemented).to.deep.equal(['IPostMessageSent']);
169+
});
170+
});

0 commit comments

Comments
 (0)