import { Disposable, DisposableCollection, } from '@theia/core/lib/common/disposable'; import { Container } from '@theia/core/shared/inversify'; import { expect } from 'chai'; import { promises as fs } from 'node:fs'; import path from 'node:path'; import temp from 'temp'; import { BoardSearch, BoardsPackage, BoardsService, Installable, } from '../../common/protocol'; import { createBaseContainer, startDaemon } from './node-test-bindings'; describe('boards-service-impl', () => { let boardService: BoardsService; let toDispose: DisposableCollection; before(async function () { this.timeout(20_000); const tracked = temp.track(); toDispose = new DisposableCollection( Disposable.create(() => tracked.cleanupSync()) ); const testDirPath = tracked.mkdirSync(); const container = await createContainer(testDirPath); await start(container, toDispose); boardService = container.get(BoardsService); }); after(() => toDispose.dispose()); describe('search', () => { it('should run search', async function () { const result = await boardService.search({}); expect(result).is.not.empty; }); it('should order the available platform release versions in descending order', async function () { const result = await boardService.search({}); result.forEach((platform) => platform.availableVersions.forEach( (currentVersion, index, versions) => { if (index < versions.length - 2) { const nextArrayElement = versions[index + 1]; const actual = Installable.Version.COMPARATOR( currentVersion, nextArrayElement ); expect(actual).to.be.greaterThan( 0, `Expected '${currentVersion}' to be gt '${nextArrayElement}'. All versions: ${JSON.stringify( versions )}` ); } } ) ); }); it("should boost a result when 'types' includes 'arduino', and lower the score if deprecated", async () => { const result = await boardService.search({}); const arduinoIndexes: number[] = []; const otherIndexes: number[] = []; const deprecatedArduinoIndexes: number[] = []; const deprecatedOtherIndexes: number[] = []; const arduino: BoardSearch.Type = 'Arduino'; result.forEach((platform, index) => { if (platform.types.includes(arduino)) { if (platform.deprecated) { deprecatedArduinoIndexes.push(index); } else { arduinoIndexes.push(index); } } else { if (platform.deprecated) { deprecatedOtherIndexes.push(index); } else { otherIndexes.push(index); } } }); arduinoIndexes.forEach( (index) => expect(otherIndexes.every((otherIndex) => otherIndex > index)).to.be .true ); otherIndexes.forEach( (index) => expect( deprecatedArduinoIndexes.every( (deprecatedArduinoIndex) => deprecatedArduinoIndex > index ) ).to.be.true ); deprecatedArduinoIndexes.forEach( (index) => expect( deprecatedOtherIndexes.every( (deprecatedOtherIndex) => deprecatedOtherIndex > index ) ).to.be.true ); }); it("should boost 'arduino' and deprecated to the end of the results", async function () { const query = 'OS'; const result = await boardService.search({ query }); expect(result.length).greaterThan(1); const lastIndex = result.length - 1; const last = result[lastIndex]; expect(last.id).to.be.equal('Microsoft:win10'); expect(last.deprecated).to.be.true; const arduinoMbedCoreIndex = result.findIndex( (platform) => platform.id === 'arduino:mbed' ); expect(arduinoMbedCoreIndex).to.be.greaterThanOrEqual(0); expect(arduinoMbedCoreIndex).to.be.lessThan(lastIndex); const first = result[0]; expect(typeof first.deprecated).to.be.equal('boolean'); expect(first.deprecated).to.be.false; }); }); it('should have the installed version set', async function () { const timeout = 5 * 60 * 1_000; // five minutes to install/uninstall the core this.timeout(timeout); // ensure installed let result = await boardService.search({ query: 'arduino:avr' }); let avr = result.find( (boardsPackage) => boardsPackage.id === 'arduino:avr' ); expect(avr).to.be.not.undefined; await boardService.install({ item: avr, skipPostInstall: true, }); // when installed the version is set result = await boardService.search({ query: 'arduino:avr' }); avr = result.find((boardsPackage) => boardsPackage.id === 'arduino:avr'); expect(avr).to.be.not.undefined; expect(avr?.installedVersion).to.be.not.undefined; // uninstall the core await boardService.uninstall({ item: avr }); result = await boardService.search({ query: 'arduino:avr' }); avr = result.find((boardsPackage) => boardsPackage.id === 'arduino:avr'); expect(avr).to.be.not.undefined; expect(avr?.installedVersion).to.be.undefined; }); }); async function createContainer(testDirPath: string): Promise { const data = path.join(testDirPath, 'data'); const user = path.join(testDirPath, 'user'); await Promise.all([ fs.mkdir(data, { recursive: true }), fs.mkdir(user, { recursive: true }), ]); return createBaseContainer({ cliConfig: { directories: { data, user } } }); } async function start( container: Container, toDispose: DisposableCollection ): Promise { return startDaemon(container, toDispose); }