From 4a8bb3cbc3836928e69c55a479be032d1ef08157 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Sun, 8 Mar 2026 21:46:58 -0700 Subject: [PATCH] [pigeon] Use hasLength and isEmpty in tests for better failure messages --- packages/pigeon/test/pigeon_lib_test.dart | 215 +++++++++++----------- 1 file changed, 105 insertions(+), 110 deletions(-) diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 13f84047f0a5..4e228129996a 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -196,12 +196,12 @@ abstract class Api1 { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); final Root root = parseResult.root; - expect(root.classes.length, equals(3)); - expect(root.apis.length, equals(1)); + expect(root.classes, hasLength(3)); + expect(root.apis, hasLength(1)); expect(root.apis[0].name, equals('Api1')); - expect(root.apis[0].methods.length, equals(1)); + expect(root.apis[0].methods, hasLength(1)); expect(root.apis[0].methods[0].name, equals('doit')); expect(root.apis[0].methods[0].parameters[0].name, equals('input')); expect( @@ -226,17 +226,17 @@ abstract class Api1 { expect(output, isNotNull); expect(unused, isNotNull); - expect(input?.fields.length, equals(1)); + expect(input?.fields, hasLength(1)); expect(input?.fields[0].name, equals('input')); expect(input?.fields[0].type.baseName, equals('String')); expect(input?.fields[0].type.isNullable, isTrue); - expect(output?.fields.length, equals(1)); + expect(output?.fields, hasLength(1)); expect(output?.fields[0].name, equals('output')); expect(output?.fields[0].type.baseName, equals('String')); expect(output?.fields[0].type.isNullable, isTrue); - expect(unused?.fields.length, equals(1)); + expect(unused?.fields, hasLength(1)); expect(unused?.fields[0].name, equals('field')); expect(unused?.fields[0].type.baseName, equals('String')); expect(unused?.fields[0].type.isNullable, isTrue); @@ -254,7 +254,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(source); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].message, contains('InvalidDatatype')); expect(results.errors[0].message, contains('dynamic')); }); @@ -268,7 +268,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(source); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect( results.errors[0].message, contains( @@ -291,7 +291,7 @@ abstract class Api { '''; final ParseResults results = parseSource(source); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); }); test('enum in classes', () { @@ -311,10 +311,10 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, equals(0)); - expect(results.root.classes.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.classes, hasLength(1)); expect(results.root.classes[0].name, equals('ClassWithEnum')); - expect(results.root.classes[0].fields.length, equals(1)); + expect(results.root.classes[0].fields, hasLength(1)); expect(results.root.classes[0].fields[0].type.baseName, equals('Enum1')); expect(results.root.classes[0].fields[0].type.isNullable, isTrue); expect(results.root.classes[0].fields[0].name, equals('enum1')); @@ -337,9 +337,9 @@ abstract class ApiTwoMethods { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.apis.length, 1); - expect(results.root.apis[0].methods.length, equals(2)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(2)); expect(results.root.apis[0].methods[0].name, equals('method1')); expect(results.root.apis[0].methods[1].name, equals('method2')); }); @@ -360,12 +360,12 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, equals(0)); - expect(results.root.classes.length, equals(2)); + expect(results.errors, isEmpty); + expect(results.root.classes, hasLength(2)); final Class nested = results.root.classes.firstWhere( (Class x) => x.name == 'Nested', ); - expect(nested.fields.length, equals(1)); + expect(nested.fields, hasLength(1)); expect(nested.fields[0].type.baseName, equals('Input1')); expect(nested.fields[0].type.isNullable, isTrue); }); @@ -386,8 +386,8 @@ abstract class AFlutterApi { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, equals(0)); - expect(results.root.apis.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); expect(results.root.apis[0].name, equals('AFlutterApi')); expect(results.root.apis[0], isA()); }); @@ -404,9 +404,9 @@ abstract class VoidApi { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, equals(0)); - expect(results.root.apis.length, equals(1)); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect(results.root.apis[0].name, equals('VoidApi')); expect(results.root.apis[0].methods[0].returnType.isVoid, isTrue); }); @@ -423,9 +423,9 @@ abstract class VoidArgApi { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, equals(0)); - expect(results.root.apis.length, equals(1)); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect(results.root.apis[0].name, equals('VoidArgApi')); expect( results.root.apis[0].methods[0].returnType.baseName, @@ -446,8 +446,8 @@ abstract class ApiWithMockDartClass { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, equals(0)); - expect(results.root.apis.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); expect( (results.root.apis[0] as AstHostApi).dartHostTestHandler, equals('ApiWithMockDartClassMock'), @@ -470,14 +470,13 @@ abstract class NestorApi { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.apis.length, 1); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); final List classNames = results.root.classes .map((Class x) => x.name) .toList(); - expect(classNames.length, 2); - expect(classNames.contains('Nestor'), true); - expect(classNames.contains('OnlyVisibleFromNesting'), true); + expect(classNames, hasLength(2)); + expect(classNames, containsAll(['Nestor', 'OnlyVisibleFromNesting'])); }); test('copyright flag', () { @@ -634,10 +633,10 @@ abstract class NestedEnumApi { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); - expect(parseResult.root.apis.length, 1); - expect(parseResult.root.classes.length, 3); - expect(parseResult.root.enums.length, 1); + expect(parseResult.errors, isEmpty); + expect(parseResult.root.apis, hasLength(1)); + expect(parseResult.root.classes, hasLength(3)); + expect(parseResult.root.enums, hasLength(1)); }); test('test circular references', () { @@ -656,19 +655,19 @@ abstract class NotificationsHostApi { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.classes.length, 2); + expect(results.errors, isEmpty); + expect(results.root.classes, hasLength(2)); final Class foo = results.root.classes.firstWhere( (Class aClass) => aClass.name == 'Foo', ); - expect(foo.fields.length, 1); + expect(foo.fields, hasLength(1)); expect(foo.fields[0].type.baseName, 'Bar'); }); test('test compilation error', () { const code = 'Hello\n'; final ParseResults results = parseSource(code); - expect(results.errors.length, greaterThanOrEqualTo(1)); + expect(results.errors, hasLength(greaterThanOrEqualTo(1))); expect(results.errors[0].lineNumber, 1); }); @@ -685,7 +684,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect(results.errors[0].message, contains('Method')); }); @@ -702,7 +701,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 2); expect(results.errors[0].message, contains('Initialization')); }); @@ -720,7 +719,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 7); expect(results.errors[0].message, contains('Field')); }); @@ -738,7 +737,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); }); test('constructor body in data class', () { @@ -754,7 +753,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect(results.errors[0].message, contains('Constructor')); }); @@ -772,7 +771,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect(results.errors[0].message, contains('Constructor')); }); @@ -790,7 +789,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 7); expect(results.errors[0].message, contains('Constructor')); }); @@ -798,14 +797,14 @@ abstract class Api { test('test invalid import', () { const code = "import 'foo.dart';\n"; final ParseResults results = parseSource(code); - expect(results.errors.length, greaterThanOrEqualTo(1)); + expect(results.errors, hasLength(greaterThanOrEqualTo(1))); expect(results.errors[0].lineNumber, 1); }); test('test valid import', () { const code = "import 'package:pigeon/pigeon.dart';\n"; final ParseResults parseResults = parseSource(code); - expect(parseResults.errors.length, 0); + expect(parseResults.errors, isEmpty); }); test('error with static field', () { @@ -821,7 +820,7 @@ abstract class WithStaticFieldApi { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(1)); + expect(parseResult.errors, hasLength(1)); expect(parseResult.errors[0].message, contains('static field')); expect(parseResult.errors[0].lineNumber, isNotNull); }); @@ -838,9 +837,9 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); final NamedType field = parseResult.root.classes[0].fields[0]; - expect(field.type.typeArguments.length, 1); + expect(field.type.typeArguments, hasLength(1)); expect(field.type.typeArguments[0].baseName, 'int'); }); @@ -856,9 +855,9 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); final NamedType field = parseResult.root.classes[0].fields[0]; - expect(field.type.typeArguments.length, 1); + expect(field.type.typeArguments, hasLength(1)); expect(field.type.typeArguments[0].baseName, 'List'); expect(field.type.typeArguments[0].typeArguments[0].baseName, 'int'); }); @@ -876,7 +875,7 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); }); test('enums argument flutter', () { @@ -893,7 +892,7 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); }); test('enums list argument', () { @@ -906,7 +905,7 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); }); test('enums map argument key', () { @@ -919,7 +918,7 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); }); test('enums map argument value', () { @@ -932,7 +931,7 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); }); test('enums return value', () { @@ -949,7 +948,7 @@ abstract class Api { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); }); test('return type generics', () { @@ -1026,7 +1025,7 @@ abstract class Api { '''; final ParseResults parseResult = parseSource(code); final NamedType field = parseResult.root.classes[0].fields[0]; - expect(field.type.typeArguments.length, 2); + expect(field.type.typeArguments, hasLength(2)); expect(field.type.typeArguments[0].baseName, 'String'); expect(field.type.typeArguments[1].baseName, 'int'); }); @@ -1043,10 +1042,10 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.root.apis.length, 1); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect(results.root.apis[0].methods[0].name, equals('method')); - expect(results.root.apis[0].methods[0].parameters.length, 2); + expect(results.root.apis[0].methods[0].parameters, hasLength(2)); }); test('no type name argument', () { @@ -1057,7 +1056,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect( results.errors[0].message, @@ -1074,9 +1073,9 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.apis.length, 1); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect( results.root.apis[0].methods[0].objcSelector, equals('subtractValue:by:'), @@ -1092,7 +1091,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect( results.errors[0].message, @@ -1109,9 +1108,9 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.apis.length, 1); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect(results.root.apis[0].methods[0].objcSelector, equals('foobar')); }); @@ -1124,9 +1123,9 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.apis.length, 1); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect( results.root.apis[0].methods[0].swiftFunction, equals('subtractValue(_:by:)'), @@ -1142,7 +1141,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect( results.errors[0].message, @@ -1159,9 +1158,9 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.apis.length, 1); - expect(results.root.apis[0].methods.length, equals(1)); + expect(results.errors, isEmpty); + expect(results.root.apis, hasLength(1)); + expect(results.root.apis[0].methods, hasLength(1)); expect(results.root.apis[0].methods[0].swiftFunction, equals('foobar()')); }); @@ -1195,8 +1194,8 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.classes.length, 1); + expect(results.errors, isEmpty); + expect(results.root.classes, hasLength(1)); expect(results.root.classes[0].name, 'Foo'); }); @@ -1212,8 +1211,8 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.classes.length, 1); + expect(results.errors, isEmpty); + expect(results.root.classes, hasLength(1)); expect(results.root.classes[0].name, 'Foo'); }); @@ -1234,19 +1233,15 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); - expect(results.root.classes.length, 2); + expect(results.errors, isEmpty); + expect(results.root.classes, hasLength(2)); expect( - results.root.classes - .where((Class element) => element.name == 'Foo') - .length, - 1, + results.root.classes.where((Class element) => element.name == 'Foo'), + hasLength(1), ); expect( - results.root.classes - .where((Class element) => element.name == 'Bar') - .length, - 1, + results.root.classes.where((Class element) => element.name == 'Bar'), + hasLength(1), ); }); @@ -1258,7 +1253,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect(results.errors[0].lineNumber, 3); expect(results.errors[0].message, contains('Unknown type: Foo')); }); @@ -1271,7 +1266,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); }); test('Export unreferenced enums', () { @@ -1293,7 +1288,7 @@ abstract class HostApiBridge { } '''; final ParseResults results = parseSource(code); - expect(results.root.enums.length, 1); + expect(results.root.enums, hasLength(1)); expect(results.root.enums[0].name, 'MessageKey'); }); @@ -1381,7 +1376,7 @@ abstract class Api { '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); expect(results.root.apis[0].methods[0].returnType.isNullable, isTrue); }); @@ -1393,7 +1388,7 @@ abstract class Api { } '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); expect( results.root.apis[0].methods[0].parameters[0].type.isNullable, isTrue, @@ -1410,7 +1405,7 @@ abstract class Api { '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); expect( results.root.apis[0].methods[0].taskQueueType, equals(TaskQueueType.serialBackgroundThread), @@ -1426,7 +1421,7 @@ abstract class Api { '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 0); + expect(results.errors, isEmpty); expect( results.root.apis[0].methods[0].taskQueueType, equals(TaskQueueType.serial), @@ -1443,7 +1438,7 @@ abstract class Api { '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect( results.errors[0].message, contains('Unsupported TaskQueue specification'), @@ -1504,7 +1499,7 @@ abstract class Api { '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect( results.errors[0].message, contains('FlutterApi method parameters must be positional'), @@ -1520,7 +1515,7 @@ abstract class Api { '''; final ParseResults results = parseSource(code); - expect(results.errors.length, 1); + expect(results.errors, hasLength(1)); expect( results.errors[0].message, contains('FlutterApi method parameters must not be optional'), @@ -1538,14 +1533,14 @@ abstract class MyClass { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(0)); + expect(parseResult.errors, isEmpty); final Root root = parseResult.root; - expect(root.apis.length, equals(1)); + expect(root.apis, hasLength(1)); final proxyApi = root.apis.single as AstProxyApi; expect(proxyApi.name, equals('MyClass')); expect(proxyApi.constructors.single.name, equals('')); - expect(proxyApi.methods.length, equals(2)); + expect(proxyApi.methods, hasLength(2)); for (final Method method in proxyApi.methods) { if (method.location == ApiLocation.host) { @@ -1569,7 +1564,7 @@ abstract class MyClass { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(1)); + expect(parseResult.errors, hasLength(1)); expect( parseResult.errors.single.message, contains('ProxyApis do not support data classes'), @@ -1799,7 +1794,7 @@ abstract class EventChannelApi { } '''; final ParseResults parseResult = parseSource(code); - expect(parseResult.errors.length, equals(1)); + expect(parseResult.errors, hasLength(1)); expect( parseResult.errors.single.message, contains(