How to test the intrinsic size of a render object in Flutter
You can create the render object directly, so you don't need to pump a widget.
A simple example is here:
testWidgets('MongolRichText has correct min instrinsic width', (WidgetTester tester) async {
MongolRenderParagraph paragraph = MongolRenderParagraph(TextSpan(text: 'A string'));
final double textWidth = paragraph.getMaxIntrinsicWidth(double.infinity);
expect(textWidth, greaterThan(0));
});
I found the solution by looking at the Flutter source code for paragraph_intrinsics_test.dart:
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/rendering.dart';
import '../flutter_test_alternative.dart';
void main() {
test('list body and paragraph intrinsics', () {
final RenderParagraph paragraph = RenderParagraph(
const TextSpan(
style: TextStyle(height: 1.0),
text: 'Hello World',
),
textDirection: TextDirection.ltr,
);
final RenderListBody testBlock = RenderListBody(
children: <RenderBox>[
paragraph,
],
);
final double textWidth = paragraph.getMaxIntrinsicWidth(double.infinity);
final double oneLineTextHeight = paragraph.getMinIntrinsicHeight(double.infinity);
final double constrainedWidth = textWidth * 0.9;
final double wrappedTextWidth = paragraph.getMinIntrinsicWidth(double.infinity);
final double twoLinesTextHeight = paragraph.getMinIntrinsicHeight(constrainedWidth);
final double manyLinesTextHeight = paragraph.getMinIntrinsicHeight(0.0);
// paragraph
expect(wrappedTextWidth, greaterThan(0.0));
expect(wrappedTextWidth, lessThan(textWidth));
expect(oneLineTextHeight, lessThan(twoLinesTextHeight));
expect(twoLinesTextHeight, lessThan(oneLineTextHeight * 3.0));
expect(manyLinesTextHeight, greaterThan(twoLinesTextHeight));
expect(paragraph.getMaxIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(paragraph.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(paragraph.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
// vertical block (same expectations)
expect(testBlock.getMinIntrinsicWidth(double.infinity), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(double.infinity), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMinIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicWidth(0.0), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(0.0), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicHeight(0.0), equals(manyLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
// horizontal block (same expectations again)
testBlock.axisDirection = AxisDirection.right;
expect(testBlock.getMinIntrinsicWidth(double.infinity), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(double.infinity), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMinIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(double.infinity), equals(oneLineTextHeight));
expect(testBlock.getMaxIntrinsicHeight(constrainedWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicWidth(0.0), equals(wrappedTextWidth));
expect(testBlock.getMaxIntrinsicWidth(0.0), equals(textWidth));
expect(testBlock.getMinIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(wrappedTextWidth), equals(twoLinesTextHeight));
expect(testBlock.getMinIntrinsicHeight(0.0), equals(manyLinesTextHeight));
expect(testBlock.getMaxIntrinsicHeight(0.0), equals(manyLinesTextHeight));
});
}
Suragch
Updated on December 15, 2022Comments
-
Suragch over 1 year
I have previously asked about testing the size of a widget in Flutter.
However, now I am trying to test the intrinsic size of the underlying render object.
I tried to do this
testWidgets('MongolRichText has correct min instrinsic width', (WidgetTester tester) async { const String myString = 'A string'; await tester.pumpWidget( Center(child: MongolText(myString)), ); MongolRenderParagraph text = tester.firstRenderObject(find.byType(MongolRenderParagraph)); expect(text, isNotNull); expect(text.getMinIntrinsicHeight(double.infinity), 100); });
where
MongolText
creates aMongolRenderParagraph
(similarly to howText
ends up creating aParagraph
). However, I get the following error:══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════
The following StateError was thrown running a test:
Bad state: No elementHow do I get the underlying render object to run tests on it?
I found the answer so I am adding this as a self answer Q&A. My answer is below.
-
Suragch over 4 yearsI'd still like to know why
tester.firstRenderObject()
didn't work, though.