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

// @dart = 2.6
@TestOn('chrome || firefox')

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

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


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);

ui.Paragraph build(ui.ParagraphStyle style, String text,
    {ui.TextStyle textStyle}) {
  final ui.ParagraphBuilder builder = ui.ParagraphBuilder(style);
  if (textStyle != null) {
    builder.pushStyle(textStyle);
  }
  builder.addText(text);
  return builder.build();
}

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)',
    () => body(TextMeasurementService.domInstance),
    skip: skipDom,
  );
  test(
    '$description (canvas)',
    () => body(TextMeasurementService.canvasInstance),
    skip: skipCanvas,
  );
}
void main() {
  internalBootstrapBrowserTest(() => testMain);
}

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);

    ParagraphGeometricStyle style1, style2, style3;
    DomParagraph style1Text1, style1Text2; // two paragraphs sharing style
    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) {
        ui.Paragraph 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, true);
        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, false);
        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, false);
        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, false);
        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, false);
        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, false);
        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, false);
        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, false);
        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, false);
        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 ui.Paragraph 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 ui.ParagraphBuilder normalBuilder = ui.ParagraphBuilder(ahemStyle);
      normalBuilder.addText('a b c');
      final ui.Paragraph normalText = normalBuilder.build();

      final ui.ParagraphBuilder spacedBuilder = ui.ParagraphBuilder(ahemStyle);
      spacedBuilder.pushStyle(ui.TextStyle(wordSpacing: 1.5));
      spacedBuilder.addText('a b c');
      final ui.Paragraph spacedText = spacedBuilder.build();

      // 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 ui.Paragraph 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 ui.Paragraph 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 ui.Paragraph 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 ui.Paragraph 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 ui.Paragraph 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 ui.Paragraph 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 ui.Paragraph 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: '...',
        );

        ui.Paragraph 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', () {
      TextMeasurementService instance = TextMeasurementService.canvasInstance;
      ui.Paragraph 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) {
        TextMeasurementService instance = TextMeasurementService.canvasInstance;
        ui.Paragraph 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, {
  double width,
  int lineNumber,
  bool hardBreak,
  double left,
}) {
  return EngineLineMetrics.withText(
    displayText,
    startIndex: startIndex,
    endIndex: endIndex,
    hardBreak: hardBreak,
    width: width,
    lineNumber: lineNumber,
    left: left,
    endIndexWithoutNewlines: -1,
    widthWithTrailingSpaces: width,
  );
}
