Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
e3ee5c6b
Unverified
Commit
e3ee5c6b
authored
Jul 13, 2019
by
Jonah Williams
Committed by
GitHub
Jul 13, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add better handling of JSON-RPC exception (#36082)
parent
d919e694
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
197 additions
and
22 deletions
+197
-22
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+22
-7
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+35
-0
usage.dart
packages/flutter_tools/lib/src/usage.dart
+6
-1
resident_runner_test.dart
...lutter_tools/test/general.shard/resident_runner_test.dart
+113
-14
terminal_handler_test.dart
...utter_tools/test/general.shard/terminal_handler_test.dart
+21
-0
No files found.
packages/flutter_tools/lib/src/resident_runner.dart
View file @
e3ee5c6b
...
@@ -844,7 +844,7 @@ abstract class ResidentRunner {
...
@@ -844,7 +844,7 @@ abstract class ResidentRunner {
}
}
class
OperationResult
{
class
OperationResult
{
OperationResult
(
this
.
code
,
this
.
message
);
OperationResult
(
this
.
code
,
this
.
message
,
{
this
.
fatal
=
false
}
);
/// The result of the operation; a non-zero code indicates a failure.
/// The result of the operation; a non-zero code indicates a failure.
final
int
code
;
final
int
code
;
...
@@ -852,6 +852,9 @@ class OperationResult {
...
@@ -852,6 +852,9 @@ class OperationResult {
/// A user facing message about the results of the operation.
/// A user facing message about the results of the operation.
final
String
message
;
final
String
message
;
/// Whether this error should cause the runner to exit.
final
bool
fatal
;
bool
get
isOk
=>
code
==
0
;
bool
get
isOk
=>
code
==
0
;
static
final
OperationResult
ok
=
OperationResult
(
0
,
''
);
static
final
OperationResult
ok
=
OperationResult
(
0
,
''
);
...
@@ -906,8 +909,14 @@ class TerminalHandler {
...
@@ -906,8 +909,14 @@ class TerminalHandler {
void
registerSignalHandlers
()
{
void
registerSignalHandlers
()
{
assert
(
residentRunner
.
stayResident
);
assert
(
residentRunner
.
stayResident
);
io
.
ProcessSignal
.
SIGINT
.
watch
().
listen
(
_cleanUpAndExit
);
io
.
ProcessSignal
.
SIGINT
.
watch
().
listen
((
io
.
ProcessSignal
signal
)
{
io
.
ProcessSignal
.
SIGTERM
.
watch
().
listen
(
_cleanUpAndExit
);
_cleanUp
(
signal
);
io
.
exit
(
0
);
});
io
.
ProcessSignal
.
SIGTERM
.
watch
().
listen
((
io
.
ProcessSignal
signal
)
{
_cleanUp
(
signal
);
io
.
exit
(
0
);
});
if
(!
residentRunner
.
supportsServiceProtocol
||
!
residentRunner
.
supportsRestart
)
if
(!
residentRunner
.
supportsServiceProtocol
||
!
residentRunner
.
supportsRestart
)
return
;
return
;
io
.
ProcessSignal
.
SIGUSR1
.
watch
().
listen
(
_handleSignal
);
io
.
ProcessSignal
.
SIGUSR1
.
watch
().
listen
(
_handleSignal
);
...
@@ -990,6 +999,9 @@ class TerminalHandler {
...
@@ -990,6 +999,9 @@ class TerminalHandler {
return
false
;
return
false
;
}
}
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
false
);
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
false
);
if
(
result
.
fatal
)
{
throwToolExit
(
result
.
message
);
}
if
(!
result
.
isOk
)
{
if
(!
result
.
isOk
)
{
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
}
}
...
@@ -1000,6 +1012,9 @@ class TerminalHandler {
...
@@ -1000,6 +1012,9 @@ class TerminalHandler {
return
false
;
return
false
;
}
}
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
true
);
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
true
);
if
(
result
.
fatal
)
{
throwToolExit
(
result
.
message
);
}
if
(!
result
.
isOk
)
{
if
(!
result
.
isOk
)
{
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
}
}
...
@@ -1051,7 +1066,8 @@ class TerminalHandler {
...
@@ -1051,7 +1066,8 @@ class TerminalHandler {
await
_commonTerminalInputHandler
(
command
);
await
_commonTerminalInputHandler
(
command
);
}
catch
(
error
,
st
)
{
}
catch
(
error
,
st
)
{
printError
(
'
$error
\n
$st
'
);
printError
(
'
$error
\n
$st
'
);
await
_cleanUpAndExit
(
null
);
await
_cleanUp
(
null
);
rethrow
;
}
finally
{
}
finally
{
_processingUserRequest
=
false
;
_processingUserRequest
=
false
;
}
}
...
@@ -1073,11 +1089,10 @@ class TerminalHandler {
...
@@ -1073,11 +1089,10 @@ class TerminalHandler {
}
}
}
}
Future
<
void
>
_cleanUp
AndExit
(
io
.
ProcessSignal
signal
)
async
{
Future
<
void
>
_cleanUp
(
io
.
ProcessSignal
signal
)
async
{
terminal
.
singleCharMode
=
false
;
terminal
.
singleCharMode
=
false
;
await
subscription
.
cancel
();
await
subscription
?
.
cancel
();
await
residentRunner
.
cleanupAfterSignal
();
await
residentRunner
.
cleanupAfterSignal
();
io
.
exit
(
0
);
}
}
}
}
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
e3ee5c6b
...
@@ -516,6 +516,9 @@ class HotRunner extends ResidentRunner {
...
@@ -516,6 +516,9 @@ class HotRunner extends ResidentRunner {
final
OperationResult
result
=
await
_restartFromSources
(
reason:
reason
,
benchmarkMode:
benchmarkMode
,);
final
OperationResult
result
=
await
_restartFromSources
(
reason:
reason
,
benchmarkMode:
benchmarkMode
,);
if
(!
result
.
isOk
)
if
(!
result
.
isOk
)
return
result
;
return
result
;
}
on
rpc
.
RpcException
{
await
_measureJsonRpcException
(
flutterDevices
,
fullRestart
);
return
OperationResult
(
1
,
'hot restart failed to complete'
,
fatal:
true
);
}
finally
{
}
finally
{
status
.
cancel
();
status
.
cancel
();
}
}
...
@@ -545,6 +548,9 @@ class HotRunner extends ResidentRunner {
...
@@ -545,6 +548,9 @@ class HotRunner extends ResidentRunner {
showTime
=
false
;
showTime
=
false
;
},
},
);
);
}
on
rpc
.
RpcException
{
await
_measureJsonRpcException
(
flutterDevices
,
fullRestart
);
return
OperationResult
(
1
,
'hot reload failed to complete'
,
fatal:
true
);
}
finally
{
}
finally
{
status
.
cancel
();
status
.
cancel
();
}
}
...
@@ -946,3 +952,32 @@ class ProjectFileInvalidator {
...
@@ -946,3 +952,32 @@ class ProjectFileInvalidator {
return
invalidatedFiles
;
return
invalidatedFiles
;
}
}
}
}
// This is an error case we would like to know more about.
Future
<
void
>
_measureJsonRpcException
(
List
<
FlutterDevice
>
flutterDevices
,
bool
fullRestart
)
async
{
String
targetPlatform
;
String
deviceSdk
;
bool
emulator
;
if
(
flutterDevices
.
length
==
1
)
{
final
Device
device
=
flutterDevices
.
first
.
device
;
targetPlatform
=
getNameForTargetPlatform
(
await
device
.
targetPlatform
);
deviceSdk
=
await
device
.
sdkNameAndVersion
;
emulator
=
await
device
.
isLocalEmulator
;
}
else
if
(
flutterDevices
.
length
>
1
)
{
targetPlatform
=
'multiple'
;
deviceSdk
=
'multiple'
;
emulator
=
false
;
}
else
{
targetPlatform
=
'unknown'
;
deviceSdk
=
'unknown'
;
emulator
=
false
;
}
flutterUsage
.
sendEvent
(
'hot'
,
'exception'
,
parameters:
<
String
,
String
>{
reloadExceptionTargetPlatform:
targetPlatform
,
reloadExceptionSdkName:
deviceSdk
,
reloadExceptionEmulator:
emulator
.
toString
(),
reloadExceptionFullRestart:
fullRestart
.
toString
(),
},
);
}
packages/flutter_tools/lib/src/usage.dart
View file @
e3ee5c6b
...
@@ -49,7 +49,12 @@ const String kCommandBuildBundleTargetPlatform = 'cd24';
...
@@ -49,7 +49,12 @@ const String kCommandBuildBundleTargetPlatform = 'cd24';
const
String
kCommandBuildBundleIsModule
=
'cd25'
;
const
String
kCommandBuildBundleIsModule
=
'cd25'
;
const
String
kCommandResult
=
'cd26'
;
const
String
kCommandResult
=
'cd26'
;
// Next ID: cd27
const
String
reloadExceptionTargetPlatform
=
'cd27'
;
const
String
reloadExceptionSdkName
=
'cd28'
;
const
String
reloadExceptionEmulator
=
'cd29'
;
const
String
reloadExceptionFullRestart
=
'cd30'
;
// Next ID: cd31
Usage
get
flutterUsage
=>
Usage
.
instance
;
Usage
get
flutterUsage
=>
Usage
.
instance
;
...
...
packages/flutter_tools/test/general.shard/resident_runner_test.dart
View file @
e3ee5c6b
...
@@ -4,12 +4,15 @@
...
@@ -4,12 +4,15 @@
import
'dart:async'
;
import
'dart:async'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
import
'package:flutter_tools/src/run_hot.dart'
;
import
'package:flutter_tools/src/run_hot.dart'
;
import
'package:flutter_tools/src/usage.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
import
'package:json_rpc_2/json_rpc_2.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../src/common.dart'
;
import
'../src/common.dart'
;
...
@@ -19,30 +22,34 @@ void main() {
...
@@ -19,30 +22,34 @@ void main() {
group
(
'ResidentRunner'
,
()
{
group
(
'ResidentRunner'
,
()
{
final
Uri
testUri
=
Uri
.
parse
(
'foo://bar'
);
final
Uri
testUri
=
Uri
.
parse
(
'foo://bar'
);
Testbed
testbed
;
Testbed
testbed
;
Mock
Device
mock
Device
;
Mock
FlutterDevice
mockFlutter
Device
;
MockVMService
mockVMService
;
MockVMService
mockVMService
;
MockDevFS
mockDevFS
;
MockDevFS
mockDevFS
;
MockFlutterView
mockFlutterView
;
ResidentRunner
residentRunner
;
ResidentRunner
residentRunner
;
MockDevice
mockDevice
;
setUp
(()
{
setUp
(()
{
testbed
=
Testbed
(
setup:
()
{
testbed
=
Testbed
(
setup:
()
{
residentRunner
=
HotRunner
(
residentRunner
=
HotRunner
(
<
FlutterDevice
>[
<
FlutterDevice
>[
mockDevice
,
mock
Flutter
Device
,
],
],
stayResident:
false
,
stayResident:
false
,
debuggingOptions:
DebuggingOptions
.
enabled
(
BuildInfo
.
debug
),
debuggingOptions:
DebuggingOptions
.
enabled
(
BuildInfo
.
debug
),
);
);
});
});
mockFlutterDevice
=
MockFlutterDevice
();
mockDevice
=
MockDevice
();
mockDevice
=
MockDevice
();
mockVMService
=
MockVMService
();
mockVMService
=
MockVMService
();
mockDevFS
=
MockDevFS
();
mockDevFS
=
MockDevFS
();
mockFlutterView
=
MockFlutterView
();
// DevFS Mocks
// DevFS Mocks
when
(
mockDevFS
.
lastCompiled
).
thenReturn
(
DateTime
(
2000
));
when
(
mockDevFS
.
lastCompiled
).
thenReturn
(
DateTime
(
2000
));
when
(
mockDevFS
.
sources
).
thenReturn
(<
Uri
>[]);
when
(
mockDevFS
.
sources
).
thenReturn
(<
Uri
>[]);
when
(
mockDevFS
.
destroy
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockDevFS
.
destroy
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
// FlutterDevice Mocks.
// FlutterDevice Mocks.
when
(
mockDevice
.
updateDevFS
(
when
(
mock
Flutter
Device
.
updateDevFS
(
// Intentionally provide empty list to match above mock.
// Intentionally provide empty list to match above mock.
invalidatedFiles:
<
Uri
>[],
invalidatedFiles:
<
Uri
>[],
mainPath:
anyNamed
(
'mainPath'
),
mainPath:
anyNamed
(
'mainPath'
),
...
@@ -61,27 +68,29 @@ void main() {
...
@@ -61,27 +68,29 @@ void main() {
invalidatedSourcesCount:
0
,
invalidatedSourcesCount:
0
,
);
);
});
});
when
(
mockDevice
.
devFS
).
thenReturn
(
mockDevFS
);
when
(
mock
Flutter
Device
.
devFS
).
thenReturn
(
mockDevFS
);
when
(
mockDevice
.
views
).
thenReturn
(<
FlutterView
>[
when
(
mock
Flutter
Device
.
views
).
thenReturn
(<
FlutterView
>[
MockFlutterView
(),
mockFlutterView
]);
]);
when
(
mockDevice
.
stopEchoingDeviceLog
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockFlutterDevice
.
device
).
thenReturn
(
mockDevice
);
when
(
mockDevice
.
observatoryUris
).
thenReturn
(<
Uri
>[
when
(
mockFlutterView
.
uiIsolate
).
thenReturn
(
MockIsolate
());
when
(
mockFlutterDevice
.
stopEchoingDeviceLog
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockFlutterDevice
.
observatoryUris
).
thenReturn
(<
Uri
>[
testUri
,
testUri
,
]);
]);
when
(
mockDevice
.
connect
(
when
(
mock
Flutter
Device
.
connect
(
reloadSources:
anyNamed
(
'reloadSources'
),
reloadSources:
anyNamed
(
'reloadSources'
),
restart:
anyNamed
(
'restart'
),
restart:
anyNamed
(
'restart'
),
compileExpression:
anyNamed
(
'compileExpression'
)
compileExpression:
anyNamed
(
'compileExpression'
)
)).
thenAnswer
((
Invocation
invocation
)
async
{
});
)).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockDevice
.
setupDevFS
(
any
,
any
,
packagesFilePath:
anyNamed
(
'packagesFilePath'
)))
when
(
mock
Flutter
Device
.
setupDevFS
(
any
,
any
,
packagesFilePath:
anyNamed
(
'packagesFilePath'
)))
.
thenAnswer
((
Invocation
invocation
)
async
{
.
thenAnswer
((
Invocation
invocation
)
async
{
return
testUri
;
return
testUri
;
});
});
when
(
mockDevice
.
vmServices
).
thenReturn
(<
VMService
>[
when
(
mock
Flutter
Device
.
vmServices
).
thenReturn
(<
VMService
>[
mockVMService
,
mockVMService
,
]);
]);
when
(
mockDevice
.
refreshViews
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mock
Flutter
Device
.
refreshViews
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
// VMService mocks.
// VMService mocks.
when
(
mockVMService
.
wsAddress
).
thenReturn
(
testUri
);
when
(
mockVMService
.
wsAddress
).
thenReturn
(
testUri
);
when
(
mockVMService
.
done
).
thenAnswer
((
Invocation
invocation
)
{
when
(
mockVMService
.
done
).
thenAnswer
((
Invocation
invocation
)
{
...
@@ -101,16 +110,106 @@ void main() {
...
@@ -101,16 +110,106 @@ void main() {
expect
(
await
result
,
0
);
expect
(
await
result
,
0
);
verify
(
mockDevice
.
initLogReader
()).
called
(
1
);
verify
(
mock
Flutter
Device
.
initLogReader
()).
called
(
1
);
expect
(
onConnectionInfo
.
isCompleted
,
true
);
expect
(
onConnectionInfo
.
isCompleted
,
true
);
expect
((
await
connectionInfo
).
baseUri
,
'foo://bar'
);
expect
((
await
connectionInfo
).
baseUri
,
'foo://bar'
);
expect
(
onAppStart
.
isCompleted
,
true
);
expect
(
onAppStart
.
isCompleted
,
true
);
}));
}));
test
(
'Can handle an RPC exception from hot reload'
,
()
=>
testbed
.
run
(()
async
{
when
(
mockDevice
.
sdkNameAndVersion
).
thenAnswer
((
Invocation
invocation
)
async
{
return
'Example'
;
});
when
(
mockDevice
.
targetPlatform
).
thenAnswer
((
Invocation
invocation
)
async
{
return
TargetPlatform
.
android_arm
;
});
when
(
mockDevice
.
isLocalEmulator
).
thenAnswer
((
Invocation
invocation
)
async
{
return
false
;
});
final
Completer
<
DebugConnectionInfo
>
onConnectionInfo
=
Completer
<
DebugConnectionInfo
>.
sync
();
final
Completer
<
void
>
onAppStart
=
Completer
<
void
>.
sync
();
unawaited
(
residentRunner
.
attach
(
appStartedCompleter:
onAppStart
,
connectionInfoCompleter:
onConnectionInfo
,
));
await
onAppStart
.
future
;
when
(
mockFlutterDevice
.
updateDevFS
(
mainPath:
anyNamed
(
'mainPath'
),
target:
anyNamed
(
'target'
),
bundle:
anyNamed
(
'bundle'
),
firstBuildTime:
anyNamed
(
'firstBuildTime'
),
bundleFirstUpload:
anyNamed
(
'bundleFirstUpload'
),
bundleDirty:
anyNamed
(
'bundleDirty'
),
fullRestart:
anyNamed
(
'fullRestart'
),
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
invalidatedFiles:
anyNamed
(
'invalidatedFiles'
),
)).
thenThrow
(
RpcException
(
666
,
'something bad happened'
));
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
false
);
expect
(
result
.
fatal
,
true
);
expect
(
result
.
code
,
1
);
verify
(
flutterUsage
.
sendEvent
(
'hot'
,
'exception'
,
parameters:
<
String
,
String
>{
reloadExceptionTargetPlatform:
getNameForTargetPlatform
(
TargetPlatform
.
android_arm
),
reloadExceptionSdkName:
'Example'
,
reloadExceptionEmulator:
'false'
,
reloadExceptionFullRestart:
'false'
,
})).
called
(
1
);
},
overrides:
<
Type
,
Generator
>{
Usage:
()
=>
MockUsage
(),
}));
test
(
'Can handle an RPC exception from hot restart'
,
()
=>
testbed
.
run
(()
async
{
when
(
mockDevice
.
sdkNameAndVersion
).
thenAnswer
((
Invocation
invocation
)
async
{
return
'Example'
;
});
when
(
mockDevice
.
targetPlatform
).
thenAnswer
((
Invocation
invocation
)
async
{
return
TargetPlatform
.
android_arm
;
});
when
(
mockDevice
.
isLocalEmulator
).
thenAnswer
((
Invocation
invocation
)
async
{
return
false
;
});
when
(
mockDevice
.
supportsHotRestart
).
thenReturn
(
true
);
final
Completer
<
DebugConnectionInfo
>
onConnectionInfo
=
Completer
<
DebugConnectionInfo
>.
sync
();
final
Completer
<
void
>
onAppStart
=
Completer
<
void
>.
sync
();
unawaited
(
residentRunner
.
attach
(
appStartedCompleter:
onAppStart
,
connectionInfoCompleter:
onConnectionInfo
,
));
await
onAppStart
.
future
;
when
(
mockFlutterDevice
.
updateDevFS
(
mainPath:
anyNamed
(
'mainPath'
),
target:
anyNamed
(
'target'
),
bundle:
anyNamed
(
'bundle'
),
firstBuildTime:
anyNamed
(
'firstBuildTime'
),
bundleFirstUpload:
anyNamed
(
'bundleFirstUpload'
),
bundleDirty:
anyNamed
(
'bundleDirty'
),
fullRestart:
anyNamed
(
'fullRestart'
),
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
invalidatedFiles:
anyNamed
(
'invalidatedFiles'
),
)).
thenThrow
(
RpcException
(
666
,
'something bad happened'
));
final
OperationResult
result
=
await
residentRunner
.
restart
(
fullRestart:
true
);
expect
(
result
.
fatal
,
true
);
expect
(
result
.
code
,
1
);
verify
(
flutterUsage
.
sendEvent
(
'hot'
,
'exception'
,
parameters:
<
String
,
String
>{
reloadExceptionTargetPlatform:
getNameForTargetPlatform
(
TargetPlatform
.
android_arm
),
reloadExceptionSdkName:
'Example'
,
reloadExceptionEmulator:
'false'
,
reloadExceptionFullRestart:
'true'
,
})).
called
(
1
);
},
overrides:
<
Type
,
Generator
>{
Usage:
()
=>
MockUsage
(),
}));
});
});
}
}
class
MockDevice
extends
Mock
implements
FlutterDevice
{}
class
Mock
Flutter
Device
extends
Mock
implements
FlutterDevice
{}
class
MockFlutterView
extends
Mock
implements
FlutterView
{}
class
MockFlutterView
extends
Mock
implements
FlutterView
{}
class
MockVMService
extends
Mock
implements
VMService
{}
class
MockVMService
extends
Mock
implements
VMService
{}
class
MockDevFS
extends
Mock
implements
DevFS
{}
class
MockDevFS
extends
Mock
implements
DevFS
{}
class
MockIsolate
extends
Mock
implements
Isolate
{}
class
MockDevice
extends
Mock
implements
Device
{}
class
MockUsage
extends
Mock
implements
Usage
{}
packages/flutter_tools/test/general.shard/terminal_handler_test.dart
View file @
e3ee5c6b
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:async'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/device.dart'
;
...
@@ -246,6 +247,16 @@ void main() {
...
@@ -246,6 +247,16 @@ void main() {
expect
(
bufferLogger
.
statusText
,
contains
(
'Try again after fixing the above error(s).'
));
expect
(
bufferLogger
.
statusText
,
contains
(
'Try again after fixing the above error(s).'
));
});
});
testUsingContext
(
'r - hotReload supported and fails fatally'
,
()
async
{
when
(
mockResidentRunner
.
canHotReload
).
thenReturn
(
true
);
when
(
mockResidentRunner
.
hotMode
).
thenReturn
(
true
);
when
(
mockResidentRunner
.
restart
(
fullRestart:
false
))
.
thenAnswer
((
Invocation
invocation
)
async
{
return
OperationResult
(
1
,
'fail'
,
fatal:
true
);
});
expect
(
terminalHandler
.
processTerminalInput
(
'r'
),
throwsA
(
isInstanceOf
<
ToolExit
>()));
});
testUsingContext
(
'r - hotReload unsupported'
,
()
async
{
testUsingContext
(
'r - hotReload unsupported'
,
()
async
{
when
(
mockResidentRunner
.
canHotReload
).
thenReturn
(
false
);
when
(
mockResidentRunner
.
canHotReload
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'r'
);
await
terminalHandler
.
processTerminalInput
(
'r'
);
...
@@ -281,6 +292,16 @@ void main() {
...
@@ -281,6 +292,16 @@ void main() {
expect
(
bufferLogger
.
statusText
,
contains
(
'Try again after fixing the above error(s).'
));
expect
(
bufferLogger
.
statusText
,
contains
(
'Try again after fixing the above error(s).'
));
});
});
testUsingContext
(
'R - hotRestart supported and fails fatally'
,
()
async
{
when
(
mockResidentRunner
.
canHotRestart
).
thenReturn
(
true
);
when
(
mockResidentRunner
.
hotMode
).
thenReturn
(
true
);
when
(
mockResidentRunner
.
restart
(
fullRestart:
true
))
.
thenAnswer
((
Invocation
invocation
)
async
{
return
OperationResult
(
1
,
'fail'
,
fatal:
true
);
});
expect
(()
=>
terminalHandler
.
processTerminalInput
(
'R'
),
throwsA
(
isInstanceOf
<
ToolExit
>()));
});
testUsingContext
(
'R - hot restart unsupported'
,
()
async
{
testUsingContext
(
'R - hot restart unsupported'
,
()
async
{
when
(
mockResidentRunner
.
canHotRestart
).
thenReturn
(
false
);
when
(
mockResidentRunner
.
canHotRestart
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'R'
);
await
terminalHandler
.
processTerminalInput
(
'R'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment