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

DomParagraph build(ui.ParagraphStyle style, String text,
    {ui.TextStyle textStyle}) {
  final DomParagraphBuilder builder = DomParagraphBuilder(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)',
    () {
      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);
}

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.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, false);
        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, false);
        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, false);
        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, false);
        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, false);
        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, false);
        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, 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 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 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,
  );
}
