Skip to content

Commit

Permalink
add support for actual and expected values in errors (via #1215)
Browse files Browse the repository at this point in the history
  • Loading branch information
baev authored Jan 14, 2025
1 parent b93d73a commit 2de0a93
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 3 deletions.
2 changes: 2 additions & 0 deletions packages/allure-js-commons/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export type ParameterOptions = Pick<Parameter, "mode" | "excluded">;
export interface StatusDetails {
message?: string;
trace?: string;
actual?: string;
expected?: string;
}

// don't use the interface as is, use Results types instead
Expand Down
8 changes: 5 additions & 3 deletions packages/allure-js-commons/src/sdk/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ export const stripAnsi = (str: string): string => {
return str.replace(regex, "");
};

export const getMessageAndTraceFromError = (
error: Error | { message?: string; stack?: string },
): Pick<StatusDetails, "message" | "trace"> => {
export const getMessageAndTraceFromError = (error: Error | { message?: string; stack?: string }): StatusDetails => {
const { message, stack } = error;
const actual = "actual" in error && error.actual !== undefined ? { actual: serialize(error.actual) } : {};
const expected = "expected" in error && error.expected !== undefined ? { expected: serialize(error.expected) } : {};
return {
message: message ? stripAnsi(message) : undefined,
trace: stack ? stripAnsi(stack) : undefined,
...actual,
...expected,
};
};

Expand Down
49 changes: 49 additions & 0 deletions packages/allure-js-commons/test/sdk/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { FixtureResult, StepResult, TestResult } from "../../src/model.js";
import {
allureLabelRegexp,
extractMetadataFromString,
getMessageAndTraceFromError,
getStatusFromError,
isAnyStepFailed,
isMetadataTag,
Expand Down Expand Up @@ -505,3 +506,51 @@ describe("serialize", () => {
});
});
});

describe("getMessageAndTraceFromError", () => {
it("should return message from error", () => {
const result = getMessageAndTraceFromError(new Error("some message"));
expect(result).toMatchObject({
message: "some message",
});
});

it("should return trace from error", () => {
const result = getMessageAndTraceFromError(new Error("some message"));
expect(result).toMatchObject({
trace: expect.stringMatching(/allure-js-commons.test.sdk.utils\.spec\.ts/),
});
});

it("should return actual from error", () => {
const error: Error & { actual?: string } = new Error("some message");
error.actual = "some actual value";
const result = getMessageAndTraceFromError(error);
expect(result).toMatchObject({
actual: "some actual value",
});
});

it("should ignore undefined actual value", () => {
const error: Error & { actual?: string } = new Error("some message");
error.actual = undefined;
const result = getMessageAndTraceFromError(error);
expect(result).not.toHaveProperty("actual");
});

it("should return expected from error", () => {
const error: Error & { expected?: string } = new Error("some message");
error.expected = "some expected value";
const result = getMessageAndTraceFromError(error);
expect(result).toMatchObject({
expected: "some expected value",
});
});

it("should ignore undefined expected value", () => {
const error: Error & { expected?: string } = new Error("some message");
error.expected = undefined;
const result = getMessageAndTraceFromError(error);
expect(result).not.toHaveProperty("expected");
});
});
74 changes: 74 additions & 0 deletions packages/allure-vitest/test/spec/expect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { describe, expect, it } from "vitest";
import { runVitestInlineTest } from "../utils.js";

describe("expect", () => {
it("should add actual and expected values when using expect", async () => {
const { tests } = await runVitestInlineTest(`
import { test, expect } from "vitest";
test("fail test", () => {
expect("a value").toEqual("the other one");
});
`);

expect(tests).toHaveLength(1);
expect(tests).toMatchObject([
{
name: "fail test",
status: "failed",
statusDetails: {
message: "expected 'a value' to deeply equal 'the other one'",
expected: "the other one",
actual: "a value",
},
},
]);
});
it("should add actual and expected values when using expect with match object", async () => {
const { tests } = await runVitestInlineTest(`
import { test, expect } from "vitest";
test("fail test", () => {
expect({ nested: { obj: "value", n: 123}}).toMatchObject({ nested: { obj: "some"} });
});
`);

expect(tests).toHaveLength(1);
expect(tests).toMatchObject([
{
name: "fail test",
status: "failed",
statusDetails: {
expected: "Object {\n" + ' "nested": Object {\n' + ' "obj": "some",\n' + " },\n" + "}",
actual: "Object {\n" + ' "nested": Object {\n' + ' "obj": "value",\n' + " },\n" + "}",
},
},
]);
});

// this is the way vitest process errors
it("should add actual and expected values when regular exception is thrown", async () => {
const { tests } = await runVitestInlineTest(`
import { test, expect } from "vitest";
test("fail test", () => {
throw new Error("fail!")
});
`);

expect(tests).toHaveLength(1);
expect(tests).toMatchObject([
{
name: "fail test",
status: "broken",
statusDetails: {
expected: "undefined",
actual: "undefined",
},
},
]);
});
});

0 comments on commit 2de0a93

Please sign in to comment.