Skip to content

Refactor #110

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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coverage-decorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
MarkdownString,
} from "vscode";
import {
CONFIG_OPTION_SHOW_DECORATIONS,
ConfigurationOptions,
ExtensionConfiguration,
} from "./extension-configuration";
import { Coverage } from "./coverage-info";
Expand Down Expand Up @@ -186,7 +186,7 @@ export class CoverageDecorations extends Disposable {
*/
private onConfigOptionUpdated(configOption: string): void {
if (
configOption === CONFIG_OPTION_SHOW_DECORATIONS &&
configOption === ConfigurationOptions.showDecorations &&
window.activeTextEditor
) {
const activeFile = window.activeTextEditor.document.uri.fsPath;
Expand Down
171 changes: 62 additions & 109 deletions src/extension-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,136 +6,89 @@ import {
} from "vscode";

export const CONFIG_SECTION_NAME = "markiscodecoverage";
export const CONFIG_OPTION_ENABLE_ON_STARTUP = "enableOnStartup";
export const CONFIG_OPTION_SEARCH_CRITERIA = "searchCriteria";
export const CONFIG_OPTION_COVERAGE_THRESHOLD = "coverageThreshold";
export const CONFIG_OPTION_SHOW_DECORATIONS = "enableDecorations";

export const DEFAULT_SEARCH_CRITERIA = "coverage/lcov*.info";
export const DEFAULT_CODE_COVERAGE_THRESHOLD = 80;
const DEFAULT_SHOW_COVERAGE = true;
const DEFAULT_SHOW_DECORATIONS = false;
const DEFAULT_SEARCH_CRITERIA = "coverage/lcov*.info";
const DEFAULT_CODE_COVERAGE_THRESHOLD = 80;

export enum ConfigurationOptions {
enableOnStartup = "enableOnStartup",
searchCriteria = "searchCriteria",
coverageThreshold = "coverageThreshold",
showDecorations = "enableDecorations",
}

export class ExtensionConfiguration extends Disposable {
private readonly _onConfigOptionUpdated = new EventEmitter<string>();
private _isDisposed = false;
private _showCoverage = true;
private _searchCriteria = "";
private _coverageThreshold = 0;
private _showDecorations = false;

constructor(config: WorkspaceConfiguration) {
// use dummy function for callOnDispose since dispose() will be overrided
super(() => true);

this.showCoverage =
!config.has(CONFIG_OPTION_ENABLE_ON_STARTUP) ||
(config.get(CONFIG_OPTION_ENABLE_ON_STARTUP) ?? true);

const configSearchCriteria =
config.has(CONFIG_OPTION_SEARCH_CRITERIA) &&
config.get(CONFIG_OPTION_SEARCH_CRITERIA);
this.searchCriteria =
configSearchCriteria && typeof configSearchCriteria === "string"
? configSearchCriteria
: DEFAULT_SEARCH_CRITERIA;

this.coverageThreshold =
config.get(CONFIG_OPTION_COVERAGE_THRESHOLD) ??
DEFAULT_CODE_COVERAGE_THRESHOLD;

this.showDecorations = config.get(CONFIG_OPTION_SHOW_DECORATIONS, false);
}

public override dispose(): void {
if (!this._isDisposed) {
this._onConfigOptionUpdated.dispose();

this._isDisposed = true;
}
constructor(
config: WorkspaceConfiguration,
public showCoverage = config.get(
ConfigurationOptions.enableOnStartup,
DEFAULT_SHOW_COVERAGE,
),
public showDecorations = config.get(
ConfigurationOptions.showDecorations,
DEFAULT_SHOW_DECORATIONS,
),
public searchCriteria = config.get(
ConfigurationOptions.searchCriteria,
DEFAULT_SEARCH_CRITERIA,
),
public coverageThreshold = config.get(
ConfigurationOptions.coverageThreshold,
DEFAULT_CODE_COVERAGE_THRESHOLD,
),
private configSectionName = CONFIG_SECTION_NAME,
private readonly _onConfigOptionUpdated:
| EventEmitter<string>
| undefined = new EventEmitter<string>(),
) {
super(() => {
_onConfigOptionUpdated.dispose();
});
}

public onConfigOptionUpdated(listener: (e: string) => any): Disposable {
this._checkDisposed();
if (!this._onConfigOptionUpdated) return Disposable.from();
return this._onConfigOptionUpdated.event(listener);
}

get showCoverage() {
this._checkDisposed();
return this._showCoverage;
}
set showCoverage(value: boolean) {
this._checkDisposed();
this._showCoverage = value;
}

get showDecorations() {
this._checkDisposed();
return this._showDecorations;
}
set showDecorations(value: boolean) {
this._checkDisposed();
this._showDecorations = value;
}

get searchCriteria() {
this._checkDisposed();
return this._searchCriteria;
}
set searchCriteria(value: string) {
this._checkDisposed();
this._searchCriteria = value;
}

get coverageThreshold() {
this._checkDisposed();
return this._coverageThreshold;
}
set coverageThreshold(value: number) {
this._checkDisposed();
this._coverageThreshold = value;
}

dispatchConfigUpdate(
evtSrc: ConfigurationChangeEvent,
latestSnapshot: WorkspaceConfiguration,
): void {
this._checkDisposed();

if (this._hasBeenUpdated(evtSrc, CONFIG_OPTION_SEARCH_CRITERIA)) {
const configSearchCriteria =
latestSnapshot.has(CONFIG_OPTION_SEARCH_CRITERIA) &&
latestSnapshot.get(CONFIG_OPTION_SEARCH_CRITERIA);
this.searchCriteria =
configSearchCriteria && typeof configSearchCriteria === "string"
? configSearchCriteria
: this.searchCriteria;
if (!this._onConfigOptionUpdated) return;

this._onConfigOptionUpdated.fire(CONFIG_OPTION_SEARCH_CRITERIA);
} else if (this._hasBeenUpdated(evtSrc, CONFIG_OPTION_COVERAGE_THRESHOLD)) {
this.coverageThreshold =
latestSnapshot.get(CONFIG_OPTION_COVERAGE_THRESHOLD) ??
this.coverageThreshold;

this._onConfigOptionUpdated.fire(CONFIG_OPTION_COVERAGE_THRESHOLD);
} else if (this._hasBeenUpdated(evtSrc, CONFIG_OPTION_SHOW_DECORATIONS)) {
if (this._hasBeenUpdated(evtSrc, ConfigurationOptions.searchCriteria)) {
this.searchCriteria = latestSnapshot.get(
ConfigurationOptions.searchCriteria,
DEFAULT_SEARCH_CRITERIA,
);
this._onConfigOptionUpdated.fire(ConfigurationOptions.searchCriteria);
} else if (
this._hasBeenUpdated(evtSrc, ConfigurationOptions.coverageThreshold)
) {
this.coverageThreshold = latestSnapshot.get(
ConfigurationOptions.coverageThreshold,
DEFAULT_CODE_COVERAGE_THRESHOLD,
);
this._onConfigOptionUpdated.fire(ConfigurationOptions.coverageThreshold);
} else if (
this._hasBeenUpdated(evtSrc, ConfigurationOptions.showDecorations)
) {
this.showDecorations = latestSnapshot.get(
CONFIG_OPTION_SHOW_DECORATIONS,
this.showDecorations,
ConfigurationOptions.showDecorations,
DEFAULT_SHOW_DECORATIONS,
);

this._onConfigOptionUpdated.fire(CONFIG_OPTION_SHOW_DECORATIONS);
this._onConfigOptionUpdated.fire(ConfigurationOptions.showDecorations);
}
}

private _hasBeenUpdated(
evtSrc: ConfigurationChangeEvent,
optionName: string,
): boolean {
return evtSrc.affectsConfiguration(`${CONFIG_SECTION_NAME}.${optionName}`);
}

private _checkDisposed() {
if (this._isDisposed) {
throw new Error("illegal state - object is disposed");
}
return evtSrc.affectsConfiguration(
`${this.configSectionName}.${optionName}`,
);
}
}
4 changes: 2 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import {
LineCoverageInfo,
} from "./coverage-info";
import {
CONFIG_OPTION_SEARCH_CRITERIA,
CONFIG_SECTION_NAME,
ConfigurationOptions,
ExtensionConfiguration,
} from "./extension-configuration";
import { parse as parseLcov } from "./parse-lcov";
Expand Down Expand Up @@ -72,7 +72,7 @@ export async function activate(
// Register watchers and listen if the coverage file directory has changed
registerWatchers();
extensionConfiguration.onConfigOptionUpdated((e) => {
if (e && e === CONFIG_OPTION_SEARCH_CRITERIA) {
if (e && e === ConfigurationOptions.searchCriteria) {
registerWatchers();
}
});
Expand Down
24 changes: 12 additions & 12 deletions src/file-coverage-info-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Uri,
} from "vscode";
import {
CONFIG_OPTION_COVERAGE_THRESHOLD,
ConfigurationOptions,
ExtensionConfiguration,
} from "./extension-configuration";
import { Coverage } from "./coverage-info";
Expand Down Expand Up @@ -107,16 +107,16 @@ export class FileCoverageInfoProvider
if (this._isDisposing || !this._showFileDecorations) return;

const coverage = this._coverageByFile.get(uri.fsPath);
if (coverage) {
const percentCovered = calculateCoveragePercent(coverage);
if (percentCovered < this._coverageThreshold) {
return new FileDecoration(
FILE_DECORATION_BADGE,
`${FILE_DECORATION_TOOLTIP_PRELUDE} ${percentCovered}% vs. ${this._coverageThreshold}%.`,
new ThemeColor("markiscodecoverage.insufficientCoverageForeground"),
);
}
}
if (!coverage) return;

const percentCovered = calculateCoveragePercent(coverage);
if (percentCovered >= this._coverageThreshold) return;

return new FileDecoration(
FILE_DECORATION_BADGE,
`$${FILE_DECORATION_TOOLTIP_PRELUDE} ${percentCovered} vs. ${this._coverageThreshold}.`,
new ThemeColor("markiscodecoverage.insufficientCoverageForeground"),
);
}

/**
Expand All @@ -128,7 +128,7 @@ export class FileCoverageInfoProvider
private handleConfigUpdate(e: string): void {
if (
this._isDisposing ||
e !== CONFIG_OPTION_COVERAGE_THRESHOLD ||
e !== ConfigurationOptions.coverageThreshold ||
this._coverageThreshold === this._configuration.coverageThreshold
) {
return;
Expand Down
Loading