Skip to content

Commit fab0623

Browse files
Merge pull request #151 from abruzzihraig/master
fix(union): Union.create() shouldn't ignore extra arguments
2 parents b379765 + 7a3999e commit fab0623

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

src/types/type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ export abstract class Type<S, T> implements IType<S, T> {
6767
import { fail } from "../utils"
6868
import { IMSTNode } from "../core/mst-node"
6969
import { IContext, IValidationResult } from "./type-checker"
70+
import { MSTAdministration } from "../core/mst-node-administration"

src/types/utility-types/union.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import {isType, IType, TypeFlags, Type} from "../type"
1+
import { isType, IType, TypeFlags, Type } from "../type"
22
import { IContext, IValidationResult, typeCheckSuccess, typeCheckFailure, flattenTypeErrors, typecheck } from "../type-checker"
3-
import {fail} from "../../utils"
3+
import { MSTAdministration } from "../../core/mst-node-administration"
4+
import { fail } from "../../utils"
45

56
export type ITypeDispatcher = (snapshot: any) => IType<any, any>
67

@@ -10,7 +11,7 @@ export class Union extends Type<any, any> {
1011

1112
get flags () {
1213
let result: TypeFlags = 0
13-
14+
1415
this.types.forEach(type => {
1516
result |= type.flags
1617
})
@@ -28,20 +29,20 @@ export class Union extends Type<any, any> {
2829
return "(" + this.types.map(factory => factory.describe()).join(" | ") + ")"
2930
}
3031

31-
create(value: any) {
32+
create(value: any, environment: any = undefined, parent: MSTAdministration | null = null, subpath: string = "") {
3233
typecheck(this, value)
3334

3435
// try the dispatcher, if defined
3536
if (this.dispatcher !== null) {
36-
return this.dispatcher(value).create(value)
37+
return (this.dispatcher(value) as any).create(value, environment, parent, subpath)
3738
}
3839

3940
// find the most accomodating type
4041
const applicableTypes = this.types.filter(type => type.is(value))
4142
if (applicableTypes.length > 1)
4243
return fail(`Ambiguos snapshot ${JSON.stringify(value)} for union ${this.name}. Please provide a dispatch in the union declaration.`)
4344

44-
return applicableTypes[0].create(value)
45+
return (applicableTypes[0] as any).create(value, environment, parent, subpath)
4546
}
4647

4748
validate(value: any, context: IContext): IValidationResult {

test/union.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {types} from "../src"
1+
import {types, hasParent, tryResolve} from "../src"
22
import {test} from "ava"
33

44
const createTestFactories = () => {
@@ -22,7 +22,11 @@ const createTestFactories = () => {
2222

2323
const DispatchPlane = types.union(snapshot => snapshot && "height" in snapshot ? Box : Square, Box, Square)
2424

25-
return {Box, Square, Cube, Plane, DispatchPlane, Heighed}
25+
const Block = types.model("Block", {
26+
list: types.array(Heighed)
27+
})
28+
29+
return {Box, Square, Cube, Plane, DispatchPlane, Heighed, Block}
2630
}
2731

2832
test("it should complain about no dispatch method", (t) => {
@@ -34,6 +38,17 @@ test("it should complain about no dispatch method", (t) => {
3438
snapshot \`{"width":2,"height":2}\` is not assignable to type: \`Box | Square\` (Multiple types are applicable and no dispatch method is defined for the union), expected an instance of \`Box | Square\` or a snapshot like \`({ width: number; height: number } | { width: number })\` instead.`)
3539
})
3640

41+
test("it should have parent whenever creating or applying from a complex data structure to a model which has Union typed children", (t) => {
42+
const {Block, Heighed} = createTestFactories()
43+
const block = Block.create({
44+
list: [{width: 2, height: 2}]
45+
})
46+
47+
const child = tryResolve(block, "./list/0")
48+
49+
hasParent(child) ? t.pass() : t.fail()
50+
})
51+
3752
test("it should complain about no dispatch method and multiple applicable types", (t) => {
3853
const {Heighed} = createTestFactories()
3954

@@ -90,4 +105,4 @@ test("it should compute exact union types - 2", (t) => {
90105

91106
t.deepEqual(DispatchPlane.is(Box.create({ width: 3, height: 2})), true)
92107
t.deepEqual(DispatchPlane.is(Square.create({ width: 3, height: 2} as any)), true)
93-
})
108+
})

0 commit comments

Comments
 (0)