js-powerkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +519 -0
- package/package.json +48 -0
- package/src/arrayUtils.js +347 -0
- package/src/index.js +8 -0
- package/src/objectUtils.js +423 -0
- package/src/stringUtils.js +319 -0
- package/tests/arrayUtils.test.js +204 -0
- package/tests/objectUtils.test.js +211 -0
- package/tests/stringUtils.test.js +220 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String Utility Functions
|
|
3
|
+
* @module string
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Capitalizes the first letter of a string.
|
|
9
|
+
* @param {string} str - The input string.
|
|
10
|
+
* @returns {string} The string with the first letter capitalized.
|
|
11
|
+
* @example
|
|
12
|
+
* capitalize('hello world'); // 'Hello world'
|
|
13
|
+
*/
|
|
14
|
+
export const capitalize = (str) => {
|
|
15
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
16
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Converts a string to camelCase.
|
|
21
|
+
* @param {string} str - The input string.
|
|
22
|
+
* @returns {string} The camelCase version of the string.
|
|
23
|
+
* @example
|
|
24
|
+
* toCamelCase('hello world'); // 'helloWorld'
|
|
25
|
+
*/
|
|
26
|
+
export const toCamelCase = (str) => {
|
|
27
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
28
|
+
return str
|
|
29
|
+
.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
|
|
30
|
+
.replace(/^./, char => char.toLowerCase());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Converts a string to kebab-case.
|
|
35
|
+
* @param {string} str - The input string.
|
|
36
|
+
* @returns {string} The kebab-case version of the string.
|
|
37
|
+
* @example
|
|
38
|
+
* toKebabCase('Hello World'); // 'hello-world'
|
|
39
|
+
*/
|
|
40
|
+
export const toKebabCase = (str) => {
|
|
41
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
42
|
+
return str
|
|
43
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
44
|
+
.replace(/[\s_]+/g, '-')
|
|
45
|
+
.toLowerCase();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Converts a string to snake_case.
|
|
50
|
+
* @param {string} str - The input string.
|
|
51
|
+
* @returns {string} The snake_case version of the string.
|
|
52
|
+
* @example
|
|
53
|
+
* toSnakeCase('Hello World'); // 'hello_world'
|
|
54
|
+
*/
|
|
55
|
+
export const toSnakeCase = (str) => {
|
|
56
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
57
|
+
return str
|
|
58
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
59
|
+
.replace(/[\s-]+/g, '_')
|
|
60
|
+
.toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Converts a string to PascalCase.
|
|
65
|
+
* @param {string} str - The input string.
|
|
66
|
+
* @returns {string} The PascalCase version of the string.
|
|
67
|
+
* @example
|
|
68
|
+
* toPascalCase('hello world'); // 'HelloWorld'
|
|
69
|
+
*/
|
|
70
|
+
export const toPascalCase = (str) => {
|
|
71
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
72
|
+
return str
|
|
73
|
+
.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
|
|
74
|
+
.replace(/^./, char => char.toUpperCase());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Capitalizes the first letter of each word
|
|
79
|
+
* @param {string} str - The string to convert
|
|
80
|
+
* @returns {string} The title case string
|
|
81
|
+
* @example
|
|
82
|
+
* toTitleCase('hello world'); // 'Hello World'
|
|
83
|
+
*/
|
|
84
|
+
export const toTitleCase = (str) => {
|
|
85
|
+
if (!str) return '';
|
|
86
|
+
return str.replace(/\w\S*/g, (txt) =>
|
|
87
|
+
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Reverses a string.
|
|
93
|
+
* @param {string} str - The input string.
|
|
94
|
+
* @returns {string} The reversed string.
|
|
95
|
+
* @example
|
|
96
|
+
* reverse('hello'); // 'olleh'
|
|
97
|
+
*/
|
|
98
|
+
export const reverse = (str) => {
|
|
99
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
100
|
+
return str.split('').reverse().join('');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Truncates a string to a specified length and adds an ellipsis.
|
|
105
|
+
* @param {string} str - The input string.
|
|
106
|
+
* @param {number} length - The maximum length.
|
|
107
|
+
* @param {string} [suffix='...'] - The suffix to add.
|
|
108
|
+
* @returns {string} The truncated string.
|
|
109
|
+
* @example
|
|
110
|
+
* truncate('Hello World', 5, '', true); // 'He...'
|
|
111
|
+
* truncate('Hello World', 5, '', false); // 'Hello'
|
|
112
|
+
*/
|
|
113
|
+
export const truncate = (str, length, suffix = '...', addSuffix = true) => {
|
|
114
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
115
|
+
if (typeof length !== 'number') throw new TypeError('Length must be a number');
|
|
116
|
+
|
|
117
|
+
if (str.length <= length) return str;
|
|
118
|
+
|
|
119
|
+
if (addSuffix && suffix) {
|
|
120
|
+
return str.slice(0, length - suffix.length) + suffix;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return str.slice(0, length);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Checks if a string is a palindrome.
|
|
128
|
+
* @param {string} str - The input string.
|
|
129
|
+
* @returns {boolean} True if the string is a palindrome.
|
|
130
|
+
* @example
|
|
131
|
+
* isPalindrome('racecar'); // true
|
|
132
|
+
*/
|
|
133
|
+
export const isPalindrome = (str) => {
|
|
134
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
135
|
+
const cleaned = str.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
136
|
+
return cleaned === cleaned.split('').reverse().join('');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Masks a string (useful for sensitive data)
|
|
141
|
+
* @param {string} str - The string to mask
|
|
142
|
+
* @param {number} visibleChars - Number of visible characters at start/end
|
|
143
|
+
* @param {string} maskChar - Character to use for masking
|
|
144
|
+
* @returns {string} The masked string
|
|
145
|
+
* @example
|
|
146
|
+
* mask('secret', 1); // 's****t'
|
|
147
|
+
*/
|
|
148
|
+
export const mask = (str, visibleChars = 4, maskChar = '*') => {
|
|
149
|
+
if (!str || str.length <= visibleChars * 2) return str;
|
|
150
|
+
const start = str.substring(0, visibleChars);
|
|
151
|
+
const end = str.substring(str.length - visibleChars);
|
|
152
|
+
const masked = maskChar.repeat(str.length - visibleChars * 2);
|
|
153
|
+
return start + masked + end;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Converts a string to a URL slug.
|
|
158
|
+
* @param {string} str - The input string.
|
|
159
|
+
* @returns {string} The slugified string.
|
|
160
|
+
* @example
|
|
161
|
+
* slugify('Hello World!'); // 'hello-world'
|
|
162
|
+
*/
|
|
163
|
+
export const slugify = (str) => {
|
|
164
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
165
|
+
return str
|
|
166
|
+
.toLowerCase()
|
|
167
|
+
.trim()
|
|
168
|
+
.replace(/[^\w\s-]/g, '')
|
|
169
|
+
.replace(/[\s_-]+/g, '-')
|
|
170
|
+
.replace(/^-+|-+$/g, '');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Counts the number of words in a string.
|
|
175
|
+
* @param {string} str - The input string.
|
|
176
|
+
* @returns {number} The word count.
|
|
177
|
+
* @example
|
|
178
|
+
* countWords('Hello world!'); // 2
|
|
179
|
+
*/
|
|
180
|
+
export const countWords = (str) => {
|
|
181
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
182
|
+
return str.trim().split(/\s+/).filter(word => word.length > 0).length;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Removes duplicate characters from a string.
|
|
187
|
+
* @param {string} str - The input string.
|
|
188
|
+
* @returns {string} The string with duplicates removed.
|
|
189
|
+
* @example
|
|
190
|
+
* removeDuplicates('hello'); // 'helo'
|
|
191
|
+
*/
|
|
192
|
+
export const removeDuplicates = (str) => {
|
|
193
|
+
if (typeof str !== 'string') throw new TypeError('Input must be a string');
|
|
194
|
+
return [...new Set(str)].join('');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Removes all whitespace from a string
|
|
199
|
+
* @param {string} str - The string to process
|
|
200
|
+
* @returns {string} String without whitespace
|
|
201
|
+
* @example
|
|
202
|
+
* removeWhitespace(' hello world '); // 'helloworld'
|
|
203
|
+
*/
|
|
204
|
+
export const removeWhitespace = (str) => {
|
|
205
|
+
if (!str) return '';
|
|
206
|
+
return str.replace(/\s+/g, '');
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Extracts all email addresses from a string
|
|
211
|
+
* @param {string} str - The string to search
|
|
212
|
+
* @returns {Array<string>} Array of email addresses
|
|
213
|
+
* @example
|
|
214
|
+
* extractEmails('Contact us at test@example.com or support@test.org'); // ['test@example.com', 'support@test.org']
|
|
215
|
+
*/
|
|
216
|
+
export const extractEmails = (str) => {
|
|
217
|
+
if (!str) return [];
|
|
218
|
+
const emailRegex = /[\w.-]+@[\w.-]+\.\w+/g;
|
|
219
|
+
return str.match(emailRegex) || [];
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Extracts all URLs from a string
|
|
224
|
+
* @param {string} str - The string to search
|
|
225
|
+
* @returns {Array<string>} Array of URLs
|
|
226
|
+
* @example
|
|
227
|
+
* extractUrls('Visit https://example.com or http://test.org'); // ['https://example.com', 'http://test.org']
|
|
228
|
+
*/
|
|
229
|
+
export const extractUrls = (str) => {
|
|
230
|
+
if (!str) return [];
|
|
231
|
+
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
232
|
+
return str.match(urlRegex) || [];
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Removes HTML tags from a string
|
|
237
|
+
* @param {string} str - The string containing HTML
|
|
238
|
+
* @returns {string} String without HTML tags
|
|
239
|
+
* @example
|
|
240
|
+
* stripHtml('<p>Hello <b>World</b></p>'); // 'Hello World'
|
|
241
|
+
*/
|
|
242
|
+
export const stripHtml = (str) => {
|
|
243
|
+
if (!str) return '';
|
|
244
|
+
return str.replace(/<[^>]*>/g, '');
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Escapes HTML special characters
|
|
249
|
+
* @param {string} str - The string to escape
|
|
250
|
+
* @returns {string} The escaped string
|
|
251
|
+
* @example
|
|
252
|
+
* escapeHtml('<div>Test & "quotes"</div>'); // '<div>Test & "quotes"</div>'
|
|
253
|
+
*/
|
|
254
|
+
export const escapeHtml = (str) => {
|
|
255
|
+
if (!str) return '';
|
|
256
|
+
const htmlEscapes = {
|
|
257
|
+
'&': '&',
|
|
258
|
+
'<': '<',
|
|
259
|
+
'>': '>',
|
|
260
|
+
'"': '"',
|
|
261
|
+
"'": '''
|
|
262
|
+
};
|
|
263
|
+
return str.replace(/[&<>"']/g, char => htmlEscapes[char]);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Checks if a string contains only numbers
|
|
268
|
+
* @param {string} str - The string to check
|
|
269
|
+
* @returns {boolean} True if numeric
|
|
270
|
+
* @example
|
|
271
|
+
* isNumeric('12345'); // true
|
|
272
|
+
*/
|
|
273
|
+
export const isNumeric = (str) => {
|
|
274
|
+
if (!str) return false;
|
|
275
|
+
return /^\d+$/.test(str);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Checks if a string is a valid email
|
|
280
|
+
* @param {string} str - The string to validate
|
|
281
|
+
* @returns {boolean} True if valid email
|
|
282
|
+
* @example
|
|
283
|
+
* isEmail('test@example.com'); // true
|
|
284
|
+
*/
|
|
285
|
+
export const isEmail = (str) => {
|
|
286
|
+
if (!str) return false;
|
|
287
|
+
const emailRegex = /^[\w.-]+@[\w.-]+\.\w+$/;
|
|
288
|
+
return emailRegex.test(str);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Checks if a string is a valid URL
|
|
293
|
+
* @param {string} str - The string to validate
|
|
294
|
+
* @returns {boolean} True if valid URL
|
|
295
|
+
* @example
|
|
296
|
+
* isUrl('https://example.com'); // true
|
|
297
|
+
*/
|
|
298
|
+
export const isUrl = (str) => {
|
|
299
|
+
if (!str) return false;
|
|
300
|
+
try {
|
|
301
|
+
new URL(str);
|
|
302
|
+
return true;
|
|
303
|
+
} catch {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Repeats a string n times
|
|
310
|
+
* @param {string} str - The string to repeat
|
|
311
|
+
* @param {number} times - Number of repetitions
|
|
312
|
+
* @returns {string} The repeated string
|
|
313
|
+
* @example
|
|
314
|
+
* repeatString('ab', 3); // 'ababab'
|
|
315
|
+
*/
|
|
316
|
+
export const repeatString = (str, times) => {
|
|
317
|
+
if (!str || times <= 0) return '';
|
|
318
|
+
return str.repeat(times);
|
|
319
|
+
};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import {
|
|
2
|
+
chunk,
|
|
3
|
+
flatten,
|
|
4
|
+
unique,
|
|
5
|
+
shuffle,
|
|
6
|
+
randomElement,
|
|
7
|
+
compact,
|
|
8
|
+
sortBy,
|
|
9
|
+
groupBy,
|
|
10
|
+
intersection,
|
|
11
|
+
difference,
|
|
12
|
+
union,
|
|
13
|
+
zip,
|
|
14
|
+
range,
|
|
15
|
+
max,
|
|
16
|
+
min,
|
|
17
|
+
sum,
|
|
18
|
+
average,
|
|
19
|
+
countOccurrences,
|
|
20
|
+
remove,
|
|
21
|
+
take,
|
|
22
|
+
drop,
|
|
23
|
+
includesAll,
|
|
24
|
+
includesAny,
|
|
25
|
+
rotate
|
|
26
|
+
} from '../src/arrayUtils.js';
|
|
27
|
+
|
|
28
|
+
describe('Array Utilities', () => {
|
|
29
|
+
describe('chunk', () => {
|
|
30
|
+
test('splits array into chunks', () => {
|
|
31
|
+
expect(chunk([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]);
|
|
32
|
+
expect(chunk([1, 2, 3], 3)).toEqual([[1, 2, 3]]);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('throws error for invalid inputs', () => {
|
|
36
|
+
expect(() => chunk('not array', 2)).toThrow(TypeError);
|
|
37
|
+
expect(() => chunk([1, 2], 0)).toThrow(TypeError);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('flatten', () => {
|
|
42
|
+
test('flattens nested arrays', () => {
|
|
43
|
+
expect(flatten([1, [2, [3, 4]], 5])).toEqual([1, 2, [3, 4], 5]);
|
|
44
|
+
expect(flatten([1, [2, [3, 4]], 5], 2)).toEqual([1, 2, 3, 4, 5]);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe('unique', () => {
|
|
49
|
+
test('removes duplicates', () => {
|
|
50
|
+
expect(unique([1, 2, 2, 3, 4, 4])).toEqual([1, 2, 3, 4]);
|
|
51
|
+
expect(unique(['a', 'b', 'a'])).toEqual(['a', 'b']);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('shuffle', () => {
|
|
56
|
+
test('shuffles array', () => {
|
|
57
|
+
const arr = [1, 2, 3, 4, 5];
|
|
58
|
+
const shuffled = shuffle(arr);
|
|
59
|
+
expect(shuffled).toHaveLength(5);
|
|
60
|
+
expect(shuffled.sort()).toEqual([1, 2, 3, 4, 5]);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('randomElement', () => {
|
|
65
|
+
test('returns random element', () => {
|
|
66
|
+
const arr = [1, 2, 3, 4, 5];
|
|
67
|
+
const element = randomElement(arr);
|
|
68
|
+
expect(arr).toContain(element);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('returns undefined for empty array', () => {
|
|
72
|
+
expect(randomElement([])).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('compact', () => {
|
|
77
|
+
test('removes falsy values', () => {
|
|
78
|
+
expect(compact([0, 1, false, 2, '', 3, null, undefined, NaN]))
|
|
79
|
+
.toEqual([1, 2, 3]);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('sortBy', () => {
|
|
84
|
+
test('sorts by property', () => {
|
|
85
|
+
const arr = [{ a: 2 }, { a: 1 }, { a: 3 }];
|
|
86
|
+
expect(sortBy(arr, 'a')).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }]);
|
|
87
|
+
expect(sortBy(arr, 'a', 'desc')).toEqual([{ a: 3 }, { a: 2 }, { a: 1 }]);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('groupBy', () => {
|
|
92
|
+
test('groups by property', () => {
|
|
93
|
+
const arr = [{ type: 'a', val: 1 }, { type: 'b', val: 2 }, { type: 'a', val: 3 }];
|
|
94
|
+
expect(groupBy(arr, 'type')).toEqual({
|
|
95
|
+
a: [{ type: 'a', val: 1 }, { type: 'a', val: 3 }],
|
|
96
|
+
b: [{ type: 'b', val: 2 }]
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('intersection', () => {
|
|
102
|
+
test('finds intersection', () => {
|
|
103
|
+
expect(intersection([1, 2, 3], [2, 3, 4])).toEqual([2, 3]);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('difference', () => {
|
|
108
|
+
test('finds difference', () => {
|
|
109
|
+
expect(difference([1, 2, 3], [2, 3, 4])).toEqual([1]);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('union', () => {
|
|
114
|
+
test('finds union', () => {
|
|
115
|
+
expect(union([1, 2, 3], [2, 3, 4])).toEqual([1, 2, 3, 4]);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('zip', () => {
|
|
120
|
+
test('zips arrays', () => {
|
|
121
|
+
expect(zip([1, 2], ['a', 'b'], [true, false])).toEqual([[1, 'a', true], [2, 'b', false]]);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('range', () => {
|
|
126
|
+
test('creates range', () => {
|
|
127
|
+
expect(range(1, 5)).toEqual([1, 2, 3, 4, 5]);
|
|
128
|
+
expect(range(0, 10, 2)).toEqual([0, 2, 4, 6, 8, 10]);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('max', () => {
|
|
133
|
+
test('finds maximum value', () => {
|
|
134
|
+
expect(max([1, 5, 3, 9, 2])).toBe(9);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('min', () => {
|
|
139
|
+
test('finds minimum value', () => {
|
|
140
|
+
expect(min([1, 5, 3, 9, 2])).toBe(1);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('sum', () => {
|
|
145
|
+
test('calculates sum', () => {
|
|
146
|
+
expect(sum([1, 2, 3, 4, 5])).toBe(15);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('average', () => {
|
|
151
|
+
test('calculates average', () => {
|
|
152
|
+
expect(average([1, 2, 3, 4, 5])).toBe(3);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe('countOccurrences', () => {
|
|
157
|
+
test('counts occurrences', () => {
|
|
158
|
+
expect(countOccurrences([1, 2, 2, 3, 3, 3]))
|
|
159
|
+
.toEqual({ '1': 1, '2': 2, '3': 3 });
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('remove', () => {
|
|
164
|
+
test('removes value from array', () => {
|
|
165
|
+
expect(remove([1, 2, 3, 2, 4], 2)).toEqual([1, 3, 4]);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('take', () => {
|
|
170
|
+
test('takes first n elements', () => {
|
|
171
|
+
expect(take([1, 2, 3, 4, 5], 3)).toEqual([1, 2, 3]);
|
|
172
|
+
expect(take([10, 21, 31, 41, 51], 4)).toEqual([10, 21, 31, 41]);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe('drop', () => {
|
|
177
|
+
test('drops first n elements', () => {
|
|
178
|
+
expect(drop([1, 2, 3, 4, 5], 2)).toEqual([3, 4, 5]);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe('includesAll', () => {
|
|
183
|
+
test('checks if includes all values', () => {
|
|
184
|
+
expect(includesAll([1, 2, 3, 4], [2, 3])).toBe(true);
|
|
185
|
+
expect(includesAll([1, 2, 3], [2, 5])).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe('includesAny', () => {
|
|
190
|
+
test('checks if includes any value', () => {
|
|
191
|
+
expect(includesAny([1, 2, 3], [3, 4, 5])).toBe(true);
|
|
192
|
+
expect(includesAny([1, 2, 3], [4, 5, 6])).toBe(false);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe('rotate', () => {
|
|
197
|
+
test('rotates array', () => {
|
|
198
|
+
expect(rotate([1, 2, 3, 4, 5], 2)).toEqual([3, 4, 5, 1, 2]);
|
|
199
|
+
expect(rotate([1, 2, 3, 4, 5], 1)).toEqual([2, 3, 4, 5, 1]);
|
|
200
|
+
expect(rotate([1, 2, 3, 4, 5], -1)).toEqual([5, 1, 2, 3, 4]);
|
|
201
|
+
expect(rotate([1, 2, 3, 4, 5], -2)).toEqual([4, 5, 1, 2, 3]);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|