From d005c136b943d40f6344a7fd9db181c319300eac Mon Sep 17 00:00:00 2001 From: Sir Robert Burbridge Date: Fri, 17 Nov 2023 11:35:00 -0500 Subject: [PATCH] Stable coverage. --- .gitignore | 2 ++ src/ast-to-html.mjs | 7 ++++ src/interpolate.mjs | 11 ++++--- src/util.mjs | 19 +++++++++++ test/interpolate.test.mjs | 68 +++++++++++++++++++++++++++++++++++++-- test/util.test.mjs | 2 -- 6 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 src/ast-to-html.mjs diff --git a/.gitignore b/.gitignore index b24d71e..46f0184 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ node_modules/ dist/ + # Compiled Java class files *.class @@ -28,6 +29,7 @@ dist/ # Unit test reports TEST*.xml +coverage/ # Generated by MacOS .DS_Store diff --git a/src/ast-to-html.mjs b/src/ast-to-html.mjs new file mode 100644 index 0000000..54aa4e9 --- /dev/null +++ b/src/ast-to-html.mjs @@ -0,0 +1,7 @@ +import { toHtml } from 'hast-util-to-html'; + +export function htmlToAst(ast) { + return toHtml(ast); +} + +export default htmlToAst; diff --git a/src/interpolate.mjs b/src/interpolate.mjs index 1fd94b4..5b517bb 100644 --- a/src/interpolate.mjs +++ b/src/interpolate.mjs @@ -28,7 +28,6 @@ function getMaskedData(node, ancestors) { function interpolateNode(node, ancestors) { const data = getMaskedData(node, ancestors); - // Interpolate properties if (node.properties && typeof node.properties === 'object') { for (const key in node.properties) { if (typeof node.properties[key] === 'string') { @@ -44,7 +43,6 @@ function interpolateNode(node, ancestors) { } } - // Interpolate text content for text nodes if (node.type === 'text' && node.value) { node.value = interpolateString(node.value, data.interp); } @@ -54,9 +52,14 @@ function interpolateNode(node, ancestors) { function interpolateString(str, data) { const context = createContext({ ...data, ...global }); - const interpolatedStr = runInContext(`\`${str}\``, context); - return interpolatedStr; + try { + const interpolatedStr = runInContext(`\`${str}\``, context); + return interpolatedStr; + } catch (e) { + console.error('Error interpolating string:', e); + return str; + } } export default interpolate; diff --git a/src/util.mjs b/src/util.mjs index 8b13789..d5848d5 100644 --- a/src/util.mjs +++ b/src/util.mjs @@ -1 +1,20 @@ +export function cloneNode (node) { + return JSON.parse(JSON.stringify(node)); +} +export function createAstNode (type, props, children) { + const ast = { + type: type, + props: props, + children: children || [], + }; + return ast; +} + +// Test if the node is an object with a "type" value (including undefined) +export function isAstNode (node) { + return (typeof node === 'object') + && (node !== null) + && ('type' in node) + ; +} diff --git a/test/interpolate.test.mjs b/test/interpolate.test.mjs index 0d6b4d2..19ab321 100644 --- a/test/interpolate.test.mjs +++ b/test/interpolate.test.mjs @@ -8,8 +8,7 @@ describe("interpolate()", () => { expect(interpolate).toBeDefined(); }) - it("should interpolate", () => { - + it("should interpolate a single node", () => { const uninterpolated = '
'; const expected = '
'; @@ -21,4 +20,69 @@ describe("interpolate()", () => { expect(rendered).toEqual(expected); }) + it("should interpolate a nested tree", () => { + const uninterpolated = ` +
+

This is a \${data.stringInPTag} in a p tag

+

This is a p with an interpolated id

+ +
+ `; + const expected = ` +
+

This is a string in a p tag

+

This is a p with an interpolated id

+ +
+ `; + + const data = { + classname: "foo", + data: { + stringInPTag: "string", + id: "foo", + listClass: "bar", + listItem: "baz", + }, + }; + const ast = htmlToAst(uninterpolated); + const interpolated = interpolate(ast, data); + const rendered = astToHtml(interpolated); + + expect(rendered).toEqual(expected); + }) + + it("should handle arbitrary javascript", () => { + const uninterpolated = ` +
+

simple: 3 * 12 = \${3 * 12}

+

named function: 3^2 = \${square(3)}

+

arrow function: 5*2 = \${(num => (num * 2))(5)}

+

arrow function: 3-8 = \${(num => (num - 8))(3)}

+
+ `; + const expected = ` +
+

simple: 3 * 12 = 36

+

named function: 3^2 = 9

+

arrow function: 5*2 = 10

+

arrow function: 3-8 = -5

+
+ `; + + const data = { + classname: "foo", + square: (num) => Math.pow(num, 2), + }; + const ast = htmlToAst(uninterpolated); + const interpolated = interpolate(ast, data); + const rendered = astToHtml(interpolated); + + expect(rendered).toEqual(expected); + }) + }); diff --git a/test/util.test.mjs b/test/util.test.mjs index a79ddd9..af90004 100644 --- a/test/util.test.mjs +++ b/test/util.test.mjs @@ -84,7 +84,5 @@ describe("isAstNode()", () => { }); }); - - });