Commit 749dfc28 authored by David Sveningsson's avatar David Sveningsson
Browse files

feat(jest): `toHTMLValidate()` matcher accepts any object with `outerHTML`, `innerHTML` or `html()`

parent ace03025
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ expect("<p></p>").toHTMLValidate();
expect("<p></i>").not.toHTMLValidate();
```

You can also pass jsdom elements:
You can also pass in JSDOM elements (or any object with a `outerHTML`, `innerHTML` or a `html()` method):

```ts
import "html-validate/jest";
+44 −1
Original line number Diff line number Diff line
@@ -136,10 +136,53 @@ describe("toHTMLValidate()", () => {
		expect(button).not.toHTMLValidate();
	});

	it("should support object with outerHTML", () => {
		expect.assertions(2);

		/* should pass */
		const valid = { outerHTML: "<p></p>" };
		expect(valid).toHTMLValidate();

		/* should fail (type not set) */
		const invalid = { outerHTML: "<button>" };
		expect(invalid).not.toHTMLValidate();
	});

	it("should support object with innerHTML", () => {
		expect.assertions(2);

		/* should pass */
		const valid = { innerHTML: "<p></p>" };
		expect(valid).toHTMLValidate();

		/* should fail (type not set) */
		const invalid = { innerHTML: "<button>" };
		expect(invalid).not.toHTMLValidate();
	});

	it("should support object with html method", () => {
		expect.assertions(2);

		/* should pass */
		const valid = { html: () => "<p></p>" };
		expect(valid).toHTMLValidate();

		/* should fail (type not set) */
		const invalid = { html: () => "<button>" };
		expect(invalid).not.toHTMLValidate();
	});

	it("should throw error when passing invalid object", () => {
		expect.hasAssertions();
		expect(() => {
			expect({}).toHTMLValidate();
			expect(42).toHTMLValidate();
		}).toThrowErrorMatchingInlineSnapshot(`"Failed to get markup from "number" argument"`);
	});

	it("should throw error when object with html method does not return string", () => {
		expect.hasAssertions();
		expect(() => {
			expect({ html: () => null }).toHTMLValidate();
		}).toThrowErrorMatchingInlineSnapshot(`"Failed to get markup from "object" argument"`);
	});

+32 −3
Original line number Diff line number Diff line
@@ -38,11 +38,40 @@ function isString(arg: Arg1 | undefined): arg is string {
	return typeof arg === "string";
}

function hasOuterHTML(value: unknown): value is { outerHTML: string } {
	if (!value || typeof value !== "object") {
		return false;
	}
	return "outerHTML" in value && typeof value.outerHTML === "string";
}

function hasInnerHTML(value: unknown): value is { innerHTML: string } {
	if (!value || typeof value !== "object") {
		return false;
	}
	return "innerHTML" in value && typeof value.innerHTML === "string";
}

function hasHTML(value: unknown): value is { html(): unknown } {
	if (!value || typeof value !== "object") {
		return false;
	}
	return "html" in value && typeof value.html === "function";
}

function getMarkup(src: unknown): string {
	if (typeof HTMLElement !== "undefined" && src instanceof HTMLElement) {
		return (src as { outerHTML: string }).outerHTML;
	if (hasOuterHTML(src)) {
		return src.outerHTML;
	}
	if (hasInnerHTML(src)) {
		return src.innerHTML;
	}
	if (hasHTML(src)) {
		const value = src.html();
		if (typeof value === "string") {
			return value;
		}
	}
	/* istanbul ignore else: prototype only allows string or HTMLElement */
	if (typeof src === "string") {
		return src;
	}