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

@TestOn('chrome || firefox')

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;

final ui.ParagraphStyle ahemStyle = ui.ParagraphStyle(
  fontFamily: 'ahem',
  fontSize: 10,
);
const ui.ParagraphConstraints constraints = ui.ParagraphConstraints(width: 50);
const ui.ParagraphConstraints infiniteConstraints =
    ui.ParagraphConstraints(width: double.infinity);

DomParagraph build(ui.ParagraphStyle style, String text,
    {ui.TextStyle? textStyle}) {
  final DomParagraphBuilder builder = DomParagraphBuilder(style as EngineParagraphStyle);
  if (textStyle != null) {
    builder.pushStyle(textStyle);
  }
  builder.addText(text);
  return builder.build() as DomParagraph;
}

typedef MeasurementTestBody = void Function(TextMeasurementService instance);

/// Runs the same test twice - once with dom measurement and once with canvas
/// measurement.
void testMeasurements(String description, MeasurementTestBody body, {
  bool? skipDom,
  bool? skipCanvas,
}) {
  test(
    '$description (dom)',
    () {
      try {
        WebExperiments.instance!.useCanvasRichText = false;
        return body(TextMeasurementService.domInstance);
      } finally {
        WebExperiments.instance!.useCanvasRichText = null;
      }
    },
    skip: skipDom,
  );
  test(
    '$description (canvas)',
    () {
      try {
        WebExperiments.instance!.useCanvasRichText = false;
        return body(TextMeasurementService.canvasInstance);
      } finally {
        WebExperiments.instance!.useCanvasRichText = null;
      }
    },
    skip: skipCanvas,
  );
}
void main() {
  internalBootstrapBrowserTest(() => testMain);
}

Future<void> testMain()  async {
  await ui.webOnlyInitializeTestDomRenderer();

  group('$RulerManager', () {
    final ui.ParagraphStyle s1 = ui.ParagraphStyle(fontFamily: 'sans-serif');
    final ui.ParagraphStyle s2 = ui.ParagraphStyle(
      fontWeight: ui.FontWeight.bold,
    );
    final ui.ParagraphStyle s3 = ui.ParagraphStyle(fontSize: 22.0);

    late ParagraphGeometricStyle style1, style2, style3;
    late DomParagraph style1Text1, style1Text2; // two paragraphs sharing style
    late DomParagraph style2Text1, style3Text3;

    setUp(() {
      style1Text1 = build(s1, '1');
      style1Text2 = build(s1, '2');
      style2Text1 = build(s2, '1');
      style3Text3 = build(s3, '3');

      style1 = style1Text1.geometricStyle;
      style2 = style2Text1.geometricStyle;
      style3 = style3Text3.geometricStyle;

      final ParagraphGeometricStyle style1_2 = style1Text2.geometricStyle;
      expect(style1_2, style1); // styles must be equal despite different text
    });

    test('caches rulers', () {
      final RulerManager rulerManager = RulerManager(rulerCacheCapacity: 2);
      ParagraphRuler ruler1, ruler2, ruler3;

      expect(rulerManager.rulerCacheCapacity, 2);
      expect(rulerManager.rulers.length, 0);

      // First ruler cached
      ruler1 = rulerManager.findOrCreateRuler(style1);
      expect(rulerManager.rulers.length, 1);
      expect(ruler1.hitCount, 1);

      // Increase hit count for style 1
      ruler1 = rulerManager.findOrCreateRuler(style1);
      expect(rulerManager.rulers.length, 1);
      expect(ruler1.hitCount, 2);

      // Previous ruler reused
      rulerManager.findOrCreateRuler(style1);
      expect(rulerManager.rulers.length, 1);
      expect(ruler1.hitCount, 3);

      // Second ruler created and cached
      ruler2 = rulerManager.findOrCreateRuler(style2);
      expect(rulerManager.rulers.length, 2);
      expect(ruler1.hitCount, 3);
      expect(ruler2.hitCount, 1);

      // Increase hit count for style 2
      rulerManager.findOrCreateRuler(style2);
      rulerManager.findOrCreateRuler(style2);
      rulerManager.findOrCreateRuler(style2);
      expect(rulerManager.rulers.length, 2);
      expect(ruler2.hitCount, 4);

      // Third ruler cached: it is ok to store more rulers that the cache
      // capacity because the cache is cleaned-up at the next microtask.
      ruler3 = rulerManager.findOrCreateRuler(style3);

      // Final ruler states
      expect(rulerManager.rulers.length, 3);
      expect(ruler1.hitCount, 3);
      expect(ruler2.hitCount, 4);
      expect(ruler3.hitCount, 1);
      // The least hit ruler isn't disposed yet.
      expect(ruler3.debugIsDisposed, isFalse);

      // Cleaning up the cache should bring its size down to capacity limit.
      rulerManager.cleanUpRulerCache();
      expect(rulerManager.rulers.length, 2);
      expect(rulerManager.rulers, containsValue(ruler1)); // retained
      expect(rulerManager.rulers, containsValue(ruler2)); // retained
      expect(rulerManager.rulers, isNot(containsValue(ruler3))); // evicted
      expect(ruler1.debugIsDisposed, isFalse);
      expect(ruler2.debugIsDisposed, isFalse);
      expect(ruler3.debugIsDisposed, isTrue);

      ruler1 = rulerManager.rulers[style1]!;
      expect(ruler1.style, style1);
      expect(ruler1.hitCount, 0); // hit counts are reset

      ruler2 = rulerManager.rulers[style2]!;
      expect(ruler2.style, style2);
      expect(ruler2.hitCount, 0); // hit counts are reset
    });
  });

  group('$TextMeasurementService', () {
    setUp(() {
      TextMeasurementService.initialize(rulerCacheCapacity: 2);
    });
    tearDown(() {
      TextMeasurementService.clearCache();
    });

    testMeasurements(
      'preserves whitespace when measuring',
      (TextMeasurementService instance) {
        DomParagraph text;
        MeasurementResult result;

        // leading whitespaces
        text = build(ahemStyle, '   abc');
        result = instance.measure(text, infiniteConstraints)!;
        expect(result.maxIntrinsicWidth, 60);
        expect(result.minIntrinsicWidth, 30);
        expect(result.height, 10);
        expect(result.lines, <EngineLineMetrics>[
          line('   abc', 0, 6, hardBreak: true, width: 60.0, lineNumber: 0, left: 0.0),
        ]);

        // trailing whitespaces
        text = build(ahemStyle, 'abc   ');
        result = instance.measure(text, infiniteConstraints)!;
        expect(result.maxIntrinsicWidth, 60);
        expect(result.minIntrinsicWidth, 30);
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('abc   ', 0, 6, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement always includes trailing whitespace in the
          // width, while Flutter and Canvas-based measurement don't.
          expect(result.lines, <EngineLineMetrics>[
            line('abc   ', 0, 6, hardBreak: true, width: 60.0, lineNumber: 0, left: 0.0),
          ]);
        }

        // mixed whitespaces
        text = build(ahemStyle, '  ab   c  ');
        result = instance.measure(text, infiniteConstraints)!;
        expect(result.maxIntrinsicWidth, 100);
        expect(result.minIntrinsicWidth, 20);
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('  ab   c  ', 0, 10, hardBreak: true, width: 80.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement always includes trailing whitespace in the
          // width, while Flutter and Canvas-based measurement don't.
          expect(result.lines, <EngineLineMetrics>[
            line('  ab   c  ', 0, 10, hardBreak: true, width: 100.0, lineNumber: 0, left: 0.0),
          ]);
        }

        // single whitespace
        text = build(ahemStyle, ' ');
        result = instance.measure(text, infiniteConstraints)!;
        expect(result.maxIntrinsicWidth, 10);
        expect(result.minIntrinsicWidth, 0);
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line(' ', 0, 1, hardBreak: true, width: 0.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement always includes trailing whitespace in the
          // width, while Flutter and Canvas-based measurement don't.
          expect(result.lines, <EngineLineMetrics>[
            line(' ', 0, 1, hardBreak: true, width: 10.0, lineNumber: 0, left: 0.0),
          ]);
        }

        // whitespace only
        text = build(ahemStyle, '     ');
        result = instance.measure(text, infiniteConstraints)!;
        expect(result.maxIntrinsicWidth, 50);
        expect(result.minIntrinsicWidth, 0);
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('     ', 0, 5, hardBreak: true, width: 0.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement always includes trailing whitespace in the
          // width, while Flutter and Canvas-based measurement don't.
          expect(result.lines, <EngineLineMetrics>[
            line('     ', 0, 5, hardBreak: true, width: 50.0, lineNumber: 0, left: 0.0),
          ]);
        }
      },
    );

    testMeasurements(
      'uses single-line when text can fit without wrapping',
      (TextMeasurementService instance) {
        final MeasurementResult result =
            instance.measure(build(ahemStyle, '12345'), constraints)!;

        // Should fit on a single line.
        expect(result.isSingleLine, isTrue);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 50);
        expect(result.minIntrinsicWidth, 50);
        expect(result.width, 50);
        expect(result.height, 10);
        expect(result.lines, <EngineLineMetrics>[
          line('12345', 0, 5, hardBreak: true, width: 50.0, lineNumber: 0, left: 0.0),
        ]);
      },
    );

    testMeasurements(
      'simple multi-line text',
      (TextMeasurementService instance) {
        const ui.ParagraphConstraints constraints =
            ui.ParagraphConstraints(width: 70);
        MeasurementResult result;

        // The long text doesn't fit in 70px of width, so it needs to wrap.
        result = instance.measure(build(ahemStyle, 'foo bar baz'), constraints)!;
        expect(result.isSingleLine, isFalse);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 110);
        expect(result.minIntrinsicWidth, 30);
        expect(result.width, 70);
        expect(result.height, 20);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('foo bar ', 0, 8, hardBreak: false, width: 70.0, lineNumber: 0, left: 0.0),
            line('baz', 8, 11, hardBreak: true, width: 30.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }
      },
    );

    testMeasurements(
      'uses multi-line for long text',
      (TextMeasurementService instance) {
        MeasurementResult result;

        // The long text doesn't fit in 50px of width, so it needs to wrap.
        result = instance.measure(build(ahemStyle, '1234567890'), constraints)!;
        expect(result.isSingleLine, isFalse);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 100);
        expect(result.minIntrinsicWidth, 100);
        expect(result.width, 50);
        expect(result.height, 20);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('12345', 0, 5, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
            line('67890', 5, 10, hardBreak: true, width: 50.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // The first word is force-broken twice.
        result =
            instance.measure(build(ahemStyle, 'abcdefghijk lm'), constraints)!;
        expect(result.isSingleLine, isFalse);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 140);
        expect(result.minIntrinsicWidth, 110);
        expect(result.width, 50);
        expect(result.height, 30);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('abcde', 0, 5, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
            line('fghij', 5, 10, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
            line('k lm', 10, 14, hardBreak: true, width: 40.0, lineNumber: 2, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // Constraints aren't enough even for a single character. In this case,
        // we show a minimum of one character per line.
        const ui.ParagraphConstraints narrowConstraints =
            ui.ParagraphConstraints(width: 8);
        result = instance.measure(build(ahemStyle, 'AA'), narrowConstraints)!;
        expect(result.isSingleLine, isFalse);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 20);
        expect(result.minIntrinsicWidth, 20);
        expect(result.width, 8);
        expect(result.height, 20);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('A', 0, 1, hardBreak: false, width: 10.0, lineNumber: 0, left: 0.0),
            line('A', 1, 2, hardBreak: true, width: 10.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // Extremely narrow constraints with new line in the middle.
        result = instance.measure(build(ahemStyle, 'AA\nA'), narrowConstraints)!;
        expect(result.isSingleLine, isFalse);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 20);
        expect(result.minIntrinsicWidth, 20);
        expect(result.width, 8);
        expect(result.height, 30);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('A', 0, 1, hardBreak: false, width: 10.0, lineNumber: 0, left: 0.0),
            line('A', 1, 3, hardBreak: true, width: 10.0, lineNumber: 1, left: 0.0),
            line('A', 3, 4, hardBreak: true, width: 10.0, lineNumber: 2, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // Extremely narrow constraints with new line in the end.
        result = instance.measure(build(ahemStyle, 'AAA\n'), narrowConstraints)!;
        expect(result.isSingleLine, isFalse);
        expect(result.alphabeticBaseline, 8);
        expect(result.maxIntrinsicWidth, 30);
        expect(result.minIntrinsicWidth, 30);
        expect(result.width, 8);
        expect(result.height, 40);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('A', 0, 1, hardBreak: false, width: 10.0, lineNumber: 0, left: 0.0),
            line('A', 1, 2, hardBreak: false, width: 10.0, lineNumber: 1, left: 0.0),
            line('A', 2, 4, hardBreak: true, width: 10.0, lineNumber: 2, left: 0.0),
            line('', 4, 4, hardBreak: true, width: 0.0, lineNumber: 3, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }
      },
      skipDom: browserEngine == BrowserEngine.webkit,
    );

    testMeasurements(
      'uses multi-line for text that contains new-line',
      (TextMeasurementService instance) {
        final MeasurementResult result =
            instance.measure(build(ahemStyle, '12\n34'), constraints)!;

        // Text containing newlines should always be drawn in multi-line mode.
        expect(result.isSingleLine, isFalse);
        expect(result.maxIntrinsicWidth, 20);
        expect(result.minIntrinsicWidth, 20);
        expect(result.width, 50);
        expect(result.height, 20);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('12', 0, 3, hardBreak: true, width: 20.0, lineNumber: 0, left: 0.0),
            line('34', 3, 5, hardBreak: true, width: 20.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }
      },
    );

    testMeasurements('empty lines', (TextMeasurementService instance) {
      MeasurementResult result;

      // Empty lines in the beginning.
      result = instance.measure(build(ahemStyle, '\n\n1234'), constraints)!;
      expect(result.maxIntrinsicWidth, 40);
      expect(result.minIntrinsicWidth, 40);
      expect(result.height, 30);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('', 0, 1, hardBreak: true, width: 0.0, lineNumber: 0, left: 0.0),
          line('', 1, 2, hardBreak: true, width: 0.0, lineNumber: 1, left: 0.0),
          line('1234', 2, 6, hardBreak: true, width: 40.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // Empty lines in the middle.
      result = instance.measure(build(ahemStyle, '12\n\n345'), constraints)!;
      expect(result.maxIntrinsicWidth, 30);
      expect(result.minIntrinsicWidth, 30);
      expect(result.height, 30);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('12', 0, 3, hardBreak: true, width: 20.0, lineNumber: 0, left: 0.0),
          line('', 3, 4, hardBreak: true, width: 0.0, lineNumber: 1, left: 0.0),
          line('345', 4, 7, hardBreak: true, width: 30.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // Empty lines in the end.
      result = instance.measure(build(ahemStyle, '1234\n\n'), constraints)!;
      expect(result.maxIntrinsicWidth, 40);
      expect(result.minIntrinsicWidth, 40);
      if (instance.isCanvas) {
        // This can only be done correctly in the canvas-based implementation.
        expect(result.height, 30);
        expect(result.lines, <EngineLineMetrics>[
          line('1234', 0, 5, hardBreak: true, width: 40.0, lineNumber: 0, left: 0.0),
          line('', 5, 6, hardBreak: true, width: 0.0, lineNumber: 1, left: 0.0),
          line('', 6, 6, hardBreak: true, width: 0.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }
    });

    testMeasurements(
      'wraps multi-line text correctly when constraint width is infinite',
      (TextMeasurementService instance) {
        final DomParagraph paragraph = build(ahemStyle, '123\n456 789');
        final MeasurementResult result =
            instance.measure(paragraph, infiniteConstraints)!;

        expect(result.isSingleLine, isFalse);
        expect(result.maxIntrinsicWidth, 70);
        expect(result.minIntrinsicWidth, 30);
        expect(result.width, double.infinity);
        expect(result.height, 20);

        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('123', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
            line('456 789', 4, 11, hardBreak: true, width: 70.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }
      },
    );

    testMeasurements(
      'takes letter spacing into account',
      (TextMeasurementService instance) {
        const ui.ParagraphConstraints constraints =
            ui.ParagraphConstraints(width: 100);
        final ui.TextStyle spacedTextStyle = ui.TextStyle(letterSpacing: 3);
        final DomParagraph spacedText =
            build(ahemStyle, 'abc', textStyle: spacedTextStyle);

        final MeasurementResult spacedResult =
            instance.measure(spacedText, constraints)!;

        expect(spacedResult.minIntrinsicWidth, 39);
        expect(spacedResult.maxIntrinsicWidth, 39);
      },
    );

    test('takes word spacing into account', () {
      const ui.ParagraphConstraints constraints =
          ui.ParagraphConstraints(width: 100);

      final DomParagraph normalText = build(ahemStyle, 'a b c');
      final DomParagraph spacedText =
          build(ahemStyle, 'a b c', textStyle: ui.TextStyle(wordSpacing: 1.5));

      // Word spacing is only supported via DOM measurement.
      final TextMeasurementService instance =
          TextMeasurementService.forParagraph(spacedText);
      expect(instance, const TypeMatcher<DomTextMeasurementService>());

      final MeasurementResult normalResult =
          instance.measure(normalText, constraints)!;
      final MeasurementResult spacedResult =
          instance.measure(spacedText, constraints)!;

      expect(
        normalResult.maxIntrinsicWidth < spacedResult.maxIntrinsicWidth,
        isTrue,
      );
    });

    testMeasurements('minIntrinsicWidth', (TextMeasurementService instance) {
      MeasurementResult result;

      // Simple case.
      result = instance.measure(build(ahemStyle, 'abc de fghi'), constraints)!;
      expect(result.minIntrinsicWidth, 40);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abc ', 0, 4, hardBreak: false, width: 30.0, lineNumber: 0, left: 0.0),
          line('de ', 4, 7, hardBreak: false, width: 20.0, lineNumber: 1, left: 0.0),
          line('fghi', 7, 11, hardBreak: true, width: 40.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With new lines.
      result = instance.measure(build(ahemStyle, 'abcd\nef\nghi'), constraints)!;
      expect(result.minIntrinsicWidth, 40);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abcd', 0, 5, hardBreak: true, width: 40.0, lineNumber: 0, left: 0.0),
          line('ef', 5, 8, hardBreak: true, width: 20.0, lineNumber: 1, left: 0.0),
          line('ghi', 8, 11, hardBreak: true, width: 30.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With trailing whitespace.
      result = instance.measure(build(ahemStyle, 'abcd      efg'), constraints)!;
      expect(result.minIntrinsicWidth, 40);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abcd      ', 0, 10, hardBreak: false, width: 40.0, lineNumber: 0, left: 0.0),
          line('efg', 10, 13, hardBreak: true, width: 30.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With trailing whitespace and new lines.
      result = instance.measure(build(ahemStyle, 'abc    \ndefg'), constraints)!;
      expect(result.minIntrinsicWidth, 40);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abc    ', 0, 8, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
          line('defg', 8, 12, hardBreak: true, width: 40.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // Very long text.
      result = instance.measure(build(ahemStyle, 'AAAAAAAAAAAA'), constraints)!;
      expect(result.minIntrinsicWidth, 120);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('AAAAA', 0, 5, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
          line('AAAAA', 5, 10, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('AA', 10, 12, hardBreak: true, width: 20.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }
    });

    testMeasurements('maxIntrinsicWidth', (TextMeasurementService instance) {
      MeasurementResult result;

      // Simple case.
      result = instance.measure(build(ahemStyle, 'abc de fghi'), constraints)!;
      expect(result.maxIntrinsicWidth, 110);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abc ', 0, 4, hardBreak: false, width: 30.0, lineNumber: 0, left: 0.0),
          line('de ', 4, 7, hardBreak: false, width: 20.0, lineNumber: 1, left: 0.0),
          line('fghi', 7, 11, hardBreak: true, width: 40.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With new lines.
      result = instance.measure(build(ahemStyle, 'abcd\nef\nghi'), constraints)!;
      expect(result.maxIntrinsicWidth, 40);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abcd', 0, 5, hardBreak: true, width: 40.0, lineNumber: 0, left: 0.0),
          line('ef', 5, 8, hardBreak: true, width: 20.0, lineNumber: 1, left: 0.0),
          line('ghi', 8, 11, hardBreak: true, width: 30.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With long whitespace.
      result = instance.measure(build(ahemStyle, 'abcd   efg'), constraints)!;
      expect(result.maxIntrinsicWidth, 100);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abcd   ', 0, 7, hardBreak: false, width: 40.0, lineNumber: 0, left: 0.0),
          line('efg', 7, 10, hardBreak: true, width: 30.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With trailing whitespace.
      result = instance.measure(build(ahemStyle, 'abc def   '), constraints)!;
      expect(result.maxIntrinsicWidth, 100);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abc ', 0, 4, hardBreak: false, width: 30.0, lineNumber: 0, left: 0.0),
          line('def   ', 4, 10, hardBreak: true, width: 30.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // With trailing whitespace and new lines.
      result = instance.measure(build(ahemStyle, 'abc \ndef   '), constraints)!;
      expect(result.maxIntrinsicWidth, 60);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('abc ', 0, 5, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
          line('def   ', 5, 11, hardBreak: true, width: 30.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // Very long text.
      result = instance.measure(build(ahemStyle, 'AAAAAAAAAAAA'), constraints)!;
      expect(result.maxIntrinsicWidth, 120);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('AAAAA', 0, 5, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
          line('AAAAA', 5, 10, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('AA', 10, 12, hardBreak: true, width: 20.0, lineNumber: 2, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }
    });

    testMeasurements(
      'respects text overflow',
      (TextMeasurementService instance) {
        final ui.ParagraphStyle overflowStyle = ui.ParagraphStyle(
          fontFamily: 'ahem',
          fontSize: 10,
          ellipsis: '...',
        );

        MeasurementResult result;

        // The text shouldn't be broken into multiple lines, so the height should
        // be equal to a height of a single line.
        final DomParagraph longText = build(
          overflowStyle,
          'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
        );
        result = instance.measure(longText, constraints)!;
        expect(result.minIntrinsicWidth, 480);
        expect(result.maxIntrinsicWidth, 480);
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('AA...', 0, 48, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't handle the ellipsis case very well. The
          // text wraps into multiple lines instead.
          expect(result.lines, isNull);
        }

        // The short prefix should make the text break into two lines, but the
        // second line should remain unbroken.
        final DomParagraph longTextShortPrefix = build(
          overflowStyle,
          'AAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
        );
        result = instance.measure(longTextShortPrefix, constraints)!;
        expect(result.minIntrinsicWidth, 450);
        expect(result.maxIntrinsicWidth, 450);
        expect(result.height, 20);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('AAA', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
            line('AA...', 4, 49, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't handle the ellipsis case very well. The
          // text wraps into multiple lines instead.
          expect(result.lines, isNull);
        }

        // Tiny constraints.
        const ui.ParagraphConstraints tinyConstraints =
            ui.ParagraphConstraints(width: 30);
        final DomParagraph text = build(overflowStyle, 'AAAA');
        result = instance.measure(text, tinyConstraints)!;
        expect(result.minIntrinsicWidth, 40);
        expect(result.maxIntrinsicWidth, 40);
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('...', 0, 4, hardBreak: false, width: 30.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't handle the ellipsis case very well. The
          // text wraps into multiple lines instead.
          expect(result.lines, isNull);
        }

        // Tinier constraints (not enough for the ellipsis).
        const ui.ParagraphConstraints tinierConstraints =
            ui.ParagraphConstraints(width: 10);
        result = instance.measure(text, tinierConstraints)!;
        expect(result.minIntrinsicWidth, 40);
        expect(result.maxIntrinsicWidth, 40);
        expect(result.height, 10);
        if (instance.isCanvas) {
          // TODO(flutter_web): https://github.com/flutter/flutter/issues/34346
          // expect(result.lines, <EngineLineMetrics>[
          //   line('.', 0, 4, hardBreak: false, width: 10.0, lineNumber: 0, left: 0.0),
          // ]);
          expect(result.lines, <EngineLineMetrics>[
            line('...', 0, 4, hardBreak: false, width: 30.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't handle the ellipsis case very well. The
          // text wraps into multiple lines instead.
          expect(result.lines, isNull);
        }
      },
      skipDom: browserEngine == BrowserEngine.webkit,
    );

    testMeasurements('respects max lines', (TextMeasurementService instance) {
      final ui.ParagraphStyle maxlinesStyle = ui.ParagraphStyle(
        fontFamily: 'ahem',
        fontSize: 10,
        maxLines: 2,
      );

      MeasurementResult result;

      // The height should be that of a single line.
      final DomParagraph oneline = build(maxlinesStyle, 'One line');
      result = instance.measure(oneline, infiniteConstraints)!;
      expect(result.height, 10);
      expect(result.lines, <EngineLineMetrics>[
        line('One line', 0, 8, hardBreak: true, width: 80.0, lineNumber: 0, left: 0.0),
      ]);

      // The height should respect max lines and be limited to two lines here.
      final DomParagraph threelines =
          build(maxlinesStyle, 'First\nSecond\nThird');
      result = instance.measure(threelines, infiniteConstraints)!;
      expect(result.height, 20);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('First', 0, 6, hardBreak: true, width: 50.0, lineNumber: 0, left: 0.0),
          line('Second', 6, 13, hardBreak: true, width: 60.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // The height should respect max lines and be limited to two lines here.
      final DomParagraph veryLong = build(
        maxlinesStyle,
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
      );
      result = instance.measure(veryLong, constraints)!;
      expect(result.height, 20);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('Lorem ', 0, 6, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
          line('ipsum ', 6, 12, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }

      // Case when last line is a long unbreakable word.
      final DomParagraph veryLongLastLine = build(
        maxlinesStyle,
        'AAA AAAAAAAAAAAAAAAAAAA',
      );
      result = instance.measure(veryLongLastLine, constraints)!;
      expect(result.height, 20);
      if (instance.isCanvas) {
        expect(result.lines, <EngineLineMetrics>[
          line('AAA ', 0, 4, hardBreak: false, width: 30.0, lineNumber: 0, left: 0.0),
          line('AAAAA', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        ]);
      } else {
        // DOM-based measurement can't produce line metrics for multi-line
        // paragraphs.
        expect(result.lines, isNull);
      }
    });

    testMeasurements(
      'respects text overflow and max lines combined',
      (TextMeasurementService instance) {
        const ui.ParagraphConstraints constraints =
            ui.ParagraphConstraints(width: 60);
        final ui.ParagraphStyle onelineStyle = ui.ParagraphStyle(
          fontFamily: 'ahem',
          fontSize: 10,
          maxLines: 1,
          ellipsis: '...',
        );
        final ui.ParagraphStyle multilineStyle = ui.ParagraphStyle(
          fontFamily: 'ahem',
          fontSize: 10,
          maxLines: 2,
          ellipsis: '...',
        );

        DomParagraph p;
        MeasurementResult result;

        // Simple no overflow case.
        p = build(onelineStyle, 'abcdef');
        result = instance.measure(p, constraints)!;
        expect(result.height, 10);
        expect(result.lines, <EngineLineMetrics>[
          line('abcdef', 0, 6, hardBreak: true, width: 60.0, lineNumber: 0, left: 0.0),
        ]);

        // Simple overflow case.
        p = build(onelineStyle, 'abcd efg');
        result = instance.measure(p, constraints)!;
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('abc...', 0, 8, hardBreak: false, width: 60.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't handle the ellipsis case very well. The
          // text wraps into multiple lines instead.
          expect(result.lines, isNull);
        }

        // Another simple overflow case.
        p = build(onelineStyle, 'a bcde fgh');
        result = instance.measure(p, constraints)!;
        expect(result.height, 10);
        if (instance.isCanvas) {
          expect(result.lines, <EngineLineMetrics>[
            line('a b...', 0, 10, hardBreak: false, width: 60.0, lineNumber: 0, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't handle the ellipsis case very well. The
          // text wraps into multiple lines instead.
          expect(result.lines, isNull);
        }

        // The ellipsis is supposed to go on the second line, but because the
        // 2nd line doesn't overflow, no ellipsis is shown.
        p = build(multilineStyle, 'abcdef ghijkl');
        result = instance.measure(p, constraints)!;
        // This can only be done correctly in the canvas-based implementation.
        if (instance.isCanvas) {
          expect(result.height, 20);

          expect(result.lines, <EngineLineMetrics>[
            line('abcdef ', 0, 7, hardBreak: false, width: 60.0, lineNumber: 0, left: 0.0),
            line('ghijkl', 7, 13, hardBreak: true, width: 60.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // But when the 2nd line is long enough, the ellipsis is shown.
        p = build(multilineStyle, 'abcd efghijkl');
        result = instance.measure(p, constraints)!;
        // This can only be done correctly in the canvas-based implementation.
        if (instance.isCanvas) {
          expect(result.height, 20);

          expect(result.lines, <EngineLineMetrics>[
            line('abcd ', 0, 5, hardBreak: false, width: 40.0, lineNumber: 0, left: 0.0),
            line('efg...', 5, 13, hardBreak: false, width: 60.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // Even if the second line can be broken, we don't break it, we just
        // insert the ellipsis.
        p = build(multilineStyle, 'abcde f gh ijk');
        result = instance.measure(p, constraints)!;
        // This can only be done correctly in the canvas-based implementation.
        if (instance.isCanvas) {
          expect(result.height, 20);

          expect(result.lines, <EngineLineMetrics>[
            line('abcde ', 0, 6, hardBreak: false, width: 50.0, lineNumber: 0, left: 0.0),
            line('f g...', 6, 14, hardBreak: false, width: 60.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // First line overflows but second line doesn't.
        p = build(multilineStyle, 'abcdefg hijk');
        result = instance.measure(p, constraints)!;
        // This can only be done correctly in the canvas-based implementation.
        if (instance.isCanvas) {
          expect(result.height, 20);

          expect(result.lines, <EngineLineMetrics>[
            line('abcdef', 0, 6, hardBreak: false, width: 60.0, lineNumber: 0, left: 0.0),
            line('g hijk', 6, 12, hardBreak: true, width: 60.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }

        // Both first and second lines overflow.
        p = build(multilineStyle, 'abcdefg hijklmnop');
        result = instance.measure(p, constraints)!;
        // This can only be done correctly in the canvas-based implementation.
        if (instance.isCanvas) {
          expect(result.height, 20);

          expect(result.lines, <EngineLineMetrics>[
            line('abcdef', 0, 6, hardBreak: false, width: 60.0, lineNumber: 0, left: 0.0),
            line('g h...', 6, 17, hardBreak: false, width: 60.0, lineNumber: 1, left: 0.0),
          ]);
        } else {
          // DOM-based measurement can't produce line metrics for multi-line
          // paragraphs.
          expect(result.lines, isNull);
        }
      },
    );

    test('handles textAlign', () {
      final TextMeasurementService instance = TextMeasurementService.canvasInstance;
      DomParagraph p;
      MeasurementResult result;

      ui.ParagraphStyle createStyle(ui.TextAlign textAlign) {
        return ui.ParagraphStyle(
          fontFamily: 'ahem',
          fontSize: 10,
          textAlign: textAlign,
          textDirection: ui.TextDirection.ltr,
        );
      }

      p = build(createStyle(ui.TextAlign.start), 'abc\ndefghi');
      result = instance.measure(p, constraints)!;
      expect(result.lines, <EngineLineMetrics>[
        line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
        line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 0.0),
      ]);

      p = build(createStyle(ui.TextAlign.end), 'abc\ndefghi');
      result = instance.measure(p, constraints)!;
      expect(result.lines, <EngineLineMetrics>[
        line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 20.0),
        line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 40.0),
      ]);

      p = build(createStyle(ui.TextAlign.center), 'abc\ndefghi');
      result = instance.measure(p, constraints)!;
      expect(result.lines, <EngineLineMetrics>[
        line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 10.0),
        line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 20.0),
      ]);

      p = build(createStyle(ui.TextAlign.left), 'abc\ndefghi');
      result = instance.measure(p, constraints)!;
      expect(result.lines, <EngineLineMetrics>[
        line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
        line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 0.0),
      ]);

      p = build(createStyle(ui.TextAlign.right), 'abc\ndefghi');
      result = instance.measure(p, constraints)!;
      expect(result.lines, <EngineLineMetrics>[
        line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 20.0),
        line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
        line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 40.0),
      ]);
    });

    testMeasurements(
      'handles rtl with textAlign',
      (TextMeasurementService instance) {
        final TextMeasurementService instance = TextMeasurementService.canvasInstance;
        DomParagraph p;
        MeasurementResult result;

        ui.ParagraphStyle createStyle(ui.TextAlign textAlign) {
          return ui.ParagraphStyle(
            fontFamily: 'ahem',
            fontSize: 10,
            textAlign: textAlign,
            textDirection: ui.TextDirection.rtl,
          );
        }

        p = build(createStyle(ui.TextAlign.start), 'abc\ndefghi');
        result = instance.measure(p, constraints)!;
        expect(result.lines, <EngineLineMetrics>[
          line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 20.0),
          line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 40.0),
        ]);

        p = build(createStyle(ui.TextAlign.end), 'abc\ndefghi');
        result = instance.measure(p, constraints)!;
        expect(result.lines, <EngineLineMetrics>[
          line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
          line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 0.0),
        ]);

        p = build(createStyle(ui.TextAlign.center), 'abc\ndefghi');
        result = instance.measure(p, constraints)!;
        expect(result.lines, <EngineLineMetrics>[
          line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 10.0),
          line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 20.0),
        ]);

        p = build(createStyle(ui.TextAlign.left), 'abc\ndefghi');
        result = instance.measure(p, constraints)!;
        expect(result.lines, <EngineLineMetrics>[
          line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 0.0),
          line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 0.0),
        ]);

        p = build(createStyle(ui.TextAlign.right), 'abc\ndefghi');
        result = instance.measure(p, constraints)!;
        expect(result.lines, <EngineLineMetrics>[
          line('abc', 0, 4, hardBreak: true, width: 30.0, lineNumber: 0, left: 20.0),
          line('defgh', 4, 9, hardBreak: false, width: 50.0, lineNumber: 1, left: 0.0),
          line('i', 9, 10, hardBreak: true, width: 10.0, lineNumber: 2, left: 40.0),
        ]);
      },
    );
  });
}

/// Shortcut to avoid many line wraps in the tests above.
EngineLineMetrics line(
  String displayText,
  int startIndex,
  int endIndex, {
  required double width,
  required int lineNumber,
  required bool hardBreak,
  required double left,
}) {
  return EngineLineMetrics.withText(
    displayText,
    startIndex: startIndex,
    endIndex: endIndex,
    hardBreak: hardBreak,
    width: width,
    lineNumber: lineNumber,
    left: left,
    endIndexWithoutNewlines: -1,
    widthWithTrailingSpaces: width,
  );
}
