// Copyright (c) 2013, 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.

/// This file tests stack_trace's ability to parse live stack traces. It's a
/// dual of dartium_test.dart, since method names can differ somewhat from
/// platform to platform. No similar file exists for dart2js since the specific
/// method names there are implementation details.
@TestOn('vm')

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

// The name of this (trivial) function is verified as part of the test
String getStackTraceString() => StackTrace.current.toString();

// The name of this (trivial) function is verified as part of the test
StackTrace getStackTraceObject() => StackTrace.current;

Frame getCaller([int level]) {
  if (level == null) return Frame.caller();
  return Frame.caller(level);
}

Frame nestedGetCaller(int level) => getCaller(level);

Trace getCurrentTrace([int level]) => Trace.current(level);

Trace nestedGetCurrentTrace(int level) => getCurrentTrace(level);

void main() {
  group('Trace', () {
    test('.parse parses a real stack trace correctly', () {
      var string = getStackTraceString();
      var trace = Trace.parse(string);
      expect(path.url.basename(trace.frames.first.uri.path),
          equals('vm_test.dart'));
      expect(trace.frames.first.member, equals('getStackTraceString'));
    });

    test('converts from a native stack trace correctly', () {
      var trace = Trace.from(getStackTraceObject());
      expect(path.url.basename(trace.frames.first.uri.path),
          equals('vm_test.dart'));
      expect(trace.frames.first.member, equals('getStackTraceObject'));
    });

    test('.from handles a stack overflow trace correctly', () {
      void overflow() => overflow();

      var trace;
      try {
        overflow();
      } catch (_, stackTrace) {
        trace = Trace.from(stackTrace);
      }

      expect(trace.frames.first.member, equals('main.<fn>.<fn>.overflow'));
    });

    group('.current()', () {
      test('with no argument returns a trace starting at the current frame',
          () {
        var trace = Trace.current();
        expect(trace.frames.first.member, equals('main.<fn>.<fn>.<fn>'));
      });

      test('at level 0 returns a trace starting at the current frame', () {
        var trace = Trace.current(0);
        expect(trace.frames.first.member, equals('main.<fn>.<fn>.<fn>'));
      });

      test('at level 1 returns a trace starting at the parent frame', () {
        var trace = getCurrentTrace(1);
        expect(trace.frames.first.member, equals('main.<fn>.<fn>.<fn>'));
      });

      test('at level 2 returns a trace starting at the grandparent frame', () {
        var trace = nestedGetCurrentTrace(2);
        expect(trace.frames.first.member, equals('main.<fn>.<fn>.<fn>'));
      });

      test('throws an ArgumentError for negative levels', () {
        expect(() => Trace.current(-1), throwsArgumentError);
      });
    });
  });

  group('Frame.caller()', () {
    test('with no argument returns the parent frame', () {
      expect(getCaller().member, equals('main.<fn>.<fn>'));
    });

    test('at level 0 returns the current frame', () {
      expect(getCaller(0).member, equals('getCaller'));
    });

    test('at level 1 returns the current frame', () {
      expect(getCaller(1).member, equals('main.<fn>.<fn>'));
    });

    test('at level 2 returns the grandparent frame', () {
      expect(nestedGetCaller(2).member, equals('main.<fn>.<fn>'));
    });

    test('throws an ArgumentError for negative levels', () {
      expect(() => Frame.caller(-1), throwsArgumentError);
    });
  });
}
