'use strict';

const escape = require('js-string-escape');

function render(errors) {
  return errors.map(error => `${error.line}:${error.column} - ${error.message} (${error.ruleId})`).join('\n');
}

function qunit(relativePath, errors, results) {
  let passed = hasPassed(results);
  let message = createAssertionMessage(relativePath, results);

  return `QUnit.module('ESLint | ${escape(relativePath)}');\n` +
    `QUnit.test('should pass ESLint', function(assert) {\n` +
    `  assert.expect(1);\n` +
    `  assert.ok(${passed}, '${escape(message)}');\n` +
    `});\n`;
}

qunit.testOnly = function(relativePath, errors, results) {
  let passed = hasPassed(results);
  let message = createAssertionMessage(relativePath, results);

  return `QUnit.test('${escape(relativePath)}', function(assert) {\n` +
    `  assert.expect(1);\n` +
    `  assert.ok(${passed}, '${escape(message)}');\n` +
    `});\n`;
};

function mocha(relativePath, errors, results) {
  let passed = hasPassed(results);
  let message = createAssertionMessage(relativePath, results);

  return (
    `describe('ESLint | ${escape(relativePath)}', function() {\n` +
    `  it('should pass ESLint', function() {\n` +
    mochaAssertion(passed, message) +
    `  });\n` +
    `});\n`
  );
}

mocha.testOnly = function(relativePath, errors, results) {
  let passed = hasPassed(results);
  let message = createAssertionMessage(relativePath, results);

  return (
    `  it('${escape(relativePath)}', function() {\n` +
    mochaAssertion(passed, message) +
    `  });\n`
  );
};

function mochaAssertion(passed, message) {
  if (passed) {
    return `    // ESLint passed\n`;
  }

  return (
      `    // ESLint failed\n`+
      `    var error = new chai.AssertionError('${escape(message)}');\n` +
      `    error.stack = undefined;\n` +
      `    throw error;\n`
  );
}

function hasPassed(results) {
  return !results.errorCount || results.errorCount.length === 0;
}

function createAssertionMessage(relativePath, results) {
  let message = `${relativePath} should pass ESLint`;

  if (results.messages) {
    message += `\n\n${render(results.messages)}`;
  }

  return message;
}

module.exports = { qunit, mocha };

@@ -898,24 +898,163 @@
 %7D);%5Cn%60;%0A%7D;%0A%0A
+qunit.header = function(group) %7B%0A  return %60QUnit.module('ESLint %7C $%7Bescape(group)%7D');%5Cn%60;%0A%7D;%0A%0Aqunit.footer = function() %7B%0A  return '';%0A%7D;%0A%0A
 function moc
@@ -1672,24 +1672,176 @@
 n%60%0A  );%0A%7D;%0A%0A
+mocha.header = function(group) %7B%0A  return %60describe('ESLint %7C $%7Bescape(group)%7D', function() %7B%5Cn%60;%0A%7D;%0A%0Amocha.footer = function() %7B%0A  return '%7D);%5Cn';%0A%7D;%0A%0A
 function moc

Add header/footer() functions