Unverified Commit f8058d7f authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Make AppContext API not be prone to Future oddities (#16034)

Follow-up comments to #15984
parent bffae215
...@@ -196,7 +196,7 @@ Future<String> _doctorText() async { ...@@ -196,7 +196,7 @@ Future<String> _doctorText() async {
try { try {
final BufferLogger logger = new BufferLogger(); final BufferLogger logger = new BufferLogger();
await context.run<Future<bool>>( await context.run<bool>(
body: () => doctor.diagnose(verbose: true), body: () => doctor.diagnose(verbose: true),
overrides: <Type, Generator>{ overrides: <Type, Generator>{
Logger: () => logger, Logger: () => logger,
......
...@@ -126,20 +126,20 @@ class AppContext { ...@@ -126,20 +126,20 @@ class AppContext {
/// If [name] is specified, the child context will be assigned the given /// If [name] is specified, the child context will be assigned the given
/// name. This is useful for debugging purposes and is analogous to naming a /// name. This is useful for debugging purposes and is analogous to naming a
/// thread in Java. /// thread in Java.
V run<V>({ Future<V> run<V>({
@required V body(), @required FutureOr<V> body(),
String name, String name,
Map<Type, Generator> overrides, Map<Type, Generator> overrides,
Map<Type, Generator> fallbacks, Map<Type, Generator> fallbacks,
}) { }) async {
final AppContext child = new AppContext._( final AppContext child = new AppContext._(
this, this,
name, name,
new Map<Type, Generator>.unmodifiable(overrides ?? const <Type, Generator>{}), new Map<Type, Generator>.unmodifiable(overrides ?? const <Type, Generator>{}),
new Map<Type, Generator>.unmodifiable(fallbacks ?? const <Type, Generator>{}), new Map<Type, Generator>.unmodifiable(fallbacks ?? const <Type, Generator>{}),
); );
return runZoned<V>( return await runZoned<Future<V>>(
body, () async => await body(),
zoneValues: <_Key, AppContext>{_Key.key: child}, zoneValues: <_Key, AppContext>{_Key.key: child},
); );
} }
......
...@@ -54,7 +54,7 @@ class DaemonCommand extends FlutterCommand { ...@@ -54,7 +54,7 @@ class DaemonCommand extends FlutterCommand {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
return context.run<Future<Null>>( return context.run<Null>(
body: () async { body: () async {
final Daemon daemon = new Daemon( final Daemon daemon = new Daemon(
stdinCommandStream, stdoutCommandResponse, stdinCommandStream, stdoutCommandResponse,
......
...@@ -38,9 +38,9 @@ Future<T> runInContext<T>( ...@@ -38,9 +38,9 @@ Future<T> runInContext<T>(
FutureOr<T> runner(), { FutureOr<T> runner(), {
Map<Type, dynamic> overrides, Map<Type, dynamic> overrides,
}) async { }) async {
return await context.run<Future<T>>( return await context.run<T>(
name: 'global fallbacks', name: 'global fallbacks',
body: () async => await runner(), body: runner,
overrides: overrides, overrides: overrides,
fallbacks: <Type, Generator>{ fallbacks: <Type, Generator>{
AndroidSdk: AndroidSdk.locateAndroidSdk, AndroidSdk: AndroidSdk.locateAndroidSdk,
......
...@@ -225,7 +225,7 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -225,7 +225,7 @@ abstract class FlutterCommand extends Command<Null> {
Future<Null> run() { Future<Null> run() {
final DateTime startTime = clock.now(); final DateTime startTime = clock.now();
return context.run<Future<Null>>( return context.run<Null>(
name: 'command', name: 'command',
overrides: <Type, Generator>{FlutterCommand: () => this}, overrides: <Type, Generator>{FlutterCommand: () => this},
body: () async { body: () async {
......
...@@ -246,7 +246,7 @@ class FlutterCommandRunner extends CommandRunner<Null> { ...@@ -246,7 +246,7 @@ class FlutterCommandRunner extends CommandRunner<Null> {
}); });
} }
await context.run<Future<Null>>( await context.run<Null>(
overrides: contextOverrides.map<Type, Generator>((Type type, dynamic value) { overrides: contextOverrides.map<Type, Generator>((Type type, dynamic value) {
return new MapEntry<Type, Generator>(type, () => value); return new MapEntry<Type, Generator>(type, () => value);
}), }),
......
...@@ -433,7 +433,7 @@ void main() { ...@@ -433,7 +433,7 @@ void main() {
depfileContent: 'output.snapshot : main.dart other.dart', depfileContent: 'output.snapshot : main.dart other.dart',
); );
await context.run( await context.run<void>(
overrides: <Type, Generator>{GenSnapshot: () => genSnapshot}, overrides: <Type, Generator>{GenSnapshot: () => genSnapshot},
body: () async { body: () async {
await fs.file('main.dart').writeAsString('import "other.dart";\nvoid main() {}'); await fs.file('main.dart').writeAsString('import "other.dart";\nvoid main() {}');
......
...@@ -32,9 +32,9 @@ void main() { ...@@ -32,9 +32,9 @@ void main() {
expect(called, isTrue); expect(called, isTrue);
}); });
test('returns child context after run', () { test('returns child context after run', () async {
final AppContext rootContext = context; final AppContext rootContext = context;
rootContext.run(name: 'child', body: () { await rootContext.run<void>(name: 'child', body: () {
expect(context, isNot(rootContext)); expect(context, isNot(rootContext));
expect(context.name, 'child'); expect(context.name, 'child');
called = true; called = true;
...@@ -42,11 +42,11 @@ void main() { ...@@ -42,11 +42,11 @@ void main() {
expect(called, isTrue); expect(called, isTrue);
}); });
test('returns grandchild context after nested run', () { test('returns grandchild context after nested run', () async {
final AppContext rootContext = context; final AppContext rootContext = context;
rootContext.run(name: 'child', body: () { await rootContext.run<void>(name: 'child', body: () async {
final AppContext childContext = context; final AppContext childContext = context;
childContext.run(name: 'grandchild', body: () { await childContext.run<void>(name: 'grandchild', body: () {
expect(context, isNot(rootContext)); expect(context, isNot(rootContext));
expect(context, isNot(childContext)); expect(context, isNot(childContext));
expect(context.name, 'grandchild'); expect(context.name, 'grandchild');
...@@ -56,9 +56,9 @@ void main() { ...@@ -56,9 +56,9 @@ void main() {
expect(called, isTrue); expect(called, isTrue);
}); });
test('scans up zone hierarchy for first context', () { test('scans up zone hierarchy for first context', () async {
final AppContext rootContext = context; final AppContext rootContext = context;
rootContext.run(name: 'child', body: () { await rootContext.run<void>(name: 'child', body: () {
final AppContext childContext = context; final AppContext childContext = context;
runZoned(() { runZoned(() {
expect(context, isNot(rootContext)); expect(context, isNot(rootContext));
...@@ -76,7 +76,7 @@ void main() { ...@@ -76,7 +76,7 @@ void main() {
final Completer<void> outer = new Completer<void>(); final Completer<void> outer = new Completer<void>();
final Completer<void> inner = new Completer<void>(); final Completer<void> inner = new Completer<void>();
String value; String value;
context.run<void>( await context.run<void>(
body: () { body: () {
outer.future.then((_) { outer.future.then((_) {
value = context[String]; value = context[String];
...@@ -93,14 +93,14 @@ void main() { ...@@ -93,14 +93,14 @@ void main() {
expect(value, 'value'); expect(value, 'value');
}); });
test('caches generated override values', () { test('caches generated override values', () async {
int consultationCount = 0; int consultationCount = 0;
String value; String value;
context.run( await context.run<void>(
body: () { body: () async {
final StringBuffer buf = new StringBuffer(context[String]); final StringBuffer buf = new StringBuffer(context[String]);
buf.write(context[String]); buf.write(context[String]);
context.run(body: () { await context.run<void>(body: () {
buf.write(context[String]); buf.write(context[String]);
}); });
value = buf.toString(); value = buf.toString();
...@@ -116,14 +116,14 @@ void main() { ...@@ -116,14 +116,14 @@ void main() {
expect(consultationCount, 1); expect(consultationCount, 1);
}); });
test('caches generated fallback values', () { test('caches generated fallback values', () async {
int consultationCount = 0; int consultationCount = 0;
String value; String value;
context.run( await context.run(
body: () { body: () async {
final StringBuffer buf = new StringBuffer(context[String]); final StringBuffer buf = new StringBuffer(context[String]);
buf.write(context[String]); buf.write(context[String]);
context.run(body: () { await context.run<void>(body: () {
buf.write(context[String]); buf.write(context[String]);
}); });
value = buf.toString(); value = buf.toString();
...@@ -139,8 +139,8 @@ void main() { ...@@ -139,8 +139,8 @@ void main() {
expect(consultationCount, 1); expect(consultationCount, 1);
}); });
test('returns null if generated value is null', () { test('returns null if generated value is null', () async {
final String value = context.run( final String value = await context.run<String>(
body: () => context[String], body: () => context[String],
overrides: <Type, Generator>{ overrides: <Type, Generator>{
String: () => null, String: () => null,
...@@ -150,7 +150,7 @@ void main() { ...@@ -150,7 +150,7 @@ void main() {
}); });
test('throws if generator has dependency cycle', () async { test('throws if generator has dependency cycle', () async {
final Future<String> value = context.run<Future<String>>( final Future<String> value = context.run<String>(
body: () async { body: () async {
return context[String]; return context[String];
}, },
...@@ -172,13 +172,13 @@ void main() { ...@@ -172,13 +172,13 @@ void main() {
group('run', () { group('run', () {
test('returns the value returned by body', () async { test('returns the value returned by body', () async {
expect(context.run<int>(body: () => 123), 123); expect(await context.run<int>(body: () => 123), 123);
expect(context.run<String>(body: () => 'value'), 'value'); expect(await context.run<String>(body: () => 'value'), 'value');
expect(await context.run<Future<int>>(body: () async => 456), 456); expect(await context.run<Future<int>>(body: () async => 456), 456);
}); });
test('passes name to child context', () { test('passes name to child context', () async {
context.run(name: 'child', body: () { await context.run<void>(name: 'child', body: () {
expect(context.name, 'child'); expect(context.name, 'child');
}); });
}); });
...@@ -190,8 +190,8 @@ void main() { ...@@ -190,8 +190,8 @@ void main() {
called = false; called = false;
}); });
test('are applied after parent context is consulted', () { test('are applied after parent context is consulted', () async {
final String value = context.run<String>( final String value = await context.run<String>(
body: () { body: () {
return context.run<String>( return context.run<String>(
body: () { body: () {
...@@ -208,9 +208,9 @@ void main() { ...@@ -208,9 +208,9 @@ void main() {
expect(value, 'child'); expect(value, 'child');
}); });
test('are not applied if parent context supplies value', () { test('are not applied if parent context supplies value', () async {
bool childConsulted = false; bool childConsulted = false;
final String value = context.run<String>( final String value = await context.run<String>(
body: () { body: () {
return context.run<String>( return context.run<String>(
body: () { body: () {
...@@ -234,8 +234,8 @@ void main() { ...@@ -234,8 +234,8 @@ void main() {
expect(childConsulted, isFalse); expect(childConsulted, isFalse);
}); });
test('may depend on one another', () { test('may depend on one another', () async {
final String value = context.run<String>( final String value = await context.run<String>(
body: () { body: () {
return context[String]; return context[String];
}, },
...@@ -249,9 +249,9 @@ void main() { ...@@ -249,9 +249,9 @@ void main() {
}); });
group('overrides', () { group('overrides', () {
test('intercept consultation of parent context', () { test('intercept consultation of parent context', () async {
bool parentConsulted = false; bool parentConsulted = false;
final String value = context.run<String>( final String value = await context.run<String>(
body: () { body: () {
return context.run<String>( return context.run<String>(
body: () => context[String], body: () => context[String],
......
...@@ -59,7 +59,7 @@ void testUsingContext(String description, dynamic testMethod(), { ...@@ -59,7 +59,7 @@ void testUsingContext(String description, dynamic testMethod(), {
test(description, () async { test(description, () async {
await runInContext<dynamic>(() { await runInContext<dynamic>(() {
return context.run<Future<dynamic>>( return context.run<dynamic>(
name: 'mocks', name: 'mocks',
overrides: <Type, Generator>{ overrides: <Type, Generator>{
Config: () => buildConfig(fs), Config: () => buildConfig(fs),
...@@ -84,7 +84,7 @@ void testUsingContext(String description, dynamic testMethod(), { ...@@ -84,7 +84,7 @@ void testUsingContext(String description, dynamic testMethod(), {
return runZoned(() { return runZoned(() {
try { try {
return context.run<Future<dynamic>>( return context.run<dynamic>(
// Apply the overrides to the test context in the zone since their // Apply the overrides to the test context in the zone since their
// instantiation may reference items already stored on the context. // instantiation may reference items already stored on the context.
overrides: overrides, overrides: overrides,
......
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