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

import 'multi_view_testing.dart';

void main() {
  testWidgets('Providing a RenderObjectWidget directly to the RootWidget fails', (WidgetTester tester) async {
    // No render tree exists to attach the RenderObjectWidget to.
    await tester.pumpWidget(
      wrapWithView: false,
      const ColoredBox(color: Colors.red),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      startsWith('The render object for ColoredBox cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('Moving a RenderObjectWidget to the RootWidget via GlobalKey fails', (WidgetTester tester) async {
    final Widget globalKeyedWidget = ColoredBox(
      key: GlobalKey(),
      color: Colors.red,
    );

    await tester.pumpWidget(
      wrapWithView: false,
      View(
        view: tester.view,
        child: globalKeyedWidget,
      ),
    );
    expect(tester.takeException(), isNull);

    await tester.pumpWidget(
      wrapWithView: false,
      globalKeyedWidget,
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      contains('cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('A View cannot be a child of a render object widget',
  experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), // leaking by design because of exception
  (WidgetTester tester) async {
    await tester.pumpWidget(Center(
      child: View(
        view: FakeView(tester.view),
        child: Container(),
      ),
    ));

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      contains('cannot maintain an independent render tree at its current location.'),
    ));
  });

  testWidgets('The child of a ViewAnchor cannot be a View',
  experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), // leaking by design because of exception
  (WidgetTester tester) async {
    await tester.pumpWidget(
      ViewAnchor(
        child: View(
          view: FakeView(tester.view),
          child: Container(),
        ),
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      contains('cannot maintain an independent render tree at its current location.'),
    ));
  });

  testWidgets('A View can not be moved via GlobalKey to be a child of a RenderObject', (WidgetTester tester) async {
    final Widget globalKeyedView = View(
      key: GlobalKey(),
      view: FakeView(tester.view),
      child: const ColoredBox(color: Colors.red),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      globalKeyedView,
    );
    expect(tester.takeException(), isNull);

    await tester.pumpWidget(
      wrapWithView: false,
      View(
        view: tester.view,
        child: globalKeyedView,
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      contains('cannot maintain an independent render tree at its current location.'),
    ));
  });

  testWidgets('The view property of a ViewAnchor cannot be a render object widget', (WidgetTester tester) async {
    await tester.pumpWidget(
      ViewAnchor(
        view: const ColoredBox(color: Colors.red),
        child: Container(),
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      startsWith('The render object for ColoredBox cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('A RenderObject cannot be moved into the view property of a ViewAnchor via GlobalKey', (WidgetTester tester) async {
    final Widget globalKeyedWidget = ColoredBox(
      key: GlobalKey(),
      color: Colors.red,
    );

    await tester.pumpWidget(
      ViewAnchor(
        child: globalKeyedWidget,
      ),
    );
    expect(tester.takeException(), isNull);

    await tester.pumpWidget(
      ViewAnchor(
        view: globalKeyedWidget,
        child: const SizedBox(),
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      contains('cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('ViewAnchor cannot be used at the top of the widget tree (outside of View)', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapWithView: false,
      const ViewAnchor(
        child: SizedBox(),
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      startsWith('The render object for SizedBox cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('ViewAnchor cannot be moved to the top of the widget tree (outside of View) via GlobalKey', (WidgetTester tester) async {
    final Widget globalKeyedViewAnchor = ViewAnchor(
      key: GlobalKey(),
      child: const SizedBox(),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      View(
        view: tester.view,
        child: globalKeyedViewAnchor,
      ),
    );
    expect(tester.takeException(), isNull);

    await tester.pumpWidget(
      wrapWithView: false,
      globalKeyedViewAnchor,
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      contains('cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('View can be used at the top of the widget tree', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapWithView: false,
      View(
        view: tester.view,
        child: Container(),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  testWidgets('View can be moved to the top of the widget tree view GlobalKey', (WidgetTester tester) async {
    final Widget globalKeyView = View(
      view: FakeView(tester.view),
      child: const ColoredBox(color: Colors.red),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      View(
        view: tester.view,
        child: ViewAnchor(
          view: globalKeyView, // This one has trouble when deactivating
          child: const SizedBox(),
        ),
      ),
    );
    expect(tester.takeException(), isNull);
    expect(find.byType(SizedBox), findsOneWidget);
    expect(find.byType(ColoredBox), findsOneWidget);

    await tester.pumpWidget(
      wrapWithView: false,
      globalKeyView,
    );
    expect(tester.takeException(), isNull);
    expect(find.byType(SizedBox), findsNothing);
    expect(find.byType(ColoredBox), findsOneWidget);
  });

  testWidgets('ViewCollection can be used at the top of the widget tree', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: tester.view,
            child: Container(),
          ),
        ],
      ),
    );

    expect(tester.takeException(), isNull);
  });

  testWidgets('ViewCollection cannot be used inside a View', (WidgetTester tester) async {
    await tester.pumpWidget(
      ViewCollection(
        views: <Widget>[
          View(
            view: FakeView(tester.view),
            child: Container(),
          ),
        ],
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      startsWith('The Element for ViewCollection cannot be inserted into slot "null" of its ancestor.'),
    ));
  });

  testWidgets('ViewCollection can be used as ViewAnchor.view', (WidgetTester tester) async {
    await tester.pumpWidget(
      ViewAnchor(
        view: ViewCollection(
          views: <Widget>[
            View(
              view: FakeView(tester.view),
              child: Container(),
            )
          ],
        ),
        child: Container(),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  testWidgets('ViewCollection cannot have render object widgets as children', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapWithView: false,
      const ViewCollection(
        views: <Widget>[
          ColoredBox(color: Colors.red),
        ],
      ),
    );

    expect(tester.takeException(), isFlutterError.having(
      (FlutterError error) => error.message,
      'message',
      startsWith('The render object for ColoredBox cannot find ancestor render object to attach to.'),
    ));
  });

  testWidgets('Views can be moved in and out of ViewCollections via GlobalKey', (WidgetTester tester) async {
    final Widget greenView = View(
      key: GlobalKey(debugLabel: 'green'),
      view: tester.view,
      child: const ColoredBox(color: Colors.green),
    );
    final Widget redView = View(
      key: GlobalKey(debugLabel: 'red'),
      view: FakeView(tester.view),
      child: const ColoredBox(color: Colors.red),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          greenView,
          ViewCollection(
            views: <Widget>[
              redView,
            ],
          ),
        ]
      ),
    );
    expect(tester.takeException(), isNull);
    expect(find.byType(ColoredBox), findsNWidgets(2));

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
          views: <Widget>[
            redView,
            ViewCollection(
              views: <Widget>[
                greenView,
              ],
            ),
          ]
      ),
    );
    expect(tester.takeException(), isNull);
    expect(find.byType(ColoredBox), findsNWidgets(2));
  });

  testWidgets('Can move stuff between views via global key: viewA -> viewB', (WidgetTester tester) async {
    final FlutterView greenView = tester.view;
    final FlutterView redView = FakeView(tester.view);
    final Widget globalKeyChild = SizedBox(
      key: GlobalKey(),
    );

    Map<int, RenderObject> collectLeafRenderObjects() {
      final Map<int, RenderObject> result = <int, RenderObject>{};
      for (final RenderView renderView in RendererBinding.instance.renderViews) {
        void visit(RenderObject object) {
          result[renderView.flutterView.viewId] = object;
          object.visitChildren(visit);
        }
        visit(renderView);
      }
      return result;
    }

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: greenView,
            child: ColoredBox(
              color: Colors.green,
              child: globalKeyChild,
            ),
          ),
          View(
            view: redView,
            child: const ColoredBox(
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    final RenderObject boxWithGlobalKey = tester.renderObject(find.byKey(globalKeyChild.key!));

    Map<int, RenderObject> leafRenderObject = collectLeafRenderObjects();
    expect(leafRenderObject[greenView.viewId], isA<RenderConstrainedBox>());
    expect(leafRenderObject[redView.viewId], isNot(isA<RenderConstrainedBox>()));

    // Move the child.
    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: greenView,
            child: const ColoredBox(
              color: Colors.green,
            ),
          ),
          View(
            view: redView,
            child: ColoredBox(
              color: Colors.red,
              child: globalKeyChild,
            ),
          ),
        ],
      ),
    );

    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      tester.renderObject(find.byKey(globalKeyChild.key!)),
      equals(boxWithGlobalKey),
    );

    leafRenderObject = collectLeafRenderObjects();
    expect(leafRenderObject[greenView.viewId], isNot(isA<RenderConstrainedBox>()));
    expect(leafRenderObject[redView.viewId], isA<RenderConstrainedBox>());
  });

  testWidgets('Can move stuff between views via global key: viewB -> viewA', (WidgetTester tester) async {
    final FlutterView greenView = tester.view;
    final FlutterView redView = FakeView(tester.view);
    final Widget globalKeyChild = SizedBox(
      key: GlobalKey(),
    );

    Map<int, RenderObject> collectLeafRenderObjects() {
      final Map<int, RenderObject> result = <int, RenderObject>{};
      for (final RenderView renderView in RendererBinding.instance.renderViews) {
        void visit(RenderObject object) {
          result[renderView.flutterView.viewId] = object;
          object.visitChildren(visit);
        }
        visit(renderView);
      }
      return result;
    }

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: greenView,
            child: const ColoredBox(
              color: Colors.green,
            ),
          ),
          View(
            view: redView,
            child: ColoredBox(
              color: Colors.red,
              child: globalKeyChild,
            ),
          ),
        ],
      ),
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    final RenderObject boxWithGlobalKey = tester.renderObject(find.byKey(globalKeyChild.key!));

    Map<int, RenderObject> leafRenderObject = collectLeafRenderObjects();
    expect(leafRenderObject[redView.viewId], isA<RenderConstrainedBox>());
    expect(leafRenderObject[greenView.viewId], isNot(isA<RenderConstrainedBox>()));

    // Move the child.
    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: greenView,
            child: ColoredBox(
              color: Colors.green,
              child: globalKeyChild,
            ),
          ),
          View(
            view: redView,
            child: const ColoredBox(
              color: Colors.red,
            ),
          ),
        ],
      ),
    );

    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      tester.renderObject(find.byKey(globalKeyChild.key!)),
      equals(boxWithGlobalKey),
    );

    leafRenderObject = collectLeafRenderObjects();
    expect(leafRenderObject[redView.viewId], isNot(isA<RenderConstrainedBox>()));
    expect(leafRenderObject[greenView.viewId], isA<RenderConstrainedBox>());
  });

  testWidgets('Can move stuff out of a view that is going away, viewA -> ViewB', (WidgetTester tester) async {
    final FlutterView greenView = tester.view;
    final Key greenKey = UniqueKey();
    final FlutterView redView = FakeView(tester.view);
    final Key redKey = UniqueKey();
    final Widget globalKeyChild = SizedBox(
      key: GlobalKey(),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            key: greenKey,
            view: greenView,
            child: const ColoredBox(
              color: Colors.green,
            ),
          ),
          View(
            key: redKey,
            view: redView,
            child: ColoredBox(
              color: Colors.red,
              child: globalKeyChild,
            ),
          ),
        ],
      ),
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    final RenderObject boxWithGlobalKey = tester.renderObject(find.byKey(globalKeyChild.key!));

    // Move the child and remove its view.
    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            key: greenKey,
            view: greenView,
            child: ColoredBox(
              color: Colors.green,
              child: globalKeyChild,
            ),
          ),
        ],
      ),
    );

    expect(
      findsColoredBox(Colors.red),
      findsNothing,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      tester.renderObject(find.byKey(globalKeyChild.key!)),
      equals(boxWithGlobalKey),
    );
  });

  testWidgets('Can move stuff out of a view that is going away, viewB -> ViewA', (WidgetTester tester) async {
    final FlutterView greenView = tester.view;
    final Key greenKey = UniqueKey();
    final FlutterView redView = FakeView(tester.view);
    final Key redKey = UniqueKey();
    final Widget globalKeyChild = SizedBox(
      key: GlobalKey(),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            key: greenKey,
            view: greenView,
            child: ColoredBox(
              color: Colors.green,
              child: globalKeyChild,
            ),
          ),
          View(
            key: redKey,
            view: redView,
            child: const ColoredBox(
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.green),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    final RenderObject boxWithGlobalKey = tester.renderObject(find.byKey(globalKeyChild.key!));

    // Move the child and remove its view.
    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            key: redKey,
            view: redView,
            child: ColoredBox(
              color: Colors.red,
              child: globalKeyChild,
            ),
          ),
        ],
      ),
    );

    expect(
      findsColoredBox(Colors.green),
      findsNothing,
    );
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(
      tester.renderObject(find.byKey(globalKeyChild.key!)),
      equals(boxWithGlobalKey),
    );
  });

  testWidgets('Can move stuff out of a view that is moving itself, stuff ends up before view', (WidgetTester tester) async {
    final Key key1 = UniqueKey();
    final Key key2 = UniqueKey();
    final Key key3 = UniqueKey();
    final Key key4 = UniqueKey();

    final GlobalKey viewKey = GlobalKey();
    final GlobalKey childKey = GlobalKey();

    await tester.pumpWidget(Column(
      children: <Widget>[
        SizedBox(key: key1),
        ViewAnchor(
          key: key2,
          view: View(
            key: viewKey,
            view: FakeView(tester.view),
            child: SizedBox(
              child: ColoredBox(
                key: childKey,
                color: Colors.green,
              ),
            ),
          ),
          child: const SizedBox(),
        ),
        ViewAnchor(
          key: key3,
          child: const SizedBox(),
        ),
        SizedBox(key: key4),
      ],
    ));

    await tester.pumpWidget(Column(
      children: <Widget>[
        SizedBox(
          key: key1,
          child: ColoredBox(
            key: childKey,
            color: Colors.green,
          ),
        ),
        ViewAnchor(
          key: key2,
          child: const SizedBox(),
        ),
        ViewAnchor(
          key: key3,
          view: View(
            key: viewKey,
            view: FakeView(tester.view),
            child: const SizedBox(),
          ),
          child: const SizedBox(),
        ),
        SizedBox(key: key4),
      ],
    ));

    await tester.pumpWidget(Column(
      children: <Widget>[
        SizedBox(key: key1),
        ViewAnchor(
          key: key2,
          view: View(
            key: viewKey,
            view: FakeView(tester.view),
            child: SizedBox(
              child: ColoredBox(
                key: childKey,
                color: Colors.green,
              ),
            ),
          ),
          child: const SizedBox(),
        ),
        ViewAnchor(
          key: key3,
          child: const SizedBox(),
        ),
        SizedBox(key: key4),
      ],
    ));
  });

  testWidgets('Can move stuff out of a view that is moving itself, stuff ends up after view', (WidgetTester tester) async {
    final Key key1 = UniqueKey();
    final Key key2 = UniqueKey();
    final Key key3 = UniqueKey();
    final Key key4 = UniqueKey();

    final GlobalKey viewKey = GlobalKey();
    final GlobalKey childKey = GlobalKey();

    await tester.pumpWidget(Column(
      children: <Widget>[
        SizedBox(key: key1),
        ViewAnchor(
          key: key2,
          view: View(
            key: viewKey,
            view: FakeView(tester.view),
            child: SizedBox(
              child: ColoredBox(
                key: childKey,
                color: Colors.green,
              ),
            ),
          ),
          child: const SizedBox(),
        ),
        ViewAnchor(
          key: key3,
          child: const SizedBox(),
        ),
        SizedBox(key: key4),
      ],
    ));

    await tester.pumpWidget(Column(
      children: <Widget>[
        SizedBox(
          key: key1,
        ),
        ViewAnchor(
          key: key2,
          child: const SizedBox(),
        ),
        ViewAnchor(
          key: key3,
          view: View(
            key: viewKey,
            view: FakeView(tester.view),
            child: const SizedBox(),
          ),
          child: const SizedBox(),
        ),
        SizedBox(
          key: key4,
          child: ColoredBox(
            key: childKey,
            color: Colors.green,
          ),
        ),
      ],
    ));

    await tester.pumpWidget(Column(
      children: <Widget>[
        SizedBox(key: key1),
        ViewAnchor(
          key: key2,
          view: View(
            key: viewKey,
            view: FakeView(tester.view),
            child: SizedBox(
              child: ColoredBox(
                key: childKey,
                color: Colors.green,
              ),
            ),
          ),
          child: const SizedBox(),
        ),
        ViewAnchor(
          key: key3,
          child: const SizedBox(),
        ),
        SizedBox(key: key4),
      ],
    ));
  });

  testWidgets('Can globalkey move down the tree from a view that is going away', (WidgetTester tester) async {
    final FlutterView anchorView = FakeView(tester.view);
    final Widget globalKeyChild = SizedBox(
      key: GlobalKey(),
    );

    await tester.pumpWidget(
      ColoredBox(
        color: Colors.green,
        child: ViewAnchor(
          view: View(
            view: anchorView,
            child: ColoredBox(
              color: Colors.yellow,
              child: globalKeyChild,
            ),
          ),
          child: const ColoredBox(color: Colors.red),
        ),
      ),
    );

    expect(findsColoredBox(Colors.green), findsOneWidget);
    expect(findsColoredBox(Colors.yellow), findsOneWidget);
    expect(
      find.descendant(
        of: findsColoredBox(Colors.yellow),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(findsColoredBox(Colors.red), findsOneWidget);
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    expect(find.byType(SizedBox), findsOneWidget);
    final RenderObject boxWithGlobalKey = tester.renderObject(find.byKey(globalKeyChild.key!));

    await tester.pumpWidget(
      ColoredBox(
        color: Colors.green,
        child: ViewAnchor(
          child: ColoredBox(
            color: Colors.red,
            child: globalKeyChild,
          ),
        ),
      ),
    );
    expect(findsColoredBox(Colors.green), findsOneWidget);
    expect(findsColoredBox(Colors.yellow), findsNothing);
    expect(
      find.descendant(
        of: findsColoredBox(Colors.yellow),
        matching: find.byType(SizedBox),
      ),
      findsNothing,
    );
    expect(findsColoredBox(Colors.red), findsOneWidget);
    expect(
      find.descendant(
        of: findsColoredBox(Colors.red),
        matching: find.byType(SizedBox),
      ),
      findsOneWidget,
    );
    expect(find.byType(SizedBox), findsOneWidget);
    expect(
      tester.renderObject(find.byKey(globalKeyChild.key!)),
      boxWithGlobalKey,
    );
  });

  testWidgets('RenderObjects are disposed when a view goes away from a ViewAnchor', (WidgetTester tester) async {
    final FlutterView anchorView = FakeView(tester.view);

    await tester.pumpWidget(
      ColoredBox(
        color: Colors.green,
        child: ViewAnchor(
          view: View(
            view: anchorView,
            child: const ColoredBox(color: Colors.yellow),
          ),
          child: const ColoredBox(color: Colors.red),
        ),
      ),
    );

    final RenderObject box = tester.renderObject(findsColoredBox(Colors.yellow));

    await tester.pumpWidget(
      const ColoredBox(
        color: Colors.green,
        child: ViewAnchor(
          child: ColoredBox(color: Colors.red),
        ),
      ),
    );

    expect(box.debugDisposed, isTrue);
  });

  testWidgets('RenderObjects are disposed when a view goes away from a ViewCollection', (WidgetTester tester) async {
    final FlutterView redView = tester.view;
    final FlutterView greenView = FakeView(tester.view);

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: redView,
            child: const ColoredBox(color: Colors.red),
          ),
          View(
            view: greenView,
            child: const ColoredBox(color: Colors.green),
          ),
        ],
      ),
    );

    expect(findsColoredBox(Colors.green), findsOneWidget);
    expect(findsColoredBox(Colors.red), findsOneWidget);
    final RenderObject box = tester.renderObject(findsColoredBox(Colors.green));

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          View(
            view: redView,
            child: const ColoredBox(color: Colors.red),
          ),
        ],
      ),
    );

    expect(findsColoredBox(Colors.green), findsNothing);
    expect(findsColoredBox(Colors.red), findsOneWidget);
    expect(box.debugDisposed, isTrue);
  });

  testWidgets('View can be wrapped and unwrapped', (WidgetTester tester) async {
    final Widget view = View(
      view: tester.view,
      child: const SizedBox(),
    );

    await tester.pumpWidget(
      wrapWithView: false,
      view,
    );

    final RenderObject renderView = tester.renderObject(find.byType(View));
    final RenderObject renderSizedBox = tester.renderObject(find.byType(SizedBox));

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[view],
      ),
    );

    expect(tester.renderObject(find.byType(View)), same(renderView));
    expect(tester.renderObject(find.byType(SizedBox)), same(renderSizedBox));

    await tester.pumpWidget(
      wrapWithView: false,
      view,
    );

    expect(tester.renderObject(find.byType(View)), same(renderView));
    expect(tester.renderObject(find.byType(SizedBox)), same(renderSizedBox));
  });

  testWidgets('ViewAnchor with View can be wrapped and unwrapped', (WidgetTester tester) async {
    final Widget viewAnchor = ViewAnchor(
      view: View(
        view: FakeView(tester.view),
        child: const SizedBox(),
      ),
      child: const ColoredBox(color: Colors.green),
    );

    await tester.pumpWidget(viewAnchor);

    final List<RenderObject> renderViews = tester.renderObjectList(find.byType(View)).toList();
    final RenderObject renderSizedBox = tester.renderObject(find.byType(SizedBox));

    await tester.pumpWidget(ColoredBox(color: Colors.yellow, child: viewAnchor));

    expect(tester.renderObjectList(find.byType(View)), renderViews);
    expect(tester.renderObject(find.byType(SizedBox)), same(renderSizedBox));

    await tester.pumpWidget(viewAnchor);

    expect(tester.renderObjectList(find.byType(View)), renderViews);
    expect(tester.renderObject(find.byType(SizedBox)), same(renderSizedBox));
  });

  testWidgets('Moving a View keeps its semantics tree stable', (WidgetTester tester) async {
    final Widget view = View(
      // No explicit key, we rely on the implicit key of the underlying RawView.
      view: tester.view,
      child: Semantics(
        textDirection: TextDirection.ltr,
        label: 'Hello',
        child: const SizedBox(),
      )
    );
    await tester.pumpWidget(
      wrapWithView: false,
      view,
    );

    final RenderObject renderSemantics = tester.renderObject(find.bySemanticsLabel('Hello'));
    final SemanticsNode semantics = tester.getSemantics(find.bySemanticsLabel('Hello'));
    expect(semantics.id, 1);
    expect(renderSemantics.debugSemantics, same(semantics));

    await tester.pumpWidget(
      wrapWithView: false,
      ViewCollection(
        views: <Widget>[
          view,
        ],
      ),
    );

    final RenderObject renderSemanticsAfterMove = tester.renderObject(find.bySemanticsLabel('Hello'));
    final SemanticsNode semanticsAfterMove = tester.getSemantics(find.bySemanticsLabel('Hello'));
    expect(renderSemanticsAfterMove, same(renderSemantics));
    expect(semanticsAfterMove.id, 1);
    expect(semanticsAfterMove, same(semantics));
  });
}

Finder findsColoredBox(Color color) {
  return find.byWidgetPredicate((Widget widget) => widget is ColoredBox && widget.color == color);
}
