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
33b183e6
Unverified
Commit
33b183e6
authored
May 03, 2021
by
Ian Hickson
Committed by
GitHub
May 03, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix extra blank lines in logger output (#81607)
parent
96e4b47f
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
317 additions
and
216 deletions
+317
-216
gradle.dart
packages/flutter_tools/lib/src/android/gradle.dart
+0
-2
common.dart
packages/flutter_tools/lib/src/base/common.dart
+1
-1
logger.dart
packages/flutter_tools/lib/src/base/logger.dart
+143
-129
terminal.dart
packages/flutter_tools/lib/src/base/terminal.dart
+20
-1
globals_null_migrated.dart
packages/flutter_tools/lib/src/globals_null_migrated.dart
+1
-0
logger_test.dart
...es/flutter_tools/test/general.shard/base/logger_test.dart
+78
-52
terminal_test.dart
.../flutter_tools/test/general.shard/base/terminal_test.dart
+47
-2
code_signing_test.dart
...utter_tools/test/general.shard/ios/code_signing_test.dart
+3
-0
overall_experience_test.dart
...tools/test/integration.shard/overall_experience_test.dart
+23
-28
testbed.dart
packages/flutter_tools/test/src/testbed.dart
+1
-1
No files found.
packages/flutter_tools/lib/src/android/gradle.dart
View file @
33b183e6
...
...
@@ -323,7 +323,6 @@ class AndroidGradleBuilder implements AndroidBuilder {
final
Status
status
=
_logger
.
startProgress
(
"Running Gradle task '
$assembleTask
'..."
,
multilineOutput:
true
,
);
final
List
<
String
>
command
=
<
String
>[
...
...
@@ -636,7 +635,6 @@ class AndroidGradleBuilder implements AndroidBuilder {
final
String
aarTask
=
getAarTaskFor
(
buildInfo
);
final
Status
status
=
_logger
.
startProgress
(
"Running Gradle task '
$aarTask
'..."
,
multilineOutput:
true
,
);
final
String
flutterRoot
=
_fileSystem
.
path
.
absolute
(
Cache
.
flutterRoot
);
...
...
packages/flutter_tools/lib/src/base/common.dart
View file @
33b183e6
...
...
@@ -21,7 +21,7 @@ class ToolExit implements Exception {
final
int
?
exitCode
;
@override
String
toString
()
=>
'Exception:
$message
'
;
String
toString
()
=>
'Exception:
$message
'
;
// TODO(ianh): Really this should say "Error".
}
/// Indicates to the linter that the given future is intentionally not awaited.
...
...
packages/flutter_tools/lib/src/base/logger.dart
View file @
33b183e6
...
...
@@ -120,16 +120,16 @@ abstract class Logger {
/// The `progressId` argument provides an ID that can be used to identify
/// this type of progress (e.g. `hot.reload`, `hot.restart`).
///
/// The `progressIndicatorPadding` can optionally be used to specify spacing
/// between the `message` and the progress indicator, if any.
/// The `progressIndicatorPadding` can optionally be used to specify the width
/// of the space into which the `message` is placed before the progress
/// indicator, if any. It is ignored if the message is longer.
Status
startProgress
(
String
message
,
{
String
?
progressId
,
bool
multilineOutput
=
false
,
int
progressIndicatorPadding
=
kDefaultStatusPadding
,
});
/// A [SilentStatus] or an [An
siSpinner
] (depending on whether the
/// A [SilentStatus] or an [An
onymousSpinnerStatus
] (depending on whether the
/// terminal is fancy enough), already started.
Status
startSpinner
({
VoidCallback
?
onFinish
});
...
...
@@ -223,12 +223,10 @@ class DelegatingLogger implements Logger {
@override
Status
startProgress
(
String
message
,
{
String
?
progressId
,
bool
multilineOutput
=
false
,
int
progressIndicatorPadding
=
kDefaultStatusPadding
,
})
{
return
_delegate
.
startProgress
(
message
,
progressId:
progressId
,
multilineOutput:
multilineOutput
,
progressIndicatorPadding:
progressIndicatorPadding
,
);
}
...
...
@@ -363,20 +361,17 @@ class StdoutLogger extends Logger {
Status
startProgress
(
String
message
,
{
String
?
progressId
,
bool
multilineOutput
=
false
,
int
progressIndicatorPadding
=
kDefaultStatusPadding
,
})
{
if
(
_status
!=
null
)
{
// Ignore nested progresses; return a no-op status object.
return
SilentStatus
(
onFinish:
_clearStatus
,
stopwatch:
_stopwatchFactory
.
createStopwatch
(),
)..
start
();
}
if
(
supportsColor
)
{
_status
=
Ansi
Status
(
_status
=
Spinner
Status
(
message:
message
,
multilineOutput:
multilineOutput
,
padding:
progressIndicatorPadding
,
onFinish:
_clearStatus
,
stdio:
_stdio
,
...
...
@@ -397,18 +392,24 @@ class StdoutLogger extends Logger {
@override
Status
startSpinner
({
VoidCallback
?
onFinish
})
{
if
(
terminal
.
supportsColor
)
{
return
AnsiSpinner
(
if
(
_status
!=
null
||
!
supportsColor
)
{
return
SilentStatus
(
onFinish:
onFinish
,
stopwatch:
_stopwatchFactory
.
createStopwatch
(),
terminal:
terminal
,
stdio:
_stdio
,
)..
start
();
}
return
SilentStatus
(
onFinish:
onFinish
,
_status
=
AnonymousSpinnerStatus
(
onFinish:
()
{
if
(
onFinish
!=
null
)
{
onFinish
();
}
_clearStatus
();
},
stdio:
_stdio
,
stopwatch:
_stopwatchFactory
.
createStopwatch
(),
terminal:
terminal
,
)..
start
();
return
_status
!;
}
void
_clearStatus
()
{
...
...
@@ -561,7 +562,6 @@ class BufferLogger extends Logger {
Status
startProgress
(
String
message
,
{
String
?
progressId
,
bool
multilineOutput
=
false
,
int
progressIndicatorPadding
=
kDefaultStatusPadding
,
})
{
assert
(
progressIndicatorPadding
!=
null
);
...
...
@@ -661,7 +661,6 @@ class VerboseLogger extends DelegatingLogger {
Status
startProgress
(
String
message
,
{
String
?
progressId
,
bool
multilineOutput
=
false
,
int
progressIndicatorPadding
=
kDefaultStatusPadding
,
})
{
assert
(
progressIndicatorPadding
!=
null
);
...
...
@@ -758,12 +757,11 @@ typedef SlowWarningCallback = String Function();
///
/// The [SilentStatus] class never has any output.
///
/// The [AnsiSpinner] subclass shows a spinner, and replaces it with a single
/// space character when stopped or canceled.
/// The [SpinnerStatus] subclass shows a message with a spinner, and replaces it
/// with timing information when stopped. When canceled, the information isn't
/// shown. In either case, a newline is printed.
///
/// The [AnsiStatus] subclass shows a spinner, and replaces it with timing
/// information when stopped. When canceled, the information isn't shown. In
/// either case, a newline is printed.
/// The [AnonymousSpinnerStatus] subclass just shows a spinner.
///
/// The [SummaryStatus] subclass shows only a static message (without an
/// indicator), then updates it when the operation ends.
...
...
@@ -835,6 +833,8 @@ class SilentStatus extends Status {
}
}
const
int
_kTimePadding
=
8
;
// should fit "99,999ms"
/// Constructor writes [message] to [stdout]. On [cancel] or [stop], will call
/// [onFinish]. On [stop], will additionally print out summary information.
class
SummaryStatus
extends
Status
{
...
...
@@ -876,7 +876,8 @@ class SummaryStatus extends Status {
_printMessage
();
}
super
.
stop
();
writeSummaryInformation
();
assert
(
_messageShowingOnCurrentLine
);
_writeToStdOut
(
elapsedTime
.
padLeft
(
_kTimePadding
));
_writeToStdOut
(
'
\n
'
);
}
...
...
@@ -888,57 +889,91 @@ class SummaryStatus extends Status {
}
}
/// Prints a (minimum) 8 character padded time.
void
writeSummaryInformation
()
{
assert
(
_messageShowingOnCurrentLine
);
_writeToStdOut
(
elapsedTime
.
padLeft
(
_kTimePadding
));
}
@override
void
pause
()
{
super
.
pause
();
_writeToStdOut
(
'
\n
'
);
_messageShowingOnCurrentLine
=
false
;
if
(
_messageShowingOnCurrentLine
)
{
_writeToStdOut
(
'
\n
'
);
_messageShowingOnCurrentLine
=
false
;
}
}
}
/// An [AnsiSpinner] is a simple animation that does nothing but implement a
/// terminal spinner. When stopped or canceled, the animation erases itself.
class
AnsiSpinner
extends
Status
{
AnsiSpinner
({
required
Stopwatch
stopwatch
,
required
Terminal
terminal
,
/// A kind of animated [Status] that has no message.
///
/// Call [pause] before outputting any text while this is running.
class
AnonymousSpinnerStatus
extends
Status
{
AnonymousSpinnerStatus
({
VoidCallback
?
onFinish
,
required
Stopwatch
stopwatch
,
required
Stdio
stdio
,
required
Terminal
terminal
,
})
:
_stdio
=
stdio
,
_terminal
=
terminal
,
_animation
=
_selectAnimation
(
terminal
),
super
(
onFinish:
onFinish
,
stopwatch:
stopwatch
,
);
final
String
_backspaceChar
=
'
\
b'
;
final
String
_clearChar
=
' '
;
final
Stdio
_stdio
;
final
Terminal
_terminal
;
bool
timedOut
=
false
;
static
const
String
_backspaceChar
=
'
\
b'
;
static
const
String
_clearChar
=
' '
;
static
const
List
<
String
>
_emojiAnimations
=
<
String
>[
'⣾⣽⣻⢿⡿⣟⣯⣷'
,
// counter-clockwise
'⣾⣷⣯⣟⡿⢿⣻⣽'
,
// clockwise
'⣾⣷⣯⣟⡿⢿⣻⣽⣷⣾⣽⣻⢿⡿⣟⣯⣷'
,
// bouncing clockwise and counter-clockwise
'⣾⣷⣯⣽⣻⣟⡿⢿⣻⣟⣯⣽'
,
// snaking
'⣾⣽⣻⢿⣿⣷⣯⣟⡿⣿'
,
// alternating rain
'⣀⣠⣤⣦⣶⣾⣿⡿⠿⠻⠛⠋⠉⠙⠛⠟⠿⢿⣿⣷⣶⣴⣤⣄'
,
// crawl up and down, large
'⠙⠚⠖⠦⢤⣠⣄⡤⠴⠲⠓⠋'
,
// crawl up and down, small
'⣀⡠⠤⠔⠒⠊⠉⠑⠒⠢⠤⢄'
,
// crawl up and down, tiny
'⡀⣄⣦⢷⠻⠙⠈⠀⠁⠋⠟⡾⣴⣠⢀⠀'
,
// slide up and down
'⠙⠸⢰⣠⣄⡆⠇⠋'
,
// clockwise line
'⠁⠈⠐⠠⢀⡀⠄⠂'
,
// clockwise dot
'⢇⢣⢱⡸⡜⡎'
,
// vertical wobble up
'⡇⡎⡜⡸⢸⢱⢣⢇'
,
// vertical wobble down
'⡀⣀⣐⣒⣖⣶⣾⣿⢿⠿⠯⠭⠩⠉⠁⠀'
,
// swirl
'⠁⠐⠄⢀⢈⢂⢠⣀⣁⣐⣄⣌⣆⣤⣥⣴⣼⣶⣷⣿⣾⣶⣦⣤⣠⣀⡀⠀⠀'
,
// snowing and melting
'⠁⠋⠞⡴⣠⢀⠀⠈⠙⠻⢷⣦⣄⡀⠀⠉⠛⠲⢤⢀⠀'
,
// falling water
'⠄⡢⢑⠈⠀⢀⣠⣤⡶⠞⠋⠁⠀⠈⠙⠳⣆⡀⠀⠆⡷⣹⢈⠀⠐⠪⢅⡀⠀'
,
// fireworks
'⠐⢐⢒⣒⣲⣶⣷⣿⡿⡷⡧⠧⠇⠃⠁⠀⡀⡠⡡⡱⣱⣳⣷⣿⢿⢯⢧⠧⠣⠃⠂⠀⠈⠨⠸⠺⡺⡾⡿⣿⡿⡷⡗⡇⡅⡄⠄⠀⡀⡐⣐⣒⣓⣳⣻⣿⣾⣼⡼⡸⡘⡈⠈⠀'
,
// fade
'⢸⡯⠭⠅⢸⣇⣀⡀⢸⣇⣸⡇⠈⢹⡏⠁⠈⢹⡏⠁⢸⣯⣭⡅⢸⡯⢕⡂⠀⠀'
,
// text crawl
];
static
const
List
<
String
>
_asciiAnimations
=
<
String
>[
r'-\|/'
,
];
static
List
<
String
>
_selectAnimation
(
Terminal
terminal
)
{
final
List
<
String
>
animations
=
terminal
.
supportsEmoji
?
_emojiAnimations
:
_asciiAnimations
;
return
animations
[
terminal
.
preferredStyle
%
animations
.
length
]
.
runes
.
map
<
String
>((
int
scalar
)
=>
String
.
fromCharCode
(
scalar
))
.
toList
();
}
int
ticks
=
0
;
Timer
?
timer
;
final
List
<
String
>
_animation
;
// Windows console font has a limited set of Unicode characters.
List
<
String
>
get
_animation
=>
!
_terminal
.
supportsEmoji
?
const
<
String
>[
r'-'
,
r'\'
,
r'|'
,
r'/'
]
:
const
<
String
>[
'⣾'
,
'⣽'
,
'⣻'
,
'⢿'
,
'⡿'
,
'⣟'
,
'⣯'
,
'⣷'
];
Timer
?
timer
;
int
ticks
=
0
;
int
_lastAnimationFrameLength
=
0
;
String
get
_currentAnimationFrame
=>
_animation
[
ticks
%
_animation
.
length
];
int
get
_currentLength
=>
_currentAnimationFrame
.
length
;
String
get
_backspace
=>
_backspaceChar
*
(
spinnerIndent
+
_currentLength
);
String
get
_clear
=>
_clearChar
*
(
spinnerIndent
+
_currentLength
);
int
get
_currentLineLength
=>
_lastAnimationFrameLength
;
@protected
int
get
spinnerIndent
=>
0
;
void
_writeToStdOut
(
String
message
)
=>
_stdio
.
stdoutWrite
(
message
);
void
_clear
(
int
length
)
{
_writeToStdOut
(
'
${_backspaceChar * length}
'
'
${_clearChar * length}
'
'
${_backspaceChar * length}
'
);
}
@override
void
start
()
{
...
...
@@ -947,10 +982,7 @@ class AnsiSpinner extends Status {
_startSpinner
();
}
void
_writeToStdOut
(
String
message
)
=>
_stdio
.
stdoutWrite
(
message
);
void
_startSpinner
()
{
_writeToStdOut
(
_clear
);
// for _callback to backspace over
timer
=
Timer
.
periodic
(
const
Duration
(
milliseconds:
100
),
_callback
);
_callback
(
timer
!);
}
...
...
@@ -959,30 +991,23 @@ class AnsiSpinner extends Status {
assert
(
this
.
timer
==
timer
);
assert
(
timer
!=
null
);
assert
(
timer
.
isActive
);
_writeToStdOut
(
_backspace
);
_writeToStdOut
(
_backspace
Char
*
_lastAnimationFrameLength
);
ticks
+=
1
;
_writeToStdOut
(
'
${_clearChar * spinnerIndent}$_currentAnimationFrame
'
);
}
@override
void
finish
()
{
assert
(
timer
!=
null
);
assert
(
timer
!.
isActive
);
timer
?.
cancel
();
timer
=
null
;
_clearSpinner
();
super
.
finish
();
}
void
_clearSpinner
()
{
_writeToStdOut
(
'
$_backspace$_clear$_backspace
'
);
final
String
newFrame
=
_currentAnimationFrame
;
_lastAnimationFrameLength
=
newFrame
.
runes
.
length
;
_writeToStdOut
(
newFrame
);
}
@override
void
pause
()
{
assert
(
timer
!=
null
);
assert
(
timer
!.
isActive
);
_clearSpinner
();
if
(
_terminal
.
supportsColor
)
{
_writeToStdOut
(
'
\r
\
x1B[K'
);
// go to start of line and clear line
}
else
{
_clear
(
_currentLineLength
);
}
_lastAnimationFrameLength
=
0
;
timer
?.
cancel
();
}
...
...
@@ -992,101 +1017,90 @@ class AnsiSpinner extends Status {
assert
(!
timer
!.
isActive
);
_startSpinner
();
}
}
const
int
_kTimePadding
=
8
;
// should fit "99,999ms"
@override
void
finish
()
{
assert
(
timer
!=
null
);
assert
(
timer
!.
isActive
);
timer
?.
cancel
();
timer
=
null
;
_clear
(
_lastAnimationFrameLength
);
_lastAnimationFrameLength
=
0
;
super
.
finish
();
}
}
/// Constructor writes [message] to [stdout] with padding, then starts an
/// indeterminate progress indicator animation (it's a subclass of
/// [AnsiSpinner]).
/// An animated version of [Status].
///
/// The constructor writes [message] to [stdout] with padding, then starts an
/// indeterminate progress indicator animation.
///
/// On [cancel] or [stop], will call [onFinish]. On [stop], will
/// additionally print out summary information.
class
AnsiStatus
extends
AnsiSpinner
{
AnsiStatus
({
this
.
message
=
''
,
this
.
multilineOutput
=
false
,
///
/// Call [pause] before outputting any text while this is running.
class
SpinnerStatus
extends
AnonymousSpinnerStatus
{
SpinnerStatus
({
required
this
.
message
,
this
.
padding
=
kDefaultStatusPadding
,
required
Stopwatch
stopwatch
,
required
Terminal
terminal
,
VoidCallback
?
onFinish
,
required
Stopwatch
stopwatch
,
required
Stdio
stdio
,
})
:
assert
(
message
!=
null
),
assert
(
multilineOutput
!=
null
),
assert
(
padding
!=
null
),
super
(
required
Terminal
terminal
,
})
:
super
(
onFinish:
onFinish
,
stdio:
stdio
,
stopwatch:
stopwatch
,
stdio:
stdio
,
terminal:
terminal
,
);
final
String
message
;
final
bool
multilineOutput
;
final
int
padding
;
static
const
String
_margin
=
' '
;
@override
int
get
spinnerIndent
=>
_kTimePadding
-
1
;
static
final
String
_margin
=
AnonymousSpinnerStatus
.
_clearChar
*
(
5
+
_kTimePadding
-
1
);
int
_totalMessageLength
=
0
;
@override
int
get
_currentLineLength
=>
_totalMessageLength
+
super
.
_currentLineLength
;
@override
void
start
()
{
_
star
tStatus
();
_
prin
tStatus
();
super
.
start
();
}
void
_
star
tStatus
()
{
void
_
prin
tStatus
()
{
final
String
line
=
'
${message.padRight(padding)}$_margin
'
;
_totalMessageLength
=
line
.
length
;
_writeToStdOut
(
line
);
}
@override
void
stop
()
{
super
.
stop
();
writeSummaryInformation
();
_writeToStdOut
(
'
\n
'
);
void
pause
()
{
super
.
pause
();
_totalMessageLength
=
0
;
}
@override
void
cancel
()
{
super
.
cancel
();
_writeToStdOut
(
'
\n
'
);
}
/// Print summary information when a task is done.
///
/// If [multilineOutput] is false, replaces the spinner with the summary message.
///
/// If [multilineOutput] is true, then it prints the message again on a new
/// line before writing the elapsed time.
void
writeSummaryInformation
()
{
if
(
multilineOutput
)
{
_writeToStdOut
(
'
\n
${'$message Done'.padRight(padding)}$_margin
'
);
}
_writeToStdOut
(
elapsedTime
.
padLeft
(
_kTimePadding
));
}
void
_clearStatus
()
{
_writeToStdOut
(
'
${_backspaceChar * _totalMessageLength}
'
'
${_clearChar * _totalMessageLength}
'
'
${_backspaceChar * _totalMessageLength}
'
,
);
void
resume
()
{
_printStatus
();
super
.
resume
();
}
@override
void
pause
()
{
super
.
pause
();
_clearStatus
();
void
stop
()
{
super
.
stop
();
// calls finish, which clears the spinner
assert
(
_totalMessageLength
>
_kTimePadding
);
_writeToStdOut
(
AnonymousSpinnerStatus
.
_backspaceChar
*
(
_kTimePadding
-
1
));
_writeToStdOut
(
elapsedTime
.
padLeft
(
_kTimePadding
));
_writeToStdOut
(
'
\n
'
);
}
@override
void
resume
()
{
_startStatus
();
super
.
resume
();
void
cancel
()
{
super
.
cancel
();
// calls finish, which clears the spinner
assert
(
_totalMessageLength
>
0
);
_writeToStdOut
(
'
\n
'
);
}
}
packages/flutter_tools/lib/src/base/terminal.dart
View file @
33b183e6
...
...
@@ -81,6 +81,10 @@ abstract class Terminal {
/// Whether the current terminal can display emoji.
bool
get
supportsEmoji
;
/// When we have a choice of styles (e.g. animated spinners), this selects the
/// style to use.
int
get
preferredStyle
;
/// Whether we are interacting with the flutter tool via the terminal.
///
/// If not set, defaults to false.
...
...
@@ -143,12 +147,15 @@ class AnsiTerminal implements Terminal {
AnsiTerminal
({
required
io
.
Stdio
stdio
,
required
Platform
platform
,
DateTime
?
now
,
// Time used to determine preferredStyle. Defaults to 0001-01-01 00:00.
})
:
_stdio
=
stdio
,
_platform
=
platform
;
_platform
=
platform
,
_now
=
now
??
DateTime
(
1
);
final
io
.
Stdio
_stdio
;
final
Platform
_platform
;
final
DateTime
_now
;
static
const
String
bold
=
'
\
u001B[1m'
;
static
const
String
resetAll
=
'
\
u001B[0m'
;
...
...
@@ -187,6 +194,15 @@ class AnsiTerminal implements Terminal {
bool
get
supportsEmoji
=>
!
_platform
.
isWindows
||
_platform
.
environment
.
containsKey
(
'WT_SESSION'
);
@override
int
get
preferredStyle
{
const
int
workdays
=
DateTime
.
friday
;
if
(
_now
.
weekday
<=
workdays
)
{
return
_now
.
weekday
-
1
;
}
return
_now
.
hour
+
workdays
;
}
final
RegExp
_boldControls
=
RegExp
(
'(
${RegExp.escape(resetBold)}
|
${RegExp.escape(bold)}
)'
,
);
...
...
@@ -355,6 +371,9 @@ class _TestTerminal implements Terminal {
@override
final
bool
supportsEmoji
;
@override
int
get
preferredStyle
=>
0
;
@override
bool
get
stdinHasTerminal
=>
false
;
...
...
packages/flutter_tools/lib/src/globals_null_migrated.dart
View file @
33b183e6
...
...
@@ -163,6 +163,7 @@ AnsiTerminal get terminal {
final
AnsiTerminal
_defaultAnsiTerminal
=
AnsiTerminal
(
stdio:
stdio
,
platform:
platform
,
now:
DateTime
.
now
(),
);
/// The global Stdio wrapper.
...
...
packages/flutter_tools/test/general.shard/base/logger_test.dart
View file @
33b183e6
...
...
@@ -192,17 +192,14 @@ void main() {
);
const
String
progressId
=
'progressId'
;
const
bool
multilineOutput
=
true
;
const
int
progressIndicatorPadding
=
kDefaultStatusPadding
*
2
;
expect
(
()
=>
delegatingLogger
.
startProgress
(
message
,
progressId:
progressId
,
multilineOutput:
multilineOutput
,
progressIndicatorPadding:
progressIndicatorPadding
,
),
_throwsInvocationFor
(()
=>
fakeLogger
.
startProgress
(
message
,
progressId:
progressId
,
multilineOutput:
multilineOutput
,
progressIndicatorPadding:
progressIndicatorPadding
,
)),
);
...
...
@@ -399,7 +396,7 @@ void main() {
Platform
ansiPlatform
;
AnsiTerminal
terminal
;
AnsiTerminal
coloredTerminal
;
AnsiStatus
ansi
Status
;
SpinnerStatus
spinner
Status
;
setUp
(()
{
platform
=
FakePlatform
(
stdoutSupportsAnsi:
false
);
...
...
@@ -414,7 +411,7 @@ void main() {
platform:
ansiPlatform
,
);
ansiStatus
=
Ansi
Status
(
spinnerStatus
=
Spinner
Status
(
message:
'Hello world'
,
padding:
20
,
onFinish:
()
=>
called
+=
1
,
...
...
@@ -424,35 +421,35 @@ void main() {
);
});
testWithoutContext
(
'An
siSpinner
works (1)'
,
()
async
{
testWithoutContext
(
'An
onymousSpinnerStatus
works (1)'
,
()
async
{
bool
done
=
false
;
mockStopwatch
=
FakeStopwatch
();
FakeAsync
().
run
((
FakeAsync
time
)
{
final
An
siSpinner
ansiSpinner
=
AnsiSpinner
(
final
An
onymousSpinnerStatus
spinner
=
AnonymousSpinnerStatus
(
stdio:
mockStdio
,
stopwatch:
stopwatchFactory
.
createStopwatch
(),
terminal:
terminal
,
)..
start
();
doWhileAsync
(
time
,
()
=>
ansiS
pinner
.
ticks
<
10
);
doWhileAsync
(
time
,
()
=>
s
pinner
.
ticks
<
10
);
List
<
String
>
lines
=
outputStdout
();
expect
(
lines
[
0
],
startsWith
(
terminal
.
supportsEmoji
?
'
\
b
⣽
\
b⣻
\
b⢿
\
b⡿
\
b⣟
\
b⣯
\
b⣷
\
b⣾
\
b⣽
\
b⣻'
:
'
\
b
\\
\
b|
\
b/
\
b-
\
b
\\
\
b|
\
b/
\
b-'
?
'⣽
\
b⣻
\
b⢿
\
b⡿
\
b⣟
\
b⣯
\
b⣷
\
b⣾
\
b⣽
\
b⣻'
:
'
\\
\
b|
\
b/
\
b-
\
b
\\
\
b|
\
b/
\
b-'
),
);
expect
(
lines
[
0
].
endsWith
(
'
\n
'
),
isFalse
);
expect
(
lines
.
length
,
equals
(
1
));
ansiS
pinner
.
stop
();
s
pinner
.
stop
();
lines
=
outputStdout
();
expect
(
lines
[
0
],
endsWith
(
'
\
b
\
b'
));
expect
(
lines
.
length
,
equals
(
1
));
// Verify that stopping or canceling multiple times throws.
expect
(
ansiS
pinner
.
stop
,
throwsAssertionError
);
expect
(
ansiS
pinner
.
cancel
,
throwsAssertionError
);
expect
(
s
pinner
.
stop
,
throwsAssertionError
);
expect
(
s
pinner
.
cancel
,
throwsAssertionError
);
done
=
true
;
});
expect
(
done
,
isTrue
);
...
...
@@ -472,12 +469,13 @@ void main() {
);
expect
(
outputStderr
().
length
,
equals
(
1
));
expect
(
outputStderr
().
first
,
isEmpty
);
// the 5 below is the margin that is always included between the message and the time.
// the 4 below is the margin that is always included between the message and the time.
// the 8 below is the space left for the time.
expect
(
outputStdout
().
join
(
'
\n
'
),
matches
(
terminal
.
supportsEmoji
?
r'^Hello {15} {
5} {8}[\b]{8} {7
}⣽$'
:
r'^Hello {15} {
5} {8}[\b]{8} {7
}\\$'
),
?
r'^Hello {15} {
4} {8
}⣽$'
:
r'^Hello {15} {
4} {8
}\\$'
),
);
mockStopwatch
.
elapsed
=
const
Duration
(
seconds:
4
,
milliseconds:
100
);
status
.
stop
();
...
...
@@ -485,8 +483,8 @@ void main() {
outputStdout
().
join
(
'
\n
'
),
matches
(
terminal
.
supportsEmoji
?
r'^Hello {15} {
5} {8}[\b]{8} {7}⣽[\b]{8} {8}
[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$'
:
r'^Hello {15} {
5} {8}[\b]{8} {7}\\[\b]{8} {8}
[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$'
,
?
r'^Hello {15} {
4} {8}⣽[\b]
[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$'
:
r'^Hello {15} {
4} {8}\\[\b]
[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$'
,
),
);
});
...
...
@@ -501,32 +499,30 @@ void main() {
outputPreferences:
OutputPreferences
.
test
(
showColor:
true
),
stopwatchFactory:
stopwatchFactory
,
);
const
String
message
=
"Knock Knock, Who's There"
;
final
Status
status
=
logger
.
startProgress
(
"Knock Knock, Who's There"
,
progressIndicatorPadding:
10
,
message
,
progressIndicatorPadding:
10
,
// ignored
);
logger
.
printStatus
(
'Rude Interrupting Cow'
);
status
.
stop
();
final
String
a
=
terminal
.
supportsEmoji
?
'⣽'
:
r'\'
;
final
String
b
=
terminal
.
supportsEmoji
?
'⣻'
:
'|'
;
const
String
blankLine
=
'
\r
\
x1B[K'
;
expect
(
outputStdout
().
join
(
'
\n
'
),
"Knock Knock, Who's There "
// initial message
'
'
// placeholder so that spinner can backspace on its first tick
'
$message
'
// initial message
'
${" " * 4}${" " * 8}
'
// margin (4) and space for the time at the end (8)
// ignore: missing_whitespace_between_adjacent_strings
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
$a
'
// first tick
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b '
// clearing the spinner
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b'
// clearing the clearing of the spinner
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b '
// clearing the message
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b'
// clearing the clearing of the message
'
$a
'
// first tick
'
$blankLine
'
// clearing the line
'Rude Interrupting Cow
\n
'
// message
"Knock Knock, Who's There "
// message restoration
' '
// placeholder so that spinner can backspace on its second tick
'
$message
'
// message restoration
'
${" " * 4}${" " * 8}
'
// margin (4) and space for the time at the end (8)
'
$b
'
// second tick
// ignore: missing_whitespace_between_adjacent_strings
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
$b
'
// second tick
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b '
// clearing the spinner to put the time
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b'
// clearing the clearing of the spinner
'
\
b
\
b'
// backspace the tick, wipe the tick, backspace the wipe
'
\
b
\
b
\
b
\
b
\
b
\
b
\
b'
// backspace the space for the time
' 5.0s
\n
'
,
// replacing it with the time
);
done
=
true
;
...
...
@@ -534,66 +530,96 @@ void main() {
expect
(
done
,
isTrue
);
});
testWithoutContext
(
'AnsiStatus works when canceled'
,
()
async
{
testWithoutContext
(
'Stdout startProgress on non-colored terminal pauses'
,
()
async
{
bool
done
=
false
;
FakeAsync
().
run
((
FakeAsync
time
)
{
mockStopwatch
.
elapsed
=
const
Duration
(
seconds:
5
);
final
Logger
logger
=
StdoutLogger
(
terminal:
terminal
,
stdio:
mockStdio
,
outputPreferences:
OutputPreferences
.
test
(
showColor:
true
),
stopwatchFactory:
stopwatchFactory
,
);
const
String
message
=
"Knock Knock, Who's There"
;
final
Status
status
=
logger
.
startProgress
(
message
,
progressIndicatorPadding:
10
,
// ignored
);
logger
.
printStatus
(
'Rude Interrupting Cow'
);
status
.
stop
();
expect
(
outputStdout
().
join
(
'
\n
'
),
'
$message
'
// initial message
' '
// margin
'
\n
'
// clearing the line
'Rude Interrupting Cow
\n
'
// message
'
$message
5.0s
\n
'
// message restoration
);
done
=
true
;
});
expect
(
done
,
isTrue
);
});
testWithoutContext
(
'SpinnerStatus works when canceled'
,
()
async
{
bool
done
=
false
;
FakeAsync
().
run
((
FakeAsync
time
)
{
ansi
Status
.
start
();
spinner
Status
.
start
();
mockStopwatch
.
elapsed
=
const
Duration
(
seconds:
1
);
doWhileAsync
(
time
,
()
=>
ansi
Status
.
ticks
<
10
);
doWhileAsync
(
time
,
()
=>
spinner
Status
.
ticks
<
10
);
List
<
String
>
lines
=
outputStdout
();
expect
(
lines
[
0
],
startsWith
(
terminal
.
supportsEmoji
?
'Hello world
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣽
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣻
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⢿
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⡿
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣟
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣯
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣷
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣾
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣽
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
⣻'
:
'Hello world
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\\
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b |
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b /
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b -
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\\
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b |
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b /
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b -
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\\
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b |'
,
?
'Hello world
⣽
\
b⣻
\
b⢿
\
b⡿
\
b⣟
\
b⣯
\
b⣷
\
b⣾
\
b⣽
\
b
⣻'
:
'Hello world
\\
\
b|
\
b/
\
b-
\
b
\\
\
b|
\
b/
\
b-
\
b
\\
\
b|'
));
expect
(
lines
.
length
,
equals
(
1
));
expect
(
lines
[
0
].
endsWith
(
'
\n
'
),
isFalse
);
// Verify a cancel does _not_ print the time and prints a newline.
ansi
Status
.
cancel
();
spinner
Status
.
cancel
();
lines
=
outputStdout
();
final
List
<
Match
>
matches
=
secondDigits
.
allMatches
(
lines
[
0
]).
toList
();
expect
(
matches
,
isEmpty
);
final
String
leading
=
terminal
.
supportsEmoji
?
'⣻'
:
'|'
;
expect
(
lines
[
0
],
endsWith
(
'
$leading
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b'
));
expect
(
lines
[
0
],
endsWith
(
'
$leading
\
b
\
b'
));
expect
(
called
,
equals
(
1
));
expect
(
lines
.
length
,
equals
(
2
));
expect
(
lines
[
1
],
equals
(
''
));
// Verify that stopping or canceling multiple times throws.
expect
(
ansi
Status
.
cancel
,
throwsAssertionError
);
expect
(
ansi
Status
.
stop
,
throwsAssertionError
);
expect
(
spinner
Status
.
cancel
,
throwsAssertionError
);
expect
(
spinner
Status
.
stop
,
throwsAssertionError
);
done
=
true
;
});
expect
(
done
,
isTrue
);
});
testWithoutContext
(
'
Ansi
Status works when stopped'
,
()
async
{
testWithoutContext
(
'
Spinner
Status works when stopped'
,
()
async
{
bool
done
=
false
;
FakeAsync
().
run
((
FakeAsync
time
)
{
ansi
Status
.
start
();
spinner
Status
.
start
();
mockStopwatch
.
elapsed
=
const
Duration
(
seconds:
1
);
doWhileAsync
(
time
,
()
=>
ansi
Status
.
ticks
<
10
);
doWhileAsync
(
time
,
()
=>
spinner
Status
.
ticks
<
10
);
List
<
String
>
lines
=
outputStdout
();
expect
(
lines
,
hasLength
(
1
));
expect
(
lines
[
0
],
terminal
.
supportsEmoji
?
'Hello world
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣽
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣻
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⢿
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⡿
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣟
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣯
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣷
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣾
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b ⣽
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
⣻'
:
'Hello world
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\\
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b |
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b /
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b -
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\\
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b |
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b /
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b -
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\\
\
b
\
b
\
b
\
b
\
b
\
b
\
b
\
b |'
,
?
'Hello world
⣽
\
b⣻
\
b⢿
\
b⡿
\
b⣟
\
b⣯
\
b⣷
\
b⣾
\
b⣽
\
b
⣻'
:
'Hello world
\\
\
b|
\
b/
\
b-
\
b
\\
\
b|
\
b/
\
b-
\
b
\\
\
b|'
);
// Verify a stop prints the time.
ansi
Status
.
stop
();
spinner
Status
.
stop
();
lines
=
outputStdout
();
expect
(
lines
,
hasLength
(
2
));
expect
(
lines
[
0
],
matches
(
terminal
.
supportsEmoji
?
r'Hello world
{8}[\b]{8} {7}⣽[\b]{8} {7}⣻[\b]{8} {7}⢿[\b]{8} {7}⡿[\b]{8} {7}⣟[\b]{8} {7}⣯[\b]{8} {7}⣷[\b]{8} {7}⣾[\b]{8} {7}⣽[\b]{8} {7}⣻[\b]{8} {7}
[\b]{8}[\d., ]{5}[\d]ms$'
:
r'Hello world
{8}[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7}/[\b]{8} {7}-[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7}/[\b]{8} {7}-[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7} [\b]{8}[\d., ]{6}[\d]ms$'
,
?
r'Hello world
⣽[\b]⣻[\b]⢿[\b]⡿[\b]⣟[\b]⣯[\b]⣷[\b]⣾[\b]⣽[\b]⣻[\b]
[\b]{8}[\d., ]{5}[\d]ms$'
:
r'Hello world
\\[\b]|[\b]/[\b]-[\b]\\[\b]|[\b]/[\b]-[\b]\\[\b]|[\b] [\b]{8}[\d., ]{5}[\d]ms$'
));
expect
(
lines
[
1
],
isEmpty
);
final
List
<
Match
>
times
=
secondDigits
.
allMatches
(
lines
[
0
]).
toList
();
...
...
@@ -607,8 +633,8 @@ void main() {
expect
(
lines
[
1
],
equals
(
''
));
// Verify that stopping or canceling multiple times throws.
expect
(
ansi
Status
.
stop
,
throwsAssertionError
);
expect
(
ansi
Status
.
cancel
,
throwsAssertionError
);
expect
(
spinner
Status
.
stop
,
throwsAssertionError
);
expect
(
spinner
Status
.
cancel
,
throwsAssertionError
);
done
=
true
;
});
expect
(
done
,
isTrue
);
...
...
packages/flutter_tools/test/general.shard/base/terminal_test.dart
View file @
33b183e6
...
...
@@ -173,12 +173,53 @@ void main() {
..
stdinHasTerminal
=
false
;
final
AnsiTerminal
ansiTerminal
=
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
()
platform:
const
LocalPlatform
()
,
);
expect
(()
=>
ansiTerminal
.
singleCharMode
=
true
,
returnsNormally
);
});
});
testWithoutContext
(
'AnsiTerminal.preferredStyle'
,
()
{
final
Stdio
stdio
=
FakeStdio
();
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
()).
preferredStyle
,
0
);
// Defaults to 0 for backwards compatibility.
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
1
)).
preferredStyle
,
0
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
2
)).
preferredStyle
,
1
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
3
)).
preferredStyle
,
2
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
4
)).
preferredStyle
,
3
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
5
)).
preferredStyle
,
4
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
6
)).
preferredStyle
,
5
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
7
)).
preferredStyle
,
5
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
8
)).
preferredStyle
,
0
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
9
)).
preferredStyle
,
1
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
10
)).
preferredStyle
,
2
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
11
)).
preferredStyle
,
3
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
1
,
1
)).
preferredStyle
,
0
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
2
,
1
)).
preferredStyle
,
1
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
3
,
1
)).
preferredStyle
,
2
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
4
,
1
)).
preferredStyle
,
3
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
5
,
1
)).
preferredStyle
,
4
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
6
,
1
)).
preferredStyle
,
6
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
7
,
1
)).
preferredStyle
,
6
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
8
,
1
)).
preferredStyle
,
0
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
9
,
1
)).
preferredStyle
,
1
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
10
,
1
)).
preferredStyle
,
2
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
11
,
1
)).
preferredStyle
,
3
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
1
,
23
)).
preferredStyle
,
0
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
2
,
23
)).
preferredStyle
,
1
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
3
,
23
)).
preferredStyle
,
2
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
4
,
23
)).
preferredStyle
,
3
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
5
,
23
)).
preferredStyle
,
4
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
6
,
23
)).
preferredStyle
,
28
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
7
,
23
)).
preferredStyle
,
28
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
8
,
23
)).
preferredStyle
,
0
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
9
,
23
)).
preferredStyle
,
1
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
10
,
23
)).
preferredStyle
,
2
);
expect
(
AnsiTerminal
(
stdio:
stdio
,
platform:
const
LocalPlatform
(),
now:
DateTime
(
2018
,
1
,
11
,
23
)).
preferredStyle
,
3
);
});
}
late
Stream
<
String
>
mockStdInStream
;
...
...
@@ -187,7 +228,8 @@ class TestTerminal extends AnsiTerminal {
TestTerminal
({
Stdio
?
stdio
,
Platform
platform
=
const
LocalPlatform
(),
})
:
super
(
stdio:
stdio
??
Stdio
(),
platform:
platform
);
DateTime
?
now
,
})
:
super
(
stdio:
stdio
??
Stdio
(),
platform:
platform
,
now:
now
??
DateTime
(
2018
));
@override
Stream
<
String
>
get
keystrokes
{
...
...
@@ -195,6 +237,9 @@ class TestTerminal extends AnsiTerminal {
}
bool
singleCharMode
=
false
;
@override
int
get
preferredStyle
=>
0
;
}
class
FakeStdio
extends
Fake
implements
Stdio
{
...
...
packages/flutter_tools/test/general.shard/ios/code_signing_test.dart
View file @
33b183e6
...
...
@@ -682,4 +682,7 @@ class TestTerminal extends AnsiTerminal {
Stream
<
String
>
get
keystrokes
{
return
mockTerminalStdInStream
;
}
@override
int
get
preferredStyle
=>
0
;
}
packages/flutter_tools/test/integration.shard/overall_experience_test.dart
View file @
33b183e6
...
...
@@ -280,6 +280,8 @@ Future<ProcessTestResult> runFlutter(
return
ProcessTestResult
(
exitCode
,
stdoutLog
,
stderrLog
);
}
const
int
progressMessageWidth
=
64
;
void
main
(
)
{
testWithoutContext
(
'flutter run writes and clears pidfile appropriately'
,
()
async
{
final
String
tempDirectory
=
fileSystem
.
systemTempDirectory
.
createTempSync
(
'flutter_overall_experience_test.'
).
resolveSymbolicLinksSync
();
...
...
@@ -326,18 +328,18 @@ void main() {
<
String
>[
'run'
,
'-dflutter-tester'
,
'--report-ready'
,
'--pid-file'
,
pidFile
,
'--no-devtools'
,
testScript
],
testDirectory
,
<
Transition
>[
Barrier
(
'Flutter run key commands.'
,
handler:
(
String
line
)
{
Multiple
(<
Pattern
>[
'Flutter run key commands.'
,
'called paint'
]
,
handler:
(
String
line
)
{
pid
=
int
.
parse
(
fileSystem
.
file
(
pidFile
).
readAsStringSync
());
processManager
.
killPid
(
pid
,
ProcessSignal
.
sigusr1
);
return
null
;
}),
Barrier
(
RegExp
(
r'^Performing hot reload\.\.\.'
),
logging:
true
),
// sometimes this includes the "called reassemble" message
Multiple
(<
Pattern
>[
RegExp
(
r'^Reloaded 0 libraries in [0-9]+ms\.$'
),
/*'called reassemble', (see TODO below)*/
'called paint'
],
handler:
(
String
line
)
{
Barrier
(
'Performing hot reload...'
.
padRight
(
progressMessageWidth
),
logging:
true
),
Multiple
(<
Pattern
>[
RegExp
(
r'^Reloaded 0 libraries in [0-9]+ms\.$'
),
'called reassemble'
,
'called paint'
],
handler:
(
String
line
)
{
processManager
.
killPid
(
pid
,
ProcessSignal
.
sigusr2
);
return
null
;
}),
Barrier
(
RegExp
(
r'^Performing hot restart\.\.\.'
)),
// sametimes this includes the "called main" message
Multiple
(<
Pattern
>[
RegExp
(
r'^Restarted application in [0-9]+ms.$'
),
/*'called main', (see TODO below)*/
'called paint'
],
handler:
(
String
line
)
{
Barrier
(
'Performing hot restart...'
.
padRight
(
progressMessageWidth
)),
Multiple
(<
Pattern
>[
RegExp
(
r'^Restarted application in [0-9]+ms.$'
),
'called main'
,
'called paint'
],
handler:
(
String
line
)
{
return
'q'
;
}),
const
Barrier
(
'Application finished.'
),
...
...
@@ -347,25 +349,20 @@ void main() {
// We check the output from the app (all starts with "called ...") and the output from the tool
// (everything else) separately, because their relative timing isn't guaranteed. Their rough timing
// is verified by the expected transitions above.
// TODO(ianh): Fix the tool so that the output isn't garbled (right now we're putting debug output from
// the app on the line where we're spinning the busy signal, rather than adding a newline).
expect
(
result
.
stdout
.
where
((
String
line
)
=>
line
.
startsWith
(
'called '
)
&&
line
!=
'called reassemble'
/* see todo above*/
&&
line
!=
'called main'
/* see todo above*/
),
<
Object
>[
expect
(
result
.
stdout
.
where
((
String
line
)
=>
line
.
startsWith
(
'called '
)),
<
Object
>[
// logs start after we receive the response to sending SIGUSR1
// SIGUSR1:
// 'called reassemble', // see todo above, this only sometimes gets included, other times it's on the "performing..." line
'called reassemble'
,
'called paint'
,
// SIGUSR2:
// 'called main', // see todo above, this is sometimes on the "performing..." line
'called main'
,
'called paint'
,
]);
expect
(
result
.
stdout
.
where
((
String
line
)
=>
!
line
.
startsWith
(
'called '
)),
<
Object
>[
// logs start after we receive the response to sending SIGUSR1
startsWith
(
'Performing hot reload...'
),
// see todo above, this sometimes ends with "called reassemble"
''
,
// this newline is probably the misplaced one for the reassemble; see todo above
'Performing hot reload...'
.
padRight
(
progressMessageWidth
),
startsWith
(
'Reloaded 0 libraries in '
),
'Performing hot restart...
'
,
'Performing hot restart...
'
.
padRight
(
progressMessageWidth
)
,
startsWith
(
'Restarted application in '
),
''
,
// this newline is the one for after we hit "q"
'Application finished.'
,
...
...
@@ -386,14 +383,14 @@ void main() {
<
String
>[
'run'
,
'-dflutter-tester'
,
'--report-ready'
,
'--no-devtools'
,
testScript
],
testDirectory
,
<
Transition
>[
Multiple
(<
Pattern
>[
'Flutter run key commands.'
,
'called main'
],
handler:
(
String
line
)
{
Multiple
(<
Pattern
>[
'Flutter run key commands.'
,
'called main'
,
'called paint'
],
handler:
(
String
line
)
{
return
'r'
;
}),
Barrier
(
RegExp
(
r'^Performing hot reload\.\.\.'
),
logging:
true
),
Multiple
(<
Pattern
>[
'ready'
,
/*'reassemble', (see todo below)*/
'called paint'
],
handler:
(
String
line
)
{
Barrier
(
'Performing hot reload...'
.
padRight
(
progressMessageWidth
),
logging:
true
),
Multiple
(<
Pattern
>[
'ready'
,
'called reassemble'
,
'called paint'
],
handler:
(
String
line
)
{
return
'R'
;
}),
Barrier
(
RegExp
(
r'^Performing hot restart\.\.\.'
)),
Barrier
(
'Performing hot restart...'
.
padRight
(
progressMessageWidth
)),
Multiple
(<
Pattern
>[
'ready'
,
'called main'
,
'called paint'
],
handler:
(
String
line
)
{
return
'p'
;
}),
...
...
@@ -410,11 +407,10 @@ void main() {
// We check the output from the app (all starts with "called ...") and the output from the tool
// (everything else) separately, because their relative timing isn't guaranteed. Their rough timing
// is verified by the expected transitions above.
// TODO(ianh): Fix the tool so that the output isn't garbled (right now we're putting debug output from
// the app on the line where we're spinning the busy signal, rather than adding a newline).
expect
(
result
.
stdout
.
where
((
String
line
)
=>
line
.
startsWith
(
'called '
)
&&
line
!=
'called reassemble'
/* see todo above*/
),
<
Object
>[
expect
(
result
.
stdout
.
where
((
String
line
)
=>
line
.
startsWith
(
'called '
)),
<
Object
>[
// logs start after we initiate the hot reload
// hot reload:
// 'called reassemble', // see todo above, this sometimes gets placed on the "Performing hot reload..." line
'called reassemble'
,
'called paint'
,
// hot restart:
'called main'
,
...
...
@@ -427,12 +423,11 @@ void main() {
]);
expect
(
result
.
stdout
.
where
((
String
line
)
=>
!
line
.
startsWith
(
'called '
)),
<
Object
>[
// logs start after we receive the response to hitting "r"
startsWith
(
'Performing hot reload...'
),
// see todo above, this sometimes ends with "called reassemble"
''
,
// this newline is probably the misplaced one for the reassemble; see todo above
'Performing hot reload...'
.
padRight
(
progressMessageWidth
),
startsWith
(
'Reloaded 0 libraries in '
),
'ready'
,
''
,
// this newline is the one for after we hit "R"
'Performing hot restart...
'
,
'Performing hot restart...
'
.
padRight
(
progressMessageWidth
)
,
startsWith
(
'Restarted application in '
),
'ready'
,
''
,
// newline for after we hit "p" the first time
...
...
@@ -462,7 +457,7 @@ void main() {
Barrier
(
RegExp
(
r'^The Flutter DevTools debugger and profiler on Flutter test device is available at: '
),
handler:
(
String
line
)
{
return
'r'
;
}),
Barrier
(
RegExp
(
r'^Performing hot reload\.\.\.'
),
logging:
true
),
Barrier
(
'Performing hot reload...'
.
padRight
(
progressMessageWidth
),
logging:
true
),
Barrier
(
RegExp
(
r'^Reloaded 0 libraries in [0-9]+ms.'
),
handler:
(
String
line
)
{
return
'q'
;
}),
...
...
@@ -472,6 +467,7 @@ void main() {
expect
(
result
.
exitCode
,
0
);
expect
(
result
.
stdout
,
<
Object
>[
startsWith
(
'Performing hot reload...'
),
''
,
'══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════'
,
'The following assertion was thrown during layout:'
,
'A RenderFlex overflowed by 69200 pixels on the right.'
,
...
...
@@ -506,7 +502,6 @@ void main() {
' verticalDirection: down'
,
'◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤'
,
'════════════════════════════════════════════════════════════════════════════════════════════════════'
,
''
,
startsWith
(
'Reloaded 0 libraries in '
),
''
,
'Application finished.'
,
...
...
packages/flutter_tools/test/src/testbed.dart
View file @
33b183e6
...
...
@@ -36,7 +36,7 @@ final Map<Type, Generator> _testbedDefaults = <Type, Generator>{
FileSystem:
()
=>
MemoryFileSystem
(
style:
globals
.
platform
.
isWindows
?
FileSystemStyle
.
windows
:
FileSystemStyle
.
posix
),
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
Logger:
()
=>
BufferLogger
(
terminal:
AnsiTerminal
(
stdio:
globals
.
stdio
,
platform:
globals
.
platform
),
// Danger, using real stdio.
terminal:
AnsiTerminal
(
stdio:
globals
.
stdio
,
platform:
globals
.
platform
),
// Danger, using real stdio.
outputPreferences:
OutputPreferences
.
test
(),
),
// Allows reading logs and prevents stdout.
OperatingSystemUtils:
()
=>
FakeOperatingSystemUtils
(),
...
...
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