// 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.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.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);
      }
    }
  });

}
