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

Use colors/safe #538

Merged
merged 3 commits into from Sep 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 28 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,31 @@
# 6.0.0

## Feature

* Use colors/safe [#538](https://github.com/bcaudan/jasmine-spec-reporter/pull/538)

## Breaking change

String prototype does not contain color properties anymore, colors must now be applied with the new `theme` component available as a field in [custom display processors](docs/customize-output.md).

**Before:**
```ts
class MyProcessor extends DisplayProcessor {
public displaySuccessfulSpec(spec: CustomReporterResult, log: string): string {
return "OK ".successful + log;
}
}
```

**Now:**
```ts
class MyProcessor extends DisplayProcessor {
public displaySuccessfulSpec(spec: CustomReporterResult, log: string): string {
return this.theme.successful("OK ") + log;
}
}
```

# 5.0.2

## Bugfix
Expand Down
2 changes: 1 addition & 1 deletion docs/customize-output.md
Expand Up @@ -41,7 +41,7 @@ For our example:
```node
var DisplayProcessor = require('jasmine-spec-reporter').DisplayProcessor;

function TimeProcessor(configuration) {
function TimeProcessor(configuration, theme) {
}

function getTime() {
Expand Down
3 changes: 3 additions & 0 deletions spec/helpers/before-all.ts
Expand Up @@ -3,12 +3,15 @@ declare namespace NodeJS {
SpecReporter;
DisplayProcessor;
TestProcessor;
colors;
}
}

global.SpecReporter = require("../../built/main").SpecReporter;
global.DisplayProcessor = require("../../built/main").DisplayProcessor;
global.TestProcessor = require("./test-processor").TestProcessor;
// tslint:disable-next-line:no-submodule-imports
global.colors = require("colors/safe");

beforeAll(() => {
const addMatchers = require("./test-helper").addMatchers;
Expand Down
14 changes: 3 additions & 11 deletions spec/helpers/test-helper.ts
@@ -1,14 +1,6 @@
require("colors");

interface String {
stripTime(): string;
}

// tslint:disable-next-line:no-unbound-method
String.prototype.stripTime = function(): string {
return this.replace(/in (\d+\.?\d*|\.\d+) secs?/, "in {time}") // replace time in summary
let stripTime = (str: string) =>
str.replace(/in (\d+\.?\d*|\.\d+) secs?/, "in {time}") // replace time in summary
.replace(/\((\d+\.?\d*|\.\d+) secs?\)/, "({time})"); // replace time in specs
};

let isArray = value => value.toString() === "[object Array]";

Expand Down Expand Up @@ -69,7 +61,7 @@ const JasmineEnv = {
logInSummary = false;
console.log = stuff => {
if (!options.withColor) {
stuff = stuff.stripColors.stripTime();
stuff = global.colors.stripColors(stripTime(stuff));
}
if (/^(Executed|\*\*\*\*\*\*\*)/.test(stuff)) {
logInSummary = true;
Expand Down
5 changes: 3 additions & 2 deletions spec/helpers/test-processor.ts
@@ -1,11 +1,12 @@
import {Configuration} from "../../built/configuration";
import {DisplayProcessor} from "../../built/main";
import {Theme} from "../../src/theme";

export class TestProcessor extends DisplayProcessor {
private test: string;

constructor(configuration: Configuration) {
super(configuration);
constructor(configuration: Configuration, theme: Theme) {
super(configuration, theme);
this.test = configuration.customOptions.test;
}

Expand Down
12 changes: 6 additions & 6 deletions spec/unit/colors-display.spec.ts
Expand Up @@ -21,7 +21,7 @@ describe("with colors", () => {
},
outputs => {
expect(outputs).not.contains(" ✓ successful spec");
expect(outputs).contains(" " + "✓ successful spec".green);
expect(outputs).contains(" " + global.colors.green("✓ successful spec"));
done();
},
{ withColor: true }
Expand All @@ -40,7 +40,7 @@ describe("with colors", () => {
},
outputs => {
expect(outputs).not.contains(" ✗ failed spec");
expect(outputs).contains(" " + "✗ failed spec".red);
expect(outputs).contains(" " + global.colors.red("✗ failed spec"));
done();
},
{ withColor: true }
Expand All @@ -59,7 +59,7 @@ describe("with colors", () => {
},
outputs => {
expect(outputs).not.contains(" * pending spec");
expect(outputs).contains(" " + "* pending spec".yellow);
expect(outputs).contains(" " + global.colors.yellow("* pending spec"));
done();
},
{ withColor: true }
Expand Down Expand Up @@ -94,7 +94,7 @@ describe("with colors", () => {
});
},
outputs => {
expect(outputs).contains(" " + "✓ successful spec".magenta);
expect(outputs).contains(" " + global.colors.magenta("✓ successful spec"));
done();
},
{ withColor: true }
Expand All @@ -112,7 +112,7 @@ describe("with colors", () => {
});
},
outputs => {
expect(outputs).contains(" " + "✗ failed spec".white);
expect(outputs).contains(" " + global.colors.white("✗ failed spec"));
done();
},
{ withColor: true }
Expand All @@ -130,7 +130,7 @@ describe("with colors", () => {
});
},
outputs => {
expect(outputs).contains(" " + "* pending spec".blue);
expect(outputs).contains(" " + global.colors.blue("* pending spec"));
done();
},
{ withColor: true }
Expand Down
2 changes: 1 addition & 1 deletion spec/unit/custom-print.spec.ts
Expand Up @@ -73,7 +73,7 @@ describe("spec reporter", () => {
expect(outputs.length).toEqual(0);
expect(customOutpouts).contains([
" suite",
" " + "✓ spec to be started".green
" " + global.colors.green("✓ spec to be started")
]);
done();
}
Expand Down
2 changes: 1 addition & 1 deletion src/configuration-parser.ts
Expand Up @@ -71,7 +71,7 @@ function merge(template: any, override: any): Configuration {
&& Object.keys(override).indexOf(key) !== -1) {
result[key] = override[key];
if (key === "displayStacktrace" && typeof override[key] === "boolean") {
console.warn("WARN: jasmine-spec-reporter 'displayStacktrace' option supports value ('none', 'raw', 'pretty'), default to 'none'\n".yellow);
console.warn("WARN: jasmine-spec-reporter 'displayStacktrace' option supports value ('none', 'raw', 'pretty'), default to 'none'\n");
result[key] = StacktraceOption.NONE;
}
} else {
Expand Down
5 changes: 4 additions & 1 deletion src/display-processor.ts
@@ -1,12 +1,15 @@
import {Configuration} from "./configuration";
import {CustomReporterResult} from "./spec-reporter";
import {Theme} from "./theme";
import SuiteInfo = jasmine.SuiteInfo;

export class DisplayProcessor {
protected configuration: Configuration;
protected theme: Theme;

constructor(configuration: Configuration) {
constructor(configuration: Configuration, theme: Theme) {
this.configuration = configuration;
this.theme = theme;
}

public displayJasmineStarted(info: SuiteInfo, log: string): string {
Expand Down
15 changes: 0 additions & 15 deletions src/display/colors-display.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/display/colors-theme.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/display/execution-display.ts
@@ -1,7 +1,6 @@
import {Configuration} from "../configuration";
import {DisplayProcessor} from "../display-processor";
import {CustomReporterResult, ExecutedSpecs} from "../spec-reporter";
import * as ColorsDisplay from "./colors-display";
import {Logger} from "./logger";

import SuiteInfo = jasmine.SuiteInfo;
Expand All @@ -23,7 +22,6 @@ export class ExecutionDisplay {

constructor(private configuration: Configuration, private logger: Logger, private specs: ExecutedSpecs,
displayProcessors: DisplayProcessor[]) {
ColorsDisplay.init(this.configuration);
this.hasCustomDisplaySpecStarted = ExecutionDisplay.hasCustomDisplaySpecStarted(displayProcessors);
}

Expand Down
11 changes: 6 additions & 5 deletions src/display/summary-display.ts
Expand Up @@ -2,10 +2,11 @@ import {Configuration} from "../configuration";
import {DisplayProcessor} from "../display-processor";
import {ExecutionMetrics} from "../execution-metrics";
import {CustomReporterResult, ExecutedSpecs} from "../spec-reporter";
import {Theme} from "../theme";
import {Logger} from "./logger";

export class SummaryDisplay {
constructor(private logger: Logger, private configuration: Configuration, private specs: ExecutedSpecs) {
constructor(private configuration: Configuration, private theme: Theme, private logger: Logger, private specs: ExecutedSpecs) {
}

public display(metrics: ExecutionMetrics) {
Expand All @@ -14,7 +15,7 @@ export class SummaryDisplay {
let status = "";
if (metrics.failedSpecs === 0 && metrics.globalErrors.length === 0) {
status = (metrics.totalSpecsDefined === metrics.executedSpecs) ?
" SUCCESS".successful : " INCOMPLETE".pending;
this.theme.successful(" SUCCESS") : this.theme.pending(" INCOMPLETE");
}
const failed = (metrics.failedSpecs > 0) ? ` (${metrics.failedSpecs} FAILED)` : "";
const pending = (metrics.pendingSpecs > 0) ? ` (${metrics.pendingSpecs} PENDING)` : "";
Expand All @@ -37,8 +38,8 @@ export class SummaryDisplay {
if (this.configuration.summary.displayPending && metrics.pendingSpecs > 0) {
this.pendingsSummary();
}
this.logger.log(execution + status + errors.failed + failed.failed
+ pending.pending + skipped.pending + duration + ".");
this.logger.log(execution + status + this.theme.failed(errors) + this.theme.failed(failed)
+ this.theme.pending(pending) + this.theme.pending(skipped) + duration + ".");

if (metrics.random) {
this.logger.log(`Randomized with seed ${metrics.seed}.`);
Expand Down Expand Up @@ -106,7 +107,7 @@ export class SummaryDisplay {
this.logger.log(`${index}) ${spec.fullName}`);
this.logger.increaseIndent();
const pendingReason = spec.pendingReason ? spec.pendingReason : "No reason given";
this.logger.log(pendingReason.pending);
this.logger.log(this.theme.pending(pendingReason));
this.logger.resetIndent();
}

Expand Down
2 changes: 1 addition & 1 deletion src/processors/default-processor.ts
Expand Up @@ -38,7 +38,7 @@ export class DefaultProcessor extends DisplayProcessor {
private displayErrorMessages(spec: CustomReporterResult, stacktraceOption: StacktraceOption): string {
const logs: string[] = [];
for (const failedExpectation of spec.failedExpectations) {
logs.push("- ".failed + failedExpectation.message.failed);
logs.push(this.theme.failed("- ") + this.theme.failed(failedExpectation.message));
if (stacktraceOption === StacktraceOption.RAW && failedExpectation.stack) {
logs.push(this.configuration.stacktrace.filter(failedExpectation.stack));
}
Expand Down
6 changes: 3 additions & 3 deletions src/processors/pretty-stacktrace-processor.ts
Expand Up @@ -19,7 +19,7 @@ export class PrettyStacktraceProcessor extends DisplayProcessor {
private displayErrorMessages(spec: CustomReporterResult) {
const logs: string[] = [];
for (const failedExpectation of spec.failedExpectations) {
logs.push("- ".failed + failedExpectation.message.failed);
logs.push(this.theme.failed("- ") + this.theme.failed(failedExpectation.message));
if (failedExpectation.stack) {
logs.push(this.prettifyStack(failedExpectation.stack));
}
Expand All @@ -40,7 +40,7 @@ export class PrettyStacktraceProcessor extends DisplayProcessor {
parseInt(columnNumber, 10)
);

logs.push(`${filename.prettyStacktraceFilename}:${lineNumber.prettyStacktraceLineNumber}:${columnNumber.prettyStacktraceColumnNumber}`);
logs.push(`${this.theme.prettyStacktraceFilename(filename)}:${this.theme.prettyStacktraceLineNumber(lineNumber)}:${this.theme.prettyStacktraceColumnNumber(columnNumber)}`);
logs.push(`${errorContext}\n`);
}
});
Expand All @@ -63,7 +63,7 @@ export class PrettyStacktraceProcessor extends DisplayProcessor {
logs.push(fileLines[i]);
}
if (i === errorLine) {
logs.push(" ".repeat(columnNb - 1) + "~".red);
logs.push(" ".repeat(columnNb - 1) + this.theme.prettyStacktraceError("~"));
}
}
return logs.join("\n");
Expand Down
6 changes: 3 additions & 3 deletions src/processors/spec-colors-processor.ts
Expand Up @@ -3,14 +3,14 @@ import {CustomReporterResult} from "../spec-reporter";

export class SpecColorsProcessor extends DisplayProcessor {
public displaySuccessfulSpec(spec: CustomReporterResult, log: string): string {
return log.successful;
return this.theme.successful(log);
}

public displayFailedSpec(spec: CustomReporterResult, log: string): string {
return log.failed;
return this.theme.failed(log);
}

public displayPendingSpec(spec: CustomReporterResult, log: string): string {
return log.pending;
return this.theme.pending(log);
}
}
23 changes: 13 additions & 10 deletions src/spec-reporter.ts
Expand Up @@ -11,6 +11,7 @@ import {SpecColorsProcessor} from "./processors/spec-colors-processor";
import {SpecDurationsProcessor} from "./processors/spec-durations-processor";
import {SpecPrefixesProcessor} from "./processors/spec-prefixes-processor";
import {SuiteNumberingProcessor} from "./processors/suite-numbering-processor";
import {Theme} from "./theme";

import CustomReporter = jasmine.CustomReporter;
import SuiteInfo = jasmine.SuiteInfo;
Expand All @@ -27,25 +28,25 @@ export interface ExecutedSpecs {
}

export class SpecReporter implements CustomReporter {
private static initProcessors(configuration: Configuration): DisplayProcessor[] {
private static initProcessors(configuration: Configuration, theme: Theme): DisplayProcessor[] {
const displayProcessors: DisplayProcessor[] = [
new DefaultProcessor(configuration),
new SpecPrefixesProcessor(configuration),
new SpecColorsProcessor(configuration),
new PrettyStacktraceProcessor(configuration)
new DefaultProcessor(configuration, theme),
new SpecPrefixesProcessor(configuration, theme),
new SpecColorsProcessor(configuration, theme),
new PrettyStacktraceProcessor(configuration, theme)
];

if (configuration.spec.displayDuration) {
displayProcessors.push(new SpecDurationsProcessor(configuration));
displayProcessors.push(new SpecDurationsProcessor(configuration, theme));
}

if (configuration.suite.displayNumber) {
displayProcessors.push(new SuiteNumberingProcessor(configuration));
displayProcessors.push(new SuiteNumberingProcessor(configuration, theme));
}

if (configuration.customProcessors) {
configuration.customProcessors.forEach((Processor: typeof DisplayProcessor) => {
displayProcessors.push(new Processor(configuration));
displayProcessors.push(new Processor(configuration, theme));
});
}

Expand All @@ -62,14 +63,16 @@ export class SpecReporter implements CustomReporter {
private summary: SummaryDisplay;
private metrics: ExecutionMetrics;
private configuration: Configuration;
private theme: Theme;

constructor(configuration?: Configuration) {
this.configuration = ConfigurationParser.parse(configuration);
const displayProcessors = SpecReporter.initProcessors(this.configuration);
this.theme = new Theme(this.configuration);
const displayProcessors = SpecReporter.initProcessors(this.configuration, this.theme);
const print = this.configuration.print;
this.logger = new Logger(displayProcessors, print);
this.display = new ExecutionDisplay(this.configuration, this.logger, this.specs, displayProcessors);
this.summary = new SummaryDisplay(this.logger, this.configuration, this.specs);
this.summary = new SummaryDisplay(this.configuration, this.theme, this.logger, this.specs);
this.metrics = new ExecutionMetrics();
}

Expand Down