// 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 'dart:ui' show TextHeightBehavior;

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/painting.dart';

void main() {
  testWidgets('Text widget parameter takes precedence over DefaultTextHeightBehavior', (WidgetTester tester) async {
    const TextHeightBehavior behavior1 = TextHeightBehavior(
      applyHeightToLastDescent: false,
      applyHeightToFirstAscent: false,
    );
    const TextHeightBehavior behavior2 = TextHeightBehavior(
      applyHeightToLastDescent: true,
      applyHeightToFirstAscent: false,
    );

    await tester.pumpWidget(
      const DefaultTextHeightBehavior(
        textHeightBehavior: behavior2,
        child: Text(
          'Hello',
          textDirection: TextDirection.ltr,
          textHeightBehavior: behavior1,
        ),
      ),
    );

    final RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textHeightBehavior, behavior1);
  });

  testWidgets('DefaultTextStyle.textHeightBehavior takes precedence over DefaultTextHeightBehavior ', (WidgetTester tester) async {
    const TextHeightBehavior behavior1 = TextHeightBehavior(
      applyHeightToLastDescent: false,
      applyHeightToFirstAscent: false,
    );
    const TextHeightBehavior behavior2 = TextHeightBehavior(
      applyHeightToLastDescent: true,
      applyHeightToFirstAscent: false,
    );

    await tester.pumpWidget(
      const DefaultTextStyle(
        style: TextStyle(),
        textHeightBehavior: behavior1,
        child: DefaultTextHeightBehavior(
          textHeightBehavior: behavior2,
          child: Text(
            'Hello',
            textDirection: TextDirection.ltr,
          ),
        ),
      ),
    );

    RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textHeightBehavior, behavior1);

    await tester.pumpWidget(
      const DefaultTextHeightBehavior(
        textHeightBehavior: behavior2,
        child: DefaultTextStyle(
          style: TextStyle(),
          textHeightBehavior: behavior1,
          child: Text(
            'Hello',
            textDirection: TextDirection.ltr,
          ),
        ),
      ),
    );

    text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textHeightBehavior, behavior1);
  });

  testWidgets('DefaultTextHeightBehavior changes propagate to Text', (WidgetTester tester) async {
    const Text textWidget = Text('Hello', textDirection: TextDirection.ltr);
    const TextHeightBehavior behavior1 = TextHeightBehavior(
      applyHeightToLastDescent: false,
      applyHeightToFirstAscent: false,
    );
    const TextHeightBehavior behavior2 = TextHeightBehavior(
      applyHeightToLastDescent: false,
      applyHeightToFirstAscent: false,
    );

    await tester.pumpWidget(const DefaultTextHeightBehavior(
      textHeightBehavior: behavior1,
      child: textWidget,
    ));

    RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textHeightBehavior, behavior1);

    await tester.pumpWidget(const DefaultTextHeightBehavior(
      textHeightBehavior: behavior2,
      child: textWidget,
    ));

    text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textHeightBehavior, behavior2);
  });

  testWidgets('DefaultTextHeightBehavior.of(context) returns null if no '
      'DefaultTextHeightBehavior widget in tree', (WidgetTester tester) async {
    const Text textWidget = Text('Hello', textDirection: TextDirection.ltr);
    TextHeightBehavior textHeightBehavior;

    await tester.pumpWidget(Builder(
      builder: (BuildContext context) {
        textHeightBehavior = DefaultTextHeightBehavior.of(context);
        return textWidget;
      },
    ));

    expect(textHeightBehavior, isNull);
    final RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textHeightBehavior, isNull);
  });
}
