2024-02-22 00:46:22 +01:00
|
|
|
import {
|
2021-01-19 18:29:38 +01:00
|
|
|
processObject,
|
|
|
|
processString,
|
2021-01-22 18:57:38 +01:00
|
|
|
isValid,
|
|
|
|
makePropSafe,
|
2021-01-29 15:35:37 +01:00
|
|
|
getManifest,
|
2022-01-21 17:24:24 +01:00
|
|
|
encodeJSBinding,
|
|
|
|
doesContainString,
|
2022-02-03 19:26:26 +01:00
|
|
|
disableEscaping,
|
2022-03-02 18:40:50 +01:00
|
|
|
findHBSBlocks,
|
2024-02-22 00:46:22 +01:00
|
|
|
} from "../src/index"
|
2021-01-19 18:29:38 +01:00
|
|
|
|
|
|
|
describe("Test that the string processing works correctly", () => {
|
2021-01-20 14:32:15 +01:00
|
|
|
it("should process a basic template string", async () => {
|
|
|
|
const output = await processString("templating is {{ adjective }}", {
|
2021-04-07 11:56:06 +02:00
|
|
|
adjective: "easy",
|
2021-01-19 18:29:38 +01:00
|
|
|
})
|
|
|
|
expect(output).toBe("templating is easy")
|
|
|
|
})
|
|
|
|
|
2021-01-21 13:08:57 +01:00
|
|
|
it("should process a literal template", async () => {
|
|
|
|
const output = await processString("derp is {{{ adjective }}}", {
|
2021-04-07 11:56:06 +02:00
|
|
|
adjective: "derp",
|
2021-01-21 13:08:57 +01:00
|
|
|
})
|
|
|
|
expect(output).toBe("derp is derp")
|
|
|
|
})
|
|
|
|
|
2021-01-20 14:32:15 +01:00
|
|
|
it("should fail gracefully when wrong type passed in", async () => {
|
2021-01-19 18:29:38 +01:00
|
|
|
let error = null
|
|
|
|
try {
|
2024-02-22 00:46:22 +01:00
|
|
|
await processString(null as any, null as any)
|
2021-01-19 18:29:38 +01:00
|
|
|
} catch (err) {
|
|
|
|
error = err
|
|
|
|
}
|
|
|
|
expect(error).not.toBeNull()
|
|
|
|
})
|
2021-01-21 14:48:23 +01:00
|
|
|
|
|
|
|
it("confirm that null properties are handled correctly", async () => {
|
|
|
|
const output = await processString("hello {{ name }} I am {{ name2 }}", {
|
|
|
|
name: undefined,
|
|
|
|
name2: null,
|
|
|
|
})
|
|
|
|
expect(output).toBe("hello I am ")
|
|
|
|
})
|
2021-01-19 18:29:38 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
describe("Test that the object processing works correctly", () => {
|
2021-01-20 14:32:15 +01:00
|
|
|
it("should be able to process an object with some template strings", async () => {
|
2021-04-07 11:56:06 +02:00
|
|
|
const output = await processObject(
|
|
|
|
{
|
|
|
|
first: "thing is {{ adjective }}",
|
|
|
|
second: "thing is bad",
|
|
|
|
third: "we are {{ adjective }} {{ noun }}",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
adjective: "easy",
|
|
|
|
noun: "people",
|
|
|
|
}
|
|
|
|
)
|
2021-01-19 18:29:38 +01:00
|
|
|
expect(output.first).toBe("thing is easy")
|
|
|
|
expect(output.second).toBe("thing is bad")
|
|
|
|
expect(output.third).toBe("we are easy people")
|
|
|
|
})
|
|
|
|
|
2021-01-20 14:32:15 +01:00
|
|
|
it("should be able to handle arrays of string templates", async () => {
|
2021-04-07 11:56:06 +02:00
|
|
|
const output = await processObject(
|
|
|
|
["first {{ noun }}", "second {{ noun }}"],
|
|
|
|
{
|
|
|
|
noun: "person",
|
|
|
|
}
|
|
|
|
)
|
2021-01-19 18:29:38 +01:00
|
|
|
expect(output[0]).toBe("first person")
|
|
|
|
expect(output[1]).toBe("second person")
|
|
|
|
})
|
|
|
|
|
2021-01-20 14:32:15 +01:00
|
|
|
it("should fail gracefully when object passed in has cycles", async () => {
|
2021-01-19 18:29:38 +01:00
|
|
|
let error = null
|
|
|
|
try {
|
2024-02-21 23:16:54 +01:00
|
|
|
const innerObj: any = { a: "thing {{ a }}" }
|
2021-01-19 18:29:38 +01:00
|
|
|
innerObj.b = innerObj
|
2021-01-20 14:32:15 +01:00
|
|
|
await processObject(innerObj, { a: 1 })
|
2021-01-19 18:29:38 +01:00
|
|
|
} catch (err) {
|
|
|
|
error = err
|
|
|
|
}
|
|
|
|
expect(error).not.toBeNull()
|
|
|
|
})
|
|
|
|
|
2021-09-17 18:18:52 +02:00
|
|
|
it("check objects get converted to string JSON automatically", async () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
const row = { a: 1 }
|
2021-09-17 18:18:52 +02:00
|
|
|
const output = await processString("{{ trigger.row }}", {
|
|
|
|
trigger: {
|
|
|
|
row,
|
2023-11-20 15:36:55 +01:00
|
|
|
},
|
2021-09-17 18:18:52 +02:00
|
|
|
})
|
|
|
|
expect(JSON.parse(output)).toEqual(row)
|
|
|
|
})
|
|
|
|
|
2021-06-09 15:17:11 +02:00
|
|
|
it("should be able to handle null objects", async () => {
|
2021-01-19 18:29:38 +01:00
|
|
|
let error = null
|
|
|
|
try {
|
2024-03-14 18:39:08 +01:00
|
|
|
await processObject(null as any, null as any)
|
2021-01-19 18:29:38 +01:00
|
|
|
} catch (err) {
|
|
|
|
error = err
|
|
|
|
}
|
2021-06-09 15:17:11 +02:00
|
|
|
expect(error).toBeNull()
|
2021-01-19 18:29:38 +01:00
|
|
|
})
|
2024-03-21 17:29:55 +01:00
|
|
|
|
|
|
|
it("should be able to handle booleans", async () => {
|
|
|
|
const output = await processObject(
|
|
|
|
{
|
|
|
|
first: true,
|
|
|
|
second: "true",
|
|
|
|
third: "another string",
|
|
|
|
forth: "with {{ template }}",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
template: "value",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
expect(output).toEqual({
|
|
|
|
first: true,
|
|
|
|
second: "true",
|
|
|
|
third: "another string",
|
|
|
|
forth: "with value",
|
|
|
|
})
|
|
|
|
})
|
2021-01-22 18:57:38 +01:00
|
|
|
})
|
2024-03-25 13:22:57 +01:00
|
|
|
|
|
|
|
describe("check arrays", () => {
|
2024-03-25 14:17:45 +01:00
|
|
|
describe("index with square brackets", () => {
|
|
|
|
it.each([
|
|
|
|
[0, "1"],
|
|
|
|
[1, "2"],
|
|
|
|
])("should handle an array of primitive types", async (index, expected) => {
|
|
|
|
const json = [1, 2, 3]
|
|
|
|
const output = await processString(`{{ testing.[${index}] }}`, {
|
|
|
|
testing: json,
|
|
|
|
})
|
|
|
|
expect(output).toEqual(expected)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should handle an array of objects", async () => {
|
|
|
|
const json = [{ value: 1 }, { value: 2 }, { value: 3 }]
|
|
|
|
const output = await processString("{{ testing.[1] }}", {
|
|
|
|
testing: json,
|
|
|
|
})
|
|
|
|
expect(output).toEqual('{"value":2}')
|
2024-03-25 13:22:57 +01:00
|
|
|
})
|
|
|
|
|
2024-03-25 14:17:45 +01:00
|
|
|
it("should handle nesting properties in an array of objects", async () => {
|
|
|
|
const json = [{ value: 1 }, { value: 2 }, { value: 3 }]
|
|
|
|
const output = await processString("{{ testing.[1].value }}", {
|
|
|
|
testing: json,
|
|
|
|
})
|
|
|
|
expect(output).toEqual("2")
|
2024-03-25 13:22:57 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2024-03-25 14:17:45 +01:00
|
|
|
describe("index without square brackets", () => {
|
|
|
|
it("should not handle an array of primitive types", async () => {
|
|
|
|
const json = [1, 2, 3]
|
|
|
|
const output = await processString(`{{ testing.1 }}`, {
|
|
|
|
testing: json,
|
|
|
|
})
|
|
|
|
expect(output).toEqual("{{ testing.1 }}")
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should not handle an array of objects", async () => {
|
|
|
|
const json = [{ value: 1 }, { value: 2 }, { value: 3 }]
|
|
|
|
const output = await processString("{{ testing.1 }}", {
|
|
|
|
testing: json,
|
|
|
|
})
|
|
|
|
expect(output).toEqual("{{ testing.1 }}")
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should handle nesting properties in an array of object types", async () => {
|
|
|
|
const json = [{ value: 1 }, { value: 2 }, { value: 3 }]
|
|
|
|
const output = await processString("{{ testing.1.value }}", {
|
|
|
|
testing: json,
|
|
|
|
})
|
|
|
|
expect(output).toEqual("2")
|
2024-03-25 13:22:57 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2021-01-22 18:57:38 +01:00
|
|
|
|
2022-05-04 18:36:30 +02:00
|
|
|
describe("check returning objects", () => {
|
|
|
|
it("should handle an array of objects", async () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
const json = [{ a: 1 }, { a: 2 }]
|
2022-05-04 18:36:30 +02:00
|
|
|
const output = await processString("{{ testing }}", {
|
2023-11-20 15:36:55 +01:00
|
|
|
testing: json,
|
2022-05-04 18:36:30 +02:00
|
|
|
})
|
|
|
|
expect(output).toEqual(JSON.stringify(json))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-01-22 18:57:38 +01:00
|
|
|
describe("check the utility functions", () => {
|
|
|
|
it("should return false for an invalid template string", () => {
|
|
|
|
const valid = isValid("{{ table1.thing prop }}")
|
|
|
|
expect(valid).toBe(false)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should state this template is valid", () => {
|
|
|
|
const valid = isValid("{{ thing }}")
|
|
|
|
expect(valid).toBe(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should make a property safe", () => {
|
|
|
|
const property = makePropSafe("thing")
|
|
|
|
expect(property).toEqual("[thing]")
|
|
|
|
})
|
2021-05-11 17:07:55 +02:00
|
|
|
|
|
|
|
it("should be able to handle an input date object", async () => {
|
|
|
|
const date = new Date()
|
|
|
|
const output = await processString("{{ dateObj }}", { dateObj: date })
|
2021-06-28 11:00:22 +02:00
|
|
|
expect(date.toString()).toEqual(output)
|
2021-05-11 17:07:55 +02:00
|
|
|
})
|
2021-01-29 15:35:37 +01:00
|
|
|
})
|
|
|
|
|
2021-11-02 17:30:43 +01:00
|
|
|
describe("check falsy values", () => {
|
|
|
|
it("should get a zero out when context contains it", async () => {
|
|
|
|
const output = await processString("{{ number }}", { number: 0 })
|
|
|
|
expect(output).toEqual("0")
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should get false out when context contains it", async () => {
|
|
|
|
const output = await processString("{{ bool }}", { bool: false })
|
|
|
|
expect(output).toEqual("false")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-01-29 15:35:37 +01:00
|
|
|
describe("check manifest", () => {
|
|
|
|
it("should be able to retrieve the manifest", () => {
|
|
|
|
const manifest = getManifest()
|
|
|
|
expect(manifest.math).not.toBeNull()
|
2021-04-07 11:56:06 +02:00
|
|
|
expect(manifest.math.abs.description).toBe(
|
|
|
|
"<p>Return the magnitude of <code>a</code>.</p>\n"
|
|
|
|
)
|
2021-01-29 15:35:37 +01:00
|
|
|
})
|
2021-04-07 11:56:06 +02:00
|
|
|
})
|
2022-01-14 18:42:14 +01:00
|
|
|
|
|
|
|
describe("check full stops that are safe", () => {
|
|
|
|
it("should allow using an escaped full stop", async () => {
|
|
|
|
const data = {
|
2023-11-20 15:36:55 +01:00
|
|
|
"c53a4a604fa754d33baaafd5bca4d3658-YXuUBqt5vI": {
|
|
|
|
"persons.firstname": "1",
|
|
|
|
},
|
2022-01-14 18:42:14 +01:00
|
|
|
}
|
2023-11-20 15:36:55 +01:00
|
|
|
const template =
|
|
|
|
"{{ [c53a4a604fa754d33baaafd5bca4d3658-YXuUBqt5vI].[persons.firstname] }}"
|
2022-01-14 18:42:14 +01:00
|
|
|
const output = await processString(template, data)
|
|
|
|
expect(output).toEqual("1")
|
|
|
|
})
|
|
|
|
})
|
2022-01-21 17:24:24 +01:00
|
|
|
|
|
|
|
describe("check does contain string function", () => {
|
|
|
|
it("should work for a simple case", () => {
|
|
|
|
const hbs = "hello {{ name }}"
|
|
|
|
expect(doesContainString(hbs, "name")).toEqual(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should reject a case where its in the string, but not the handlebars", () => {
|
|
|
|
const hbs = "hello {{ name }}"
|
|
|
|
expect(doesContainString(hbs, "hello")).toEqual(false)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should handle if its in javascript", () => {
|
|
|
|
const js = encodeJSBinding(`return $("foo")`)
|
|
|
|
expect(doesContainString(js, "foo")).toEqual(true)
|
|
|
|
})
|
|
|
|
})
|
2022-02-03 19:26:26 +01:00
|
|
|
|
|
|
|
describe("check that disabling escaping function works", () => {
|
|
|
|
it("should work for a single statement", () => {
|
|
|
|
expect(disableEscaping("{{ name }}")).toEqual("{{{ name }}}")
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should work for two statements", () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
expect(disableEscaping("{{ name }} welcome to {{ platform }}")).toEqual(
|
|
|
|
"{{{ name }}} welcome to {{{ platform }}}"
|
|
|
|
)
|
2022-02-03 19:26:26 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
it("shouldn't convert triple braces", () => {
|
|
|
|
expect(disableEscaping("{{{ name }}}")).toEqual("{{{ name }}}")
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should work with a combination", () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
expect(disableEscaping("{{ name }} welcome to {{{ platform }}}")).toEqual(
|
|
|
|
"{{{ name }}} welcome to {{{ platform }}}"
|
|
|
|
)
|
2022-02-03 19:26:26 +01:00
|
|
|
})
|
2022-02-17 14:22:36 +01:00
|
|
|
|
|
|
|
it("should work with multiple escaped", () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
expect(disableEscaping("{{ name }} welcome to {{ name }}")).toEqual(
|
|
|
|
"{{{ name }}} welcome to {{{ name }}}"
|
|
|
|
)
|
2022-02-17 14:22:36 +01:00
|
|
|
})
|
2022-02-03 19:26:26 +01:00
|
|
|
})
|
|
|
|
|
2022-03-02 18:40:50 +01:00
|
|
|
describe("check find hbs blocks function", () => {
|
|
|
|
it("should find none", () => {
|
|
|
|
expect(findHBSBlocks("hello there")).toEqual([])
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should find two", () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
expect(findHBSBlocks("{{ hello }} there {{{ name }}}")).toEqual([
|
|
|
|
"{{ hello }}",
|
|
|
|
"{{{ name }}}",
|
|
|
|
])
|
2022-03-02 18:40:50 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2023-01-27 16:15:07 +01:00
|
|
|
describe("should leave HBS blocks if not found using option", () => {
|
|
|
|
it("should replace one, leave one", async () => {
|
2023-11-20 15:36:55 +01:00
|
|
|
const output = await processString(
|
|
|
|
"{{ a }}, {{ b }}",
|
|
|
|
{ b: 1 },
|
|
|
|
{ onlyFound: true }
|
|
|
|
)
|
2023-01-27 16:15:07 +01:00
|
|
|
expect(output).toBe("{{ a }}, 1")
|
|
|
|
})
|
|
|
|
})
|
2024-06-28 15:18:15 +02:00
|
|
|
|
|
|
|
describe("check multiple space behaviour", () => {
|
|
|
|
it("should remove whitespace and use the helper correctly", async () => {
|
|
|
|
const output = await processString("{{ add num1 num2 }}", {
|
|
|
|
num1: 1,
|
|
|
|
num2: 2,
|
|
|
|
})
|
|
|
|
expect(output).toEqual("3")
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should ensure that whitespace within a string is respected", async () => {
|
|
|
|
const output = await processString("{{ trimRight 'test string ' }}", {
|
|
|
|
num1: 1,
|
|
|
|
num2: 2,
|
|
|
|
})
|
|
|
|
expect(output).toEqual("test string")
|
|
|
|
})
|
|
|
|
})
|