Skip to content

Commit 8872b98

Browse files
committed
cue: fix PathCorrection tests
This fixes one bug in Reference, but mostly just means dealing with a different ordering of fields. Change-Id: I5a220bdb239ffddae2ba56efed2d591b4c86d78c Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7741 Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 6c49cf0 commit 8872b98

File tree

2 files changed

+132
-134
lines changed

2 files changed

+132
-134
lines changed

cue/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,13 @@ func reference(c *context, env *adt.Environment, r adt.Expr) (inst *Instance, pa
18301830
defer ctx.PopState(ctx.PushState(env, r.Source()))
18311831

18321832
switch x := r.(type) {
1833+
// TODO: do we need to handle Vertex as well, in case this is hard-wired?
1834+
// Probably not, as this results from dynamic content.
1835+
1836+
case *adt.NodeLink:
1837+
// TODO: consider getting rid of NodeLink.
1838+
inst, path = mkPath(c, nil, x.Node)
1839+
18331840
case *adt.FieldReference:
18341841
env := ctx.Env(x.UpCount)
18351842
inst, path = mkPath(c, nil, env.Vertex)

cue/types_test.go

Lines changed: 125 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,32 +2482,33 @@ func TestPathCorrection(t *testing.T) {
24822482
want string
24832483
skip bool
24842484
}{{
2485-
// // TODO: structural cycle.
2486-
// input: `
2487-
// a: b: {
2488-
// c: d: b
2489-
// }
2490-
// `,
2491-
// lookup: func(i *Instance) Value {
2492-
// _, a := i.Lookup("a", "b", "c", "d").Expr()
2493-
// return a[0].Lookup("b", "c", "d")
2494-
// },
2495-
// want: "a.b",
2496-
// }, {
2485+
input: `
2486+
a: b: {
2487+
c: d: b
2488+
}
2489+
`,
2490+
lookup: func(i *Instance) Value {
2491+
op, a := i.Lookup("a", "b", "c", "d").Expr()
2492+
_ = op
2493+
return a[0] // structural cycle errors.
2494+
},
2495+
want: "a",
2496+
}, {
24972497

24982498
// TODO: embedding: have field operators.
2499-
// input: `
2500-
// a: {
2501-
// c: 3
2502-
// {x: c}
2503-
// }
2504-
// `,
2505-
// lookup: func(i *Instance) Value {
2506-
// _, a := i.Lookup("a").Expr()
2507-
// return a[1].Lookup("x")
2508-
// },
2509-
// want: "a.c",
2510-
// }, {
2499+
input: `
2500+
a: {
2501+
{x: c}
2502+
c: 3
2503+
}
2504+
`,
2505+
lookup: func(i *Instance) Value {
2506+
op, a := i.Lookup("a").Expr()
2507+
_ = op
2508+
return a[0].Lookup("x")
2509+
},
2510+
want: "a.c",
2511+
}, {
25112512

25122513
// TODO: implement proper Elem()
25132514
input: `
@@ -2557,46 +2558,45 @@ func TestPathCorrection(t *testing.T) {
25572558
return a[0]
25582559
},
25592560
want: "#T",
2560-
// }, {
2561-
// input: `
2562-
// #a: {
2563-
// #T: {b: 3}
2564-
// close({}) | close({c: #T}) | close({d: string})
2565-
// }
2566-
// `,
2567-
// lookup: func(i *Instance) Value {
2568-
// f, _ := i.LookupField("#a")
2569-
// _, a := f.Value.Expr() // &
2570-
// _, a = a[1].Expr() // |
2571-
// return a[1].Lookup("c")
2572-
// },
2573-
// want: "#a.#T",
2574-
}, {
2575-
// TODO: iterate over Definitions
2576-
// input: `
2577-
// package foo
2578-
2579-
// #Struct: {
2580-
// #T: int
2581-
2582-
// {b?: #T}
2583-
// }`,
2584-
// want: "#Struct.#T",
2585-
// lookup: func(inst *Instance) Value {
2586-
// // Locate Struct
2587-
// i, _ := inst.Value().Fields(Definitions(true))
2588-
// if !i.Next() {
2589-
// t.Fatal("no fields")
2590-
// }
2591-
// // Locate b
2592-
// i, _ = i.Value().Fields(Definitions(true), Optional(true))
2593-
// if !(i.Next() && i.Next()) {
2594-
// t.Fatal("no fields")
2595-
// }
2596-
// v := i.Value()
2597-
// return v
2598-
// },
2599-
// }, {
2561+
}, {
2562+
input: `
2563+
#a: {
2564+
close({}) | close({c: #T}) | close({d: string})
2565+
#T: {b: 3}
2566+
}
2567+
`,
2568+
lookup: func(i *Instance) Value {
2569+
f, _ := i.LookupField("#a")
2570+
_, a := f.Value.Expr() // &
2571+
_, a = a[0].Expr() // |
2572+
return a[1].Lookup("c")
2573+
},
2574+
want: "#a.#T",
2575+
}, {
2576+
input: `
2577+
package foo
2578+
2579+
#Struct: {
2580+
#T: int
2581+
2582+
{b?: #T}
2583+
}`,
2584+
want: "#Struct.#T",
2585+
lookup: func(inst *Instance) Value {
2586+
// Locate Struct
2587+
i, _ := inst.Value().Fields(Definitions(true))
2588+
if !i.Next() {
2589+
t.Fatal("no fields")
2590+
}
2591+
// Locate b
2592+
i, _ = i.Value().Fields(Definitions(true), Optional(true))
2593+
if !(i.Next() && i.Next()) {
2594+
t.Fatal("no fields")
2595+
}
2596+
v := i.Value()
2597+
return v
2598+
},
2599+
}, {
26002600

26012601
input: `
26022602
package foo
@@ -2617,80 +2617,71 @@ func TestPathCorrection(t *testing.T) {
26172617
v = v.Lookup("a")
26182618
return v
26192619
},
2620-
// }, {
2620+
}, {
26212621

26222622
// TODO: record additionalItems in list
2623-
// input: `
2624-
// package foo
2625-
2626-
// #A: #B: #T
2627-
2628-
// #T: {
2629-
// a: [...#S]
2630-
// #S: {}
2631-
// }
2632-
// `,
2633-
// want: "#T.#S",
2634-
// lookup: func(inst *Instance) Value {
2635-
// f, _ := inst.Value().LookupField("#A")
2636-
// f, _ = f.Value.LookupField("#B")
2637-
// v := f.Value
2638-
// v = Dereference(v)
2639-
// v, _ = v.Lookup("a").Elem()
2640-
// return v
2641-
// },
2642-
// }, {
2623+
input: `
2624+
package foo
26432625
2644-
// YAY: works.
2645-
// input: `
2646-
// #A: {
2647-
// b: #T
2648-
// }
2649-
2650-
// #T: {
2651-
// a: #S
2652-
// #S: {}
2653-
// }
2654-
// `,
2655-
// want: "#T.#S",
2656-
// lookup: func(inst *Instance) Value {
2657-
// f, _ := inst.Value().LookupField("#A")
2658-
// v := f.Value.Lookup("b")
2659-
// v = Dereference(v)
2660-
// v = v.Lookup("a")
2661-
// return v
2662-
// },
2663-
// }, {
2626+
#A: #B: #T
2627+
2628+
#T: {
2629+
a: [...#S]
2630+
#S: {}
2631+
}
2632+
`,
2633+
want: "#T.#S",
2634+
lookup: func(inst *Instance) Value {
2635+
f, _ := inst.Value().LookupField("#A")
2636+
f, _ = f.Value.LookupField("#B")
2637+
v := f.Value
2638+
v = Dereference(v)
2639+
v, _ = v.Lookup("a").Elem()
2640+
return v
2641+
},
2642+
}, {
2643+
input: `
2644+
#A: {
2645+
b: #T
2646+
}
26642647
2665-
// // TODO(eval): embedded structs are currently represented at the same
2666-
// // level as the enclosing struct. This means that the parent of an
2667-
// // embedded struct skips the struct in which it is embedded. Treat
2668-
// // embedded structs as "anonymous" fields.
2669-
// // This could perhaps be made fixed with dereferencing as well.
2670-
// skip: true,
2671-
// input: `
2672-
// #Tracing: {
2673-
// #T: { address?: string }
2674-
// #S: { ip?: string }
2675-
2676-
// close({}) | close({
2677-
// t: #T
2678-
// }) | close({
2679-
// s: #S
2680-
// })
2681-
// }
2682-
// #X: {}
2683-
// #X // Disconnect top-level struct from the one visible by close.
2684-
// `,
2685-
// want: "",
2686-
// lookup: func(inst *Instance) Value {
2687-
// f, _ := inst.Value().LookupField("#Tracing")
2688-
// v := f.Value.Eval()
2689-
// _, args := v.Expr()
2690-
// v = args[1].Lookup("t")
2691-
// v = Dereference(v)
2692-
// return v
2693-
// },
2648+
#T: {
2649+
a: #S
2650+
#S: {}
2651+
}
2652+
`,
2653+
want: "#T.#S",
2654+
lookup: func(inst *Instance) Value {
2655+
f, _ := inst.Value().LookupField("#A")
2656+
v := f.Value.Lookup("b")
2657+
v = Dereference(v)
2658+
v = v.Lookup("a")
2659+
return v
2660+
},
2661+
}, {
2662+
input: `
2663+
#Tracing: {
2664+
#T: { address?: string }
2665+
#S: { ip?: string }
2666+
2667+
close({}) | close({
2668+
t: #T
2669+
}) | close({
2670+
s: #S
2671+
})
2672+
}
2673+
#X: {}
2674+
#X // Disconnect top-level struct from the one visible by close.
2675+
`,
2676+
want: "#Tracing.#T",
2677+
lookup: func(inst *Instance) Value {
2678+
f, _ := inst.Value().LookupField("#Tracing")
2679+
v := f.Value.Eval()
2680+
_, args := v.Expr()
2681+
v = args[1]
2682+
v = v.Lookup("t")
2683+
return v
2684+
},
26942685
}}
26952686
for _, tc := range testCases {
26962687
if tc.skip {

0 commit comments

Comments
 (0)