@conjecture-dev/g-std
Version:
A collection of TypeScript utility functions for common programming tasks
215 lines • 8.55 kB
JavaScript
import assert from 'node:assert';
import { describe, test } from 'node:test';
import { objectMap, arrayFilterMap, all, enumerate, findDuplicates, f, objectFromEntries, objectEntries, canonicalize, Success, ChangeDetector, ice, zip, zipOutcome, sorted, consecutive, safeParseInt, clamp, isNonEmpty, deepObjectFilterK, assertNever, any, promiseWithResolvers, throuncedAsync, flatten, safeFindIndex, allNonNull, Failure, } from '../index';
void describe('Examples', () => {
// @function objectMap
void test('objectMap example', () => {
const obj = { a: 1, b: 2, c: 3 };
const doubled = objectMap(obj, (_, value) => value * 2);
assert.deepStrictEqual(doubled, { a: 2, b: 4, c: 6 });
});
// @function arrayFilterMap
void test('arrayFilterMap example', () => {
const numbers = [1, 2, 3, 4, 5];
const evenDoubled = arrayFilterMap(numbers, x => x % 2 === 0 ? ['some', x * 2] : ['none']);
assert.deepStrictEqual(evenDoubled, [4, 8]);
});
// @function all
void test('all example', () => {
assert.strictEqual(all([1, 2, 3]), true);
assert.strictEqual(all([1, 0, 3]), false);
});
// @function enumerate
void test('enumerate example', () => {
const arr = ['a', 'b', 'c'];
const enumerated = enumerate(arr);
assert.deepStrictEqual(enumerated, [[0, 'a'], [1, 'b'], [2, 'c']]);
});
// @function findDuplicates
void test('findDuplicates example', () => {
const arr = [1, 2, 2, 3, 3, 3];
const duplicates = findDuplicates(arr);
assert.deepStrictEqual(duplicates, [2, 3, 3]);
});
// @function f
void test('f template literal example', () => {
const name = 'Alice';
const age = 25;
const result = f `${name} is ${age} years old`;
assert.strictEqual(result, 'Alice is 25 years old');
});
// @function objectFromEntries
void test('objectFromEntries example', () => {
const entries = [['a', 1], ['b', 2]];
const obj = objectFromEntries(entries);
assert.deepStrictEqual(obj, { a: 1, b: 2 });
});
// @function objectEntries
void test('objectEntries example', () => {
const obj = { a: 1, b: 2 };
const entries = objectEntries(obj);
assert.deepStrictEqual(entries, [['a', 1], ['b', 2]]);
});
// @function canonicalize
void test('canonicalize example', () => {
const obj1 = { b: 2, a: 1 };
const obj2 = { a: 1, b: 2 };
assert.strictEqual(canonicalize(obj1), canonicalize(obj2));
});
// @function ChangeDetector
void test('ChangeDetector example', () => {
const detector = new ChangeDetector();
assert.strictEqual(detector.hasChanged({ value: 1 }), true);
assert.strictEqual(detector.hasChanged({ value: 1 }), false);
assert.strictEqual(detector.hasChanged({ value: 2 }), true);
});
// @function ice
void test('ice example', () => {
const obj = { a: 1, b: 2 };
const frozen = ice(obj);
assert(Object.isFrozen(frozen));
});
// @function zip
void test('zip example', () => {
const arr1 = [1, 2, 3];
const arr2 = ['a', 'b', 'c'];
const zipped = zip(arr1, arr2);
assert.deepStrictEqual(zipped, [[1, 'a'], [2, 'b'], [3, 'c']]);
});
// @function zipOutcome
void test('zipOutcome example', () => {
const arr1 = [1, 2, 3];
const arr2 = ['a', 'b', 'c'];
const result = zipOutcome(arr1, arr2);
assert.deepStrictEqual(result, Success([[1, 'a'], [2, 'b'], [3, 'c']]));
});
// @function sorted
void test('sorted example', () => {
const arr = [3, 1, 2];
const sortedArr = sorted(arr);
assert.deepStrictEqual(sortedArr, [1, 2, 3]);
});
// @function consecutive
void test('consecutive example', () => {
const arr = [1, 2, 3, 4];
const pairs = consecutive(arr, 2);
assert.deepStrictEqual(pairs, [[1, 2], [2, 3], [3, 4]]);
});
// @function safeParseInt
void test('safeParseInt example', () => {
assert.strictEqual(safeParseInt('123'), 123);
assert.strictEqual(safeParseInt('abc'), null);
});
// @function clamp
void test('clamp example', () => {
assert.strictEqual(clamp(5, 0, 10), 5);
assert.strictEqual(clamp(-1, 0, 10), 0);
assert.strictEqual(clamp(11, 0, 10), 10);
});
// @function isNonEmpty
void test('isNonEmpty example', () => {
const arr1 = [1, 2, 3];
const arr2 = [];
assert.strictEqual(isNonEmpty(arr1), true);
assert.strictEqual(isNonEmpty(arr2), false);
if (isNonEmpty(arr1)) {
const first = arr1[0]; // TypeScript knows this is safe
assert.strictEqual(first, 1);
}
});
// @function deepObjectFilterK
void test('deepObjectFilterK example', () => {
const obj = {
a: 1,
b: {
c: 2,
d: 3,
},
e: [4, 5],
};
const filtered = deepObjectFilterK(obj, key => key !== 'd');
assert.deepStrictEqual(filtered, {
a: 1,
b: {
c: 2,
},
e: [4, 5],
});
});
// @function assertNever
void test('assertNever example', () => {
const getColorValue = (color) => {
switch (color) {
case 'red': return 1;
case 'blue': return 2;
case 'green': return 3;
default: return assertNever(color);
}
};
assert.strictEqual(getColorValue('red'), 1);
});
// @function any
void test('any example', () => {
assert.strictEqual(any([0, false, null]), false);
assert.strictEqual(any([0, true, null]), true);
assert.strictEqual(any([1, 2, 3]), true);
});
// @function promiseWithResolvers
void test('promiseWithResolvers example', async () => {
const { promise, resolve } = promiseWithResolvers();
setTimeout(() => resolve(42), 0);
const result = await promise;
assert.strictEqual(result, 42);
});
// @function throuncedAsync
void test('throuncedAsync example', async () => {
let executed = [];
const fn = async (x) => {
executed = [...executed, x];
return x;
};
const { fn: throttled } = throuncedAsync(fn, { throunceMs: 100 });
// First call executes immediately
const result1 = await throttled('first');
assert.deepStrictEqual(result1, Success('first'));
assert.deepStrictEqual(executed, ['first']);
// Second call within throunce window is throttled
const result2Promise = throttled('second');
await new Promise(resolve => setTimeout(resolve, 10));
assert.deepStrictEqual(executed, ['first'], 'Second call should not have executed yet');
// Third call overrides second call
const result3Promise = throttled('third');
await new Promise(resolve => setTimeout(resolve, 10));
assert.deepStrictEqual(executed, ['first'], 'Third call should not have executed yet');
// Wait for throunce window to pass
await new Promise(resolve => setTimeout(resolve, 150));
// Check results
assert.deepStrictEqual(await result2Promise, Failure('throttled'));
assert.deepStrictEqual(await result3Promise, Success('third'));
assert.deepStrictEqual(executed, ['first', 'third']);
});
// @function flatten
void test('flatten example', () => {
const arr = [[1, 2], [3], [4, 5]];
const flattened = flatten(arr);
assert.deepStrictEqual(flattened, [1, 2, 3, 4, 5]);
});
// @function safeFindIndex
void test('safeFindIndex example', () => {
const arr = [1, 2, 3, 4];
assert.strictEqual(safeFindIndex(arr, x => x === 2), 1);
assert.strictEqual(safeFindIndex(arr, x => x === 5), null);
});
// @function allNonNull
void test('allNonNull example', () => {
const arr1 = [1, 2, 3];
const arr2 = [1, null, 3];
assert.strictEqual(allNonNull(arr1), true);
assert.strictEqual(allNonNull(arr2), false);
if (allNonNull(arr1)) {
const sum = arr1.reduce((a, b) => a + b, 0); // TypeScript knows these are numbers
assert.strictEqual(sum, 6);
}
});
});
//# sourceMappingURL=examples.test.js.map