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

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('ListView can handle shrinking top elements', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          cacheExtent: 0.0,
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 400.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
            SizedBox(height: 400.0, child: Text('4')),
            SizedBox(height: 400.0, child: Text('5')),
            SizedBox(height: 400.0, child: Text('6')),
          ],
        ),
      ),
    );

    controller.jumpTo(1000.0);
    await tester.pump();

    expect(tester.getTopLeft(find.text('4')).dy, equals(200.0));

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          cacheExtent: 0.0,
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 200.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
            SizedBox(height: 400.0, child: Text('4')),
            SizedBox(height: 400.0, child: Text('5')),
            SizedBox(height: 400.0, child: Text('6')),
          ],
        ),
      ),
    );

    expect(controller.offset, equals(1000.0));
    expect(tester.getTopLeft(find.text('4')).dy, equals(200.0));

    controller.jumpTo(300.0);
    await tester.pump();

    expect(controller.offset, equals(300.0));
    expect(tester.getTopLeft(find.text('2')).dy, equals(100.0));

    controller.jumpTo(50.0);
    await tester.pump();

    expect(controller.offset, equals(0.0));
    expect(tester.getTopLeft(find.text('2')).dy, equals(200.0));
  });

  testWidgets('ListView can handle shrinking top elements with cache extent', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 400.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
            SizedBox(height: 400.0, child: Text('4')),
            SizedBox(height: 400.0, child: Text('5')),
            SizedBox(height: 400.0, child: Text('6')),
          ],
        ),
      ),
    );

    controller.jumpTo(1000.0);
    await tester.pump();

    expect(tester.getTopLeft(find.text('4')).dy, equals(200.0));

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 200.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
            SizedBox(height: 400.0, child: Text('4')),
            SizedBox(height: 400.0, child: Text('5')),
            SizedBox(height: 400.0, child: Text('6')),
          ],
        ),
      ),
    );

    expect(controller.offset, equals(1000.0));
    expect(tester.getTopLeft(find.text('4')).dy, equals(200.0));

    controller.jumpTo(300.0);
    await tester.pump();

    expect(controller.offset, equals(250.0));
    expect(tester.getTopLeft(find.text('2')).dy, equals(-50.0));

    controller.jumpTo(50.0);
    await tester.pump();

    expect(controller.offset, equals(50.0));
    expect(tester.getTopLeft(find.text('2')).dy, equals(150.0));
  });

  testWidgets('ListView can handle inserts at 0', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 400.0, child: Text('0')),
            SizedBox(height: 400.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
          ],
        ),
      ),
    );
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsNothing);
    expect(find.text('3'), findsNothing);

    final Finder findItemA = find.descendant(of: find.byType(SizedBox), matching: find.text('A'));
    final Finder findItemB = find.descendant(of: find.byType(SizedBox), matching: find.text('B'));
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 10.0, child: Text('A')),
            SizedBox(height: 10.0, child: Text('B')),
            SizedBox(height: 400.0, child: Text('0')),
            SizedBox(height: 400.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
          ],
        ),
      ),
    );
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsOneWidget);
    expect(tester.getTopLeft(findItemA).dy, 0.0);
    expect(tester.getBottomRight(findItemA).dy, 10.0);
    expect(tester.getTopLeft(findItemB).dy, 10.0);
    expect(tester.getBottomRight(findItemB).dy, 20.0);


    controller.jumpTo(1200.0);
    await tester.pump();
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsNothing);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          controller: controller,
          children: const <Widget>[
            SizedBox(height: 200.0, child: Text('A')),
            SizedBox(height: 200.0, child: Text('B')),
            SizedBox(height: 400.0, child: Text('0')),
            SizedBox(height: 400.0, child: Text('1')),
            SizedBox(height: 400.0, child: Text('2')),
            SizedBox(height: 400.0, child: Text('3')),
          ],
        ),
      ),
    );
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsNothing);

    // Scrolling to 0 causes items A and B to underflow (extend below
    // scrollOffset 0) because their heights have grown from 10 - 200.
    // RenderSliver list corrects the scroll offset in this case. Only item
    // B will become visible and item B's bottom edge will still appear
    // where it was when its height was 10.0.
    controller.jumpTo(0.0);
    await tester.pump();
    expect(find.text('B'), findsOneWidget);
    expect(controller.offset, greaterThan(0.0)); // RenderSliverList corrected the offset.
    expect(tester.getTopLeft(findItemB).dy, -180.0);
    expect(tester.getBottomRight(findItemB).dy, 20.0);


    controller.jumpTo(0.0);
    await tester.pump();
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsOneWidget);
    expect(tester.getTopLeft(findItemA).dy, 0.0);
    expect(tester.getBottomRight(findItemA).dy, 200.0);
    expect(tester.getTopLeft(findItemB).dy, 200.0);
    expect(tester.getBottomRight(findItemB).dy, 400.0);
  });
}
