Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced coverage displaying #36

Merged
merged 14 commits into from
Apr 1, 2017
8 changes: 7 additions & 1 deletion example/test-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@ module.exports.test = function test(testNumber) {
if(testNumber === 2) {
return false;
}
return "null";

if(testNumber === 3) return "notNull";
if(testNumber === 4) return "reallyNull";

testNumber = testNumber === 5 ? "woop":"wap";

return testNumber;
}
18 changes: 14 additions & 4 deletions example/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@ const testFunc = require('./test-coverage').test;

describe('test func', function() {
it('should show coverage on line 8', function() {
var num = testFunc(3);
assert(num==="null");
var num = testFunc(1);
assert(num===true);
});

it('should show coverage on line 6', function() {
var num = testFunc(2);
assert(num===false);
var num = testFunc(4);
assert(num==="reallyNull");
});

it('should show coverage on line 9', function() {
var num = testFunc(6);
assert(num==="wap");
});

it('should show coverage on line 9 x2', function() {
var num = testFunc(5);
assert(num==="woop");
});
});
5 changes: 4 additions & 1 deletion images/gutter-icon-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion images/gutter-icon-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions images/no-gutter-icon-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions images/no-gutter-icon-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions images/partial-gutter-icon-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions images/partial-gutter-icon-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 44 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,55 @@
"default": "rgba(36, 56, 27, 0.75)",
"description": "dark themed highlight for code coverage"
},
"coverage-gutters.gutterIconPathDark": {
"coverage-gutters.partialHighlightLight": {
"type": "string",
"default": "./images/gutter-icon-dark.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for dark themes"
"default": "rgba(220, 213, 143, 0.75)",
"description": "light theme partial highlight for code coverage"
},
"coverage-gutters.partialHighlightDark": {
"type": "string",
"default": "rgba(57, 50, 27, 0.75)",
"description": "dark theme partial highlight for code coverage"
},
"coverage-gutters.noHighlightLight": {
"type": "string",
"default": "rgba(220, 213, 143, 0.75)",
"description": "light theme partial highlight for code coverage"
},
"coverage-gutters.noHighlightDark": {
"type": "string",
"default": "rgba(57, 27, 27, 0.75)",
"description": "dark theme partial highlight for code coverage"
},
"coverage-gutters.gutterIconPathLight": {
"type": "string",
"default": "./images/gutter-icon-light.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for light themes"
"description": "path to an icon (svg, png, etc) for displaying in the gutter for full coverage"
},
"coverage-gutters.gutterIconPathDark": {
"type": "string",
"default": "./images/gutter-icon-dark.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for full coverage"
},
"coverage-gutters.partialGutterIconPathLight": {
"type": "string",
"default": "./images/partial-gutter-icon-light.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for partial coverage"
},
"coverage-gutters.partialGutterIconPathDark": {
"type": "string",
"default": "./images/partial-gutter-icon-dark.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for partial coverage"
},
"coverage-gutters.noGutterIconPathLight": {
"type": "string",
"default": "./images/no-gutter-icon-light.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for no coverage"
},
"coverage-gutters.noGutterIconPathDark": {
"type": "string",
"default": "./images/no-gutter-icon-dark.svg",
"description": "path to an icon (svg, png, etc) for displaying in the gutter for no coverage"
},
"coverage-gutters.customizable.menus-editor-context-displayCoverage-enabled": {
"type": "boolean",
Expand Down
67 changes: 55 additions & 12 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import {ExtensionContext, TextEditorDecorationType} from "vscode";
import {ExtensionContext, OverviewRulerLane, TextEditorDecorationType} from "vscode";
import {InterfaceVscode} from "./wrappers/vscode";

export type ConfigStore = {
lcovFileName: string;
coverageDecorationType: TextEditorDecorationType;
gutterDecorationType: TextEditorDecorationType;
fullCoverageDecorationType: TextEditorDecorationType;
partialCoverageDecorationType: TextEditorDecorationType;
noCoverageDecorationType: TextEditorDecorationType;
altSfCompare: boolean;
};

export class Config {
export interface InterfaceConfig {
get(): ConfigStore;
setup(): ConfigStore;
}

export class Config implements InterfaceConfig {
private vscode: InterfaceVscode;
private context: ExtensionContext;

private lcovFileName: string;
private coverageDecorationType: TextEditorDecorationType;
private gutterDecorationType: TextEditorDecorationType;
private fullCoverageDecorationType: TextEditorDecorationType;
private partialCoverageDecorationType: TextEditorDecorationType;
private noCoverageDecorationType: TextEditorDecorationType;
private altSfCompare: boolean;

constructor(vscode: InterfaceVscode, context: ExtensionContext) {
Expand All @@ -25,9 +32,10 @@ export class Config {
public get(): ConfigStore {
return {
altSfCompare: this.altSfCompare,
coverageDecorationType: this.coverageDecorationType,
gutterDecorationType: this.gutterDecorationType,
fullCoverageDecorationType: this.fullCoverageDecorationType,
lcovFileName: this.lcovFileName,
noCoverageDecorationType: this.noCoverageDecorationType,
partialCoverageDecorationType: this.partialCoverageDecorationType,
};
}

Expand All @@ -47,28 +55,63 @@ export class Config {
this.lcovFileName = rootConfig.get("lcovname") as string;
this.altSfCompare = rootConfig.get("altSfCompare") as boolean;

// Themes and icons
const coverageLightBackgroundColour = rootConfig.get("highlightlight") as string;
const coverageDarkBackgroundColour = rootConfig.get("highlightdark") as string;
const partialCoverageLightBackgroundColour = rootConfig.get("partialHighlightLight") as string;
const partialCoverageDarkBackgroundColour = rootConfig.get("partialHighlightDark") as string;
const noCoverageLightBackgroundColour = rootConfig.get("noHighlightLight") as string;
const noCoverageDarkBackgroundColour = rootConfig.get("noHighlightDark") as string;
const gutterIconPathDark = rootConfig.get("gutterIconPathDark") as string;
const gutterIconPathLight = rootConfig.get("gutterIconPathLight") as string;
const partialGutterIconPathDark = rootConfig.get("partialGutterIconPathDark") as string;
const partialGutterIconPathLight = rootConfig.get("partialGutterIconPathLight") as string;
const noGutterIconPathDark = rootConfig.get("noGutterIconPathDark") as string;
const noGutterIconPathLight = rootConfig.get("noGutterIconPathLight") as string;

this.coverageDecorationType = this.vscode.createTextEditorDecorationType({
this.fullCoverageDecorationType = this.vscode.createTextEditorDecorationType({
dark: {
backgroundColor: coverageDarkBackgroundColour,
gutterIconPath: this.context.asAbsolutePath(gutterIconPathDark),
overviewRulerColor: coverageDarkBackgroundColour,
},
isWholeLine: true,
light: {
backgroundColor: coverageLightBackgroundColour,
gutterIconPath: this.context.asAbsolutePath(gutterIconPathLight),
overviewRulerColor: coverageLightBackgroundColour,
},
overviewRulerLane: OverviewRulerLane.Full,
});

this.gutterDecorationType = this.vscode.createTextEditorDecorationType({
this.partialCoverageDecorationType = this.vscode.createTextEditorDecorationType({
dark: {
gutterIconPath: this.context.asAbsolutePath(gutterIconPathDark),
backgroundColor: partialCoverageDarkBackgroundColour,
gutterIconPath: this.context.asAbsolutePath(partialGutterIconPathDark),
overviewRulerColor: partialCoverageDarkBackgroundColour,
},
isWholeLine: true,
light: {
gutterIconPath: this.context.asAbsolutePath(gutterIconPathLight),
backgroundColor: partialCoverageLightBackgroundColour,
gutterIconPath: this.context.asAbsolutePath(partialGutterIconPathLight),
overviewRulerColor: partialCoverageLightBackgroundColour,
},
overviewRulerLane: OverviewRulerLane.Full,
});

this.noCoverageDecorationType = this.vscode.createTextEditorDecorationType({
dark: {
backgroundColor: noCoverageDarkBackgroundColour,
gutterIconPath: this.context.asAbsolutePath(noGutterIconPathDark),
overviewRulerColor: noCoverageDarkBackgroundColour,
},
isWholeLine: true,
light: {
backgroundColor: noCoverageLightBackgroundColour,
gutterIconPath: this.context.asAbsolutePath(noGutterIconPathLight),
overviewRulerColor: noCoverageLightBackgroundColour,
},
overviewRulerLane: OverviewRulerLane.Full,
});

return this.get();
Expand Down
26 changes: 21 additions & 5 deletions src/gutters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class Gutters {

public async displayCoverageForActiveFile() {
const textEditor = window.activeTextEditor;
this.textEditors.push(textEditor);
this.addTextEditorToCache(textEditor);
try {
const lcovPath = await this.lcov.find();
await this.loadAndRenderCoverage(textEditor, lcovPath);
Expand All @@ -52,7 +52,12 @@ export class Gutters {
this.fileWatcher = vscodeImpl.watchFile(lcovPath);
this.fileWatcher.onDidChange(async (event) => {
this.textEditors.forEach(async (editor) => {
this.loadAndRenderCoverage(editor, lcovPath);
if (!editor.document) {
// editor can no longer display coverage, remove from cache
this.removeTextEditorFromCache(editor);
} else {
this.loadAndRenderCoverage(editor, lcovPath);
}
});
});
} catch (e) {
Expand All @@ -62,7 +67,7 @@ export class Gutters {

public removeCoverageForActiveFile() {
const activeEditor = window.activeTextEditor;
this.textEditors = this.textEditors.filter((editor) => editor !== activeEditor);
this.removeTextEditorFromCache(activeEditor);
this.removeDecorationsForTextEditor(activeEditor);
}

Expand All @@ -75,10 +80,21 @@ export class Gutters {
return this.textEditors;
}

private addTextEditorToCache(editor: TextEditor) {
// keep textEditors a unique array by removing existing editors
this.textEditors = this.textEditors.filter((cache) => cache !== editor);
this.textEditors.push(editor);
}

private removeTextEditorFromCache(editor: TextEditor) {
this.textEditors = this.textEditors.filter((cache) => cache !== editor);
}

private removeDecorationsForTextEditor(editor: TextEditor) {
if (!editor) { return; }
editor.setDecorations(this.configStore.coverageDecorationType, []);
editor.setDecorations(this.configStore.gutterDecorationType, []);
editor.setDecorations(this.configStore.fullCoverageDecorationType, []);
editor.setDecorations(this.configStore.partialCoverageDecorationType, []);
editor.setDecorations(this.configStore.noCoverageDecorationType, []);
}

private async loadAndRenderCoverage(textEditor: TextEditor, lcovPath: string): Promise<void> {
Expand Down
Loading