// ***************************************************************************** // Copyright (C) 2017 TypeFox and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom'; const disableJSDOM = enableJSDOM(); import * as chai from 'chai'; import URI from '@theia/core/lib/common/uri'; import { Container } from '@theia/core/shared/inversify'; import { ProblemManager } from './problem-manager'; import { Event } from '@theia/core/lib/common/event'; import { ILogger } from '@theia/core/lib/common/logger'; import { DiagnosticSeverity, Range } from '@theia/core/shared/vscode-languageserver-protocol'; import { MockLogger } from '@theia/core/lib/common/test/mock-logger'; import { FileService } from '@theia/filesystem/lib/browser/file-service'; import { LocalStorageService, StorageService } from '@theia/core/lib/browser/storage-service'; disableJSDOM(); const expect = chai.expect; let manager: ProblemManager; let container: Container; /** * The default range for test purposes. */ const range: Range = { start: { line: 0, character: 10 }, end: { line: 0, character: 10 } }; describe('problem-manager', () => { beforeEach(() => { container = new Container(); container.bind(ILogger).to(MockLogger); container.bind(StorageService).to(LocalStorageService).inSingletonScope(); container.bind(LocalStorageService).toSelf().inSingletonScope(); container.bind(FileService).toConstantValue({ onDidFilesChange: Event.None }); container.bind(ProblemManager).toSelf(); manager = container.get(ProblemManager); }); describe('#setMarkers', () => { it('should successfully set new markers', () => { expect(Array.from(manager.getUris()).length).to.equal(0); manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range }]); expect(Array.from(manager.getUris()).length).to.equal(1); }); it('should replace markers', () => { const uri = new URI('a'); let events = 0; manager.onDidChangeMarkers(() => events++); expect(events).equal(0); const initial = manager.setMarkers(uri, 'a', [{ message: 'a', range }]); expect(initial.length).equal(0); expect(events).equal(1); const updated = manager.setMarkers(uri, 'a', [{ message: 'a', range }]); expect(updated.length).equal(1); expect(events).equal(2); expect(manager.findMarkers({ uri }).length).equal(1); }); }); describe('#cleanAllMarkers', () => { it('should successfully clean all markers', () => { // Create mock markers. manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range }]); manager.setMarkers(new URI('b'), 'b', [{ message: 'a', range }]); manager.setMarkers(new URI('c'), 'c', [{ message: 'a', range }]); expect(Array.from(manager.getUris()).length).to.equal(3); // Clean the markers. manager.cleanAllMarkers(); expect(Array.from(manager.getUris()).length).to.equal(0); }); }); describe('#findMarkers', () => { it('should find markers by `owner`', () => { const owner: string = 'foo'; manager.setMarkers(new URI('a'), owner, [{ message: 'a', range }]); manager.setMarkers(new URI('b'), owner, [{ message: 'a', range }]); expect(manager.findMarkers({ owner }).length).equal(2); expect(manager.findMarkers({ owner: 'unknown' }).length).equal(0); }); it('should find markers by `owner` and `uri`', () => { const owner: string = 'foo'; const uri = new URI('bar'); // Create a marker to match the filter. manager.setMarkers(uri, owner, [{ message: 'a', range }]); // Create 2 markers that do not match the filter. manager.setMarkers(new URI('invalid'), 'invalid-owner', [{ message: 'a', range }]); manager.setMarkers(new URI('invalid'), 'invalid-owner', [{ message: 'a', range }]); // Expect to find the markers which satisfy the filter only. expect(manager.findMarkers({ owner, uri }).length).equal(1); }); describe('dataFilter', () => { it('should find markers that satisfy filter for `severity`', () => { manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range, severity: DiagnosticSeverity.Error }]); expect(manager.findMarkers({ dataFilter: d => d.severity === DiagnosticSeverity.Error }).length).equal(1); expect(manager.findMarkers({ dataFilter: d => d.severity !== DiagnosticSeverity.Error }).length).equal(0); }); it('should find markers that satisfy filter for `code`', () => { const code = 100; manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range, code }]); expect(manager.findMarkers({ dataFilter: d => d.code === code }).length).equal(1); expect(manager.findMarkers({ dataFilter: d => d.code !== code }).length).equal(0); }); it('should find markers that satisfy filter for `message`', () => { const message = 'foo'; manager.setMarkers(new URI('a'), 'a', [{ message, range }]); expect(manager.findMarkers({ dataFilter: d => d.message === message }).length).equal(1); expect(manager.findMarkers({ dataFilter: d => d.message !== message }).length).equal(0); }); it('should find markers that satisfy filter for `source`', () => { const source = 'typescript'; manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range, source }]); expect(manager.findMarkers({ dataFilter: d => d.source === source }).length).equal(1); expect(manager.findMarkers({ dataFilter: d => d.source !== source }).length).equal(0); }); it('should find markers that satisfy filter for `range`', () => { manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range }]); // The default `range` has a start line number of 0. expect(manager.findMarkers({ dataFilter: d => d.range.start.line === 0 }).length).equal(1); expect(manager.findMarkers({ dataFilter: d => d.range.start.line > 0 }).length).equal(0); }); }); }); describe('#getUris', () => { it('should return 0 uris when no markers are present', () => { expect(Array.from(manager.getUris()).length).to.equal(0); }); it('should return the list of uris', () => { manager.setMarkers(new URI('a'), 'a', [{ message: 'a', range, severity: DiagnosticSeverity.Error }]); manager.setMarkers(new URI('b'), 'b', [{ message: 'a', range, severity: DiagnosticSeverity.Error }]); expect(Array.from(manager.getUris()).length).to.equal(2); }); }); describe('#getProblemStat', () => { it('should return 0 stats when no markers are present', () => { const { errors, warnings, infos } = manager.getProblemStat(); expect(errors).to.equal(0); expect(warnings).to.equal(0); expect(infos).to.equal(0); }); it('should return the proper problem stats', () => { // Create 3 error markers. manager.setMarkers(new URI('error-1'), 'error-1', [{ message: 'a', range, severity: DiagnosticSeverity.Error }]); manager.setMarkers(new URI('error-2'), 'error-2', [{ message: 'a', range, severity: DiagnosticSeverity.Error }]); manager.setMarkers(new URI('error-3'), 'error-3', [{ message: 'a', range, severity: DiagnosticSeverity.Error }]); // Create 2 warning markers. manager.setMarkers(new URI('warning-1'), 'warning-1', [{ message: 'a', range, severity: DiagnosticSeverity.Warning }]); manager.setMarkers(new URI('warning-2'), 'warning-2', [{ message: 'a', range, severity: DiagnosticSeverity.Warning }]); // Create 1 info marker. manager.setMarkers(new URI('info-1'), 'info-1', [{ message: 'a', range, severity: DiagnosticSeverity.Information }]); // Collect the total problem stats for the application. const { errors, warnings, infos } = manager.getProblemStat(); expect(errors).to.equal(3); expect(warnings).to.equal(2); expect(infos).to.equal(1); }); }); });