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

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

void main() {
  SourceLocation location;
  setUp(() {
    location = SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart");
  });

  group('errors', () {
    group('for new SourceLocation()', () {
      test('offset may not be negative', () {
        expect(() => SourceLocation(-1), throwsRangeError);
      });

      test('line may not be negative', () {
        expect(() => SourceLocation(0, line: -1), throwsRangeError);
      });

      test('column may not be negative', () {
        expect(() => SourceLocation(0, column: -1), throwsRangeError);
      });
    });

    test('for distance() source URLs must match', () {
      expect(() => location.distance(SourceLocation(0)), throwsArgumentError);
    });

    test('for compareTo() source URLs must match', () {
      expect(() => location.compareTo(SourceLocation(0)), throwsArgumentError);
    });
  });

  test('fields work correctly', () {
    expect(location.sourceUrl, equals(Uri.parse("foo.dart")));
    expect(location.offset, equals(15));
    expect(location.line, equals(2));
    expect(location.column, equals(6));
  });

  group('toolString', () {
    test('returns a computer-readable representation', () {
      expect(location.toolString, equals('foo.dart:3:7'));
    });

    test('gracefully handles a missing source URL', () {
      final location = SourceLocation(15, line: 2, column: 6);
      expect(location.toolString, equals('unknown source:3:7'));
    });
  });

  test("distance returns the absolute distance between locations", () {
    final other = SourceLocation(10, sourceUrl: "foo.dart");
    expect(location.distance(other), equals(5));
    expect(other.distance(location), equals(5));
  });

  test("pointSpan returns an empty span at location", () {
    final span = location.pointSpan();
    expect(span.start, equals(location));
    expect(span.end, equals(location));
    expect(span.text, isEmpty);
  });

  group("compareTo()", () {
    test("sorts by offset", () {
      final other = SourceLocation(20, sourceUrl: "foo.dart");
      expect(location.compareTo(other), lessThan(0));
      expect(other.compareTo(location), greaterThan(0));
    });

    test("considers equal locations equal", () {
      expect(location.compareTo(location), equals(0));
    });
  });

  group("equality", () {
    test("two locations with the same offset and source are equal", () {
      final other = SourceLocation(15, sourceUrl: "foo.dart");
      expect(location, equals(other));
    });

    test("a different offset isn't equal", () {
      final other = SourceLocation(10, sourceUrl: "foo.dart");
      expect(location, isNot(equals(other)));
    });

    test("a different source isn't equal", () {
      final other = SourceLocation(15, sourceUrl: "bar.dart");
      expect(location, isNot(equals(other)));
    });
  });
}
