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

// @dart = 2.8

import 'package:flutter/src/foundation/assertions.dart';
import 'package:flutter/src/painting/basic_types.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';

const List<Widget> children = <Widget>[
  SizedBox(width: 200.0, height: 150.0),
  SizedBox(width: 200.0, height: 150.0),
  SizedBox(width: 200.0, height: 150.0),
  SizedBox(width: 200.0, height: 150.0),
];

void expectRects(WidgetTester tester, List<Rect> expected) {
  final Finder finder = find.byType(SizedBox);
  finder.precache();
  final List<Rect> actual = <Rect>[];
  for (int i = 0; i < expected.length; ++i) {
    final Finder current = finder.at(i);
    expect(current, findsOneWidget);
    actual.add(tester.getRect(finder.at(i)));
  }
  expect(() => finder.at(expected.length), throwsRangeError);
  expect(actual, equals(expected));
}

void main() {

  testWidgets('ListBody down', (WidgetTester tester) async {
    await tester.pumpWidget(Flex(
      direction: Axis.vertical,
      children: <Widget>[ ListBody(children: children) ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 150.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 300.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 450.0, 800.0, 150.0),
      ],
    );
  });

  testWidgets('ListBody up', (WidgetTester tester) async {
    await tester.pumpWidget(Flex(
      direction: Axis.vertical,
      children: <Widget>[ ListBody(reverse: true, children: children) ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(0.0, 450.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 300.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 150.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 0.0, 800.0, 150.0),
      ],
    );
  });

  testWidgets('ListBody right', (WidgetTester tester) async {
    await tester.pumpWidget(Flex(
      textDirection: TextDirection.ltr,
      direction: Axis.horizontal,
      children: <Widget>[
        Directionality(
          textDirection: TextDirection.ltr,
          child: ListBody(mainAxis: Axis.horizontal, children: children),
        ),
      ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(200.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(400.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(600.0, 0.0, 200.0, 600.0),
      ],
    );
  });

  testWidgets('ListBody left', (WidgetTester tester) async {
    await tester.pumpWidget(Flex(
      textDirection: TextDirection.ltr,
      direction: Axis.horizontal,
      children: <Widget>[
        Directionality(
          textDirection: TextDirection.rtl,
          child: ListBody(mainAxis: Axis.horizontal, children: children),
        ),
      ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(600.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(400.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(200.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(0.0, 0.0, 200.0, 600.0),
      ],
    );
  });

  testWidgets('Limited space along main axis error', (WidgetTester tester) async {
    final FlutterExceptionHandler oldHandler = FlutterError.onError;
    final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
    FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
    try {
      await tester.pumpWidget(
        SizedBox(
          width: 100,
          height: 100,
          child: Directionality(
            textDirection: TextDirection.rtl,
            child: ListBody(
              mainAxis: Axis.horizontal,
              children: children,
            ),
          ),
        ),
      );
    } finally {
      FlutterError.onError = oldHandler;
    }
    expect(errors, isNotEmpty);
    expect(errors.first.exception, isFlutterError);
    expect(errors.first.exception.toStringDeep(), equalsIgnoringHashCodes(
      'FlutterError\n'
      '   RenderListBody must have unlimited space along its main axis.\n'
      '   RenderListBody does not clip or resize its children, so it must\n'
      '   be placed in a parent that does not constrain the main axis.\n'
      '   You probably want to put the RenderListBody inside a\n'
      '   RenderViewport with a matching main axis.\n'
    ));
  });

  testWidgets('Nested ListBody unbounded cross axis error', (WidgetTester tester) async {
    final FlutterExceptionHandler oldHandler = FlutterError.onError;
    final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
    FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
    try {
      await tester.pumpWidget(
        Flex(
          textDirection: TextDirection.ltr,
          direction: Axis.horizontal,
          children: <Widget>[
            Directionality(
              textDirection: TextDirection.ltr,
              child: ListBody(
                mainAxis: Axis.horizontal,
                children: <Widget>[
                  Flex(
                    textDirection: TextDirection.ltr,
                    direction: Axis.vertical,
                    children: <Widget>[
                      Directionality(
                        textDirection: TextDirection.ltr,
                        child: ListBody(
                          mainAxis: Axis.vertical,
                          children: children,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      );
    } finally {
      FlutterError.onError = oldHandler;
    }
    expect(errors, isNotEmpty);
    expect(errors.first.exception, isFlutterError);
    expect(errors.first.exception.toStringDeep(), equalsIgnoringHashCodes(
      'FlutterError\n'
      '   RenderListBody must have a bounded constraint for its cross axis.\n'
      '   RenderListBody forces its children to expand to fit the\n'
      "   RenderListBody's container, so it must be placed in a parent that\n"
      '   constrains the cross axis to a finite dimension.\n'
      '   If you are attempting to nest a RenderListBody with one direction\n'
      '   inside one of another direction, you will want to wrap the inner\n'
      '   one inside a box that fixes the dimension in that direction, for\n'
      '   example, a RenderIntrinsicWidth or RenderIntrinsicHeight object.\n'
      '   This is relatively expensive, however.\n'
    ));
  });
}
