All files / src/mixin base.ts

50% Statements 3/6
100% Branches 0/0
33.33% Functions 1/3
50% Lines 3/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87                                                                                            1x 2x         2x                                                                    
import { makeFluent } from "../base";
import type { HKT } from "../base/hkt";
import { Mixin, type Input, type Return } from "../base/mixin";
 
export interface Base extends Mixin.HKT {
	new: (t: HKT.T<this>) => Input<typeof t> extends infer T
		? {
				/**
				 * Interospect value using the specified `callback` without
				 * modifying the value.
				 * @param callback The interospective callback
				 * @see `transform` to modify
				 * @from {@link Base `Base`}
				 * @example
				 * ```ts
				 * let x;
				 * const value = $(10).tap(v => { x = ++v }).value;
				 *
				 * expect(x).toBe(11);
				 * expect(value).toBe(10);
				 * ```
				 */
				tap(
					callback: (value: Readonly<T>) => void,
				): Return<T, typeof t>;
				/**
				 * Put value through or pipe value through the specified
				 * `callback` using the outputted return value as a new value.
				 * A.K.A., _transform_ the current value using a callback
				 * @param callback The transformative callback
				 * @from {@link Base `Base`}
				 * @example
				 * ```ts
				 * const value = $("Hello")
				 * 	.transform(v => v.toUpperCase())
				 * 	.value;
				 * expect(value).toBe("HELLO");
				 * ```
				 */
				transform<U>(
					callback: (value: T) => U,
				): Return<U, typeof t>;
			}
		: never;
}
 
export const Base = Mixin<Base>((value, $, fluent) => {
	$.tap = (callback: (value: unknown) => void) => {
		callback(value);
		return fluent(value);
	};
 
	$.transform = (callback: (value: unknown) => unknown) => {
		return fluent(callback(value));
	};
});
 
if (import.meta.vitest) {
	const { test, expect } = import.meta.vitest;
 
	const registry = [Base] as const;
	const $ = makeFluent(registry);
 
	test("tap()", () => {
		const value = 5;
		let out = 0;
 
		const result = $(value).tap((v) => (out = v)).value;
 
		expect(result).toBe(value);
		expect(out).toBe(value);
	});
 
	test("transform()", () => {
		const value = 5;
		const increment = (v: number) => v + 1;
 
		expect($(value).transform(increment).value).toBe(
			increment(value),
		);
 
		expect(
			$(value).transform(increment).transform(increment).value,
		).toBe(increment(increment(value)));
	});
}