// 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/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('SizedBox constructors', (WidgetTester tester) async {
    const SizedBox a = SizedBox();
    expect(a.width, isNull);
    expect(a.height, isNull);

    const SizedBox b = SizedBox(width: 10.0);
    expect(b.width, 10.0);
    expect(b.height, isNull);

    const SizedBox c = SizedBox(width: 10.0, height: 20.0);
    expect(c.width, 10.0);
    expect(c.height, 20.0);

    final SizedBox d = SizedBox.fromSize();
    expect(d.width, isNull);
    expect(d.height, isNull);

    final SizedBox e = SizedBox.fromSize(size: const Size(1.0, 2.0));
    expect(e.width, 1.0);
    expect(e.height, 2.0);

    const SizedBox f = SizedBox.expand();
    expect(f.width, double.infinity);
    expect(f.height, double.infinity);

    const SizedBox g = SizedBox.shrink();
    expect(g.width, 0.0);
    expect(g.height, 0.0);
  });

  testWidgets('SizedBox - no child', (WidgetTester tester) async {
    final GlobalKey patient = GlobalKey();

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(0.0, 0.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          height: 0.0,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(0.0, 0.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          width: 0.0,
          height: 0.0,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(0.0, 0.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          width: 100.0,
          height: 100.0,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(100.0, 100.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          width: 1000.0,
          height: 1000.0,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(800.0, 600.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox.expand(
          key: patient,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(800.0, 600.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox.shrink(
          key: patient,
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(0.0, 0.0)));
  });

  testWidgets('SizedBox - container child', (WidgetTester tester) async {
    final GlobalKey patient = GlobalKey();

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(800.0, 600.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          height: 0.0,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(800.0, 0.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          width: 0.0,
          height: 0.0,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(0.0, 0.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          width: 100.0,
          height: 100.0,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(100.0, 100.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          key: patient,
          width: 1000.0,
          height: 1000.0,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(800.0, 600.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox.expand(
          key: patient,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(800.0, 600.0)));

    await tester.pumpWidget(
      Center(
        child: SizedBox.shrink(
          key: patient,
          child: Container(),
        ),
      ),
    );
    expect(patient.currentContext!.size, equals(const Size(0.0, 0.0)));
  });
}
