mirror of
https://github.com/lancedikson/bowser
synced 2024-10-27 20:34:22 +00:00
Get rid of semver and use old comparison which is more applicable
This commit is contained in:
parent
6030eb9e5d
commit
4ab0d9dfd3
@ -1,8 +1,8 @@
|
|||||||
import semver from 'semver';
|
|
||||||
import browserParsersList from './parser-browsers';
|
import browserParsersList from './parser-browsers';
|
||||||
import osParsersList from './parser-os';
|
import osParsersList from './parser-os';
|
||||||
import platformParsersList from './parser-platforms';
|
import platformParsersList from './parser-platforms';
|
||||||
import enginesParsersList from './parser-engines';
|
import enginesParsersList from './parser-engines';
|
||||||
|
import { compareVersions } from './utils';
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
/**
|
/**
|
||||||
@ -303,18 +303,14 @@ class Parser {
|
|||||||
* // or with platforms
|
* // or with platforms
|
||||||
* if (browser.check({desktop: { chrome: '>118.01.1322' } }))
|
* if (browser.check({desktop: { chrome: '>118.01.1322' } }))
|
||||||
*/
|
*/
|
||||||
semverCheck(checkTree) {
|
check(checkTree) {
|
||||||
const thisVersion = this.getBrowser().version;
|
|
||||||
if (!semver.valid(semver.coerce(thisVersion))) {
|
|
||||||
throw new Error(`Version of current browser doesn't seem applicable: ${thisVersion}`);
|
|
||||||
}
|
|
||||||
const keysToProcess = Object.keys(checkTree);
|
const keysToProcess = Object.keys(checkTree);
|
||||||
return keysToProcess.some((browserAttribute) => {
|
return keysToProcess.some((browserAttribute) => {
|
||||||
const objectOrVersion = checkTree[browserAttribute];
|
const objectOrVersion = checkTree[browserAttribute];
|
||||||
|
|
||||||
if (typeof objectOrVersion === 'object') {
|
if (typeof objectOrVersion === 'object') {
|
||||||
return (this.isOs(browserAttribute) || this.isPlatform(browserAttribute))
|
return (this.isOs(browserAttribute) || this.isPlatform(browserAttribute))
|
||||||
&& this.semverCheck(objectOrVersion);
|
&& this.check(objectOrVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.isBrowser(browserAttribute) && this.satisfies(objectOrVersion);
|
return this.isBrowser(browserAttribute) && this.satisfies(objectOrVersion);
|
||||||
@ -326,7 +322,19 @@ class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
satisfies(version) {
|
satisfies(version) {
|
||||||
return semver.satisfies(semver.coerce(this.getBrowser().version), version);
|
let expectedResult = 0;
|
||||||
|
let comparableVersion = version;
|
||||||
|
|
||||||
|
if (version[0] === '>') {
|
||||||
|
expectedResult = 1;
|
||||||
|
comparableVersion = version.substr(1);
|
||||||
|
} else if (version[0] === '<') {
|
||||||
|
expectedResult = -1;
|
||||||
|
comparableVersion = version.substr(1);
|
||||||
|
} else if (version[0] === '=') {
|
||||||
|
comparableVersion = version.substr(1);
|
||||||
|
}
|
||||||
|
return compareVersions(this.getBrowserVersion(), comparableVersion) === expectedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
isOs(osName) {
|
isOs(osName) {
|
||||||
|
81
src/utils.js
81
src/utils.js
@ -50,6 +50,87 @@ class Utils {
|
|||||||
default: return undefined;
|
default: return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get version precisions count
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* getVersionPrecision("1.10.3") // 3
|
||||||
|
*
|
||||||
|
* @param {string} version
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
static getVersionPrecision(version) {
|
||||||
|
return version.split('.').length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* @param {String} versionA versions versions to compare
|
||||||
|
* @param {String} versionB versions versions to compare
|
||||||
|
* @return {Number} comparison result: -1 when versionA is lower,
|
||||||
|
* 1 when versionA is bigger, 0 when both equal
|
||||||
|
*/
|
||||||
|
static compareVersions(versionA, versionB) {
|
||||||
|
// 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 chunks = Utils.map([versionA, versionB], (version) => {
|
||||||
|
const delta = precision - Utils.getVersionPrecision(version);
|
||||||
|
|
||||||
|
// 2) "9" -> "9.0" (for precision = 2)
|
||||||
|
const _version = version + new Array(delta + 1).join('.0');
|
||||||
|
|
||||||
|
// 3) "9.0" -> ["000000000"", "000000009"]
|
||||||
|
return Utils.map(_version.split('.'), chunk => new Array(20 - chunk.length).join('0') + chunk).reverse();
|
||||||
|
});
|
||||||
|
|
||||||
|
// iterate in reverse order by reversed chunks array
|
||||||
|
precision -= 1;
|
||||||
|
while (precision >= 0) {
|
||||||
|
// 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) {
|
||||||
|
// all version chunks are same
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
precision -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array::map polyfill
|
||||||
|
*
|
||||||
|
* @param {Array} arr
|
||||||
|
* @param {Function} iterator
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
static map(arr, iterator) {
|
||||||
|
const result = [];
|
||||||
|
let i;
|
||||||
|
if (Array.prototype.map) {
|
||||||
|
return Array.prototype.map.call(arr, iterator);
|
||||||
|
}
|
||||||
|
for (i = 0; i < arr.length; i += 1) {
|
||||||
|
result.push(iterator(arr[i]));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Utils;
|
module.exports = Utils;
|
||||||
|
@ -58,13 +58,17 @@ test('Skip parsing shouldn\'t parse', (t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Parser.check should make simple check', (t) => {
|
test('Parser.check should make simple check', (t) => {
|
||||||
t.is(parser.semverCheck({ opera: '>42' }), true);
|
t.is(parser.check({ opera: '>42' }), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Parser.check should make simple check', (t) => {
|
test('Parser.check should make simple check', (t) => {
|
||||||
t.is(parser.semverCheck({
|
t.is(parser.check({
|
||||||
macos: {
|
macos: {
|
||||||
opera: '>42',
|
safari: '>11',
|
||||||
},
|
},
|
||||||
|
ios: {
|
||||||
|
safari: '>10',
|
||||||
|
},
|
||||||
|
opera: '>42',
|
||||||
}), true);
|
}), true);
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ import test from 'ava';
|
|||||||
import {
|
import {
|
||||||
getFirstMatch,
|
getFirstMatch,
|
||||||
getWindowsVersionName,
|
getWindowsVersionName,
|
||||||
|
compareVersions,
|
||||||
} from '../../src/utils';
|
} from '../../src/utils';
|
||||||
|
|
||||||
test('getFirstMatch', (t) => {
|
test('getFirstMatch', (t) => {
|
||||||
@ -13,3 +14,35 @@ test('getWindowsVersionName', (t) => {
|
|||||||
t.is(getWindowsVersionName('NT 5.0'), '2000');
|
t.is(getWindowsVersionName('NT 5.0'), '2000');
|
||||||
t.is(getWindowsVersionName('XXX'), void 0);
|
t.is(getWindowsVersionName('XXX'), void 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('compareVersions', (t) => {
|
||||||
|
const comparisionsTasks = [
|
||||||
|
['9.0', '10', -1],
|
||||||
|
['11', '10', 1],
|
||||||
|
['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.0800.2', -1],
|
||||||
|
['1.0.0-alpha', '1.0.0-alpha.1', -1],
|
||||||
|
['1.0.0-alpha.1', '1.0.0-alpha.beta', -1],
|
||||||
|
['1.0.0-alpha.beta', '1.0.0-beta', -1],
|
||||||
|
['1.0.0-beta', '1.0.0-beta.2', -1],
|
||||||
|
['1.0.0-beta.11', '1.0.0-rc.1', -1],
|
||||||
|
['1.0.0-rc.1', '1.0.0', -1],
|
||||||
|
];
|
||||||
|
|
||||||
|
comparisionsTasks.forEach((testingParams) => {
|
||||||
|
const versionA = testingParams[0];
|
||||||
|
const versionB = testingParams[1];
|
||||||
|
const result = testingParams[2];
|
||||||
|
let matching = ' == ';
|
||||||
|
|
||||||
|
if (result > 0) {
|
||||||
|
matching = ' > ';
|
||||||
|
} else if (result < 0) {
|
||||||
|
matching = ' < ';
|
||||||
|
}
|
||||||
|
|
||||||
|
t.is(compareVersions(versionA, versionB), result, `version ${versionA} should be ${matching} version ${versionB}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user