Last active
December 3, 2025 15:49
-
-
Save dubzzz/2045286b2fe303ed8c94956ea8f0f064 to your computer and use it in GitHub Desktop.
Relationship builder in fast-check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import fc from 'fast-check'; | |
| type ArbitraryStructure<TSelfParts> = { [K in keyof TSelfParts]: fc.Arbitrary<TSelfParts[K]> }; | |
| type ArbitrariesStructure<TAllSelfParts> = { [Name in keyof TAllSelfParts]: ArbitraryStructure<TAllSelfParts[Name]> }; | |
| type Arity = '0-1' | '1' | 'many'; | |
| type Relationship<TTypeNames> = { arity: Arity; type: TTypeNames }; | |
| type SelfRelationshipsToOutput<TRelationships, TAll> = { | |
| [K in keyof TRelationships]: TRelationships[K] extends { arity: '0-1'; type: infer TTypeName extends keyof TAll } | |
| ? TAll[TTypeName] | undefined | |
| : TRelationships[K] extends { arity: '1'; type: infer TTypeName extends keyof TAll } | |
| ? TAll[TTypeName] | |
| : TRelationships[K] extends { arity: 'many'; type: infer TTypeName extends keyof TAll } | |
| ? TAll[TTypeName][] | |
| : never; | |
| }; | |
| type Prettify<T> = { [K in keyof T]: T[K] } & {}; | |
| type SingleOutput< | |
| TAllSelfParts, | |
| TRelationships extends { [Name in keyof TAllSelfParts]: { [K in string]: Relationship<keyof TAllSelfParts> } }, | |
| > = { | |
| [Name in keyof TAllSelfParts]: Prettify< | |
| TAllSelfParts[Name] & SelfRelationshipsToOutput<TRelationships[Name], SingleOutput<TAllSelfParts, TRelationships>> | |
| >; | |
| }; | |
| type ExpandOutput< | |
| TAllSelfParts, | |
| TRelationships extends { [Name in keyof TAllSelfParts]: { [K in string]: Relationship<keyof TAllSelfParts> } }, | |
| > = { | |
| [Name in keyof SingleOutput<TAllSelfParts, TRelationships>]: SingleOutput<TAllSelfParts, TRelationships>[Name][]; | |
| }; | |
| declare function rels< | |
| TAllSelfParts, | |
| TRelationships extends { [Name in keyof TAllSelfParts]: { [K in string]: Relationship<keyof TAllSelfParts> } }, | |
| >( | |
| arbitraries: ArbitrariesStructure<TAllSelfParts>, | |
| rules: TRelationships, | |
| ): Arbitrary<ExpandOutput<TAllSelfParts, TRelationships>>; | |
| const arb = rels( | |
| { | |
| employee: { | |
| name: fc.string(), | |
| }, | |
| team: { | |
| name: fc.string(), | |
| }, | |
| preference: {}, | |
| }, | |
| { | |
| employee: { | |
| manager: { arity: '0-1', type: 'employee' }, | |
| team: { arity: '1', type: 'team' }, | |
| preferences: { arity: 'many', type: 'preference' }, | |
| }, | |
| team: {}, | |
| preference: {}, | |
| }, | |
| ); | |
| fc.property(arb, (v) => { | |
| const name = v.employee[0].name; | |
| const manager = v.employee[0].manager; | |
| const preferences = v.employee[0].preferences; | |
| const team = v.employee[0].team; | |
| const teamName = v.team[0].name; | |
| }); | |
| /* Ideally: | |
| const arb = rels({ | |
| employee: { | |
| name: fc.string(), | |
| manager: { arity: '0-1', type: 'employee' }, | |
| team: { arity: '1', type: 'team' }, | |
| preferences: { arity: 'many', type: 'preference', exclusive: true }, | |
| }, | |
| team: { | |
| name: fc.string(), | |
| }, | |
| preference: {}, | |
| });*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment