Skip to content

Fixing the Sauce Labs tests and some old browser compatibility #2884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f236594
Update the selection of browser versions in Sauce Labs (#2879)
jgonggrijp Sep 25, 2020
96432bf
Drop an old outcomment from the .travis.yml (#2857)
jgonggrijp Sep 25, 2020
d3dd874
Run coveralls only in Node 10 (#2857)
jgonggrijp Sep 25, 2020
2223939
Add a fallback for byteOffset in toDataView (#2879)
jgonggrijp Oct 7, 2020
b16b623
Use typed array, not DataView as comparison view in _.isEqual (#2879)
jgonggrijp Oct 9, 2020
21ff8ed
Make DataView-depending tests conditional on its existence (#2879)
jgonggrijp Oct 9, 2020
eea411e
Add checks to diagnose and work around IE/edge test errors (#2879)
jgonggrijp Oct 9, 2020
8fe0c99
Address a timing issue in the debounce asap test (#2879)
jgonggrijp Oct 9, 2020
376e03f
Work around incorrect string tags in IE 10 - Edge 13 (#2879)
jgonggrijp Oct 10, 2020
0061801
Remove the diagnostic checks from eea411e42b2324d (#2879)
jgonggrijp Oct 10, 2020
0fffc03
Add new diagnostic checks for still failing tests in IE 11 (#2879)
jgonggrijp Oct 10, 2020
59494c9
Take non-enumerability of Map/WeakMap/Set methods into account (#2879)
jgonggrijp Oct 11, 2020
7380637
Update diagnostics from 0fffc03 to match 59494c9 (#2879)
jgonggrijp Oct 11, 2020
74b7d3a
Fix an oversight that caused _.isWeakMap(new Map) == true (#2879)
jgonggrijp Oct 11, 2020
5e3f191
Remove the diagnostics from 0fffc037+73806370 again (#2879)
jgonggrijp Oct 11, 2020
3bc482d
Add 4ms slack to _.throttle tests sensitive to setTimeout imprecision
jgonggrijp Oct 11, 2020
dce5d42
Make the new IE fallback code a bit more compact (#2879)
jgonggrijp Oct 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,24 @@ sudo: false
jobs:
include:
- node_js: 8
env: BROWSER=false
env: EXTRA=false
- node_js: 10
env: BROWSER=true
env: EXTRA=true
- node_js: 14
env: BROWSER=false
env: EXTRA=false
before_install:
- npm install -g karma-cli
before_script:
- npm install karma-sauce-launcher
script:
- npm test
- "[ $BROWSER = false ] || npm run test-browser"
- "[ $BROWSER = false ] || karma start karma.conf-sauce.js"
- "[ $EXTRA = false ] || npm run test-browser"
- "[ $EXTRA = false ] || karma start karma.conf-sauce.js"
- "[ $EXTRA = false ] || npm run coveralls"
notifications:
email: false
env:
global:
- NPM_CONFIG_PROGRESS="false"
- secure: bDZSBQfqr21hCayjcZ20IxrV6+XGhxQPFIfwWqEKLrF93Gu8LLVjZRxXE/mE8I8N4Z5WtDNb4ZHrm/TTzmcPa5MuHgIxEdknQCncobH8oimwc83SHwEPk6okeNKl39VlCjvvnmoe/V/KpnknuYn3Rqghtl/Uv9KLpCwskwjTtcw=
- secure: SRECgXuwcZTcD3GVxTS2bYNgRyye4vq6BLrV2PH9FyNenowsKQR2EwlC/dppc1Q8NWMgv79J/R96q9JOFh+mEH9L5dlBb2yhnGH8amVeM/ChAJHT/F8YktKM453uVpz5fR00QcCQDDUOx6Pvx374ID0OKNpWKAkQBWA9mPTsLnE=
# matrix: BROWSER=false
after_success: npm run coveralls
36 changes: 19 additions & 17 deletions karma.conf-sauce.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
var _ = require('./');

// Browsers to run on Sauce Labs platforms
// (See https://saucelabs.com/platform/supported-browsers-devices for an
// up-to-date overview of supported versions of browsers and platforms.)
var sauceBrowsers = _.reduce([
['firefox', '35'],
['firefox', '30'],
['firefox', '21'],
['firefox', 'latest'],
['firefox', '60'],
['firefox', '40'],
['firefox', '11'],
['firefox', '4'],
// ['firefox', '4'], // failing due to "not enough arguments"

['chrome', 'latest'],
['chrome', '60'],
['chrome', '40'],
['chrome', '39'],
['chrome', '31'],
['chrome', '26'],

// ['microsoftedge', 'latest', 'Windows 10'],
// ['internet explorer', '11', 'Windows 10'],
// latest Edge as well as pre-Blink versions
['microsoftedge', 'latest', 'Windows 10'],
['microsoftedge', '18', 'Windows 10'],
['microsoftedge', '13', 'Windows 10'],

['internet explorer', 'latest', 'Windows 10'],
['internet explorer', '10', 'Windows 8'],
['internet explorer', '9', 'Windows 7'],

// Currently disabled due to karma-sauce issues
// ['internet explorer', '8'],
// ['internet explorer', '7'],
// ['internet explorer', '6'],
// Older versions of IE no longer supported by Sauce Labs

//['android', 'latest']

['safari', '8.0', 'OS X 10.10'],
['safari', '7'],
['safari', 'latest', 'macOS 10.15'],
['safari', '12', 'macOS 10.14'],
['safari', '11', 'macOS 10.13'],
['safari', '8', 'OS X 10.10'],

], function(memo, platform) {
// internet explorer -> ie
Expand Down
3 changes: 3 additions & 0 deletions modules/_hasObjectTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import tagTester from './_tagTester.js';

export default tagTester('Object');
37 changes: 37 additions & 0 deletions modules/_methodFingerprint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import getLength from './_getLength.js';
import isFunction from './isFunction.js';
import allKeys from './allKeys.js';

// Since the regular `Object.prototype.toString` type tests don't work for
// some types in IE 11, we use a fingerprinting heuristic instead, based
// on the methods. It's not great, but it's the best we got.
// The fingerprint method lists are defined below.
export function ie11fingerprint(methods) {
var length = getLength(methods);
return function(obj) {
if (obj == null) return false;
// `Map`, `WeakMap` and `Set` have no enumerable keys.
var keys = allKeys(obj);
if (getLength(keys)) return false;
for (var i = 0; i < length; i++) {
if (!isFunction(obj[methods[i]])) return false;
}
// If we are testing against `WeakMap`, we need to ensure that
// `obj` doesn't have a `forEach` method in order to distinguish
// it from a regular `Map`.
return methods !== weakMapMethods || !isFunction(obj[forEachName]);
};
}

// In the interest of compact minification, we write
// each string in the fingerprints only once.
var forEachName = 'forEach',
hasName = 'has',
commonInit = ['clear', 'delete'],
mapTail = ['get', hasName, 'set'];

// `Map`, `WeakMap` and `Set` each have slightly different
// combinations of the above sublists.
export var mapMethods = commonInit.concat(forEachName, mapTail),
weakMapMethods = commonInit.concat(mapTail),
setMethods = ['add'].concat(commonInit, forEachName, hasName);
3 changes: 2 additions & 1 deletion modules/_setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export var push = ArrayProto.push,
hasOwnProperty = ObjProto.hasOwnProperty;

// Modern feature detection.
export var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined';
export var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
supportsDataView = typeof DataView !== 'undefined';

// All **ECMAScript 5+** native function implementations that we hope to use
// are declared here.
Expand Down
10 changes: 10 additions & 0 deletions modules/_stringTagBug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { supportsDataView } from './_setup.js';
import hasObjectTag from './_hasObjectTag.js';

// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
// In IE 11, the most common among them, this problem also applies to
// `Map`, `WeakMap` and `Set`.
export var hasStringTagBug = (
supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
),
isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
8 changes: 4 additions & 4 deletions modules/_toDataView.js → modules/_toBufferView.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import getByteLength from './_getByteLength.js';

// Internal function to wrap or shallow-copy an ArrayBuffer,
// typed array or DataView to a new DataView, reusing the buffer.
export default function toDataView(bufferSource) {
return new DataView(
// typed array or DataView to a new view, reusing the buffer.
export default function toBufferView(bufferSource) {
return new Uint8Array(
bufferSource.buffer || bufferSource,
bufferSource.byteOffset,
bufferSource.byteOffset || 0,
getByteLength(bufferSource)
);
}
8 changes: 4 additions & 4 deletions modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ export { default as isDate } from './isDate.js';
export { default as isRegExp } from './isRegExp.js';
export { default as isError } from './isError.js';
export { default as isSymbol } from './isSymbol.js';
export { default as isMap } from './isMap.js';
export { default as isWeakMap } from './isWeakMap.js';
export { default as isSet } from './isSet.js';
export { default as isWeakSet } from './isWeakSet.js';
export { default as isArrayBuffer } from './isArrayBuffer.js';
export { default as isDataView } from './isDataView.js';
export { default as isArray } from './isArray.js';
Expand All @@ -43,6 +39,10 @@ export { default as isTypedArray } from './isTypedArray.js';
export { default as isEmpty } from './isEmpty.js';
export { default as isMatch } from './isMatch.js';
export { default as isEqual } from './isEqual.js';
export { default as isMap } from './isMap.js';
export { default as isWeakMap } from './isWeakMap.js';
export { default as isSet } from './isSet.js';
export { default as isWeakSet } from './isWeakSet.js';

// Functions that treat an object as a dictionary of key-value pairs.
export { default as keys } from './keys.js';
Expand Down
13 changes: 12 additions & 1 deletion modules/isDataView.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
import tagTester from './_tagTester.js';
import isFunction from './isFunction.js';
import isArrayBuffer from './isArrayBuffer.js';
import { hasStringTagBug } from './_stringTagBug.js';

export default tagTester('DataView');
var isDataView = tagTester('DataView');

// In IE 10 - Edge 13, we need a different heuristic
// to determine whether an object is a `DataView`.
function ie10IsDataView(obj) {
return obj != null && isFunction(obj.getInt8) && isArrayBuffer(obj.buffer);
}

export default (hasStringTagBug ? ie10IsDataView : isDataView);
36 changes: 19 additions & 17 deletions modules/isEqual.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ import { toString, SymbolProto } from './_setup.js';
import getByteLength from './_getByteLength.js';
import isTypedArray from './isTypedArray.js';
import isFunction from './isFunction.js';
import { hasStringTagBug } from './_stringTagBug.js';
import isDataView from './isDataView.js';
import keys from './keys.js';
import has from './_has.js';
import toDataView from './_toDataView.js';
import toBufferView from './_toBufferView.js';

// We use this string twice, so give it a name for minification.
var tagDataView = '[object DataView]';

// Internal recursive comparison function for `_.isEqual`.
function eq(a, b, aStack, bStack) {
Expand All @@ -30,6 +35,11 @@ function deepEq(a, b, aStack, bStack) {
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className !== toString.call(b)) return false;
// Work around a bug in IE 10 - Edge 13.
if (hasStringTagBug && className == '[object Object]' && isDataView(a)) {
if (!isDataView(b)) return false;
className = tagDataView;
}
switch (className) {
// These types are compared by value.
case '[object RegExp]':
Expand All @@ -53,26 +63,18 @@ function deepEq(a, b, aStack, bStack) {
case '[object Symbol]':
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
case '[object ArrayBuffer]':
// Coerce to `DataView` so we can fall through to the next case.
return deepEq(toDataView(a), toDataView(b), aStack, bStack);
case '[object DataView]':
case tagDataView:
// Coerce to typed array so we can fall through.
return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
}

var areArrays = className === '[object Array]';
if (!areArrays && isTypedArray(a)) {
var byteLength = getByteLength(a);
if (byteLength !== getByteLength(b)) return false;
if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
while (byteLength--) {
if (a.getUint8(byteLength) !== b.getUint8(byteLength)) {
return false;
}
}
return true;
areArrays = true;
}

if (isTypedArray(a)) {
// Coerce typed arrays to `DataView`.
return deepEq(toDataView(a), toDataView(b), aStack, bStack);
}

var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;

Expand Down
4 changes: 3 additions & 1 deletion modules/isMap.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import tagTester from './_tagTester.js';
import { isIE11 } from './_stringTagBug.js';
import { ie11fingerprint, mapMethods } from './_methodFingerprint.js';

export default tagTester('Map');
export default isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
4 changes: 3 additions & 1 deletion modules/isSet.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import tagTester from './_tagTester.js';
import { isIE11 } from './_stringTagBug.js';
import { ie11fingerprint, setMethods } from './_methodFingerprint.js';

export default tagTester('Set');
export default isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
4 changes: 3 additions & 1 deletion modules/isWeakMap.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import tagTester from './_tagTester.js';
import { isIE11 } from './_stringTagBug.js';
import { ie11fingerprint, weakMapMethods } from './_methodFingerprint.js';

export default tagTester('WeakMap');
export default isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
15 changes: 9 additions & 6 deletions test/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@
throttledUpdate(1); throttledUpdate(2);
_.delay(function(){ throttledUpdate(3); }, 64);
assert.strictEqual(value, 1, 'updated to latest value');
_.delay(function(){ assert.strictEqual(value, 3, 'updated to latest value'); done(); }, 96);
_.delay(function(){ assert.strictEqual(value, 3, 'updated to latest value'); done(); }, 104);
});

QUnit.test('throttle once', function(assert) {
Expand Down Expand Up @@ -281,7 +281,7 @@
assert.strictEqual(results[4], 2, 'incr was throttled');
assert.strictEqual(results[5], 3, 'incr was called trailing');
done();
}, 300);
}, 304);
});

QUnit.test('throttle triggers trailing call when invoked repeatedly', function(assert) {
Expand Down Expand Up @@ -428,7 +428,7 @@
_.delay(function(){
assert.strictEqual(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
done();
}, 100);
}, 104);
});

QUnit.test('throttle cancel', function(assert) {
Expand Down Expand Up @@ -493,14 +493,17 @@
assert.strictEqual(counter, 1, 'incr was called immediately');
_.delay(debouncedIncr, 16);
_.delay(debouncedIncr, 32);
_.delay(debouncedIncr, 48);
_.delay(function(){
_.delay(function() {
debouncedIncr();
_.delay(finish, 80);
}, 48);
var finish = function(){
assert.strictEqual(counter, 1, 'incr was debounced');
c = debouncedIncr();
assert.strictEqual(c, 2);
assert.strictEqual(counter, 2, 'incr was called again');
done();
}, 128);
};
});

QUnit.test('debounce asap cancel', function(assert) {
Expand Down
Loading