<commit_before>const path = require('path')
const expect = require('chai').expect
const html = require('html')
const htmlBeautifier = require('js-beautify').html
const { JSDOM } = require('jsdom')

const nunjucksConfig = require('~/config/nunjucks')

const nunjucks = nunjucksConfig(null, {
  root: path.normalize(rootPath),
})

const COMPONENTS_PATH = '_components/'
const MACROS_PATH = '_macros/'
const EXT = 'njk'

const normaliseHtml = (string) => {
  const beautiful = htmlBeautifier(string, {
    indent_size: 2,
    max_preserve_newlines: 0,
  })

  return html.prettyPrint(beautiful, {
    indent_size: 2,
  })
}

function getMacros (fileName) {
  const filePath = `${MACROS_PATH}${fileName}.${EXT}`

  return {
    render (macroName, props, ...rest) {
      const importString = `{% from "${filePath}" import ${macroName} %}`
      const args = rest.length ? `,${[...rest].map(JSON.stringify)}` : ''
      const macroOutput = nunjucks.renderString(`${importString} {{ ${macroName}(${JSON.stringify(props)}${args}) }}`)
      return normaliseHtml(macroOutput)
    },

    renderToDom (macroName, props, ...rest) {
      const macroOutput = this.render(macroName, props, ...rest)
      return (new JSDOM(macroOutput)).window.document.body.firstElementChild
    },
  }
}

const renderComponent = (name, input) => {
  const componentPath = `${COMPONENTS_PATH}${name}.${EXT}`
  return normaliseHtml(nunjucks.render(componentPath, input))
}

const renderComponentToDom = (name, input) => {
  const renderedComponent = renderComponent(name, input)
  return (new JSDOM(renderedComponent)).window.document.body.firstElementChild
}

const expectComponent = (name, input, expected) => {
  // Normalise HTML whitespace, to make diffing simpler
  expect(
    renderComponent(name, input)<commit_msg>Refactor macro test helper to test callers<commit_after>const path = require('path')
const expect = require('chai').expect
const html = require('html')
const htmlBeautifier = require('js-beautify').html
const { JSDOM } = require('jsdom')

const nunjucksConfig = require('~/config/nunjucks')

const nunjucks = nunjucksConfig(null, {
  root: path.normalize(rootPath),
})

const COMPONENTS_PATH = '_components/'
const MACROS_PATH = '_macros/'
const EXT = 'njk'

const normaliseHtml = (string) => {
  const beautiful = htmlBeautifier(string, {
    indent_size: 2,
    max_preserve_newlines: 0,
  })

  return html.prettyPrint(beautiful, {
    indent_size: 2,
  })
}

function getMacros (fileName) {
  const filePath = `${MACROS_PATH}${fileName}.${EXT}`

  function renderMacro (name, caller, props, ...rest) {
    const importString = `{% from "${filePath}" import ${name} %}`
    const args = rest.length ? `,${[...rest].map(JSON.stringify)}` : ''
    let macroOutput

    if (caller) {
      macroOutput = nunjucks.renderString(`
        ${importString}
        {% call ${name}(${JSON.stringify(props, undefined, 1)}${args}) %}
          ${caller.join(' ')}
        {% endcall %}
      `)
    } else {
      macroOutput = nunjucks.renderString(`${importString} {{ ${name}(${JSON.stringify(props)}${args}) }}`)
    }

    return normaliseHtml(macroOutput)
  }

  return {
    render (macroName, props, ...rest) {
      return renderMacro(macroName, null, props, ...rest)
    },

    renderWithCaller (macroName, caller, props, ...rest) {
      return renderMacro(macroName, caller, props, ...rest)
    },

    renderToDom (macroName, props, ...rest) {
      const macroOutput = this.render(macroName, props, ...rest)
      return (new JSDOM(macroOutput)).window.document.body.firstElementChild
    },

    renderWithCallerToDom (macroName, props, ...rest) {
      return function (...caller) {
        if (!caller.length) { return null }
        const macroOutput = this.renderWithCaller(macroName, caller, props, ...rest)
        return (new JSDOM(macroOutput)).window.document.body.firstElementChild
      }.bind(this)
    },
  }
}

const renderComponent = (name, input) => {
  const componentPath = `${COMPONENTS_PATH}${name}.${EXT}`
  return normaliseHtml(nunjucks.render(componentPath, input))
}

const renderComponentToDom = (name, input) => {
  const renderedComponent = renderComponent(name, input)
  return (new JSDOM(renderedComponent)).window.document.body.firstElementChild
}

const expectComponent = (name, input, expected) => {
  // Normalise HTML whitespace, to make diffing simpler
  expect(
    renderComponent(name, input)
{'fraction_non_alphanumeric': 0.15117328519855597, 'fraction_numerical': 0.00157942238267148, 'mean_word_length': 3.9753086419753085, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6175688', 'n_tokens_mistral': 1437, 'n_tokens_neox': 1386, 'n_words': 302}