text: 'use strict';
  
  var tap = require('tap');
  
  var stripFullStack = require('./common').stripFullStack;
  var runProgram = require('./common').runProgram;
  
  var nodeVersion = process.versions.node;
  var majorVersion = nodeVersion.split('.')[0];
  
  if (Number(majorVersion) < 8) {
      process.exit(0); // eslint-disable-line no-process-exit
  }
  
  tap.test('async1', function (t) {
      runProgram('async-await', 'async1.js', function (r) {
          t.same(r.stdout.toString('utf8'), [
              'TAP version 13',
              '# async1',
              'ok 1 before await',
              'ok 2 after await',
              '',
              '1..2',
              '# tests 2',
              '# pass  2',
              '',
              '# ok'
          ].join('\n') + '\n\n');
          t.same(r.exitCode, 0);
          t.same(r.stderr.toString('utf8'), '');
          t.end();
      });
  });
  
  tap.test('async2', function (t) {
      runProgram('async-await', 'async2.js', function (r) {
          var stdout = r.stdout.toString('utf8');
          var lines = stdout.split('\n').filter(function (line) {
              return !(/^(\s+)at(\s+)<anonymous>$/).test(line);
          });
  
          t.same(stripFullStack(lines.join('\n')), [
              'TAP version 13',
              '# async2',
              'ok 1 before await',
              'not ok 2 after await',
              '  ---',
              '    operator: ok',
              '    expected: true',
              '    actual:   false',
              '    at: Test.myTest ($TEST/async-await/async2.js:$LINE:$COL)',
              '    stack: |-',
              '      Error: after await',
              '          [... stack stripped ...]',
              '          at Test.myTest ($TEST/async-await/async2.js:$LINE:$COL)',
              '  ...',
              '',
              '1..2',
              '# tests 2',
              '# pass  1',
              '# fail  1',
              '',
              ''
          ]);
          t.same(r.exitCode, 1);
          t.same(r.stderr.toString('utf8'), '');
          t.end();
      });
  });
  
  tap.test('async3', function (t) {
      runProgram('async-await', 'async3.js', function (r) {
          t.same(r.stdout.toString('utf8'), [
              'TAP version 13',
              '# async3',
              'ok 1 before await',
              'ok 2 after await',
              '',
              '1..2',
              '# tests 2',
              '# pass  2',
              '',
              '# ok'
          ].join('\n') + '\n\n');
          t.same(r.exitCode, 0);
          t.same(r.stderr.toString('utf8'), '');
          t.end();
      });
  });
  
  tap.test('async4', function (t) {
      runProgram('async-await', 'async4.js', function (r) {
          t.same(stripFullStack(r.stdout.toString('utf8')), [
              'TAP version 13',
              '# async4',
              'ok 1 before await',
              'not ok 2 Error: oops',
              '  ---',
              '    operator: error',
              '    at: Test.myTest ($TEST/async-await/async4.js:$LINE:$COL)',
              '    stack: |-',
              '      Error: oops',
              '          at Timeout.myTimeout [as _onTimeout] ($TEST/async-await/async4.js:$LINE:$COL)',
              '          [... stack stripped ...]',
              '  ...',
              '',
              '1..2',
              '# tests 2',
              '# pass  1',
              '# fail  1',
              '',
              ''
          ]);
          t.same(r.exitCode, 1);
          t.same(r.stderr.toString('utf8'), '');
          t.end();
      });
  });
  
  tap.test('async5', function (t) {
      runProgram('async-await', 'async5.js', function (r) {
          t.same(stripFullStack(r.stdout.toString('utf8')), [
              'TAP version 13',
              '# async5',
              'ok 1 before server',
              'ok 2 after server',
              'ok 3 before request',
              'ok 4 after request',
              'ok 5 res.statusCode is 200',
              'not ok 6 .end() already called: mockDb.state is new',
              '  ---',
              '    operator: fail',
              '    at: Timeout._onTimeout ($TEST/async-await/async5.js:$LINE:$COL)',
              '    stack: |-',
              '      Error: .end() already called: mockDb.state is new',
              '          [... stack stripped ...]',
              '          at Timeout._onTimeout ($TEST/async-await/async5.js:$LINE:$COL)',
              '          [... stack stripped ...]',
              '  ...',
              'not ok 7 .end() already called: error on close',
              '  ---',
              '    operator: fail',
              '    at: Server.<anonymous> ($TEST/async-await/async5.js:$LINE:$COL)',
              '    stack: |-',
              '      Error: .end() already called: error on close',
              '          [... stack stripped ...]',
              '          at Server.<anonymous> ($TEST/async-await/async5.js:$LINE:$COL)',
              '          [... stack stripped ...]',
              '  ...',
              'not ok 8 .end() already called',
              '  ---',
              '    operator: fail',
              '    at: Server.<anonymous> ($TEST/async-await/async5.js:$LINE:$COL)',
              '    stack: |-',
              '      Error: .end() already called',
              '          [... stack stripped ...]',
              '          at Server.<anonymous> ($TEST/async-await/async5.js:$LINE:$COL)',
              '          [... stack stripped ...]',
              '  ...',
              '',
              '1..8',
              '# tests 8',
              '# pass  5',
              '# fail  3',
              '',
              ''
          ]);
          t.same(r.exitCode, 1);
          t.same(r.stderr.toString('utf8'), '');
          t.end();
      });
  });
  
  tap.test('sync-error', function (t) {
      runProgram('async-await', 'sync-error.js', function (r) {
          t.same(stripFullStack(r.stdout.toString('utf8')), [
              'TAP version 13',
              '# sync-error',
              'ok 1 before throw',
              ''
          ]);
          t.same(r.exitCode, 1);
  
          var stderr = r.stderr.toString('utf8');
          var lines = stderr.split('\n');
          lines = lines.filter(function (line) {
              return !(/\(timers.js:/).test(line)
                  && !(/\(internal\/timers.js:/).test(line)
                  && !(/Immediate\.next/).test(line);
          });
          stderr = lines.join('\n');
  
          t.same(stripFullStack(stderr), [
              '$TEST/async-await/sync-error.js:7',
              '    throw new Error(\'oopsie\');',
              '    ^',
              '',
              'Error: oopsie',
              '    at Test.myTest ($TEST/async-await/sync-error.js:$LINE:$COL)',
              '    at Test.bound [as _cb] ($TAPE/lib/test.js:$LINE:$COL)',
              '    at Test.run ($TAPE/lib/test.js:$LINE:$COL)',
              '    at Test.bound [as run] ($TAPE/lib/test.js:$LINE:$COL)',
              ''
          ]);
          t.end();
      });
  });
  
  tap.test('async-error', function (t) {
      runProgram('async-await', 'async-error.js', function (r) {
          var stdout = r.stdout.toString('utf8');
          var lines = stdout.split('\n');
          lines = lines.filter(function (line) {
              return !(/^(\s+)at(\s+)<anonymous>$/).test(line);
          });
          stdout = lines.join('\n');
  
          t.same(stripFullStack(stdout), [
              'TAP version 13',
              '# async-error',
              'ok 1 before throw',
              'not ok 2 Error: oopsie',
              '  ---',
              '    operator: error',
              '    stack: |-',
              '      Error: oopsie',
              '          at Test.myTest ($TEST/async-await/async-error.js:$LINE:$COL)',
              '          [... stack stripped ...]',
              '  ...',
              '',
              '1..2',
              '# tests 2',
              '# pass  1',
              '# fail  1',
              '',
              ''
          ]);
          t.same(r.exitCode, 1);
  
          var stderr = r.stderr.toString('utf8');
          var stderrLines = stderr.split('\n');
          stderrLines = stderrLines.filter(function (line) {
              return !(/\(timers.js:/).test(line)
                  && !(/\(internal\/timers.js:/).test(line)
                  && !(/Immediate\.next/).test(line);
          });
          t.same(stderrLines.join('\n'), '');
          t.end();
      });
  });
  
  tap.test('async-bug', function (t) {
      runProgram('async-await', 'async-bug.js', function (r) {
          var stdout = r.stdout.toString('utf8');
          var lines = stdout.split('\n');
          lines = lines.filter(function (line) {
              return !(/^(\s+)at(\s+)<anonymous>$/).test(line);
          });
          stdout = lines.join('\n');
  
          t.same(stripFullStack(stdout), [
              'TAP version 13',
              '# async-error',
              'ok 1 before throw',
              'ok 2 should be strictly equal',
              'not ok 3 TypeError: Cannot read property \'length\' of null',
              '  ---',
              '    operator: error',
              '    stack: |-',
              '      TypeError: Cannot read property \'length\' of null',
              '          at myCode ($TEST/async-await/async-bug.js:$LINE:$COL)',
              '          at Test.myTest ($TEST/async-await/async-bug.js:$LINE:$COL)',
              '  ...',
              '',
              '1..3',
              '# tests 3',
              '# pass  2',
              '# fail  1',
              '',
              ''
          ]);
          t.same(r.exitCode, 1);
  
          var stderr = r.stderr.toString('utf8');
  
          t.same(stderr, '');
          t.end();
      });
  });
  