mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-20 23:56:20 +08:00
CB-12546: more specs for android_sdk and check_reqs. added fixtures for sdk targets. refactored target listing.
This commit is contained in:
parent
f7687a2567
commit
3554267adf
77
bin/templates/cordova/lib/android_sdk.js
vendored
77
bin/templates/cordova/lib/android_sdk.js
vendored
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
@ -44,51 +44,68 @@ module.exports.version_string_to_api_level = {
|
||||
'7.1.1': 25
|
||||
};
|
||||
|
||||
module.exports.list_targets = function() {
|
||||
module.exports.list_targets_with_android = function() {
|
||||
return superspawn.spawn('android', ['list', 'targets'])
|
||||
.then(function(stdout) {
|
||||
var target_out = stdout.split('\n');
|
||||
var targets = [];
|
||||
for (var i = target_out.length; i >= 0; i--) {
|
||||
for (var i = target_out.length - 1; i >= 0; i--) {
|
||||
if(target_out[i].match(/id:/)) {
|
||||
targets.push(targets[i].split(' ')[1]);
|
||||
targets.push(target_out[i].match(/"(.+)"/)[1]);
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}).catch(function(err) {
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.list_targets_with_sdkmanager = function() {
|
||||
return superspawn.spawn('sdkmanager', ['--list'])
|
||||
.then(function(stdout) {
|
||||
var parsing_installed_packages = false;
|
||||
var lines = stdout.split('\n');
|
||||
var targets = [];
|
||||
for (var i = 0, l = lines.length; i < l; i++) {
|
||||
var line = lines[i];
|
||||
if (line.match(/Installed packages/)) {
|
||||
parsing_installed_packages = true;
|
||||
} else if (line.match(/Available Packages/) || line.match(/Available Updates/)) {
|
||||
// we are done working through installed packages, exit
|
||||
break;
|
||||
}
|
||||
if (parsing_installed_packages) {
|
||||
// Match stock android platform
|
||||
if (line.match(/platforms;android-\d+/)) {
|
||||
targets.push(line.match(/(android-\d+)/)[1]);
|
||||
}
|
||||
// Match Google APIs
|
||||
if (line.match(/addon-google_apis-google-\d+/)) {
|
||||
var description = lines[i + 1];
|
||||
// munge description to match output from old android sdk tooling
|
||||
var api_level = description.match(/Android (\d+)/); //[1];
|
||||
if (api_level) {
|
||||
targets.push('Google Inc.:Google APIs:' + api_level[1]);
|
||||
}
|
||||
}
|
||||
// TODO: match anything else?
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.list_targets = function() {
|
||||
return module.exports.list_targets_with_android()
|
||||
.catch(function(err) {
|
||||
// there's a chance `android` no longer works.
|
||||
// lets see if `sdkmanager` is available and we can figure it out
|
||||
var avail_regex = /android command is no longer available/;
|
||||
if (err.code && (err.stdout.match(avail_regex) || err.stderr.match(avail_regex))) {
|
||||
return superspawn.spawn('sdkmanager', ['--list'])
|
||||
.then(function(stdout) {
|
||||
var parsing_installed_packages = false;
|
||||
var lines = stdout.split('\n');
|
||||
var targets = [];
|
||||
for (var i = 0, l = lines.length; i < l; i++) {
|
||||
var line = lines[i];
|
||||
if (line.match(/Installed packages/)) {
|
||||
parsing_installed_packages = true;
|
||||
} else if (line.match(/Available Packages/) || line.match(/Available Updates/)) {
|
||||
// we are done working through installed packages, exit
|
||||
break;
|
||||
}
|
||||
if (parsing_installed_packages && line.match(/platforms;android-\d+/)) {
|
||||
targets.push(line.match(/android-\d+/)[0].split('-')[1]);
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
});
|
||||
return module.exports.list_targets_with_sdkmanager();
|
||||
} else throw err;
|
||||
}).then(function(targets) {
|
||||
if (targets.length === 0) {
|
||||
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
||||
} else {
|
||||
// Ensure we are working with integers
|
||||
targets = targets.map(function(t) { return parseInt(t); });
|
||||
// Sort them in descending order.
|
||||
targets.sort(function(a, b) { return b-a; });
|
||||
return targets;
|
||||
}
|
||||
return targets;
|
||||
});
|
||||
};
|
||||
|
3
bin/templates/cordova/lib/check_reqs.js
vendored
3
bin/templates/cordova/lib/check_reqs.js
vendored
@ -317,8 +317,7 @@ module.exports.check_android_target = function(originalError) {
|
||||
// android-L
|
||||
// Google Inc.:Google APIs:20
|
||||
// Google Inc.:Glass Development Kit Preview:20
|
||||
var desired_api_level = parseInt(module.exports.get_target().replace(/android-/, ''));
|
||||
// Changing "targets" to "target" is stupid and makes more code. Thanks Google!
|
||||
var desired_api_level = module.exports.get_target();
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
if (targets.indexOf(desired_api_level) >= 0) {
|
||||
|
116
spec/fixtures/android_list_targets.txt
vendored
Normal file
116
spec/fixtures/android_list_targets.txt
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
Available Android targets:
|
||||
----------
|
||||
id: 1 or "android-20"
|
||||
Name: Android 4.4W.2
|
||||
Type: Platform
|
||||
API level: 20
|
||||
Revision: 2
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : no ABIs.
|
||||
----------
|
||||
id: 2 or "android-21"
|
||||
Name: Android 5.0.1
|
||||
Type: Platform
|
||||
API level: 21
|
||||
Revision: 2
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : android-tv/armeabi-v7a, android-tv/x86, default/armeabi-v7a, default/x86, default/x86_64
|
||||
----------
|
||||
id: 3 or "android-22"
|
||||
Name: Android 5.1.1
|
||||
Type: Platform
|
||||
API level: 22
|
||||
Revision: 2
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : android-tv/armeabi-v7a, android-tv/x86, default/armeabi-v7a, default/x86, default/x86_64
|
||||
----------
|
||||
id: 4 or "android-MNC"
|
||||
Name: Android M (Preview)
|
||||
Type: Platform
|
||||
API level: MNC
|
||||
Revision: 1
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : no ABIs.
|
||||
----------
|
||||
id: 5 or "android-23"
|
||||
Name: Android 6.0
|
||||
Type: Platform
|
||||
API level: 23
|
||||
Revision: 3
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : android-tv/armeabi-v7a, android-tv/x86, default/x86, default/x86_64
|
||||
----------
|
||||
id: 6 or "android-N"
|
||||
Name: Android N (Preview)
|
||||
Type: Platform
|
||||
API level: N
|
||||
Revision: 3
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : no ABIs.
|
||||
----------
|
||||
id: 7 or "android-24"
|
||||
Name: Android 7.0
|
||||
Type: Platform
|
||||
API level: 24
|
||||
Revision: 2
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : android-tv/x86, default/x86, default/x86_64
|
||||
----------
|
||||
id: 8 or "android-25"
|
||||
Name: Android 7.1.1
|
||||
Type: Platform
|
||||
API level: 25
|
||||
Revision: 3
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : android-tv/x86, google_apis/x86, google_apis/x86_64
|
||||
----------
|
||||
id: 9 or "Google Inc.:Google APIs:21"
|
||||
Name: Google APIs
|
||||
Type: Add-On
|
||||
Vendor: Google Inc.
|
||||
Revision: 1
|
||||
Description: Android + Google APIs
|
||||
Based on Android 5.0.1 (API level 21)
|
||||
Libraries:
|
||||
* com.android.future.usb.accessory (usb.jar)
|
||||
API for USB Accessories
|
||||
* com.google.android.media.effects (effects.jar)
|
||||
Collection of video effects
|
||||
* com.google.android.maps (maps.jar)
|
||||
API for Google Maps
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : google_apis/armeabi-v7a, google_apis/x86, google_apis/x86_64
|
||||
----------
|
||||
id: 10 or "Google Inc.:Google APIs:22"
|
||||
Name: Google APIs
|
||||
Type: Add-On
|
||||
Vendor: Google Inc.
|
||||
Revision: 1
|
||||
Description: Android + Google APIs
|
||||
Based on Android 5.1.1 (API level 22)
|
||||
Libraries:
|
||||
* com.android.future.usb.accessory (usb.jar)
|
||||
API for USB Accessories
|
||||
* com.google.android.media.effects (effects.jar)
|
||||
Collection of video effects
|
||||
* com.google.android.maps (maps.jar)
|
||||
API for Google Maps
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : google_apis/armeabi-v7a, google_apis/x86, google_apis/x86_64
|
||||
----------
|
||||
id: 11 or "Google Inc.:Google APIs:23"
|
||||
Name: Google APIs
|
||||
Type: Add-On
|
||||
Vendor: Google Inc.
|
||||
Revision: 1
|
||||
Description: Android + Google APIs
|
||||
Based on Android 6.0 (API level 23)
|
||||
Libraries:
|
||||
* com.android.future.usb.accessory (usb.jar)
|
||||
API for USB Accessories
|
||||
* com.google.android.media.effects (effects.jar)
|
||||
Collection of video effects
|
||||
* com.google.android.maps (maps.jar)
|
||||
API for Google Maps
|
||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
||||
Tag/ABIs : google_apis/armeabi-v7a, google_apis/x86, google_apis/x86_64
|
1137
spec/fixtures/sdkmanager_list.txt
vendored
Normal file
1137
spec/fixtures/sdkmanager_list.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
122
spec/unit/android_sdk.spec.js
Normal file
122
spec/unit/android_sdk.spec.js
Normal file
@ -0,0 +1,122 @@
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
/* jshint laxcomma:true */
|
||||
|
||||
var android_sdk = require("../../bin/templates/cordova/lib/android_sdk");
|
||||
var superspawn = require("cordova-common").superspawn;
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var Q = require("q");
|
||||
|
||||
describe("android_sdk", function () {
|
||||
describe("list_targets_with_android", function() {
|
||||
it("should parse and return results from `android list targets` command", function(done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "android_list_targets.txt"), "utf-8"));
|
||||
return android_sdk.list_targets_with_android()
|
||||
.then(function(list) {
|
||||
[ "Google Inc.:Google APIs:23",
|
||||
"Google Inc.:Google APIs:22",
|
||||
"Google Inc.:Google APIs:21",
|
||||
"android-25",
|
||||
"android-24",
|
||||
"android-N",
|
||||
"android-23",
|
||||
"android-MNC",
|
||||
"android-22",
|
||||
"android-21",
|
||||
"android-20" ].forEach(function(target) {
|
||||
expect(list).toContain(target);
|
||||
});
|
||||
}).fail(function(err) {
|
||||
console.log(err);
|
||||
expect(err).toBeUndefined();
|
||||
}).fin(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("list_targets_with_sdkmanager", function() {
|
||||
it("should parse and return results from `sdkmanager --list` command", function(done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdkmanager_list.txt"), "utf-8"));
|
||||
return android_sdk.list_targets_with_sdkmanager()
|
||||
.then(function(list) {
|
||||
[ "Google Inc.:Google APIs:19",
|
||||
"Google Inc.:Google APIs:21",
|
||||
"Google Inc.:Google APIs:22",
|
||||
"Google Inc.:Google APIs:23",
|
||||
"Google Inc.:Google APIs:24",
|
||||
"android-19",
|
||||
"android-21",
|
||||
"android-22",
|
||||
"android-23",
|
||||
"android-24",
|
||||
"android-25" ].forEach(function(target) {
|
||||
expect(list).toContain(target);
|
||||
});
|
||||
}).fail(function(err) {
|
||||
console.log(err);
|
||||
expect(err).toBeUndefined();
|
||||
}).fin(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("list_targets", function() {
|
||||
it("should parse Android SDK installed target information with `android` command first", function() {
|
||||
var deferred = Q.defer();
|
||||
var android_spy = spyOn(android_sdk, "list_targets_with_android").and.returnValue(deferred.promise);
|
||||
android_sdk.list_targets();
|
||||
expect(android_spy).toHaveBeenCalled();
|
||||
});
|
||||
it("should parse Android SDK installed target information with `avdmanager` command if list_targets_with_android fails due to `android` command being obsolete", function(done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets_with_android").and.returnValue(deferred.promise);
|
||||
deferred.reject({
|
||||
code: 1,
|
||||
stdout: "The android command is no longer available."
|
||||
});
|
||||
var twoferred = Q.defer();
|
||||
twoferred.resolve(["target1"]);
|
||||
var sdkmanager_spy = spyOn(android_sdk, "list_targets_with_sdkmanager").and.returnValue(twoferred.promise);
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
expect(sdkmanager_spy).toHaveBeenCalled();
|
||||
expect(targets[0]).toEqual("target1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should throw an error if no Android targets were found.", function(done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets_with_android").and.returnValue(deferred.promise);
|
||||
deferred.resolve([]);
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
done.fail();
|
||||
}).catch(function(err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("No android targets (SDKs) installed!");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -19,9 +19,11 @@
|
||||
/* jshint laxcomma:true */
|
||||
|
||||
var check_reqs = require("../../bin/templates/cordova/lib/check_reqs");
|
||||
var android_sdk = require("../../bin/templates/cordova/lib/android_sdk");
|
||||
var shelljs = require("shelljs");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var Q = require("q");
|
||||
|
||||
describe("check_reqs", function () {
|
||||
var original_env;
|
||||
@ -218,4 +220,32 @@ describe("check_reqs", function () {
|
||||
expect(target).toContain("android-");
|
||||
});
|
||||
});
|
||||
describe("check_android_target", function() {
|
||||
it("should should return full list of supported targets if there is a match to ideal api level", function(done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets").and.returnValue(deferred.promise);
|
||||
var fake_targets = ["you are my fire", "my one desire"];
|
||||
deferred.resolve(fake_targets);
|
||||
spyOn(check_reqs, "get_target").and.returnValue("you are my fire");
|
||||
return check_reqs.check_android_target()
|
||||
.then(function(targets) {
|
||||
expect(targets).toBeDefined();
|
||||
expect(targets).toEqual(fake_targets);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should error out if there is no match between ideal api level and installed targets", function(done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets").and.returnValue(deferred.promise);
|
||||
var fake_targets = ["you are my fire", "my one desire"];
|
||||
deferred.resolve(fake_targets);
|
||||
spyOn(check_reqs, "get_target").and.returnValue("and i knowwwwwwwwwwww");
|
||||
return check_reqs.check_android_target()
|
||||
.catch(function(err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("Please install Android target");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user