feat(shorebird_cli): add Adb (#825)

This commit is contained in:
Felix Angelov
2023-07-11 15:13:20 -04:00
committed by GitHub
parent eb545110f2
commit cc0e7bf658
4 changed files with 125 additions and 0 deletions
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:scoped/scoped.dart';
import 'package:shorebird_cli/src/android_sdk.dart';
import 'package:shorebird_cli/src/android_studio.dart';
import 'package:shorebird_cli/src/auth/auth.dart';
import 'package:shorebird_cli/src/bundletool.dart';
@@ -17,6 +18,7 @@ Future<void> main(List<String> args) async {
await runScoped(
() async => ShorebirdCliCommandRunner().run(args),
values: {
androidSdkRef,
androidStudioRef,
authRef,
bundletoolRef,
+20
View File
@@ -0,0 +1,20 @@
import 'package:shorebird_cli/src/android_sdk.dart';
import 'package:shorebird_cli/src/process.dart';
/// A wrapper around the `adb` command.
class Adb {
Future<ShorebirdProcessResult> _exec(String command) async {
final adbPath = androidSdk.adbPath;
if (adbPath == null) throw Exception('Unable to locate adb.');
return process.run(adbPath, command.split(' '));
}
/// Starts the app with the given [package] name.
Future<void> startApp(String package) async {
final result = await _exec('shell monkey -p $package 1');
if (result.exitCode != 0) {
throw Exception('Unable to start app: ${result.stderr}');
}
}
}
@@ -2,12 +2,19 @@ import 'dart:io';
import 'package:collection/collection.dart';
import 'package:path/path.dart' as p;
import 'package:scoped/scoped.dart';
import 'package:shorebird_cli/src/platform.dart';
// https://developer.android.com/studio/command-line/variables.html#envar
const kAndroidHome = 'ANDROID_HOME';
const kAndroidSdkRoot = 'ANDROID_SDK_ROOT';
/// A reference to a [AndroidSdk] instance.
final androidSdkRef = create(AndroidSdk.new);
/// The [AndroidSdk] instance available in the current zone.
AndroidSdk get androidSdk => read(androidSdkRef);
/// A wrapper around Android SDK.
class AndroidSdk {
/// The path to the Android SDK installation.
@@ -0,0 +1,96 @@
import 'package:mocktail/mocktail.dart';
import 'package:scoped/scoped.dart';
import 'package:shorebird_cli/src/adb.dart';
import 'package:shorebird_cli/src/android_sdk.dart';
import 'package:shorebird_cli/src/process.dart';
import 'package:test/test.dart';
class _MockAndroidSdk extends Mock implements AndroidSdk {}
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
void main() {
group(Adb, () {
const adbPath = '/path/to/adb';
late AndroidSdk androidSdk;
late ShorebirdProcess process;
late Adb adb;
R runWithOverrides<R>(R Function() body) {
return runScoped(
() => body(),
values: {
androidSdkRef.overrideWith(() => androidSdk),
processRef.overrideWith(() => process),
},
);
}
setUp(() {
androidSdk = _MockAndroidSdk();
process = _MockShorebirdProcess();
adb = Adb();
when(() => androidSdk.adbPath).thenReturn(adbPath);
when(
() => process.run(any(), any()),
).thenAnswer(
(_) async => const ShorebirdProcessResult(
exitCode: 0,
stdout: '',
stderr: '',
),
);
});
group('startApp', () {
const package = 'com.example.app';
test('throws when unable to locate adb', () async {
when(() => androidSdk.adbPath).thenReturn(null);
await expectLater(
() => runWithOverrides(() => adb.startApp(package)),
throwsA(
isA<Exception>().having(
(e) => e.toString(),
'exception()',
contains('Unable to locate adb'),
),
),
);
});
test('throws process exits with non-zero exit code', () async {
when(
() => process.run(any(), any()),
).thenAnswer(
(_) async => const ShorebirdProcessResult(
exitCode: 1,
stdout: '',
stderr: 'oops',
),
);
await expectLater(
() => runWithOverrides(() => adb.startApp(package)),
throwsA(
isA<Exception>().having(
(e) => e.toString(),
'exception()',
contains('Unable to start app: oops'),
),
),
);
});
test('completes when process exits with 0', () async {
await expectLater(
runWithOverrides(() => adb.startApp(package)),
completes,
);
verify(
() => process.run(adbPath, 'shell monkey -p $package 1'.split(' ')),
).called(1);
});
});
});
}