Commit 6ca2e5dc authored by Yegor's avatar Yegor Committed by GitHub

fix _debugCheckOwnerBuildTargetExists; sync localizations and tests (#12245)

* Revert "When parts of the program are changed in a hot reload, but not executed during the reassemble, warn that a restart may be needed. (#12304)"

This reverts commit 90028813.

* fix _debugCheckOwnerBuildTargetExists; sync localizations and tests

* address comments
parent 2b78675b
......@@ -3272,29 +3272,28 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
@mustCallSuper
void didChangeDependencies() {
assert(_active); // otherwise markNeedsBuild is a no-op
_debugCheckOwnerBuildTargetExists('didChangeDependencies');
assert(_debugCheckOwnerBuildTargetExists('didChangeDependencies'));
markNeedsBuild();
}
void _debugCheckOwnerBuildTargetExists(String methodName) {
bool _debugCheckOwnerBuildTargetExists(String methodName) {
assert(() {
if (owner._debugCurrentBuildTarget == null) {
throw new FlutterError(
'$methodName for ${widget.runtimeType} was called at an '
'inappropriate time.\n'
'\n'
'It may only be called while the widgets are being built. A possible '
'cause of this error is when $methodName is called during '
'one of:\n'
'\n'
' * network I/O event\n'
' * file I/O event\n'
' * timer\n'
' * microtask (caused by Future.then, async/await, scheduleMicrotask)'
'$methodName for ${widget.runtimeType} was called at an '
'inappropriate time.\n'
'It may only be called while the widgets are being built. A possible '
'cause of this error is when $methodName is called during '
'one of:\n'
' * network I/O event\n'
' * file I/O event\n'
' * timer\n'
' * microtask (caused by Future.then, async/await, scheduleMicrotask)'
);
}
return true;
});
}());
return true;
}
/// Returns a description of what caused this element to be created.
......@@ -3942,7 +3941,7 @@ class InheritedElement extends ProxyElement {
/// by first obtaining their [InheritedElement] using
/// [BuildContext.ancestorInheritedElementForWidgetOfExactType].
void dispatchDidChangeDependencies() {
_debugCheckOwnerBuildTargetExists('dispatchDidChangeDependencies');
assert(_debugCheckOwnerBuildTargetExists('dispatchDidChangeDependencies'));
for (Element dependent in _dependents) {
assert(() {
// check that it really is our descendant
......
......@@ -206,23 +206,20 @@ class _LocalizationsScope extends InheritedWidget {
Key key,
@required this.locale,
@required this.localizationsState,
@required this.loadGeneration,
@required this.typeToResources,
Widget child,
}) : super(key: key, child: child) {
assert(localizationsState != null);
assert(typeToResources != null);
}
final Locale locale;
final _LocalizationsState localizationsState;
/// A monotonically increasing number that changes after localizations
/// delegates have finished loading new data. When this number changes, it
/// triggers inherited widget notifications.
final int loadGeneration;
final Map<Type, dynamic> typeToResources;
@override
bool updateShouldNotify(_LocalizationsScope old) {
return loadGeneration != old.loadGeneration;
return typeToResources != old.typeToResources;
}
}
......@@ -445,11 +442,6 @@ class _LocalizationsState extends State<Localizations> {
final GlobalKey _localizedResourcesScopeKey = new GlobalKey();
Map<Type, dynamic> _typeToResources = <Type, dynamic>{};
/// A monotonically increasing number that increases after localizations
/// delegates have finished loading new data, triggering inherited widget
/// notifications.
int _loadGeneration = 0;
Locale get locale => _locale;
Locale _locale;
......@@ -513,7 +505,6 @@ class _LocalizationsState extends State<Localizations> {
setState(() {
_typeToResources = value;
_locale = locale;
_loadGeneration += 1;
});
});
}
......@@ -539,7 +530,7 @@ class _LocalizationsState extends State<Localizations> {
key: _localizedResourcesScopeKey,
locale: _locale,
localizationsState: this,
loadGeneration: _loadGeneration,
typeToResources: _typeToResources,
child: new Directionality(
textDirection: _textDirection,
child: widget.child,
......
......@@ -159,6 +159,23 @@ Widget buildFrame({
);
}
class SyncLoadTest extends StatefulWidget {
const SyncLoadTest();
@override
SyncLoadTestState createState() => new SyncLoadTestState();
}
class SyncLoadTestState extends State<SyncLoadTest> {
@override
Widget build(BuildContext context) {
return new Text(
TestLocalizations.of(context).message,
textDirection: TextDirection.rtl,
);
}
}
void main() {
testWidgets('Localizations.localeFor in a WidgetsApp with system locale', (WidgetTester tester) async {
BuildContext pageContext;
......@@ -205,27 +222,27 @@ void main() {
});
testWidgets('Synchronously loaded localizations in a WidgetsApp', (WidgetTester tester) async {
BuildContext pageContext;
await tester.pumpWidget(
buildFrame(
delegates: <LocalizationsDelegate<dynamic>>[
new SyncTestLocalizationsDelegate()
],
buildContent: (BuildContext context) {
pageContext = context;
return new Text(TestLocalizations.of(context).message);
}
)
);
final List<LocalizationsDelegate<dynamic>> delegates = <LocalizationsDelegate<dynamic>>[
new SyncTestLocalizationsDelegate(),
const DefaultWidgetsLocalizationsDelegate(),
];
Future<Null> pumpTest(Locale locale) async {
await tester.pumpWidget(new Localizations(
locale: locale,
delegates: delegates,
child: const SyncLoadTest(),
));
}
expect(TestLocalizations.of(pageContext), isNotNull);
await pumpTest(const Locale('en', 'US'));
expect(find.text('en_US'), findsOneWidget);
await tester.binding.setLocale('en', 'GB');
await pumpTest(const Locale('en', 'GB'));
await tester.pump();
expect(find.text('en_GB'), findsOneWidget);
await tester.binding.setLocale('en', 'US');
await pumpTest(const Locale('en', 'US'));
await tester.pump();
expect(find.text('en_US'), findsOneWidget);
});
......
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