124 lines
3.4 KiB
TypeScript
124 lines
3.4 KiB
TypeScript
import { getManifest } from "../src"
|
|
import { getJsHelperList } from "../src/helpers"
|
|
|
|
import { convertToJS, processStringSync, encodeJSBinding } from "../src/index"
|
|
|
|
function tryParseJson(str: string) {
|
|
if (typeof str !== "string") {
|
|
return
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(str.replace(/'/g, '"'))
|
|
} catch (e) {
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
type ExampleType = [
|
|
string,
|
|
{
|
|
hbs: string
|
|
js: string
|
|
requiresHbsBody: boolean
|
|
}
|
|
]
|
|
|
|
export const getParsedManifest = () => {
|
|
const manifest: any = getManifest()
|
|
const collections = Object.keys(manifest)
|
|
|
|
const examples = collections.reduce((acc, collection) => {
|
|
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, "")
|
|
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 }]
|
|
})
|
|
|
|
if (functions.length) {
|
|
acc[collection] = functions
|
|
}
|
|
return acc
|
|
}, {} as Record<string, ExampleType[]>)
|
|
|
|
return examples
|
|
}
|
|
|
|
export const runJsHelpersTests = ({
|
|
funcWrap,
|
|
testsToSkip,
|
|
}: {
|
|
funcWrap?: any
|
|
testsToSkip?: any
|
|
} = {}) => {
|
|
funcWrap = funcWrap || ((delegate: () => any) => delegate())
|
|
const manifest = getParsedManifest()
|
|
|
|
const processJS = (js: string, context: object | undefined) => {
|
|
return funcWrap(() => processStringSync(encodeJSBinding(js), context))
|
|
}
|
|
|
|
function escapeRegExp(string: string) {
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") // $& means the whole matched string
|
|
}
|
|
|
|
describe("can be parsed and run as js", () => {
|
|
const jsHelpers = getJsHelperList()!
|
|
const jsExamples = Object.keys(manifest).reduce((acc, v) => {
|
|
acc[v] = manifest[v].filter(([key]) => jsHelpers[key])
|
|
return acc
|
|
}, {} as typeof manifest)
|
|
|
|
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: any = {
|
|
double: (i: number) => i * 2,
|
|
isString: (x: any) => 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(/ /g, " ")
|
|
expect(result).toEqual(js)
|
|
})
|
|
})
|
|
})
|
|
}
|