Silently ignore non-iterables in {#each} (#2)

* Silently ignore non-iterables in {#each}

* silence console.info
This commit is contained in:
David Bruant 2025-04-17 19:38:32 +02:00 committed by GitHub
parent ecfedf9317
commit 1094c9b838
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 10 deletions

View File

@ -1,5 +1,5 @@
console.info('DOM implementation in browser') //console.info('DOM implementation in browser')
/** @type { typeof DOMImplementation.prototype.createDocument } */ /** @type { typeof DOMImplementation.prototype.createDocument } */
export function createDocument(...args){ export function createDocument(...args){

View File

@ -1,6 +1,6 @@
import { DOMImplementation } from "@xmldom/xmldom" import { DOMImplementation } from "@xmldom/xmldom"
console.info('DOM implementation in Node.js based on xmldom') //console.info('DOM implementation in Node.js based on xmldom')
const implementation = new DOMImplementation() const implementation = new DOMImplementation()

View File

@ -30,7 +30,7 @@ const ODTMimetype = 'application/vnd.oasis.opendocument.text'
* @param {any} context - data / global object * @param {any} context - data / global object
* @return {any} * @return {any}
*/ */
function evaludateTemplateExpression(expression, context){ function evaluateTemplateExpression(expression, context){
const parts = expression.trim().split('.') const parts = expression.trim().split('.')
let value = context; let value = context;
@ -76,7 +76,7 @@ function findPlacesToFillInString(str) {
parts.push(fixedPart) parts.push(fixedPart)
parts.push(data => evaludateTemplateExpression(expression, data)) parts.push(data => evaluateTemplateExpression(expression, data))
remaining = newRemaining remaining = newRemaining
} }
@ -189,12 +189,10 @@ function fillEachBlock(startNode, iterableExpression, itemExpression, endNode, d
// Find the iterable in the data // Find the iterable in the data
// PPP eventually, evaluate the expression as a JS expression // PPP eventually, evaluate the expression as a JS expression
const iterable = evaludateTemplateExpression(iterableExpression, data) let iterable = evaluateTemplateExpression(iterableExpression, data)
if(!iterable){ if(!iterable || typeof iterable[Symbol.iterator] !== 'function'){
throw new TypeError(`Missing iterable (${iterableExpression})`) // when there is no iterable, silently replace with empty array
} iterable = []
if(typeof iterable[Symbol.iterator] !== 'function'){
throw new TypeError(`'${iterableExpression}' is not iterable`)
} }
// create each loop result // create each loop result

View File

@ -71,6 +71,35 @@ Pâtes à lasagne (fraîches !)
`) `)
});
test('Filling with {#each} and non-iterable value results in no error and empty result', async t => {
const templatePath = join(import.meta.dirname, './data/enum-courses.odt')
const templateContent = `🧺 La liste de courses incroyable 🧺
{#each listeCourses as élément}
{élément}
{/each}
`
const data = {
listeCourses : undefined
}
const odtTemplate = await getOdtTemplate(templatePath)
const templateTextContent = await getOdtTextContent(odtTemplate)
t.deepEqual(templateTextContent, templateContent, 'reconnaissance du template')
const odtResult = await fillOdtTemplate(odtTemplate, data)
const odtResultTextContent = await getOdtTextContent(odtResult)
t.deepEqual(odtResultTextContent, `🧺 La liste de courses incroyable 🧺
`)
}); });