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
8b5af14f
Commit
8b5af14f
authored
Sep 19, 2018
by
tonyzhao1
Committed by
Mehmet Fidanboylu
Sep 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use grouped validator instead of categories (#21577)
This is a cleanup PR.
parent
36b735ee
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
222 additions
and
203 deletions
+222
-203
android_studio_validator.dart
...utter_tools/lib/src/android/android_studio_validator.dart
+1
-1
android_workflow.dart
packages/flutter_tools/lib/src/android/android_workflow.dart
+1
-2
context_runner.dart
packages/flutter_tools/lib/src/context_runner.dart
+1
-0
doctor.dart
packages/flutter_tools/lib/src/doctor.dart
+68
-108
ios_workflow.dart
packages/flutter_tools/lib/src/ios/ios_workflow.dart
+41
-20
vscode_validator.dart
packages/flutter_tools/lib/src/vscode/vscode_validator.dart
+1
-1
doctor_test.dart
packages/flutter_tools/test/commands/doctor_test.dart
+49
-22
ios_workflow_test.dart
packages/flutter_tools/test/ios/ios_workflow_test.dart
+60
-49
No files found.
packages/flutter_tools/lib/src/android/android_studio_validator.dart
View file @
8b5af14f
...
...
@@ -13,7 +13,7 @@ import 'android_studio.dart';
class
AndroidStudioValidator
extends
DoctorValidator
{
final
AndroidStudio
_studio
;
AndroidStudioValidator
(
this
.
_studio
)
:
super
(
'Android Studio'
,
ValidatorCategory
.
androidStudio
);
AndroidStudioValidator
(
this
.
_studio
)
:
super
(
'Android Studio'
);
static
List
<
DoctorValidator
>
get
allValidators
{
final
List
<
DoctorValidator
>
validators
=
<
DoctorValidator
>[];
...
...
packages/flutter_tools/lib/src/android/android_workflow.dart
View file @
8b5af14f
...
...
@@ -46,8 +46,7 @@ class AndroidWorkflow implements Workflow {
}
class
AndroidValidator
extends
DoctorValidator
{
AndroidValidator
():
super
(
'Android toolchain - develop for Android devices'
,
ValidatorCategory
.
androidToolchain
);
AndroidValidator
():
super
(
'Android toolchain - develop for Android devices'
,);
static
const
String
_jdkDownload
=
'https://www.oracle.com/technetwork/java/javase/downloads/'
;
...
...
packages/flutter_tools/lib/src/context_runner.dart
View file @
8b5af14f
...
...
@@ -54,6 +54,7 @@ Future<T> runInContext<T>(
Cache:
()
=>
Cache
(),
Clock:
()
=>
const
Clock
(),
CocoaPods:
()
=>
CocoaPods
(),
CocoaPodsValidator:
()
=>
const
CocoaPodsValidator
(),
Config:
()
=>
Config
(),
DevFSConfig:
()
=>
DevFSConfig
(),
DeviceManager:
()
=>
DeviceManager
(),
...
...
packages/flutter_tools/lib/src/doctor.dart
View file @
8b5af14f
...
...
@@ -51,7 +51,7 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider {
_validators
.
add
(
androidValidator
);
if
(
iosWorkflow
.
appliesToHostPlatform
)
_validators
.
add
(
iosValidator
);
_validators
.
add
(
GroupedValidator
(<
DoctorValidator
>[
iosValidator
,
cocoapodsValidator
])
);
final
List
<
DoctorValidator
>
ideValidators
=
<
DoctorValidator
>[];
ideValidators
.
addAll
(
AndroidStudioValidator
.
allValidators
);
...
...
@@ -121,28 +121,8 @@ class Doctor {
bool
allGood
=
true
;
final
Set
<
ValidatorCategory
>
finishedGroups
=
Set
<
ValidatorCategory
>();
for
(
DoctorValidator
validator
in
validators
)
{
final
ValidatorCategory
currentCategory
=
validator
.
category
;
ValidationResult
result
;
if
(
currentCategory
.
isGrouped
)
{
if
(
finishedGroups
.
contains
(
currentCategory
))
{
// We already handled this category via a previous validator.
continue
;
}
// Skip ahead and get results for the other validators in this category.
final
List
<
ValidationResult
>
results
=
<
ValidationResult
>[];
for
(
DoctorValidator
subValidator
in
validators
.
where
(
(
DoctorValidator
v
)
=>
v
.
category
==
currentCategory
))
{
results
.
add
(
await
subValidator
.
validate
());
}
result
=
_mergeValidationResults
(
results
);
finishedGroups
.
add
(
currentCategory
);
}
else
{
result
=
await
validator
.
validate
();
}
final
ValidationResult
result
=
await
validator
.
validate
();
buffer
.
write
(
'
${result.leadingBox}
${validator.title}
is '
);
if
(
result
.
type
==
ValidationType
.
missing
)
buffer
.
write
(
'not installed.'
);
...
...
@@ -158,7 +138,6 @@ class Doctor {
if
(
result
.
type
!=
ValidationType
.
installed
)
allGood
=
false
;
}
if
(!
allGood
)
{
...
...
@@ -180,39 +159,15 @@ class Doctor {
bool
doctorResult
=
true
;
int
issues
=
0
;
final
List
<
ValidatorTask
>
taskList
=
startValidatorTasks
();
final
Set
<
ValidatorCategory
>
finishedGroups
=
Set
<
ValidatorCategory
>();
for
(
ValidatorTask
validatorTask
in
taskList
)
{
for
(
ValidatorTask
validatorTask
in
startValidatorTasks
())
{
final
DoctorValidator
validator
=
validatorTask
.
validator
;
final
ValidatorCategory
currentCategory
=
validator
.
category
;
final
Status
status
=
Status
.
withSpinner
();
ValidationResult
result
;
if
(
currentCategory
.
isGrouped
)
{
if
(
finishedGroups
.
contains
(
currentCategory
))
{
continue
;
}
final
List
<
ValidationResult
>
results
=
<
ValidationResult
>[];
for
(
ValidatorTask
subValidator
in
taskList
.
where
(
(
ValidatorTask
t
)
=>
t
.
validator
.
category
==
currentCategory
))
{
try
{
results
.
add
(
await
subValidator
.
result
);
}
catch
(
exception
)
{
status
.
cancel
();
rethrow
;
}
}
result
=
_mergeValidationResults
(
results
);
finishedGroups
.
add
(
currentCategory
);
}
else
{
try
{
result
=
await
validatorTask
.
result
;
}
catch
(
exception
)
{
status
.
cancel
();
rethrow
;
}
try
{
result
=
await
validatorTask
.
result
;
}
catch
(
exception
)
{
status
.
cancel
();
rethrow
;
}
status
.
stop
();
...
...
@@ -256,35 +211,6 @@ class Doctor {
return
doctorResult
;
}
ValidationResult
_mergeValidationResults
(
List
<
ValidationResult
>
results
)
{
ValidationType
mergedType
=
results
[
0
].
type
;
final
List
<
ValidationMessage
>
mergedMessages
=
<
ValidationMessage
>[];
for
(
ValidationResult
result
in
results
)
{
switch
(
result
.
type
)
{
case
ValidationType
.
installed
:
if
(
mergedType
==
ValidationType
.
missing
)
{
mergedType
=
ValidationType
.
partial
;
}
break
;
case
ValidationType
.
partial
:
mergedType
=
ValidationType
.
partial
;
break
;
case
ValidationType
.
missing
:
if
(
mergedType
==
ValidationType
.
installed
)
{
mergedType
=
ValidationType
.
partial
;
}
break
;
default
:
throw
'Unrecognized validation type: '
+
result
.
type
.
toString
();
}
mergedMessages
.
addAll
(
result
.
messages
);
}
return
ValidationResult
(
mergedType
,
mergedMessages
,
statusInfo:
results
[
0
].
statusInfo
);
}
bool
get
canListAnything
=>
workflows
.
any
((
Workflow
workflow
)
=>
workflow
.
canListDevices
);
bool
get
canLaunchAnything
{
...
...
@@ -292,11 +218,8 @@ class Doctor {
return
true
;
return
workflows
.
any
((
Workflow
workflow
)
=>
workflow
.
canLaunchDevices
);
}
}
/// A series of tools and required install steps for a target platform (iOS or Android).
abstract
class
Workflow
{
/// Whether the workflow applies to this platform (as in, should we ever try and use it).
...
...
@@ -318,32 +241,69 @@ enum ValidationType {
installed
}
/// Validator output is grouped by category.
class
ValidatorCategory
{
final
String
name
;
// Whether we should bundle results for validators sharing this cateogry,
// or let each stand alone.
final
bool
isGrouped
;
const
ValidatorCategory
(
this
.
name
,
this
.
isGrouped
);
static
const
ValidatorCategory
androidToolchain
=
ValidatorCategory
(
'androidToolchain'
,
true
);
static
const
ValidatorCategory
androidStudio
=
ValidatorCategory
(
'androidStudio'
,
false
);
static
const
ValidatorCategory
ios
=
ValidatorCategory
(
'ios'
,
true
);
static
const
ValidatorCategory
flutter
=
ValidatorCategory
(
'flutter'
,
false
);
static
const
ValidatorCategory
ide
=
ValidatorCategory
(
'ide'
,
false
);
static
const
ValidatorCategory
device
=
ValidatorCategory
(
'device'
,
false
);
static
const
ValidatorCategory
other
=
ValidatorCategory
(
'other'
,
false
);
}
abstract
class
DoctorValidator
{
const
DoctorValidator
(
this
.
title
,
[
this
.
category
=
ValidatorCategory
.
other
]
);
const
DoctorValidator
(
this
.
title
);
final
String
title
;
final
ValidatorCategory
category
;
Future
<
ValidationResult
>
validate
();
}
/// A validator that runs other [DoctorValidator]s and combines their output
/// into a single [ValidationResult]. It uses the title of the first validator
/// passed to the constructor and reports the statusInfo of the first validator
/// that provides one. Other titles and statusInfo strings are discarded.
class
GroupedValidator
extends
DoctorValidator
{
GroupedValidator
(
this
.
subValidators
)
:
super
(
subValidators
[
0
].
title
);
final
List
<
DoctorValidator
>
subValidators
;
@override
Future
<
ValidationResult
>
validate
()
async
{
final
List
<
ValidatorTask
>
tasks
=
<
ValidatorTask
>[];
for
(
DoctorValidator
validator
in
subValidators
)
{
tasks
.
add
(
ValidatorTask
(
validator
,
validator
.
validate
()));
}
final
List
<
ValidationResult
>
results
=
<
ValidationResult
>[];
for
(
ValidatorTask
subValidator
in
tasks
)
{
results
.
add
(
await
subValidator
.
result
);
}
return
_mergeValidationResults
(
results
);
}
ValidationResult
_mergeValidationResults
(
List
<
ValidationResult
>
results
)
{
assert
(
results
.
isNotEmpty
,
'Validation results should not be empty'
);
ValidationType
mergedType
=
results
[
0
].
type
;
final
List
<
ValidationMessage
>
mergedMessages
=
<
ValidationMessage
>[];
String
statusInfo
;
for
(
ValidationResult
result
in
results
)
{
statusInfo
??=
result
.
statusInfo
;
switch
(
result
.
type
)
{
case
ValidationType
.
installed
:
if
(
mergedType
==
ValidationType
.
missing
)
{
mergedType
=
ValidationType
.
partial
;
}
break
;
case
ValidationType
.
partial
:
mergedType
=
ValidationType
.
partial
;
break
;
case
ValidationType
.
missing
:
if
(
mergedType
==
ValidationType
.
installed
)
{
mergedType
=
ValidationType
.
partial
;
}
break
;
default
:
throw
'Unrecognized validation type: '
+
result
.
type
.
toString
();
}
mergedMessages
.
addAll
(
result
.
messages
);
}
return
ValidationResult
(
mergedType
,
mergedMessages
,
statusInfo:
statusInfo
);
}
}
class
ValidationResult
{
/// [ValidationResult.type] should only equal [ValidationResult.installed]
...
...
@@ -383,7 +343,7 @@ class ValidationMessage {
}
class
_FlutterValidator
extends
DoctorValidator
{
_FlutterValidator
()
:
super
(
'Flutter'
,
ValidatorCategory
.
flutter
);
_FlutterValidator
()
:
super
(
'Flutter'
);
@override
Future
<
ValidationResult
>
validate
()
async
{
...
...
@@ -432,7 +392,7 @@ bool _genSnapshotRuns(String genSnapshotPath) {
}
class
NoIdeValidator
extends
DoctorValidator
{
NoIdeValidator
()
:
super
(
'Flutter IDE Support'
,
ValidatorCategory
.
ide
);
NoIdeValidator
()
:
super
(
'Flutter IDE Support'
);
@override
Future
<
ValidationResult
>
validate
()
async
{
...
...
@@ -445,7 +405,7 @@ class NoIdeValidator extends DoctorValidator {
abstract
class
IntelliJValidator
extends
DoctorValidator
{
final
String
installPath
;
IntelliJValidator
(
String
title
,
this
.
installPath
)
:
super
(
title
,
ValidatorCategory
.
ide
);
IntelliJValidator
(
String
title
,
this
.
installPath
)
:
super
(
title
);
String
get
version
;
String
get
pluginsPath
;
...
...
@@ -640,7 +600,7 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
}
class
DeviceValidator
extends
DoctorValidator
{
DeviceValidator
()
:
super
(
'Connected devices'
,
ValidatorCategory
.
device
);
DeviceValidator
()
:
super
(
'Connected devices'
);
@override
Future
<
ValidationResult
>
validate
()
async
{
...
...
packages/flutter_tools/lib/src/ios/ios_workflow.dart
View file @
8b5af14f
...
...
@@ -16,6 +16,7 @@ import 'plist_utils.dart' as plist;
IOSWorkflow
get
iosWorkflow
=>
context
[
IOSWorkflow
];
IOSValidator
get
iosValidator
=>
context
[
IOSValidator
];
CocoaPodsValidator
get
cocoapodsValidator
=>
context
[
CocoaPodsValidator
];
class
IOSWorkflow
implements
Workflow
{
const
IOSWorkflow
();
...
...
@@ -42,8 +43,7 @@ class IOSWorkflow implements Workflow {
class
IOSValidator
extends
DoctorValidator
{
const
IOSValidator
()
:
super
(
'iOS toolchain - develop for iOS devices'
,
ValidatorCategory
.
ios
);
const
IOSValidator
()
:
super
(
'iOS toolchain - develop for iOS devices'
);
Future
<
bool
>
get
hasIDeviceInstaller
=>
exitsHappyAsync
(<
String
>[
'ideviceinstaller'
,
'-h'
]);
...
...
@@ -175,13 +175,45 @@ class IOSValidator extends DoctorValidator {
}
}
final
CocoaPodsStatus
cocoaPodsStatus
=
await
cocoaPods
.
evaluateCocoaPodsInstallation
;
}
else
{
brewStatus
=
ValidationType
.
missing
;
messages
.
add
(
ValidationMessage
.
error
(
'Brew not installed; use this to install tools for iOS device development.
\n
'
'Download brew at https://brew.sh/.'
));
}
return
ValidationResult
(
<
ValidationType
>[
xcodeStatus
,
brewStatus
].
reduce
(
_mergeValidationTypes
),
messages
,
statusInfo:
xcodeVersionInfo
);
}
ValidationType
_mergeValidationTypes
(
ValidationType
t1
,
ValidationType
t2
)
{
return
t1
==
t2
?
t1
:
ValidationType
.
partial
;
}
}
class
CocoaPodsValidator
extends
DoctorValidator
{
const
CocoaPodsValidator
()
:
super
(
'CocoaPods subvalidator'
);
bool
get
hasHomebrew
=>
os
.
which
(
'brew'
)
!=
null
;
@override
Future
<
ValidationResult
>
validate
()
async
{
final
List
<
ValidationMessage
>
messages
=
<
ValidationMessage
>[];
ValidationType
status
=
ValidationType
.
installed
;
if
(
hasHomebrew
)
{
final
CocoaPodsStatus
cocoaPodsStatus
=
await
cocoaPods
.
evaluateCocoaPodsInstallation
;
if
(
cocoaPodsStatus
==
CocoaPodsStatus
.
recommended
)
{
if
(
await
cocoaPods
.
isCocoaPodsInitialized
)
{
messages
.
add
(
ValidationMessage
(
'CocoaPods version
${await cocoaPods.cocoaPodsVersionText}
'
));
}
else
{
brewS
tatus
=
ValidationType
.
partial
;
s
tatus
=
ValidationType
.
partial
;
messages
.
add
(
ValidationMessage
.
error
(
'CocoaPods installed but not initialized.
\n
'
'
$noCocoaPodsConsequence
\n
'
...
...
@@ -191,8 +223,8 @@ class IOSValidator extends DoctorValidator {
));
}
}
else
{
brewStatus
=
ValidationType
.
partial
;
if
(
cocoaPodsStatus
==
CocoaPodsStatus
.
notInstalled
)
{
status
=
ValidationType
.
missing
;
messages
.
add
(
ValidationMessage
.
error
(
'CocoaPods not installed.
\n
'
'
$noCocoaPodsConsequence
\n
'
...
...
@@ -200,6 +232,7 @@ class IOSValidator extends DoctorValidator {
'
$cocoaPodsInstallInstructions
'
));
}
else
{
status
=
ValidationType
.
partial
;
messages
.
add
(
ValidationMessage
.
hint
(
'CocoaPods out of date (
${cocoaPods.cocoaPodsRecommendedVersion}
is recommended).
\n
'
'
$noCocoaPodsConsequence
\n
'
...
...
@@ -209,21 +242,9 @@ class IOSValidator extends DoctorValidator {
}
}
}
else
{
brewStatus
=
ValidationType
.
missing
;
messages
.
add
(
ValidationMessage
.
error
(
'Brew not installed; use this to install tools for iOS device development.
\n
'
'Download brew at https://brew.sh/.'
));
// Only set status. The main validator handles messages for missing brew.
status
=
ValidationType
.
missing
;
}
return
ValidationResult
(
<
ValidationType
>[
xcodeStatus
,
brewStatus
].
reduce
(
_mergeValidationTypes
),
messages
,
statusInfo:
xcodeVersionInfo
);
}
ValidationType
_mergeValidationTypes
(
ValidationType
t1
,
ValidationType
t2
)
{
return
t1
==
t2
?
t1
:
ValidationType
.
partial
;
return
ValidationResult
(
status
,
messages
);
}
}
packages/flutter_tools/lib/src/vscode/vscode_validator.dart
View file @
8b5af14f
...
...
@@ -13,7 +13,7 @@ class VsCodeValidator extends DoctorValidator {
'https://marketplace.visualstudio.com/items?itemName=
${VsCode.extensionIdentifier}
'
;
final
VsCode
_vsCode
;
VsCodeValidator
(
this
.
_vsCode
)
:
super
(
_vsCode
.
productName
,
ValidatorCategory
.
ide
);
VsCodeValidator
(
this
.
_vsCode
)
:
super
(
_vsCode
.
productName
);
static
Iterable
<
DoctorValidator
>
get
installedValidators
{
return
VsCode
...
...
packages/flutter_tools/test/commands/doctor_test.dart
View file @
8b5af14f
...
...
@@ -184,7 +184,6 @@ void main() {
});
});
group
(
'doctor with grouped validators'
,
()
{
testUsingContext
(
'validate diagnose combines validator output'
,
()
async
{
expect
(
await
FakeGroupedDoctor
().
diagnose
(),
isTrue
);
...
...
@@ -201,22 +200,24 @@ void main() {
));
});
testUsingContext
(
'validate summary combines validator output'
,
()
async
{
expect
(
await
FakeGroupedDoctor
().
summaryText
,
equals
(
'[✓] Category 1 is fully installed.
\n
'
'[!] Category 2 is partially installed; more components are available.
\n
'
testUsingContext
(
'validate merging assigns statusInfo and title'
,
()
async
{
// There are two subvalidators. Only the second contains statusInfo.
expect
(
await
FakeGroupedDoctorWithStatus
().
diagnose
(),
isTrue
);
expect
(
testLogger
.
statusText
,
equals
(
'[✓] First validator title (A status message)
\n
'
' • A helpful message
\n
'
' • A different message
\n
'
'
\n
'
'Run "flutter doctor" for information about installing additional components.
\n
'
'• No issues found!
\n
'
));
});
});
group
(
'
doctor merging validator
results'
,
()
{
final
PassingGroupedValidator
installed
=
PassingGroupedValidator
(
'Category'
,
groupedCategory1
);
final
PartialGroupedValidator
partial
=
PartialGroupedValidator
(
'Category'
,
groupedCategory1
);
final
MissingGroupedValidator
missing
=
MissingGroupedValidator
(
'Category'
,
groupedCategory1
);
group
(
'
grouped validator merging
results'
,
()
{
final
PassingGroupedValidator
installed
=
PassingGroupedValidator
(
'Category'
);
final
PartialGroupedValidator
partial
=
PartialGroupedValidator
(
'Category'
);
final
MissingGroupedValidator
missing
=
MissingGroupedValidator
(
'Category'
);
testUsingContext
(
'validate installed + installed = installed'
,
()
async
{
expect
(
await
FakeSmallGroupDoctor
(
installed
,
installed
).
diagnose
(),
isTrue
);
...
...
@@ -405,11 +406,9 @@ class FakeDoctorValidatorsProvider implements DoctorValidatorsProvider {
}
ValidatorCategory
groupedCategory1
=
const
ValidatorCategory
(
'group 1'
,
true
);
ValidatorCategory
groupedCategory2
=
const
ValidatorCategory
(
'group 2'
,
true
);
class
PassingGroupedValidator
extends
DoctorValidator
{
PassingGroupedValidator
(
String
name
,
ValidatorCategory
group
)
:
super
(
name
,
group
);
PassingGroupedValidator
(
String
name
)
:
super
(
name
);
@override
Future
<
ValidationResult
>
validate
()
async
{
...
...
@@ -421,7 +420,7 @@ class PassingGroupedValidator extends DoctorValidator {
}
class
MissingGroupedValidator
extends
DoctorValidator
{
MissingGroupedValidator
(
String
name
,
ValidatorCategory
group
):
super
(
name
,
group
);
MissingGroupedValidator
(
String
name
):
super
(
name
);
@override
Future
<
ValidationResult
>
validate
()
async
{
...
...
@@ -432,7 +431,7 @@ class MissingGroupedValidator extends DoctorValidator {
}
class
PartialGroupedValidator
extends
DoctorValidator
{
PartialGroupedValidator
(
String
name
,
ValidatorCategory
group
):
super
(
name
,
group
);
PartialGroupedValidator
(
String
name
):
super
(
name
);
@override
Future
<
ValidationResult
>
validate
()
async
{
...
...
@@ -442,28 +441,56 @@ class PartialGroupedValidator extends DoctorValidator {
}
}
/// A doctor that has two category groups of two validators each.
class
PassingGroupedValidatorWithStatus
extends
DoctorValidator
{
PassingGroupedValidatorWithStatus
(
String
name
)
:
super
(
name
);
@override
Future
<
ValidationResult
>
validate
()
async
{
final
List
<
ValidationMessage
>
messages
=
<
ValidationMessage
>[];
messages
.
add
(
ValidationMessage
(
'A different message'
));
return
ValidationResult
(
ValidationType
.
installed
,
messages
,
statusInfo:
'A status message'
);
}
}
/// A doctor that has two groups of two validators each.
class
FakeGroupedDoctor
extends
Doctor
{
List
<
DoctorValidator
>
_validators
;
@override
List
<
DoctorValidator
>
get
validators
{
if
(
_validators
==
null
)
{
_validators
=
<
DoctorValidator
>[];
_validators
.
add
(
PassingGroupedValidator
(
'Category 1'
,
groupedCategory1
));
_validators
.
add
(
PassingGroupedValidator
(
'Category 1'
,
groupedCategory1
));
_validators
.
add
(
PassingGroupedValidator
(
'Category 2'
,
groupedCategory2
));
_validators
.
add
(
MissingGroupedValidator
(
'Category 2'
,
groupedCategory2
));
_validators
.
add
(
GroupedValidator
(<
DoctorValidator
>[
PassingGroupedValidator
(
'Category 1'
),
PassingGroupedValidator
(
'Category 1'
)
]));
_validators
.
add
(
GroupedValidator
(<
DoctorValidator
>[
PassingGroupedValidator
(
'Category 2'
),
MissingGroupedValidator
(
'Category 2'
)
]));
}
return
_validators
;
}
}
class
FakeGroupedDoctorWithStatus
extends
Doctor
{
List
<
DoctorValidator
>
_validators
;
@override
List
<
DoctorValidator
>
get
validators
{
_validators
??=
<
DoctorValidator
>[
GroupedValidator
(<
DoctorValidator
>[
PassingGroupedValidator
(
'First validator title'
),
PassingGroupedValidatorWithStatus
(
'Second validator title'
),
])];
return
_validators
;
}
}
/// A doctor that takes any two validators. Used to check behavior when
/// merging ValidationTypes (installed, missing, partial).
class
FakeSmallGroupDoctor
extends
Doctor
{
List
<
DoctorValidator
>
_validators
;
FakeSmallGroupDoctor
(
DoctorValidator
val1
,
DoctorValidator
val2
)
{
_validators
=
<
DoctorValidator
>[
val1
,
val2
];
_validators
=
<
DoctorValidator
>[
GroupedValidator
(<
DoctorValidator
>[
val1
,
val2
])
];
}
@override
List
<
DoctorValidator
>
get
validators
=>
_validators
;
...
...
packages/flutter_tools/test/ios/ios_workflow_test.dart
View file @
8b5af14f
...
...
@@ -190,15 +190,13 @@ void main() {
CocoaPods:
()
=>
cocoaPods
,
});
testUsingContext
(
'Emits partial status when
CocoaPods
is not installed'
,
()
async
{
testUsingContext
(
'Emits partial status when
simctl
is not installed'
,
()
async
{
when
(
xcode
.
isInstalled
).
thenReturn
(
true
);
when
(
xcode
.
versionText
)
.
thenReturn
(
'Xcode 8.2.1
\n
Build version 8C1002
\n
'
);
when
(
xcode
.
isInstalledAndMeetsVersionCheck
).
thenReturn
(
true
);
when
(
xcode
.
eulaSigned
).
thenReturn
(
true
);
when
(
cocoaPods
.
evaluateCocoaPodsInstallation
)
.
thenAnswer
((
_
)
async
=>
CocoaPodsStatus
.
notInstalled
);
when
(
xcode
.
isSimctlInstalled
).
thenReturn
(
true
);
when
(
xcode
.
isSimctlInstalled
).
thenReturn
(
false
);
final
IOSWorkflowTestTarget
workflow
=
IOSWorkflowTestTarget
();
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
partial
);
...
...
@@ -208,35 +206,19 @@ void main() {
CocoaPods:
()
=>
cocoaPods
,
});
testUsingContext
(
'Emits partial status when CocoaPods version is too low'
,
()
async
{
when
(
xcode
.
isInstalled
).
thenReturn
(
true
);
when
(
xcode
.
versionText
)
.
thenReturn
(
'Xcode 8.2.1
\n
Build version 8C1002
\n
'
);
when
(
xcode
.
isInstalledAndMeetsVersionCheck
).
thenReturn
(
true
);
when
(
xcode
.
eulaSigned
).
thenReturn
(
true
);
when
(
cocoaPods
.
evaluateCocoaPodsInstallation
)
.
thenAnswer
((
_
)
async
=>
CocoaPodsStatus
.
belowRecommendedVersion
);
when
(
xcode
.
isSimctlInstalled
).
thenReturn
(
true
);
final
IOSWorkflowTestTarget
workflow
=
IOSWorkflowTestTarget
();
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
partial
);
},
overrides:
<
Type
,
Generator
>{
IMobileDevice:
()
=>
iMobileDevice
,
Xcode:
()
=>
xcode
,
CocoaPods:
()
=>
cocoaPods
,
});
testUsingContext
(
'
Emits partial status when CocoaPods is not initialized
'
,
()
async
{
testUsingContext
(
'
Succeeds when all checks pass
'
,
()
async
{
when
(
xcode
.
isInstalled
).
thenReturn
(
true
);
when
(
xcode
.
versionText
)
.
thenReturn
(
'Xcode 8.2.1
\n
Build version 8C1002
\n
'
);
when
(
xcode
.
isInstalledAndMeetsVersionCheck
).
thenReturn
(
true
);
when
(
xcode
.
eulaSigned
).
thenReturn
(
true
);
when
(
cocoaPods
.
isCocoaPodsInitialized
).
thenAnswer
((
_
)
async
=>
false
);
when
(
xcode
.
isSimctlInstalled
).
thenReturn
(
true
);
ensureDirectoryExists
(
fs
.
path
.
join
(
homeDirPath
,
'.cocoapods'
,
'repos'
,
'master'
,
'README.md'
));
final
ValidationResult
result
=
await
IOSWorkflowTestTarget
().
validate
();
expect
(
result
.
type
,
ValidationType
.
partial
);
expect
(
result
.
type
,
ValidationType
.
installed
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
IMobileDevice:
()
=>
iMobileDevice
,
...
...
@@ -244,42 +226,62 @@ void main() {
CocoaPods:
()
=>
cocoaPods
,
ProcessManager:
()
=>
processManager
,
});
});
testUsingContext
(
'Emits partial status when simctl is not installed'
,
()
async
{
when
(
xcode
.
isInstalled
).
thenReturn
(
true
);
when
(
xcode
.
versionText
)
.
thenReturn
(
'Xcode 8.2.1
\n
Build version 8C1002
\n
'
);
when
(
xcode
.
isInstalledAndMeetsVersionCheck
).
thenReturn
(
true
);
when
(
xcode
.
eulaSigned
).
thenReturn
(
true
);
when
(
xcode
.
isSimctlInstalled
).
thenReturn
(
false
);
final
IOSWorkflowTestTarget
workflow
=
IOSWorkflowTestTarget
();
group
(
'iOS CocoaPods validation'
,
()
{
MockCocoaPods
cocoaPods
;
setUp
(()
{
cocoaPods
=
MockCocoaPods
();
when
(
cocoaPods
.
evaluateCocoaPodsInstallation
)
.
thenAnswer
((
_
)
async
=>
CocoaPodsStatus
.
recommended
);
when
(
cocoaPods
.
isCocoaPodsInitialized
).
thenAnswer
((
_
)
async
=>
true
);
when
(
cocoaPods
.
cocoaPodsVersionText
).
thenAnswer
((
_
)
async
=>
'1.8.0'
);
});
testUsingContext
(
'Emits installed status when CocoaPods is installed'
,
()
async
{
final
CocoaPodsTestTarget
workflow
=
CocoaPodsTestTarget
();
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
partial
);
expect
(
result
.
type
,
ValidationType
.
installed
);
},
overrides:
<
Type
,
Generator
>{
IMobileDevice:
()
=>
iMobileDevice
,
Xcode:
()
=>
xcode
,
CocoaPods:
()
=>
cocoaPods
,
});
testUsingContext
(
'Emits missing status when CocoaPods is not installed'
,
()
async
{
when
(
cocoaPods
.
evaluateCocoaPodsInstallation
)
.
thenAnswer
((
_
)
async
=>
CocoaPodsStatus
.
notInstalled
);
final
CocoaPodsTestTarget
workflow
=
CocoaPodsTestTarget
();
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
missing
);
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
cocoaPods
,
});
testUsingContext
(
'Succeeds when all checks pass'
,
()
async
{
when
(
xcode
.
isInstalled
).
thenReturn
(
true
);
when
(
xcode
.
versionText
)
.
thenReturn
(
'Xcode 8.2.1
\n
Build version 8C1002
\n
'
);
when
(
xcode
.
isInstalledAndMeetsVersionCheck
).
thenReturn
(
true
);
when
(
xcode
.
eulaSigned
).
thenReturn
(
true
);
when
(
xcode
.
isSimctlInstalled
).
thenReturn
(
true
);
testUsingContext
(
'Emits partial status when CocoaPods is not initialized'
,
()
async
{
when
(
cocoaPods
.
isCocoaPodsInitialized
).
thenAnswer
((
_
)
async
=>
false
);
final
CocoaPodsTestTarget
workflow
=
CocoaPodsTestTarget
();
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
partial
);
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
cocoaPods
,
});
ensureDirectoryExists
(
fs
.
path
.
join
(
homeDirPath
,
'.cocoapods'
,
'repos'
,
'master'
,
'README.md'
));
testUsingContext
(
'Emits partial status when CocoaPods version is too low'
,
()
async
{
when
(
cocoaPods
.
evaluateCocoaPodsInstallation
)
.
thenAnswer
((
_
)
async
=>
CocoaPodsStatus
.
belowRecommendedVersion
);
final
CocoaPodsTestTarget
workflow
=
CocoaPodsTestTarget
();
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
partial
);
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
cocoaPods
,
});
final
ValidationResult
result
=
await
IOSWorkflowTestTarget
().
validate
();
expect
(
result
.
type
,
ValidationType
.
installed
);
testUsingContext
(
'Emits missing status when homebrew is not installed'
,
()
async
{
final
CocoaPodsTestTarget
workflow
=
CocoaPodsTestTarget
(
hasHomebrew:
false
);
final
ValidationResult
result
=
await
workflow
.
validate
();
expect
(
result
.
type
,
ValidationType
.
missing
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
IMobileDevice:
()
=>
iMobileDevice
,
Xcode:
()
=>
xcode
,
CocoaPods:
()
=>
cocoaPods
,
ProcessManager:
()
=>
processManager
,
});
});
}
...
...
@@ -330,3 +332,12 @@ class IOSWorkflowTestTarget extends IOSValidator {
@override
final
Future
<
bool
>
hasIDeviceInstaller
;
}
class
CocoaPodsTestTarget
extends
CocoaPodsValidator
{
CocoaPodsTestTarget
({
this
.
hasHomebrew
=
true
});
@override
final
bool
hasHomebrew
;
}
\ No newline at end of file
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