budibase/packages/string-templates/test/utils.ts

124 lines
3.3 KiB
TypeScript
Raw Normal View History

2024-02-21 23:43:12 +01:00
import { getManifest } from "../src"
import { getJsHelperList } from "../src/helpers"
2024-02-21 23:43:12 +01:00
import { convertToJS, processStringSync, encodeJSBinding } from "../src/index"
function tryParseJson(str) {
if (typeof str !== "string") {
return
}
try {
return JSON.parse(str.replace(/'/g, '"'))
} catch (e) {
return
}
}
2024-02-21 23:43:12 +01:00
type ExampleType = [
string,
{
hbs: string
js: string
requiresHbsBody: boolean
}
]
export const getParsedManifest = () => {
const manifest = getManifest()
const collections = Object.keys(manifest)
2024-02-21 23:43:12 +01:00
const examples = collections.reduce((acc, collection) => {
2024-02-21 23:43:12 +01:00
const functions = Object.entries<{
example: string
requiresBlock: boolean
}>(manifest[collection])
.filter(
([_, details]) =>
details.example?.split("->").map(x => x.trim()).length > 1
)
.map(([name, details]): ExampleType => {
const example = details.example
let [hbs, js] = example.split("->").map(x => x.trim())
// Trim 's
js = js.replace(/^'|'$/g, "")
2024-02-21 23:43:12 +01:00
let parsedExpected: string
if ((parsedExpected = tryParseJson(js))) {
if (Array.isArray(parsedExpected)) {
if (typeof parsedExpected[0] === "object") {
js = JSON.stringify(parsedExpected)
} else {
js = parsedExpected.join(",")
}
}
}
const requiresHbsBody = details.requiresBlock
return [name, { hbs, js, requiresHbsBody }]
})
2024-02-21 23:43:12 +01:00
if (functions.length) {
acc[collection] = functions
}
return acc
2024-02-21 23:43:12 +01:00
}, {} as Record<string, ExampleType[]>)
return examples
}
2024-02-21 23:43:12 +01:00
export const runJsHelpersTests = ({
funcWrap,
testsToSkip,
}: {
funcWrap?: any
testsToSkip?: any
} = {}) => {
funcWrap = funcWrap || (delegate => delegate())
const manifest = getParsedManifest()
const processJS = (js, context) => {
return funcWrap(() => processStringSync(encodeJSBinding(js), context))
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") // $& means the whole matched string
}
describe("can be parsed and run as js", () => {
2024-02-21 23:43:12 +01:00
const jsHelpers = getJsHelperList()!
const jsExamples = Object.keys(manifest).reduce((acc, v) => {
acc[v] = manifest[v].filter(([key]) => jsHelpers[key])
return acc
}, {})
describe.each(Object.keys(jsExamples))("%s", collection => {
const examplesToRun = jsExamples[collection]
.filter(([_, { requiresHbsBody }]) => !requiresHbsBody)
.filter(([key]) => !testsToSkip?.includes(key))
examplesToRun.length &&
it.each(examplesToRun)("%s", async (_, { hbs, js }) => {
const context = {
double: i => i * 2,
isString: x => typeof x === "string",
}
const arrays = hbs.match(/\[[^/\]]+\]/)
arrays?.forEach((arrayString, i) => {
hbs = hbs.replace(
new RegExp(escapeRegExp(arrayString)),
`array${i}`
)
context[`array${i}`] = JSON.parse(arrayString.replace(/'/g, '"'))
})
let convertedJs = convertToJS(hbs)
let result = await processJS(convertedJs, context)
result = result.replace(/&nbsp;/g, " ")
expect(result).toEqual(js)
})
})
})
}