mirror of
https://github.com/lancedikson/bowser
synced 2024-10-27 20:34:22 +00:00
Adds loose comparison support
This commit is contained in:
parent
42b4c8cfa3
commit
6204d9f417
@ -111,6 +111,13 @@ const isValidBrowser = browser.satisfies({
|
||||
chrome: ">20.1.1432",
|
||||
firefox: ">31",
|
||||
opera: ">22"
|
||||
|
||||
// also supports equality operator
|
||||
chrome: "=20.1.1432", // will match particular build only
|
||||
|
||||
// and loose-equality operator
|
||||
chrome: "~20" // will match any 20.* sub-version
|
||||
chrome: "~20.1" // will match any 20.1.* sub-version (20.1.19 as well as 20.1.12.42-alpha.1)
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -397,6 +397,7 @@ class Parser {
|
||||
compareVersion(version) {
|
||||
let expectedResult = 0;
|
||||
let comparableVersion = version;
|
||||
let isLoose = false;
|
||||
|
||||
if (version[0] === '>') {
|
||||
expectedResult = 1;
|
||||
@ -406,8 +407,12 @@ class Parser {
|
||||
comparableVersion = version.substr(1);
|
||||
} else if (version[0] === '=') {
|
||||
comparableVersion = version.substr(1);
|
||||
} else if (version[0] === '~') {
|
||||
isLoose = true;
|
||||
comparableVersion = version.substr(1);
|
||||
}
|
||||
return compareVersions(this.getBrowserVersion(), comparableVersion) === expectedResult;
|
||||
|
||||
return compareVersions(this.getBrowserVersion(), comparableVersion, isLoose) === expectedResult;
|
||||
}
|
||||
|
||||
isOS(osName) {
|
||||
|
30
src/utils.js
30
src/utils.js
@ -68,23 +68,26 @@ class Utils {
|
||||
* Calculate browser version weight
|
||||
*
|
||||
* @example
|
||||
* compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1
|
||||
* compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1
|
||||
* compareVersions(['1.10.2.1', '1.10.2.1']); // 0
|
||||
* compareVersions(['1.10.2.1', '1.0800.2']); // -1
|
||||
* compareVersions('1.10.2.1', '1.8.2.1.90') // 1
|
||||
* compareVersions('1.010.2.1', '1.09.2.1.90'); // 1
|
||||
* compareVersions('1.10.2.1', '1.10.2.1'); // 0
|
||||
* compareVersions('1.10.2.1', '1.0800.2'); // -1
|
||||
* compareVersions('1.10.2.1', '1.10', true); // 0
|
||||
*
|
||||
* @param {String} versionA versions versions to compare
|
||||
* @param {String} versionB versions versions to compare
|
||||
* @param {boolean} [isLoose] enable loose comparison
|
||||
* @return {Number} comparison result: -1 when versionA is lower,
|
||||
* 1 when versionA is bigger, 0 when both equal
|
||||
*/
|
||||
/* eslint consistent-return: 1 */
|
||||
static compareVersions(versionA, versionB) {
|
||||
static compareVersions(versionA, versionB, isLoose = false) {
|
||||
// 1) get common precision for both versions, for example for "10.0" and "9" it should be 2
|
||||
let precision = Math.max(
|
||||
Utils.getVersionPrecision(versionA),
|
||||
Utils.getVersionPrecision(versionB),
|
||||
);
|
||||
const versionAPrecision = Utils.getVersionPrecision(versionA);
|
||||
const versionBPrecision = Utils.getVersionPrecision(versionB);
|
||||
|
||||
let precision = Math.max(versionAPrecision, versionBPrecision);
|
||||
let lastPrecision = 0;
|
||||
|
||||
const chunks = Utils.map([versionA, versionB], (version) => {
|
||||
const delta = precision - Utils.getVersionPrecision(version);
|
||||
@ -96,14 +99,19 @@ class Utils {
|
||||
return Utils.map(_version.split('.'), chunk => new Array(20 - chunk.length).join('0') + chunk).reverse();
|
||||
});
|
||||
|
||||
// adjust precision for loose comparison
|
||||
if (isLoose) {
|
||||
lastPrecision = precision - Math.min(versionAPrecision, versionBPrecision);
|
||||
}
|
||||
|
||||
// iterate in reverse order by reversed chunks array
|
||||
precision -= 1;
|
||||
while (precision >= 0) {
|
||||
while (precision >= lastPrecision) {
|
||||
// 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true)
|
||||
if (chunks[0][precision] > chunks[1][precision]) {
|
||||
return 1;
|
||||
} else if (chunks[0][precision] === chunks[1][precision]) {
|
||||
if (precision === 0) {
|
||||
if (precision === lastPrecision) {
|
||||
// all version chunks are same
|
||||
return 0;
|
||||
}
|
||||
|
@ -57,8 +57,13 @@ test('Skip parsing shouldn\'t parse', (t) => {
|
||||
t.deepEqual((new Parser(UA, true)).getResult(), {});
|
||||
});
|
||||
|
||||
test('Parser.check should make simple comparison', (t) => {
|
||||
test('Parser.check should make simple comparisons', (t) => {
|
||||
// also covers Parser.compareVersion() method
|
||||
t.is(parser.satisfies({ opera: '>42' }), true);
|
||||
t.is(parser.satisfies({ opera: '<44' }), true);
|
||||
t.is(parser.satisfies({ opera: '=43.0.2442.1165' }), true);
|
||||
t.is(parser.satisfies({ opera: '~43.0' }), true);
|
||||
t.is(parser.satisfies({ opera: '~43' }), true);
|
||||
});
|
||||
|
||||
test('Parser.check should make complex comparison', (t) => {
|
||||
|
@ -22,6 +22,9 @@ test('compareVersions', (t) => {
|
||||
['1.10.2.1', '1.8.2.1.90', 1],
|
||||
['1.010.2.1', '1.08.2.1.90', 1],
|
||||
['1.10.2.1', '1.10.2.1', 0],
|
||||
['1.10.2.1', '1.10.2', 0, true],
|
||||
['1.10.2.1', '1.10', 0, true],
|
||||
['1.10.2.1', '1', 0, true],
|
||||
['1.10.2.1', '1.0800.2', -1],
|
||||
['1.0.0-alpha', '1.0.0-alpha.1', -1],
|
||||
['1.0.0-alpha.1', '1.0.0-alpha.beta', -1],
|
||||
@ -35,7 +38,8 @@ test('compareVersions', (t) => {
|
||||
const versionA = testingParams[0];
|
||||
const versionB = testingParams[1];
|
||||
const result = testingParams[2];
|
||||
let matching = ' == ';
|
||||
const isLoose = testingParams.length > 3 ? testingParams[3] : false;
|
||||
let matching = isLoose ? '~' : ' == ';
|
||||
|
||||
if (result > 0) {
|
||||
matching = ' > ';
|
||||
@ -43,6 +47,6 @@ test('compareVersions', (t) => {
|
||||
matching = ' < ';
|
||||
}
|
||||
|
||||
t.is(compareVersions(versionA, versionB), result, `version ${versionA} should be ${matching} version ${versionB}`);
|
||||
t.is(compareVersions(versionA, versionB, isLoose), result, `version ${versionA} should be ${matching} version ${versionB}`);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user