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

library test.src.summary.api_signature_test;

import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ApiSignatureTest);
  });
}

@reflectiveTest
class ApiSignatureTest {
  ApiSignature sig = new ApiSignature.unversioned();

  void checkBytes(List<int> bytes) {
    expect(sig.getBytes_forDebug(), bytes);
    expect(sig.toHex(), hex.encode(md5.convert(bytes).bytes));
  }

  String signUnlinkedCombinator(UnlinkedCombinatorBuilder combinator) {
    ApiSignature sig = new ApiSignature();
    combinator.collectApiSignature(sig);
    return sig.toHex();
  }

  void test_addBool() {
    sig.addBool(true);
    sig.addBool(true);
    sig.addBool(false);
    sig.addBool(true);
    sig.addBool(false);
    sig.addBool(false);
    sig.addBool(true);
    sig.addBool(false);
    checkBytes([1, 1, 0, 1, 0, 0, 1, 0]);
  }

  void test_addBytes() {
    // Check that offset works correctly by adding bytes in 2 chunks.
    sig.addBytes([1, 2, 3, 4, 5]);
    sig.addBytes([0xff, 0xfe, 0xfd, 0xfc, 0xfb]);
    checkBytes([1, 2, 3, 4, 5, 0xff, 0xfe, 0xfd, 0xfc, 0xfb]);
  }

  void test_addDouble() {
    sig.addDouble(1.0 / 3.0);
    sig.addDouble(-1.0);
    checkBytes([85, 85, 85, 85, 85, 85, 213, 63, 0, 0, 0, 0, 0, 0, 240, 191]);
  }

  void test_addInt() {
    sig.addInt(1);
    sig.addInt(1000);
    sig.addInt(1000000);
    sig.addInt(1000000000);
    checkBytes(
        [1, 0, 0, 0, 0xe8, 3, 0, 0, 0x40, 0x42, 0xf, 0, 0, 0xca, 0x9a, 0x3b]);
  }

  void test_addString() {
    sig.addString('abc');
    sig.addString('\u00f8');
    checkBytes([3, 0, 0, 0, 0x61, 0x62, 0x63, 2, 0, 0, 0, 0xc3, 0xb8]);
  }

  void test_excludesInformative() {
    // Verify that API signatures exclude informative data by checking that two
    // UnlinkedCombinator instances that differ only in their offset result in
    // the same signature.
    UnlinkedCombinatorBuilder combinator1 =
        new UnlinkedCombinatorBuilder(shows: ['foo'], offset: 1);
    UnlinkedCombinatorBuilder combinator2 =
        new UnlinkedCombinatorBuilder(shows: ['foo'], offset: 2);
    expect(signUnlinkedCombinator(combinator1),
        signUnlinkedCombinator(combinator2));
  }

  void test_includesSemantic() {
    // Verify that API signatures include semantic data by checking that two
    // UnlinkedCombinator instances that differ only in their "shows" lists
    // result in different signatures.
    UnlinkedCombinatorBuilder combinator1 =
        new UnlinkedCombinatorBuilder(shows: ['foo'], offset: 1);
    UnlinkedCombinatorBuilder combinator2 =
        new UnlinkedCombinatorBuilder(shows: ['bar'], offset: 1);
    expect(signUnlinkedCombinator(combinator1),
        isNot(signUnlinkedCombinator(combinator2)));
  }

  void test_manyInts() {
    // This verifies that the logic to extend the internal buffer works
    // properly.
    List<int> expectedResult = [];
    for (int i = 0; i < 100000; i++) {
      sig.addInt(i);
      expectedResult.add(i % 0x100);
      expectedResult.add((i ~/ 0x100) % 0x100);
      expectedResult.add((i ~/ 0x10000) % 0x100);
      expectedResult.add((i ~/ 0x1000000) % 0x100);
    }
    checkBytes(expectedResult);
  }
}
