| // 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. |
| |
| // This is testing some of the named constants. |
| // ignore_for_file: use_named_constants |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| import 'dart:io'; |
| import 'dart:typed_data'; |
| import 'dart:ui'; |
| |
| import 'package:litetest/litetest.dart'; |
| import 'package:path/path.dart' as path; |
| |
| Future<Uint8List> readFile(String fileName) async { |
| final File file = File(path.join('flutter', 'testing', 'resources', fileName)); |
| return file.readAsBytes(); |
| } |
| |
| void testFontWeight() { |
| test('FontWeight.lerp works with non-null values', () { |
| expect(FontWeight.lerp(FontWeight.w400, FontWeight.w600, .5), equals(FontWeight.w500)); |
| }); |
| |
| test('FontWeight.lerp returns null if a and b are null', () { |
| expect(FontWeight.lerp(null, null, 0), isNull); |
| }); |
| |
| test('FontWeight.lerp returns FontWeight.w400 if a is null', () { |
| expect(FontWeight.lerp(null, FontWeight.w400, 0), equals(FontWeight.w400)); |
| }); |
| |
| test('FontWeight.lerp returns FontWeight.w400 if b is null', () { |
| expect(FontWeight.lerp(FontWeight.w400, null, 1), equals(FontWeight.w400)); |
| }); |
| |
| test('FontWeights have the correct value', () { |
| expect(FontWeight.w100.value, 100); |
| expect(FontWeight.w200.value, 200); |
| expect(FontWeight.w300.value, 300); |
| expect(FontWeight.w400.value, 400); |
| expect(FontWeight.w500.value, 500); |
| expect(FontWeight.w600.value, 600); |
| expect(FontWeight.w700.value, 700); |
| expect(FontWeight.w800.value, 800); |
| expect(FontWeight.w900.value, 900); |
| }); |
| } |
| |
| void testParagraphStyle() { |
| final ParagraphStyle ps0 = ParagraphStyle(textDirection: TextDirection.ltr, fontSize: 14.0); |
| final ParagraphStyle ps1 = ParagraphStyle(textDirection: TextDirection.rtl, fontSize: 14.0); |
| final ParagraphStyle ps2 = ParagraphStyle(textAlign: TextAlign.center, fontWeight: FontWeight.w800, fontSize: 10.0, height: 100.0); |
| final ParagraphStyle ps3 = ParagraphStyle(fontWeight: FontWeight.w700, fontSize: 12.0, height: 123.0); |
| |
| test('ParagraphStyle toString works', () { |
| expect(ps0.toString(), equals('ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.ltr, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, textHeightBehavior: unspecified, fontFamily: unspecified, fontSize: 14.0, height: unspecified, strutStyle: unspecified, ellipsis: unspecified, locale: unspecified)')); |
| expect(ps1.toString(), equals('ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.rtl, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, textHeightBehavior: unspecified, fontFamily: unspecified, fontSize: 14.0, height: unspecified, strutStyle: unspecified, ellipsis: unspecified, locale: unspecified)')); |
| expect(ps2.toString(), equals('ParagraphStyle(textAlign: TextAlign.center, textDirection: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, maxLines: unspecified, textHeightBehavior: unspecified, fontFamily: unspecified, fontSize: 10.0, height: 100.0x, strutStyle: unspecified, ellipsis: unspecified, locale: unspecified)')); |
| expect(ps3.toString(), equals('ParagraphStyle(textAlign: unspecified, textDirection: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, maxLines: unspecified, textHeightBehavior: unspecified, fontFamily: unspecified, fontSize: 12.0, height: 123.0x, strutStyle: unspecified, ellipsis: unspecified, locale: unspecified)')); |
| }); |
| } |
| |
| void testTextStyle() { |
| final TextStyle ts0 = TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0, height: 123.0); |
| final TextStyle ts1 = TextStyle(color: const Color(0xFF00FF00), fontWeight: FontWeight.w800, fontSize: 10.0, height: 100.0); |
| final TextStyle ts2 = TextStyle(fontFamily: 'test'); |
| final TextStyle ts3 = TextStyle(fontFamily: 'foo', fontFamilyFallback: <String>['Roboto', 'test']); |
| final TextStyle ts4 = TextStyle(leadingDistribution: TextLeadingDistribution.even); |
| |
| test('TextStyle toString works', () { |
| expect( |
| ts0.toString(), |
| equals('TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 12.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 123.0x, leadingDistribution: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified, fontFeatures: unspecified, fontVariations: unspecified)'), |
| ); |
| expect( |
| ts1.toString(), |
| equals('TextStyle(color: Color(0xff00ff00), decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 10.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 100.0x, leadingDistribution: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified, fontFeatures: unspecified, fontVariations: unspecified)'), |
| ); |
| expect( |
| ts2.toString(), |
| equals('TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: test, fontFamilyFallback: unspecified, fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, leadingDistribution: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified, fontFeatures: unspecified, fontVariations: unspecified)'), |
| ); |
| expect( |
| ts3.toString(), |
| equals('TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: foo, fontFamilyFallback: [Roboto, test], fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, leadingDistribution: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified, fontFeatures: unspecified, fontVariations: unspecified)'), |
| ); |
| expect( |
| ts4.toString(), |
| equals('TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, leadingDistribution: TextLeadingDistribution.even, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified, fontFeatures: unspecified, fontVariations: unspecified)'), |
| ); |
| }); |
| } |
| |
| void testTextHeightBehavior() { |
| const TextHeightBehavior behavior0 = TextHeightBehavior(); |
| const TextHeightBehavior behavior1 = TextHeightBehavior( |
| applyHeightToFirstAscent: false, |
| applyHeightToLastDescent: false |
| ); |
| const TextHeightBehavior behavior2 = TextHeightBehavior( |
| applyHeightToFirstAscent: false, |
| ); |
| const TextHeightBehavior behavior3 = TextHeightBehavior( |
| applyHeightToLastDescent: false |
| ); |
| const TextHeightBehavior behavior4 = TextHeightBehavior( |
| applyHeightToLastDescent: false, |
| leadingDistribution: TextLeadingDistribution.even, |
| ); |
| |
| test('TextHeightBehavior default constructor works', () { |
| expect(behavior0.applyHeightToFirstAscent, equals(true)); |
| expect(behavior0.applyHeightToLastDescent, equals(true)); |
| |
| expect(behavior1.applyHeightToFirstAscent, equals(false)); |
| expect(behavior1.applyHeightToLastDescent, equals(false)); |
| |
| expect(behavior2.applyHeightToFirstAscent, equals(false)); |
| expect(behavior2.applyHeightToLastDescent, equals(true)); |
| |
| expect(behavior3.applyHeightToFirstAscent, equals(true)); |
| expect(behavior3.applyHeightToLastDescent, equals(false)); |
| |
| expect(behavior4.applyHeightToLastDescent, equals(false)); |
| expect(behavior4.leadingDistribution, equals(TextLeadingDistribution.even)); |
| }); |
| |
| test('TextHeightBehavior toString works', () { |
| expect(behavior0.toString(), equals('TextHeightBehavior(applyHeightToFirstAscent: true, applyHeightToLastDescent: true, leadingDistribution: TextLeadingDistribution.proportional)')); |
| expect(behavior1.toString(), equals('TextHeightBehavior(applyHeightToFirstAscent: false, applyHeightToLastDescent: false, leadingDistribution: TextLeadingDistribution.proportional)')); |
| expect(behavior2.toString(), equals('TextHeightBehavior(applyHeightToFirstAscent: false, applyHeightToLastDescent: true, leadingDistribution: TextLeadingDistribution.proportional)')); |
| expect(behavior3.toString(), equals('TextHeightBehavior(applyHeightToFirstAscent: true, applyHeightToLastDescent: false, leadingDistribution: TextLeadingDistribution.proportional)')); |
| expect(behavior4.toString(), equals('TextHeightBehavior(applyHeightToFirstAscent: true, applyHeightToLastDescent: false, leadingDistribution: TextLeadingDistribution.even)')); |
| }); |
| } |
| |
| void testTextRange() { |
| test('TextRange empty ranges are correct', () { |
| const TextRange range = TextRange(start: -1, end: -1); |
| expect(range, equals(const TextRange.collapsed(-1))); |
| expect(range, equals(TextRange.empty)); |
| }); |
| test('TextRange isValid works', () { |
| expect(TextRange.empty.isValid, isFalse); |
| expect(const TextRange(start: 0, end: 0).isValid, isTrue); |
| expect(const TextRange(start: 0, end: 10).isValid, isTrue); |
| expect(const TextRange(start: 10, end: 10).isValid, isTrue); |
| expect(const TextRange(start: -1, end: 10).isValid, isFalse); |
| expect(const TextRange(start: 10, end: 0).isValid, isTrue); |
| expect(const TextRange(start: 10, end: -1).isValid, isFalse); |
| }); |
| test('TextRange isCollapsed works', () { |
| expect(TextRange.empty.isCollapsed, isTrue); |
| expect(const TextRange(start: 0, end: 0).isCollapsed, isTrue); |
| expect(const TextRange(start: 0, end: 10).isCollapsed, isFalse); |
| expect(const TextRange(start: 10, end: 10).isCollapsed, isTrue); |
| expect(const TextRange(start: -1, end: 10).isCollapsed, isFalse); |
| expect(const TextRange(start: 10, end: 0).isCollapsed, isFalse); |
| expect(const TextRange(start: 10, end: -1).isCollapsed, isFalse); |
| }); |
| test('TextRange isNormalized works', () { |
| expect(TextRange.empty.isNormalized, isTrue); |
| expect(const TextRange(start: 0, end: 0).isNormalized, isTrue); |
| expect(const TextRange(start: 0, end: 10).isNormalized, isTrue); |
| expect(const TextRange(start: 10, end: 10).isNormalized, isTrue); |
| expect(const TextRange(start: -1, end: 10).isNormalized, isTrue); |
| expect(const TextRange(start: 10, end: 0).isNormalized, isFalse); |
| expect(const TextRange(start: 10, end: -1).isNormalized, isFalse); |
| }); |
| test('TextRange textBefore works', () { |
| expect(const TextRange(start: 0, end: 0).textBefore('hello'), isEmpty); |
| expect(const TextRange(start: 1, end: 1).textBefore('hello'), equals('h')); |
| expect(const TextRange(start: 1, end: 2).textBefore('hello'), equals('h')); |
| expect(const TextRange(start: 5, end: 5).textBefore('hello'), equals('hello')); |
| expect(const TextRange(start: 0, end: 5).textBefore('hello'), isEmpty); |
| }); |
| test('TextRange textAfter works', () { |
| expect(const TextRange(start: 0, end: 0).textAfter('hello'), equals('hello')); |
| expect(const TextRange(start: 1, end: 1).textAfter('hello'), equals('ello')); |
| expect(const TextRange(start: 1, end: 2).textAfter('hello'), equals('llo')); |
| expect(const TextRange(start: 5, end: 5).textAfter('hello'), isEmpty); |
| expect(const TextRange(start: 0, end: 5).textAfter('hello'), isEmpty); |
| }); |
| test('TextRange textInside works', () { |
| expect(const TextRange(start: 0, end: 0).textInside('hello'), isEmpty); |
| expect(const TextRange(start: 1, end: 1).textInside('hello'), isEmpty); |
| expect(const TextRange(start: 1, end: 2).textInside('hello'), equals('e')); |
| expect(const TextRange(start: 5, end: 5).textInside('hello'), isEmpty); |
| expect(const TextRange(start: 0, end: 5).textInside('hello'), equals('hello')); |
| }); |
| } |
| |
| void testGlyphInfo() { |
| test('constructor', () { |
| const Rect testRect = Rect.fromLTWH(1, 2, 3, 4); |
| const TextRange testRange = TextRange(start: 5, end: 6); |
| const TextDirection testDirection = TextDirection.ltr; |
| final GlyphInfo info = GlyphInfo(testRect, testRange, testDirection); |
| expect(info.graphemeClusterLayoutBounds, testRect); |
| expect(info.graphemeClusterCodeUnitRange, testRange); |
| expect(info.writingDirection, testDirection); |
| }); |
| } |
| |
| void testLoadFontFromList() { |
| test('loadFontFromList will send platform message after font is loaded', () async { |
| late String message; |
| channelBuffers.setListener( |
| 'flutter/system', |
| (ByteData? data, PlatformMessageResponseCallback? callback) { |
| assert(data != null); |
| final Uint8List list = data!.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); |
| message = utf8.decode(list); |
| }, |
| ); |
| final Uint8List fontData = Uint8List(0); |
| await loadFontFromList(fontData, fontFamily: 'fake'); |
| expect(message, '{"type":"fontsChange"}'); |
| channelBuffers.clearListener('flutter/system'); |
| }); |
| } |
| |
| void testFontFeatureClass() { |
| test('FontFeature class', () { |
| expect(const FontFeature.alternative(1), const FontFeature('aalt')); |
| expect(const FontFeature.alternative(5), const FontFeature('aalt', 5)); |
| expect(const FontFeature.alternativeFractions(), const FontFeature('afrc')); |
| expect(const FontFeature.contextualAlternates(), const FontFeature('calt')); |
| expect(const FontFeature.caseSensitiveForms(), const FontFeature('case')); |
| expect( FontFeature.characterVariant(1), const FontFeature('cv01')); |
| expect( FontFeature.characterVariant(18), const FontFeature('cv18')); |
| expect( FontFeature.characterVariant(99), const FontFeature('cv99')); |
| expect(const FontFeature.denominator(), const FontFeature('dnom')); |
| expect(const FontFeature.fractions(), const FontFeature('frac')); |
| expect(const FontFeature.historicalForms(), const FontFeature('hist')); |
| expect(const FontFeature.historicalLigatures(), const FontFeature('hlig')); |
| expect(const FontFeature.liningFigures(), const FontFeature('lnum')); |
| expect(const FontFeature.localeAware(), const FontFeature('locl')); |
| expect(const FontFeature.localeAware(), const FontFeature('locl')); |
| expect(const FontFeature.localeAware(enable: false), const FontFeature('locl', 0)); |
| expect(const FontFeature.notationalForms(), const FontFeature('nalt')); |
| expect(const FontFeature.notationalForms(5), const FontFeature('nalt', 5)); |
| expect(const FontFeature.numerators(), const FontFeature('numr')); |
| expect(const FontFeature.oldstyleFigures(), const FontFeature('onum')); |
| expect(const FontFeature.ordinalForms(), const FontFeature('ordn')); |
| expect(const FontFeature.proportionalFigures(), const FontFeature('pnum')); |
| expect(const FontFeature.randomize(), const FontFeature('rand')); |
| expect(const FontFeature.stylisticAlternates(), const FontFeature('salt')); |
| expect(const FontFeature.scientificInferiors(), const FontFeature('sinf')); |
| expect( FontFeature.stylisticSet(1), const FontFeature('ss01')); |
| expect( FontFeature.stylisticSet(18), const FontFeature('ss18')); |
| expect(const FontFeature.subscripts(), const FontFeature('subs')); |
| expect(const FontFeature.superscripts(), const FontFeature('sups')); |
| expect(const FontFeature.swash(), const FontFeature('swsh')); |
| expect(const FontFeature.swash(0), const FontFeature('swsh', 0)); |
| expect(const FontFeature.swash(5), const FontFeature('swsh', 5)); |
| expect(const FontFeature.tabularFigures(), const FontFeature('tnum')); |
| expect(const FontFeature.slashedZero(), const FontFeature('zero')); |
| expect(const FontFeature.enable('TEST'), const FontFeature('TEST')); |
| expect(const FontFeature.disable('TEST'), const FontFeature('TEST', 0)); |
| expect(const FontFeature('FEAT', 1000).feature, 'FEAT'); |
| expect(const FontFeature('FEAT', 1000).value, 1000); |
| expect(const FontFeature('FEAT', 1000).toString(), "FontFeature('FEAT', 1000)"); |
| }); |
| } |
| |
| void testFontVariation() { |
| test('FontVariation', () async { |
| final Uint8List fontData = await readFile('RobotoSlab-VariableFont_wght.ttf'); |
| await loadFontFromList(fontData, fontFamily: 'RobotoSerif'); |
| |
| final ParagraphBuilder baseBuilder = ParagraphBuilder(ParagraphStyle( |
| fontFamily: 'RobotoSerif', |
| fontSize: 40.0, |
| )); |
| baseBuilder.addText('Hello'); |
| final Paragraph baseParagraph = baseBuilder.build(); |
| baseParagraph.layout(const ParagraphConstraints(width: double.infinity)); |
| final double baseWidth = baseParagraph.minIntrinsicWidth; |
| |
| final ParagraphBuilder wideBuilder = ParagraphBuilder(ParagraphStyle( |
| fontFamily: 'RobotoSerif', |
| fontSize: 40.0, |
| )); |
| wideBuilder.pushStyle(TextStyle( |
| fontFamily: 'RobotoSerif', |
| fontSize: 40.0, |
| fontVariations: <FontVariation>[const FontVariation('wght', 900.0)], |
| )); |
| wideBuilder.addText('Hello'); |
| final Paragraph wideParagraph = wideBuilder.build(); |
| wideParagraph.layout(const ParagraphConstraints(width: double.infinity)); |
| final double wideWidth = wideParagraph.minIntrinsicWidth; |
| |
| expect(wideWidth, greaterThan(baseWidth)); |
| }); |
| |
| test('FontVariation constructors', () async { |
| expect(const FontVariation.weight(123.0).axis, 'wght'); |
| expect(const FontVariation.weight(123.0).value, 123.0); |
| expect(const FontVariation.width(123.0).axis, 'wdth'); |
| expect(const FontVariation.width(123.0).value, 123.0); |
| expect(const FontVariation.slant(45.0).axis, 'slnt'); |
| expect(const FontVariation.slant(45.0).value, 45.0); |
| expect(const FontVariation.opticalSize(67.0).axis, 'opsz'); |
| expect(const FontVariation.opticalSize(67.0).value, 67.0); |
| expect(const FontVariation.italic(0.8).axis, 'ital'); |
| expect(const FontVariation.italic(0.8).value, 0.8); |
| }); |
| |
| test('FontVariation.lerp', () async { |
| expect(FontVariation.lerp(const FontVariation.weight(100.0), const FontVariation.weight(300.0), 0.5), const FontVariation.weight(200.0)); |
| expect(FontVariation.lerp(const FontVariation.slant(0.0), const FontVariation.slant(-80.0), 0.25), const FontVariation.slant(-20.0)); |
| expect(FontVariation.lerp(const FontVariation.width(90.0), const FontVariation.italic(0.2), 0.1), const FontVariation.width(90.0)); |
| expect(FontVariation.lerp(const FontVariation.width(90.0), const FontVariation.italic(0.2), 0.9), const FontVariation.italic(0.2)); |
| }); |
| } |
| |
| void testGetWordBoundary() { |
| test('GetWordBoundary', () async { |
| final Uint8List fontData = await readFile('RobotoSlab-VariableFont_wght.ttf'); |
| await loadFontFromList(fontData, fontFamily: 'RobotoSerif'); |
| |
| final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle( |
| fontFamily: 'RobotoSerif', |
| fontSize: 40.0, |
| )); |
| builder.addText('Hello team'); |
| final Paragraph paragraph = builder.build(); |
| paragraph.layout(const ParagraphConstraints(width: double.infinity)); |
| |
| TextRange range = paragraph.getWordBoundary(const TextPosition(offset: 5, affinity: TextAffinity.upstream)); |
| expect(range.start, 0); |
| expect(range.end, 5); |
| |
| range = paragraph.getWordBoundary(const TextPosition(offset: 5)); |
| expect(range.start, 5); |
| expect(range.end, 6); |
| }); |
| } |
| |
| void main() { |
| testFontWeight(); |
| testParagraphStyle(); |
| testTextStyle(); |
| testTextHeightBehavior(); |
| testTextRange(); |
| testGlyphInfo(); |
| testLoadFontFromList(); |
| testFontFeatureClass(); |
| testFontVariation(); |
| testGetWordBoundary(); |
| } |