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
d6806392
Unverified
Commit
d6806392
authored
Apr 09, 2020
by
Kirill Pertsev
Committed by
GitHub
Apr 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implements --machine flag for `devices` command (#50581)
parent
74a1b9b3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
322 additions
and
42 deletions
+322
-42
devices.dart
packages/flutter_tools/lib/src/commands/devices.dart
+19
-0
device.dart
packages/flutter_tools/lib/src/device.dart
+22
-0
devices_test.dart
...tter_tools/test/commands.shard/hermetic/devices_test.dart
+61
-0
devices_test.dart
...ter_tools/test/commands.shard/permeable/devices_test.dart
+93
-0
device_test.dart
packages/flutter_tools/test/general.shard/device_test.dart
+31
-42
fake_devices.dart
packages/flutter_tools/test/src/fake_devices.dart
+96
-0
No files found.
packages/flutter_tools/lib/src/commands/devices.dart
View file @
d6806392
...
...
@@ -6,13 +6,21 @@ import 'dart:async';
import
'../base/common.dart'
;
import
'../base/utils.dart'
;
import
'../convert.dart'
;
import
'../device.dart'
;
import
'../doctor.dart'
;
import
'../globals.dart'
as
globals
;
import
'../runner/flutter_command.dart'
;
class
DevicesCommand
extends
FlutterCommand
{
DevicesCommand
()
{
argParser
.
addFlag
(
'machine'
,
negatable:
false
,
help:
'Output device information in machine readable structured JSON format'
,
);
argParser
.
addOption
(
'timeout'
,
abbr:
't'
,
...
...
@@ -73,6 +81,8 @@ class DevicesCommand extends FlutterCommand {
globals
.
printStatus
(
'•
$diagnostic
'
,
hangingIndent:
2
);
}
}
}
else
if
(
boolArg
(
'machine'
))
{
await
printDevicesAsJson
(
devices
);
}
else
{
globals
.
printStatus
(
'
${devices.length}
connected
${pluralize('device', devices.length)}
:
\n
'
);
await
Device
.
printDevices
(
devices
);
...
...
@@ -80,4 +90,13 @@ class DevicesCommand extends FlutterCommand {
return
FlutterCommandResult
.
success
();
}
Future
<
void
>
printDevicesAsJson
(
List
<
Device
>
devices
)
async
{
globals
.
printStatus
(
const
JsonEncoder
.
withIndent
(
' '
).
convert
(
await
Future
.
wait
(
devices
.
map
((
Device
d
)
=>
d
.
toJson
()))
)
);
}
}
packages/flutter_tools/lib/src/device.dart
View file @
d6806392
...
...
@@ -538,6 +538,28 @@ abstract class Device {
await
descriptions
(
devices
).
forEach
(
globals
.
printStatus
);
}
/// Convert the Device object to a JSON representation suitable for serialization.
Future
<
Map
<
String
,
Object
>>
toJson
()
async
{
final
bool
isLocalEmu
=
await
isLocalEmulator
;
return
<
String
,
Object
>{
'name'
:
name
,
'id'
:
id
,
'isSupported'
:
isSupported
(),
'targetPlatform'
:
getNameForTargetPlatform
(
await
targetPlatform
),
'emulator'
:
isLocalEmu
,
'sdk'
:
await
sdkNameAndVersion
,
'capabilities'
:
<
String
,
Object
>{
'hotReload'
:
supportsHotReload
,
'hotRestart'
:
supportsHotRestart
,
'screenshot'
:
supportsScreenshot
,
'fastStart'
:
supportsFastStart
,
'flutterExit'
:
supportsFlutterExit
,
'hardwareRendering'
:
isLocalEmu
&&
await
supportsHardwareRendering
,
'startPaused'
:
supportsStartPaused
,
}
};
}
/// Clean up resources allocated by device
///
/// For example log readers or port forwarders.
...
...
packages/flutter_tools/test/commands.shard/hermetic/devices_test.dart
View file @
d6806392
...
...
@@ -15,6 +15,7 @@ import 'package:process/process.dart';
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/fake_devices.dart'
;
void
main
(
)
{
group
(
'devices'
,
()
{
...
...
@@ -36,6 +37,53 @@ void main() {
DeviceManager:
()
=>
DeviceManager
(),
ProcessManager:
()
=>
MockProcessManager
(),
});
testUsingContext
(
'Outputs parsable JSON with --machine flag'
,
()
async
{
final
DevicesCommand
command
=
DevicesCommand
();
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'devices'
,
'--machine'
]);
expect
(
json
.
decode
(
testLogger
.
statusText
),
<
Map
<
String
,
Object
>>[
<
String
,
Object
>{
'name'
:
'ephemeral'
,
'id'
:
'ephemeral'
,
'isSupported'
:
true
,
'targetPlatform'
:
'android-arm'
,
'emulator'
:
true
,
'sdk'
:
'Test SDK (1.2.3)'
,
'capabilities'
:
<
String
,
Object
>{
'hotReload'
:
true
,
'hotRestart'
:
true
,
'screenshot'
:
false
,
'fastStart'
:
false
,
'flutterExit'
:
true
,
'hardwareRendering'
:
true
,
'startPaused'
:
true
}
},
<
String
,
Object
>{
'name'
:
'webby'
,
'id'
:
'webby'
,
'isSupported'
:
true
,
'targetPlatform'
:
'web-javascript'
,
'emulator'
:
true
,
'sdk'
:
'Web SDK (1.2.4)'
,
'capabilities'
:
<
String
,
Object
>{
'hotReload'
:
true
,
'hotRestart'
:
true
,
'screenshot'
:
false
,
'fastStart'
:
false
,
'flutterExit'
:
true
,
'hardwareRendering'
:
false
,
'startPaused'
:
true
}
}
]
);
},
overrides:
<
Type
,
Generator
>{
DeviceManager:
()
=>
_FakeDeviceManager
(),
ProcessManager:
()
=>
MockProcessManager
(),
});
});
}
...
...
@@ -66,3 +114,16 @@ class MockProcessManager extends Mock implements ProcessManager {
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
}
class
_FakeDeviceManager
extends
DeviceManager
{
_FakeDeviceManager
();
@override
Future
<
List
<
Device
>>
getAllConnectedDevices
()
=>
Future
<
List
<
Device
>>.
value
(
fakeDevices
.
map
((
FakeDeviceJsonData
d
)
=>
d
.
dev
).
toList
());
@override
Future
<
List
<
Device
>>
refreshAllConnectedDevices
({
Duration
timeout
})
=>
getAllConnectedDevices
();
}
packages/flutter_tools/test/commands.shard/permeable/devices_test.dart
0 → 100644
View file @
d6806392
// Copyright 2014 The Flutter 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:convert'
;
import
'package:file/file.dart'
;
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/web/chrome.dart'
;
import
'package:flutter_tools/src/commands/devices.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/config.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'package:flutter_tools/src/base/context.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
void
main
(
)
{
group
(
'devices'
,
()
{
Directory
configDir
;
Config
config
;
tearDown
(()
{
if
(
configDir
!=
null
)
{
tryToDelete
(
configDir
);
configDir
=
null
;
}
});
setUpAll
(()
{
configDir
??=
globals
.
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_config_dir_test.'
,
);
config
=
Config
.
test
(
Config
.
kFlutterSettings
,
directory:
configDir
,
logger:
globals
.
logger
,
)..
setValue
(
'enable-web'
,
true
);
});
// Test assumes no devices connected.
// Should return only `web-server` device
testUsingContext
(
'Test the --machine flag'
,
()
async
{
final
BufferLogger
logger
=
context
.
get
<
Logger
>()
as
BufferLogger
;
final
DevicesCommand
command
=
DevicesCommand
();
final
CommandRunner
<
void
>
runner
=
createTestCommandRunner
(
command
);
await
runner
.
run
(<
String
>[
'devices'
,
'--machine'
]);
expect
(
json
.
decode
(
logger
.
statusText
),
<
Map
<
String
,
Object
>>[
<
String
,
Object
>{
'name'
:
'Web Server'
,
'id'
:
'web-server'
,
'isSupported'
:
true
,
'targetPlatform'
:
'web-javascript'
,
'emulator'
:
false
,
'sdk'
:
'Flutter Tools'
,
'capabilities'
:
<
String
,
Object
>{
'hotReload'
:
true
,
'hotRestart'
:
true
,
'screenshot'
:
false
,
'fastStart'
:
false
,
'flutterExit'
:
true
,
'hardwareRendering'
:
false
,
'startPaused'
:
true
}
}
]
);
},
overrides:
<
Type
,
Generator
>{
DeviceManager:
()
=>
DeviceManager
(),
Config:
()
=>
config
,
ChromeLauncher:
()
=>
_DisabledChromeLauncher
(),
});
});
}
// Without ChromeLauncher DeviceManager constructor fails with noSuchMethodError
// trying to call canFindChrome on null
// Also, Chrome may have different versions on different machines and
// JSON will not match, because the `sdk` field of the Device contains version number
// Mock the launcher to make it appear that we don't have Chrome.
class
_DisabledChromeLauncher
implements
ChromeLauncher
{
@override
bool
canFindChrome
()
=>
false
;
@override
Future
<
Chrome
>
launch
(
String
url
,
{
bool
headless
=
false
,
int
debugPort
,
bool
skipCheck
=
false
,
Directory
cacheDir
})
=>
Future
<
Chrome
>.
error
(
'Chrome disabled'
);
}
\ No newline at end of file
packages/flutter_tools/test/general.shard/device_test.dart
View file @
d6806392
...
...
@@ -12,6 +12,7 @@ import 'package:mockito/mockito.dart';
import
'../src/common.dart'
;
import
'../src/context.dart'
;
import
'../src/fake_devices.dart'
;
import
'../src/mocks.dart'
;
void
main
(
)
{
...
...
@@ -24,9 +25,9 @@ void main() {
});
testUsingContext
(
'getDeviceById'
,
()
async
{
final
_MockDevice
device1
=
_Mock
Device
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
_MockDevice
device2
=
_Mock
Device
(
'Nexus 5X'
,
'01abfc49119c410e'
);
final
_MockDevice
device3
=
_Mock
Device
(
'iPod touch'
,
'82564b38861a9a5'
);
final
FakeDevice
device1
=
Fake
Device
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
FakeDevice
device2
=
Fake
Device
(
'Nexus 5X'
,
'01abfc49119c410e'
);
final
FakeDevice
device3
=
Fake
Device
(
'iPod touch'
,
'82564b38861a9a5'
);
final
List
<
Device
>
devices
=
<
Device
>[
device1
,
device2
,
device3
];
final
DeviceManager
deviceManager
=
TestDeviceManager
(
devices
);
...
...
@@ -42,42 +43,42 @@ void main() {
});
testUsingContext
(
'getAllConnectedDevices caches'
,
()
async
{
final
_MockDevice
device1
=
_Mock
Device
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
FakeDevice
device1
=
Fake
Device
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
TestDeviceManager
deviceManager
=
TestDeviceManager
(<
Device
>[
device1
]);
expect
(
await
deviceManager
.
getAllConnectedDevices
(),
<
Device
>[
device1
]);
final
_MockDevice
device2
=
_Mock
Device
(
'Nexus 5X'
,
'01abfc49119c410e'
);
final
FakeDevice
device2
=
Fake
Device
(
'Nexus 5X'
,
'01abfc49119c410e'
);
deviceManager
.
resetDevices
(<
Device
>[
device2
]);
expect
(
await
deviceManager
.
getAllConnectedDevices
(),
<
Device
>[
device1
]);
});
testUsingContext
(
'refreshAllConnectedDevices does not cache'
,
()
async
{
final
_MockDevice
device1
=
_Mock
Device
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
FakeDevice
device1
=
Fake
Device
(
'Nexus 5'
,
'0553790d0a4e726f'
);
final
TestDeviceManager
deviceManager
=
TestDeviceManager
(<
Device
>[
device1
]);
expect
(
await
deviceManager
.
refreshAllConnectedDevices
(),
<
Device
>[
device1
]);
final
_MockDevice
device2
=
_Mock
Device
(
'Nexus 5X'
,
'01abfc49119c410e'
);
final
FakeDevice
device2
=
Fake
Device
(
'Nexus 5X'
,
'01abfc49119c410e'
);
deviceManager
.
resetDevices
(<
Device
>[
device2
]);
expect
(
await
deviceManager
.
refreshAllConnectedDevices
(),
<
Device
>[
device2
]);
});
});
group
(
'Filter devices'
,
()
{
_Mock
Device
ephemeral
;
_Mock
Device
nonEphemeralOne
;
_Mock
Device
nonEphemeralTwo
;
_Mock
Device
unsupported
;
_Mock
Device
webDevice
;
_Mock
Device
fuchsiaDevice
;
Fake
Device
ephemeral
;
Fake
Device
nonEphemeralOne
;
Fake
Device
nonEphemeralTwo
;
Fake
Device
unsupported
;
Fake
Device
webDevice
;
Fake
Device
fuchsiaDevice
;
setUp
(()
{
ephemeral
=
_Mock
Device
(
'ephemeral'
,
'ephemeral'
,
true
);
nonEphemeralOne
=
_Mock
Device
(
'nonEphemeralOne'
,
'nonEphemeralOne'
,
false
);
nonEphemeralTwo
=
_Mock
Device
(
'nonEphemeralTwo'
,
'nonEphemeralTwo'
,
false
);
unsupported
=
_Mock
Device
(
'unsupported'
,
'unsupported'
,
true
,
false
);
webDevice
=
_Mock
Device
(
'webby'
,
'webby'
)
ephemeral
=
Fake
Device
(
'ephemeral'
,
'ephemeral'
,
true
);
nonEphemeralOne
=
Fake
Device
(
'nonEphemeralOne'
,
'nonEphemeralOne'
,
false
);
nonEphemeralTwo
=
Fake
Device
(
'nonEphemeralTwo'
,
'nonEphemeralTwo'
,
false
);
unsupported
=
Fake
Device
(
'unsupported'
,
'unsupported'
,
true
,
false
);
webDevice
=
Fake
Device
(
'webby'
,
'webby'
)
..
targetPlatform
=
Future
<
TargetPlatform
>.
value
(
TargetPlatform
.
web_javascript
);
fuchsiaDevice
=
_Mock
Device
(
'fuchsiay'
,
'fuchsiay'
)
fuchsiaDevice
=
Fake
Device
(
'fuchsiay'
,
'fuchsiay'
)
..
targetPlatform
=
Future
<
TargetPlatform
>.
value
(
TargetPlatform
.
fuchsia_x64
);
});
...
...
@@ -182,6 +183,17 @@ void main() {
});
});
});
group
(
'JSON encode devices'
,
()
{
testUsingContext
(
'Consistency of JSON representation'
,
()
async
{
expect
(
// This tests that fakeDevices is a list of tuples where "second" is the
// correct JSON representation of the "first". Actual values are irrelevant
await
Future
.
wait
(
fakeDevices
.
map
((
FakeDeviceJsonData
d
)
=>
d
.
dev
.
toJson
())),
fakeDevices
.
map
((
FakeDeviceJsonData
d
)
=>
d
.
json
)
);
});
});
}
class
TestDeviceManager
extends
DeviceManager
{
...
...
@@ -208,27 +220,4 @@ class TestDeviceManager extends DeviceManager {
}
}
class
_MockDevice
extends
Device
{
_MockDevice
(
this
.
name
,
String
id
,
[
bool
ephemeral
=
true
,
this
.
_isSupported
=
true
])
:
super
(
id
,
platformType:
PlatformType
.
web
,
category:
Category
.
mobile
,
ephemeral:
ephemeral
,
);
final
bool
_isSupported
;
@override
final
String
name
;
@override
Future
<
TargetPlatform
>
targetPlatform
=
Future
<
TargetPlatform
>.
value
(
TargetPlatform
.
android_arm
);
@override
void
noSuchMethod
(
Invocation
invocation
)
=>
super
.
noSuchMethod
(
invocation
);
@override
bool
isSupportedForProject
(
FlutterProject
flutterProject
)
=>
_isSupported
;
}
class
MockProcess
extends
Mock
implements
Process
{}
packages/flutter_tools/test/src/fake_devices.dart
0 → 100644
View file @
d6806392
// Copyright 2014 The Flutter 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:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/project.dart'
;
/// A list of fake devices to test JSON serialization
/// (`Device.toJson()` and `--machine` flag for `devices` command)
List
<
FakeDeviceJsonData
>
fakeDevices
=
<
FakeDeviceJsonData
>[
FakeDeviceJsonData
(
FakeDevice
(
'ephemeral'
,
'ephemeral'
,
true
),
<
String
,
Object
>{
'name'
:
'ephemeral'
,
'id'
:
'ephemeral'
,
'isSupported'
:
true
,
'targetPlatform'
:
'android-arm'
,
'emulator'
:
true
,
'sdk'
:
'Test SDK (1.2.3)'
,
'capabilities'
:
<
String
,
Object
>{
'hotReload'
:
true
,
'hotRestart'
:
true
,
'screenshot'
:
false
,
'fastStart'
:
false
,
'flutterExit'
:
true
,
'hardwareRendering'
:
true
,
'startPaused'
:
true
}
}
),
FakeDeviceJsonData
(
FakeDevice
(
'webby'
,
'webby'
)
..
targetPlatform
=
Future
<
TargetPlatform
>.
value
(
TargetPlatform
.
web_javascript
)
..
sdkNameAndVersion
=
Future
<
String
>.
value
(
'Web SDK (1.2.4)'
),
<
String
,
Object
>{
'name'
:
'webby'
,
'id'
:
'webby'
,
'isSupported'
:
true
,
'targetPlatform'
:
'web-javascript'
,
'emulator'
:
true
,
'sdk'
:
'Web SDK (1.2.4)'
,
'capabilities'
:
<
String
,
Object
>{
'hotReload'
:
true
,
'hotRestart'
:
true
,
'screenshot'
:
false
,
'fastStart'
:
false
,
'flutterExit'
:
true
,
'hardwareRendering'
:
false
,
'startPaused'
:
true
}
}
),
];
/// Fake device to test `devices` command
class
FakeDevice
extends
Device
{
FakeDevice
(
this
.
name
,
String
id
,
[
bool
ephemeral
=
true
,
this
.
_isSupported
=
true
])
:
super
(
id
,
platformType:
PlatformType
.
web
,
category:
Category
.
mobile
,
ephemeral:
ephemeral
,
);
final
bool
_isSupported
;
@override
final
String
name
;
@override
Future
<
TargetPlatform
>
targetPlatform
=
Future
<
TargetPlatform
>.
value
(
TargetPlatform
.
android_arm
);
@override
void
noSuchMethod
(
Invocation
invocation
)
=>
super
.
noSuchMethod
(
invocation
);
@override
bool
isSupportedForProject
(
FlutterProject
flutterProject
)
=>
_isSupported
;
@override
bool
isSupported
()
=>
_isSupported
;
@override
Future
<
bool
>
isLocalEmulator
=
Future
<
bool
>.
value
(
true
);
@override
Future
<
String
>
sdkNameAndVersion
=
Future
<
String
>.
value
(
'Test SDK (1.2.3)'
);
}
/// Combines fake device with its canonical JSON representation
class
FakeDeviceJsonData
{
FakeDeviceJsonData
(
this
.
dev
,
this
.
json
);
final
FakeDevice
dev
;
final
Map
<
String
,
Object
>
json
;
}
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