diff --git a/src/check/polyfills.ts b/src/check/polyfills.ts index ddde2ba02f0..5a606da2208 100644 --- a/src/check/polyfills.ts +++ b/src/check/polyfills.ts @@ -1,8 +1,7 @@ // All the implementations below are directly taken from https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference /** @hidden */ -export const ObjectEntries = (obj: any): [string, any][] => { - if (Object.entries) return Object.entries(obj); +export const ObjectEntriesImpl = (obj: any): [string, any][] => { const ownProps = Object.keys(obj); let i = ownProps.length; const resArray = new Array(i); @@ -10,34 +9,39 @@ export const ObjectEntries = (obj: any): [string, any][] => { return resArray; }; -/** hidden */ -export const StringPadEnd = (src: string, targetLength: number, padString: string) => { - if (src && src.padEnd) return src.padEnd(targetLength, padString); +/** @hidden */ +export const ObjectEntries = Object.entries ? Object.entries : ObjectEntriesImpl; + +/** @hidden */ +const repeatUpToLength = (src: string, targetLength: number): string => { + for (; targetLength > src.length; src += src); + return src; +}; + +/** @hidden */ +export const StringPadEndImpl = (src: string, targetLength: number, padString: string) => { targetLength = targetLength >> 0; - padString = String(typeof padString !== 'undefined' ? padString : ' '); - if (src.length > targetLength) { - return String(src); - } else { - targetLength = targetLength - src.length; - while (targetLength > padString.length) { - padString += padString; - } - return String(src) + padString.slice(0, targetLength); - } + if (padString === '' || src.length > targetLength) return String(src); + targetLength = targetLength - src.length; + padString = repeatUpToLength(typeof padString !== 'undefined' ? String(padString) : ' ', targetLength); + return String(src) + padString.slice(0, targetLength); }; /** @hidden */ -export const StringPadStart = (src: string, targetLength: number, padString: string) => { - if (src && src.padStart) return src.padStart(targetLength, padString); +export const StringPadEnd = String.prototype.padEnd + ? (src: string, targetLength: number, padString: string) => src.padEnd(targetLength, padString) + : StringPadEndImpl; + +/** @hidden */ +export const StringPadStartImpl = (src: string, targetLength: number, padString: string) => { targetLength = targetLength >> 0; - padString = String(typeof padString !== 'undefined' ? padString : ' '); - if (src.length > targetLength) { - return String(src); - } else { - targetLength = targetLength - src.length; - while (targetLength > padString.length) { - padString += padString; - } - return padString.slice(0, targetLength) + String(src); - } + if (padString === '' || src.length > targetLength) return String(src); + targetLength = targetLength - src.length; + padString = repeatUpToLength(typeof padString !== 'undefined' ? String(padString) : ' ', targetLength); + return padString.slice(0, targetLength) + String(src); }; + +/** @hidden */ +export const StringPadStart = String.prototype.padStart + ? (src: string, targetLength: number, padString: string) => src.padStart(targetLength, padString) + : StringPadStartImpl; diff --git a/test/unit/check/polyfills.spec.ts b/test/unit/check/polyfills.spec.ts new file mode 100644 index 00000000000..caa37f3a302 --- /dev/null +++ b/test/unit/check/polyfills.spec.ts @@ -0,0 +1,43 @@ +import * as assert from 'assert'; +import * as fc from '../../../lib/fast-check'; + +import { ObjectEntriesImpl, StringPadEndImpl, StringPadStartImpl } from '../../../src/check/polyfills'; + +describe('polyfills', () => { + describe('Object.entries', () => { + if (Object.entries) { + it('Should give the same answer as built-it entries', () => + fc.assert( + fc.property(fc.dictionary(fc.fullUnicodeString(), fc.fullUnicodeString()), d => { + assert.deepStrictEqual(ObjectEntriesImpl(d), Object.entries(d)); + }) + )); + } + }); + describe('String.prototype.padEnd', () => { + if (String.prototype.padEnd) { + it('Should give the same answer as built-it padEnd', () => + fc.assert( + fc.property( + fc.fullUnicodeString(), + fc.nat(1000), + fc.fullUnicodeString(), + (src, l, pad) => StringPadEndImpl(src, l, pad) === src.padEnd(l, pad) + ) + )); + } + }); + describe('String.prototype.padStart', () => { + if (String.prototype.padStart) { + it('Should give the same answer as built-it padStart', () => + fc.assert( + fc.property( + fc.fullUnicodeString(), + fc.nat(1000), + fc.fullUnicodeString(), + (src, l, pad) => StringPadStartImpl(src, l, pad) === src.padStart(l, pad) + ) + )); + } + }); +});