2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ import 'dart:async' ;
6
+ import 'dart:convert' ;
7
+ import 'dart:io' ;
8
+ import 'dart:typed_data' ;
9
+
5
10
import 'package:collection/collection.dart' show ListEquality, MapEquality;
6
11
7
12
import 'package:flutter_devicelab/framework/devices.dart' ;
@@ -18,8 +23,7 @@ void main() {
18
23
device = FakeDevice (deviceId: 'fakeDeviceId' );
19
24
});
20
25
21
- tearDown (() {
22
- });
26
+ tearDown (() {});
23
27
24
28
group ('cpu check' , () {
25
29
test ('arm64' , () async {
@@ -119,12 +123,80 @@ void main() {
119
123
120
124
group ('adb' , () {
121
125
test ('tap' , () async {
126
+ FakeDevice .resetLog ();
122
127
await device.tap (100 , 200 );
123
128
expectLog (< CommandArgs > [
124
- cmd (command: 'getprop' , arguments: < String > ['ro.bootimage.build.fingerprint' , ';' , 'getprop' , 'ro.build.version.release' , ';' , 'getprop' , 'ro.build.version.sdk' ]),
125
129
cmd (command: 'input' , arguments: < String > ['tap' , '100' , '200' ]),
126
130
]);
127
131
});
132
+
133
+ test ('awaitDevice' , () async {
134
+ FakeDevice .resetLog ();
135
+ // The expected value from `adb shell getprop sys.boot_completed`
136
+ FakeDevice .output = '1' ;
137
+ await device.awaitDevice ();
138
+ expectLog (< CommandArgs > [
139
+ cmd (command: 'adb' , environment: < String , String > {
140
+ FakeDevice .canFailKey: 'false'
141
+ }, arguments: < String > [
142
+ '-s' ,
143
+ device.deviceId,
144
+ 'wait-for-device' ,
145
+ ]),
146
+ cmd (command: 'adb' , environment: < String , String > {
147
+ FakeDevice .canFailKey: 'false' ,
148
+ }, arguments: < String > [
149
+ '-s' ,
150
+ device.deviceId,
151
+ 'shell' ,
152
+ 'getprop sys.boot_completed' ,
153
+ ])
154
+ ]);
155
+ });
156
+
157
+ test ('reboot' , () async {
158
+ FakeDevice .resetLog ();
159
+ await device.reboot ();
160
+ expectLog (< CommandArgs > [
161
+ cmd (command: 'adb' , environment: < String , String > {
162
+ FakeDevice .canFailKey: 'false'
163
+ }, arguments: < String > [
164
+ '-s' ,
165
+ device.deviceId,
166
+ 'reboot' ,
167
+ ]),
168
+ ]);
169
+ });
170
+
171
+ test ('clearLog' , () async {
172
+ FakeDevice .resetLog ();
173
+ await device.clearLogs ();
174
+ expectLog (< CommandArgs > [
175
+ cmd (command: 'adb' , environment: < String , String > {
176
+ FakeDevice .canFailKey: 'true'
177
+ }, arguments: < String > [
178
+ '-s' ,
179
+ device.deviceId,
180
+ 'logcat' ,
181
+ '-c' ,
182
+ ]),
183
+ ]);
184
+ });
185
+
186
+ test ('startLoggingToSink calls adb' , () async {
187
+ FakeDevice .resetLog ();
188
+ await device.startLoggingToSink (IOSink (_MemoryIOSink ()));
189
+ expectLog (< CommandArgs > [
190
+ cmd (command: 'adb' , environment: < String , String > {
191
+ FakeDevice .canFailKey: 'true'
192
+ }, arguments: < String > [
193
+ '-s' ,
194
+ device.deviceId,
195
+ 'logcat' ,
196
+ '--clear' ,
197
+ ]),
198
+ ]);
199
+ });
128
200
});
129
201
});
130
202
}
@@ -181,6 +253,8 @@ class CommandArgs {
181
253
class FakeDevice extends AndroidDevice {
182
254
FakeDevice ({required super .deviceId});
183
255
256
+ static const String canFailKey = 'canFail' ;
257
+
184
258
static String output = '' ;
185
259
186
260
static List <CommandArgs > commandLog = < CommandArgs > [];
@@ -213,6 +287,21 @@ class FakeDevice extends AndroidDevice {
213
287
''' ;
214
288
}
215
289
290
+ @override
291
+ Future <String > adb (List <String > arguments,
292
+ {Map <String , String >? environment,
293
+ bool silent = false ,
294
+ bool canFail = false }) async {
295
+ environment ?? = < String , String > {};
296
+ commandLog.add (CommandArgs (
297
+ command: 'adb' ,
298
+ // ignore: prefer_spread_collections
299
+ arguments: < String > ['-s' , deviceId]..addAll (arguments),
300
+ environment: environment..putIfAbsent ('canFail' , () => '$canFail ' ),
301
+ ));
302
+ return output;
303
+ }
304
+
216
305
@override
217
306
Future <String > shellEval (String command, List <String > arguments, { Map <String , String >? environment, bool silent = false }) async {
218
307
commandLog.add (CommandArgs (
@@ -232,3 +321,65 @@ class FakeDevice extends AndroidDevice {
232
321
));
233
322
}
234
323
}
324
+
325
+ /// An IOSink that collects whatever is written to it.
326
+ /// Inspired by packages/flutter_tools/lib/src/base/net.dart
327
+ class _MemoryIOSink implements IOSink {
328
+ @override
329
+ Encoding encoding = utf8;
330
+
331
+ final BytesBuilder writes = BytesBuilder (copy: false );
332
+
333
+ @override
334
+ void add (List <int > data) {
335
+ writes.add (data);
336
+ }
337
+
338
+ @override
339
+ Future <void > addStream (Stream <List <int >> stream) {
340
+ final Completer <void > completer = Completer <void >();
341
+ stream.listen (add).onDone (completer.complete);
342
+ return completer.future;
343
+ }
344
+
345
+ @override
346
+ void writeCharCode (int charCode) {
347
+ add (< int > [charCode]);
348
+ }
349
+
350
+ @override
351
+ void write (Object ? obj) {
352
+ add (encoding.encode ('$obj ' ));
353
+ }
354
+
355
+ @override
356
+ void writeln ([Object ? obj = '' ]) {
357
+ add (encoding.encode ('$obj \n ' ));
358
+ }
359
+
360
+ @override
361
+ void writeAll (Iterable <dynamic > objects, [String separator = '' ]) {
362
+ bool addSeparator = false ;
363
+ for (final dynamic object in objects) {
364
+ if (addSeparator) {
365
+ write (separator);
366
+ }
367
+ write (object);
368
+ addSeparator = true ;
369
+ }
370
+ }
371
+
372
+ @override
373
+ void addError (dynamic error, [StackTrace ? stackTrace]) {
374
+ throw UnimplementedError ();
375
+ }
376
+
377
+ @override
378
+ Future <void > get done => close ();
379
+
380
+ @override
381
+ Future <void > close () async {}
382
+
383
+ @override
384
+ Future <void > flush () async {}
385
+ }
0 commit comments