// 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/android/android_device.dart'; import 'package:mockito/mockito.dart'; import '../../src/common.dart'; import '../../src/context.dart'; const int kLollipopVersionCode = 21; const String kLastLogcatTimestamp = '11-27 15:39:04.506'; void main() { testWithoutContext('AdbLogReader calls adb logcat with expected flags apiVersion 21', () async { final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ const FakeCommand( command: <String>[ 'adb', '-s', '1234', 'logcat', '-v', 'time', '-T', kLastLogcatTimestamp, ], ) ]); await AdbLogReader.createLogReader( createMockDevice(kLollipopVersionCode), processManager, ); expect(processManager.hasRemainingExpectations, false); }); testWithoutContext('AdbLogReader calls adb logcat with expected flags apiVersion < 21', () async { final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ const FakeCommand( command: <String>[ 'adb', '-s', '1234', 'logcat', '-v', 'time', ], ) ]); await AdbLogReader.createLogReader( createMockDevice(kLollipopVersionCode - 1), processManager, ); expect(processManager.hasRemainingExpectations, false); }); testWithoutContext('AdbLogReader calls adb logcat with expected flags null apiVersion', () async { final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ const FakeCommand( command: <String>[ 'adb', '-s', '1234', 'logcat', '-v', 'time', ], ) ]); await AdbLogReader.createLogReader( createMockDevice(null), processManager, ); expect(processManager.hasRemainingExpectations, false); }); testWithoutContext('AdbLogReader calls adb logcat with expected flags when requesting past logs', () async { final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ const FakeCommand( command: <String>[ 'adb', '-s', '1234', 'logcat', '-v', 'time', '-s', 'flutter', ], ) ]); await AdbLogReader.createLogReader( createMockDevice(null), processManager, includePastLogs: true, ); expect(processManager.hasRemainingExpectations, false); }); testWithoutContext('AdbLogReader handles process early exit', () async { final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ FakeCommand( command: const <String>[ 'adb', '-s', '1234', 'logcat', '-v', 'time', ], completer: Completer<void>.sync(), stdout: 'Hello There\n', ) ]); final AdbLogReader logReader = await AdbLogReader.createLogReader( createMockDevice(null), processManager, ); final Completer<void> onDone = Completer<void>.sync(); logReader.logLines.listen((String _) { }, onDone: onDone.complete); logReader.dispose(); await onDone.future; }); } MockAndroidDevice createMockDevice(int sdkLevel) { final MockAndroidDevice mockAndroidDevice = MockAndroidDevice(); when(mockAndroidDevice.apiVersion) .thenAnswer((Invocation invocation) async => sdkLevel.toString()); when(mockAndroidDevice.lastLogcatTimestamp).thenReturn(kLastLogcatTimestamp); when(mockAndroidDevice.adbCommandForDevice(any)) .thenAnswer((Invocation invocation) => <String>[ 'adb', '-s', '1234', ...invocation.positionalArguments.first as List<String> ]); return mockAndroidDevice; } class MockAndroidDevice extends Mock implements AndroidDevice {}