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

// reduced-test-set:
//   This file is run as part of a reduced test set in CI on Mac and Windows
//   machines.
@Tags(<String>['reduced-test-set'])
library;

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

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

void main() {
  testWidgets('Radio control test', (WidgetTester tester) async {
    final Key key = UniqueKey();
    final log = <int?>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(key: key, value: 1, groupValue: 2, onChanged: log.add),
        ),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, equals(<int>[1]));
    log.clear();

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            key: key,
            value: 1,
            groupValue: 1,
            onChanged: log.add,
            activeColor: CupertinoColors.systemGreen,
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, isEmpty);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(key: key, value: 1, groupValue: 2)),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, isEmpty);
  });

  testWidgets('Radio disabled', (WidgetTester tester) async {
    final Key key = UniqueKey();
    final log = <int?>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            key: key,
            value: 1,
            groupValue: 2,
            enabled: false,
            onChanged: log.add,
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, equals(<int>[]));
  });

  testWidgets('Radio can be toggled when toggleable is set', (WidgetTester tester) async {
    final Key key = UniqueKey();
    final log = <int?>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            key: key,
            value: 1,
            groupValue: 2,
            onChanged: log.add,
            toggleable: true,
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, equals(<int>[1]));
    log.clear();

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            key: key,
            value: 1,
            groupValue: 1,
            onChanged: log.add,
            toggleable: true,
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, equals(<int?>[null]));
    log.clear();

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(key: key, value: 1, onChanged: log.add, toggleable: true),
        ),
      ),
    );

    await tester.tap(find.byKey(key));

    expect(log, equals(<int>[1]));
  });

  testWidgets('Radio selected semantics - platform adaptive', (WidgetTester tester) async {
    final semantics = SemanticsTester(tester);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 1, onChanged: (int? i) {})),
      ),
    );

    final bool isApple =
        defaultTargetPlatform == TargetPlatform.iOS ||
        defaultTargetPlatform == TargetPlatform.macOS;
    expect(
      semantics,
      includesNodeWith(
        flags: <SemanticsFlag>[
          SemanticsFlag.isInMutuallyExclusiveGroup,
          SemanticsFlag.hasCheckedState,
          SemanticsFlag.hasEnabledState,
          SemanticsFlag.isEnabled,
          SemanticsFlag.isFocusable,
          SemanticsFlag.isChecked,
          if (isApple) SemanticsFlag.hasSelectedState,
          if (isApple) SemanticsFlag.isSelected,
        ],
        actions: <SemanticsAction>[
          SemanticsAction.tap,
          if (defaultTargetPlatform != TargetPlatform.iOS) SemanticsAction.focus,
        ],
      ),
    );
    semantics.dispose();
  }, variant: TargetPlatformVariant.all());

  testWidgets('Radio semantics', (WidgetTester tester) async {
    final semantics = SemanticsTester(tester);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 2, onChanged: (int? i) {})),
      ),
    );

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

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 2, groupValue: 2, onChanged: (int? i) {})),
      ),
    );

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

    await tester.pumpWidget(
      const CupertinoApp(home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 2))),
    );

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

    await tester.pump();

    // Now the isFocusable should be gone.
    expect(
      tester.getSemantics(find.byType(Focus).last),
      matchesSemantics(
        hasCheckedState: true,
        hasEnabledState: true,
        isInMutuallyExclusiveGroup: true,
      ),
    );

    await tester.pumpWidget(
      const CupertinoApp(home: Center(child: CupertinoRadio<int>(value: 2, groupValue: 2))),
    );

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

    semantics.dispose();
  });

  testWidgets('has semantic events', (WidgetTester tester) async {
    final semantics = SemanticsTester(tester);
    final Key key = UniqueKey();
    dynamic semanticEvent;
    int? radioValue = 2;
    tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(
      SystemChannels.accessibility,
      (dynamic message) async {
        semanticEvent = message;
      },
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            key: key,
            value: 1,
            groupValue: radioValue,
            onChanged: (int? i) {
              radioValue = i;
            },
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(key));
    final RenderObject object = tester.firstRenderObject(find.byKey(key));

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

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

  testWidgets('Radio can be controlled by keyboard shortcuts', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    int? groupValue = 1;
    const radioKey0 = Key('radio0');
    const radioKey1 = Key('radio1');
    const radioKey2 = Key('radio2');
    final focusNode2 = FocusNode(debugLabel: 'radio2');
    addTearDown(focusNode2.dispose);
    Widget buildApp({bool enabled = true}) {
      return CupertinoApp(
        home: Center(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return SizedBox(
                width: 200,
                height: 100,
                child: Row(
                  children: <Widget>[
                    CupertinoRadio<int>(
                      key: radioKey0,
                      value: 0,
                      onChanged: enabled
                          ? (int? newValue) {
                              setState(() {
                                groupValue = newValue;
                              });
                            }
                          : null,
                      groupValue: groupValue,
                      autofocus: true,
                    ),
                    CupertinoRadio<int>(
                      key: radioKey1,
                      value: 1,
                      onChanged: enabled
                          ? (int? newValue) {
                              setState(() {
                                groupValue = newValue;
                              });
                            }
                          : null,
                      groupValue: groupValue,
                    ),
                    CupertinoRadio<int>(
                      key: radioKey2,
                      value: 2,
                      onChanged: enabled
                          ? (int? newValue) {
                              setState(() {
                                groupValue = newValue;
                              });
                            }
                          : null,
                      groupValue: groupValue,
                      focusNode: focusNode2,
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      );
    }

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

    await tester.sendKeyEvent(LogicalKeyboardKey.enter);
    await tester.pumpAndSettle();
    // On web, radios don't respond to the enter key.
    expect(groupValue, kIsWeb ? equals(1) : equals(0));

    focusNode2.requestFocus();
    await tester.pumpAndSettle();

    await tester.sendKeyEvent(LogicalKeyboardKey.space);
    await tester.pumpAndSettle();
    expect(groupValue, equals(2));
  });

  testWidgets('Show a checkmark when useCheckmarkStyle is true', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 1, onChanged: (int? i) {})),
      ),
    );
    await tester.pumpAndSettle();

    // Has no checkmark when useCheckmarkStyle is false
    expect(
      tester.firstRenderObject<RenderBox>(find.byType(CupertinoRadio<int>)),
      isNot(paints..path()),
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 2,
            useCheckmarkStyle: true,
            onChanged: (int? i) {},
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    // Has no checkmark when group value doesn't match the value
    expect(
      tester.firstRenderObject<RenderBox>(find.byType(CupertinoRadio<int>)),
      isNot(paints..path()),
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 1,
            useCheckmarkStyle: true,
            onChanged: (int? i) {},
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    // Draws a path to show the checkmark when toggled on
    expect(tester.firstRenderObject<RenderBox>(find.byType(CupertinoRadio<int>)), paints..path());
  });

  testWidgets('Do not crash when widget disappears while pointer is down', (
    WidgetTester tester,
  ) async {
    final Key key = UniqueKey();

    Widget buildRadio(bool show) {
      return CupertinoApp(
        home: Center(
          child: show
              ? CupertinoRadio<bool>(key: key, value: true, groupValue: false, onChanged: (_) {})
              : Container(),
        ),
      );
    }

    await tester.pumpWidget(buildRadio(true));
    final Offset center = tester.getCenter(find.byKey(key));
    // 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(buildRadio(false));
    expect(find.byKey(key), findsNothing);
    // Release pointer after widget disappeared.
    await gesture.up();
  });

  testWidgets('Radio has correct default active/inactive/fill/border colors in light mode', (
    WidgetTester tester,
  ) async {
    Widget buildRadio({required int value, required int groupValue}) {
      return CupertinoApp(
        home: Center(
          child: RepaintBoundary(
            child: CupertinoRadio<int>(
              value: value,
              groupValue: groupValue,
              onChanged: (int? i) {},
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildRadio(value: 1, groupValue: 1));
    await expectLater(
      find.byType(CupertinoRadio<int>),
      matchesGoldenFile('radio.light_theme.selected.png'),
    );
    await tester.pumpWidget(buildRadio(value: 1, groupValue: 2));
    await expectLater(
      find.byType(CupertinoRadio<int>),
      matchesGoldenFile('radio.light_theme.unselected.png'),
    );
  });

  testWidgets('Radio has correct default active/inactive/fill/border colors in dark mode', (
    WidgetTester tester,
  ) async {
    Widget buildRadio({required int value, required int groupValue, bool enabled = true}) {
      return CupertinoApp(
        theme: const CupertinoThemeData(brightness: Brightness.dark),
        home: Center(
          child: RepaintBoundary(
            child: CupertinoRadio<int>(
              value: value,
              groupValue: groupValue,
              onChanged: enabled ? (int? i) {} : null,
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildRadio(value: 1, groupValue: 1));
    await expectLater(
      find.byType(CupertinoRadio<int>),
      matchesGoldenFile('radio.dark_theme.selected.png'),
    );
    await tester.pumpWidget(buildRadio(value: 1, groupValue: 2));
    await expectLater(
      find.byType(CupertinoRadio<int>),
      matchesGoldenFile('radio.dark_theme.unselected.png'),
    );
  });

  testWidgets(
    'Disabled radio has correct default active/inactive/fill/border colors in light mode',
    (WidgetTester tester) async {
      Widget buildRadio({required int value, required int groupValue}) {
        return CupertinoApp(
          home: Center(
            child: RepaintBoundary(
              child: CupertinoRadio<int>(value: value, groupValue: groupValue),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildRadio(value: 1, groupValue: 1));
      await expectLater(
        find.byType(CupertinoRadio<int>),
        matchesGoldenFile('radio.disabled_light_theme.selected.png'),
      );
      await tester.pumpWidget(buildRadio(value: 1, groupValue: 2));
      await expectLater(
        find.byType(CupertinoRadio<int>),
        matchesGoldenFile('radio.disabled_light_theme.unselected.png'),
      );
    },
  );

  testWidgets(
    'Disabled radio has correct default active/inactive/fill/border colors in dark mode',
    (WidgetTester tester) async {
      Widget buildRadio({required int value, required int groupValue}) {
        return CupertinoApp(
          theme: const CupertinoThemeData(brightness: Brightness.dark),
          home: Center(
            child: RepaintBoundary(
              child: CupertinoRadio<int>(value: value, groupValue: groupValue),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildRadio(value: 1, groupValue: 1));
      await expectLater(
        find.byType(CupertinoRadio<int>),
        matchesGoldenFile('radio.disabled_dark_theme.selected.png'),
      );
      await tester.pumpWidget(buildRadio(value: 1, groupValue: 2));
      await expectLater(
        find.byType(CupertinoRadio<int>),
        matchesGoldenFile('radio.disabled_dark_theme.unselected.png'),
      );
    },
  );

  testWidgets('Radio can set inactive/active/fill colors', (WidgetTester tester) async {
    const inactiveBorderColor = Color(0xffd1d1d6);
    const activeColor = Color(0x0000000A);
    const fillColor = Color(0x0000000B);
    const inactiveColor = Color(0x0000000C);
    const innerRadius = 2.975;
    const outerRadius = 7.0;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 2,
            onChanged: (int? i) {},
            activeColor: activeColor,
            fillColor: fillColor,
            inactiveColor: inactiveColor,
          ),
        ),
      ),
    );

    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: inactiveColor)
        ..circle(radius: outerRadius, style: PaintingStyle.stroke, color: inactiveBorderColor),
      reason: 'Unselected radio button should use inactive and border colors',
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 1,
            onChanged: (int? i) {},
            activeColor: activeColor,
            fillColor: fillColor,
            inactiveColor: inactiveColor,
          ),
        ),
      ),
    );

    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: activeColor)
        ..circle(radius: innerRadius, style: PaintingStyle.fill, color: fillColor),
      reason: 'Selected radio button should use active and fill colors',
    );
  });

  testWidgets('Radio is slightly darkened when pressed in light mode', (WidgetTester tester) async {
    const activeInnerColor = Color(0xffffffff);
    const activeOuterColor = Color(0xff007aff);
    const inactiveBorderColor = Color(0xffd1d1d6);
    const inactiveOuterColor = Color(0xffffffff);
    const innerRadius = 2.975;
    const outerRadius = 7.0;
    const pressedShadowColor = Color(0x26ffffff);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 2, onChanged: (int? i) {})),
      ),
    );

    final TestGesture gesture1 = await tester.startGesture(
      tester.getCenter(find.byType(CupertinoRadio<int>)),
    );
    await tester.pump();

    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: inactiveOuterColor)
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: pressedShadowColor)
        ..circle(radius: outerRadius, style: PaintingStyle.stroke, color: inactiveBorderColor),
      reason: 'Unselected pressed radio button is slightly darkened',
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 2, groupValue: 2, onChanged: (int? i) {})),
      ),
    );

    final TestGesture gesture2 = await tester.startGesture(
      tester.getCenter(find.byType(CupertinoRadio<int>)),
    );
    await tester.pump();

    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: activeOuterColor)
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: pressedShadowColor)
        ..circle(radius: innerRadius, style: PaintingStyle.fill, color: activeInnerColor),
      reason: 'Selected pressed radio button is slightly darkened',
    );

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

  testWidgets('Radio is slightly lightened when pressed in dark mode', (WidgetTester tester) async {
    const activeInnerColor = Color(0xffffffff);
    const activeOuterColor = Color(0xff007aff);
    const inactiveBorderColor = Color(0x40000000);
    const innerRadius = 2.975;
    const outerRadius = 7.0;
    const pressedShadowColor = Color(0x26ffffff);

    await tester.pumpWidget(
      CupertinoApp(
        theme: const CupertinoThemeData(brightness: Brightness.dark),
        home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 2, onChanged: (int? i) {})),
      ),
    );

    final TestGesture gesture1 = await tester.startGesture(
      tester.getCenter(find.byType(CupertinoRadio<int>)),
    );
    await tester.pump();

    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..path()
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: pressedShadowColor)
        ..circle(radius: outerRadius, style: PaintingStyle.stroke, color: inactiveBorderColor),
      reason: 'Unselected pressed radio button is slightly lightened',
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 2, groupValue: 2, onChanged: (int? i) {})),
      ),
    );

    final TestGesture gesture2 = await tester.startGesture(
      tester.getCenter(find.byType(CupertinoRadio<int>)),
    );
    await tester.pump();

    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: activeOuterColor)
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: pressedShadowColor)
        ..circle(radius: innerRadius, style: PaintingStyle.fill, color: activeInnerColor),
      reason: 'Selected pressed radio button is slightly lightened',
    );

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

  testWidgets('Radio is focusable and has correct focus colors', (WidgetTester tester) async {
    const activeInnerColor = Color(0xffffffff);
    const activeOuterColor = Color(0xff007aff);
    final Color defaultFocusColor =
        HSLColor.fromColor(CupertinoColors.activeBlue.withOpacity(kCupertinoFocusColorOpacity))
            .withLightness(kCupertinoFocusColorBrightness)
            .withSaturation(kCupertinoFocusColorSaturation)
            .toColor();
    const innerRadius = 2.975;
    const outerRadius = 7.0;
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    final node = FocusNode();
    addTearDown(node.dispose);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 1,
            onChanged: (int? i) {},
            focusNode: node,
            autofocus: true,
          ),
        ),
      ),
    );

    await tester.pump();
    expect(node.hasPrimaryFocus, isTrue);
    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: activeOuterColor)
        ..circle(radius: innerRadius, style: PaintingStyle.fill, color: activeInnerColor)
        ..circle(strokeWidth: 3.0, style: PaintingStyle.stroke, color: defaultFocusColor),
      reason: 'Radio is focusable and shows the default focus color',
    );
  });

  testWidgets('Radio can configure a focus color', (WidgetTester tester) async {
    const activeInnerColor = Color(0xffffffff);
    const activeOuterColor = Color(0xff007aff);
    const focusColor = Color(0x0000000A);
    const innerRadius = 2.975;
    const outerRadius = 7.0;
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    final node = FocusNode();
    addTearDown(node.dispose);

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 1,
            onChanged: (int? i) {},
            focusColor: focusColor,
            focusNode: node,
            autofocus: true,
          ),
        ),
      ),
    );

    await tester.pump();
    expect(node.hasPrimaryFocus, isTrue);
    expect(
      find.byType(CupertinoRadio<int>),
      paints
        ..circle(radius: outerRadius, style: PaintingStyle.fill, color: activeOuterColor)
        ..circle(radius: innerRadius, style: PaintingStyle.fill, color: activeInnerColor)
        ..circle(strokeWidth: 3.0, style: PaintingStyle.stroke, color: focusColor),
      reason: 'Radio configures the color of the focus outline',
    );
  });

  testWidgets('Radio configures mouse cursor', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 1,
            onChanged: (int? i) {},
            mouseCursor: SystemMouseCursors.forbidden,
          ),
        ),
      ),
    );
    final TestGesture gesture = await tester.createGesture(
      kind: PointerDeviceKind.mouse,
      pointer: 1,
    );
    addTearDown(gesture.removePointer);
    await gesture.addPointer(location: tester.getCenter(find.byType(CupertinoRadio<int>)));
    await tester.pump();
    await gesture.moveTo(tester.getCenter(find.byType(CupertinoRadio<int>)));
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.forbidden,
    );
  });

  testWidgets('Mouse cursor resolves in disabled/hovered/focused states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'Radio');
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;

    await tester.pumpWidget(
      CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(
            value: 1,
            groupValue: 1,
            onChanged: (int? i) {},
            mouseCursor: const _RadioMouseCursor(),
            focusNode: focusNode,
          ),
        ),
      ),
    );
    final TestGesture gesture = await tester.createGesture(
      kind: PointerDeviceKind.mouse,
      pointer: 1,
    );
    addTearDown(gesture.removePointer);
    await gesture.addPointer(location: tester.getCenter(find.byType(CupertinoRadio<int>)));
    await tester.pump();

    // Test hovered case.
    await gesture.moveTo(tester.getCenter(find.byType(CupertinoRadio<int>)));
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.click,
    );

    // Test focused case.
    focusNode.requestFocus();
    await tester.pump();
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.basic,
    );

    // Test disabled case.
    await tester.pumpWidget(
      const CupertinoApp(
        home: Center(
          child: CupertinoRadio<int>(value: 1, groupValue: 1, mouseCursor: _RadioMouseCursor()),
        ),
      ),
    );

    await tester.pump();
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.forbidden,
    );
    focusNode.dispose();
  });

  testWidgets('Radio default mouse cursor', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 1, onChanged: (int? i) {})),
      ),
    );
    final TestGesture gesture = await tester.createGesture(
      kind: PointerDeviceKind.mouse,
      pointer: 1,
    );
    addTearDown(gesture.removePointer);
    await gesture.addPointer(location: tester.getCenter(find.byType(CupertinoRadio<int>)));
    await tester.pump();
    await gesture.moveTo(tester.getCenter(find.byType(CupertinoRadio<int>)));
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
    );
  });

  // Regression tests for https://github.com/flutter/flutter/issues/170422
  group('Radio accessibility announcements on various platforms', () {
    testWidgets('Unselected radio should be vocalized via hint on iOS/macOS platform', (
      WidgetTester tester,
    ) async {
      const WidgetsLocalizations localizations = DefaultWidgetsLocalizations();
      await tester.pumpWidget(
        CupertinoApp(
          home: Center(child: CupertinoRadio<int>(value: 2, groupValue: 1, onChanged: (int? i) {})),
        ),
      );

      final SemanticsNode semanticNode = tester.getSemantics(find.byType(Focus).last);
      if (defaultTargetPlatform == TargetPlatform.iOS ||
          defaultTargetPlatform == TargetPlatform.macOS) {
        expect(semanticNode.hint, localizations.radioButtonUnselectedLabel);
      } else {
        expect(semanticNode.hint, anyOf(isNull, isEmpty));
      }
    });

    testWidgets('Selected radio should be vocalized via the selected flag on all platforms', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        CupertinoApp(
          home: Center(child: CupertinoRadio<int>(value: 1, groupValue: 1, onChanged: (int? i) {})),
        ),
      );

      final SemanticsNode semanticNode = tester.getSemantics(find.byType(Focus).last);
      // Radio semantics should not have hint.
      expect(semanticNode.hint, anyOf(isNull, isEmpty));
    });
  });

  testWidgets('CupertinoRadio does not crash at zero area', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Center(child: SizedBox.shrink(child: CupertinoRadio<bool>(value: false))),
      ),
    );
    expect(tester.getSize(find.byType(CupertinoRadio<bool>)), Size.zero);
  });
}

class _RadioMouseCursor extends WidgetStateMouseCursor {
  const _RadioMouseCursor();

  @override
  MouseCursor resolve(Set<WidgetState> states) {
    if (states.contains(WidgetState.disabled)) {
      return SystemMouseCursors.forbidden;
    }
    if (states.contains(WidgetState.focused)) {
      return SystemMouseCursors.basic;
    }
    return SystemMouseCursors.click;
  }

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