mirror of
https://github.com/apache/cordova-android.git
synced 2026-05-30 00:00:04 +08:00
refactor: unify installation on devices & emulators (#1123)
* refactor: unify installation on devices & emulators This change replaces the almost identical methods `device.install` and `emulator.install` with the generic `target.install`. * fix: use unified installation in platform-centric bins
This commit is contained in:
committed by
GitHub
parent
aa679ea1d6
commit
bb7d733cde
@@ -103,106 +103,4 @@ describe('device', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('install', () => {
|
||||
let AndroidManifestSpy;
|
||||
let AndroidManifestFns;
|
||||
let AndroidManifestGetActivitySpy;
|
||||
let buildSpy;
|
||||
let target;
|
||||
|
||||
beforeEach(() => {
|
||||
target = { target: DEVICE_LIST[0], arch: 'arm7', isEmulator: false };
|
||||
|
||||
buildSpy = jasmine.createSpyObj('build', ['findBestApkForArchitecture']);
|
||||
device.__set__('build', buildSpy);
|
||||
|
||||
AndroidManifestFns = jasmine.createSpyObj('AndroidManifestFns', ['getPackageId', 'getActivity']);
|
||||
AndroidManifestGetActivitySpy = jasmine.createSpyObj('getActivity', ['getName']);
|
||||
AndroidManifestFns.getActivity.and.returnValue(AndroidManifestGetActivitySpy);
|
||||
AndroidManifestSpy = jasmine.createSpy('AndroidManifest').and.returnValue(AndroidManifestFns);
|
||||
device.__set__('AndroidManifest', AndroidManifestSpy);
|
||||
|
||||
AdbSpy.install.and.returnValue(Promise.resolve());
|
||||
AdbSpy.shell.and.returnValue(Promise.resolve());
|
||||
AdbSpy.start.and.returnValue(Promise.resolve());
|
||||
});
|
||||
|
||||
it('should get the full target object if only id is specified', () => {
|
||||
const targetId = DEVICE_LIST[0];
|
||||
spyOn(device, 'resolveTarget').and.returnValue(Promise.resolve(target));
|
||||
|
||||
return device.install(targetId).then(() => {
|
||||
expect(device.resolveTarget).toHaveBeenCalledWith(targetId);
|
||||
});
|
||||
});
|
||||
|
||||
it('should install to the passed target', () => {
|
||||
return device.install(target).then(() => {
|
||||
expect(AdbSpy.install).toHaveBeenCalledWith(target.target, undefined, jasmine.anything());
|
||||
});
|
||||
});
|
||||
|
||||
it('should install the correct apk based on the architecture and build results', () => {
|
||||
const buildResults = {
|
||||
apkPaths: 'path/to/apks',
|
||||
buildType: 'debug',
|
||||
buildMethod: 'foo'
|
||||
};
|
||||
|
||||
const apkPath = 'my/apk/path/app.apk';
|
||||
buildSpy.findBestApkForArchitecture.and.returnValue(apkPath);
|
||||
|
||||
return device.install(target, buildResults).then(() => {
|
||||
expect(buildSpy.findBestApkForArchitecture).toHaveBeenCalledWith(buildResults, target.arch);
|
||||
expect(AdbSpy.install).toHaveBeenCalledWith(jasmine.anything(), apkPath, jasmine.anything());
|
||||
});
|
||||
});
|
||||
|
||||
it('should uninstall and reinstall app if failure is due to different certificates', () => {
|
||||
AdbSpy.install.and.returnValues(
|
||||
Promise.reject('Failed to install: INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES'),
|
||||
Promise.resolve()
|
||||
);
|
||||
|
||||
AdbSpy.uninstall.and.callFake(() => {
|
||||
expect(AdbSpy.install).toHaveBeenCalledTimes(1);
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
return device.install(target).then(() => {
|
||||
expect(AdbSpy.install).toHaveBeenCalledTimes(2);
|
||||
expect(AdbSpy.uninstall).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw any error not caused by different certificates', () => {
|
||||
const errorMsg = new CordovaError('Failed to install');
|
||||
AdbSpy.install.and.returnValues(Promise.reject(errorMsg));
|
||||
|
||||
return device.install(target).then(
|
||||
() => fail('Unexpectedly resolved'),
|
||||
err => {
|
||||
expect(err).toBe(errorMsg);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should unlock the screen on device', () => {
|
||||
return device.install(target).then(() => {
|
||||
expect(AdbSpy.shell).toHaveBeenCalledWith(target.target, 'input keyevent 82');
|
||||
});
|
||||
});
|
||||
|
||||
it('should start the newly installed app on the device', () => {
|
||||
const packageId = 'unittestapp';
|
||||
const activityName = 'TestActivity';
|
||||
AndroidManifestFns.getPackageId.and.returnValue(packageId);
|
||||
AndroidManifestGetActivitySpy.getName.and.returnValue(activityName);
|
||||
|
||||
return device.install(target).then(() => {
|
||||
expect(AdbSpy.start).toHaveBeenCalledWith(target.target, `${packageId}/.${activityName}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -575,107 +575,4 @@ describe('emulator', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('install', () => {
|
||||
let AndroidManifestSpy;
|
||||
let AndroidManifestFns;
|
||||
let AndroidManifestGetActivitySpy;
|
||||
let AdbSpy;
|
||||
let buildSpy;
|
||||
let target;
|
||||
|
||||
beforeEach(() => {
|
||||
target = { target: EMULATOR_LIST[1], arch: 'arm7', isEmulator: true };
|
||||
|
||||
buildSpy = jasmine.createSpyObj('build', ['findBestApkForArchitecture']);
|
||||
emu.__set__('build', buildSpy);
|
||||
|
||||
AndroidManifestFns = jasmine.createSpyObj('AndroidManifestFns', ['getPackageId', 'getActivity']);
|
||||
AndroidManifestGetActivitySpy = jasmine.createSpyObj('getActivity', ['getName']);
|
||||
AndroidManifestFns.getActivity.and.returnValue(AndroidManifestGetActivitySpy);
|
||||
AndroidManifestSpy = jasmine.createSpy('AndroidManifest').and.returnValue(AndroidManifestFns);
|
||||
emu.__set__('AndroidManifest', AndroidManifestSpy);
|
||||
|
||||
AdbSpy = jasmine.createSpyObj('Adb', ['shell', 'start', 'install', 'uninstall']);
|
||||
AdbSpy.shell.and.returnValue(Promise.resolve());
|
||||
AdbSpy.start.and.returnValue(Promise.resolve());
|
||||
AdbSpy.install.and.returnValue(Promise.resolve());
|
||||
AdbSpy.uninstall.and.returnValue(Promise.resolve());
|
||||
emu.__set__('Adb', AdbSpy);
|
||||
});
|
||||
|
||||
it('should get the full target object if only id is specified', () => {
|
||||
const targetId = target.target;
|
||||
spyOn(emu, 'resolveTarget').and.returnValue(Promise.resolve(target));
|
||||
|
||||
return emu.install(targetId, {}).then(() => {
|
||||
expect(emu.resolveTarget).toHaveBeenCalledWith(targetId);
|
||||
});
|
||||
});
|
||||
|
||||
it('should install to the passed target', () => {
|
||||
return emu.install(target, {}).then(() => {
|
||||
expect(AdbSpy.install.calls.argsFor(0)[0]).toBe(target.target);
|
||||
});
|
||||
});
|
||||
|
||||
it('should install the correct apk based on the architecture and build results', () => {
|
||||
const buildResults = {
|
||||
apkPaths: 'path/to/apks',
|
||||
buildType: 'debug',
|
||||
buildMethod: 'foo'
|
||||
};
|
||||
|
||||
const apkPath = 'my/apk/path/app.apk';
|
||||
buildSpy.findBestApkForArchitecture.and.returnValue(apkPath);
|
||||
|
||||
return emu.install(target, buildResults).then(() => {
|
||||
expect(buildSpy.findBestApkForArchitecture).toHaveBeenCalledWith(buildResults, target.arch);
|
||||
|
||||
expect(AdbSpy.install.calls.argsFor(0)[1]).toBe(apkPath);
|
||||
});
|
||||
});
|
||||
|
||||
it('should uninstall and reinstall app if failure is due to different certificates', () => {
|
||||
AdbSpy.install.and.returnValues(
|
||||
Promise.reject('Failure: INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES'),
|
||||
Promise.resolve()
|
||||
);
|
||||
|
||||
return emu.install(target, {}).then(() => {
|
||||
expect(AdbSpy.install).toHaveBeenCalledTimes(2);
|
||||
expect(AdbSpy.uninstall).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw any error not caused by different certificates', () => {
|
||||
const errorMsg = 'Failure: Failed to install';
|
||||
AdbSpy.install.and.rejectWith(new CordovaError(errorMsg));
|
||||
|
||||
return emu.install(target, {}).then(
|
||||
() => fail('Unexpectedly resolved'),
|
||||
err => {
|
||||
expect(err).toEqual(jasmine.any(CordovaError));
|
||||
expect(err.message).toContain(errorMsg);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should unlock the screen on device', () => {
|
||||
return emu.install(target, {}).then(() => {
|
||||
expect(AdbSpy.shell).toHaveBeenCalledWith(target.target, 'input keyevent 82');
|
||||
});
|
||||
});
|
||||
|
||||
it('should start the newly installed app on the device', () => {
|
||||
const packageId = 'unittestapp';
|
||||
const activityName = 'TestActivity';
|
||||
AndroidManifestFns.getPackageId.and.returnValue(packageId);
|
||||
AndroidManifestGetActivitySpy.getName.and.returnValue(activityName);
|
||||
|
||||
return emu.install(target, {}).then(() => {
|
||||
expect(AdbSpy.start).toHaveBeenCalledWith(target.target, `${packageId}/.${activityName}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,18 +45,23 @@ describe('run', () => {
|
||||
describe('run method', () => {
|
||||
let deviceSpyObj;
|
||||
let emulatorSpyObj;
|
||||
let targetSpyObj;
|
||||
let eventsSpyObj;
|
||||
let getInstallTargetSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
deviceSpyObj = jasmine.createSpyObj('deviceSpy', ['install', 'list', 'resolveTarget']);
|
||||
emulatorSpyObj = jasmine.createSpyObj('emulatorSpy', ['install', 'list_images', 'list_started', 'resolveTarget', 'start', 'wait_for_boot']);
|
||||
deviceSpyObj = jasmine.createSpyObj('deviceSpy', ['list', 'resolveTarget']);
|
||||
emulatorSpyObj = jasmine.createSpyObj('emulatorSpy', ['list_images', 'list_started', 'resolveTarget', 'start', 'wait_for_boot']);
|
||||
eventsSpyObj = jasmine.createSpyObj('eventsSpy', ['emit']);
|
||||
getInstallTargetSpy = jasmine.createSpy('getInstallTargetSpy');
|
||||
|
||||
targetSpyObj = jasmine.createSpyObj('target', ['install']);
|
||||
targetSpyObj.install.and.resolveTo();
|
||||
|
||||
run.__set__({
|
||||
device: deviceSpyObj,
|
||||
emulator: emulatorSpyObj,
|
||||
target: targetSpyObj,
|
||||
events: eventsSpyObj,
|
||||
getInstallTarget: getInstallTargetSpy
|
||||
});
|
||||
@@ -187,7 +192,7 @@ describe('run', () => {
|
||||
deviceSpyObj.resolveTarget.and.returnValue(deviceTarget);
|
||||
|
||||
return run.run().then(() => {
|
||||
expect(deviceSpyObj.install).toHaveBeenCalledWith(deviceTarget, { apkPaths: [], buildType: 'debug' });
|
||||
expect(targetSpyObj.install).toHaveBeenCalledWith(deviceTarget, { apkPaths: [], buildType: 'debug' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -199,7 +204,7 @@ describe('run', () => {
|
||||
emulatorSpyObj.wait_for_boot.and.returnValue(Promise.resolve());
|
||||
|
||||
return run.run().then(() => {
|
||||
expect(emulatorSpyObj.install).toHaveBeenCalledWith(emulatorTarget, { apkPaths: [], buildType: 'debug' });
|
||||
expect(targetSpyObj.install).toHaveBeenCalledWith(emulatorTarget, { apkPaths: [], buildType: 'debug' });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
const rewire = require('rewire');
|
||||
const { CordovaError } = require('cordova-common');
|
||||
|
||||
describe('target', () => {
|
||||
let target;
|
||||
|
||||
beforeEach(() => {
|
||||
target = rewire('../../bin/templates/cordova/lib/target');
|
||||
});
|
||||
|
||||
describe('install', () => {
|
||||
let AndroidManifestSpy;
|
||||
let AndroidManifestFns;
|
||||
let AndroidManifestGetActivitySpy;
|
||||
let AdbSpy;
|
||||
let buildSpy;
|
||||
let installTarget;
|
||||
|
||||
beforeEach(() => {
|
||||
installTarget = { target: 'emulator-5556', isEmulator: true, arch: 'atari' };
|
||||
|
||||
buildSpy = jasmine.createSpyObj('build', ['findBestApkForArchitecture']);
|
||||
target.__set__('build', buildSpy);
|
||||
|
||||
AndroidManifestFns = jasmine.createSpyObj('AndroidManifestFns', ['getPackageId', 'getActivity']);
|
||||
AndroidManifestGetActivitySpy = jasmine.createSpyObj('getActivity', ['getName']);
|
||||
AndroidManifestFns.getActivity.and.returnValue(AndroidManifestGetActivitySpy);
|
||||
AndroidManifestSpy = jasmine.createSpy('AndroidManifest').and.returnValue(AndroidManifestFns);
|
||||
target.__set__('AndroidManifest', AndroidManifestSpy);
|
||||
|
||||
AdbSpy = jasmine.createSpyObj('Adb', ['shell', 'start', 'install', 'uninstall']);
|
||||
AdbSpy.shell.and.returnValue(Promise.resolve());
|
||||
AdbSpy.start.and.returnValue(Promise.resolve());
|
||||
AdbSpy.install.and.returnValue(Promise.resolve());
|
||||
AdbSpy.uninstall.and.returnValue(Promise.resolve());
|
||||
target.__set__('Adb', AdbSpy);
|
||||
|
||||
// Silence output during test
|
||||
spyOn(target.__get__('events'), 'emit');
|
||||
});
|
||||
|
||||
it('should install to the passed target', () => {
|
||||
return target.install(installTarget, {}).then(() => {
|
||||
expect(AdbSpy.install.calls.argsFor(0)[0]).toBe(installTarget.target);
|
||||
});
|
||||
});
|
||||
|
||||
it('should install the correct apk based on the architecture and build results', () => {
|
||||
const buildResults = {
|
||||
apkPaths: 'path/to/apks',
|
||||
buildType: 'debug',
|
||||
buildMethod: 'foo'
|
||||
};
|
||||
|
||||
const apkPath = 'my/apk/path/app.apk';
|
||||
buildSpy.findBestApkForArchitecture.and.returnValue(apkPath);
|
||||
|
||||
return target.install(installTarget, buildResults).then(() => {
|
||||
expect(buildSpy.findBestApkForArchitecture).toHaveBeenCalledWith(buildResults, installTarget.arch);
|
||||
|
||||
expect(AdbSpy.install.calls.argsFor(0)[1]).toBe(apkPath);
|
||||
});
|
||||
});
|
||||
|
||||
it('should uninstall and reinstall app if failure is due to different certificates', () => {
|
||||
AdbSpy.install.and.returnValues(
|
||||
Promise.reject('Failure: INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES'),
|
||||
Promise.resolve()
|
||||
);
|
||||
|
||||
return target.install(installTarget, {}).then(() => {
|
||||
expect(AdbSpy.install).toHaveBeenCalledTimes(2);
|
||||
expect(AdbSpy.uninstall).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw any error not caused by different certificates', () => {
|
||||
const errorMsg = 'Failure: Failed to install';
|
||||
AdbSpy.install.and.rejectWith(new CordovaError(errorMsg));
|
||||
|
||||
return target.install(installTarget, {}).then(
|
||||
() => fail('Unexpectedly resolved'),
|
||||
err => {
|
||||
expect(err).toEqual(jasmine.any(CordovaError));
|
||||
expect(err.message).toContain(errorMsg);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should unlock the screen on device', () => {
|
||||
return target.install(installTarget, {}).then(() => {
|
||||
expect(AdbSpy.shell).toHaveBeenCalledWith(installTarget.target, 'input keyevent 82');
|
||||
});
|
||||
});
|
||||
|
||||
it('should start the newly installed app on the device', () => {
|
||||
const packageId = 'unittestapp';
|
||||
const activityName = 'TestActivity';
|
||||
AndroidManifestFns.getPackageId.and.returnValue(packageId);
|
||||
AndroidManifestGetActivitySpy.getName.and.returnValue(activityName);
|
||||
|
||||
return target.install(installTarget, {}).then(() => {
|
||||
expect(AdbSpy.start).toHaveBeenCalledWith(installTarget.target, `${packageId}/.${activityName}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user