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
38970f5f
Unverified
Commit
38970f5f
authored
Apr 10, 2018
by
Konstantin Scheglov
Committed by
GitHub
Apr 10, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a new Device backed by flutter_tester. (#16405)
parent
03a0cd25
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
401 additions
and
0 deletions
+401
-0
application_package.dart
packages/flutter_tools/lib/src/application_package.dart
+4
-0
artifacts.dart
packages/flutter_tools/lib/src/artifacts.dart
+2
-0
build_info.dart
packages/flutter_tools/lib/src/build_info.dart
+3
-0
build_aot.dart
packages/flutter_tools/lib/src/commands/build_aot.dart
+2
-0
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+2
-0
device.dart
packages/flutter_tools/lib/src/device.dart
+2
-0
flutter_command_runner.dart
.../flutter_tools/lib/src/runner/flutter_command_runner.dart
+11
-0
flutter_tester.dart
packages/flutter_tools/lib/src/tester/flutter_tester.dart
+208
-0
flutter_tester_test.dart
packages/flutter_tools/test/tester/flutter_tester_test.dart
+167
-0
No files found.
packages/flutter_tools/lib/src/application_package.dart
View file @
38970f5f
...
...
@@ -17,6 +17,7 @@ import 'build_info.dart';
import
'globals.dart'
;
import
'ios/plist_utils.dart'
as
plist
;
import
'ios/xcodeproj.dart'
;
import
'tester/flutter_tester.dart'
;
abstract
class
ApplicationPackage
{
/// Package ID from the Android Manifest or equivalent.
...
...
@@ -274,6 +275,8 @@ Future<ApplicationPackage> getApplicationPackageForPlatform(TargetPlatform platf
return
applicationBinary
==
null
?
new
IOSApp
.
fromCurrentDirectory
()
:
new
IOSApp
.
fromIpa
(
applicationBinary
);
case
TargetPlatform
.
tester
:
return
new
FlutterTesterApp
.
fromCurrentDirectory
();
case
TargetPlatform
.
darwin_x64
:
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
windows_x64
:
...
...
@@ -305,6 +308,7 @@ class ApplicationPackageStore {
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
tester
:
return
null
;
}
return
null
;
...
...
packages/flutter_tools/lib/src/artifacts.dart
View file @
38970f5f
...
...
@@ -114,6 +114,7 @@ class CachedArtifacts extends Artifacts {
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
tester
:
return
_getHostArtifactPath
(
artifact
,
platform
);
}
assert
(
false
,
'Invalid platform
$platform
.'
);
...
...
@@ -205,6 +206,7 @@ class CachedArtifacts extends Artifacts {
case
TargetPlatform
.
darwin_x64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
tester
:
assert
(
mode
==
null
,
'Platform
$platform
does not support different build modes.'
);
return
fs
.
path
.
join
(
engineDir
,
platformName
);
case
TargetPlatform
.
ios
:
...
...
packages/flutter_tools/lib/src/build_info.dart
View file @
38970f5f
...
...
@@ -157,6 +157,7 @@ enum TargetPlatform {
linux_x64
,
windows_x64
,
fuchsia
,
tester
,
}
String
getNameForTargetPlatform
(
TargetPlatform
platform
)
{
...
...
@@ -179,6 +180,8 @@ String getNameForTargetPlatform(TargetPlatform platform) {
return
'windows-x64'
;
case
TargetPlatform
.
fuchsia
:
return
'fuchsia'
;
case
TargetPlatform
.
tester
:
return
'flutter-tester'
;
}
assert
(
false
);
return
null
;
...
...
packages/flutter_tools/lib/src/commands/build_aot.dart
View file @
38970f5f
...
...
@@ -247,6 +247,7 @@ Future<String> _buildAotSnapshot(
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
tester
:
assert
(
false
);
}
...
...
@@ -347,6 +348,7 @@ Future<String> _buildAotSnapshot(
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
tester
:
assert
(
false
);
}
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
38970f5f
...
...
@@ -24,6 +24,7 @@ import '../resident_runner.dart';
import
'../run_cold.dart'
;
import
'../run_hot.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../tester/flutter_tester.dart'
;
import
'../vmservice.dart'
;
const
String
protocolVersion
=
'0.2.0'
;
...
...
@@ -570,6 +571,7 @@ class DeviceDomain extends Domain {
addDeviceDiscoverer
(
new
AndroidDevices
());
addDeviceDiscoverer
(
new
IOSDevices
());
addDeviceDiscoverer
(
new
IOSSimulators
());
addDeviceDiscoverer
(
new
FlutterTesterDevices
());
}
void
addDeviceDiscoverer
(
PollingDeviceDiscovery
discoverer
)
{
...
...
packages/flutter_tools/lib/src/device.dart
View file @
38970f5f
...
...
@@ -16,6 +16,7 @@ import 'build_info.dart';
import
'globals.dart'
;
import
'ios/devices.dart'
;
import
'ios/simulators.dart'
;
import
'tester/flutter_tester.dart'
;
DeviceManager
get
deviceManager
=>
context
[
DeviceManager
];
...
...
@@ -28,6 +29,7 @@ class DeviceManager {
_deviceDiscoverers
.
add
(
new
AndroidDevices
());
_deviceDiscoverers
.
add
(
new
IOSDevices
());
_deviceDiscoverers
.
add
(
new
IOSSimulators
());
_deviceDiscoverers
.
add
(
new
FlutterTesterDevices
());
}
final
List
<
DeviceDiscovery
>
_deviceDiscoverers
=
<
DeviceDiscovery
>[];
...
...
packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
View file @
38970f5f
...
...
@@ -26,6 +26,7 @@ import '../cache.dart';
import
'../dart/package_map.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../tester/flutter_tester.dart'
;
import
'../usage.dart'
;
import
'../version.dart'
;
import
'../vmservice.dart'
;
...
...
@@ -79,6 +80,11 @@ class FlutterCommandRunner extends CommandRunner<Null> {
help:
'Captures a bug report file to submit to the Flutter team '
'(contains local paths, device
\n
identifiers, and log snippets).'
);
argParser
.
addFlag
(
'show-test-device'
,
negatable:
false
,
hide:
!
verboseHelp
,
help:
'List the special
\'
flutter-tester
\'
device in device listings. '
'This headless device is used to
\n
test Flutter tooling.'
);
String
packagesHelp
;
if
(
fs
.
isFileSync
(
kPackagesFileName
))
...
...
@@ -180,6 +186,11 @@ class FlutterCommandRunner extends CommandRunner<Null> {
contextOverrides
[
Logger
]
=
new
VerboseLogger
(
logger
);
}
if
(
topLevelResults
[
'show-test-device'
]
||
topLevelResults
[
'device-id'
]
==
FlutterTesterDevices
.
kTesterDeviceId
)
{
FlutterTesterDevices
.
showFlutterTesterDevice
=
true
;
}
String
recordTo
=
topLevelResults
[
'record-to'
];
String
replayFrom
=
topLevelResults
[
'replay-from'
];
...
...
packages/flutter_tools/lib/src/tester/flutter_tester.dart
0 → 100644
View file @
38970f5f
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:convert'
;
import
'package:meta/meta.dart'
;
import
'../application_package.dart'
;
import
'../artifacts.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../dart/package_map.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../protocol_discovery.dart'
;
import
'../version.dart'
;
class
FlutterTesterApp
extends
ApplicationPackage
{
final
String
_directory
;
factory
FlutterTesterApp
.
fromCurrentDirectory
()
{
return
new
FlutterTesterApp
.
_
(
fs
.
currentDirectory
.
path
);
}
FlutterTesterApp
.
_
(
String
directory
)
:
_directory
=
directory
,
super
(
id:
directory
);
@override
String
get
name
=>
fs
.
path
.
basename
(
_directory
);
@override
String
get
packagePath
=>
fs
.
path
.
join
(
_directory
,
'.packages'
);
}
// TODO(scheglov): This device does not currently work with full restarts.
class
FlutterTesterDevice
extends
Device
{
final
_FlutterTesterDeviceLogReader
_logReader
=
new
_FlutterTesterDeviceLogReader
();
Process
_process
;
FlutterTesterDevice
(
String
deviceId
)
:
super
(
deviceId
);
@override
Future
<
bool
>
get
isLocalEmulator
async
=>
false
;
@override
String
get
name
=>
'Flutter test device'
;
@override
DevicePortForwarder
get
portForwarder
=>
null
;
@override
Future
<
String
>
get
sdkNameAndVersion
async
{
final
FlutterVersion
flutterVersion
=
FlutterVersion
.
instance
;
return
'Flutter
${flutterVersion.frameworkRevisionShort}
'
;
}
@override
Future
<
TargetPlatform
>
get
targetPlatform
async
=>
TargetPlatform
.
tester
;
@override
void
clearLogs
()
{}
@override
DeviceLogReader
getLogReader
({
ApplicationPackage
app
})
=>
_logReader
;
@override
Future
<
bool
>
installApp
(
ApplicationPackage
app
)
async
=>
true
;
@override
Future
<
bool
>
isAppInstalled
(
ApplicationPackage
app
)
async
=>
false
;
@override
Future
<
bool
>
isLatestBuildInstalled
(
ApplicationPackage
app
)
async
=>
false
;
@override
bool
isSupported
()
=>
true
;
@override
Future
<
LaunchResult
>
startApp
(
ApplicationPackage
package
,
{
@required
String
mainPath
,
String
route
,
@required
DebuggingOptions
debuggingOptions
,
Map
<
String
,
dynamic
>
platformArgs
,
bool
prebuiltApplication:
false
,
bool
applicationNeedsRebuild:
false
,
bool
usesTerminalUi:
true
,
bool
ipv6:
false
,
})
async
{
if
(!
debuggingOptions
.
buildInfo
.
isDebug
)
{
printError
(
'This device only supports debug mode.'
);
return
new
LaunchResult
.
failed
();
}
final
String
shellPath
=
artifacts
.
getArtifactPath
(
Artifact
.
flutterTester
);
if
(!
fs
.
isFileSync
(
shellPath
))
throwToolExit
(
'Cannot find Flutter shell at
$shellPath
'
);
final
List
<
String
>
command
=
<
String
>[
shellPath
,
'--non-interactive'
,
'--enable-dart-profiling'
,
'--packages=
${PackageMap.globalPackagesPath}
'
,
];
if
(
debuggingOptions
.
debuggingEnabled
)
{
if
(
debuggingOptions
.
startPaused
)
{
command
.
add
(
'--start-paused'
);
}
if
(
debuggingOptions
.
hasObservatoryPort
)
command
.
add
(
'--observatory-port=
${debuggingOptions.hasObservatoryPort}
'
);
}
// TODO(scheglov): Provide assets location, once it is possible.
if
(
mainPath
!=
null
)
{
command
.
add
(
mainPath
);
}
try
{
printTrace
(
'
$shellPath
${command.join(' ')}
'
);
_process
=
await
processManager
.
start
(
command
);
_process
.
stdout
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
((
String
line
)
{
_logReader
.
addLine
(
line
);
});
_process
.
stderr
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
((
String
line
)
{
_logReader
.
addLine
(
line
);
});
if
(!
debuggingOptions
.
debuggingEnabled
)
return
new
LaunchResult
.
succeeded
();
final
ProtocolDiscovery
observatoryDiscovery
=
new
ProtocolDiscovery
.
observatory
(
getLogReader
(),
hostPort:
debuggingOptions
.
observatoryPort
);
final
Uri
observatoryUri
=
await
observatoryDiscovery
.
uri
;
return
new
LaunchResult
.
succeeded
(
observatoryUri:
observatoryUri
);
}
catch
(
error
)
{
printError
(
'Failed to launch
$package
:
$error
'
);
return
new
LaunchResult
.
failed
();
}
}
@override
Future
<
bool
>
stopApp
(
ApplicationPackage
app
)
async
{
_process
?.
kill
();
_process
=
null
;
return
true
;
}
@override
Future
<
bool
>
uninstallApp
(
ApplicationPackage
app
)
async
=>
true
;
}
class
FlutterTesterDevices
extends
PollingDeviceDiscovery
{
static
const
String
kTesterDeviceId
=
'flutter-tester'
;
static
bool
showFlutterTesterDevice
=
false
;
final
FlutterTesterDevice
_testerDevice
=
new
FlutterTesterDevice
(
kTesterDeviceId
);
FlutterTesterDevices
()
:
super
(
'Flutter tester'
);
@override
bool
get
canListAnything
=>
true
;
@override
bool
get
supportsPlatform
=>
true
;
@override
Future
<
List
<
Device
>>
pollingGetDevices
()
async
{
return
showFlutterTesterDevice
?
<
Device
>[
_testerDevice
]
:
<
Device
>[];
}
}
class
_FlutterTesterDeviceLogReader
extends
DeviceLogReader
{
final
StreamController
<
String
>
_logLinesController
=
new
StreamController
<
String
>.
broadcast
();
@override
int
get
appPid
=>
0
;
@override
Stream
<
String
>
get
logLines
=>
_logLinesController
.
stream
;
@override
String
get
name
=>
'flutter tester log reader'
;
void
addLine
(
String
line
)
=>
_logLinesController
.
add
(
line
);
}
packages/flutter_tools/test/tester/flutter_tester_test.dart
0 → 100644
View file @
38970f5f
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:file/file.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/tester/flutter_tester.dart'
;
import
'package:process/process.dart'
;
import
'package:test/test.dart'
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
import
'../src/mocks.dart'
;
void
main
(
)
{
MemoryFileSystem
fs
;
setUp
(()
{
fs
=
new
MemoryFileSystem
();
});
group
(
'FlutterTesterApp'
,
()
{
testUsingContext
(
'fromCurrentDirectory'
,
()
async
{
const
String
projectPath
=
'/home/my/projects/my_project'
;
await
fs
.
directory
(
projectPath
).
create
(
recursive:
true
);
fs
.
currentDirectory
=
projectPath
;
final
FlutterTesterApp
app
=
new
FlutterTesterApp
.
fromCurrentDirectory
();
expect
(
app
.
name
,
'my_project'
);
expect
(
app
.
packagePath
,
fs
.
path
.
join
(
projectPath
,
'.packages'
));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
});
group
(
'FlutterTesterDevices'
,
()
{
tearDown
(()
{
FlutterTesterDevices
.
showFlutterTesterDevice
=
false
;
});
testUsingContext
(
'no device'
,
()
async
{
final
FlutterTesterDevices
discoverer
=
new
FlutterTesterDevices
();
final
List
<
Device
>
devices
=
await
discoverer
.
devices
;
expect
(
devices
,
isEmpty
);
});
testUsingContext
(
'has device'
,
()
async
{
FlutterTesterDevices
.
showFlutterTesterDevice
=
true
;
final
FlutterTesterDevices
discoverer
=
new
FlutterTesterDevices
();
final
List
<
Device
>
devices
=
await
discoverer
.
devices
;
expect
(
devices
,
hasLength
(
1
));
final
Device
device
=
devices
.
single
;
expect
(
device
,
const
isInstanceOf
<
FlutterTesterDevice
>());
expect
(
device
.
id
,
'flutter-tester'
);
});
});
group
(
'FlutterTesterDevice'
,
()
{
FlutterTesterDevice
device
;
List
<
String
>
logLines
;
setUp
(()
{
device
=
new
FlutterTesterDevice
(
'flutter-tester'
);
logLines
=
<
String
>[];
device
.
getLogReader
().
logLines
.
listen
(
logLines
.
add
);
});
testUsingContext
(
'getters'
,
()
async
{
expect
(
device
.
id
,
'flutter-tester'
);
expect
(
await
device
.
isLocalEmulator
,
isFalse
);
expect
(
device
.
name
,
'Flutter test device'
);
expect
(
device
.
portForwarder
,
isNull
);
expect
(
await
device
.
targetPlatform
,
TargetPlatform
.
tester
);
expect
(
await
device
.
installApp
(
null
),
isTrue
);
expect
(
await
device
.
isAppInstalled
(
null
),
isFalse
);
expect
(
await
device
.
isLatestBuildInstalled
(
null
),
isFalse
);
expect
(
await
device
.
uninstallApp
(
null
),
isTrue
);
expect
(
device
.
isSupported
(),
isTrue
);
});
group
(
'startApp'
,
()
{
String
flutterRoot
;
String
flutterTesterPath
;
String
projectPath
;
String
mainPath
;
MockProcessManager
mockProcessManager
;
MockProcess
mockProcess
;
final
Map
<
Type
,
Generator
>
startOverrides
=
<
Type
,
Generator
>{
Platform:
()
=>
new
FakePlatform
(
operatingSystem:
'linux'
),
FileSystem:
()
=>
fs
,
Cache:
()
=>
new
Cache
(
rootOverride:
fs
.
directory
(
flutterRoot
)),
ProcessManager:
()
=>
mockProcessManager
,
};
setUp
(()
{
flutterRoot
=
fs
.
path
.
join
(
'home'
,
'me'
,
'flutter'
);
flutterTesterPath
=
fs
.
path
.
join
(
flutterRoot
,
'bin'
,
'cache'
,
'artifacts'
,
'engine'
,
'linux-x64'
,
'flutter_tester'
);
final
File
flutterTesterFile
=
fs
.
file
(
flutterTesterPath
);
flutterTesterFile
.
parent
.
createSync
(
recursive:
true
);
flutterTesterFile
.
writeAsBytesSync
(
const
<
int
>[]);
projectPath
=
fs
.
path
.
join
(
'home'
,
'me'
,
'hello'
);
mainPath
=
fs
.
path
.
join
(
projectPath
,
'lin'
,
'main.dart'
);
mockProcessManager
=
new
MockProcessManager
();
mockProcessManager
.
processFactory
=
(
List
<
String
>
commands
)
=>
mockProcess
;
});
testUsingContext
(
'not debug'
,
()
async
{
final
LaunchResult
result
=
await
device
.
startApp
(
null
,
mainPath:
mainPath
,
debuggingOptions:
new
DebuggingOptions
.
disabled
(
const
BuildInfo
(
BuildMode
.
release
,
null
)));
expect
(
result
.
started
,
isFalse
);
},
overrides:
startOverrides
);
testUsingContext
(
'no flutter_tester'
,
()
async
{
fs
.
file
(
flutterTesterPath
).
deleteSync
();
expect
(()
async
{
await
device
.
startApp
(
null
,
mainPath:
mainPath
,
debuggingOptions:
new
DebuggingOptions
.
disabled
(
const
BuildInfo
(
BuildMode
.
debug
,
null
)));
},
throwsToolExit
());
},
overrides:
startOverrides
);
testUsingContext
(
'start'
,
()
async
{
final
Uri
observatoryUri
=
Uri
.
parse
(
'http://127.0.0.1:6666/'
);
mockProcess
=
new
MockProcess
(
stdout:
new
Stream
<
List
<
int
>>.
fromIterable
(<
List
<
int
>>[
'''
Observatory listening on
$observatoryUri
Hello!
'''
.
codeUnits
]));
final
LaunchResult
result
=
await
device
.
startApp
(
null
,
mainPath:
mainPath
,
debuggingOptions:
new
DebuggingOptions
.
enabled
(
const
BuildInfo
(
BuildMode
.
debug
,
null
)));
expect
(
result
.
started
,
isTrue
);
expect
(
result
.
observatoryUri
,
observatoryUri
);
expect
(
logLines
.
last
,
'Hello!'
);
},
overrides:
startOverrides
);
});
});
}
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