text: var parser = require('../');
  var test = require('tape');
  
  test('output event', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      '# is true',
      'ok 1 true value',
      'ok 2 true value',
      '1..2'
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
  
      t.deepEqual(output, {
        asserts: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' },
          { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' }
        ],
        fail: [],
        pass: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' },
          { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' }
        ],
        results: [],
        tests: [
          { name: 'is true', number: 1, raw: '# is true', type: 'test' }
        ],
        versions: [],
        comments: [],
        plans: [{ from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }],
        errors: []
      }, 'output data');
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('output callback', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      '# is true',
      'ok 1 true value',
      'ok 2 true value',
      '1..2'
    ];
  
    var p = parser(function (err, output) {
  
      t.deepEqual(output, {
        asserts: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' },
          { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' }
        ],
        fail: [],
        pass: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' },
          { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' }
        ],
        results: [],
        tests: [
          { name: 'is true', number: 1, raw: '# is true', type: 'test' }
        ],
        versions: [],
        comments: [],
        plans: [{ from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }],
        errors: []
      }, 'output data');
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('tests', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      '# is true',
      'ok 1 true value',
      'ok 2 true value'
    ];
  
    var p = parser();
  
    p.on('test', function (test) {
  
      t.deepEqual(test, {
        type: 'test',
        name: 'is true',
        raw: '# is true',
        number: 1
      }, 'test is parsed');
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('asserts', function (t) {
  
    t.plan(2);
  
    var mockTap = [
      '# is true',
      'ok 1 true value',
      'ok 2 true value'
    ];
  
    var p = parser();
  
    var asserts = [];
    p.on('assert', function (assert) {
      asserts.push(assert);
    });
  
    p.on('output', function () {
  
      t.deepEqual(asserts[0], {
        name: 'true value',
        number: 1,
        ok: true,
        raw: 'ok 1 true value',
        test: 1,
        type: 'assert'
      }, 'assert 1')
      t.deepEqual(asserts[1], {
        name: 'true value',
        number: 2,
        ok: true,
        raw: 'ok 2 true value',
        test: 1,
        type: 'assert'
      }, 'assert 2')
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('results', function (t) {
  
    t.plan(3);
  
    var mockTap = [
      '# tests 15',
      '# pass  13',
      '# fail  2'
    ];
  
    var p = parser();
  
    var results = [];
    p.on('result', function (result) {
      results.push(result);
    });
  
    p.on('output', function () {
  
      t.deepEqual(results[0], {
        count: '15',
        name: 'tests',
        raw: '# tests 15',
        type: 'result'
      }, 'tests');
  
      t.deepEqual(results[1], {
        count: '13',
        name: 'pass',
        raw: '# pass  13',
        type: 'result'
      }, 'pass');
  
      t.deepEqual(results[2], {
        count: '2',
        name: 'fail',
        raw: '# fail  2',
        type: 'result'
      }, 'fail');
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('version', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      'TAP version 13'
    ];
  
    var p = parser();
  
    var results = [];
    p.on('version', function (version) {
  
      t.deepEqual(version, {
        raw: 'TAP version 13',
        type: 'version'
      }, 'version data');
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('pass', function (t) {
  
    t.plan(2);
  
    var mockTap = [
      '# is true',
      'ok 1 true value',
      'ok 2 true value'
    ];
  
    var p = parser();
  
    var passes = [];
    p.on('pass', function (pass) {
  
      passes.push(pass);
    });
  
    p.on('output', function () {
  
      t.deepEqual(passes[0], {
        name: 'true value',
        number: 1,
        ok: true,
        raw: 'ok 1 true value',
        test: 1,
        type: 'assert'
      }, 'pass 1');
  
      t.deepEqual(passes[1], {
        name: 'true value',
        number: 2,
        ok: true,
        raw: 'ok 2 true value',
        test: 1,
        type: 'assert'
      }, 'pass 2');
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('failed assertion', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      "TAP version 13",
      "# is true",
      "ok 1 true value",
      "ok 2 true value",
      "not ok 3 strings match",
      "  ---",
      "    operator: equal",
      "    expected: 'you'",
      "    actual:   'me'",
      "    at: Test.<anonymous> (/Users/scott/www/divshot/divshot-cli/test/index.js:8:5)",
      "  ...",
      "not ok 4 plan != count",
      "  ---",
      "    operator: fail",
      "    expected: 4",
      "    actual:   3",
      "  ...",
      "ok 5 true value",
      "not ok 6 - failure",
      "not ok 15 - item not found",
      "",
      "1..15",
    ];
  
    var fails = [];
    var p = parser(function () {
  
      t.deepEqual(
        fails,
        [
          {
            error: {
              actual: 'me',
              at: {
                character: '5',
                file: '/Users/scott/www/divshot/divshot-cli/test/index.js',
                line: '8'
              },
              expected: 'you',
              operator: 'equal',
              raw: [
                "    operator: equal",
                "    expected: 'you'",
                "    actual:   'me'",
                "    at: Test.<anonymous> (/Users/scott/www/divshot/divshot-cli/test/index.js:8:5)"
              ].join('\n')
            },
            name: 'strings match',
            number: 3,
            ok: false,
            raw: 'not ok 3 strings match',
            test: 1,
            type: 'assert'
          },
          {
            error: {
              actual: '3',
              expected: '4',
              operator: 'count',
              raw: [
                "    operator: fail",
                "    expected: 4",
                "    actual:   3"
              ].join('\n')
            },
            name: 'plan != count',
            number: 4,
            ok: false,
            raw: 'not ok 4 plan != count',
            test: 1,
            type: 'plan'
          },
          {
            error: { actual: undefined, expected: undefined, operator: undefined, at: undefined },
            name: 'failure',
            number: 6,
            ok: false,
            raw: 'not ok 6 - failure',
            test: 1,
            type: 'assert'
          },
          {
            error: { actual: undefined, expected: undefined, operator: undefined, at: undefined },
            name: 'item not found',
            number: 15,
            ok: false,
            raw: 'not ok 15 - item not found',
            test: 1,
            type: 'assert'
          }
        ],
        'fails'
      );
    });
  
    p.on('fail', function (fail) {
  
      fails.push(fail);
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('plan', function (t) {
  
    var mockTap = [
      '1..2',
    ];
  
    var plans = [];
    var p = parser(function () {
      t.deepEqual(plans, [
        { from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }
      ]);
      t.end();
    });
  
    p.on('plan', function (plan) {
      plans.push(plan);
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  
  // NOTE: comments output the same as test names.
  // This makes it very difficult to parse them.
  // Ignoring them for now. Just don't use comments.
  test('comments');
  
  test('generic output', function (t) {
  
    var mockTap = [
      "TAP version 13",
      "# is true",
      "ok 1 true value",
      "not ok 2 strings match",
      "  ---",
      "    operator: equal",
      "    expected: 'you'",
      "    actual:   'me'",
      "    at: Test.<anonymous> (/Users/scott/www/divshot/divshot-cli/test/index.js:8:5)",
      "  ...",
      "ok 3 true value",
      "this is a console log",
      "# false values",
      "ok 4 should be false",
      "ok 5 false value"
    ];
  
    var comments = [];
    var p = parser(function (err, output) {
  
      t.deepEqual(
        comments,
        [
          {
            type: 'comment',
            raw: 'this is a console log',
            test: 1
          }
        ],
        'one comment'
      );
      t.end();
    });
  
    p.on('comment', function (comment) {
  
      comments.push(comment);
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('handles HTTP error source', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      "TAP version 13",
      "# is true",
      "ok 1 true value",
      "ok 2 true value",
      "not ok 3 strings match",
      "  ---",
      "    operator: equal",
      "    expected: 'you'",
      "    actual:   'me'",
      "    at: Test.<anonymous> (http://localhost:9966/index.js:8:5)",
      "  ...",
      "not ok 15 plan != count",
      "  ---",
      "    operator: fail",
      "    expected: 4",
      "    actual:   3",
      "  ...",
      "",
      "1..15",
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
      var assert = output.fail[0];
      t.deepEqual(assert.error.at, { character: '5', file: 'http://localhost:9966/index.js', line: '8' });
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('handles raw error string', function (t) {
  
    t.plan(1);
  
    var rawLines = [
      "    operator: deepEqual",
      "    expected:",
      "      { 0: 0, 1: 0, 10: 0, 11: 255, 12: 0, 13: 0, 14: 0, 15: 255, 2: 0, 3: 221, 4: 0, 5: 0, 6: 0, 7: 255, 8: 0, 9: 0 }",
      "    actual:",
      "      { 0: 0, 1: 0, 10: 0, 11: 255, 12: 0, 13: 0, 14: 0, 15: 255, 2: 0, 3: 255, 4: 0, 5: 0, 6: 0, 7: 255, 8: 0, 9: 0 }",
      "    at: Test.<anonymous> (http://localhost:9966/index.js:8:5)"
    ];
  
    var mockTap = [
      "TAP version 13",
      "# is true",
      "ok 1 true value",
      "ok 2 true value",
      "not ok 3 arrays match",
      "  ---"
    ].concat(rawLines).concat([
      "  ...",
      "not ok 15 plan != count",
      "  ---",
      "    operator: fail",
      "    expected: 4",
      "    actual:   3",
      "  ...",
      "",
      "1..15",
    ]);
  
    var p = parser();
  
    p.on('output', function (output) {
      var assert = output.fail[0];
      t.deepEqual(assert.error.raw, rawLines.join('\n'));
    });
  
    mockTap.forEach(function (line) {
  
      p.write(line + '\n');
    });
    p.end();
  });
  
  test('handles multiline error string with |-', function (t) {
  
    t.plan(2);
  
    var mockTap = [
      "TAP version 13",
      "# is true",
      "ok 1 true value",
      "not ok 2 object deep equal with cross",
      "  ---",
      "    operator: deepEqual",
      "    expected: |-",
      "      { a: 1, b: 2 }",
      "    actual: |-",
      "      { a: 1, b: 3 }",
      "    at: Test.<anonymous> (/Users/germ/Projects/a/b/test.js:7:5)",
      "  ...",
      "",
      "1..2",
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
      var assert = output.fail[0];
      t.equal(assert.error.expected, '{ a: 1, b: 2 }');
      t.equal(assert.error.actual, '{ a: 1, b: 3 }');
    });
  
    mockTap.forEach(function (line) {
      p.write(line + '\n');
    });
    p.end();
  
  });
  
  test('handles multiline error stack with |-', function (t) {
  
    t.plan(2);
  
    var mockTap = [
      "TAP version 13",
      "# promise error",
      "not ok 1 TypeError: foo",
      "  ---",
      "    operator: error",
      "    expected: |-",
      "      undefined",
      "    actual: |-",
      "      [TypeError: foo]",
      "    at: process._tickCallback (internal/process/next_tick.js:103:7)",
      "    stack: |-",
      "      TypeError: foo",
      "          at throwError (/Users/germ/Projects/a/b/test.js:17:9)",
      "          at Promise.resolve.then (/Users/germ/Projects/a/b/test.js:24:5)",
      "          at process._tickCallback (internal/process/next_tick.js:103:7)",
      "  ...",
      "",
      "1..1",
      "# tests 1",
      "# pass  0",
      "# fail  1"
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
      var assert = output.fail[0];
      t.equal(assert.error.stack, 'TypeError: foo\n'
        + 'at throwError (/Users/germ/Projects/a/b/test.js:17:9)\n'
        + 'at Promise.resolve.then (/Users/germ/Projects/a/b/test.js:24:5)\n'
        + 'at process._tickCallback (internal/process/next_tick.js:103:7)\n'
      );
      t.equal(assert.error.raw, '    operator: error\n'
        + '    expected: |-\n'
        + '      undefined\n'
        + '    actual: |-\n'
        + '      [TypeError: foo]\n'
        + '    at: process._tickCallback (internal/process/next_tick.js:103:7)\n'
        + '    stack: |-\n'
        + 'TypeError: foo\n'
        + 'at throwError (/Users/germ/Projects/a/b/test.js:17:9)\n'
        + 'at Promise.resolve.then (/Users/germ/Projects/a/b/test.js:24:5)\n'
        + 'at process._tickCallback (internal/process/next_tick.js:103:7)'
      );
    });
  
    mockTap.forEach(function (line) {
      p.write(line + '\n');
    });
    p.end();
  
  });
  
  test('output without plan', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      "# is true",
      "ok 1 true value",
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
  
      t.deepEqual(output, {
        asserts: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }
        ],
        fail: [],
        pass: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }
        ],
        results: [],
        tests: [
          { name: 'is true', number: 1, raw: '# is true', type: 'test' }
        ],
        versions: [],
        comments: [],
        plans: [],
        errors: [
          { message: 'no plan provided', type: 'error' }
        ]
      }, 'output data with empty plans and no plan provided');
    });
  
    mockTap.forEach(function (line) {
      p.write(line + '\n');
    });
    p.end();
  
  });
  
  test('output with assert count and plan mismatch', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      "# is true",
      "ok 1 true value",
      "1..2",
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
  
      t.deepEqual(output, {
        asserts: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }
        ],
        fail: [],
        pass: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }
        ],
        results: [],
        tests: [
          { name: 'is true', number: 1, raw: '# is true', type: 'test' }
        ],
        versions: [],
        comments: [],
        plans: [
          { from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }
        ],
        errors: [
          { message: 'incorrect number of assertions made', type: 'error' }
        ]
      }, 'output data with empty assert count and plan mismatch error');
    });
  
    mockTap.forEach(function (line) {
      p.write(line + '\n');
    });
    p.end();
  
  });
  
  test('output with plan end and assertion number mismatch', function (t) {
  
    t.plan(1);
  
    var mockTap = [
      "# is true",
      "ok 1 true value",
      'ok 3 true value',
      "1..2",
    ];
  
    var p = parser();
  
    p.on('output', function (output) {
  
      t.deepEqual(output, {
        asserts: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' },
          { name: 'true value', number: 3, ok: true, raw: 'ok 3 true value', test: 1, type: 'assert' }
        ],
        fail: [],
        pass: [
          { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' },
          { name: 'true value', number: 3, ok: true, raw: 'ok 3 true value', test: 1, type: 'assert' }
        ],
        results: [],
        tests: [
          { name: 'is true', number: 1, raw: '# is true', type: 'test' }
        ],
        versions: [],
        comments: [],
        plans: [
          { from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }
        ],
        errors: [
          { message: 'last assertion number does not equal the plan end', type: 'error' }
        ]
      }, 'output data with plan end error');
    });
  
    mockTap.forEach(function (line) {
      p.write(line + '\n');
    });
    p.end();
  
  });
  