Skip to content

Commit

Permalink
Merge 861314e into a33b727
Browse files Browse the repository at this point in the history
  • Loading branch information
Tymek committed Jun 30, 2020
2 parents a33b727 + 861314e commit 0232d2e
Show file tree
Hide file tree
Showing 21 changed files with 772 additions and 236 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Bug-fixes within the same version aren't needed
## Master
* refactor editor decorations and load icons from `vscode-codicons` [@Tymek](https://github.com/Tymek)
* move test status indicator from editor text to gutter [@Tymek](https://github.com/Tymek)
* improve create-react-app detection logic - stephtr
* improve the detection of cases in which Jest needs to be restarted with `--watchAll` - [@lordofthelake](https://github.com/lordofthelake)
* upgrade all dependencies to the latest, except istanbul-lib-xxx, which requires more code change and will be handled in a separate coverage PR. - @connectdotz
Expand Down
4 changes: 4 additions & 0 deletions custom.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module '*.svg' {
const content: string;
export default content;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ module.exports = {
'debug',
'@babel/template',
],
moduleNameMapper: {
'\\.(svg)$': '<rootDir>/tests/fileMock.ts',
},
};
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@
"@types/vscode": "^1.23.0",
"@typescript-eslint/eslint-plugin": "^2.32.0",
"@typescript-eslint/parser": "^2.32.0",
"copy-webpack-plugin": "^6.0.2",
"coveralls": "^3.1.0",
"danger": "^10.1.1",
"eslint": "^7.0.0",
Expand All @@ -301,10 +302,12 @@
"eslint-plugin-prettier": "^3.1.3",
"jest": "^25.5.0",
"prettier": "^2.0.5",
"raw-loader": "^4.0.1",
"rimraf": "^3.0.2",
"ts-jest": "^25.4.0",
"ts-loader": "^7.0.1",
"typescript": "^3.8.3",
"vscode-codicons": "^0.0.4",
"vscode-test": "^1.3.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
Expand Down
14 changes: 5 additions & 9 deletions src/Coverage/Formatters/GutterFormatter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { AbstractFormatter } from '../AbstractFormatter';
import * as vscode from 'vscode';
import { FileCoverage } from 'istanbul-lib-coverage';
import { isValidLocation } from '../helpers';
import prepareIcon from '../../../decorations/prepareIcon';
import coverageGutterIcon from '../../../../icons/coverage.svg';

export interface CoverageLines {
covered: vscode.Range[];
Expand All @@ -23,28 +25,22 @@ export class GutterFormatter extends AbstractFormatter {
backgroundColor: '',
overviewRulerColor: 'rgba(121, 31, 10, 0.75)',
overviewRulerLane: vscode.OverviewRulerLane.Left,
gutterIconPath: context.asAbsolutePath(
'./src/Coverage/Formatters/GutterFormatter/uncovered-gutter-icon.svg'
),
gutterIconPath: prepareIcon(context, 'uncovered', coverageGutterIcon, '#791F0A'),
});

this.partiallyCoveredLine = vscode.window.createTextEditorDecorationType({
backgroundColor: 'rgba(121, 86, 10, 0.75)',
overviewRulerColor: 'rgba(121, 86, 10, 0.75)',
overviewRulerLane: vscode.OverviewRulerLane.Left,
gutterIconPath: context.asAbsolutePath(
'./src/Coverage/Formatters/GutterFormatter/partially-covered-gutter-icon.svg'
),
gutterIconPath: prepareIcon(context, 'partially-covered', coverageGutterIcon, '#79560A'),
});

this.coveredLine = vscode.window.createTextEditorDecorationType({
isWholeLine: true,
backgroundColor: '',
overviewRulerColor: '',
overviewRulerLane: vscode.OverviewRulerLane.Left,
gutterIconPath: context.asAbsolutePath(
'./src/Coverage/Formatters/GutterFormatter/covered-gutter-icon.svg'
),
gutterIconPath: prepareIcon(context, 'covered', coverageGutterIcon, '#2D790A'),
});
}

Expand Down

This file was deleted.

This file was deleted.

118 changes: 118 additions & 0 deletions src/Decorations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import * as path from 'path';
import * as fs from 'fs';
import {
window,
OverviewRulerLane,
DecorationRangeBehavior,
ExtensionContext,
TextEditorDecorationType,
DecorationRenderOptions,
} from 'vscode';
import passingIcon from 'vscode-codicons/src/icons/check.svg';
import failingIcon from 'vscode-codicons/src/icons/chrome-close.svg';
import skipIcon from 'vscode-codicons/src/icons/debug-step-over.svg';
import unknownIcon from 'vscode-codicons/src/icons/question.svg';

export class Decorations {
private static ICONS_PATH = path.join('out', 'icons');

private context: ExtensionContext;

public passing: TextEditorDecorationType;
public failing: TextEditorDecorationType;
public skip: TextEditorDecorationType;
public unknown: TextEditorDecorationType;

constructor(context) {
this.context = context;

this.passing = this.createStateDecoration([['passing', passingIcon, '#35A15E'], 'green']);
this.failing = this.createStateDecoration([['failing', failingIcon, '#D6443C'], 'red']);
this.skip = this.createStateDecoration([['skip', skipIcon, '#fed37f'], 'yellow']);
this.unknown = this.createStateDecoration(
[['unknown', unknownIcon, '#BBBBBB'], 'darkgrey'],
[['unknown-light', unknownIcon, '#555555']]
);
}

private resolvePath(...args: string[]): string {
return this.context.asAbsolutePath(path.join(...args));
}

private prepareIcon(state: string, source: string, color?: string): string {
const resultIconPath = this.resolvePath(Decorations.ICONS_PATH, `${state}.svg`);
let result = source.toString();

if (color !== undefined) {
result = result.replace('fill="currentColor"', `fill="${color}"`);
}

if (!fs.existsSync(resultIconPath) || fs.readFileSync(resultIconPath).toString() !== result) {
if (!fs.existsSync(this.resolvePath(Decorations.ICONS_PATH))) {
fs.mkdirSync(this.resolvePath(Decorations.ICONS_PATH));
}

fs.writeFileSync(resultIconPath, result);
}

return resultIconPath;
}

private createStateDecoration(
dark: /* default */ [Parameters<Decorations['prepareIcon']>, string?],
light?: /* optional overrides */ [Parameters<Decorations['prepareIcon']>, string?]
): TextEditorDecorationType {
const [iconOptions, overviewRulerColor] = dark;
const icon = this.prepareIcon(...iconOptions);

const options: DecorationRenderOptions = {
gutterIconPath: icon,
gutterIconSize: 'contain',
overviewRulerLane: OverviewRulerLane.Left,
rangeBehavior: DecorationRangeBehavior.ClosedClosed,
dark: {
gutterIconPath: icon,
},
light: {
gutterIconPath: light !== undefined ? this.prepareIcon(...light[0]) : icon,
},
};

if (overviewRulerColor) {
options['overviewRulerColor'] = overviewRulerColor;
options['dark']['overviewRulerColor'] = overviewRulerColor;
}

if (light !== undefined && light[1] !== undefined) {
options['light']['overviewRulerColor'] = light[1];
}

return window.createTextEditorDecorationType(options);
}

public failingAssertionStyle(text: string): TextEditorDecorationType {
return window.createTextEditorDecorationType({
isWholeLine: true,
overviewRulerColor: 'red',
overviewRulerLane: OverviewRulerLane.Left,
light: {
before: {
color: '#FF564B',
},
after: {
color: '#FF564B',
contentText: ' // ' + text,
},
},
dark: {
before: {
color: '#AD322D',
},
after: {
color: '#AD322D',
contentText: ' // ' + text,
},
},
});
}
}
29 changes: 9 additions & 20 deletions src/JestExt.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import { ProjectWorkspace, JestTotalResults } from 'jest-editor-support';

import * as decorations from './decorations';
import { Decorations } from './Decorations';
import { PluginResourceSettings } from './Settings';
import { statusBar, Status, StatusBar, Mode } from './StatusBar';
import {
Expand Down Expand Up @@ -50,17 +50,13 @@ export class JestExt {

private jestWorkspace: ProjectWorkspace;
private pluginSettings: PluginResourceSettings;
private decorations: Decorations;
private workspaceFolder: vscode.WorkspaceFolder;
private instanceSettings: InstanceSettings;

// The ability to show fails in the problems section
private failDiagnostics: vscode.DiagnosticCollection;

private passingItStyle: vscode.TextEditorDecorationType;
private failingItStyle: vscode.TextEditorDecorationType;
private skipItStyle: vscode.TextEditorDecorationType;
private unknownItStyle: vscode.TextEditorDecorationType;

private parsingTestFile = false;

// We have to keep track of our inline assert fails to remove later
Expand Down Expand Up @@ -113,7 +109,7 @@ export class JestExt {
this.handleJestEditorSupportEvent = this.handleJestEditorSupportEvent.bind(this);

// The theme stuff
this.setupDecorators();
this.decorations = new Decorations(context);
// The bottom bar thing
this.setupStatusBar();
// reset the jest diagnostics
Expand Down Expand Up @@ -223,26 +219,26 @@ export class JestExt {
}

updateDecorators(testResults: SortedTestResults, editor: vscode.TextEditor): void {
// Dots
// Status indicators (gutter icons)
const styleMap = [
{
data: testResults.success,
decorationType: this.passingItStyle,
decorationType: this.decorations.passing,
state: TestReconciliationState.KnownSuccess,
},
{
data: testResults.fail,
decorationType: this.failingItStyle,
decorationType: this.decorations.failing,
state: TestReconciliationState.KnownFail,
},
{
data: testResults.skip,
decorationType: this.skipItStyle,
decorationType: this.decorations.skip,
state: TestReconciliationState.KnownSkip,
},
{
data: testResults.unknown,
decorationType: this.unknownItStyle,
decorationType: this.decorations.unknown,
state: TestReconciliationState.Unknown,
},
];
Expand Down Expand Up @@ -427,7 +423,7 @@ export class JestExt {

// We have to make a new style for each unique message, this is
// why we have to remove off of them beforehand
const style = decorations.failingAssertionStyle(errorMessage);
const style = this.decorations.failingAssertionStyle(errorMessage);
this.failingAssertionDecorators[fileName].push(style);

return { style, decorator };
Expand Down Expand Up @@ -502,13 +498,6 @@ export class JestExt {
this.status.update(status, details, modes);
}

private setupDecorators(): void {
this.passingItStyle = decorations.passingItName();
this.failingItStyle = decorations.failingItName();
this.skipItStyle = decorations.skipItName();
this.unknownItStyle = decorations.notRanItName();
}

private shouldIgnoreOutput(text: string): boolean {
// this fails when snapshots change - to be revised - returning always false for now
return (
Expand Down
Loading

0 comments on commit 0232d2e

Please sign in to comment.