mirror of
https://github.com/apache/cordova-android.git
synced 2026-04-04 00:02:03 +08:00
refactor: use target SDK of built APK to determine best emulator (#1267)
* refactor(emulator): require emulatorId in emulator.run * refactor: use effective targetSdk to find best emulator
This commit is contained in:
committed by
GitHub
parent
fb36e03aeb
commit
70a1eff705
@@ -23,7 +23,6 @@ const rewire = require('rewire');
|
||||
const which = require('which');
|
||||
|
||||
const CordovaError = require('cordova-common').CordovaError;
|
||||
const check_reqs = require('../../bin/templates/cordova/lib/check_reqs');
|
||||
|
||||
describe('emulator', () => {
|
||||
let emu;
|
||||
@@ -102,17 +101,14 @@ describe('emulator', () => {
|
||||
});
|
||||
|
||||
describe('best_image', () => {
|
||||
let target_mock;
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(emu, 'list_images');
|
||||
target_mock = spyOn(check_reqs, 'get_target').and.returnValue('android-26');
|
||||
});
|
||||
|
||||
it('should return undefined if there are no defined AVDs', () => {
|
||||
emu.list_images.and.returnValue(Promise.resolve([]));
|
||||
|
||||
return emu.best_image().then(best_avd => {
|
||||
return emu.best_image(26).then(best_avd => {
|
||||
expect(best_avd).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -122,31 +118,29 @@ describe('emulator', () => {
|
||||
const second_fake_avd = { name: 'AnotherAVD' };
|
||||
emu.list_images.and.returnValue(Promise.resolve([fake_avd, second_fake_avd]));
|
||||
|
||||
return emu.best_image().then(best_avd => {
|
||||
return emu.best_image(26).then(best_avd => {
|
||||
expect(best_avd).toBe(fake_avd);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the first AVD for the API level that matches the project target', () => {
|
||||
target_mock.and.returnValue('android-25');
|
||||
const fake_avd = { name: 'MyFakeAVD', target: 'Android 7.0 (API level 24)' };
|
||||
const second_fake_avd = { name: 'AnotherAVD', target: 'Android 7.1 (API level 25)' };
|
||||
const third_fake_avd = { name: 'AVDThree', target: 'Android 8.0 (API level 26)' };
|
||||
emu.list_images.and.returnValue(Promise.resolve([fake_avd, second_fake_avd, third_fake_avd]));
|
||||
|
||||
return emu.best_image().then(best_avd => {
|
||||
return emu.best_image(25).then(best_avd => {
|
||||
expect(best_avd).toBe(second_fake_avd);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the AVD with API level that is closest to the project target API level, without going over', () => {
|
||||
target_mock.and.returnValue('android-26');
|
||||
const fake_avd = { name: 'MyFakeAVD', target: 'Android 7.0 (API level 24)' };
|
||||
const second_fake_avd = { name: 'AnotherAVD', target: 'Android 7.1 (API level 25)' };
|
||||
const third_fake_avd = { name: 'AVDThree', target: 'Android 99.0 (API level 134)' };
|
||||
emu.list_images.and.returnValue(Promise.resolve([fake_avd, second_fake_avd, third_fake_avd]));
|
||||
|
||||
return emu.best_image().then(best_avd => {
|
||||
return emu.best_image(26).then(best_avd => {
|
||||
expect(best_avd).toBe(second_fake_avd);
|
||||
});
|
||||
});
|
||||
@@ -160,7 +154,7 @@ describe('emulator', () => {
|
||||
target: 'Android 8.0'
|
||||
}]));
|
||||
|
||||
return emu.best_image().then(best_avd => {
|
||||
return emu.best_image(26).then(best_avd => {
|
||||
expect(best_avd).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -249,23 +243,14 @@ describe('emulator', () => {
|
||||
emu.__set__('which', whichSpy);
|
||||
});
|
||||
|
||||
it('should find an emulator if an id is not specified', () => {
|
||||
spyOn(emu, 'best_image').and.returnValue(Promise.resolve(emulator));
|
||||
|
||||
return emu.start().then(() => {
|
||||
// This is the earliest part in the code where we can hook in and check
|
||||
// the emulator that has been selected.
|
||||
const spawnArgs = execaSpy.calls.argsFor(0);
|
||||
expect(spawnArgs[1]).toContain(emulator.name);
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the specified emulator', () => {
|
||||
spyOn(emu, 'best_image');
|
||||
|
||||
return emu.start(emulator.name).then(() => {
|
||||
expect(emu.best_image).not.toHaveBeenCalled();
|
||||
|
||||
// This is the earliest part in the code where we can hook in and check
|
||||
// the emulator that has been selected.
|
||||
const spawnArgs = execaSpy.calls.argsFor(0);
|
||||
expect(spawnArgs[1]).toContain(emulator.name);
|
||||
});
|
||||
|
||||
@@ -59,17 +59,21 @@ describe('run', () => {
|
||||
emulator: emulatorSpyObj
|
||||
});
|
||||
|
||||
// run needs `this` to behave like an Api instance
|
||||
run.run = run.run.bind({
|
||||
_builder: builders.getBuilder('FakeRootPath')
|
||||
const builder = builders.getBuilder('FakeRootPath');
|
||||
spyOn(builder, 'fetchBuildResults').and.returnValue({
|
||||
buildType: 'debug',
|
||||
apkPaths: ['fake.apk']
|
||||
});
|
||||
|
||||
// run needs `this` to behave like an Api instance
|
||||
run.run = run.run.bind({ _builder: builder });
|
||||
});
|
||||
|
||||
it('should install on target after build', () => {
|
||||
return run.run().then(() => {
|
||||
expect(targetSpyObj.install).toHaveBeenCalledWith(
|
||||
resolvedTarget,
|
||||
{ apkPaths: [], buildType: 'debug' }
|
||||
{ apkPaths: ['fake.apk'], buildType: 'debug' }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,43 +117,52 @@ describe('target', () => {
|
||||
|
||||
describe('resolveToOfflineEmulator', () => {
|
||||
const emuId = 'emulator-5554';
|
||||
let resolveToOfflineEmulator, emulatorSpyObj;
|
||||
let resolveToOfflineEmulator, emulatorSpyObj, getTargetSdkFromApkSpy, buildResults;
|
||||
|
||||
beforeEach(() => {
|
||||
resolveToOfflineEmulator = target.__get__('resolveToOfflineEmulator');
|
||||
|
||||
emulatorSpyObj = jasmine.createSpyObj('emulatorSpy', ['start']);
|
||||
buildResults = { apkPaths: ['fake.apk'] };
|
||||
|
||||
emulatorSpyObj = jasmine.createSpyObj('emulatorSpy', ['start', 'best_image']);
|
||||
emulatorSpyObj.start.and.resolveTo(emuId);
|
||||
emulatorSpyObj.best_image.and.resolveTo();
|
||||
|
||||
getTargetSdkFromApkSpy = jasmine.createSpy('getTargetSdkFromApk').and.resolveTo(99);
|
||||
|
||||
target.__set__({
|
||||
emulator: emulatorSpyObj,
|
||||
isEmulatorName: name => name.startsWith('emu')
|
||||
isEmulatorName: name => name.startsWith('emu'),
|
||||
getTargetSdkFromApk: getTargetSdkFromApkSpy
|
||||
});
|
||||
});
|
||||
|
||||
it('should start an emulator and run on that if none is running', () => {
|
||||
return resolveToOfflineEmulator().then(result => {
|
||||
emulatorSpyObj.best_image.and.resolveTo({ name: 'best-avd' });
|
||||
|
||||
return resolveToOfflineEmulator({ type: 'emulator' }, buildResults).then(result => {
|
||||
expect(result).toEqual({ id: emuId, type: 'emulator' });
|
||||
expect(emulatorSpyObj.start).toHaveBeenCalled();
|
||||
expect(getTargetSdkFromApkSpy).toHaveBeenCalledWith(buildResults.apkPaths[0]);
|
||||
expect(emulatorSpyObj.start).toHaveBeenCalledWith('best-avd');
|
||||
});
|
||||
});
|
||||
|
||||
it('should start named emulator and then run on it if it is specified', () => {
|
||||
return resolveToOfflineEmulator({ id: 'emu3' }).then(result => {
|
||||
return resolveToOfflineEmulator({ id: 'emu3' }, buildResults).then(result => {
|
||||
expect(result).toEqual({ id: emuId, type: 'emulator' });
|
||||
expect(emulatorSpyObj.start).toHaveBeenCalledWith('emu3');
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null if given ID is not an avd name', () => {
|
||||
return resolveToOfflineEmulator({ id: 'dev1' }).then(result => {
|
||||
return resolveToOfflineEmulator({ id: 'dev1' }, buildResults).then(result => {
|
||||
expect(result).toBe(null);
|
||||
expect(emulatorSpyObj.start).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null if given type is not emulator', () => {
|
||||
return resolveToOfflineEmulator({ type: 'device' }).then(result => {
|
||||
return resolveToOfflineEmulator({ type: 'device' }, buildResults).then(result => {
|
||||
expect(result).toBe(null);
|
||||
expect(emulatorSpyObj.start).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -161,7 +170,7 @@ describe('target', () => {
|
||||
});
|
||||
|
||||
describe('resolve', () => {
|
||||
let resolveToOnlineTarget, resolveToOfflineEmulator;
|
||||
let resolveToOnlineTarget, resolveToOfflineEmulator, buildResults;
|
||||
|
||||
beforeEach(() => {
|
||||
resolveToOnlineTarget = jasmine.createSpy('resolveToOnlineTarget')
|
||||
@@ -170,6 +179,8 @@ describe('target', () => {
|
||||
resolveToOfflineEmulator = jasmine.createSpy('resolveToOfflineEmulator')
|
||||
.and.resolveTo(null);
|
||||
|
||||
buildResults = { apkPaths: ['fake.apk'] };
|
||||
|
||||
target.__set__({
|
||||
resolveToOnlineTarget,
|
||||
resolveToOfflineEmulator,
|
||||
@@ -181,7 +192,7 @@ describe('target', () => {
|
||||
const spec = { type: 'device' };
|
||||
resolveToOnlineTarget.and.resolveTo({ id: 'dev1', type: 'device' });
|
||||
|
||||
return target.resolve(spec).then(result => {
|
||||
return target.resolve(spec, buildResults).then(result => {
|
||||
expect(result.id).toBe('dev1');
|
||||
expect(resolveToOnlineTarget).toHaveBeenCalledWith(spec);
|
||||
expect(resolveToOfflineEmulator).not.toHaveBeenCalled();
|
||||
@@ -192,10 +203,10 @@ describe('target', () => {
|
||||
const spec = { type: 'emulator' };
|
||||
resolveToOfflineEmulator.and.resolveTo({ id: 'emu1', type: 'emulator' });
|
||||
|
||||
return target.resolve(spec).then(result => {
|
||||
return target.resolve(spec, buildResults).then(result => {
|
||||
expect(result.id).toBe('emu1');
|
||||
expect(resolveToOnlineTarget).toHaveBeenCalledWith(spec);
|
||||
expect(resolveToOfflineEmulator).toHaveBeenCalledWith(spec);
|
||||
expect(resolveToOfflineEmulator).toHaveBeenCalledWith(spec, buildResults);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -203,7 +214,7 @@ describe('target', () => {
|
||||
const spec = { type: 'device' };
|
||||
resolveToOnlineTarget.and.resolveTo({ id: 'dev1', type: 'device' });
|
||||
|
||||
return target.resolve(spec).then(result => {
|
||||
return target.resolve(spec, buildResults).then(result => {
|
||||
expect(result.arch).toBe('dev1-arch');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user