mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-05 06:42:26 +03:00
WIP: v2.0.0 intial commit
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
import { each, indexOf } from 'core/utils/arrays';
|
||||
|
||||
describe('array utilities', () => {
|
||||
describe('each', () => {
|
||||
describe('each through Array', () => {
|
||||
test('returns input', () => {
|
||||
const arr = [1, 2, 3];
|
||||
expect(each(arr, () => { })).toBe(arr);
|
||||
});
|
||||
|
||||
test('correct times', () => {
|
||||
const arr = [1, 2, 3];
|
||||
const eachCallback = jest.fn();
|
||||
|
||||
each(arr, eachCallback);
|
||||
expect(eachCallback).toBeCalledTimes(arr.length);
|
||||
});
|
||||
|
||||
test('correct callback values', () => {
|
||||
const arr = [1, 2, 3];
|
||||
each(arr, (value, index, src) => {
|
||||
expect(value).toBe(arr[index]);
|
||||
expect(arr).toBe(src);
|
||||
});
|
||||
});
|
||||
|
||||
test('return false equals break', () => {
|
||||
const arr = [1, 2, 3];
|
||||
const testFunc = jest.fn();
|
||||
|
||||
each(arr, () => {
|
||||
testFunc();
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(testFunc).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('return true equals continue', () => {
|
||||
const arr = [1, 2, 3];
|
||||
const testFunc = jest.fn();
|
||||
|
||||
each(arr, (value, index) => {
|
||||
if (index === 0)
|
||||
return true;
|
||||
testFunc();
|
||||
});
|
||||
|
||||
expect(testFunc).toBeCalledTimes(arr.length - 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('each through Object', () => {
|
||||
test('returns input', () => {
|
||||
const obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
};
|
||||
expect(each(obj, () => { })).toBe(obj);
|
||||
});
|
||||
|
||||
test('correct times', () => {
|
||||
const obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
};
|
||||
const eachCallback = jest.fn();
|
||||
|
||||
each(obj, eachCallback);
|
||||
expect(eachCallback).toBeCalledTimes(Object.keys(obj).length);
|
||||
});
|
||||
|
||||
test('correct callback values', () => {
|
||||
const obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
};
|
||||
each(obj, (value, key, src) => {
|
||||
expect(value).toBe(obj[key]);
|
||||
expect(obj).toBe(src);
|
||||
});
|
||||
});
|
||||
|
||||
test('return false equals break', () => {
|
||||
const obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
};
|
||||
const testFunc = jest.fn();
|
||||
|
||||
each(obj, () => {
|
||||
testFunc();
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(testFunc).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('return true equals continue', () => {
|
||||
const obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
};
|
||||
const testFunc = jest.fn();
|
||||
let index = -1;
|
||||
|
||||
each(obj, (value) => {
|
||||
index++;
|
||||
if (index === 0)
|
||||
return true;
|
||||
testFunc();
|
||||
});
|
||||
|
||||
expect(testFunc).toBeCalledTimes(Object.keys(obj).length - 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('each through ArrayLike Object', () => {
|
||||
test('returns input', () => {
|
||||
const arrLikeObj = document.querySelectorAll('*');
|
||||
expect(each(arrLikeObj, () => { })).toBe(arrLikeObj);
|
||||
});
|
||||
|
||||
test('correct times', () => {
|
||||
const arrLikeObj = document.querySelectorAll('*');
|
||||
const eachCallback = jest.fn();
|
||||
|
||||
each(arrLikeObj, eachCallback);
|
||||
expect(eachCallback).toBeCalledTimes(arrLikeObj.length);
|
||||
});
|
||||
|
||||
test('correct callback values', () => {
|
||||
const arrLikeObj = document.querySelectorAll('*');
|
||||
each(arrLikeObj, (value, index, src) => {
|
||||
expect(value).toBe(arrLikeObj[index]);
|
||||
expect(src).toBe(arrLikeObj);
|
||||
});
|
||||
});
|
||||
|
||||
test('return false equals break', () => {
|
||||
const arrLikeObj = document.querySelectorAll('*');
|
||||
const testFunc = jest.fn();
|
||||
|
||||
each(arrLikeObj, () => {
|
||||
testFunc();
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(testFunc).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('return true equals continue', () => {
|
||||
const arrLikeObj = document.querySelectorAll('*');
|
||||
const testFunc = jest.fn();
|
||||
|
||||
each(arrLikeObj, (value, index) => {
|
||||
if (index === 0)
|
||||
return true;
|
||||
testFunc();
|
||||
});
|
||||
|
||||
expect(testFunc).toBeCalledTimes(arrLikeObj.length - 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('indexOf', () => {
|
||||
const idx = indexOf([1, 2, 3], 2);
|
||||
expect(idx).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,148 @@
|
||||
import { extend } from 'core/utils/extend';
|
||||
import { isPlainObject } from 'core/utils/types';
|
||||
|
||||
//type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T
|
||||
type Deep = {
|
||||
foo?: {
|
||||
bar?: boolean,
|
||||
baz?: boolean
|
||||
},
|
||||
foo2?: Document
|
||||
};
|
||||
type Settings = {
|
||||
xnumber0?: null,
|
||||
xnumber1?: number | null,
|
||||
xnumber2?: number | null,
|
||||
xstring1?: string,
|
||||
xstring2?: string,
|
||||
xxx?: string
|
||||
};
|
||||
type NestedArray = {
|
||||
arr: Array<any> | object
|
||||
};
|
||||
|
||||
//https://github.com/jquery/jquery/blob/master/test/unit/core.js#L965
|
||||
describe('extend', () => {
|
||||
test('equals object assign', () => {
|
||||
let settings: Settings = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" };
|
||||
const options: Settings = { xnumber2: 1, xstring2: "x", xxx: "newstring" };
|
||||
const optionsCopy: Settings = { xnumber2: 1, xstring2: "x", xxx: "newstring" };
|
||||
const merged: Settings = { xnumber1: 5, xnumber2: 1, xstring1: "peter", xstring2: "x", xxx: "newstring" };
|
||||
|
||||
extend(settings, options);
|
||||
expect(settings).toEqual(merged);
|
||||
expect(options).toEqual(optionsCopy);
|
||||
|
||||
extend(settings, null, options);
|
||||
expect(settings).toEqual(merged);
|
||||
expect(options).toEqual(optionsCopy);
|
||||
|
||||
|
||||
const deep1: Deep = { foo: { bar: true } };
|
||||
const deep2: Deep = { foo: { baz: true }, foo2: document };
|
||||
const deep2copy: Deep = { foo: { baz: true }, foo2: document };
|
||||
const deepmerged: Deep = { foo: { bar: true, baz: true }, foo2: document };
|
||||
|
||||
extend(deep1, deep2);
|
||||
expect(deep1.foo).toEqual(deepmerged.foo);
|
||||
expect(deep2.foo).toEqual(deep2copy.foo);
|
||||
expect(deep1.foo2).toBe(document);
|
||||
|
||||
|
||||
const arr = [1, 2, 3];
|
||||
const nestedArray: NestedArray = { arr: arr };
|
||||
|
||||
expect(extend({}, nestedArray).arr).not.toBe(arr);
|
||||
expect(Array.isArray(extend({ arr: {} }, nestedArray).arr)).toBeTruthy();
|
||||
expect(Array.isArray(extend({ arr: {} }, nestedArray).arr)).toBeTruthy();
|
||||
expect(isPlainObject(extend({ arr: arr }, { arr: {} }).arr)).toBeTruthy();
|
||||
|
||||
let empty = {};
|
||||
const optionsWithLength = { "foo": { "length": -1 } };
|
||||
|
||||
|
||||
extend(empty, optionsWithLength);
|
||||
expect(empty["foo"]).toEqual(optionsWithLength["foo"]);
|
||||
|
||||
empty = {};
|
||||
const optionsWithDate = { "foo": { "date": new Date() } };
|
||||
|
||||
|
||||
extend(empty, optionsWithDate);
|
||||
expect(empty["foo"]).toEqual(optionsWithDate["foo"]);
|
||||
|
||||
/** @constructor */
|
||||
const myKlass = function () { };
|
||||
// @ts-ignore
|
||||
const customObject = new myKlass();
|
||||
const optionsWithCustomObject = { "foo": { "date": customObject } };
|
||||
empty = {};
|
||||
|
||||
extend(empty, optionsWithCustomObject);
|
||||
expect(empty["foo"] && empty["foo"]["date"] === customObject).toBeTruthy();
|
||||
|
||||
// Makes the class a little more realistic
|
||||
myKlass.prototype = { "someMethod": function () { } };
|
||||
empty = {};
|
||||
|
||||
extend(empty, optionsWithCustomObject);
|
||||
expect(empty["foo"] && empty["foo"]["date"] === customObject).toBeTruthy();
|
||||
|
||||
const MyNumber = Number;
|
||||
|
||||
var ret: any = extend({ foo: 4 }, { foo: new MyNumber(5) });
|
||||
expect(parseInt(ret.foo?.toString() as string, 10) === 5).toBeTruthy();
|
||||
|
||||
let nullUndef = extend({}, options, { xnumber2: null });
|
||||
expect(nullUndef.xnumber2).toBe(null);
|
||||
|
||||
// @ts-ignore
|
||||
nullUndef = extend({}, options, { xnumber2: undefined });
|
||||
expect(nullUndef.xnumber2).toBe(options.xnumber2);
|
||||
|
||||
// @ts-ignore
|
||||
nullUndef = extend({}, options, { xnumber0: null });
|
||||
expect(nullUndef.xnumber0).toBe(null);
|
||||
|
||||
const target = {};
|
||||
const recursive = { foo: target, bar: 5 };
|
||||
|
||||
extend(target, recursive);
|
||||
expect(target).toEqual({ bar: 5 });
|
||||
|
||||
ret = extend({ foo: [] }, { foo: [0] });
|
||||
expect(ret.foo?.length).toBe(1);
|
||||
|
||||
ret = extend({ foo: "1,2,3" }, { foo: [1, 2, 3] });
|
||||
expect(typeof ret.foo !== "string").toBeTruthy();
|
||||
|
||||
ret = extend({ foo: "bar" }, { foo: null });
|
||||
expect(typeof ret.foo !== "undefined").toBeTruthy();
|
||||
|
||||
const obj = { foo: null };
|
||||
extend(obj, { foo: "notnull" });
|
||||
expect(obj.foo).toBe("notnull");
|
||||
|
||||
const func: { (): void, key?: string } = () => { };
|
||||
extend(func, { key: "value" });
|
||||
expect(func.key).toBe("value");
|
||||
|
||||
const defaults = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" };
|
||||
const defaultsCopy = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" };
|
||||
const options1 = { xnumber2: 1, xstring2: "x" };
|
||||
const options1Copy = { xnumber2: 1, xstring2: "x" };
|
||||
const options2 = { xstring2: "xx", xxx: "newstringx" };
|
||||
const options2Copy = { xstring2: "xx", xxx: "newstringx" };
|
||||
const merged2 = { xnumber1: 5, xnumber2: 1, xstring1: "peter", xstring2: "xx", xxx: "newstringx" };
|
||||
|
||||
settings = extend({}, defaults, options1, options2);
|
||||
expect(settings).toEqual(merged2);
|
||||
expect(defaults).toEqual(defaultsCopy);
|
||||
expect(options1).toEqual(options1Copy);
|
||||
expect(options2).toEqual(options2Copy);
|
||||
|
||||
expect(extend('', { foo: 1 })).toEqual({ foo: 1 });
|
||||
expect(extend(null, { foo: null, deep: { foo: null } })).toEqual({ foo: null, deep: { foo: null } });
|
||||
expect(extend(12, { foo: 1, deep: { foo: null, text: '' } })).toEqual({ foo: 1, deep: { foo: null, text: '' } });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,216 @@
|
||||
import { type, isNumber, isString, isBoolean, isFunction, isArray, isObject, isUndefined, isNull, isArrayLike, isPlainObject, isEmptyObject, isHTMLElement } from 'core/utils/types';
|
||||
|
||||
const testfn = function () { };
|
||||
const testfnAsync = async function () { };
|
||||
|
||||
const typeNameValueMap = {
|
||||
null: null,
|
||||
undefined: undefined,
|
||||
void0: void 0,
|
||||
infinity: Infinity,
|
||||
number: 0,
|
||||
string: '0',
|
||||
booleanTrue: true,
|
||||
booleanFalse: false,
|
||||
function: testfn,
|
||||
functionAsync: testfnAsync,
|
||||
functionArrow: () => { },
|
||||
functionArrowAsync: async () => { },
|
||||
functionConstructor: new (testfn as any)(),
|
||||
arrayEmpty: [],
|
||||
objectEmpty: {},
|
||||
array: [1, 2, 3],
|
||||
object: { a: 1, b: 2, c: 3 },
|
||||
objectCreate: Object.create(null),
|
||||
arrayLikeObject: { 0: 0, 1: 1, 2: 2, length: 3 },
|
||||
newNumber: new Number(0),
|
||||
newString: new String('0'),
|
||||
newBoolean: new Boolean(false),
|
||||
newFunction: new Function(''),
|
||||
newArray: new Array(),
|
||||
document: document,
|
||||
window: window,
|
||||
body: document.body,
|
||||
querySelectorAll: document.querySelectorAll('*'),
|
||||
};
|
||||
|
||||
const testTypeFn = (typeFunc: Function, expectedTypeNameValueResultMap: any) => {
|
||||
Object.keys(typeNameValueMap).forEach(comparisonKey => {
|
||||
const comparisonValue = typeNameValueMap[comparisonKey];
|
||||
const result = typeFunc(comparisonValue);
|
||||
if (expectedTypeNameValueResultMap.hasOwnProperty(comparisonKey)) {
|
||||
const todoComparisonValue = expectedTypeNameValueResultMap[comparisonKey];
|
||||
expect(result + comparisonKey).toBe(todoComparisonValue + comparisonKey);
|
||||
}
|
||||
else {
|
||||
expect(result + comparisonKey).toBe(false + comparisonKey);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
describe('types', () => {
|
||||
test('type', () => {
|
||||
expect(type(undefined)).toBe("undefined");
|
||||
expect(type(null)).toBe("null");
|
||||
expect(type(true)).toBe("boolean");
|
||||
expect(type(new Boolean())).toBe("boolean");
|
||||
expect(type(3)).toBe("number");
|
||||
expect(type(new Number(3))).toBe("number");
|
||||
expect(type("test")).toBe("string");
|
||||
expect(type(new String("test"))).toBe("string");
|
||||
expect(type(function () { })).toBe("function");
|
||||
expect(type([])).toBe("array");
|
||||
expect(type(new Array())).toBe("array");
|
||||
expect(type(new Date())).toBe("date");
|
||||
expect(type(new Error())).toBe("error");
|
||||
expect(type(Symbol())).toBe("symbol");
|
||||
expect(type(Object(Symbol()))).toBe("symbol");
|
||||
expect(type(/test/)).toBe("regexp");
|
||||
});
|
||||
|
||||
test('isNumber', () => {
|
||||
testTypeFn(isNumber, {
|
||||
number: true,
|
||||
infinity: true,
|
||||
newNumber: false // new Number() not a number is ok
|
||||
});
|
||||
});
|
||||
|
||||
test('isString', () => {
|
||||
testTypeFn(isString, {
|
||||
string: true,
|
||||
newString: false // new String() not a string is ok
|
||||
});
|
||||
});
|
||||
|
||||
test('isBoolean', () => {
|
||||
testTypeFn(isBoolean, {
|
||||
booleanTrue: true,
|
||||
booleanFalse: true,
|
||||
newBoolean: false // new Boolean() not a boolean is ok
|
||||
});
|
||||
});
|
||||
|
||||
test('isFunction', () => {
|
||||
testTypeFn(isFunction, {
|
||||
function: true,
|
||||
functionAsync: true,
|
||||
functionArrow: true,
|
||||
functionArrowAsync: true,
|
||||
newFunction: true
|
||||
});
|
||||
});
|
||||
|
||||
test('isArray', () => {
|
||||
testTypeFn(isArray, {
|
||||
array: true,
|
||||
arrayEmpty: true,
|
||||
newArray: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isObject', () => {
|
||||
testTypeFn(isObject, {
|
||||
object: true,
|
||||
objectEmpty: true,
|
||||
objectCreate: true,
|
||||
document: true,
|
||||
window: true,
|
||||
body: true,
|
||||
querySelectorAll: true,
|
||||
functionConstructor: true,
|
||||
arrayLikeObject: true,
|
||||
|
||||
// is ok since nobody does this
|
||||
newNumber: true,
|
||||
newString: true,
|
||||
newBoolean: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isUndefined', () => {
|
||||
testTypeFn(isUndefined, {
|
||||
undefined: true,
|
||||
void0: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isNull', () => {
|
||||
testTypeFn(isNull, {
|
||||
null: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isArrayLike', () => {
|
||||
testTypeFn(isArrayLike, {
|
||||
array: true,
|
||||
arrayEmpty: true,
|
||||
arrayLikeObject: true,
|
||||
querySelectorAll: true,
|
||||
string: true,
|
||||
newString: true,
|
||||
newArray: true,
|
||||
// is ok I guess...
|
||||
window: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isPlainObject', () => {
|
||||
testTypeFn(isPlainObject, {
|
||||
object: true,
|
||||
objectEmpty: true,
|
||||
objectCreate: true,
|
||||
arrayLikeObject: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isEmptyObject', () => {
|
||||
testTypeFn(isEmptyObject, {
|
||||
objectEmpty: true,
|
||||
objectCreate: true,
|
||||
arrayEmpty: true,
|
||||
|
||||
newNumber: true,
|
||||
newBoolean: true,
|
||||
newFunction: true,
|
||||
newArray: true,
|
||||
|
||||
null: true,
|
||||
undefined: true,
|
||||
booleanTrue: true,
|
||||
booleanFalse: true,
|
||||
void0: true,
|
||||
number: true,
|
||||
infinity: true,
|
||||
functionConstructor: true,
|
||||
function: true,
|
||||
functionAsync: true,
|
||||
functionArrow: true,
|
||||
functionArrowAsync: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('isHTMLElement', () => {
|
||||
const temp = window.HTMLElement;
|
||||
|
||||
testTypeFn(isHTMLElement, {
|
||||
body: true
|
||||
});
|
||||
Array.from(document.querySelectorAll('*')).forEach((elm) => {
|
||||
expect(isHTMLElement(elm)).toBeTruthy();
|
||||
});
|
||||
|
||||
delete window.HTMLElement;
|
||||
// @ts-ignore
|
||||
window.HTMLElement = null;
|
||||
|
||||
testTypeFn(isHTMLElement, {
|
||||
body: true
|
||||
});
|
||||
Array.from(document.querySelectorAll('*')).forEach((elm) => {
|
||||
expect(isHTMLElement(elm)).toBeTruthy();
|
||||
});
|
||||
|
||||
window.HTMLElement = temp;
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user