@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/platform.dart';
1111import 'package:flutter_tools/src/cache.dart' ;
1212import 'package:flutter_tools/src/commands/attach.dart' ;
1313import 'package:flutter_tools/src/device.dart' ;
14+ import 'package:flutter_tools/src/resident_runner.dart' ;
1415import 'package:flutter_tools/src/run_hot.dart' ;
1516import 'package:mockito/mockito.dart' ;
1617
@@ -25,48 +26,132 @@ void main() {
2526 .posix,
2627 );
2728
28- setUpAll (() {
29+ setUp (() {
2930 Cache .disableLocking ();
3031 testFileSystem.directory ('lib' ).createSync ();
3132 testFileSystem.file ('lib/main.dart' ).createSync ();
3233 });
3334
34- testUsingContext ( 'finds observatory port and forwards ' , () async {
35+ group ( 'with one device and no specified target file ' , () {
3536 const int devicePort = 499 ;
3637 const int hostPort = 42 ;
37- final MockDeviceLogReader mockLogReader = new MockDeviceLogReader ();
38- final MockPortForwarder portForwarder = new MockPortForwarder ();
39- final MockAndroidDevice device = new MockAndroidDevice ();
40- when (device.getLogReader ()).thenAnswer ((_) {
41- // Now that the reader is used, start writing messages to it.
42- Timer .run (() {
43- mockLogReader.addLine ('Foo' );
44- mockLogReader.addLine (
45- 'Observatory listening on http://127.0.0.1:$devicePort ' );
38+
39+ MockDeviceLogReader mockLogReader;
40+ MockPortForwarder portForwarder;
41+ MockAndroidDevice device;
42+
43+ setUp (() {
44+ mockLogReader = new MockDeviceLogReader ();
45+ portForwarder = new MockPortForwarder ();
46+ device = new MockAndroidDevice ();
47+ when (device.getLogReader ()).thenAnswer ((_) {
48+ // Now that the reader is used, start writing messages to it.
49+ Timer .run (() {
50+ mockLogReader.addLine ('Foo' );
51+ mockLogReader.addLine (
52+ 'Observatory listening on http://127.0.0.1:$devicePort ' );
53+ });
54+
55+ return mockLogReader;
4656 });
57+ when (device.portForwarder).thenReturn (portForwarder);
58+ when (portForwarder.forward (devicePort, hostPort: anyNamed ('hostPort' )))
59+ .thenAnswer ((_) async => hostPort);
60+ when (portForwarder.forwardedPorts).thenReturn (
61+ < ForwardedPort > [new ForwardedPort (hostPort, devicePort)]);
62+ when (portForwarder.unforward (any)).thenAnswer ((_) async => null );
4763
48- return mockLogReader;
64+ // We cannot add the device to a device manager because that is
65+ // only enabled by the context of each testUsingContext call.
66+ //
67+ // Instead each test will add the device to the device manager
68+ // on its own.
4969 });
50- when (device.portForwarder).thenReturn (portForwarder);
51- when (portForwarder.forward (devicePort, hostPort: anyNamed ('hostPort' )))
52- .thenAnswer ((_) async => hostPort);
53- when (portForwarder.forwardedPorts).thenReturn (
54- < ForwardedPort > [new ForwardedPort (hostPort, devicePort)]);
55- when (portForwarder.unforward (any)).thenAnswer ((_) async => null );
56- testDeviceManager.addDevice (device);
5770
58- final AttachCommand command = new AttachCommand ();
71+ tearDown (() {
72+ mockLogReader.dispose ();
73+ });
5974
60- await createTestCommandRunner (command).run (< String > ['attach' ]);
75+ testUsingContext ('finds observatory port and forwards' , () async {
76+ testDeviceManager.addDevice (device);
6177
62- verify (portForwarder.forward (devicePort, hostPort: anyNamed ('hostPort' )))
63- .called (1 );
78+ final AttachCommand command = new AttachCommand ();
79+
80+ await createTestCommandRunner (command).run (< String > ['attach' ]);
81+
82+ verify (
83+ portForwarder.forward (devicePort, hostPort: anyNamed ('hostPort' )),
84+ ).called (1 );
85+ }, overrides: < Type , Generator > {
86+ FileSystem : () => testFileSystem,
87+ });
88+
89+ testUsingContext ('accepts filesystem parameters' , () async {
90+ testDeviceManager.addDevice (device);
91+
92+ const String filesystemScheme = 'foo' ;
93+ const String filesystemRoot = '/build-output/' ;
94+ const String projectRoot = '/build-output/project-root' ;
95+ const String outputDill = '/tmp/output.dill' ;
96+
97+ final MockHotRunnerFactory mockHotRunnerFactory = new MockHotRunnerFactory ();
98+ when (
99+ mockHotRunnerFactory.build (
100+ any,
101+ target: anyNamed ('target' ),
102+ projectRootPath: anyNamed ('projectRootPath' ),
103+ dillOutputPath: anyNamed ('dillOutputPath' ),
104+ debuggingOptions: anyNamed ('debuggingOptions' ),
105+ packagesFilePath: anyNamed ('packagesFilePath' ),
106+ usesTerminalUI: anyNamed ('usesTerminalUI' ),
107+ ),
108+ )..thenReturn (new MockHotRunner ());
109+
110+ final AttachCommand command = new AttachCommand (
111+ hotRunnerFactory: mockHotRunnerFactory,
112+ );
113+ await createTestCommandRunner (command).run (< String > [
114+ 'attach' ,
115+ '--filesystem-scheme' ,
116+ filesystemScheme,
117+ '--filesystem-root' ,
118+ filesystemRoot,
119+ '--project-root' ,
120+ projectRoot,
121+ '--output-dill' ,
122+ outputDill,
123+ '-v' ,
124+ ]);
125+
126+ // Validate the attach call built a mock runner with the right
127+ // project root and output dill.
128+ final VerificationResult verificationResult = verify (
129+ mockHotRunnerFactory.build (
130+ captureAny,
131+ target: anyNamed ('target' ),
132+ projectRootPath: projectRoot,
133+ dillOutputPath: outputDill,
134+ debuggingOptions: anyNamed ('debuggingOptions' ),
135+ packagesFilePath: anyNamed ('packagesFilePath' ),
136+ usesTerminalUI: anyNamed ('usesTerminalUI' ),
137+ ),
138+ )..called (1 );
139+
140+ final List <FlutterDevice > flutterDevices = verificationResult.captured.first;
141+ expect (flutterDevices, hasLength (1 ));
142+
143+ // Validate that the attach call built a flutter device with the right
144+ // output dill, filesystem scheme, and filesystem root.
145+ final FlutterDevice flutterDevice = flutterDevices.first;
146+
147+ expect (flutterDevice.dillOutputPath, outputDill);
148+ expect (flutterDevice.fileSystemScheme, filesystemScheme);
149+ expect (flutterDevice.fileSystemRoots, const < String > [filesystemRoot]);
150+ }, overrides: < Type , Generator > {
151+ FileSystem : () => testFileSystem,
152+ });
153+ });
64154
65- mockLogReader.dispose ();
66- }, overrides: < Type , Generator > {
67- FileSystem : () => testFileSystem,
68- },
69- );
70155
71156 testUsingContext ('selects specified target' , () async {
72157 const int devicePort = 499 ;
@@ -102,6 +187,9 @@ void main() {
102187 final File foo = fs.file ('lib/foo.dart' )
103188 ..createSync ();
104189
190+ // Delete the main.dart file to be sure that attach works without it.
191+ fs.file ('lib/main.dart' ).deleteSync ();
192+
105193 final AttachCommand command = new AttachCommand (
106194 hotRunnerFactory: mockHotRunnerFactory);
107195 await createTestCommandRunner (command).run (
0 commit comments