UNPKG

polen

Version:

A framework for delightful GraphQL developer portals

121 lines (99 loc) 3.71 kB
import { Ts } from '@wollybeard/kit' import { objFilter, ObjOmit, ObjPick, objPolicyFilter } from './kit-temp.js' import type { ObjPolicyFilter } from './kit-temp.js' // Test object for all tests interface TestObj { a: string b: number c: boolean d: string[] } declare const testObj: TestObj // Test 1: objPolicyFilter with allow mode { const result = objPolicyFilter(`allow`, testObj, [`a`, `c`] as const) Ts.assertEqual<{ a: string; c: boolean }>()(result) } // Test 2: objPolicyFilter with deny mode { const result = objPolicyFilter(`deny`, testObj, [`a`, `c`] as const) Ts.assertEqual<{ b: number; d: string[] }>()(result) } // Test 3: objFilter returns Partial<T> { const result = objFilter(testObj, (key, value) => value !== `hello`) Ts.assertEqual<Partial<TestObj>>()(result) // All properties are optional Ts.assertSub<typeof result.a>()(undefined) Ts.assertSub<typeof result.b>()(undefined) Ts.assertSub<typeof result.c>()(undefined) Ts.assertSub<typeof result.d>()(undefined) } // Test 4: ObjPick type inference { const result = ObjPick(testObj, [`a`, `c`] as const) Ts.assertEqual<{ a: string; c: boolean }>()(result) } // Test 5: ObjOmit type inference { const result = ObjOmit(testObj, [`a`, `c`] as const) Ts.assertEqual<{ b: number; d: string[] }>()(result) } // Test 6: ObjPolicyFilter type-level function { type Allow = ObjPolicyFilter<TestObj, `a` | `c`, `allow`> type _TestAllow = Ts.AssertEqual<Allow, { a: string; c: boolean }> type Deny = ObjPolicyFilter<TestObj, `a` | `c`, `deny`> type _TestDeny = Ts.AssertEqual<Deny, { b: number; d: string[] }> type AllowEmpty = ObjPolicyFilter<TestObj, never, `allow`> type _TestAllowEmpty = Ts.AssertEqual<AllowEmpty, {}> type DenyEmpty = ObjPolicyFilter<TestObj, never, `deny`> type _TestDenyEmpty = Ts.AssertEqual<DenyEmpty, TestObj> } // Test 7: Edge cases { // Empty object const empty = {} const allowEmpty = objPolicyFilter(`allow`, empty, []) const denyEmpty = objPolicyFilter(`deny`, empty, []) const filterEmpty = objFilter(empty, () => true) Ts.assertEqual<{}>()(allowEmpty) Ts.assertEqual<{}>()(denyEmpty) Ts.assertEqual<{}>()(filterEmpty) // Single property object const single = { a: 1 } const allowSingle = objPolicyFilter(`allow`, single, [`a`] as const) const denySingle = objPolicyFilter(`deny`, single, [`a`] as const) const filterSingle = objFilter(single, () => true) Ts.assertEqual<{ a: number }>()(allowSingle) Ts.assertEqual<{}>()(denySingle) Ts.assertEqual<{ a?: number }>()(filterSingle) } // Test 8: Complex nested object { interface ComplexObj { nested: { a: string; b: number } array: string[] optional?: boolean readonly ro: string } const complexObj = {} as ComplexObj const picked = objPolicyFilter(`allow`, complexObj, [`nested`, `optional`] as const) Ts.assertEqual<{ nested: { a: string; b: number }; optional?: boolean }>()(picked) const omitted = objPolicyFilter(`deny`, complexObj, [`nested`, `optional`] as const) Ts.assertEqual<{ array: string[]; readonly ro: string }>()(omitted) const filtered = objFilter(complexObj, (key) => key !== `array`) Ts.assertEqual<Partial<ComplexObj>>()(filtered) } // Test 9: Keys parameter type inference { // With const assertion const keys1 = [`a`, `c`] as const const result1 = objPolicyFilter(`allow`, testObj, keys1) Ts.assertEqual<{ a: string; c: boolean }>()(result1) // Without const assertion (wider type) const keys2: (keyof TestObj)[] = [`a`, `c`] const result2 = objPolicyFilter(`allow`, testObj, keys2) // Result is a union of all possible picks type Result2 = typeof result2 // Pick<TestObj, keyof TestObj> }