Unverified Commit 1c7e34bb authored by Darren Austin's avatar Darren Austin Committed by GitHub

Migrate flutter_localizations to null safety. (#68645)

Migrate flutter_localizations to null safety.
parent 2a5aa294
......@@ -704,7 +704,7 @@ Future<void> _runFrameworkTests() async {
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata, tests: <String>[path.join('test', 'src', 'real_tests')]);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'integration_test'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata, options: soundNullSafetyOptions);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata, options: soundNullSafetyOptions);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: mixedModeNullSafetyOptions);
......
......@@ -382,15 +382,20 @@ $factoryDeclaration
///
/// Used by [generateGetter] below.
String generateType(Map<String, dynamic> attributes) {
bool optional = false;
String type = 'String';
if (attributes != null) {
optional = attributes.containsKey('optional');
switch (attributes['x-flutter-type'] as String) {
case 'icuShortTimePattern':
return 'TimeOfDayFormat';
type = 'TimeOfDayFormat';
break;
case 'scriptCategory':
return 'ScriptCategory';
type = 'ScriptCategory';
break;
}
}
return 'String';
return type + (optional ? '?' : '');
}
/// Returns the appropriate name for getters with the given attributes.
......
......@@ -16,7 +16,6 @@ HeaderGenerator generateCupertinoHeader = (String regenerateInstructions) {
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart' as intl;
......@@ -40,14 +39,14 @@ ConstructorGenerator generateCupertinoConstructor = (LocaleInfo locale) {
/// For details on the meaning of the arguments, see [GlobalCupertinoLocalizations].
const CupertinoLocalization${locale.camelCase()}({
String localeName = '$localeName',
@required intl.DateFormat fullYearFormat,
@required intl.DateFormat dayFormat,
@required intl.DateFormat mediumDateFormat,
@required intl.DateFormat singleDigitHourFormat,
@required intl.DateFormat singleDigitMinuteFormat,
@required intl.DateFormat doubleDigitMinuteFormat,
@required intl.DateFormat singleDigitSecondFormat,
@required intl.NumberFormat decimalFormat,
required intl.DateFormat fullYearFormat,
required intl.DateFormat dayFormat,
required intl.DateFormat mediumDateFormat,
required intl.DateFormat singleDigitHourFormat,
required intl.DateFormat singleDigitMinuteFormat,
required intl.DateFormat doubleDigitMinuteFormat,
required intl.DateFormat singleDigitSecondFormat,
required intl.NumberFormat decimalFormat,
}) : super(
localeName: localeName,
fullYearFormat: fullYearFormat,
......@@ -64,7 +63,7 @@ ConstructorGenerator generateCupertinoConstructor = (LocaleInfo locale) {
const String cupertinoFactoryName = 'getCupertinoTranslation';
const String cupertinoFactoryDeclaration = '''
GlobalCupertinoLocalizations getCupertinoTranslation(
GlobalCupertinoLocalizations? getCupertinoTranslation(
Locale locale,
intl.DateFormat fullYearFormat,
intl.DateFormat dayFormat,
......
......@@ -16,7 +16,6 @@ HeaderGenerator generateMaterialHeader = (String regenerateInstructions) {
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
......@@ -40,15 +39,15 @@ ConstructorGenerator generateMaterialConstructor = (LocaleInfo locale) {
/// For details on the meaning of the arguments, see [GlobalMaterialLocalizations].
const MaterialLocalization${locale.camelCase()}({
String localeName = '$localeName',
@required intl.DateFormat fullYearFormat,
@required intl.DateFormat compactDateFormat,
@required intl.DateFormat shortDateFormat,
@required intl.DateFormat mediumDateFormat,
@required intl.DateFormat longDateFormat,
@required intl.DateFormat yearMonthFormat,
@required intl.DateFormat shortMonthDayFormat,
@required intl.NumberFormat decimalFormat,
@required intl.NumberFormat twoDigitZeroPaddedFormat,
required intl.DateFormat fullYearFormat,
required intl.DateFormat compactDateFormat,
required intl.DateFormat shortDateFormat,
required intl.DateFormat mediumDateFormat,
required intl.DateFormat longDateFormat,
required intl.DateFormat yearMonthFormat,
required intl.DateFormat shortMonthDayFormat,
required intl.NumberFormat decimalFormat,
required intl.NumberFormat twoDigitZeroPaddedFormat,
}) : super(
localeName: localeName,
fullYearFormat: fullYearFormat,
......@@ -66,7 +65,7 @@ ConstructorGenerator generateMaterialConstructor = (LocaleInfo locale) {
const String materialFactoryName = 'getMaterialTranslation';
const String materialFactoryDeclaration = '''
GlobalMaterialLocalizations getMaterialTranslation(
GlobalMaterialLocalizations? getMaterialTranslation(
Locale locale,
intl.DateFormat fullYearFormat,
intl.DateFormat compactDateFormat,
......
......@@ -67,8 +67,9 @@ void validateEnglishLocalizations(File file) {
continue;
}
final bool optional = atResource.containsKey('optional');
final String description = atResource['description'] as String;
if (description == null)
if (description == null && !optional)
errorMessages.writeln('No description specified for $atResourceId');
final String plural = atResource['plural'] as String;
......@@ -78,7 +79,7 @@ void validateEnglishLocalizations(File file) {
if (!bundle.containsKey(resourceIdOther))
errorMessages.writeln('Default plural resource $resourceIdOther undefined');
} else {
if (!bundle.containsKey(resourceId))
if (!optional && !bundle.containsKey(resourceId))
errorMessages.writeln('No matching $resourceId defined for $atResourceId');
}
}
......
......@@ -1763,9 +1763,10 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
});
},
children: List<Widget>.generate(24, (int index) {
final String label = localizations.timerPickerHourLabel(index) ?? '';
final String semanticsLabel = textDirectionFactor == 1
? localizations.timerPickerHour(index) + localizations.timerPickerHourLabel(index)
: localizations.timerPickerHourLabel(index) + localizations.timerPickerHour(index);
? localizations.timerPickerHour(index) + label
: label + localizations.timerPickerHour(index);
return Semantics(
label: semanticsLabel,
......@@ -1793,7 +1794,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
child: _buildHourPicker(additionalPadding, selectionOverlay),
),
_buildLabel(
localizations.timerPickerHourLabel(lastSelectedHour ?? selectedHour!),
localizations.timerPickerHourLabel(lastSelectedHour ?? selectedHour!) ?? '',
additionalPadding,
),
],
......@@ -1826,10 +1827,10 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
},
children: List<Widget>.generate(60 ~/ widget.minuteInterval, (int index) {
final int minute = index * widget.minuteInterval;
final String label = localizations.timerPickerMinuteLabel(minute) ?? '';
final String semanticsLabel = textDirectionFactor == 1
? localizations.timerPickerMinute(minute) + localizations.timerPickerMinuteLabel(minute)
: localizations.timerPickerMinuteLabel(minute) + localizations.timerPickerMinute(minute);
? localizations.timerPickerMinute(minute) + label
: label + localizations.timerPickerMinute(minute);
return Semantics(
label: semanticsLabel,
......@@ -1857,7 +1858,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
child: _buildMinutePicker(additionalPadding, selectionOverlay),
),
_buildLabel(
localizations.timerPickerMinuteLabel(lastSelectedMinute ?? selectedMinute),
localizations.timerPickerMinuteLabel(lastSelectedMinute ?? selectedMinute) ?? '',
additionalPadding,
),
],
......@@ -1890,10 +1891,10 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
},
children: List<Widget>.generate(60 ~/ widget.secondInterval, (int index) {
final int second = index * widget.secondInterval;
final String label = localizations.timerPickerSecondLabel(second) ?? '';
final String semanticsLabel = textDirectionFactor == 1
? localizations.timerPickerSecond(second) + localizations.timerPickerSecondLabel(second)
: localizations.timerPickerSecondLabel(second) + localizations.timerPickerSecond(second);
? localizations.timerPickerSecond(second) + label
: label + localizations.timerPickerSecond(second);
return Semantics(
label: semanticsLabel,
......@@ -1921,7 +1922,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
child: _buildSecondPicker(additionalPadding, selectionOverlay),
),
_buildLabel(
localizations.timerPickerSecondLabel(lastSelectedSecond ?? selectedSecond!),
localizations.timerPickerSecondLabel(lastSelectedSecond ?? selectedSecond!) ?? '',
additionalPadding,
),
],
......
......@@ -108,7 +108,7 @@ abstract class CupertinoLocalizations {
/// Semantics label for the given hour value in [CupertinoDatePicker].
// The global version uses the translated string from the arb file.
String datePickerHourSemanticsLabel(int hour);
String? datePickerHourSemanticsLabel(int hour);
/// Minute that is shown in [CupertinoDatePicker] spinner corresponding
/// to the given minute value.
......@@ -122,7 +122,7 @@ abstract class CupertinoLocalizations {
/// Semantics label for the given minute value in [CupertinoDatePicker].
// The global version uses the translated string from the arb file.
String datePickerMinuteSemanticsLabel(int minute);
String? datePickerMinuteSemanticsLabel(int minute);
/// The order of the date elements that will be shown in [CupertinoDatePicker].
// The global version uses the translated string from the arb file.
......@@ -190,7 +190,7 @@ abstract class CupertinoLocalizations {
/// [CupertinoTimerPicker] when selected hour value is `hour`.
/// This function will deal with pluralization based on the `hour` parameter.
// The global version uses the translated string from the arb file.
String timerPickerHourLabel(int hour);
String? timerPickerHourLabel(int hour);
/// All possible hour labels that appears next to the hour picker in
/// [CupertinoTimerPicker]
......@@ -200,7 +200,7 @@ abstract class CupertinoLocalizations {
/// [CupertinoTimerPicker] when selected minute value is `minute`.
/// This function will deal with pluralization based on the `minute` parameter.
// The global version uses the translated string from the arb file.
String timerPickerMinuteLabel(int minute);
String? timerPickerMinuteLabel(int minute);
/// All possible minute labels that appears next to the minute picker in
/// [CupertinoTimerPicker]
......@@ -210,7 +210,7 @@ abstract class CupertinoLocalizations {
/// [CupertinoTimerPicker] when selected minute value is `second`.
/// This function will deal with pluralization based on the `second` parameter.
// The global version uses the translated string from the arb file.
String timerPickerSecondLabel(int second);
String? timerPickerSecondLabel(int second);
/// All possible second labels that appears next to the second picker in
/// [CupertinoTimerPicker]
......
# Use the parent analysis options settings and enable null-experiment.
include: ../analysis_options.yaml
analyzer:
errors:
always_require_non_null_named_parameters: false # not needed with nnbd
type_init_formals: false # https://github.com/dart-lang/linter/issues/2192
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
void_checks: false # https://github.com/dart-lang/linter/issues/2185
unnecessary_null_comparison: false # Turned off until null-safe rollout is complete.
{
"@datePickerHourSemanticsLabelZero": {
"optional": true
},
"datePickerHourSemanticsLabelOne": "$hour o'clock",
"@datePickerHourSemanticsLabelOne": {
"optional": true
},
"@datePickerHourSemanticsLabelTwo": {
"optional": true
},
"@datePickerHourSemanticsLabelFew": {
"optional": true
},
"@datePickerHourSemanticsLabelMany": {
"optional": true
},
"datePickerHourSemanticsLabelOther": "$hour o'clock",
"@datePickerHourSemanticsLabel": {
"description": "Accessibility announcement for the selected hour on a time picker such as '5 o'clock' or '5点'",
"plural": "hour"
},
"@datePickerMinuteSemanticsLabelZero": {
"optional": true
},
"datePickerMinuteSemanticsLabelOne": "1 minute",
"@datePickerMinuteSemanticsLabelOne": {
"optional": true
},
"@datePickerMinuteSemanticsLabelTwo": {
"optional": true
},
"@datePickerMinuteSemanticsLabelFew": {
"optional": true
},
"@datePickerMinuteSemanticsLabelMany": {
"optional": true
},
"datePickerMinuteSemanticsLabelOther": "$minute minutes",
"@datePickerMinuteSemanticsLabel": {
"description": "Accessibility announcement for the selected minute on a time picker such as '15 minutes' or '15分'",
......@@ -49,21 +79,66 @@
"parameters": "tabIndex, tabCount"
},
"@timerPickerHourLabelZero": {
"optional": true
},
"timerPickerHourLabelOne": "hour",
"@timerPickerHourLabelOne": {
"optional": true
},
"@timerPickerHourLabelTwo": {
"optional": true
},
"@timerPickerHourLabelFew": {
"optional": true
},
"@timerPickerHourLabelMany": {
"optional": true
},
"timerPickerHourLabelOther": "hours",
"@timerPickerHourLabel": {
"description": "The label adjacent to an hour integer number in a countdown timer. The reference abbreviation is what iOS does in the stock clock app's countdown timer.",
"plural": "hour"
},
"@timerPickerMinuteLabelZero": {
"optional": true
},
"timerPickerMinuteLabelOne": "min.",
"@timerPickerMinuteLabelOne": {
"optional": true
},
"@timerPickerMinuteLabelTwo": {
"optional": true
},
"@timerPickerMinuteLabelFew": {
"optional": true
},
"@timerPickerMinuteLabelMany": {
"optional": true
},
"timerPickerMinuteLabelOther": "min.",
"@timerPickerMinuteLabel": {
"description": "The label adjacent to a minute integer number in a countdown timer. The reference abbreviation is what iOS does in the stock clock app's countdown timer.",
"plural": "minute"
},
"@timerPickerSecondLabelZero": {
"optional": true
},
"timerPickerSecondLabelOne": "sec.",
"@timerPickerSecondLabelOne": {
"optional": true
},
"@timerPickerSecondLabelTwo": {
"optional": true
},
"@timerPickerSecondLabelFew": {
"optional": true
},
"@timerPickerSecondLabelMany": {
"optional": true
},
"timerPickerSecondLabelOther": "sec.",
"@timerPickerSecondLabel": {
"description": "The label adjacent to a second integer number in a countdown timer. The reference abbreviation is what iOS does in the stock clock app's countdown timer.",
......
......@@ -73,7 +73,22 @@
},
"licensesPackageDetailTextZero": "No licenses",
"@licensesPackageDetailTextZero": {
"optional": true
},
"licensesPackageDetailTextOne": "1 license",
"@licensesPackageDetailTextOne": {
"optional": true
},
"@licensesPackageDetailTextTwo": {
"optional": true
},
"@licensesPackageDetailTextFew": {
"optional": true
},
"@licensesPackageDetailTextMany": {
"optional": true
},
"licensesPackageDetailTextOther": "$licenseCount licenses",
"@licensesPackageDetailText": {
"description": "The subtitle and detail text for a package displayed on the Flutter licenses page. The value of $licenseCount is an integer which indicates the number of licenses the package has.",
......@@ -104,7 +119,22 @@
},
"selectedRowCountTitleZero": "No items selected",
"@selectedRowCountTitleZero": {
"optional": true
},
"selectedRowCountTitleOne": "1 item selected",
"@selectedRowCountTitleOne": {
"optional": true
},
"@selectedRowCountTitleTwo": {
"optional": true
},
"@selectedRowCountTitleFew": {
"optional": true
},
"@selectedRowCountTitleMany": {
"optional": true
},
"selectedRowCountTitleOther": "$selectedRowCount items selected",
"@selectedRowCountTitle": {
"description": "The title for the header of a paginated data table when the user is selecting rows. The value of $selectedRowCount is an integer which indicates the number of data table row elements that have been selected.",
......@@ -389,7 +419,22 @@
},
"remainingTextFieldCharacterCountZero": "No characters remaining",
"@remainingTextFieldCharacterCountZero": {
"optional": true
},
"remainingTextFieldCharacterCountOne": "1 character remaining",
"@remainingTextFieldCharacterCountOne": {
"optional": true
},
"@remainingTextFieldCharacterCountTwo": {
"optional": true
},
"@remainingTextFieldCharacterCountFew": {
"optional": true
},
"@remainingTextFieldCharacterCountMany": {
"optional": true
},
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining",
"@remainingTextFieldCharacterCount": {
"description": "The label for the TextField's character counter. remainingCharacters is a integer representing how many more characters the user can type into the text field before using up a given budget. All values are greater than or equal to zero.",
......
{
"scriptCategory": "tall",
"timeOfDayFormat": "HH:mm",
"anteMeridiemAbbreviation": "AM",
"@anteMeridiemAbbreviation": {"notUsed":"Pashto time format does not use a.m. indicator"},
"postMeridiemAbbreviation": "PM",
"@postMeridiemAbbreviation": {"notUsed":"Pashto time format does not use p.m. indicator"},
"openAppDrawerTooltip": "د پرانیستی نیینګ مینو",
"backButtonTooltip": "شاته",
......
......@@ -28,7 +28,7 @@ void loadDateIntlDataIfNotLoaded() {
// Strip scriptCode from the locale, as we do not distinguish between scripts
// for dates.
final List<String> codes = locale.split('_');
String countryCode;
String? countryCode;
if (codes.length == 2) {
countryCode = codes[1].length < 4 ? codes[1] : null;
} else if (codes.length == 3) {
......
......@@ -43,7 +43,7 @@ class GlobalWidgetsLocalizations implements WidgetsLocalizations {
@override
TextDirection get textDirection => _textDirection;
TextDirection _textDirection;
late TextDirection _textDirection;
/// Creates an object that provides localized resource values for the
/// lowest levels of the Flutter framework.
......
......@@ -2,7 +2,7 @@ name: flutter_localizations
environment:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
sdk: ">=2.2.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"
dependencies:
# To update these, use "flutter update-packages --force-upgrade".
......
......@@ -63,7 +63,7 @@ void main() {
)
);
await tester.binding.setLocale('zh', null);
await tester.binding.setLocale('zh', '');
await tester.pump();
await tester.binding.setLocale('es', 'US');
await tester.pump();
......@@ -87,18 +87,18 @@ class _DummyLocalizationsDelegate extends LocalizationsDelegate<DummyLocalizatio
class DummyLocalizations {}
class LocalizationTracker extends StatefulWidget {
const LocalizationTracker({Key key}) : super(key: key);
const LocalizationTracker({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => LocalizationTrackerState();
}
class LocalizationTrackerState extends State<LocalizationTracker> {
double captionFontSize;
late double captionFontSize;
@override
Widget build(BuildContext context) {
captionFontSize = Theme.of(context).textTheme.caption.fontSize;
captionFontSize = Theme.of(context).textTheme.caption!.fontSize!;
return Container();
}
}
......@@ -9,9 +9,9 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
DateTime firstDate;
DateTime lastDate;
DateTime initialDate;
late DateTime firstDate;
late DateTime lastDate;
late DateTime initialDate;
setUp(() {
firstDate = DateTime(2001, DateTime.january, 1);
......@@ -53,10 +53,10 @@ void main() {
for (final Locale locale in testLocales.keys) {
testWidgets('shows dates for $locale', (WidgetTester tester) async {
final List<String> expectedDaysOfWeek = testLocales[locale]['expectedDaysOfWeek'] as List<String>;
final List<String> expectedDaysOfMonth = testLocales[locale]['expectedDaysOfMonth'] as List<String>;
final String expectedMonthYearHeader = testLocales[locale]['expectedMonthYearHeader'] as String;
final TextDirection textDirection = testLocales[locale]['textDirection'] as TextDirection;
final List<String> expectedDaysOfWeek = testLocales[locale]!['expectedDaysOfWeek'] as List<String>;
final List<String> expectedDaysOfMonth = testLocales[locale]!['expectedDaysOfMonth'] as List<String>;
final String expectedMonthYearHeader = testLocales[locale]!['expectedMonthYearHeader'] as String;
final TextDirection textDirection = testLocales[locale]!['textDirection'] as TextDirection;
final DateTime baseDate = DateTime(2017, 9, 27);
await _pumpBoilerplate(tester, CalendarDatePicker(
......@@ -72,7 +72,7 @@ void main() {
expect(find.text(dayOfWeek), findsWidgets);
}
Offset previousCellOffset;
Offset? previousCellOffset;
for (final String dayOfMonth in expectedDaysOfMonth) {
final Finder dayCell = find.descendant(of: find.byType(GridView), matching: find.text(dayOfMonth));
expect(dayCell, findsOneWidget);
......
......@@ -163,7 +163,7 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/67644.
testWidgets('en_US is initialized correctly by Flutter when DateFormat is used', (WidgetTester tester) async {
DateFormat dateFormat;
late DateFormat dateFormat;
await tester.pumpWidget(MaterialApp(
supportedLocales: const <Locale>[
......@@ -180,7 +180,7 @@ void main() {
}),
));
expect(dateFormat?.locale, 'en_US');
expect(dateFormat.locale, 'en_US');
});
}
......
......@@ -9,13 +9,13 @@ import 'package:flutter_test/flutter_test.dart';
class _TimePickerLauncher extends StatelessWidget {
const _TimePickerLauncher({
Key key,
Key? key,
this.onChanged,
this.locale,
required this.locale,
this.entryMode = TimePickerEntryMode.dial,
}) : super(key: key);
final ValueChanged<TimeOfDay> onChanged;
final ValueChanged<TimeOfDay?>? onChanged;
final Locale locale;
final TimePickerEntryMode entryMode;
......@@ -32,7 +32,7 @@ class _TimePickerLauncher extends StatelessWidget {
return ElevatedButton(
child: const Text('X'),
onPressed: () async {
onChanged(await showTimePicker(
onChanged?.call(await showTimePicker(
context: context,
initialEntryMode: entryMode,
initialTime: const TimeOfDay(hour: 7, minute: 0),
......@@ -49,7 +49,7 @@ class _TimePickerLauncher extends StatelessWidget {
Future<Offset> startPicker(
WidgetTester tester,
ValueChanged<TimeOfDay> onChanged, {
ValueChanged<TimeOfDay?> onChanged, {
Locale locale = const Locale('en', 'US'),
}) async {
await tester.pumpWidget(_TimePickerLauncher(onChanged: onChanged, locale: locale,));
......@@ -89,7 +89,7 @@ void main() {
];
for (final Locale locale in locales) {
final Offset center = await startPicker(tester, (TimeOfDay time) { }, locale: locale);
final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale);
final Text stringFragmentText = tester.widget(stringFragmentTextFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
......@@ -133,8 +133,8 @@ void main() {
await finishPicker(tester);
}
tester.binding.window.physicalSizeTestValue = null;
tester.binding.window.devicePixelRatioTestValue = null;
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
});
testWidgets('can localize the header in all known formats - landscape', (WidgetTester tester) async {
......@@ -161,7 +161,7 @@ void main() {
];
for (final Locale locale in locales) {
final Offset center = await startPicker(tester, (TimeOfDay time) { }, locale: locale);
final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale);
final Text stringFragmentText = tester.widget(stringFragmentTextFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy;
......@@ -210,8 +210,8 @@ void main() {
await finishPicker(tester);
}
tester.binding.window.physicalSizeTestValue = null;
tester.binding.window.devicePixelRatioTestValue = null;
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
});
testWidgets('can localize input mode in all known formats', (WidgetTester tester) async {
......@@ -234,7 +234,7 @@ void main() {
];
for (final Locale locale in locales) {
await tester.pumpWidget(_TimePickerLauncher(onChanged: (TimeOfDay time) { }, locale: locale, entryMode: TimePickerEntryMode.input));
await tester.pumpWidget(_TimePickerLauncher(onChanged: (TimeOfDay? time) { }, locale: locale, entryMode: TimePickerEntryMode.input));
await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1));
......@@ -292,8 +292,8 @@ void main() {
// 12:00 AM position. Because there's only one ring, no matter where you
// tap the time will be the same.
for (int i = 1; i < 10; i++) {
TimeOfDay result;
final Offset center = await startPicker(tester, (TimeOfDay time) { result = time; }, locale: locale);
TimeOfDay? result;
final Offset center = await startPicker(tester, (TimeOfDay? time) { result = time; }, locale: locale);
final Size size = tester.getSize(find.byKey(const Key('time-picker-dial')));
final double dy = (size.height / 2.0 / 10) * i;
await tester.tapAt(Offset(center.dx, center.dy - dy));
......@@ -348,13 +348,13 @@ void main() {
final dynamic dialPainter = dialPaint.painter;
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
expect(
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text as TextSpan).text),
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels12To11,
);
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
expect(
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text as TextSpan).text),
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels12To11,
);
});
......@@ -366,13 +366,13 @@ void main() {
final dynamic dialPainter = dialPaint.painter;
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
expect(
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text as TextSpan).text),
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels00To22TwoDigit,
);
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
expect(
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text as TextSpan).text),
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels00To22TwoDigit,
);
});
......
......@@ -53,10 +53,10 @@ class FooMaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLoc
}
Widget buildFrame({
Locale locale,
Locale? locale,
Iterable<LocalizationsDelegate<dynamic>> delegates = GlobalMaterialLocalizations.delegates,
WidgetBuilder buildContent,
LocaleResolutionCallback localeResolutionCallback,
required WidgetBuilder buildContent,
LocaleResolutionCallback? localeResolutionCallback,
Iterable<Locale> supportedLocales = const <Locale>[
Locale('en', 'US'),
Locale('es', 'ES'),
......@@ -210,7 +210,7 @@ void main() {
await tester.pumpWidget(
buildFrame(
// Accept whatever locale we're given
localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) => locale,
localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) => locale,
delegates: <FooMaterialLocalizationsDelegate>[
const FooMaterialLocalizationsDelegate(supportedLanguage: 'allLanguages'),
],
......
......@@ -92,7 +92,7 @@ void main() {
expect(topRight, const Offset(477.0, 347.5));
expect(bottomLeft, const Offset(392.0, 364.5));
expect(bottomRight, const Offset(477.0, 364.5));
}, skip: !isLinux);
});
testWidgets('Text baseline with EN locale', (WidgetTester tester) async {
// This test in combination with 'Text baseline with CJK locale' verify the baselines
......@@ -164,7 +164,6 @@ void main() {
Offset bottomLeft = tester.getBottomLeft(find.text('hello, world'));
Offset bottomRight = tester.getBottomRight(find.text('hello, world'));
expect(topLeft, const Offset(392.0, 300.0));
expect(topRight, const Offset(584.0, 300.0));
expect(bottomLeft, const Offset(392.0, 316));
......@@ -179,5 +178,5 @@ void main() {
expect(topRight, const Offset(472.0, 348.0));
expect(bottomLeft, const Offset(392.0, 364.0));
expect(bottomRight, const Offset(472.0, 364.0));
}, skip: !isLinux);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment