Skip to content

Commit

Permalink
refactor(validation): add assertion functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aimee-gm committed May 14, 2020
1 parent 03bb35a commit 92b5d8d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/helpers/nodeMatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const rootClassRegex = classRegex("h");
const propClassRegex = classRegex("(p|e|u|dt)");

export const isParentNode = (node: MixedNode): node is ParentNode =>
Boolean(node.hasOwnProperty("tagName") && node.hasOwnProperty("childNodes"));
"tagName" in node && "childNodes" in node;

export const isTextNode = (node: MixedNode): node is DefaultTreeTextNode =>
Boolean(node.hasOwnProperty("value"));
"value" in node;

export const isMicroformatV2Root = (node: ParentNode): boolean =>
getClassNames(node).some((cl) => cl.match(rootClassRegex));
Expand Down
88 changes: 45 additions & 43 deletions src/validator.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,72 @@
import { ParentNode } from "./types";
import { isParentNode } from "./helpers/nodeMatchers";

export const validator = (html: unknown, options: unknown): void => {
if (typeof html === "undefined") {
throw new TypeError("Microformats parser: HTML not provided");
const assertIsString = (str: unknown, name: string): string => {
if (typeof str === "undefined") {
throw new TypeError(`Microformats parser: ${name} not provided`);
}

if (typeof html !== "string") {
throw new TypeError("Microformats parser: HTML is not a string");
if (typeof str !== "string") {
throw new TypeError(`Microformats parser: ${name} is not a string`);
}

if (html === "") {
throw new TypeError("Microformats parser: HTML cannot be empty");
if (str === "") {
throw new TypeError(`Microformats parser: ${name} cannot be empty`);
}

if (typeof options === "undefined") {
throw new TypeError("Microformats parser: options is not provided");
}
return str;
};

if (typeof options !== "object") {
throw new TypeError("Microformats parser: options is not an object");
const assertIsBoolean = (bool: unknown, name: string): boolean => {
if (typeof bool !== "boolean") {
throw new TypeError(`Microformats parser: ${name} is not a boolean`);
}

if (options === null) {
throw new TypeError("Microformats parser: options cannot be null");
}
return bool;
};

// eslint-disable-next-line
//@ts-ignore
const { baseUrl } = options;
const assertIsObject = (
obj: unknown,
name: string
): Record<string, unknown> => {
if (typeof obj === "undefined") {
throw new TypeError(`Microformats parser: ${name} is not provided`);
}

if (typeof baseUrl === "undefined") {
throw new TypeError("Microformats parser: baseUrl not provided");
if (typeof obj !== "object") {
throw new TypeError(`Microformats parser: ${name} is not an object`);
}

if (typeof baseUrl !== "string") {
throw new TypeError("Microformats parser: baseUrl is not a string");
if (Array.isArray(obj)) {
throw new TypeError(`Microformats parser: ${name} is not an object`);
}

if (baseUrl === "") {
throw new TypeError("Microformats parser: baseUrl cannot be empty");
if (obj === null) {
throw new TypeError(`Microformats parser: ${name} cannot be null`);
}

// verify the url provided is valid
new URL(baseUrl);
return obj as Record<string, unknown>;
};

// eslint-disable-next-line
//@ts-ignore
const { experimental } = options;
export const validator = (
unknownHtml: unknown,
unknownOptions: unknown
): void => {
assertIsString(unknownHtml, "HTML");

if (typeof experimental !== "undefined" && typeof experimental !== "object") {
throw new TypeError("Microformats parser: experimental is not an object");
}
const options = assertIsObject(unknownOptions, "options");

if (typeof experimental === "object" && Array.isArray(experimental)) {
throw new TypeError("Microformats parser: experimental is not an object");
}
const baseUrl = assertIsString(options.baseUrl, "baseUrl");

// verify the url provided is valid
new URL(baseUrl);

if ("experimental" in options) {
const experimental = assertIsObject(options.experimental, "experimental");

if (
experimental &&
"lang" in experimental &&
typeof experimental.lang !== "boolean"
) {
throw new TypeError(
"Microformats parser: experimental.lang is not a boolean"
);
if ("lang" in experimental) {
assertIsBoolean(experimental.lang, "experimental.lang");
}
}
};

Expand Down
6 changes: 6 additions & 0 deletions test/validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ describe("validation", () => {
});

describe("experimental", () => {
it("should not throw an error if it is an empty object", () => {
expect(() =>
mf2(html, { baseUrl: "http://example.com", experimental: {} })
).to.not.throw();
});

it("should throw an error if it is not an object", () => {
expect(() =>
mf2(html, { baseUrl: "http://example.com", experimental: "" })
Expand Down

0 comments on commit 92b5d8d

Please sign in to comment.