Commit fede6b1a authored by David Sveningsson's avatar David Sveningsson Committed by David Sveningsson
Browse files

refactor(vitest): use shared function to get report from received value

parent 2e352d6f
Loading
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
import { type AsyncExpectationResult, type MatcherState } from "@vitest/expect";
import { FileSystemConfigLoader } from "../../config/loaders/file-system";
import { HtmlValidate } from "../../htmlvalidate";
import { type Report } from "../../reporter";
import { getReport } from "../utils";

type ToBeInvalidMatcher = (
	this: MatcherState,
	received: Report | string | Promise<Report> | Promise<string>,
) => AsyncExpectationResult;

function createMatcher(): ToBeInvalidMatcher {
	const loader = new FileSystemConfigLoader({
		extends: ["html-validate:recommended"],
	});
	const htmlvalidate = new HtmlValidate(loader);

async function toBeInvalid(
	this: MatcherState,
	received: Report | string | Promise<Report> | Promise<string>,
): AsyncExpectationResult {
		const resolved = await received;

		let report: Report;
		if (typeof resolved === "string") {
			const filename = this.testPath ?? "inline";
			report = await htmlvalidate.validateString(resolved, filename, {
				rules: {
					"void-style": "off",
				},
			});
		} else {
			report = resolved;
		}
	const report = await getReport(received, this);

	if (report.valid) {
		return {
@@ -44,6 +25,7 @@ function createMatcher(): ToBeInvalidMatcher {
	};
}

function createMatcher(): ToBeInvalidMatcher {
	return toBeInvalid;
}

+9 −27
Original line number Diff line number Diff line
import { type AsyncExpectationResult, type MatcherState } from "@vitest/expect";
import { FileSystemConfigLoader } from "../../config/loaders/file-system";
import { HtmlValidate } from "../../htmlvalidate";
import { type Report } from "../../reporter";
import { getReport } from "../utils";

type ToBeValidMatcher = (
	this: MatcherState,
	received: Report | string | Promise<Report> | Promise<string>,
) => AsyncExpectationResult;

function createMatcher(): ToBeValidMatcher {
	const loader = new FileSystemConfigLoader({
		extends: ["html-validate:recommended"],
	});
	const htmlvalidate = new HtmlValidate(loader);

async function toBeValid(
	this: MatcherState,
	received: Report | string | Promise<Report> | Promise<string>,
): AsyncExpectationResult {
		const resolved = await received;

		let report: Report;
		if (typeof resolved === "string") {
			const filename = this.testPath ?? "inline";
			report = await htmlvalidate.validateString(resolved, filename, {
				rules: {
					"void-style": "off",
				},
			});
		} else {
			report = resolved;
		}
	const report = await getReport(received, this);

		if (report.valid) {
	if (!report.valid) {
		const firstError = report.results[0].messages[0];
		return {
				pass: true,
				message: /* istanbul ignore next */ () => "Result should not contain error",
			pass: false,
			message: () => `Result should be valid but had error "${firstError.message}"`,
		};
	}

		const firstError = report.results[0].messages[0];
	return {
			pass: false,
			message: () => `Result should be valid but had error "${firstError.message}"`,
		pass: true,
		message: /* istanbul ignore next */ () => "Result should not contain error",
	};
}

function createMatcher(): ToBeValidMatcher {
	return toBeValid;
}

+3 −23
Original line number Diff line number Diff line
import { type AsyncExpectationResult, type MatcherState } from "@vitest/expect";
import * as vitest from "vitest";
import { FileSystemConfigLoader } from "../../config/loaders/file-system";
import { HtmlValidate } from "../../htmlvalidate";
import { type Report } from "../../reporter";
import { codeframe } from "../utils";
import { codeframe, getReport } from "../utils";

type ToMatchCodeframeMatcher = (
	this: MatcherState,
@@ -11,12 +9,6 @@ type ToMatchCodeframeMatcher = (
	hint?: string,
) => AsyncExpectationResult;

function createMatcher(): ToMatchCodeframeMatcher {
	const loader = new FileSystemConfigLoader({
		extends: ["html-validate:recommended"],
	});
	const htmlvalidate = new HtmlValidate(loader);

async function toMatchCodeframe(
	this: MatcherState,
	received: Report | string | Promise<Report> | Promise<string>,
@@ -27,25 +19,13 @@ function createMatcher(): ToMatchCodeframeMatcher {
		throw new Error("toMatchCodeframe() requires vitest 4.1.3 or later. Please upgrade vitest.");
	}

		const resolved = await received;

		let report: Report;
		if (typeof resolved === "string") {
			const filename = this.testPath ?? "inline";
			report = await htmlvalidate.validateString(resolved, filename, {
				rules: {
					"void-style": "off",
				},
			});
		} else {
			report = resolved;
		}

	const report = await getReport(received, this);
	const snapshot = codeframe(report.results).replaceAll(/\s+$/gm, "");

	return vitest.Snapshots.toMatchSnapshot.call(this, snapshot, hint);
}

function createMatcher(): ToMatchCodeframeMatcher {
	return toMatchCodeframe;
}

+43 −0
Original line number Diff line number Diff line
import { type MatcherState } from "@vitest/expect";
import { defineConfig } from "../../config";
import { FileSystemConfigLoader } from "../../config/loaders/file-system";
import { HtmlValidate } from "../../htmlvalidate";
import { type Report } from "../../reporter";

/** @todo this is cached without any mechanism to flush, this would typically
 * not be an issue but in watch mode this would cause issues if the
 * configuration is changed */
const state = {
	htmlvalidate: null as HtmlValidate | null,
};

const defaultConfig = defineConfig({
	rules: {
		"void-style": "off",
	},
});

function getValidator(): HtmlValidate {
	if (state.htmlvalidate === null) {
		const loader = new FileSystemConfigLoader({
			extends: ["html-validate:recommended"],
		});
		state.htmlvalidate = new HtmlValidate(loader);
	}
	return state.htmlvalidate;
}

export async function getReport(
	received: Report | string | Promise<Report> | Promise<string>,
	state: Pick<MatcherState, "testPath">,
): Promise<Report> {
	const resolved = await received;

	if (typeof resolved === "string") {
		const { testPath = "inline" } = state;
		const htmlvalidate = getValidator();
		return await htmlvalidate.validateString(resolved, testPath, defaultConfig);
	}

	return resolved;
}
+1 −0
Original line number Diff line number Diff line
export { codeframe } from "./codeframe";
export { type MaybeAsyncCallback, diverge } from "./diverge";
export { getReport } from "./get-report";
export { isThenable } from "./is-thenable";