Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fd38ba4

Browse filesBrowse files
author
Akos Kitta
committed
test: added compiler + build output path test
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent 2d85902 commit fd38ba4
Copy full SHA for fd38ba4

File tree

Expand file treeCollapse file tree

3 files changed

+319
-8
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+319
-8
lines changed

‎arduino-ide-extension/src/node/core-client-provider.ts

Copy file name to clipboardExpand all lines: arduino-ide-extension/src/node/core-client-provider.ts
+1-5Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,7 @@ export class CoreClientProvider {
136136
this.toDisposeOnCloseClient.pushAll([
137137
Disposable.create(() => client.client.close()),
138138
Disposable.create(() => {
139-
this.ready.reject(
140-
new Error(
141-
`Disposed. Creating a new gRPC core client on address ${address}.`
142-
)
143-
);
139+
this.ready.resolve();
144140
this.ready = new Deferred();
145141
}),
146142
]);

‎arduino-ide-extension/src/node/sketches-service-impl.ts

Copy file name to clipboardExpand all lines: arduino-ide-extension/src/node/sketches-service-impl.ts
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
SketchContainer,
1919
SketchesError,
2020
} from '../common/protocol/sketches-service';
21-
import { NotificationServiceServerImpl } from './notification-service-server';
21+
import { NotificationServiceServer } from '../common/protocol';
2222
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
2323
import { CoreClientAware } from './core-client-provider';
2424
import {
@@ -76,8 +76,8 @@ export class SketchesServiceImpl
7676
@inject(ConfigServiceImpl)
7777
private readonly configService: ConfigServiceImpl;
7878

79-
@inject(NotificationServiceServerImpl)
80-
private readonly notificationService: NotificationServiceServerImpl;
79+
@inject(NotificationServiceServer)
80+
private readonly notificationService: NotificationServiceServer;
8181

8282
@inject(EnvVariablesServer)
8383
private readonly envVariableServer: EnvVariablesServer;
+315Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
2+
import {
3+
CommandContribution,
4+
CommandRegistry,
5+
CommandService,
6+
} from '@theia/core/lib/common/command';
7+
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
8+
import { Disposable } from '@theia/core/lib/common/disposable';
9+
import { EnvVariablesServer as TheiaEnvVariablesServer } from '@theia/core/lib/common/env-variables';
10+
import { ILogger } from '@theia/core/lib/common/logger';
11+
import { isWindows } from '@theia/core/lib/common/os';
12+
import { waitForEvent } from '@theia/core/lib/common/promise-util';
13+
import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
14+
import { BackendApplicationConfigProvider } from '@theia/core/lib/node/backend-application-config-provider';
15+
import { FileUri } from '@theia/core/lib/node/file-uri';
16+
import {
17+
Container,
18+
ContainerModule,
19+
injectable,
20+
} from '@theia/core/shared/inversify';
21+
import { expect } from 'chai';
22+
import {
23+
ArduinoDaemon,
24+
AttachedBoardsChangeEvent,
25+
AvailablePorts,
26+
BoardsPackage,
27+
BoardsService,
28+
ConfigService,
29+
ConfigState,
30+
CoreService,
31+
IndexUpdateDidCompleteParams,
32+
IndexUpdateDidFailParams,
33+
IndexUpdateParams,
34+
LibraryPackage,
35+
NotificationServiceClient,
36+
NotificationServiceServer,
37+
OutputMessage,
38+
ProgressMessage,
39+
ResponseService,
40+
Sketch,
41+
SketchesService,
42+
} from '../../common/protocol';
43+
import { ArduinoDaemonImpl } from '../../node/arduino-daemon-impl';
44+
import { BoardDiscovery } from '../../node/board-discovery';
45+
import { BoardsServiceImpl } from '../../node/boards-service-impl';
46+
import { ConfigServiceImpl } from '../../node/config-service-impl';
47+
import { CoreClientProvider } from '../../node/core-client-provider';
48+
import { CoreServiceImpl } from '../../node/core-service-impl';
49+
import { IsTempSketch } from '../../node/is-temp-sketch';
50+
import { MonitorManager } from '../../node/monitor-manager';
51+
import { MonitorService } from '../../node/monitor-service';
52+
import {
53+
MonitorServiceFactory,
54+
MonitorServiceFactoryOptions,
55+
} from '../../node/monitor-service-factory';
56+
import { SketchesServiceImpl } from '../../node/sketches-service-impl';
57+
import { EnvVariablesServer } from '../../node/theia/env-variables/env-variables-server';
58+
59+
const timeout = 50_000;
60+
const avr = 'arduino:avr';
61+
const uno = 'arduino:avr:uno';
62+
63+
describe('core-service-impl', () => {
64+
let container: Container;
65+
let toDispose: Disposable[];
66+
67+
before(() => {
68+
BackendApplicationConfigProvider.set({ configDirName: 'testArduinoIDE' });
69+
});
70+
71+
beforeEach(async function () {
72+
this.timeout(timeout);
73+
toDispose = [];
74+
container = createContainer();
75+
await start(container, toDispose);
76+
});
77+
78+
afterEach(() => {
79+
let disposable = toDispose.pop();
80+
while (disposable) {
81+
try {
82+
disposable?.dispose();
83+
} catch {}
84+
disposable = toDispose.pop();
85+
}
86+
});
87+
88+
describe('compile', () => {
89+
it('should execute a command with the build path', async function () {
90+
this.timeout(timeout);
91+
const coreService = container.get<CoreService>(CoreService);
92+
const sketchesService = container.get<SketchesService>(SketchesService);
93+
const commandService =
94+
container.get<TestCommandRegistry>(TestCommandRegistry);
95+
const sketch = await sketchesService.createNewSketch();
96+
97+
await coreService.compile({
98+
fqbn: uno,
99+
sketch,
100+
optimizeForDebug: false,
101+
sourceOverride: {},
102+
verbose: true,
103+
});
104+
105+
const executedBuildDidCompleteCommands =
106+
commandService.executedCommands.filter(
107+
([command]) =>
108+
command === 'arduino.languageserver.notifyBuildDidComplete'
109+
);
110+
expect(executedBuildDidCompleteCommands.length).to.be.equal(1);
111+
const [, args] = executedBuildDidCompleteCommands[0];
112+
expect(args.length).to.be.equal(1);
113+
const arg = args[0];
114+
expect(typeof arg).to.be.equal('object');
115+
expect('buildOutputUri' in arg).to.be.true;
116+
expect(arg.buildOutputUri).to.be.not.undefined;
117+
118+
const tempBuildPaths = await sketchesService.tempBuildPath(sketch);
119+
if (isWindows) {
120+
expect(tempBuildPaths.length).to.be.greaterThan(1);
121+
} else {
122+
expect(tempBuildPaths.length).to.be.equal(1);
123+
}
124+
125+
const { buildOutputUri } = arg;
126+
const buildOutputPath = FileUri.fsPath(buildOutputUri).toString();
127+
expect(tempBuildPaths.includes(buildOutputPath)).to.be.true;
128+
});
129+
});
130+
});
131+
132+
async function start(
133+
container: Container,
134+
toDispose: Disposable[]
135+
): Promise<void> {
136+
const daemon = container.get<ArduinoDaemonImpl>(ArduinoDaemonImpl);
137+
const configService = container.get<ConfigServiceImpl>(ConfigServiceImpl);
138+
toDispose.push(Disposable.create(() => daemon.stop()));
139+
configService.onStart();
140+
daemon.onStart();
141+
await waitForEvent(daemon.onDaemonStarted, timeout);
142+
const boardService = container.get<BoardsServiceImpl>(BoardsServiceImpl);
143+
const searchResults = await boardService.search({ query: avr });
144+
const platform = searchResults.find(({ id }) => id === avr);
145+
if (!platform) {
146+
throw new Error(`Could not find platform: ${avr}`);
147+
}
148+
await boardService.install({ item: platform });
149+
}
150+
151+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
152+
function createContainer(): Container {
153+
const container = new Container({ defaultScope: 'Singleton' });
154+
const module = new ContainerModule((bind) => {
155+
bind(CoreClientProvider).toSelf().inSingletonScope();
156+
bind(CoreServiceImpl).toSelf().inSingletonScope();
157+
bind(CoreService).toService(CoreServiceImpl);
158+
bind(BoardsServiceImpl).toSelf().inSingletonScope();
159+
bind(BoardsService).toService(BoardsServiceImpl);
160+
bind(TestResponseService).toSelf().inSingletonScope();
161+
bind(ResponseService).toService(TestResponseService);
162+
bind(MonitorManager).toSelf().inSingletonScope();
163+
bind(MonitorServiceFactory).toFactory(
164+
({ container }) =>
165+
(options: MonitorServiceFactoryOptions) => {
166+
const child = container.createChild();
167+
child
168+
.bind<MonitorServiceFactoryOptions>(MonitorServiceFactoryOptions)
169+
.toConstantValue({
170+
...options,
171+
});
172+
child.bind(MonitorService).toSelf();
173+
return child.get<MonitorService>(MonitorService);
174+
}
175+
);
176+
bind(EnvVariablesServer).toSelf().inSingletonScope();
177+
bind(TheiaEnvVariablesServer).toService(EnvVariablesServer);
178+
bind(ArduinoDaemonImpl).toSelf().inSingletonScope();
179+
bind(ArduinoDaemon).toService(ArduinoDaemonImpl);
180+
bind(MockLogger).toSelf().inSingletonScope();
181+
bind(ILogger).toService(MockLogger);
182+
bind(TestNotificationServiceServer).toSelf().inSingletonScope();
183+
bind(NotificationServiceServer).toService(TestNotificationServiceServer);
184+
bind(ConfigServiceImpl).toSelf().inSingletonScope();
185+
bind(ConfigService).toService(ConfigServiceImpl);
186+
bind(TestCommandRegistry).toSelf().inSingletonScope();
187+
bind(CommandRegistry).toService(TestCommandRegistry);
188+
bind(CommandService).toService(CommandRegistry);
189+
bindContributionProvider(bind, CommandContribution);
190+
bind(TestBoardDiscovery).toSelf().inSingletonScope();
191+
bind(BoardDiscovery).toService(TestBoardDiscovery);
192+
bind(IsTempSketch).toSelf().inSingletonScope();
193+
bind(SketchesServiceImpl).toSelf().inSingletonScope();
194+
bind(SketchesService).toService(SketchesServiceImpl);
195+
});
196+
container.load(module);
197+
return container;
198+
}
199+
200+
@injectable()
201+
class TestResponseService implements ResponseService {
202+
readonly outputMessages: OutputMessage[] = [];
203+
readonly progressMessages: ProgressMessage[] = [];
204+
205+
appendToOutput(message: OutputMessage): void {
206+
this.outputMessages.push(message);
207+
}
208+
reportProgress(message: ProgressMessage): void {
209+
this.progressMessages.push(message);
210+
}
211+
}
212+
213+
@injectable()
214+
class TestNotificationServiceServer implements NotificationServiceServer {
215+
readonly events: string[] = [];
216+
217+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
218+
disposeClient(client: NotificationServiceClient): void {
219+
this.events.push('disposeClient:');
220+
}
221+
notifyDidReinitialize(): void {
222+
this.events.push('notifyDidReinitialize:');
223+
}
224+
notifyIndexUpdateWillStart(params: IndexUpdateParams): void {
225+
this.events.push(`notifyIndexUpdateWillStart:${JSON.stringify(params)}`);
226+
}
227+
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void {
228+
this.events.push(
229+
`notifyIndexUpdateDidProgress:${JSON.stringify(progressMessage)}`
230+
);
231+
}
232+
notifyIndexUpdateDidComplete(params: IndexUpdateDidCompleteParams): void {
233+
this.events.push(`notifyIndexUpdateDidComplete:${JSON.stringify(params)}`);
234+
}
235+
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void {
236+
this.events.push(`notifyIndexUpdateDidFail:${JSON.stringify(params)}`);
237+
}
238+
notifyDaemonDidStart(port: string): void {
239+
this.events.push(`notifyDaemonDidStart:${port}`);
240+
}
241+
notifyDaemonDidStop(): void {
242+
this.events.push('notifyDaemonDidStop:');
243+
}
244+
notifyConfigDidChange(event: ConfigState): void {
245+
this.events.push(`notifyConfigDidChange:${JSON.stringify(event)}`);
246+
}
247+
notifyPlatformDidInstall(event: { item: BoardsPackage }): void {
248+
this.events.push(`notifyPlatformDidInstall:${JSON.stringify(event)}`);
249+
}
250+
notifyPlatformDidUninstall(event: { item: BoardsPackage }): void {
251+
this.events.push(`notifyPlatformDidUninstall:${JSON.stringify(event)}`);
252+
}
253+
notifyLibraryDidInstall(event: {
254+
item: LibraryPackage | 'zip-install';
255+
}): void {
256+
this.events.push(`notifyLibraryDidInstall:${JSON.stringify(event)}`);
257+
}
258+
notifyLibraryDidUninstall(event: { item: LibraryPackage }): void {
259+
this.events.push(`notifyLibraryDidUninstall:${JSON.stringify(event)}`);
260+
}
261+
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void {
262+
this.events.push(`notifyAttachedBoardsDidChange:${JSON.stringify(event)}`);
263+
}
264+
notifyRecentSketchesDidChange(event: { sketches: Sketch[] }): void {
265+
this.events.push(`notifyRecentSketchesDidChange:${JSON.stringify(event)}`);
266+
}
267+
dispose(): void {
268+
this.events.push('dispose');
269+
}
270+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
271+
setClient(client: NotificationServiceClient | undefined): void {
272+
this.events.push('setClient:');
273+
}
274+
}
275+
276+
@injectable()
277+
class TestBoardDiscovery extends BoardDiscovery {
278+
mutableAvailablePorts: AvailablePorts = {};
279+
280+
override async start(): Promise<void> {
281+
// NOOP
282+
}
283+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
284+
override async stop(restart?: boolean): Promise<void> {
285+
// NOOP
286+
}
287+
override get availablePorts(): AvailablePorts {
288+
return this.mutableAvailablePorts;
289+
}
290+
}
291+
292+
@injectable()
293+
class TestCommandRegistry extends CommandRegistry {
294+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
295+
readonly executedCommands: [string, any[]][] = [];
296+
297+
override async executeCommand<T>(
298+
commandId: string,
299+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
300+
...args: any[]
301+
): Promise<T | undefined> {
302+
const { token } = new CancellationTokenSource();
303+
this.onWillExecuteCommandEmitter.fire({
304+
commandId,
305+
args,
306+
token,
307+
waitUntil: () => {
308+
// NOOP
309+
},
310+
});
311+
this.executedCommands.push([commandId, args]);
312+
this.onDidExecuteCommandEmitter.fire({ commandId, args });
313+
return undefined;
314+
}
315+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.