parent
2a0c2b0629
commit
3316818633
@ -1,126 +0,0 @@ |
||||
/* eslint-disable @typescript-eslint/no-explicit-any */ |
||||
import type { |
||||
InterfaceType, |
||||
PrimitiveType, |
||||
TraverserTypes, |
||||
UnionType, |
||||
} from "."; |
||||
|
||||
export type InterfaceVisitorFunction< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends InterfaceType<keyof Types>, |
||||
Context, |
||||
> = (originalData: Type["type"], context: Context) => Promise<void>; |
||||
|
||||
export type InterfaceVisitorPropertyFunction< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends InterfaceType<keyof Types>, |
||||
PropertyName extends keyof Type["properties"], |
||||
Context, |
||||
> = ( |
||||
originalData: Types[Type["properties"][PropertyName]]["type"], |
||||
context: Context, |
||||
) => Promise<void>; |
||||
|
||||
export type InterfaceVisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends InterfaceType<keyof Types>, |
||||
Context, |
||||
> = { |
||||
visitor: InterfaceVisitorFunction<Types, Type, Context>; |
||||
properties: { |
||||
[PropertyName in keyof Type["properties"]]: InterfaceVisitorPropertyFunction< |
||||
Types, |
||||
Type, |
||||
PropertyName, |
||||
Context |
||||
>; |
||||
}; |
||||
}; |
||||
|
||||
export type UnionVisitorFunction< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends UnionType<keyof Types>, |
||||
Context, |
||||
> = (originalData: Type["type"], context: Context) => Promise<void>; |
||||
|
||||
export type UnionVisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends UnionType<keyof Types>, |
||||
Context, |
||||
> = UnionVisitorFunction<Types, Type, Context>; |
||||
|
||||
export type PrimitiveVisitorFunction<Type extends PrimitiveType, Context> = ( |
||||
originalData: Type["type"], |
||||
context: Context, |
||||
) => Promise<void>; |
||||
|
||||
export type PrimitiveVisitorDefinition< |
||||
Type extends PrimitiveType, |
||||
Context, |
||||
> = PrimitiveVisitorFunction<Type, Context>; |
||||
|
||||
export type VisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Context, |
||||
> = Types[TypeName] extends InterfaceType<keyof Types> |
||||
? InterfaceVisitorDefinition<Types, Types[TypeName], Context> |
||||
: Types[TypeName] extends UnionType<keyof Types> |
||||
? UnionVisitorDefinition<Types, Types[TypeName], Context> |
||||
: Types[TypeName] extends PrimitiveType |
||||
? PrimitiveVisitorDefinition<Types[TypeName], Context> |
||||
: never; |
||||
|
||||
export type Visitors<Types extends TraverserTypes<any>, Context> = { |
||||
[TypeName in keyof Types]: VisitorDefinition<Types, TypeName, Context>; |
||||
}; |
||||
|
||||
/** |
||||
* Input |
||||
*/ |
||||
export type InterfaceVisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends InterfaceType<keyof Types>, |
||||
Context, |
||||
> = { |
||||
visitor: InterfaceVisitorFunction<Types, Type, Context>; |
||||
properties?: Partial<{ |
||||
[PropertyName in keyof Type["properties"]]: InterfaceVisitorPropertyFunction< |
||||
Types, |
||||
Type, |
||||
PropertyName, |
||||
Context |
||||
>; |
||||
}>; |
||||
}; |
||||
|
||||
export type UnionVisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
Type extends UnionType<keyof Types>, |
||||
Context, |
||||
> = UnionVisitorFunction<Types, Type, Context>; |
||||
|
||||
export type PrimitiveVisitorInputDefinition< |
||||
Type extends PrimitiveType, |
||||
Context, |
||||
> = PrimitiveVisitorFunction<Type, Context>; |
||||
|
||||
export type VisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Context, |
||||
> = Types[TypeName] extends InterfaceType<keyof Types> |
||||
? InterfaceVisitorInputDefinition<Types, Types[TypeName], Context> |
||||
: Types[TypeName] extends UnionType<keyof Types> |
||||
? UnionVisitorInputDefinition<Types, Types[TypeName], Context> |
||||
: Types[TypeName] extends PrimitiveType |
||||
? PrimitiveVisitorInputDefinition<Types[TypeName], Context> |
||||
: never; |
||||
|
||||
export type VisitorsInput< |
||||
Types extends TraverserTypes<any>, |
||||
Context, |
||||
> = Partial<{ |
||||
[TypeName in keyof Types]: VisitorInputDefinition<Types, TypeName, Context>; |
||||
}>; |
@ -1,5 +1,9 @@ |
||||
/* eslint-disable @typescript-eslint/no-explicit-any */ |
||||
import type { BaseReturnType, BaseTraverserTypes, TraverserTypes } from ".."; |
||||
import type { |
||||
BaseReturnType, |
||||
BaseTraverserTypes, |
||||
TraverserTypes, |
||||
} from "../../"; |
||||
import type { TransformerReturnTypes } from "../TransformerReturnTypes"; |
||||
import { transformerInterfaceSubTraverser } from "./TransformerInterfaceSubTraverser"; |
||||
import { transformerPrimitiveSubTraverser } from "./TransformerPrimitiveSubTraverser"; |
@ -1,4 +1,4 @@ |
||||
import type { KeyTypes } from "../.."; |
||||
import type { KeyTypes } from "../../../"; |
||||
import { MultiMap } from "./MultiMap"; |
||||
import { MultiSet } from "./MultiSet"; |
||||
import type { TransformerSubTraverserExecutingPromises } from "./transformerSubTraverserTypes"; |
@ -0,0 +1,157 @@ |
||||
/* eslint-disable @typescript-eslint/no-explicit-any */ |
||||
import type { |
||||
InterfaceType, |
||||
PrimitiveType, |
||||
TraverserTypes, |
||||
UnionType, |
||||
} from "../"; |
||||
import type { InterfaceInstanceNode } from "../instanceGraph/nodes/InterfaceInstanceNode"; |
||||
import type { PrimitiveInstanceNode } from "../instanceGraph/nodes/PrimitiveInstanceNode"; |
||||
import type { UnionInstanceNode } from "../instanceGraph/nodes/UnionInstanceNode"; |
||||
|
||||
export type InterfaceVisitorFunction< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends InterfaceType<keyof Types> & Types[TypeName], |
||||
Context, |
||||
> = ( |
||||
originalData: Type["type"], |
||||
node: InterfaceInstanceNode<Types, TypeName, Type>, |
||||
context: Context, |
||||
) => Promise<void>; |
||||
|
||||
export type InterfaceVisitorPropertyFunction< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends InterfaceType<keyof Types> & Types[TypeName], |
||||
PropertyName extends keyof Type["properties"], |
||||
Context, |
||||
> = ( |
||||
originalData: Types[Type["properties"][PropertyName]]["type"], |
||||
node: InterfaceInstanceNode<Types, TypeName, Type>, |
||||
context: Context, |
||||
) => Promise<void>; |
||||
|
||||
export type InterfaceVisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends InterfaceType<keyof Types> & Types[TypeName], |
||||
Context, |
||||
> = { |
||||
visitor: InterfaceVisitorFunction<Types, TypeName, Type, Context>; |
||||
properties: { |
||||
[PropertyName in keyof Type["properties"]]: InterfaceVisitorPropertyFunction< |
||||
Types, |
||||
TypeName, |
||||
Type, |
||||
PropertyName, |
||||
Context |
||||
>; |
||||
}; |
||||
}; |
||||
|
||||
export type UnionVisitorFunction< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends UnionType<keyof Types> & Types[TypeName], |
||||
Context, |
||||
> = ( |
||||
originalData: Type["type"], |
||||
node: UnionInstanceNode<Types, TypeName, Type>, |
||||
context: Context, |
||||
) => Promise<void>; |
||||
|
||||
export type UnionVisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends UnionType<keyof Types> & Types[TypeName], |
||||
Context, |
||||
> = UnionVisitorFunction<Types, TypeName, Type, Context>; |
||||
|
||||
export type PrimitiveVisitorFunction< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends PrimitiveType & Types[TypeName], |
||||
Context, |
||||
> = ( |
||||
originalData: Type["type"], |
||||
node: PrimitiveInstanceNode<Types, TypeName, Type>, |
||||
context: Context, |
||||
) => Promise<void>; |
||||
|
||||
export type PrimitiveVisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends PrimitiveType & Types[TypeName], |
||||
Context, |
||||
> = PrimitiveVisitorFunction<Types, TypeName, Type, Context>; |
||||
|
||||
export type VisitorDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Context, |
||||
> = Types[TypeName] extends InterfaceType<keyof Types> |
||||
? InterfaceVisitorDefinition<Types, TypeName, Types[TypeName], Context> |
||||
: Types[TypeName] extends UnionType<keyof Types> |
||||
? UnionVisitorDefinition<Types, TypeName, Types[TypeName], Context> |
||||
: Types[TypeName] extends PrimitiveType |
||||
? PrimitiveVisitorDefinition<Types, TypeName, Types[TypeName], Context> |
||||
: never; |
||||
|
||||
export type Visitors<Types extends TraverserTypes<any>, Context> = { |
||||
[TypeName in keyof Types]: VisitorDefinition<Types, TypeName, Context>; |
||||
}; |
||||
|
||||
/** |
||||
* Input |
||||
*/ |
||||
export type InterfaceVisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends InterfaceType<keyof Types> & Types[TypeName], |
||||
Context, |
||||
> = { |
||||
visitor: InterfaceVisitorFunction<Types, TypeName, Type, Context>; |
||||
properties?: Partial<{ |
||||
[PropertyName in keyof Type["properties"]]: InterfaceVisitorPropertyFunction< |
||||
Types, |
||||
TypeName, |
||||
Type, |
||||
PropertyName, |
||||
Context |
||||
>; |
||||
}>; |
||||
}; |
||||
|
||||
export type UnionVisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends UnionType<keyof Types> & Types[TypeName], |
||||
Context, |
||||
> = UnionVisitorFunction<Types, TypeName, Type, Context>; |
||||
|
||||
export type PrimitiveVisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Type extends PrimitiveType & Types[TypeName], |
||||
Context, |
||||
> = PrimitiveVisitorFunction<Types, TypeName, Type, Context>; |
||||
|
||||
export type VisitorInputDefinition< |
||||
Types extends TraverserTypes<any>, |
||||
TypeName extends keyof Types, |
||||
Context, |
||||
> = Types[TypeName] extends InterfaceType<keyof Types> |
||||
? InterfaceVisitorInputDefinition<Types, TypeName, Types[TypeName], Context> |
||||
: Types[TypeName] extends UnionType<keyof Types> |
||||
? UnionVisitorInputDefinition<Types, TypeName, Types[TypeName], Context> |
||||
: Types[TypeName] extends PrimitiveType |
||||
? PrimitiveVisitorInputDefinition<Types, TypeName, Types[TypeName], Context> |
||||
: never; |
||||
|
||||
export type VisitorsInput< |
||||
Types extends TraverserTypes<any>, |
||||
Context, |
||||
> = Partial<{ |
||||
[TypeName in keyof Types]: VisitorInputDefinition<Types, TypeName, Context>; |
||||
}>; |
@ -1,5 +1,5 @@ |
||||
/* eslint-disable @typescript-eslint/no-explicit-any */ |
||||
import type { BaseTraverserTypes, TraverserTypes } from ".."; |
||||
import type { BaseTraverserTypes, TraverserTypes } from "../../"; |
||||
import type { |
||||
VisitorSubTraverser, |
||||
VisitorSubTraverserGlobals, |
@ -0,0 +1,156 @@ |
||||
import type { TraverserDefinitions, ValidateTraverserTypes } from "../../src"; |
||||
import { InstanceGraph } from "../../src/instanceGraph/instanceGraph"; |
||||
|
||||
describe("InstanceGraph", () => { |
||||
/** |
||||
* Types |
||||
*/ |
||||
type Element = "Water" | "Earth" | "Fire" | "Air"; |
||||
interface Bender { |
||||
name: string; |
||||
element: Element; |
||||
friends: Person[]; |
||||
} |
||||
interface NonBender { |
||||
name: string; |
||||
friends: Person[]; |
||||
} |
||||
type Person = Bender | NonBender; |
||||
|
||||
/** |
||||
* Raw Data to Traverse |
||||
*/ |
||||
const aang: Bender = { |
||||
name: "Aang", |
||||
element: "Air", |
||||
friends: [], |
||||
}; |
||||
const sokka: NonBender = { |
||||
name: "Sokka", |
||||
friends: [], |
||||
}; |
||||
const katara: Bender = { |
||||
name: "Katara", |
||||
element: "Water", |
||||
friends: [], |
||||
}; |
||||
aang.friends.push(sokka, katara); |
||||
sokka.friends.push(aang, katara); |
||||
katara.friends.push(aang, sokka); |
||||
|
||||
/** |
||||
* Traverser Types |
||||
*/ |
||||
type AvatarTraverserTypes = ValidateTraverserTypes<{ |
||||
Element: { |
||||
kind: "primitive"; |
||||
type: Element; |
||||
}; |
||||
Bender: { |
||||
kind: "interface"; |
||||
type: Bender; |
||||
properties: { |
||||
element: "Element"; |
||||
friends: "Person"; |
||||
}; |
||||
}; |
||||
NonBender: { |
||||
kind: "interface"; |
||||
type: NonBender; |
||||
properties: { |
||||
friends: "Person"; |
||||
}; |
||||
}; |
||||
Person: { |
||||
kind: "union"; |
||||
type: Person; |
||||
typeNames: "Bender" | "NonBender"; |
||||
}; |
||||
}>; |
||||
|
||||
/** |
||||
* Create the traverser definition |
||||
*/ |
||||
const avatarTraverserDefinition: TraverserDefinitions<AvatarTraverserTypes> = |
||||
{ |
||||
Element: { |
||||
kind: "primitive", |
||||
}, |
||||
Bender: { |
||||
kind: "interface", |
||||
properties: { |
||||
element: "Element", |
||||
friends: "Person", |
||||
}, |
||||
}, |
||||
NonBender: { |
||||
kind: "interface", |
||||
properties: { |
||||
friends: "Person", |
||||
}, |
||||
}, |
||||
Person: { |
||||
kind: "union", |
||||
selector: (item) => { |
||||
return (item as Bender).element ? "Bender" : "NonBender"; |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
describe("Build Instance Graph", () => { |
||||
it("returns child nodes when child methods are called.", () => { |
||||
const graph = new InstanceGraph(avatarTraverserDefinition); |
||||
const aangBender = graph.getNodeFor(aang, "Bender"); |
||||
expect(aangBender.typeName).toBe("Bender"); |
||||
expect(aangBender.instance.name).toBe("Aang"); |
||||
// child
|
||||
const aangElement = aangBender.child("element"); |
||||
expect(aangElement.instance).toBe("Air"); |
||||
expect(aangElement.typeName).toBe("Element"); |
||||
const aangFriends = aangBender.child("friends"); |
||||
expect(aangFriends.length).toBe(2); |
||||
const sokkaPerson = aangFriends[0]; |
||||
const kataraPerson = aangFriends[1]; |
||||
expect(sokkaPerson.instance.name).toBe("Sokka"); |
||||
expect(kataraPerson.instance.name).toBe("Katara"); |
||||
expect(sokkaPerson.typeName).toBe("Person"); |
||||
expect(kataraPerson.typeName).toBe("Person"); |
||||
const sokkaNonBender = sokkaPerson.child(); |
||||
expect(sokkaNonBender.instance.name).toBe("Sokka"); |
||||
expect(sokkaNonBender.typeName).toBe("NonBender"); |
||||
if (sokkaNonBender.typeName === "NonBender") { |
||||
const aangPerson = sokkaNonBender.child("friends")[0]; |
||||
const aangBender2 = aangPerson.child(); |
||||
expect(aangBender2).toBe(aangBender); |
||||
} |
||||
// allChildren
|
||||
const [childElemement, childSokka, childKatara] = |
||||
aangBender.allChildren(); |
||||
expect(childElemement.instance).toBe("Air"); |
||||
expect((childSokka.instance as NonBender).name).toBe("Sokka"); |
||||
expect((childKatara.instance as Bender).name).toBe("Katara"); |
||||
const childOfSokkaPerson = sokkaPerson.allChildren(); |
||||
expect(childOfSokkaPerson.length).toBe(1); |
||||
expect(childOfSokkaPerson[0].instance.name).toBe("Sokka"); |
||||
}); |
||||
|
||||
it("returns parent nodes when parent methods are called.", () => { |
||||
const graph = new InstanceGraph(avatarTraverserDefinition); |
||||
const aangBender = graph.getNodeFor(aang, "Bender"); |
||||
// parent
|
||||
const [aangPerson] = aangBender.parent("Person"); |
||||
expect(aangPerson.instance.name).toBe("Aang"); |
||||
expect(aangPerson.typeName).toBe("Person"); |
||||
const [sokkaNonBender] = aangPerson.parent("NonBender", "friends"); |
||||
const [kataraBender] = aangPerson.parent("Bender", "friends"); |
||||
expect(sokkaNonBender.typeName).toBe("NonBender"); |
||||
expect(sokkaNonBender.instance.name).toBe("Sokka"); |
||||
expect(kataraBender.typeName).toBe("Bender"); |
||||
expect(kataraBender.instance.name).toBe("Katara"); |
||||
}); |
||||
}); |
||||
|
||||
describe("Transformer", () => { |
||||
it("transforms", () => {}); |
||||
}); |
||||
}); |
@ -1,7 +1,7 @@ |
||||
import type { TraverserDefinition } from "../../../src"; |
||||
import type { TraverserDefinitions } from "../../../src"; |
||||
import type { AvatarTraverserTypes, Bender } from "./AvatarTraverserTypes"; |
||||
|
||||
export const avatarTraverserDefinition: TraverserDefinition<AvatarTraverserTypes> = |
||||
export const avatarTraverserDefinition: TraverserDefinitions<AvatarTraverserTypes> = |
||||
{ |
||||
Element: { |
||||
kind: "primitive", |
@ -1,161 +1,19 @@ |
||||
import type { |
||||
TraverserDefinitions, |
||||
ValidateTraverserTypes, |
||||
} from "../../../src"; |
||||
import { InstanceGraph } from "../../../src/instanceGraph/instanceGraph"; |
||||
import { BrokenAvatarTransformer } from "./AvatarBrokenTransformer"; |
||||
import { AvatarErroringTransformer } from "./AvatarErroringTransformer"; |
||||
import { aang } from "./sampleData"; |
||||
|
||||
describe("AvatarExample", () => { |
||||
/** |
||||
* Types |
||||
*/ |
||||
type Element = "Water" | "Earth" | "Fire" | "Air"; |
||||
interface Bender { |
||||
name: string; |
||||
element: Element; |
||||
friends: Person[]; |
||||
} |
||||
interface NonBender { |
||||
name: string; |
||||
friends: Person[]; |
||||
} |
||||
type Person = Bender | NonBender; |
||||
|
||||
/** |
||||
* Raw Data to Traverse |
||||
*/ |
||||
const aang: Bender = { |
||||
name: "Aang", |
||||
element: "Air", |
||||
friends: [], |
||||
}; |
||||
const sokka: NonBender = { |
||||
name: "Sokka", |
||||
friends: [], |
||||
}; |
||||
const katara: Bender = { |
||||
name: "Katara", |
||||
element: "Water", |
||||
friends: [], |
||||
}; |
||||
aang.friends.push(sokka, katara); |
||||
sokka.friends.push(aang, katara); |
||||
katara.friends.push(aang, sokka); |
||||
|
||||
/** |
||||
* Traverser Types |
||||
*/ |
||||
type AvatarTraverserTypes = ValidateTraverserTypes<{ |
||||
Element: { |
||||
kind: "primitive"; |
||||
type: Element; |
||||
}; |
||||
Bender: { |
||||
kind: "interface"; |
||||
type: Bender; |
||||
properties: { |
||||
element: "Element"; |
||||
friends: "Person"; |
||||
}; |
||||
}; |
||||
NonBender: { |
||||
kind: "interface"; |
||||
type: NonBender; |
||||
properties: { |
||||
friends: "Person"; |
||||
}; |
||||
}; |
||||
Person: { |
||||
kind: "union"; |
||||
type: Person; |
||||
typeNames: "Bender" | "NonBender"; |
||||
}; |
||||
}>; |
||||
|
||||
/** |
||||
* Create the traverser definition |
||||
*/ |
||||
const avatarTraverserDefinition: TraverserDefinitions<AvatarTraverserTypes> = |
||||
{ |
||||
Element: { |
||||
kind: "primitive", |
||||
}, |
||||
Bender: { |
||||
kind: "interface", |
||||
properties: { |
||||
element: "Element", |
||||
friends: "Person", |
||||
}, |
||||
}, |
||||
NonBender: { |
||||
kind: "interface", |
||||
properties: { |
||||
friends: "Person", |
||||
}, |
||||
}, |
||||
Person: { |
||||
kind: "union", |
||||
selector: (item) => { |
||||
return (item as Bender).element ? "Bender" : "NonBender"; |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
describe("Build Instance Graph", () => { |
||||
it("returns child nodes when child methods are called.", () => { |
||||
const graph = new InstanceGraph(avatarTraverserDefinition); |
||||
const aangBender = graph.getNodeFor(aang, "Bender"); |
||||
expect(aangBender.typeName).toBe("Bender"); |
||||
expect(aangBender.instance.name).toBe("Aang"); |
||||
// child
|
||||
const aangElement = aangBender.child("element"); |
||||
expect(aangElement.instance).toBe("Air"); |
||||
expect(aangElement.typeName).toBe("Element"); |
||||
const aangFriends = aangBender.child("friends"); |
||||
expect(aangFriends.length).toBe(2); |
||||
const sokkaPerson = aangFriends[0]; |
||||
const kataraPerson = aangFriends[1]; |
||||
expect(sokkaPerson.instance.name).toBe("Sokka"); |
||||
expect(kataraPerson.instance.name).toBe("Katara"); |
||||
expect(sokkaPerson.typeName).toBe("Person"); |
||||
expect(kataraPerson.typeName).toBe("Person"); |
||||
const sokkaNonBender = sokkaPerson.child(); |
||||
expect(sokkaNonBender.instance.name).toBe("Sokka"); |
||||
expect(sokkaNonBender.typeName).toBe("NonBender"); |
||||
if (sokkaNonBender.typeName === "NonBender") { |
||||
const aangPerson = sokkaNonBender.child("friends")[0]; |
||||
const aangBender2 = aangPerson.child(); |
||||
expect(aangBender2).toBe(aangBender); |
||||
} |
||||
// allChildren
|
||||
const [childElemement, childSokka, childKatara] = |
||||
aangBender.allChildren(); |
||||
expect(childElemement.instance).toBe("Air"); |
||||
expect((childSokka.instance as NonBender).name).toBe("Sokka"); |
||||
expect((childKatara.instance as Bender).name).toBe("Katara"); |
||||
const childOfSokkaPerson = sokkaPerson.allChildren(); |
||||
expect(childOfSokkaPerson.length).toBe(1); |
||||
expect(childOfSokkaPerson[0].instance.name).toBe("Sokka"); |
||||
}); |
||||
|
||||
it("returns parent nodes when parent methods are called.", () => { |
||||
const graph = new InstanceGraph(avatarTraverserDefinition); |
||||
const aangBender = graph.getNodeFor(aang, "Bender"); |
||||
// parent
|
||||
const [aangPerson] = aangBender.parent("Person"); |
||||
expect(aangPerson.instance.name).toBe("Aang"); |
||||
expect(aangPerson.typeName).toBe("Person"); |
||||
const [sokkaNonBender] = aangPerson.parent("NonBender", "friends"); |
||||
const [kataraBender] = aangPerson.parent("Bender", "friends"); |
||||
expect(sokkaNonBender.typeName).toBe("NonBender"); |
||||
expect(sokkaNonBender.instance.name).toBe("Sokka"); |
||||
expect(kataraBender.typeName).toBe("Bender"); |
||||
expect(kataraBender.instance.name).toBe("Katara"); |
||||
}); |
||||
describe("Avatar", () => { |
||||
it("Throws an error before entering an infinite loop", async () => { |
||||
await expect( |
||||
BrokenAvatarTransformer.transform(aang, "Bender", undefined), |
||||
).rejects.toThrow( |
||||
`Circular dependency found. Use the 'setReturnPointer' function. The loop includes the 'Bender' type`, |
||||
); |
||||
}); |
||||
|
||||
describe("Transformer", () => { |
||||
it("transforms", () => { |
||||
|
||||
}) |
||||
it("Bubbles errors", async () => { |
||||
await expect( |
||||
AvatarErroringTransformer.transform(aang, "Bender", undefined), |
||||
).rejects.toThrow("No Non Benders Allowed"); |
||||
}); |
||||
}); |
||||
|
@ -1,19 +0,0 @@ |
||||
import { BrokenAvatarTransformer } from "./AvatarBrokenTransformer"; |
||||
import { AvatarErroringTransformer } from "./AvatarErroringTransformer"; |
||||
import { aang } from "./sampleData"; |
||||
|
||||
describe("Avatar", () => { |
||||
it("Throws an error before entering an infinite loop", async () => { |
||||
await expect( |
||||
BrokenAvatarTransformer.transform(aang, "Bender", undefined), |
||||
).rejects.toThrow( |
||||
`Circular dependency found. Use the 'setReturnPointer' function. The loop includes the 'Bender' type`, |
||||
); |
||||
}); |
||||
|
||||
it("Bubbles errors", async () => { |
||||
await expect( |
||||
AvatarErroringTransformer.transform(aang, "Bender", undefined), |
||||
).rejects.toThrow("No Non Benders Allowed"); |
||||
}); |
||||
}); |
Loading…
Reference in new issue