feat(shorebird_cli): add Adb (#825)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user