// 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 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/src/gestures/constants.dart';
import 'package:flutter_test/flutter_test.dart';

import '../widgets/semantics_tester.dart';

void main() {
  final theme = ThemeData();
  setUp(() {
    debugResetSemanticsIdCounter();
  });

  testWidgets('Checkbox size is configurable by ThemeData.materialTapTargetSize', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      Theme(
        data: theme.copyWith(materialTapTargetSize: MaterialTapTargetSize.padded),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Material(
            child: Center(child: Checkbox(value: true, onChanged: (bool? newValue) {})),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byType(Checkbox)), const Size(48.0, 48.0));

    await tester.pumpWidget(
      Theme(
        data: theme.copyWith(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Material(
            child: Center(child: Checkbox(value: true, onChanged: (bool? newValue) {})),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byType(Checkbox)), const Size(40.0, 40.0));
  });

  testWidgets('Checkbox semantics', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(child: Checkbox(value: false, onChanged: (bool? b) {})),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Focus).last),
      matchesSemantics(
        hasCheckedState: true,
        hasEnabledState: true,
        isEnabled: true,
        hasTapAction: true,
        hasFocusAction: true,
        isFocusable: true,
      ),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(child: Checkbox(value: true, onChanged: (bool? b) {})),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Focus).last),
      matchesSemantics(
        hasCheckedState: true,
        hasEnabledState: true,
        isChecked: true,
        isEnabled: true,
        hasTapAction: true,
        hasFocusAction: true,
        isFocusable: true,
      ),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: const Material(child: Checkbox(value: false, onChanged: null)),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Checkbox)),
      matchesSemantics(
        hasCheckedState: true,
        hasEnabledState: true,
        // isFocusable is delayed by 1 frame.
        isFocusable: true,
        hasFocusAction: true,
      ),
    );

    await tester.pump();
    // isFocusable should be false now after the 1 frame delay.
    expect(
      tester.getSemantics(find.byType(Checkbox)),
      matchesSemantics(hasCheckedState: true, hasEnabledState: true),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: const Material(child: Checkbox(value: true, onChanged: null)),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Checkbox)),
      matchesSemantics(hasCheckedState: true, hasEnabledState: true, isChecked: true),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: const Material(child: Checkbox(value: null, tristate: true, onChanged: null)),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Checkbox)),
      matchesSemantics(hasCheckedState: true, hasEnabledState: true, isCheckStateMixed: true),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: const Material(child: Checkbox(value: true, tristate: true, onChanged: null)),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Checkbox)),
      matchesSemantics(hasCheckedState: true, hasEnabledState: true, isChecked: true),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: const Material(child: Checkbox(value: false, tristate: true, onChanged: null)),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Checkbox)),
      matchesSemantics(hasCheckedState: true, hasEnabledState: true),
    );

    // Check if semanticLabel is there.
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Theme(
          data: theme,
          child: Material(
            child: Checkbox(semanticLabel: 'checkbox', value: true, onChanged: (bool? b) {}),
          ),
        ),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Focus).last),
      matchesSemantics(
        label: 'checkbox',
        textDirection: TextDirection.ltr,
        hasCheckedState: true,
        hasEnabledState: true,
        isChecked: true,
        isEnabled: true,
        hasTapAction: true,
        hasFocusAction: true,
        isFocusable: true,
      ),
    );
    handle.dispose();
  });

  testWidgets('Can wrap Checkbox with Semantics', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(
          child: Semantics(
            label: 'foo',
            textDirection: TextDirection.ltr,
            child: Checkbox(value: false, onChanged: (bool? b) {}),
          ),
        ),
      ),
    );

    expect(
      tester.getSemantics(find.byType(Focus).last),
      matchesSemantics(
        label: 'foo',
        textDirection: TextDirection.ltr,
        hasCheckedState: true,
        hasEnabledState: true,
        isEnabled: true,
        hasTapAction: true,
        hasFocusAction: true,
        isFocusable: true,
      ),
    );
    handle.dispose();
  });

  testWidgets('Checkbox tristate: true', (WidgetTester tester) async {
    bool? checkBoxValue;

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                tristate: true,
                value: checkBoxValue,
                onChanged: (bool? value) {
                  setState(() {
                    checkBoxValue = value;
                  });
                },
              );
            },
          ),
        ),
      ),
    );

    expect(tester.widget<Checkbox>(find.byType(Checkbox)).value, null);

    await tester.tap(find.byType(Checkbox));
    await tester.pumpAndSettle();
    expect(checkBoxValue, false);

    await tester.tap(find.byType(Checkbox));
    await tester.pumpAndSettle();
    expect(checkBoxValue, true);

    await tester.tap(find.byType(Checkbox));
    await tester.pumpAndSettle();
    expect(checkBoxValue, null);

    checkBoxValue = true;
    await tester.pumpAndSettle();
    expect(checkBoxValue, true);

    checkBoxValue = null;
    await tester.pumpAndSettle();
    expect(checkBoxValue, null);
  });

  testWidgets('has semantics for tristate', (WidgetTester tester) async {
    final semantics = SemanticsTester(tester);
    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(
          child: Checkbox(tristate: true, value: null, onChanged: (bool? newValue) {}),
        ),
      ),
    );

    expect(
      semantics.nodesWith(
        flags: <SemanticsFlag>[
          SemanticsFlag.hasCheckedState,
          SemanticsFlag.hasEnabledState,
          SemanticsFlag.isEnabled,
          SemanticsFlag.isFocusable,
          SemanticsFlag.isCheckStateMixed,
        ],
        actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
      ),
      hasLength(1),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(
          child: Checkbox(tristate: true, value: true, onChanged: (bool? newValue) {}),
        ),
      ),
    );

    expect(
      semantics.nodesWith(
        flags: <SemanticsFlag>[
          SemanticsFlag.hasCheckedState,
          SemanticsFlag.hasEnabledState,
          SemanticsFlag.isEnabled,
          SemanticsFlag.isChecked,
          SemanticsFlag.isFocusable,
        ],
        actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
      ),
      hasLength(1),
    );

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(
          child: Checkbox(tristate: true, value: false, onChanged: (bool? newValue) {}),
        ),
      ),
    );

    expect(
      semantics.nodesWith(
        flags: <SemanticsFlag>[
          SemanticsFlag.hasCheckedState,
          SemanticsFlag.hasEnabledState,
          SemanticsFlag.isEnabled,
          SemanticsFlag.isFocusable,
        ],
        actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
      ),
      hasLength(1),
    );

    semantics.dispose();
  });

  testWidgets('has semantic events', (WidgetTester tester) async {
    dynamic semanticEvent;
    bool? checkboxValue = false;
    tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(
      SystemChannels.accessibility,
      (dynamic message) async {
        semanticEvent = message;
      },
    );
    final semanticsTester = SemanticsTester(tester);

    await tester.pumpWidget(
      Theme(
        data: theme,
        child: Material(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                value: checkboxValue,
                onChanged: (bool? value) {
                  setState(() {
                    checkboxValue = value;
                  });
                },
              );
            },
          ),
        ),
      ),
    );

    await tester.tap(find.byType(Checkbox));
    final RenderObject object = tester.firstRenderObject(find.byType(Checkbox));

    expect(checkboxValue, true);
    expect(semanticEvent, <String, dynamic>{
      'type': 'tap',
      'nodeId': object.debugSemantics!.id,
      'data': <String, dynamic>{},
    });
    expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);

    tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(
      SystemChannels.accessibility,
      null,
    );
    semanticsTester.dispose();
  });

  testWidgets('Material2 - Checkbox tristate rendering, programmatic transitions', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData(useMaterial3: false);
    Widget buildFrame(bool? checkboxValue) {
      return Theme(
        data: theme,
        child: Material(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(tristate: true, value: checkboxValue, onChanged: (bool? value) {});
            },
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    await tester.pumpWidget(buildFrame(false));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..rrect(color: Colors.transparent),
    ); // paint transparent border
    expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
    expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox

    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: theme.colorScheme.secondary)
        ..path(color: const Color(0xFFFFFFFF)),
    ); // checkmark is rendered as a path

    await tester.pumpWidget(buildFrame(false));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..rrect(color: Colors.transparent),
    ); // paint transparent border
    expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
    expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox

    await tester.pumpWidget(buildFrame(null));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")

    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: theme.colorScheme.secondary)
        ..path(color: const Color(0xFFFFFFFF)),
    ); // checkmark is rendered as a path

    await tester.pumpWidget(buildFrame(null));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
  });

  testWidgets('Material3 - Checkbox tristate rendering, programmatic transitions', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData();
    Widget buildFrame(bool? checkboxValue) {
      return Theme(
        data: theme,
        child: Material(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(tristate: true, value: checkboxValue, onChanged: (bool? value) {});
            },
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    await tester.pumpWidget(buildFrame(false));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..rrect(color: Colors.transparent),
    ); // paint transparent border
    expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
    expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox

    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: theme.colorScheme.primary)
        ..path(color: theme.colorScheme.onPrimary),
    ); // checkmark is rendered as a path

    await tester.pumpWidget(buildFrame(false));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..rrect(color: Colors.transparent),
    ); // paint transparent border
    expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
    expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox

    await tester.pumpWidget(buildFrame(null));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")

    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: theme.colorScheme.primary)
        ..path(color: theme.colorScheme.onPrimary),
    ); // checkmark is rendered as a path

    await tester.pumpWidget(buildFrame(null));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
  });

  testWidgets('Material2 - Checkbox color rendering', (WidgetTester tester) async {
    var theme = ThemeData(useMaterial3: false);
    const borderColor = Color(0xff2196f3);
    var checkColor = const Color(0xffFFFFFF);
    Color activeColor;

    Widget buildFrame({Color? activeColor, Color? checkColor, ThemeData? themeData}) {
      return Material(
        child: Theme(
          data: themeData ?? theme,
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                value: true,
                activeColor: activeColor,
                checkColor: checkColor,
                onChanged: (bool? value) {},
              );
            },
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    await tester.pumpWidget(buildFrame(checkColor: checkColor));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: borderColor)
        ..path(color: checkColor),
    ); // paints's color is 0xFFFFFFFF (default color)

    checkColor = const Color(0xFF000000);

    await tester.pumpWidget(buildFrame(checkColor: checkColor));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: borderColor)
        ..path(color: checkColor),
    ); // paints's color is 0xFF000000 (params)

    activeColor = const Color(0xFF00FF00);

    final ColorScheme colorScheme = const ColorScheme.light().copyWith(secondary: activeColor);
    theme = theme.copyWith(colorScheme: colorScheme);
    await tester.pumpWidget(buildFrame(themeData: theme));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..rrect(color: activeColor),
    ); // paints's color is 0xFF00FF00 (theme)

    activeColor = const Color(0xFF000000);

    await tester.pumpWidget(buildFrame(activeColor: activeColor));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..rrect(color: activeColor));
  });

  testWidgets('Material3 - Checkbox color rendering', (WidgetTester tester) async {
    var theme = ThemeData();
    const borderColor = Color(0xFF6750A4);
    var checkColor = const Color(0xffFFFFFF);
    Color activeColor;

    Widget buildFrame({Color? activeColor, Color? checkColor, ThemeData? themeData}) {
      return Material(
        child: Theme(
          data: themeData ?? theme,
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                value: true,
                activeColor: activeColor,
                checkColor: checkColor,
                onChanged: (bool? value) {},
              );
            },
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    await tester.pumpWidget(buildFrame(checkColor: checkColor));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: borderColor)
        ..path(color: checkColor),
    ); // paints's color is 0xFFFFFFFF (default color)

    checkColor = const Color(0xFF000000);

    await tester.pumpWidget(buildFrame(checkColor: checkColor));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints
        ..rrect(color: borderColor)
        ..path(color: checkColor),
    ); // paints's color is 0xFF000000 (params)

    activeColor = const Color(0xFF00FF00);

    final ColorScheme colorScheme = const ColorScheme.light().copyWith(primary: activeColor);
    theme = theme.copyWith(colorScheme: colorScheme);
    await tester.pumpWidget(buildFrame(themeData: theme));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..rrect(color: activeColor),
    ); // paints's color is 0xFF00FF00 (theme)

    activeColor = const Color(0xFF000000);

    await tester.pumpWidget(buildFrame(activeColor: activeColor));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..rrect(color: activeColor));
  });

  testWidgets('Material2 - Checkbox is focusable and has correct focus color', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'Checkbox');
    addTearDown(focusNode.dispose);
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = true;
    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: value,
                  onChanged: enabled
                      ? (bool? newValue) {
                          setState(() {
                            value = newValue;
                          });
                        }
                      : null,
                  focusColor: Colors.orange[500],
                  autofocus: true,
                  focusNode: focusNode,
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());

    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: Colors.orange[500])
        ..rrect(color: const Color(0xff2196f3))
        ..path(color: Colors.white),
    );

    // Check the false value.
    value = false;
    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: Colors.orange[500])
        ..drrect(
          color: const Color(0x8a000000),
          outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
          inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
        ),
    );

    // Check what happens when disabled.
    value = false;
    await tester.pumpWidget(buildApp(enabled: false));
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isFalse);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..drrect(
        color: const Color(0x61000000),
        outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
        inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
      ),
    );
  });

  testWidgets('Material3 - Checkbox is focusable and has correct focus color', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'Checkbox');
    addTearDown(focusNode.dispose);
    final theme = ThemeData();
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = true;
    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: value,
                  onChanged: enabled
                      ? (bool? newValue) {
                          setState(() {
                            value = newValue;
                          });
                        }
                      : null,
                  focusColor: Colors.orange[500],
                  autofocus: true,
                  focusNode: focusNode,
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());

    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: Colors.orange[500])
        ..rrect(color: theme.colorScheme.primary)
        ..path(color: theme.colorScheme.onPrimary),
    );

    // Check the false value.
    value = false;
    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: Colors.orange[500])
        ..drrect(
          color: theme.colorScheme.onSurface,
          outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2.0)),
          inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
        ),
    );

    // Check what happens when disabled.
    value = false;
    await tester.pumpWidget(buildApp(enabled: false));
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isFalse);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..drrect(
        color: theme.colorScheme.onSurface.withOpacity(0.38),
        outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2.0)),
        inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
      ),
    );
  });

  testWidgets('Checkbox with splash radius set', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    const double splashRadius = 30;
    Widget buildApp() {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: false,
                  onChanged: (bool? newValue) {},
                  focusColor: Colors.orange[500],
                  autofocus: true,
                  splashRadius: splashRadius,
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: Colors.orange[500], radius: splashRadius),
    );
  });

  testWidgets('Checkbox starts the splash in center, even when tap is on the corner', (
    WidgetTester tester,
  ) async {
    Widget buildApp() {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(value: false, onChanged: (bool? newValue) {});
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    final Offset checkboxTopLeftGlobal = tester.getTopLeft(find.byType(Checkbox));
    final Offset checkboxCenterGlobal = tester.getCenter(find.byType(Checkbox));
    final Offset checkboxCenterLocal = checkboxCenterGlobal - checkboxTopLeftGlobal;
    final TestGesture gesture = await tester.startGesture(checkboxTopLeftGlobal);
    await tester.pump();
    // Wait for the splash to be drawn, but not long enough for it to animate towards the center, since
    // we want to catch it in its starting position.
    await tester.pump(const Duration(milliseconds: 1));
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(x: checkboxCenterLocal.dx, y: checkboxCenterLocal.dy),
    );

    // Finish gesture to release resources.
    await gesture.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Material2 - Checkbox can be hovered and has correct hover color', (
    WidgetTester tester,
  ) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = true;
    final theme = ThemeData(useMaterial3: false);
    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: value,
                  onChanged: enabled
                      ? (bool? newValue) {
                          setState(() {
                            value = newValue;
                          });
                        }
                      : null,
                  hoverColor: Colors.orange[500],
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..rrect(color: const Color(0xff2196f3))
        ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
    );

    // Start hovering
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: Colors.orange[500])
        ..rrect(color: const Color(0xff2196f3))
        ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
    );

    // Check what happens when disabled.
    await tester.pumpWidget(buildApp(enabled: false));
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..rrect(color: const Color(0x61000000))
        ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
    );
  });

  testWidgets('Material3 - Checkbox can be hovered and has correct hover color', (
    WidgetTester tester,
  ) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = true;
    final theme = ThemeData();
    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: value,
                  onChanged: enabled
                      ? (bool? newValue) {
                          setState(() {
                            value = newValue;
                          });
                        }
                      : null,
                  hoverColor: Colors.orange[500],
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..rrect(color: const Color(0xff6750a4))
        ..path(color: theme.colorScheme.onPrimary, style: PaintingStyle.stroke, strokeWidth: 2.0),
    );

    // Start hovering
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: Colors.orange[500])
        ..rrect(color: const Color(0xff6750a4))
        ..path(color: theme.colorScheme.onPrimary, style: PaintingStyle.stroke, strokeWidth: 2.0),
    );

    // Check what happens when disabled.
    await tester.pumpWidget(buildApp(enabled: false));
    await tester.pumpAndSettle();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..rrect(color: theme.colorScheme.onSurface.withOpacity(0.38))
        ..path(color: theme.colorScheme.surface, style: PaintingStyle.stroke, strokeWidth: 2.0),
    );
  });

  testWidgets('Checkbox can be toggled by keyboard shortcuts', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = true;
    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: value,
                  onChanged: enabled
                      ? (bool? newValue) {
                          setState(() {
                            value = newValue;
                          });
                        }
                      : null,
                  focusColor: Colors.orange[500],
                  autofocus: true,
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    await tester.sendKeyEvent(LogicalKeyboardKey.enter);
    await tester.pumpAndSettle();
    // On web, checkboxes don't respond to the enter key.
    expect(value, kIsWeb ? isTrue : isFalse);
    await tester.sendKeyEvent(LogicalKeyboardKey.enter);
    await tester.pumpAndSettle();
    expect(value, isTrue);
    await tester.sendKeyEvent(LogicalKeyboardKey.space);
    await tester.pumpAndSettle();
    expect(value, isFalse);
    await tester.sendKeyEvent(LogicalKeyboardKey.space);
    await tester.pumpAndSettle();
    expect(value, isTrue);
  });

  testWidgets(
    'Material3 - Checkbox visual density cannot be overriden by ThemeData.visualDensity',
    (WidgetTester tester) async {
      const key = Key('test');
      Widget buldCheckbox() {
        return MaterialApp(
          theme: theme.copyWith(visualDensity: VisualDensity.compact),
          home: Material(
            child: Center(
              child: Checkbox(key: key, value: true, onChanged: (bool? value) {}),
            ),
          ),
        );
      }

      await tester.pumpWidget(buldCheckbox());
      await tester.pumpAndSettle();
      final RenderBox box = tester.renderObject(find.byKey(key));
      expect(box.size, equals(const Size(48, 48)));
    },
  );

  testWidgets(
    'Material3 - Checkbox with MaterialTapTargetSize.padded meets Material Guidelines on desktop',
    (WidgetTester tester) async {
      const key = Key('test');
      Widget buldCheckbox() {
        return MaterialApp(
          theme: theme,
          home: Material(
            child: Center(
              child: Checkbox(
                key: key,
                materialTapTargetSize: MaterialTapTargetSize.padded,
                value: true,
                onChanged: (bool? value) {},
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buldCheckbox());
      await tester.pumpAndSettle();
      final RenderBox box = tester.renderObject(find.byKey(key));
      expect(box.size, equals(const Size(48, 48)));
    },
    variant: TargetPlatformVariant.desktop(),
  );

  testWidgets('Checkbox responds to density changes', (WidgetTester tester) async {
    const key = Key('test');
    Future<void> buildTest({VisualDensity? visualDensity}) async {
      return tester.pumpWidget(
        MaterialApp(
          theme: theme,
          home: Material(
            child: Center(
              child: Checkbox(
                visualDensity: visualDensity,
                key: key,
                onChanged: (bool? value) {},
                value: true,
              ),
            ),
          ),
        ),
      );
    }

    // Test the default visual density.
    await buildTest();
    await tester.pumpAndSettle();
    final RenderBox box = tester.renderObject(find.byKey(key));
    expect(box.size, equals(const Size(48, 48)));

    await buildTest(visualDensity: VisualDensity.standard);
    await tester.pumpAndSettle();
    expect(box.size, equals(const Size(48, 48)));

    await buildTest(visualDensity: VisualDensity.compact);
    await tester.pumpAndSettle();
    expect(box.size, equals(const Size(40, 40)));

    await buildTest(visualDensity: const VisualDensity(horizontal: 3.0, vertical: 3.0));
    await tester.pumpAndSettle();
    expect(box.size, equals(const Size(60, 60)));

    await buildTest(visualDensity: const VisualDensity(horizontal: -3.0, vertical: -3.0));
    await tester.pumpAndSettle();
    expect(box.size, equals(const Size(36, 36)));

    await buildTest(visualDensity: const VisualDensity(horizontal: 3.0, vertical: -3.0));
    await tester.pumpAndSettle();
    expect(box.size, equals(const Size(60, 36)));
  });

  testWidgets('Checkbox stops hover animation when removed from the tree.', (
    WidgetTester tester,
  ) async {
    const checkboxKey = Key('checkbox');
    bool? checkboxVal = true;

    await tester.pumpWidget(
      Theme(
        data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Material(
            child: Center(
              child: StatefulBuilder(
                builder: (_, StateSetter setState) => Checkbox(
                  key: checkboxKey,
                  value: checkboxVal,
                  onChanged: (bool? newValue) => setState(() {
                    checkboxVal = newValue;
                  }),
                ),
              ),
            ),
          ),
        ),
      ),
    );

    expect(find.byKey(checkboxKey), findsOneWidget);
    final Offset checkboxCenter = tester.getCenter(find.byKey(checkboxKey));
    final TestGesture testGesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await testGesture.moveTo(checkboxCenter);

    await tester.pump(); // start animation
    await tester.pump(
      const Duration(milliseconds: 25),
    ); // hover animation duration is 50 ms. It is half-way.

    await tester.pumpWidget(
      Theme(
        data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Material(child: Center(child: Container())),
        ),
      ),
    );

    // Hover animation should not trigger an exception when the checkbox is removed
    // before the hover animation should complete.
    expect(tester.takeException(), isNull);

    await testGesture.removePointer();
  });

  testWidgets('Checkbox changes mouse cursor when hovered', (WidgetTester tester) async {
    // Test Checkbox() constructor
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: Scaffold(
          body: Align(
            alignment: Alignment.topLeft,
            child: Material(
              child: MouseRegion(
                cursor: SystemMouseCursors.forbidden,
                child: Checkbox(
                  mouseCursor: SystemMouseCursors.text,
                  value: true,
                  onChanged: (_) {},
                ),
              ),
            ),
          ),
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(
      kind: PointerDeviceKind.mouse,
      pointer: 1,
    );
    await gesture.addPointer(location: tester.getCenter(find.byType(Checkbox)));
    addTearDown(gesture.removePointer);

    await tester.pump();

    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.text,
    );

    // Test default cursor
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: Scaffold(
          body: Align(
            alignment: Alignment.topLeft,
            child: Material(
              child: MouseRegion(
                cursor: SystemMouseCursors.forbidden,
                child: Checkbox(value: true, onChanged: (_) {}),
              ),
            ),
          ),
        ),
      ),
    );

    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
    );

    // Test default cursor when disabled
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: const Scaffold(
          body: Align(
            alignment: Alignment.topLeft,
            child: Material(
              child: MouseRegion(
                cursor: SystemMouseCursors.forbidden,
                child: Checkbox(value: true, onChanged: null),
              ),
            ),
          ),
        ),
      ),
    );

    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.basic,
    );

    // Test cursor when tristate
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: const Scaffold(
          body: Align(
            alignment: Alignment.topLeft,
            child: Material(
              child: MouseRegion(
                cursor: SystemMouseCursors.forbidden,
                child: Checkbox(
                  value: null,
                  tristate: true,
                  onChanged: null,
                  mouseCursor: _SelectedGrabMouseCursor(),
                ),
              ),
            ),
          ),
        ),
      ),
    );

    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.grab,
    );

    await tester.pumpAndSettle();
  });

  testWidgets('Checkbox fill color resolves in enabled/disabled states', (
    WidgetTester tester,
  ) async {
    const activeEnabledFillColor = Color(0xFF000001);
    const activeDisabledFillColor = Color(0xFF000002);

    Color getFillColor(Set<WidgetState> states) {
      if (states.contains(WidgetState.disabled)) {
        return activeDisabledFillColor;
      }
      return activeEnabledFillColor;
    }

    final WidgetStateProperty<Color> fillColor = WidgetStateColor.resolveWith(getFillColor);

    Widget buildFrame({required bool enabled}) {
      return Material(
        child: Theme(
          data: theme,
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                value: true,
                fillColor: fillColor,
                onChanged: enabled ? (bool? value) {} : null,
              );
            },
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    await tester.pumpWidget(buildFrame(enabled: true));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..rrect(color: activeEnabledFillColor));

    await tester.pumpWidget(buildFrame(enabled: false));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..rrect(color: activeDisabledFillColor));
  });

  testWidgets('Checkbox fill color resolves in hovered/focused states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'checkbox');
    addTearDown(focusNode.dispose);

    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    const hoveredFillColor = Color(0xFF000001);
    const focusedFillColor = Color(0xFF000002);

    Color getFillColor(Set<WidgetState> states) {
      if (states.contains(WidgetState.hovered)) {
        return hoveredFillColor;
      }
      if (states.contains(WidgetState.focused)) {
        return focusedFillColor;
      }
      return Colors.transparent;
    }

    final WidgetStateProperty<Color> fillColor = WidgetStateColor.resolveWith(getFillColor);

    Widget buildFrame() {
      return Material(
        child: Theme(
          data: theme,
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                focusNode: focusNode,
                autofocus: true,
                value: true,
                fillColor: fillColor,
                onChanged: (bool? value) {},
              );
            },
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    await tester.pumpWidget(buildFrame());
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(getCheckboxRenderer(), paints..rrect(color: focusedFillColor));

    // Start hovering
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(getCheckboxRenderer(), paints..rrect(color: hoveredFillColor));
  });

  testWidgets('Checkbox respects shape and side', (WidgetTester tester) async {
    const roundedRectangleBorder = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(5)),
    );

    const side = BorderSide(width: 4, color: Color(0xfff44336));

    Widget buildApp() {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  value: false,
                  onChanged: (bool? newValue) {},
                  shape: roundedRectangleBorder,
                  side: side,
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();

    expect(tester.widget<Checkbox>(find.byType(Checkbox)).shape, roundedRectangleBorder);
    expect(tester.widget<Checkbox>(find.byType(Checkbox)).side, side);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..drrect(
        color: const Color(0xfff44336),
        outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(5)),
        inner: RRect.fromLTRBR(19.0, 19.0, 29.0, 29.0, const Radius.circular(1)),
      ),
    );
  });

  testWidgets(
    'Material2 - Checkbox default overlay color in active/pressed/focused/hovered states',
    (WidgetTester tester) async {
      final focusNode = FocusNode(debugLabel: 'Checkbox');
      addTearDown(focusNode.dispose);
      tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;

      final theme = ThemeData(useMaterial3: false);
      final ColorScheme colors = theme.colorScheme;
      Widget buildCheckbox({bool active = false, bool focused = false}) {
        return MaterialApp(
          theme: theme,
          home: Scaffold(
            body: Checkbox(
              focusNode: focusNode,
              autofocus: focused,
              value: active,
              onChanged: (_) {},
            ),
          ),
        );
      }

      await tester.pumpWidget(buildCheckbox());
      final TestGesture gesture1 = await tester.startGesture(
        tester.getCenter(find.byType(Checkbox)),
      );
      await tester.pumpAndSettle();

      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: theme.unselectedWidgetColor.withAlpha(kRadialReactionAlpha)),
        reason:
            'Default inactive pressed Checkbox should have overlay color from default fillColor',
      );

      await tester.pumpWidget(buildCheckbox(active: true));
      final TestGesture gesture2 = await tester.startGesture(
        tester.getCenter(find.byType(Checkbox)),
      );
      await tester.pumpAndSettle();

      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: colors.secondary.withAlpha(kRadialReactionAlpha)),
        reason: 'Default active pressed Checkbox should have overlay color from default fillColor',
      );

      await tester.pumpWidget(Container()); // reset test
      await tester.pumpWidget(buildCheckbox(focused: true));
      await tester.pumpAndSettle();

      expect(focusNode.hasPrimaryFocus, isTrue);
      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: theme.focusColor),
        reason: 'Focused Checkbox should use default focused overlay color',
      );

      await tester.pumpWidget(Container()); // reset test
      await tester.pumpWidget(buildCheckbox());
      final TestGesture gesture3 = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture3.addPointer();
      addTearDown(gesture3.removePointer);
      await gesture3.moveTo(tester.getCenter(find.byType(Checkbox)));
      await tester.pumpAndSettle();

      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: theme.hoverColor),
        reason: 'Hovered Checkbox should use default hovered overlay color',
      );

      // Finish gestures to release resources.
      await gesture1.up();
      await gesture2.up();
      await tester.pumpAndSettle();
    },
  );

  testWidgets(
    'Material3 - Checkbox default overlay color in active/pressed/focused/hovered states',
    (WidgetTester tester) async {
      final focusNode = FocusNode(debugLabel: 'Checkbox');
      addTearDown(focusNode.dispose);
      tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;

      final theme = ThemeData();
      final ColorScheme colors = theme.colorScheme;
      Widget buildCheckbox({bool active = false, bool focused = false}) {
        return MaterialApp(
          theme: theme,
          home: Scaffold(
            body: Checkbox(
              focusNode: focusNode,
              autofocus: focused,
              value: active,
              onChanged: (_) {},
            ),
          ),
        );
      }

      await tester.pumpWidget(buildCheckbox());
      final TestGesture gesture1 = await tester.startGesture(
        tester.getCenter(find.byType(Checkbox)),
      );
      await tester.pumpAndSettle();

      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: colors.primary.withOpacity(0.1)),
        reason:
            'Default inactive pressed Checkbox should have overlay color from default fillColor',
      );

      await tester.pumpWidget(buildCheckbox(active: true));
      final TestGesture gesture2 = await tester.startGesture(
        tester.getCenter(find.byType(Checkbox)),
      );
      await tester.pumpAndSettle();

      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: colors.onSurface.withOpacity(0.1)),
        reason: 'Default active pressed Checkbox should have overlay color from default fillColor',
      );

      await tester.pumpWidget(Container()); // reset test
      await tester.pumpWidget(buildCheckbox(focused: true));
      await tester.pumpAndSettle();

      expect(focusNode.hasPrimaryFocus, isTrue);
      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: colors.onSurface.withOpacity(0.1)),
        reason: 'Focused Checkbox should use default focused overlay color',
      );

      await tester.pumpWidget(Container()); // reset test
      await tester.pumpWidget(buildCheckbox());
      final TestGesture gesture3 = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture3.addPointer();
      addTearDown(gesture3.removePointer);
      await gesture3.moveTo(tester.getCenter(find.byType(Checkbox)));
      await tester.pumpAndSettle();

      expect(
        Material.of(tester.element(find.byType(Checkbox))),
        paints..circle(color: colors.onSurface.withOpacity(0.08)),
        reason: 'Hovered Checkbox should use default hovered overlay color',
      );

      // Finish gestures to release resources.
      await gesture1.up();
      await gesture2.up();
      await tester.pumpAndSettle();
    },
  );

  testWidgets('Checkbox overlay color resolves in active/pressed/focused/hovered states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'Checkbox');
    addTearDown(focusNode.dispose);
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;

    const fillColor = Color(0xFF000000);
    const activePressedOverlayColor = Color(0xFF000001);
    const inactivePressedOverlayColor = Color(0xFF000002);
    const hoverOverlayColor = Color(0xFF000003);
    const focusOverlayColor = Color(0xFF000004);
    const hoverColor = Color(0xFF000005);
    const focusColor = Color(0xFF000006);

    Color? getOverlayColor(Set<WidgetState> states) {
      if (states.contains(WidgetState.pressed)) {
        if (states.contains(WidgetState.selected)) {
          return activePressedOverlayColor;
        }
        return inactivePressedOverlayColor;
      }
      if (states.contains(WidgetState.hovered)) {
        return hoverOverlayColor;
      }
      if (states.contains(WidgetState.focused)) {
        return focusOverlayColor;
      }
      return null;
    }

    const splashRadius = 24.0;

    Widget buildCheckbox({bool active = false, bool focused = false, bool useOverlay = true}) {
      return MaterialApp(
        theme: theme,
        home: Scaffold(
          body: Checkbox(
            focusNode: focusNode,
            autofocus: focused,
            value: active,
            onChanged: (_) {},
            fillColor: const MaterialStatePropertyAll<Color>(fillColor),
            overlayColor: useOverlay ? WidgetStateProperty.resolveWith(getOverlayColor) : null,
            hoverColor: hoverColor,
            focusColor: focusColor,
            splashRadius: splashRadius,
          ),
        ),
      );
    }

    await tester.pumpWidget(buildCheckbox(useOverlay: false));
    final TestGesture gesture1 = await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: fillColor.withAlpha(kRadialReactionAlpha), radius: splashRadius),
      reason: 'Default inactive pressed Checkbox should have overlay color from fillColor',
    );

    await tester.pumpWidget(buildCheckbox(active: true, useOverlay: false));
    final TestGesture gesture2 = await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: fillColor.withAlpha(kRadialReactionAlpha), radius: splashRadius),
      reason: 'Default active pressed Checkbox should have overlay color from fillColor',
    );

    await tester.pumpWidget(buildCheckbox());
    final TestGesture gesture3 = await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: inactivePressedOverlayColor, radius: splashRadius),
      reason: 'Inactive pressed Checkbox should have overlay color: $inactivePressedOverlayColor',
    );

    await tester.pumpWidget(buildCheckbox(active: true));
    final TestGesture gesture4 = await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: activePressedOverlayColor, radius: splashRadius),
      reason: 'Active pressed Checkbox should have overlay color: $activePressedOverlayColor',
    );

    await tester.pumpWidget(Container()); // reset test
    await tester.pumpWidget(buildCheckbox(focused: true));
    await tester.pumpAndSettle();

    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: focusOverlayColor, radius: splashRadius),
      reason: 'Focused Checkbox should use overlay color $focusOverlayColor over $focusColor',
    );

    // Start hovering
    final TestGesture gesture5 = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture5.addPointer();
    addTearDown(gesture5.removePointer);
    await gesture5.moveTo(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: hoverOverlayColor, radius: splashRadius),
      reason: 'Hovered Checkbox should use overlay color $hoverOverlayColor over $hoverColor',
    );

    // Finish gestures to release resources.
    await gesture1.up();
    await gesture2.up();
    await gesture3.up();
    await gesture4.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Tristate Checkbox overlay color resolves in pressed active/inactive states', (
    WidgetTester tester,
  ) async {
    const activePressedOverlayColor = Color(0xFF000001);
    const inactivePressedOverlayColor = Color(0xFF000002);

    Color? getOverlayColor(Set<WidgetState> states) {
      if (states.contains(WidgetState.pressed)) {
        if (states.contains(WidgetState.selected)) {
          return activePressedOverlayColor;
        }
        return inactivePressedOverlayColor;
      }
      return null;
    }

    const splashRadius = 24.0;
    TestGesture gesture;
    bool? value = false;

    Widget buildTristateCheckbox() {
      return MaterialApp(
        theme: theme,
        home: Scaffold(
          body: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Checkbox(
                value: value,
                tristate: true,
                onChanged: (bool? v) {
                  setState(() {
                    value = v;
                  });
                },
                overlayColor: WidgetStateProperty.resolveWith(getOverlayColor),
                splashRadius: splashRadius,
              );
            },
          ),
        ),
      );
    }

    // The checkbox is inactive.
    await tester.pumpWidget(buildTristateCheckbox());
    gesture = await tester.press(find.byType(Checkbox));
    await tester.pumpAndSettle();

    expect(value, false);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: inactivePressedOverlayColor, radius: splashRadius),
      reason: 'Inactive pressed Checkbox should have overlay color: $inactivePressedOverlayColor',
    );

    // The checkbox is active.
    await gesture.up();
    gesture = await tester.press(find.byType(Checkbox));
    await tester.pumpAndSettle();

    expect(value, true);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: activePressedOverlayColor, radius: splashRadius),
      reason: 'Active pressed Checkbox should have overlay color: $activePressedOverlayColor',
    );

    // The checkbox is active in tri-state.
    await gesture.up();
    gesture = await tester.press(find.byType(Checkbox));
    await tester.pumpAndSettle();

    expect(value, null);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: activePressedOverlayColor, radius: splashRadius),
      reason:
          'Active (tristate) pressed Checkbox should have overlay color: $activePressedOverlayColor',
    );

    // The checkbox is inactive again.
    await gesture.up();
    gesture = await tester.press(find.byType(Checkbox));
    await tester.pumpAndSettle();

    expect(value, false);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..circle(color: inactivePressedOverlayColor, radius: splashRadius),
      reason: 'Inactive pressed Checkbox should have overlay color: $inactivePressedOverlayColor',
    );

    await gesture.up();
  });

  testWidgets('Do not crash when widget disappears while pointer is down', (
    WidgetTester tester,
  ) async {
    Widget buildCheckbox(bool show) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(child: show ? Checkbox(value: true, onChanged: (_) {}) : Container()),
        ),
      );
    }

    await tester.pumpWidget(buildCheckbox(true));
    final Offset center = tester.getCenter(find.byType(Checkbox));
    // Put a pointer down on the screen.
    final TestGesture gesture = await tester.startGesture(center);
    await tester.pump();
    // While the pointer is down, the widget disappears.
    await tester.pumpWidget(buildCheckbox(false));
    expect(find.byType(Checkbox), findsNothing);
    // Release pointer after widget disappeared.
    await gesture.up();
  });

  testWidgets('Checkbox BorderSide side only applies when unselected in M2', (
    WidgetTester tester,
  ) async {
    const borderColor = Color(0xfff44336);
    const activeColor = Color(0xff123456);
    const side = BorderSide(width: 4, color: borderColor);

    Widget buildApp({bool? value, bool enabled = true}) {
      return MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Material(
          child: Center(
            child: Checkbox(
              value: value,
              tristate: value == null,
              activeColor: activeColor,
              onChanged: enabled ? (bool? newValue) {} : null,
              side: side,
            ),
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    void expectBorder() {
      expect(
        getCheckboxRenderer(),
        paints..drrect(
          color: borderColor,
          outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
          inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
        ),
      );
    }

    // Checkbox is unselected, so the specified BorderSide appears.

    await tester.pumpWidget(buildApp(value: false));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp(value: false, enabled: false));
    await tester.pumpAndSettle();
    expectBorder();

    // Checkbox is selected/indeterminate, so the specified BorderSide is transparent

    await tester.pumpWidget(buildApp(value: true));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..drrect(color: Colors.transparent));
    expect(getCheckboxRenderer(), paints..rrect(color: activeColor)); // checkbox fill

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..drrect(color: Colors.transparent));
    expect(getCheckboxRenderer(), paints..rrect(color: activeColor)); // checkbox fill
  });

  testWidgets('Material2 - Checkbox WidgetStateBorderSide applies unconditionally', (
    WidgetTester tester,
  ) async {
    const borderColor = Color(0xfff44336);
    const side = BorderSide(width: 4, color: borderColor);
    final theme = ThemeData(useMaterial3: false);

    Widget buildApp({bool? value, bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: Checkbox(
              value: value,
              tristate: value == null,
              onChanged: enabled ? (bool? newValue) {} : null,
              side: WidgetStateBorderSide.resolveWith((Set<WidgetState> states) => side),
            ),
          ),
        ),
      );
    }

    void expectBorder() {
      expect(
        tester.renderObject<RenderBox>(find.byType(Checkbox)),
        paints..drrect(
          color: borderColor,
          outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
          inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
        ),
      );
    }

    await tester.pumpWidget(buildApp(value: false));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp(value: false, enabled: false));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp(value: true));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expectBorder();
  });

  testWidgets('Material3 - Checkbox WidgetStateBorderSide applies unconditionally', (
    WidgetTester tester,
  ) async {
    const borderColor = Color(0xfff44336);
    const side = BorderSide(width: 4, color: borderColor);
    final theme = ThemeData();

    Widget buildApp({bool? value, bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: Checkbox(
              value: value,
              tristate: value == null,
              onChanged: enabled ? (bool? newValue) {} : null,
              side: WidgetStateBorderSide.resolveWith((Set<WidgetState> states) => side),
            ),
          ),
        ),
      );
    }

    void expectBorder() {
      expect(
        tester.renderObject<RenderBox>(find.byType(Checkbox)),
        paints..drrect(
          color: borderColor,
          outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)),
          inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
        ),
      );
    }

    await tester.pumpWidget(buildApp(value: false));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp(value: false, enabled: false));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp(value: true));
    await tester.pumpAndSettle();
    expectBorder();

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expectBorder();
  });

  testWidgets('disabled checkbox shows tooltip', (WidgetTester tester) async {
    const longPressTooltip = 'long press tooltip';
    const tapTooltip = 'tap tooltip';
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Tooltip(message: longPressTooltip, child: Checkbox(value: true, onChanged: null)),
        ),
      ),
    );

    // Default tooltip shows up after long pressed.
    final Finder tooltip0 = find.byType(Tooltip);
    expect(find.text(longPressTooltip), findsNothing);

    await tester.tap(tooltip0);
    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text(longPressTooltip), findsNothing);

    final TestGesture gestureLongPress = await tester.startGesture(tester.getCenter(tooltip0));
    await tester.pump();
    await tester.pump(kLongPressTimeout);
    await gestureLongPress.up();
    await tester.pump();

    expect(find.text(longPressTooltip), findsOneWidget);

    // Tooltip shows up after tapping when set triggerMode to TooltipTriggerMode.tap.
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Tooltip(
            triggerMode: TooltipTriggerMode.tap,
            message: tapTooltip,
            child: Checkbox(value: true, onChanged: null),
          ),
        ),
      ),
    );

    await tester.pump(const Duration(days: 1));
    await tester.pumpAndSettle();
    expect(find.text(tapTooltip), findsNothing);
    expect(find.text(longPressTooltip), findsNothing);

    final Finder tooltip1 = find.byType(Tooltip);
    await tester.tap(tooltip1);
    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text(tapTooltip), findsOneWidget);
  });

  testWidgets('Material3 - Checkbox has default error color when isError is set to true', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'Checkbox');
    addTearDown(focusNode.dispose);
    final themeData = ThemeData();
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = true;
    Widget buildApp({bool autoFocus = true}) {
      return MaterialApp(
        theme: themeData,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  isError: true,
                  value: value,
                  onChanged: (bool? newValue) {
                    setState(() {
                      value = newValue;
                    });
                  },
                  autofocus: autoFocus,
                  focusNode: focusNode,
                );
              },
            ),
          ),
        ),
      );
    }

    // Focused
    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: themeData.colorScheme.error.withOpacity(0.1))
        ..rrect(color: themeData.colorScheme.error)
        ..path(color: themeData.colorScheme.onError),
    );

    // Default color
    await tester.pumpWidget(Container());
    await tester.pumpWidget(buildApp(autoFocus: false));
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isFalse);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..rrect(color: themeData.colorScheme.error)
        ..path(color: themeData.colorScheme.onError),
    );

    // Start hovering
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();

    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: themeData.colorScheme.error.withOpacity(0.08))
        ..rrect(color: themeData.colorScheme.error),
    );

    // Start pressing
    final TestGesture gestureLongPress = await tester.startGesture(
      tester.getCenter(find.byType(Checkbox)),
    );
    await tester.pump();
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints
        ..circle(color: themeData.colorScheme.error.withOpacity(0.1))
        ..rrect(color: themeData.colorScheme.error),
    );
    await gestureLongPress.up();
    await tester.pump();
  });

  testWidgets('Material3 - Checkbox WidgetStateBorderSide applies in error states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'Checkbox');
    addTearDown(focusNode.dispose);
    final themeData = ThemeData();
    const borderColor = Color(0xffffeb3b);
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    bool? value = false;
    Widget buildApp({bool autoFocus = true}) {
      return MaterialApp(
        theme: themeData,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(
                  isError: true,
                  side: WidgetStateBorderSide.resolveWith((Set<WidgetState> states) {
                    if (states.contains(WidgetState.error)) {
                      return const BorderSide(color: borderColor, width: 4);
                    }
                    return const BorderSide(color: Colors.red, width: 2);
                  }),
                  value: value,
                  onChanged: (bool? newValue) {
                    setState(() {
                      value = newValue;
                    });
                  },
                  autofocus: autoFocus,
                  focusNode: focusNode,
                );
              },
            ),
          ),
        ),
      );
    }

    void expectBorder() {
      expect(
        tester.renderObject<RenderBox>(find.byType(Checkbox)),
        paints..drrect(
          color: borderColor,
          outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)),
          inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expectBorder();

    // Focused
    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isTrue);
    expectBorder();

    // Default color
    await tester.pumpWidget(Container());
    await tester.pumpWidget(buildApp(autoFocus: false));
    await tester.pumpAndSettle();
    expect(focusNode.hasPrimaryFocus, isFalse);
    expectBorder();

    // Start hovering
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
    await tester.pumpAndSettle();
    expectBorder();

    // Start pressing
    final TestGesture gestureLongPress = await tester.startGesture(
      tester.getCenter(find.byType(Checkbox)),
    );
    await tester.pump();
    expectBorder();
    await gestureLongPress.up();
    await tester.pump();
  });

  testWidgets('Material3 - Checkbox has correct default shape', (WidgetTester tester) async {
    final themeData = ThemeData();

    Widget buildApp() {
      return MaterialApp(
        theme: themeData,
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox(value: false, onChanged: (bool? newValue) {});
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();

    final OutlinedBorder? expectedShape = themeData.checkboxTheme.shape;
    expect(tester.widget<Checkbox>(find.byType(Checkbox)).shape, expectedShape);
    expect(
      Material.of(tester.element(find.byType(Checkbox))),
      paints..drrect(
        outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2)),
        inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
      ),
    );
  });

  testWidgets('Checkbox.adaptive shows the correct platform widget', (WidgetTester tester) async {
    Widget buildApp(TargetPlatform platform) {
      return MaterialApp(
        theme: ThemeData(platform: platform),
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Checkbox.adaptive(value: false, onChanged: (bool? newValue) {});
              },
            ),
          ),
        ),
      );
    }

    for (final platform in <TargetPlatform>[TargetPlatform.iOS, TargetPlatform.macOS]) {
      await tester.pumpWidget(buildApp(platform));
      await tester.pumpAndSettle();

      expect(find.byType(CupertinoCheckbox), findsOneWidget);
    }

    for (final platform in <TargetPlatform>[
      TargetPlatform.android,
      TargetPlatform.fuchsia,
      TargetPlatform.linux,
      TargetPlatform.windows,
    ]) {
      await tester.pumpWidget(buildApp(platform));
      await tester.pumpAndSettle();

      expect(find.byType(CupertinoCheckbox), findsNothing);
    }
  });

  testWidgets(
    'Checkbox.adaptive respects Checkbox.mouseCursor on iOS/macOS',
    (WidgetTester tester) async {
      Widget buildApp({MouseCursor? mouseCursor}) {
        return MaterialApp(
          home: Material(
            child: Checkbox.adaptive(
              value: true,
              onChanged: (bool? newValue) {},
              mouseCursor: mouseCursor,
            ),
          ),
        );
      }

      await tester.pumpWidget(buildApp());
      final TestGesture gesture = await tester.createGesture(
        kind: PointerDeviceKind.mouse,
        pointer: 1,
      );
      await gesture.addPointer(location: tester.getCenter(find.byType(CupertinoCheckbox)));
      await tester.pump();
      await gesture.moveTo(tester.getCenter(find.byType(CupertinoCheckbox)));
      expect(
        RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
        kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
      );

      // Test mouse cursor can be configured.
      await tester.pumpWidget(buildApp(mouseCursor: SystemMouseCursors.click));
      expect(
        RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
        SystemMouseCursors.click,
      );

      // Test Checkbox.adaptive can resolve a WidgetStateMouseCursor.
      await tester.pumpWidget(buildApp(mouseCursor: const _SelectedGrabMouseCursor()));
      expect(
        RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
        SystemMouseCursors.grab,
      );

      await gesture.removePointer();
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.iOS,
      TargetPlatform.macOS,
    }),
  );

  testWidgets('Material2 - Checkbox respects fillColor when it is unchecked', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData(useMaterial3: false);
    const activeBackgroundColor = Color(0xff123456);
    const inactiveBackgroundColor = Color(0xff654321);

    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: Checkbox(
              fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
                if (states.contains(WidgetState.selected)) {
                  return activeBackgroundColor;
                }
                return inactiveBackgroundColor;
              }),
              value: false,
              onChanged: enabled ? (bool? newValue) {} : null,
            ),
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    // Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..drrect(color: theme.unselectedWidgetColor));
    expect(getCheckboxRenderer(), paints..rrect(color: inactiveBackgroundColor));

    await tester.pumpWidget(buildApp(enabled: false));
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..drrect(color: theme.disabledColor));
    expect(getCheckboxRenderer(), paints..rrect(color: inactiveBackgroundColor));
  });

  testWidgets('Material3 - Checkbox respects fillColor when it is unchecked', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData();
    const activeBackgroundColor = Color(0xff123456);
    const inactiveBackgroundColor = Color(0xff654321);

    Widget buildApp({bool enabled = true}) {
      return MaterialApp(
        theme: theme,
        home: Material(
          child: Center(
            child: Checkbox(
              fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
                if (states.contains(WidgetState.selected)) {
                  return activeBackgroundColor;
                }
                return inactiveBackgroundColor;
              }),
              value: false,
              onChanged: enabled ? (bool? newValue) {} : null,
            ),
          ),
        ),
      );
    }

    RenderBox getCheckboxRenderer() {
      return tester.renderObject<RenderBox>(find.byType(Checkbox));
    }

    // Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
    await tester.pumpWidget(buildApp());
    await tester.pumpAndSettle();
    expect(getCheckboxRenderer(), paints..drrect(color: theme.colorScheme.onSurfaceVariant));
    expect(getCheckboxRenderer(), paints..rrect(color: inactiveBackgroundColor));

    await tester.pumpWidget(buildApp(enabled: false));
    await tester.pumpAndSettle();
    expect(
      getCheckboxRenderer(),
      paints..drrect(color: theme.colorScheme.onSurface.withOpacity(0.38)),
    );
    expect(getCheckboxRenderer(), paints..rrect(color: inactiveBackgroundColor));
  });

  testWidgets('Checkbox renders at zero area', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Center(
          child: SizedBox.shrink(child: Scaffold(body: Checkbox(value: true, onChanged: null))),
        ),
      ),
    );
    expect(tester.takeException(), isNull);
  });
}

class _SelectedGrabMouseCursor extends WidgetStateMouseCursor {
  const _SelectedGrabMouseCursor();

  @override
  MouseCursor resolve(Set<WidgetState> states) {
    if (states.contains(WidgetState.selected)) {
      return SystemMouseCursors.grab;
    }
    return SystemMouseCursors.basic;
  }

  @override
  String get debugDescription => '_SelectedGrabMouseCursor()';
}
