Skip to content

Commit

Permalink
feat(compat): implement pad (#584)
Browse files Browse the repository at this point in the history
  • Loading branch information
D-Sketon authored Sep 24, 2024
1 parent 7623503 commit c734f73
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 8 deletions.
14 changes: 10 additions & 4 deletions benchmarks/performance/pad.bench.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { bench, describe } from 'vitest';
import { pad as padStartToolkit } from 'es-toolkit';
import { pad as padStartLodash } from 'lodash';
import { pad as padToolkit } from 'es-toolkit';
import { pad as padToolkitCompat } from 'es-toolkit/compat';
import { pad as padLodash } from 'lodash';

describe('pad', () => {
bench('es-toolkit/pad', () => {
const str = 'abc';
padStartToolkit(str, 6, '_-');
padToolkit(str, 6, '_-');
});

bench('es-toolkit/compat/pad', () => {
const str = 'abc';
padToolkitCompat(str, 6, '_-');
});

bench('lodash/pad', () => {
const str = 'abc';
padStartLodash(str, 6, '_-');
padLodash(str, 6, '_-');
});
});
8 changes: 4 additions & 4 deletions benchmarks/performance/padEnd.bench.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { bench, describe } from 'vitest';
import { padEnd as padStartToolkit } from 'es-toolkit/compat';
import { padEnd as padStartLodash } from 'lodash';
import { padEnd as padEndToolkit } from 'es-toolkit/compat';
import { padEnd as padEndLodash } from 'lodash';

describe('padEnd', () => {
bench('es-toolkit/padEnd', () => {
const str = 'abc';
padStartToolkit(str, 6, '_-');
padEndToolkit(str, 6, '_-');
});

bench('lodash/padEnd', () => {
const str = 'abc';
padStartLodash(str, 6, '_-');
padEndLodash(str, 6, '_-');
});
});
1 change: 1 addition & 0 deletions src/compat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export { lowerCase } from './string/lowerCase.ts';
export { upperCase } from './string/upperCase.ts';
export { startsWith } from './string/startsWith.ts';
export { endsWith } from './string/endsWith.ts';
export { pad } from './string/pad.ts';
export { padStart } from './string/padStart.ts';
export { padEnd } from './string/padEnd.ts';
export { repeat } from './string/repeat.ts';
Expand Down
67 changes: 67 additions & 0 deletions src/compat/string/pad.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { describe, it, expect } from 'vitest';
import { pad } from './pad';

describe('pad', () => {
it(`\`pad\` should not pad if string is >= \`length\``, () => {
expect(pad('abc', 2)).toBe('abc');
expect(pad('abc', 3)).toBe('abc');
});

it(`\`pad\` should treat negative \`length\` as \`0\``, () => {
[0, -2].forEach(length => {
expect(pad('abc', length)).toBe('abc');
});
});

it(`\`pad\` should coerce \`length\` to a number`, () => {
['', '4'].forEach(length => {
const actual = length ? 'abc ' : 'abc';
// @ts-expect-error - invalid length
expect(pad('abc', length)).toBe(actual);
});
});

it(`\`pad\` should treat nullish values as empty strings`, () => {
[undefined, '_-'].forEach(chars => {
const expected = chars ? '__' : ' ';
// @ts-expect-error - invalid string
expect(pad(null, 2, chars)).toBe(expected);
// @ts-expect-error - invalid string
expect(pad(undefined, 2, chars)).toBe(expected);
expect(pad('', 2, chars)).toBe(expected);
});
});

it(`\`pad\` should return \`string\` when \`chars\` coerces to an empty string`, () => {
const values = ['', Object('')];
const expected = values.map(() => 'abc');

const actual = values.map(value => pad('abc', 6, value));

expect(actual).toEqual(expected);
});

it('should pad a string to a given length', () => {
// eslint-disable-next-line no-sparse-arrays
const values = [, undefined];
const expected = values.map(() => ' abc ');

const actual = values.map((value, index) => (index ? pad('abc', 6, value) : pad('abc', 6)));

expect(actual).toEqual(expected);
});

it('should truncate pad characters to fit the pad length', () => {
expect(pad('abc', 8)).toBe(' abc ');
expect(pad('abc', 8, '_-')).toBe('_-abc_-_');
});

it('should coerce `string` to a string', () => {
const values = [Object('abc'), { toString: () => 'abc' }];
const expected = values.map(() => true);

const actual = values.map(value => pad(value, 6) === ' abc ');

expect(actual).toEqual(expected);
});
});
21 changes: 21 additions & 0 deletions src/compat/string/pad.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { pad as padToolkit } from '../../string/pad.ts';
import { toString } from '../util/toString.ts';
/**
* Pads string on the left and right sides if it's shorter than length. Padding characters are truncated if they can't be evenly divided by length.
* If the length is less than or equal to the original string's length, or if the padding character is an empty string, the original string is returned unchanged.
*
* @param {string} str - The string to pad.
* @param {number} [length] - The length of the resulting string once padded.
* @param {string} [chars] - The character(s) to use for padding.
* @returns {string} - The padded string, or the original string if padding is not required.
*
* @example
* const result1 = pad('abc', 8); // result will be ' abc '
* const result2 = pad('abc', 8, '_-'); // result will be '_-abc_-_'
* const result3 = pad('abc', 3); // result will be 'abc'
* const result4 = pad('abc', 2); // result will be 'abc'
*
*/
export function pad(str: string, length: number, chars = ' '): string {
return padToolkit(toString(str), length, chars);
}

0 comments on commit c734f73

Please sign in to comment.