// Copyright (c) 2019, 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:expect/expect.dart';

// Typed as dynamic to also test spreading a value of type dynamic.
const dynamic list = [1, 2, 3, 4];
const dynamic map = {1: 1, 2: 2, 3: 3, 4: 4};
const dynamic set = {1, 2, 3, 4};

void main() {
  testList();
  testMap();
  testSet();
  testKeyOrder();
}

void testList() {
  // Only spread.
  Expect.identical(list, const <int>[...list]);
  Expect.identical(list, const <int>[...set]);

  // Spread at beginning.
  Expect.identical(list, const <int>[...<int>[1, 2], 3, 4]);

  // Spread in middle.
  Expect.identical(list, const <int>[1, ...<int>[2, 3], 4]);

  // Spread at end.
  Expect.identical(list, const <int>[1, 2, ...<int>[3, 4]]);

  // Empty spreads.
  Expect.identical(list,
      const <int>[...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]]);

  // Multiple spreads.
  Expect.identical(list,
      const <int>[...<int>[1], 2, ...<int>[3, 4]]);

  // Nested spreads.
  Expect.identical(list,
      const <int>[...<int>[...<int>[1, 2], ...<int>[3, 4]]]);

  // Null-aware.
  const list23 = <int>[2, 3] as List<int>?;
  const list4 = <int>[4] as List<int>?;
  Expect.identical(list,
      const <int>[1, ...?list23, ...?(null), ...?list4]);

  // Does not deep flatten.
  Expect.identical(
      const <Object>[1, 2, <int>[3], 4],
      const <Object>[1, ...<Object>[2, <int>[3], 4]]);

  // Establishes const context.
  Expect.identical(const <Symbol>[Symbol("sym")],
      const <Symbol>[...<Symbol>[Symbol("sym")]]);
}

void testMap() {
  // Only spread.
  Expect.identical(map, const <int, int>{...map});

  // Spread at beginning.
  Expect.identical(map,
      const <int, int>{...<int, int>{1: 1, 2: 2}, 3: 3, 4: 4});

  // Spread in middle.
  Expect.identical(map,
      const <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});

  // Spread at end.
  Expect.identical(map,
      const <int, int>{1: 1, 2: 2, ...<int, int>{3: 3, 4: 4}});

  // Empty spreads.
  Expect.identical(map, const <int, int>{
    ...<int, int>{},
    1: 1,
    2: 2,
    ...<int, int>{},
    3: 3,
    4: 4,
    ...<int, int>{}
  });

  // Multiple spreads.
  Expect.identical(map,
      const <int, int>{...<int, int>{1: 1}, 2: 2, ...<int, int>{3: 3, 4: 4}});

  // Nested spreads.
  Expect.identical(map, const <int, int>{
    ...<int, int>{
      ...<int, int>{1: 1, 2: 2},
      ...<int, int>{3: 3, 4: 4}
    }
  });

  // Null-aware.
  const map23 = <int, int>{2: 2, 3: 3} as Map<int, int>?;
  const map4 = <int, int>{4: 4} as Map<int, int>?;
  Expect.identical(map, const <int, int>{
    1: 1,
    ...?map23,
    ...?(null),
    ...?map4
  });

  // Does not deep flatten.
  Expect.identical(const <int, Object>{
    1: 1,
    2: 2,
    3: <int, int>{3: 3},
    4: 4
  }, const <int, Object>{
    1: 1,
    ...<int, Object>{
      2: 2,
      3: <int, int>{3: 3},
      4: 4
    }
  });

  // Establishes const context.
  Expect.identical(const <Symbol, Symbol>{
    Symbol("sym"): Symbol("bol")
  }, const <Symbol, Symbol>{
    ...<Symbol, Symbol>{Symbol("sym"): Symbol("bol")}
  });
}

void testSet() {
  // Only spread.
  Expect.identical(set, const <int>{...set});
  Expect.identical(set, const <int>{...list});

  // Spread at beginning.
  Expect.identical(set, const <int>{...<int>[1, 2], 3, 4});

  // Spread in middle.
  Expect.identical(set, const <int>{1, ...<int>[2, 3], 4});

  // Spread at end.
  Expect.identical(set, const <int>{1, 2, ...<int>[3, 4]});

  // Empty spreads.
  Expect.identical(set,
      const <int>{...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]});

  // Multiple spreads.
  Expect.identical(set, const <int>{...<int>[1], 2, ...<int>[3, 4]});

  // Nested spreads.
  Expect.identical(set, const <int>{...<int>{...<int>[1, 2], ...<int>[3, 4]}});

  // Null-aware.
  const list23 = <int>[2, 3] as List<int>?;
  const list4 = <int>[4] as List<int>?;
  Expect.identical(set,
      const <int>{1, ...?list23, ...?(null), ...?list4});

  // Does not deep flatten.
  Expect.identical(const <Object>{1, 2, <int>{3}, 4},
      const <Object>{1, ...<Object>{2, <int>{3}, 4}});

  // Establishes const context.
  Expect.identical(const <Symbol>{Symbol("sym")},
      const <Symbol>{...<Symbol>{Symbol("sym")}});
}

void testKeyOrder() {
  // Canonicalization isn't affected by which elements are spread.
  Expect.identical(map,
      const <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});
  Expect.identical(map,
      const <int, int>{1: 1, ...<int, int>{2: 2}, 3: 3, ...<int, int>{4: 4}});

  Expect.identical(set, const <int>{1, ...<int>{2, 3}, 4});
  Expect.identical(set, const <int>{1, ...<int>{2}, 3, ...<int>{4}});

  // Ordering does affect canonicalization.
  Expect.notIdentical(const <int, int>{1: 1, 2: 2, 3: 3},
      const <int, int>{1: 1, ...<int, int>{3: 3, 2: 2}});
  Expect.notIdentical(const <int>{1, 2, 3}, const <int>{1, ...<int>{3, 2}});
}
