// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8

import 'package:flutter/material.dart';

import '../flutter_test_alternative.dart';

const List<int> primaryKeys = <int>[50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
const List<int> accentKeys = <int>[100, 200, 400, 700];

void main() {
  test('MaterialColor basic functionality', () {
    const MaterialColor color = MaterialColor(
      500,
      <int, Color>{
         50: Color(0x00000050),
        100: Color(0x00000100),
        200: Color(0x00000200),
        300: Color(0x00000300),
        400: Color(0x00000400),
        500: Color(0x00000500),
        600: Color(0x00000600),
        700: Color(0x00000700),
        800: Color(0x00000800),
        900: Color(0x00000900),
      },
    );

    expect(color.value, 500);

    expect(color[50].value, 0x00000050);
    expect(color[100].value, 0x00000100);
    expect(color[200].value, 0x00000200);
    expect(color[300].value, 0x00000300);
    expect(color[400].value, 0x00000400);
    expect(color[500].value, 0x00000500);
    expect(color[600].value, 0x00000600);
    expect(color[700].value, 0x00000700);
    expect(color[800].value, 0x00000800);
    expect(color[900].value, 0x00000900);

    expect(color.shade50.value, 0x00000050);
    expect(color.shade100.value, 0x00000100);
    expect(color.shade200.value, 0x00000200);
    expect(color.shade300.value, 0x00000300);
    expect(color.shade400.value, 0x00000400);
    expect(color.shade500.value, 0x00000500);
    expect(color.shade600.value, 0x00000600);
    expect(color.shade700.value, 0x00000700);
    expect(color.shade800.value, 0x00000800);
    expect(color.shade900.value, 0x00000900);
  });

  test('Colors swatches do not contain duplicates', () {
    for (final MaterialColor color in Colors.primaries)
      expect(primaryKeys.map<Color>((int key) => color[key]).toSet().length, primaryKeys.length);

    expect(primaryKeys.map<Color>((int key) => Colors.grey[key]).toSet().length, primaryKeys.length);

    for (final MaterialAccentColor color in Colors.accents)
      expect(accentKeys.map<Color>((int key) => color[key]).toSet().length, accentKeys.length);
  });

  test('All color swatch colors are opaque and equal their primary color', () {
    for (final MaterialColor color in Colors.primaries) {
      expect(color.value, color.shade500.value);
      for (final int key in primaryKeys) {
        expect(color[key].alpha, 0xFF);
      }
    }

    expect(Colors.grey.value, Colors.grey.shade500.value);
    for (final int key in primaryKeys) {
      expect(Colors.grey[key].alpha, 0xFF);
    }

    for (final MaterialAccentColor color in Colors.accents) {
      expect(color.value, color.shade200.value);
      for (final int key in accentKeys) {
        expect(color[key].alpha, 0xFF);
      }
    }
  });

}
