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 COMPONENT_EXT = 'njk'

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

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

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

const renderComponentToDom = (name, input) => {
  const renderedComponent = renderComponent(name, input)
  return (new JSDOM(renderedComponent)).window.document.body.querySelector('body>:first-child')
}

const expectComponent = (name, input, expected) => {
  // Normalise HTML whitespace, to make diffing simpler
  expect(
    renderComponent(name, input)
  ).to.equal(
    normaliseHtml(expected)
  )
}

function domTokenToArray (obj) {
  let array = []
  // iterate backwards ensuring that length is an UInt32
  for (let i = obj.length >>> 0; i--;) {
    array[i] = obj[i]
  }
  return array
}

module.exports = {
  expectComponent,
  renderComponentToDom,
  domTokenToArray,
}

@@ -352,26 +352,47 @@
 '%0Aconst 
-COMPONENT_
+MACROS_PATH = '_macros/'%0Aconst 
 EXT = 'n
@@ -596,24 +596,572 @@
  2,%0A  %7D)%0A%7D%0A%0A
+function getMacros (fileName) %7B%0A  const filePath = %60$%7BMACROS_PATH%7D$%7BfileName%7D.$%7BEXT%7D%60%0A%0A  return %7B%0A    render (macroName, props) %7B%0A      const importString = %60%7B%25 from %22$%7BfilePath%7D%22 import $%7BmacroName%7D %25%7D%60%0A      const macroOutput = nunjucks.renderString(%60$%7BimportString%7D %7B%7B $%7BmacroName%7D($%7BJSON.stringify(props)%7D) %7D%7D%60)%0A      return normaliseHtml(macroOutput)%0A    %7D,%0A%0A    renderToDom (macroName, props) %7B%0A      const macroOutput = this.render(macroName, props)%0A      return (new JSDOM(macroOutput)).window.document.body.firstElementChild%0A    %7D,%0A  %7D%0A%7D%0A%0A
 const render
@@ -1248,18 +1248,8 @@
 %7D.$%7B
-COMPONENT_
 EXT%7D
@@ -1485,42 +1485,25 @@
 ody.
-querySelector('body%3E:first-c
+firstElementC
 hild
-')
 %0A%7D%0A%0A
@@ -1933,16 +1933,29 @@
 ponent,%0A
+  getMacros,%0A
   render

Add new helper for rendering macros in tests