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
97e03104
Unverified
Commit
97e03104
authored
Nov 13, 2018
by
Greg Spencer
Committed by
GitHub
Nov 13, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make the 'time to update' message depend up on the channel. (#24173)
Fixes #24158
parent
72b6a706
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
382 additions
and
329 deletions
+382
-329
version.dart
packages/flutter_tools/lib/src/version.dart
+29
-15
channel_test.dart
packages/flutter_tools/test/channel_test.dart
+1
-1
version_test.dart
packages/flutter_tools/test/version_test.dart
+352
-313
No files found.
packages/flutter_tools/lib/src/version.dart
View file @
97e03104
...
...
@@ -207,20 +207,34 @@ class FlutterVersion {
/// The amount of time we wait before pinging the server to check for the
/// availability of a newer version of Flutter.
@visibleForTesting
static
const
Duration
kC
heckAgeConsideredUpToDate
=
Duration
(
days:
3
);
static
const
Duration
c
heckAgeConsideredUpToDate
=
Duration
(
days:
3
);
/// We warn the user if the age of their Flutter installation is greater than
/// this duration.
/// this duration. The durations are slightly longer than the expected release
/// cadence for each channel, to give the user a grace period before they get
/// notified.
///
/// This is set to 5 weeks because releases are currently around every 4 weeks.
/// For example, for the beta channel, this is set to five weeks because
/// beta releases happen approximately every month.
@visibleForTesting
static
const
Duration
kVersionAgeConsideredUpToDate
=
Duration
(
days:
35
);
static
Duration
versionAgeConsideredUpToDate
(
String
channel
)
{
switch
(
channel
)
{
case
'stable'
:
return
const
Duration
(
days:
365
~/
2
);
// Six months
case
'beta'
:
return
const
Duration
(
days:
7
*
8
);
// Eight weeks
case
'dev'
:
return
const
Duration
(
days:
7
*
4
);
// Four weeks
default
:
return
const
Duration
(
days:
7
*
3
);
// Three weeks
}
}
/// The amount of time we wait between issuing a warning.
///
/// This is to avoid annoying users who are unable to upgrade right away.
@visibleForTesting
static
const
Duration
kM
axTimeSinceLastWarning
=
Duration
(
days:
1
);
static
const
Duration
m
axTimeSinceLastWarning
=
Duration
(
days:
1
);
/// The amount of time we pause for to let the user read the message about
/// outdated Flutter installation.
...
...
@@ -238,7 +252,7 @@ class FlutterVersion {
static
Future
<
void
>
resetFlutterVersionFreshnessCheck
()
async
{
try
{
await
Cache
.
instance
.
getStampFileFor
(
VersionCheckStamp
.
kF
lutterVersionCheckStampFile
,
VersionCheckStamp
.
f
lutterVersionCheckStampFile
,
).
delete
();
}
on
FileSystemException
{
// Ignore, since we don't mind if the file didn't exist in the first place.
...
...
@@ -258,7 +272,7 @@ class FlutterVersion {
final
DateTime
localFrameworkCommitDate
=
DateTime
.
parse
(
frameworkCommitDate
);
final
Duration
frameworkAge
=
_clock
.
now
().
difference
(
localFrameworkCommitDate
);
final
bool
installationSeemsOutdated
=
frameworkAge
>
kVersionAgeConsideredUpToDate
;
final
bool
installationSeemsOutdated
=
frameworkAge
>
versionAgeConsideredUpToDate
(
channel
)
;
// Get whether there's a newer version on the remote. This only goes
// to the server if we haven't checked recently so won't happen on every
...
...
@@ -273,8 +287,8 @@ class FlutterVersion {
// Do not load the stamp before the above server check as it may modify the stamp file.
final
VersionCheckStamp
stamp
=
await
VersionCheckStamp
.
load
();
final
DateTime
lastTimeWarningWasPrinted
=
stamp
.
lastTimeWarningWasPrinted
??
_clock
.
ago
(
kM
axTimeSinceLastWarning
*
2
);
final
bool
beenAWhileSinceWarningWasPrinted
=
_clock
.
now
().
difference
(
lastTimeWarningWasPrinted
)
>
kM
axTimeSinceLastWarning
;
final
DateTime
lastTimeWarningWasPrinted
=
stamp
.
lastTimeWarningWasPrinted
??
_clock
.
ago
(
m
axTimeSinceLastWarning
*
2
);
final
bool
beenAWhileSinceWarningWasPrinted
=
_clock
.
now
().
difference
(
lastTimeWarningWasPrinted
)
>
m
axTimeSinceLastWarning
;
// We show a warning if either we know there is a new remote version, or we couldn't tell but the local
// version is outdated.
...
...
@@ -327,7 +341,7 @@ class FlutterVersion {
/// Gets the release date of the latest available Flutter version.
///
/// This method sends a server request if it's been more than
/// [
kC
heckAgeConsideredUpToDate] since the last version check.
/// [
c
heckAgeConsideredUpToDate] since the last version check.
///
/// Returns null if the cached version is out-of-date or missing, and we are
/// unable to reach the server to get the latest version.
...
...
@@ -339,7 +353,7 @@ class FlutterVersion {
final
Duration
timeSinceLastCheck
=
_clock
.
now
().
difference
(
versionCheckStamp
.
lastTimeVersionWasChecked
);
// Don't ping the server too often. Return cached value if it's fresh.
if
(
timeSinceLastCheck
<
kC
heckAgeConsideredUpToDate
)
if
(
timeSinceLastCheck
<
c
heckAgeConsideredUpToDate
)
return
versionCheckStamp
.
lastKnownRemoteVersion
;
}
...
...
@@ -381,10 +395,10 @@ class VersionCheckStamp {
/// The prefix of the stamp file where we cache Flutter version check data.
@visibleForTesting
static
const
String
kF
lutterVersionCheckStampFile
=
'flutter_version_check'
;
static
const
String
f
lutterVersionCheckStampFile
=
'flutter_version_check'
;
static
Future
<
VersionCheckStamp
>
load
()
async
{
final
String
versionCheckStamp
=
Cache
.
instance
.
getStampFor
(
kF
lutterVersionCheckStampFile
);
final
String
versionCheckStamp
=
Cache
.
instance
.
getStampFor
(
f
lutterVersionCheckStampFile
);
if
(
versionCheckStamp
!=
null
)
{
// Attempt to parse stamp JSON.
...
...
@@ -435,8 +449,8 @@ class VersionCheckStamp {
if
(
newTimeWarningWasPrinted
!=
null
)
jsonData
[
'lastTimeWarningWasPrinted'
]
=
'
$newTimeWarningWasPrinted
'
;
const
JsonEncoder
kP
rettyJsonEncoder
=
JsonEncoder
.
withIndent
(
' '
);
Cache
.
instance
.
setStampFor
(
kFlutterVersionCheckStampFile
,
kP
rettyJsonEncoder
.
convert
(
jsonData
));
const
JsonEncoder
p
rettyJsonEncoder
=
JsonEncoder
.
withIndent
(
' '
);
Cache
.
instance
.
setStampFor
(
flutterVersionCheckStampFile
,
p
rettyJsonEncoder
.
convert
(
jsonData
));
}
Map
<
String
,
String
>
toJson
({
...
...
packages/flutter_tools/test/channel_test.dart
View file @
97e03104
...
...
@@ -188,7 +188,7 @@ void main() {
)).
thenAnswer
((
_
)
=>
Future
<
Process
>.
value
(
createMockProcess
()));
final
File
versionCheckFile
=
Cache
.
instance
.
getStampFileFor
(
VersionCheckStamp
.
kF
lutterVersionCheckStampFile
,
VersionCheckStamp
.
f
lutterVersionCheckStampFile
,
);
/// Create a bogus "leftover" version check file to make sure it gets
...
...
packages/flutter_tools/test/version_test.dart
View file @
97e03104
...
...
@@ -19,10 +19,8 @@ import 'src/common.dart';
import
'src/context.dart'
;
final
SystemClock
_testClock
=
SystemClock
.
fixed
(
DateTime
(
2015
,
1
,
1
));
final
DateTime
_upToDateVersion
=
_testClock
.
ago
(
FlutterVersion
.
kVersionAgeConsideredUpToDate
~/
2
);
final
DateTime
_outOfDateVersion
=
_testClock
.
ago
(
FlutterVersion
.
kVersionAgeConsideredUpToDate
*
2
);
final
DateTime
_stampUpToDate
=
_testClock
.
ago
(
FlutterVersion
.
kCheckAgeConsideredUpToDate
~/
2
);
final
DateTime
_stampOutOfDate
=
_testClock
.
ago
(
FlutterVersion
.
kCheckAgeConsideredUpToDate
*
2
);
final
DateTime
_stampUpToDate
=
_testClock
.
ago
(
FlutterVersion
.
checkAgeConsideredUpToDate
~/
2
);
final
DateTime
_stampOutOfDate
=
_testClock
.
ago
(
FlutterVersion
.
checkAgeConsideredUpToDate
*
2
);
void
main
(
)
{
MockProcessManager
mockProcessManager
;
...
...
@@ -33,324 +31,363 @@ void main() {
mockCache
=
MockCache
();
});
group
(
'
$FlutterVersion
'
,
()
{
setUpAll
(()
{
Cache
.
disableLocking
();
FlutterVersion
.
timeToPauseToLetUserReadTheMessage
=
Duration
.
zero
;
});
testUsingContext
(
'prints nothing when Flutter installation looks fresh'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_upToDateVersion
,
// Server will be pinged because we haven't pinged within last x days
expectServerPing:
true
,
remoteCommitDate:
_outOfDateVersion
,
expectSetStamp:
true
);
await
FlutterVersion
.
instance
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
for
(
String
channel
in
FlutterVersion
.
officialChannels
)
{
DateTime
getChannelUpToDateVersion
()
{
return
_testClock
.
ago
(
FlutterVersion
.
versionAgeConsideredUpToDate
(
channel
)
~/
2
);
}
testUsingContext
(
'prints nothing when Flutter installation looks out-of-date by is actually up-to-date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
stamp:
VersionCheckStamp
(
lastTimeVersionWasChecked:
_stampOutOfDate
,
lastKnownRemoteVersion:
_outOfDateVersion
,
),
remoteCommitDate:
_outOfDateVersion
,
expectSetStamp:
true
,
expectServerPing:
true
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
DateTime
getChannelOutOfDateVersion
()
{
return
_testClock
.
ago
(
FlutterVersion
.
versionAgeConsideredUpToDate
(
channel
)
*
2
);
}
testUsingContext
(
'does not ping server when version stamp is up-to-date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
stamp:
VersionCheckStamp
(
lastTimeVersionWasChecked:
_stampUpToDate
,
lastKnownRemoteVersion:
_upToDateVersion
,
),
expectSetStamp:
true
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
group
(
'
$FlutterVersion
for
$channel
'
,
()
{
setUpAll
(()
{
Cache
.
disableLocking
();
FlutterVersion
.
timeToPauseToLetUserReadTheMessage
=
Duration
.
zero
;
});
testUsingContext
(
'does not print warning if printed recently'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
stamp:
VersionCheckStamp
(
testUsingContext
(
'prints nothing when Flutter installation looks fresh'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelUpToDateVersion
(),
// Server will be pinged because we haven't pinged within last x days
expectServerPing:
true
,
remoteCommitDate:
getChannelOutOfDateVersion
(),
expectSetStamp:
true
,
channel:
channel
,
);
await
FlutterVersion
.
instance
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'prints nothing when Flutter installation looks out-of-date but is actually up-to-date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
stamp:
VersionCheckStamp
(
lastTimeVersionWasChecked:
_stampOutOfDate
,
lastKnownRemoteVersion:
getChannelOutOfDateVersion
(),
),
remoteCommitDate:
getChannelOutOfDateVersion
(),
expectSetStamp:
true
,
expectServerPing:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'does not ping server when version stamp is up-to-date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
stamp:
VersionCheckStamp
(
lastTimeVersionWasChecked:
_stampUpToDate
,
lastKnownRemoteVersion:
_upToDateVersion
,
),
expectSetStamp:
true
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
expect
((
await
VersionCheckStamp
.
load
()).
lastTimeWarningWasPrinted
,
_testClock
.
now
());
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
lastKnownRemoteVersion:
getChannelUpToDateVersion
(),
),
expectSetStamp:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'does not print warning if printed recently'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
stamp:
VersionCheckStamp
(
lastTimeVersionWasChecked:
_stampUpToDate
,
lastKnownRemoteVersion:
getChannelUpToDateVersion
(),
),
expectSetStamp:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
expect
((
await
VersionCheckStamp
.
load
()).
lastTimeWarningWasPrinted
,
_testClock
.
now
());
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'pings server when version stamp is missing then does not'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
remoteCommitDate:
getChannelUpToDateVersion
(),
expectSetStamp:
true
,
expectServerPing:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
testUsingContext
(
'pings server when version stamp is missing then does not'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
remoteCommitDate:
_upToDateVersion
,
expectSetStamp:
true
,
expectServerPing:
true
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
// Immediate subsequent check is not expected to ping the server.
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
stamp:
await
VersionCheckStamp
.
load
(),
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
testUsingContext
(
'pings server when version stamp is out-of-date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
stamp:
VersionCheckStamp
(
// Immediate subsequent check is not expected to ping the server.
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
stamp:
await
VersionCheckStamp
.
load
(),
channel:
channel
,
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'pings server when version stamp is out-of-date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
stamp:
VersionCheckStamp
(
lastTimeVersionWasChecked:
_stampOutOfDate
,
lastKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
2
)),
),
remoteCommitDate:
_upToDateVersion
,
expectSetStamp:
true
,
expectServerPing:
true
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'does not print warning when unable to connect to server if not out of date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_upToDateVersion
,
errorOnFetch:
true
,
expectServerPing:
true
,
expectSetStamp:
true
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'prints warning when unable to connect to server if really out of date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
errorOnFetch:
true
,
expectServerPing:
true
,
expectSetStamp:
true
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
versionOutOfDateMessage
(
_testClock
.
now
().
difference
(
_outOfDateVersion
)));
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'versions comparison'
,
()
async
{
fakeData
(
),
remoteCommitDate:
getChannelUpToDateVersion
(),
expectSetStamp:
true
,
expectServerPing:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
newVersionAvailableMessage
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'does not print warning when unable to connect to server if not out of date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
_outOfDateVersion
,
localCommitDate:
getChannelUpToDateVersion
()
,
errorOnFetch:
true
,
expectServerPing:
true
,
expectSetStamp:
true
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
when
(
mockProcessManager
.
runSync
(
<
String
>[
'git'
,
'merge-base'
,
'--is-ancestor'
,
'abcdef'
,
'123456'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
)).
thenReturn
(
ProcessResult
(
1
,
0
,
''
,
''
));
expect
(
version
.
checkRevisionAncestry
(
tentativeDescendantRevision:
'123456'
,
tentativeAncestorRevision:
'abcdef'
,
),
true
);
verify
(
mockProcessManager
.
runSync
(
<
String
>[
'git'
,
'merge-base'
,
'--is-ancestor'
,
'abcdef'
,
'123456'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
));
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
});
});
group
(
'
$VersionCheckStamp
'
,
()
{
void
_expectDefault
(
VersionCheckStamp
stamp
)
{
expect
(
stamp
.
lastKnownRemoteVersion
,
isNull
);
expect
(
stamp
.
lastTimeVersionWasChecked
,
isNull
);
expect
(
stamp
.
lastTimeWarningWasPrinted
,
isNull
);
}
testUsingContext
(
'loads blank when stamp file missing'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'loads blank when stamp file is malformed JSON'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
stampJson:
'<'
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
expectSetStamp:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'prints warning when unable to connect to server if really out of date'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
errorOnFetch:
true
,
expectServerPing:
true
,
expectSetStamp:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
versionOutOfDateMessage
(
_testClock
.
now
().
difference
(
getChannelOutOfDateVersion
())));
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'versions comparison'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
localCommitDate:
getChannelOutOfDateVersion
(),
errorOnFetch:
true
,
expectServerPing:
true
,
expectSetStamp:
true
,
channel:
channel
,
);
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
when
(
mockProcessManager
.
runSync
(
<
String
>[
'git'
,
'merge-base'
,
'--is-ancestor'
,
'abcdef'
,
'123456'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
)).
thenReturn
(
ProcessResult
(
1
,
0
,
''
,
''
));
expect
(
version
.
checkRevisionAncestry
(
tentativeDescendantRevision:
'123456'
,
tentativeAncestorRevision:
'abcdef'
,
),
true
);
verify
(
mockProcessManager
.
runSync
(
<
String
>[
'git'
,
'merge-base'
,
'--is-ancestor'
,
'abcdef'
,
'123456'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
));
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
});
});
testUsingContext
(
'loads blank when stamp file is well-formed but invalid JSON'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
stampJson:
'[]'
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
group
(
'
$VersionCheckStamp
for
$channel
'
,
()
{
void
_expectDefault
(
VersionCheckStamp
stamp
)
{
expect
(
stamp
.
lastKnownRemoteVersion
,
isNull
);
expect
(
stamp
.
lastTimeVersionWasChecked
,
isNull
);
expect
(
stamp
.
lastTimeWarningWasPrinted
,
isNull
);
}
testUsingContext
(
'loads valid JSON'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
stampJson:
'''
testUsingContext
(
'loads blank when stamp file missing'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
channel:
channel
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'loads blank when stamp file is malformed JSON'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
stampJson:
'<'
,
channel:
channel
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'loads blank when stamp file is well-formed but invalid JSON'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
stampJson:
'[]'
,
channel:
channel
,
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'loads valid JSON'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
stampJson:
'''
{
"lastKnownRemoteVersion": "
${_testClock.ago(const Duration(days: 1))}
",
"lastTimeVersionWasChecked": "
${_testClock.ago(const Duration(days: 2))}
",
"lastTimeWarningWasPrinted": "
${_testClock.now()}
"
}
'''
);
final
VersionCheckStamp
stamp
=
await
VersionCheckStamp
.
load
();
expect
(
stamp
.
lastKnownRemoteVersion
,
_testClock
.
ago
(
const
Duration
(
days:
1
)));
expect
(
stamp
.
lastTimeVersionWasChecked
,
_testClock
.
ago
(
const
Duration
(
days:
2
)));
expect
(
stamp
.
lastTimeWarningWasPrinted
,
_testClock
.
now
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'stores version stamp'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
expectSetStamp:
true
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
final
VersionCheckStamp
stamp
=
VersionCheckStamp
(
lastKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
1
)),
lastTimeVersionWasChecked:
_testClock
.
ago
(
const
Duration
(
days:
2
)),
lastTimeWarningWasPrinted:
_testClock
.
now
(),
);
await
stamp
.
store
();
final
VersionCheckStamp
storedStamp
=
await
VersionCheckStamp
.
load
();
expect
(
storedStamp
.
lastKnownRemoteVersion
,
_testClock
.
ago
(
const
Duration
(
days:
1
)));
expect
(
storedStamp
.
lastTimeVersionWasChecked
,
_testClock
.
ago
(
const
Duration
(
days:
2
)));
expect
(
storedStamp
.
lastTimeWarningWasPrinted
,
_testClock
.
now
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'overwrites individual fields'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
expectSetStamp:
true
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
final
VersionCheckStamp
stamp
=
VersionCheckStamp
(
lastKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
10
)),
lastTimeVersionWasChecked:
_testClock
.
ago
(
const
Duration
(
days:
9
)),
lastTimeWarningWasPrinted:
_testClock
.
ago
(
const
Duration
(
days:
8
)),
);
await
stamp
.
store
(
newKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
1
)),
newTimeVersionWasChecked:
_testClock
.
ago
(
const
Duration
(
days:
2
)),
newTimeWarningWasPrinted:
_testClock
.
now
(),
);
final
VersionCheckStamp
storedStamp
=
await
VersionCheckStamp
.
load
();
expect
(
storedStamp
.
lastKnownRemoteVersion
,
_testClock
.
ago
(
const
Duration
(
days:
1
)));
expect
(
storedStamp
.
lastTimeVersionWasChecked
,
_testClock
.
ago
(
const
Duration
(
days:
2
)));
expect
(
storedStamp
.
lastTimeWarningWasPrinted
,
_testClock
.
now
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
'''
,
channel:
channel
,
);
final
VersionCheckStamp
stamp
=
await
VersionCheckStamp
.
load
();
expect
(
stamp
.
lastKnownRemoteVersion
,
_testClock
.
ago
(
const
Duration
(
days:
1
)));
expect
(
stamp
.
lastTimeVersionWasChecked
,
_testClock
.
ago
(
const
Duration
(
days:
2
)));
expect
(
stamp
.
lastTimeWarningWasPrinted
,
_testClock
.
now
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'stores version stamp'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
expectSetStamp:
true
,
channel:
channel
,
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
final
VersionCheckStamp
stamp
=
VersionCheckStamp
(
lastKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
1
)),
lastTimeVersionWasChecked:
_testClock
.
ago
(
const
Duration
(
days:
2
)),
lastTimeWarningWasPrinted:
_testClock
.
now
(),
);
await
stamp
.
store
();
final
VersionCheckStamp
storedStamp
=
await
VersionCheckStamp
.
load
();
expect
(
storedStamp
.
lastKnownRemoteVersion
,
_testClock
.
ago
(
const
Duration
(
days:
1
)));
expect
(
storedStamp
.
lastTimeVersionWasChecked
,
_testClock
.
ago
(
const
Duration
(
days:
2
)));
expect
(
storedStamp
.
lastTimeWarningWasPrinted
,
_testClock
.
now
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
testUsingContext
(
'overwrites individual fields'
,
()
async
{
fakeData
(
mockProcessManager
,
mockCache
,
expectSetStamp:
true
,
channel:
channel
,
);
_expectDefault
(
await
VersionCheckStamp
.
load
());
final
VersionCheckStamp
stamp
=
VersionCheckStamp
(
lastKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
10
)),
lastTimeVersionWasChecked:
_testClock
.
ago
(
const
Duration
(
days:
9
)),
lastTimeWarningWasPrinted:
_testClock
.
ago
(
const
Duration
(
days:
8
)),
);
await
stamp
.
store
(
newKnownRemoteVersion:
_testClock
.
ago
(
const
Duration
(
days:
1
)),
newTimeVersionWasChecked:
_testClock
.
ago
(
const
Duration
(
days:
2
)),
newTimeWarningWasPrinted:
_testClock
.
now
(),
);
final
VersionCheckStamp
storedStamp
=
await
VersionCheckStamp
.
load
();
expect
(
storedStamp
.
lastKnownRemoteVersion
,
_testClock
.
ago
(
const
Duration
(
days:
1
)));
expect
(
storedStamp
.
lastTimeVersionWasChecked
,
_testClock
.
ago
(
const
Duration
(
days:
2
)));
expect
(
storedStamp
.
lastTimeWarningWasPrinted
,
_testClock
.
now
());
},
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
mockProcessManager
,
Cache:
()
=>
mockCache
,
});
});
}
);
}
}
void
_expectVersionMessage
(
String
message
)
{
...
...
@@ -369,6 +406,7 @@ void fakeData(
bool
errorOnFetch
=
false
,
bool
expectSetStamp
=
false
,
bool
expectServerPing
=
false
,
String
channel
=
'master'
,
})
{
ProcessResult
success
(
String
standardOutput
)
{
return
ProcessResult
(
1
,
0
,
standardOutput
,
''
);
...
...
@@ -379,19 +417,21 @@ void fakeData(
}
when
(
cache
.
getStampFor
(
any
)).
thenAnswer
((
Invocation
invocation
)
{
expect
(
invocation
.
positionalArguments
.
single
,
VersionCheckStamp
.
kF
lutterVersionCheckStampFile
);
expect
(
invocation
.
positionalArguments
.
single
,
VersionCheckStamp
.
f
lutterVersionCheckStampFile
);
if
(
stampJson
!=
null
)
if
(
stampJson
!=
null
)
{
return
stampJson
;
}
if
(
stamp
!=
null
)
if
(
stamp
!=
null
)
{
return
json
.
encode
(
stamp
.
toJson
());
}
return
null
;
});
when
(
cache
.
setStampFor
(
any
,
any
)).
thenAnswer
((
Invocation
invocation
)
{
expect
(
invocation
.
positionalArguments
.
first
,
VersionCheckStamp
.
kF
lutterVersionCheckStampFile
);
expect
(
invocation
.
positionalArguments
.
first
,
VersionCheckStamp
.
f
lutterVersionCheckStampFile
);
if
(
expectSetStamp
)
{
stamp
=
VersionCheckStamp
.
fromJson
(
json
.
decode
(
invocation
.
positionalArguments
[
1
]));
...
...
@@ -405,10 +445,7 @@ void fakeData(
bool
argsAre
(
String
a1
,
[
String
a2
,
String
a3
,
String
a4
,
String
a5
,
String
a6
,
String
a7
,
String
a8
])
{
const
ListEquality
<
String
>
equality
=
ListEquality
<
String
>();
final
List
<
String
>
args
=
invocation
.
positionalArguments
.
single
;
final
List
<
String
>
expectedArgs
=
<
String
>[
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
]
.
where
((
String
arg
)
=>
arg
!=
null
)
.
toList
();
final
List
<
String
>
expectedArgs
=
<
String
>[
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
].
where
((
String
arg
)
=>
arg
!=
null
).
toList
();
return
equality
.
equals
(
args
,
expectedArgs
);
}
...
...
@@ -418,11 +455,12 @@ void fakeData(
return
success
(
''
);
}
else
if
(
argsAre
(
'git'
,
'remote'
,
'add'
,
'__flutter_version_check__'
,
'https://github.com/flutter/flutter.git'
))
{
return
success
(
''
);
}
else
if
(
argsAre
(
'git'
,
'fetch'
,
'__flutter_version_check__'
,
'master'
))
{
if
(!
expectServerPing
)
}
else
if
(
argsAre
(
'git'
,
'fetch'
,
'__flutter_version_check__'
,
channel
))
{
if
(!
expectServerPing
)
{
fail
(
'Did not expect server ping'
);
}
return
errorOnFetch
?
failure
(
128
)
:
success
(
''
);
}
else
if
(
remoteCommitDate
!=
null
&&
argsAre
(
'git'
,
'log'
,
'__flutter_version_check__/
master
'
,
'-n'
,
'1'
,
'--pretty=format:%ad'
,
'--date=iso'
))
{
}
else
if
(
remoteCommitDate
!=
null
&&
argsAre
(
'git'
,
'log'
,
'__flutter_version_check__/
$channel
'
,
'-n'
,
'1'
,
'--pretty=format:%ad'
,
'--date=iso'
))
{
return
success
(
remoteCommitDate
.
toString
());
}
...
...
@@ -438,7 +476,7 @@ void fakeData(
<
String
>[
'git'
,
'rev-parse'
,
'--abbrev-ref'
,
'--symbolic'
,
'@{u}'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
environment:
anyNamed
(
'environment'
),
)).
thenReturn
(
ProcessResult
(
101
,
0
,
'master'
,
''
));
)).
thenReturn
(
ProcessResult
(
101
,
0
,
channel
,
''
));
when
(
pm
.
runSync
(
<
String
>[
'git'
,
'rev-parse'
,
'--abbrev-ref'
,
'HEAD'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
...
...
@@ -462,4 +500,5 @@ void fakeData(
}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
MockCache
extends
Mock
implements
Cache
{}
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