From f5a908584c5f6325f10c8c9039e23d34c546e53e Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 10:02:14 +0000 Subject: [PATCH 01/12] fixes #359 IE11 Added Array.prototype.find and Object.assign polyfills --- src/parser.js | 16 ++++++++-------- src/utils.js | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/parser.js b/src/parser.js index 1b3681f..9f90f0a 100644 --- a/src/parser.js +++ b/src/parser.js @@ -82,7 +82,7 @@ class Parser { parseBrowser() { this.parsedResult.browser = {}; - const browserDescriptor = browserParsersList.find((_browser) => { + const browserDescriptor = Utils.find(browserParsersList, _browser => { if (typeof _browser.test === 'function') { return _browser.test(this); } @@ -165,7 +165,7 @@ class Parser { parseOS() { this.parsedResult.os = {}; - const os = osParsersList.find((_os) => { + const os = Utils.find(osParsersList, _os => { if (typeof _os.test === 'function') { return _os.test(this); } @@ -241,7 +241,7 @@ class Parser { parsePlatform() { this.parsedResult.platform = {}; - const platform = platformParsersList.find((_platform) => { + const platform = Utils.find(platformParsersList, _platform => { if (typeof _platform.test === 'function') { return _platform.test(this); } @@ -292,7 +292,7 @@ class Parser { parseEngine() { this.parsedResult.engine = {}; - const engine = enginesParsersList.find((_engine) => { + const engine = Utils.find(enginesParsersList, _engine => { if (typeof _engine.test === 'function') { return _engine.test(this); } @@ -328,7 +328,7 @@ class Parser { * @return {ParsedResult} */ getResult() { - return Object.assign({}, this.parsedResult); + return Utils.assign({}, this.parsedResult); } /** @@ -370,7 +370,7 @@ class Parser { if (platformsAndOSCounter > 0) { const platformsAndOSNames = Object.keys(platformsAndOSes); - const OSMatchingDefinition = platformsAndOSNames.find(name => (this.isOS(name))); + const OSMatchingDefinition = Utils.find(platformsAndOSNames, name => (this.isOS(name))); if (OSMatchingDefinition) { const osResult = this.satisfies(platformsAndOSes[OSMatchingDefinition]); @@ -380,7 +380,7 @@ class Parser { } } - const platformMatchingDefinition = platformsAndOSNames.find(name => (this.isPlatform(name))); + const platformMatchingDefinition = Utils.find(platformsAndOSNames, name => (this.isPlatform(name))); if (platformMatchingDefinition) { const platformResult = this.satisfies(platformsAndOSes[platformMatchingDefinition]); @@ -392,7 +392,7 @@ class Parser { if (browsersCounter > 0) { const browserNames = Object.keys(browsers); - const matchingDefinition = browserNames.find(name => (this.isBrowser(name, true))); + const matchingDefinition = Utils.find(browserNames, name => (this.isBrowser(name, true))); if (matchingDefinition !== void 0) { return this.compareVersion(browsers[matchingDefinition]); diff --git a/src/utils.js b/src/utils.js index 7e36f8f..7105d32 100644 --- a/src/utils.js +++ b/src/utils.js @@ -231,6 +231,44 @@ export default class Utils { return result; } + /** + * Array::find polyfill + * + * @param {Array} arr + * @param {Function} predicate + * @return {Array} + */ + static find(arr, predicate) { + let i; + let l; + for (i = 0, l = arr.length; i < l; i++ ) { + const value = arr[i]; + if (!predicate(value, i)) continue; + return value; + } + } + + /** + * Object::assign polyfill + * + * @param {Object} obj + * @param {Object} ...objs + * @return {Object} + */ + static assign(obj) { + let i; + let l; + let k; + for (i = 1, l = arguments.length; i < l; i++) { + const assigner = arguments[i]; + if (!(typeof assigner === "object")) continue; + for (k in assigner) { + obj[k] = assigner[k] + } + } + return obj; + } + /** * Get short version/alias for a browser name * From 066f665aacb131502363c12e99184e52f688ea8e Mon Sep 17 00:00:00 2001 From: Oliver Foster Date: Thu, 19 Dec 2019 10:05:29 +0000 Subject: [PATCH 02/12] Changed bad code --- src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 7105d32..f972f15 100644 --- a/src/utils.js +++ b/src/utils.js @@ -261,7 +261,7 @@ export default class Utils { let k; for (i = 1, l = arguments.length; i < l; i++) { const assigner = arguments[i]; - if (!(typeof assigner === "object")) continue; + if (typeof assigner !== "object") continue; for (k in assigner) { obj[k] = assigner[k] } From d0dfa37e502981e2fca5c49a6ac2002228121c87 Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 10:12:52 +0000 Subject: [PATCH 03/12] Added fallback to native functions --- src/utils.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/utils.js b/src/utils.js index f972f15..f1d82d7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -241,6 +241,9 @@ export default class Utils { static find(arr, predicate) { let i; let l; + if (Array.prototype.find) { + return Array.prototype.find.call(arr, predicate); + } for (i = 0, l = arr.length; i < l; i++ ) { const value = arr[i]; if (!predicate(value, i)) continue; @@ -259,6 +262,9 @@ export default class Utils { let i; let l; let k; + if (Object.assign) { + return Object.assign.apply(Object, arguments); + } for (i = 1, l = arguments.length; i < l; i++) { const assigner = arguments[i]; if (typeof assigner !== "object") continue; From 97aa1e1972561b8bf984b449eb6019c5336f56a8 Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 10:36:51 +0000 Subject: [PATCH 04/12] Fix travis warnings --- src/parser.js | 13 ++++++++----- src/utils.js | 23 +++++++++++++---------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/parser.js b/src/parser.js index 9f90f0a..831b5cf 100644 --- a/src/parser.js +++ b/src/parser.js @@ -82,7 +82,7 @@ class Parser { parseBrowser() { this.parsedResult.browser = {}; - const browserDescriptor = Utils.find(browserParsersList, _browser => { + const browserDescriptor = Utils.find(browserParsersList, (_browser) => { if (typeof _browser.test === 'function') { return _browser.test(this); } @@ -165,7 +165,7 @@ class Parser { parseOS() { this.parsedResult.os = {}; - const os = Utils.find(osParsersList, _os => { + const os = Utils.find(osParsersList, (_os) => { if (typeof _os.test === 'function') { return _os.test(this); } @@ -241,7 +241,7 @@ class Parser { parsePlatform() { this.parsedResult.platform = {}; - const platform = Utils.find(platformParsersList, _platform => { + const platform = Utils.find(platformParsersList, (_platform) => { if (typeof _platform.test === 'function') { return _platform.test(this); } @@ -292,7 +292,7 @@ class Parser { parseEngine() { this.parsedResult.engine = {}; - const engine = Utils.find(enginesParsersList, _engine => { + const engine = Utils.find(enginesParsersList, (_engine) => { if (typeof _engine.test === 'function') { return _engine.test(this); } @@ -380,7 +380,10 @@ class Parser { } } - const platformMatchingDefinition = Utils.find(platformsAndOSNames, name => (this.isPlatform(name))); + const platformMatchingDefinition = Utils.find( + platformsAndOSNames, + name => (this.isPlatform(name)) + ); if (platformMatchingDefinition) { const platformResult = this.satisfies(platformsAndOSes[platformMatchingDefinition]); diff --git a/src/utils.js b/src/utils.js index f1d82d7..cdf76e1 100644 --- a/src/utils.js +++ b/src/utils.js @@ -244,11 +244,14 @@ export default class Utils { if (Array.prototype.find) { return Array.prototype.find.call(arr, predicate); } - for (i = 0, l = arr.length; i < l; i++ ) { + for (i = 0, l = arr.length; i < l; i+=1) { const value = arr[i]; - if (!predicate(value, i)) continue; + if (!predicate(value, i)) { + continue; + } return value; } + return undefined; } /** @@ -258,19 +261,19 @@ export default class Utils { * @param {Object} ...objs * @return {Object} */ - static assign(obj) { + static assign(obj, ...assigners) { let i; let l; - let k; if (Object.assign) { - return Object.assign.apply(Object, arguments); + return Object.assign(obj, ...assigners); } - for (i = 1, l = arguments.length; i < l; i++) { - const assigner = arguments[i]; - if (typeof assigner !== "object") continue; - for (k in assigner) { - obj[k] = assigner[k] + for (i = 0, l = assigners.length; i < l; i+=1) { + const assigner = assigners[i]; + if (typeof assigner !== 'object') { + continue; } + const keys = Object.keys(assigner); + keys.forEach(key => obj[key] = assigner[key]); } return obj; } From e55055534f95311651ac7ada7b5cfb77f9f1d93d Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 10:45:33 +0000 Subject: [PATCH 05/12] Fix travis errors --- src/parser.js | 5 ++--- src/utils.js | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/parser.js b/src/parser.js index 831b5cf..8bacf3e 100644 --- a/src/parser.js +++ b/src/parser.js @@ -381,9 +381,8 @@ class Parser { } const platformMatchingDefinition = Utils.find( - platformsAndOSNames, - name => (this.isPlatform(name)) - ); + platformsAndOSNames, + name => (this.isPlatform(name))); if (platformMatchingDefinition) { const platformResult = this.satisfies(platformsAndOSes[platformMatchingDefinition]); diff --git a/src/utils.js b/src/utils.js index cdf76e1..6f92bf2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -210,6 +210,8 @@ export default class Utils { return -1; } } + + return undefined; } /** @@ -244,12 +246,11 @@ export default class Utils { if (Array.prototype.find) { return Array.prototype.find.call(arr, predicate); } - for (i = 0, l = arr.length; i < l; i+=1) { + for (i = 0, l = arr.length; i < l; i += 1) { const value = arr[i]; - if (!predicate(value, i)) { - continue; + if (predicate(value, i)) { + return value; } - return value; } return undefined; } @@ -262,18 +263,20 @@ export default class Utils { * @return {Object} */ static assign(obj, ...assigners) { + const result = obj; let i; let l; if (Object.assign) { return Object.assign(obj, ...assigners); } - for (i = 0, l = assigners.length; i < l; i+=1) { + for (i = 0, l = assigners.length; i < l; i += 1) { const assigner = assigners[i]; - if (typeof assigner !== 'object') { - continue; + if (typeof assigner === 'object') { + const keys = Object.keys(assigner); + keys.forEach((key) => { + result[key] = assigner[key]; + }); } - const keys = Object.keys(assigner); - keys.forEach(key => obj[key] = assigner[key]); } return obj; } From a54868776d7039dddda3468a995e2cba7c409d72 Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 10:51:30 +0000 Subject: [PATCH 06/12] Fixed linting issues --- src/parser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser.js b/src/parser.js index 8bacf3e..2fcfcab 100644 --- a/src/parser.js +++ b/src/parser.js @@ -382,7 +382,8 @@ class Parser { const platformMatchingDefinition = Utils.find( platformsAndOSNames, - name => (this.isPlatform(name))); + name => (this.isPlatform(name)), + ); if (platformMatchingDefinition) { const platformResult = this.satisfies(platformsAndOSes[platformMatchingDefinition]); From 3cdfd7de02b16bb4c6f6821ea679f692c76d832b Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 11:22:40 +0000 Subject: [PATCH 07/12] Expanded test coverage for utils.js --- src/utils.js | 4 ++-- test/unit/utils.js | 48 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/utils.js b/src/utils.js index 6f92bf2..d771ed2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -303,7 +303,7 @@ export default class Utils { * @param {string} browserName * @return {string} */ - static getBrowserTypeByAlias(browserAlia) { - return BROWSER_MAP[browserAlia] || ''; + static getBrowserTypeByAlias(browserAlias) { + return BROWSER_MAP[browserAlias] || ''; } } diff --git a/test/unit/utils.js b/test/unit/utils.js index b41843e..0ddd00d 100644 --- a/test/unit/utils.js +++ b/test/unit/utils.js @@ -1,11 +1,18 @@ import test from 'ava'; import { - getBrowserAlias, getFirstMatch, + getSecondMatch, + matchAndReturnConst, getWindowsVersionName, getMacOSVersionName, getAndroidVersionName, + getVersionPrecision, compareVersions, + map, + find, + assign, + getBrowserAlias, + getBrowserTypeByAlias } from '../../src/utils'; test('getFirstMatch', (t) => { @@ -13,6 +20,16 @@ test('getFirstMatch', (t) => { t.is(matchedVersion, '11.11.11'); }); +test('getSecondMatch', (t) => { + const matchedVersion = getSecondMatch(/version\/(\S+)/i, 'Chrome Version/11.11.11 Chrome Version/22.22.22'); + t.is(matchedVersion, '22.22.22'); +}); + +test('matchAndReturnConst', (t) => { + const _const = matchAndReturnConst(/version/i, 'version', "_const"); + t.is(_const, '_const'); +}); + test('getWindowsVersionName', (t) => { t.is(getWindowsVersionName('NT 5.0'), '2000'); t.is(getWindowsVersionName('XXX'), void 0); @@ -32,6 +49,11 @@ test('getAndroidVersionName', (t) => { t.is(getAndroidVersionName('XXX'), void 0); }); +test('getVersionPrecision', (t) => { + const precision = getVersionPrecision("10.14.5"); + t.is(precision, 3); +}); + test('compareVersions', (t) => { const comparisionsTasks = [ ['9.0', '10', -1], @@ -68,7 +90,31 @@ test('compareVersions', (t) => { }); }); +test('map', (t) => { + const result = map([1,2], (value) => value+2); + t.is(result[0], 3); + t.is(result[1], 4); +}); + +test('find', (t) => { + const result = find([1,2], (value) => value==2); + t.is(result, 1); +}); + +test('assign', (t) => { + const result = assign({}, { a: 1 }, { b: 1 }, { b: 2, c: 3 }); + t.is(result['a'], 1); + t.is(result['b'], 2); + t.is(result['c'], 3); +}); + test('getBrowserAlias', (t) => { t.is(getBrowserAlias('Microsoft Edge'), 'edge'); t.is(getBrowserAlias('Unexisting Browser'), void 0); }); + +test('getBrowserTypeByAlias', (t) => { + t.is(getBrowserTypeByAlias('edge'), 'Microsoft Edge'); + t.is(getBrowserTypeByAlias(void 0), ''); +}); + From 64bbd2a9b19840687fd8caa984c964c37b9b929f Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 11:26:52 +0000 Subject: [PATCH 08/12] Fixed tests --- test/unit/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/utils.js b/test/unit/utils.js index 0ddd00d..1dd39fd 100644 --- a/test/unit/utils.js +++ b/test/unit/utils.js @@ -21,7 +21,7 @@ test('getFirstMatch', (t) => { }); test('getSecondMatch', (t) => { - const matchedVersion = getSecondMatch(/version\/(\S+)/i, 'Chrome Version/11.11.11 Chrome Version/22.22.22'); + const matchedVersion = getSecondMatch(/version\/(\S+)/ig, 'Chrome Version/11.11.11 Chrome Version/22.22.22'); t.is(matchedVersion, '22.22.22'); }); @@ -98,7 +98,7 @@ test('map', (t) => { test('find', (t) => { const result = find([1,2], (value) => value==2); - t.is(result, 1); + t.is(result, 2); }); test('assign', (t) => { From cad365b53e3bc9172898b4f33a67cc438dca1180 Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 11:38:49 +0000 Subject: [PATCH 09/12] Fixed getSecondMatch test --- test/unit/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/utils.js b/test/unit/utils.js index 1dd39fd..ecaec44 100644 --- a/test/unit/utils.js +++ b/test/unit/utils.js @@ -21,7 +21,7 @@ test('getFirstMatch', (t) => { }); test('getSecondMatch', (t) => { - const matchedVersion = getSecondMatch(/version\/(\S+)/ig, 'Chrome Version/11.11.11 Chrome Version/22.22.22'); + const matchedVersion = getSecondMatch(/version\/(\S+).*version\/(\S+)/i, 'Chrome Version/11.11.11 Chrome Version/22.22.22'); t.is(matchedVersion, '22.22.22'); }); From b74bb0caa26b8532ce1b59a044527b6f4aa80760 Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 11:46:15 +0000 Subject: [PATCH 10/12] Added polyfill tests --- test/unit/utils.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/unit/utils.js b/test/unit/utils.js index ecaec44..70b365e 100644 --- a/test/unit/utils.js +++ b/test/unit/utils.js @@ -94,11 +94,22 @@ test('map', (t) => { const result = map([1,2], (value) => value+2); t.is(result[0], 3); t.is(result[1], 4); + const original = Array.prototype.map; + delete Array.prototype.map; + const polyfillResult = map([1,2], (value) => value+2); + Array.prototype.map = original; + t.is(polyfillResult[0], 3); + t.is(polyfillResult[1], 4); }); test('find', (t) => { const result = find([1,2], (value) => value==2); t.is(result, 2); + const original = Array.prototype.find; + delete Array.prototype.find; + const polyfillResult = find([1,2], (value) => value==2); + Array.prototype.find = original; + t.is(polyfillResult, 2); }); test('assign', (t) => { @@ -106,6 +117,13 @@ test('assign', (t) => { t.is(result['a'], 1); t.is(result['b'], 2); t.is(result['c'], 3); + const original = Object.assign; + delete Object.assign; + const polyfillResult = assign({}, { a: 1 }, { b: 1 }, { b: 2, c: 3 }); + Object.assign = original; + t.is(polyfillResult['a'], 1); + t.is(polyfillResult['b'], 2); + t.is(polyfillResult['c'], 3); }); test('getBrowserAlias', (t) => { From f27c7e0580032c170122b0c49e7e03fe75df6b5a Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 11:49:50 +0000 Subject: [PATCH 11/12] Edited typo --- src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index d771ed2..afb51fb 100644 --- a/src/utils.js +++ b/src/utils.js @@ -300,7 +300,7 @@ export default class Utils { * @example * getBrowserAlias('edge') // Microsoft Edge * - * @param {string} browserName + * @param {string} browserAlias * @return {string} */ static getBrowserTypeByAlias(browserAlias) { From 5a6af193d24f49e0841f8b4a3c5dedd638628e95 Mon Sep 17 00:00:00 2001 From: Oliver foster Date: Thu, 19 Dec 2019 12:00:46 +0000 Subject: [PATCH 12/12] Extended test cases and fixed bug --- src/utils.js | 2 +- test/unit/utils.js | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/utils.js b/src/utils.js index afb51fb..d1174bf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -271,7 +271,7 @@ export default class Utils { } for (i = 0, l = assigners.length; i < l; i += 1) { const assigner = assigners[i]; - if (typeof assigner === 'object') { + if (typeof assigner === 'object' && assigner !== null) { const keys = Object.keys(assigner); keys.forEach((key) => { result[key] = assigner[key]; diff --git a/test/unit/utils.js b/test/unit/utils.js index 70b365e..1c2a9d5 100644 --- a/test/unit/utils.js +++ b/test/unit/utils.js @@ -107,9 +107,11 @@ test('find', (t) => { t.is(result, 2); const original = Array.prototype.find; delete Array.prototype.find; - const polyfillResult = find([1,2], (value) => value==2); + const polyfillResultFound = find([1,2], (value) => value==2); + const polyfillResultNotFound = find([1,2], (value) => value==3); Array.prototype.find = original; - t.is(polyfillResult, 2); + t.is(polyfillResultFound, 2); + t.is(polyfillResultNotFound, undefined); }); test('assign', (t) => { @@ -119,7 +121,7 @@ test('assign', (t) => { t.is(result['c'], 3); const original = Object.assign; delete Object.assign; - const polyfillResult = assign({}, { a: 1 }, { b: 1 }, { b: 2, c: 3 }); + const polyfillResult = assign({}, { a: 1 }, { b: 1 }, null, { b: 2, c: 3 }); Object.assign = original; t.is(polyfillResult['a'], 1); t.is(polyfillResult['b'], 2);