-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add true gutters and increase testability (#28)
* add changelog and update readme * increment version * update parse lcov d.ts * update md's * wrap external modules * refactor for testability * cleanup tests * allow linux and windows to pass tests * flesh out gutters tests * cleanup types on config * remove dispose test from unit * setup test files * remove dones * cover lcov with tests * fix tests to work with CI * add gutter icons and customization * update feature gifs and readme
- Loading branch information
Showing
22 changed files
with
525 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
### 0.2.0 | ||
- true gutter indicators | ||
- contribution doc | ||
- refactor gutters to be more testable | ||
|
||
### 0.1.3 | ||
- colour updates | ||
- context menu additions | ||
- icon resizing | ||
|
||
### 0.1.2 | ||
- minor doc tweaks | ||
- cleanup default colours and use rgba | ||
|
||
### 0.1.1 | ||
- give the icon a background | ||
|
||
### 0.1.0 | ||
- display and remove lcov line coverage using commands | ||
- modify highlight colour using workspace settings | ||
- modify lcov name using workspace settings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
'use strict'; | ||
|
||
import {TextEditorDecorationType, ExtensionContext} from "vscode"; | ||
|
||
export interface configStore { | ||
lcovFileName: string, | ||
coverageDecorationType: TextEditorDecorationType, | ||
gutterDecorationType: TextEditorDecorationType | ||
} | ||
|
||
export class Config { | ||
private createTextEditorDecorationType; | ||
private executeCommand; | ||
private workspaceConfig; | ||
private context: ExtensionContext; | ||
|
||
private lcovFileName: string; | ||
private coverageDecorationType: TextEditorDecorationType; | ||
private gutterDecorationType: TextEditorDecorationType; | ||
|
||
constructor( | ||
createTextEditorDecorationType, | ||
executeCommand, | ||
workspaceConfig, | ||
context: ExtensionContext | ||
) { | ||
this.createTextEditorDecorationType = createTextEditorDecorationType; | ||
this.executeCommand = executeCommand; | ||
this.workspaceConfig = workspaceConfig; | ||
this.context = context; | ||
} | ||
|
||
public get(): configStore { | ||
return { | ||
lcovFileName: this.lcovFileName, | ||
coverageDecorationType: this.coverageDecorationType, | ||
gutterDecorationType: this.gutterDecorationType | ||
} | ||
} | ||
|
||
public setup(): configStore { | ||
//Customizable UI configurations | ||
const rootCustomConfig = this.workspaceConfig("coverage-gutters.customizable"); | ||
const configsCustom = Object.keys(rootCustomConfig); | ||
for(let element of configsCustom) { | ||
this.executeCommand( | ||
"setContext", | ||
"config.coverage-gutters.customizable." + element, | ||
rootCustomConfig.get(element)); | ||
} | ||
|
||
//Basic configurations | ||
const rootConfig = this.workspaceConfig("coverage-gutters"); | ||
this.lcovFileName = rootConfig.get("lcovname") as string; | ||
const coverageLightBackgroundColour = rootConfig.get("highlightlight") as string; | ||
const coverageDarkBackgroundColour = rootConfig.get("highlightdark") as string; | ||
const gutterIconPathDark = rootConfig.get("gutterIconPathDark") as string; | ||
const gutterIconPathLight = rootConfig.get("gutterIconPathLight") as string; | ||
|
||
this.coverageDecorationType = this.createTextEditorDecorationType({ | ||
isWholeLine: true, | ||
light: { | ||
backgroundColor: coverageLightBackgroundColour | ||
}, | ||
dark: { | ||
backgroundColor: coverageDarkBackgroundColour | ||
} | ||
}); | ||
|
||
this.gutterDecorationType = this.createTextEditorDecorationType({ | ||
light: { | ||
gutterIconPath: this.context.asAbsolutePath(gutterIconPathLight) | ||
}, | ||
dark: { | ||
gutterIconPath: this.context.asAbsolutePath(gutterIconPathDark) | ||
} | ||
}); | ||
|
||
return this.get(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,50 @@ | ||
'use strict'; | ||
|
||
import * as vscode from "vscode"; | ||
import * as parse from "lcov-parse"; | ||
import {readFile} from "fs"; | ||
import { | ||
createTextEditorDecorationType, | ||
executeCommand, | ||
getConfiguration, | ||
setDecorations, | ||
findFiles | ||
} from "./wrappers/vscode"; | ||
import {readFile} from "./wrappers/fs"; | ||
import {lcovParse} from "./wrappers/lcov-parse"; | ||
import {Range, window, ExtensionContext} from "vscode"; | ||
|
||
import {Lcov, lcov} from "./lcov"; | ||
import {Indicators, indicators} from "./indicators"; | ||
import {Config, configStore} from "./config"; | ||
|
||
export class Gutters { | ||
private lcovFileName: string; | ||
private coverageDecorationType: vscode.TextEditorDecorationType; | ||
private coverageLightBackgroundColour: string; | ||
private coverageDarkBackgroundColour: string; | ||
|
||
constructor() { | ||
const config = vscode.workspace.getConfiguration("coverage-gutters"); | ||
|
||
//Customizable UI configurations | ||
const configsCustom = Object.keys(config.get("customizable")); | ||
for(let element of configsCustom) { | ||
vscode.commands.executeCommand( | ||
"setContext", | ||
"config.coverage-gutters.customizable." + element, | ||
vscode.workspace.getConfiguration("coverage-gutters.customizable").get(element)); | ||
} | ||
|
||
//Basic configurations | ||
this.lcovFileName = config.get("lcovname") as string; | ||
this.coverageLightBackgroundColour = config.get("highlightlight") as string; | ||
this.coverageDarkBackgroundColour = config.get("highlightdark") as string; | ||
|
||
this.coverageDecorationType = vscode.window.createTextEditorDecorationType({ | ||
isWholeLine: true, | ||
light: { | ||
backgroundColor: this.coverageLightBackgroundColour | ||
}, | ||
dark: { | ||
backgroundColor: this.coverageDarkBackgroundColour | ||
} | ||
}); | ||
private configStore: configStore; | ||
private lcov: lcov; | ||
private indicators: indicators; | ||
|
||
constructor(context: ExtensionContext) { | ||
this.configStore = new Config( | ||
createTextEditorDecorationType, | ||
executeCommand, | ||
getConfiguration, | ||
context | ||
).setup(); | ||
this.lcov = new Lcov(this.configStore, findFiles, readFile); | ||
this.indicators = new Indicators(this.configStore, lcovParse, setDecorations); | ||
} | ||
|
||
public async displayCoverageForActiveFile() { | ||
try { | ||
const activeFile = vscode.window.activeTextEditor.document.fileName; | ||
const lcovPath = await this.findLcov(); | ||
const lcovFile = await this.loadLcov(lcovPath); | ||
const coveredLines = await this.extractCoverage(lcovFile, activeFile); | ||
await this.renderIndicators(coveredLines); | ||
const activeFile = window.activeTextEditor.document.fileName; | ||
const lcovPath = await this.lcov.find(); | ||
const lcovFile = await this.lcov.load(lcovPath); | ||
const coveredLines = await this.indicators.extract(lcovFile, activeFile); | ||
await this.indicators.render(coveredLines); | ||
} catch(e) { | ||
console.log(e); | ||
} | ||
} | ||
|
||
public dispose() { | ||
vscode.window.activeTextEditor.setDecorations(this.coverageDecorationType, []); | ||
} | ||
|
||
private findLcov(): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
vscode.workspace.findFiles("**/" + this.lcovFileName, "**/node_modules/**", 1) | ||
.then((uriLcov) => { | ||
if(!uriLcov.length) return reject(new Error("Could not find a lcov file!")); | ||
return resolve(uriLcov[0].fsPath); | ||
}); | ||
}); | ||
} | ||
|
||
private renderIndicators(lines: Detail[]): Promise<Function> { | ||
return new Promise((resolve, reject) => { | ||
let renderLines = []; | ||
lines.forEach((detail) => { | ||
if(detail.hit > 0) { | ||
renderLines.push(new vscode.Range(detail.line - 1, 0, detail.line - 1, 0)); | ||
} | ||
}); | ||
vscode.window.activeTextEditor.setDecorations(this.coverageDecorationType, renderLines); | ||
return resolve(); | ||
}); | ||
} | ||
|
||
private loadLcov(lcovPath: string): Promise<string> { | ||
return new Promise<string>((resolve, reject) => { | ||
readFile(lcovPath, (err, data) => { | ||
if(err) return reject(err); | ||
return resolve(data.toString()); | ||
}); | ||
}); | ||
} | ||
|
||
private extractCoverage(lcovFile: string, file: string): Promise<Array<Detail>> { | ||
return new Promise<Array<Detail>>((resolve, reject) => { | ||
parse(lcovFile, (err, data) => { | ||
if(err) return reject(err); | ||
let section = data.find((section) => { | ||
//prevent hazardous casing mishaps | ||
return section.file.toLocaleLowerCase() === file.toLocaleLowerCase(); | ||
}); | ||
|
||
if(!section) return reject(new Error("No coverage for file!")); | ||
return resolve(section.lines.details); | ||
}); | ||
}); | ||
setDecorations(this.configStore.coverageDecorationType, []); | ||
setDecorations(this.configStore.gutterDecorationType, []); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"use strict"; | ||
|
||
import {configStore} from "./config"; | ||
import {Range} from "vscode"; | ||
import {Detail} from "lcov-parse"; | ||
|
||
export interface indicators { | ||
render(lines: Array<Detail>): Promise<string>, | ||
extract(lcovFile: string, file: string): Promise<Array<Detail>> | ||
} | ||
|
||
export class Indicators implements indicators{ | ||
private parseLcov; | ||
private configStore: configStore; | ||
private setDecorations; | ||
|
||
constructor(configStore, parseLcov, setDecorations) { | ||
this.configStore = configStore; | ||
this.parseLcov = parseLcov; | ||
this.setDecorations = setDecorations; | ||
} | ||
|
||
public render(lines: Detail[]): Promise<string> { | ||
return new Promise<string>((resolve, reject) => { | ||
let renderLines = []; | ||
lines.forEach((detail) => { | ||
if(detail.hit > 0) { | ||
renderLines.push(new Range(detail.line - 1, 0, detail.line - 1, 0)); | ||
} | ||
}); | ||
this.setDecorations(this.configStore.coverageDecorationType, renderLines); | ||
this.setDecorations(this.configStore.gutterDecorationType, renderLines); | ||
return resolve(); | ||
}); | ||
} | ||
|
||
public extract(lcovFile: string, file: string): Promise<Array<Detail>> { | ||
return new Promise<Array<Detail>>((resolve, reject) => { | ||
this.parseLcov(lcovFile, (err, data) => { | ||
if(err) return reject(err); | ||
let section = data.find((section) => { | ||
//prevent hazardous casing mishaps | ||
return section.file.toLocaleLowerCase() === file.toLocaleLowerCase(); | ||
}); | ||
|
||
if(!section) return reject(new Error("No coverage for file!")); | ||
return resolve(section.lines.details); | ||
}); | ||
}); | ||
} | ||
} |
Oops, something went wrong.