// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// dart2js chain tests are separated out because dart2js stack traces are
// inconsistent due to inlining and browser differences. These tests don't
// assert anything about the content of the traces, just the number of traces in
// a chain.
@TestOn('js')

import 'dart:async';

import 'package:stack_trace/stack_trace.dart';
import 'package:test/test.dart';

import 'utils.dart';

void main() {
  group('capture() with onError catches exceptions', () {
    test('thrown synchronously', () async {
      var chain = await captureFuture(() => throw 'error');
      expect(chain.traces, hasLength(1));
    });

    test('thrown in a microtask', () async {
      var chain = await captureFuture(() => inMicrotask(() => throw 'error'));
      expect(chain.traces, hasLength(2));
    });

    test('thrown in a one-shot timer', () async {
      var chain =
          await captureFuture(() => inOneShotTimer(() => throw 'error'));
      expect(chain.traces, hasLength(2));
    });

    test('thrown in a periodic timer', () async {
      var chain =
          await captureFuture(() => inPeriodicTimer(() => throw 'error'));
      expect(chain.traces, hasLength(2));
    });

    test('thrown in a nested series of asynchronous operations', () async {
      var chain = await captureFuture(() {
        inPeriodicTimer(() {
          inOneShotTimer(() => inMicrotask(() => throw 'error'));
        });
      });

      expect(chain.traces, hasLength(4));
    });

    test('thrown in a long future chain', () async {
      var chain = await captureFuture(() => inFutureChain(() => throw 'error'));

      // Despite many asynchronous operations, there's only one level of
      // nested calls, so there should be only two traces in the chain. This
      // is important; programmers expect stack trace memory consumption to be
      // O(depth of program), not O(length of program).
      expect(chain.traces, hasLength(2));
    });

    test('thrown in new Future()', () async {
      var chain = await captureFuture(() => inNewFuture(() => throw 'error'));
      expect(chain.traces, hasLength(3));
    });

    test('thrown in new Future.sync()', () async {
      var chain = await captureFuture(() {
        inMicrotask(() => inSyncFuture(() => throw 'error'));
      });

      expect(chain.traces, hasLength(3));
    });

    test('multiple times', () {
      var completer = new Completer();
      var first = true;

      Chain.capture(() {
        inMicrotask(() => throw 'first error');
        inPeriodicTimer(() => throw 'second error');
      }, onError: (error, chain) {
        try {
          if (first) {
            expect(error, equals('first error'));
            expect(chain.traces, hasLength(2));
            first = false;
          } else {
            expect(error, equals('second error'));
            expect(chain.traces, hasLength(2));
            completer.complete();
          }
        } catch (error, stackTrace) {
          completer.completeError(error, stackTrace);
        }
      });

      return completer.future;
    });

    test('passed to a completer', () async {
      var trace = new Trace.current();
      var chain = await captureFuture(() {
        inMicrotask(() => completerErrorFuture(trace));
      });

      expect(chain.traces, hasLength(3));

      // The first trace is the trace that was manually reported for the
      // error.
      expect(chain.traces.first.toString(), equals(trace.toString()));
    });

    test('passed to a completer with no stack trace', () async {
      var chain = await captureFuture(() {
        inMicrotask(() => completerErrorFuture());
      });

      expect(chain.traces, hasLength(2));
    });

    test('passed to a stream controller', () async {
      var trace = new Trace.current();
      var chain = await captureFuture(() {
        inMicrotask(() => controllerErrorStream(trace).listen(null));
      });

      expect(chain.traces, hasLength(3));
      expect(chain.traces.first.toString(), equals(trace.toString()));
    });

    test('passed to a stream controller with no stack trace', () async {
      var chain = await captureFuture(() {
        inMicrotask(() => controllerErrorStream().listen(null));
      });

      expect(chain.traces, hasLength(2));
    });

    test('and relays them to the parent zone', () {
      var completer = new Completer();

      runZoned(() {
        Chain.capture(() {
          inMicrotask(() => throw 'error');
        }, onError: (error, chain) {
          expect(error, equals('error'));
          expect(chain.traces, hasLength(2));
          throw error;
        });
      }, onError: (error, chain) {
        try {
          expect(error, equals('error'));
          expect(chain, new isInstanceOf<Chain>());
          expect(chain.traces, hasLength(2));
          completer.complete();
        } catch (error, stackTrace) {
          completer.completeError(error, stackTrace);
        }
      });

      return completer.future;
    });
  });

  test('capture() without onError passes exceptions to parent zone', () {
    var completer = new Completer();

    runZoned(() {
      Chain.capture(() => inMicrotask(() => throw 'error'));
    }, onError: (error, chain) {
      try {
        expect(error, equals('error'));
        expect(chain, new isInstanceOf<Chain>());
        expect(chain.traces, hasLength(2));
        completer.complete();
      } catch (error, stackTrace) {
        completer.completeError(error, stackTrace);
      }
    });

    return completer.future;
  });

  group('current() within capture()', () {
    test('called in a microtask', () async {
      var completer = new Completer();
      Chain.capture(() {
        inMicrotask(() => completer.complete(new Chain.current()));
      });

      var chain = await completer.future;
      expect(chain.traces, hasLength(2));
    });

    test('called in a one-shot timer', () async {
      var completer = new Completer();
      Chain.capture(() {
        inOneShotTimer(() => completer.complete(new Chain.current()));
      });

      var chain = await completer.future;
      expect(chain.traces, hasLength(2));
    });

    test('called in a periodic timer', () async {
      var completer = new Completer();
      Chain.capture(() {
        inPeriodicTimer(() => completer.complete(new Chain.current()));
      });

      var chain = await completer.future;
      expect(chain.traces, hasLength(2));
    });

    test('called in a nested series of asynchronous operations', () async {
      var completer = new Completer();
      Chain.capture(() {
        inPeriodicTimer(() {
          inOneShotTimer(() {
            inMicrotask(() => completer.complete(new Chain.current()));
          });
        });
      });

      var chain = await completer.future;
      expect(chain.traces, hasLength(4));
    });

    test('called in a long future chain', () async {
      var completer = new Completer();
      Chain.capture(() {
        inFutureChain(() => completer.complete(new Chain.current()));
      });

      var chain = await completer.future;
      expect(chain.traces, hasLength(2));
    });
  });

  test(
      'current() outside of capture() returns a chain wrapping the current '
      'trace', () {
    // The test runner runs all tests with chains enabled.
    return Chain.disable(() async {
      var completer = new Completer();
      inMicrotask(() => completer.complete(new Chain.current()));

      var chain = await completer.future;
      // Since the chain wasn't loaded within [Chain.capture], the full stack
      // chain isn't available and it just returns the current stack when
      // called.
      expect(chain.traces, hasLength(1));
    });
  });

  group('forTrace() within capture()', () {
    test('called for a stack trace from a microtask', () async {
      var chain = await Chain.capture(() {
        return chainForTrace(inMicrotask, () => throw 'error');
      });

      // Because [chainForTrace] has to set up a future chain to capture the
      // stack trace while still showing it to the zone specification, it adds
      // an additional level of async nesting and so an additional trace.
      expect(chain.traces, hasLength(3));
    });

    test('called for a stack trace from a one-shot timer', () async {
      var chain = await Chain.capture(() {
        return chainForTrace(inOneShotTimer, () => throw 'error');
      });

      expect(chain.traces, hasLength(3));
    });

    test('called for a stack trace from a periodic timer', () async {
      var chain = await Chain.capture(() {
        return chainForTrace(inPeriodicTimer, () => throw 'error');
      });

      expect(chain.traces, hasLength(3));
    });

    test(
        'called for a stack trace from a nested series of asynchronous '
        'operations', () async {
      var chain = await Chain.capture(() {
        return chainForTrace((callback) {
          inPeriodicTimer(() => inOneShotTimer(() => inMicrotask(callback)));
        }, () => throw 'error');
      });

      expect(chain.traces, hasLength(5));
    });

    test('called for a stack trace from a long future chain', () async {
      var chain = await Chain.capture(() {
        return chainForTrace(inFutureChain, () => throw 'error');
      });

      expect(chain.traces, hasLength(3));
    });

    test(
        'called for an unregistered stack trace returns a chain wrapping that '
        'trace', () {
      var trace;
      var chain = Chain.capture(() {
        try {
          throw 'error';
        } catch (_, stackTrace) {
          trace = stackTrace;
          return new Chain.forTrace(stackTrace);
        }
      });

      expect(chain.traces, hasLength(1));
      expect(chain.traces.first.toString(),
          equals(new Trace.from(trace).toString()));
    });
  });

  test(
      'forTrace() outside of capture() returns a chain wrapping the given '
      'trace', () {
    var trace;
    var chain = Chain.capture(() {
      try {
        throw 'error';
      } catch (_, stackTrace) {
        trace = stackTrace;
        return new Chain.forTrace(stackTrace);
      }
    });

    expect(chain.traces, hasLength(1));
    expect(chain.traces.first.toString(),
        equals(new Trace.from(trace).toString()));
  });
}
