Skip to content

Commit

Permalink
cty: use unmarked val when Transform walks object attrs
Browse files Browse the repository at this point in the history
When descending into an object inside a Transformer, the marks from the
outer object should not be applied to the attribute values. This follows
the pattern used in other collection types, and ensures marks are stable
across multiple transformations.
  • Loading branch information
jbardin committed Jul 15, 2024
1 parent 7b73cce commit 043bf38
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
18 changes: 18 additions & 0 deletions cty/marks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,21 @@ func TestPathValueMarks(t *testing.T) {
})
}
}

func TestReapplyMarks(t *testing.T) {
// Re-applying the same marks to an object value should not change the result.
obj := ObjectVal(map[string]Value{
"nested": ObjectVal(map[string]Value{
"attr": StringVal("not directly marked"),
}),
})

pvm := []PathValueMarks{{Path: GetAttrPath("nested"), Marks: NewValueMarks("mark")}}

first := obj.MarkWithPaths(pvm)
second := first.MarkWithPaths(pvm)

if !first.RawEquals(second) {
t.Fatalf("Value changed re-applying marks\n1st: %#v\n2nd: %#v\n", first, second)
}
}
2 changes: 1 addition & 1 deletion cty/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func transform(path Path, val Value, t Transformer) (Value, error) {
atys := ty.AttributeTypes()
newAVs := make(map[string]Value)
for name := range atys {
av := val.GetAttr(name)
av := rawVal.GetAttr(name)
path := append(path, GetAttrStep{
Name: name,
})
Expand Down
23 changes: 23 additions & 0 deletions cty/walk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,26 @@ func TestTransform(t *testing.T) {
t.Fatalf("wrong value\n got: %#v\nwant: %#v", gotVal, wantVal)
}
}

func TestTransformMarked(t *testing.T) {
val := ObjectVal(map[string]Value{
"list": ListVal([]Value{True, True, False}).Mark("mark"),
"set": SetVal([]Value{True, False}).Mark("mark"),
"map": MapVal(map[string]Value{"a": True, "b": False}).Mark("mark"),
"object": ObjectVal(map[string]Value{
"a": True,
"b": ListVal([]Value{False, False, False}),
}).Mark("mark"),
})

// This noop transform should not change any values or marks.
gotVal, err := Transform(val, func(p Path, v Value) (Value, error) {
return v, nil
})
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if !gotVal.RawEquals(val) {
t.Fatalf("wrong value\n got: %#v\nwant: %#v", gotVal, val)
}
}

0 comments on commit 043bf38

Please sign in to comment.