function runTest(index, host, doc) {
  var options = tests[index] = tests[index]();
  var holder = doc.createElement('div');
  holder.id = options.name;
  var body = doc.body;
  body.appendChild(holder);
  holder.innerHTML = options.template;

  info('Running ' + options.name);
  template(holder, options.data, options.options);

  if (typeof options.result == 'string') {
    is(holder.innerHTML, options.result, options.name);
  }
  else {
    ok(holder.innerHTML.match(options.result) != null,
       options.name + ' result=\'' + holder.innerHTML + '\'');
  }

  if (options.also) {
    options.also(options);
  }

  function runNextTest() {
    index++;
    if (index < tests.length) {
      runTest(index, host, doc);
    }
    else {
      finished(host);
    }
  }

  if (options.later) {
    var ais = is.bind(this);

    function createTester(holder, options) {
      return () => {
        ais(holder.innerHTML, options.later, options.name + ' later');
        runNextTest();
      };
    }

    executeSoon(createTester(holder, options));
  }
  else {
    runNextTest();
  }
}
function runTest(index, host, doc) {
  const options = tests[index] = tests[index]();
  const holder = doc.createElement("div");
  holder.id = options.name;
  const body = doc.body;
  body.appendChild(holder);
  // eslint-disable-next-line no-unsanitized/property
  holder.innerHTML = options.template;

  info("Running " + options.name);
  template(holder, options.data, options.options);

  if (typeof options.result == "string") {
    is(holder.innerHTML, options.result, options.name);
  } else {
    ok(holder.innerHTML.match(options.result) != null,
       options.name + " result='" + holder.innerHTML + "'");
  }

  if (options.also) {
    options.also(options);
  }

  function runNextTest() {
    index++;
    if (index < tests.length) {
      runTest(index, host, doc);
    } else {
      finished(host);
    }
  }

  if (options.later) {
    const ais = is.bind(this);

    function createTester(testHolder, testOptions) {
      return () => {
        ais(testHolder.innerHTML, testOptions.later, testOptions.name + " later");
        runNextTest();
      };
    }

    executeSoon(createTester(holder, options));
  } else {
    runNextTest();
  }
}