Skip to content

Commit 4476483

Browse files
authored
Add WalkAttribute to hclext.BodyContent (#207)
1 parent 3a61636 commit 4476483

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

hclext/structure.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,20 @@ func (b *BodyContent) Copy() *BodyContent {
200200
return out
201201
}
202202

203+
// WalkAttributes visits all attributes with the passed walker function.
204+
func (b *BodyContent) WalkAttributes(walker func(*Attribute) hcl.Diagnostics) hcl.Diagnostics {
205+
var diags hcl.Diagnostics
206+
for _, attr := range b.Attributes {
207+
walkDiags := walker(attr)
208+
diags = diags.Extend(walkDiags)
209+
}
210+
for _, b := range b.Blocks {
211+
walkDiags := b.Body.WalkAttributes(walker)
212+
diags = diags.Extend(walkDiags)
213+
}
214+
return diags
215+
}
216+
203217
// AsNative returns self as hcl.Attributes
204218
func (as Attributes) AsNative() hcl.Attributes {
205219
ret := hcl.Attributes{}

hclext/structure_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"testing"
55

66
"github.com/google/go-cmp/cmp"
7+
"github.com/google/go-cmp/cmp/cmpopts"
78
"github.com/hashicorp/hcl/v2"
89
"github.com/hashicorp/hcl/v2/hclsyntax"
10+
"github.com/zclconf/go-cty/cty"
911
)
1012

1113
func TestContent_PartialContent(t *testing.T) {
@@ -857,3 +859,138 @@ func Test_IsEmpty(t *testing.T) {
857859
})
858860
}
859861
}
862+
863+
func TestCopy_BodyContent(t *testing.T) {
864+
body := &BodyContent{
865+
Attributes: Attributes{
866+
"foo": {Name: "foo"},
867+
},
868+
Blocks: Blocks{
869+
{
870+
Body: &BodyContent{
871+
Attributes: Attributes{
872+
"bar": {Name: "bar"},
873+
},
874+
Blocks: Blocks{
875+
{
876+
Body: &BodyContent{
877+
Attributes: Attributes{
878+
"baz": {Name: "baz"},
879+
},
880+
},
881+
},
882+
},
883+
},
884+
},
885+
{
886+
Body: &BodyContent{
887+
Attributes: Attributes{
888+
"aaa": {Name: "aaa"},
889+
"bbb": {Name: "bbb"},
890+
},
891+
},
892+
},
893+
},
894+
}
895+
896+
if diff := cmp.Diff(body.Copy(), body); diff != "" {
897+
t.Error(diff)
898+
}
899+
}
900+
901+
func TestWalkAttributes(t *testing.T) {
902+
body := &BodyContent{
903+
Attributes: Attributes{
904+
"foo": {Name: "foo"},
905+
},
906+
Blocks: Blocks{
907+
{
908+
Body: &BodyContent{
909+
Attributes: Attributes{
910+
"bar": {Name: "bar"},
911+
},
912+
Blocks: Blocks{
913+
{
914+
Body: &BodyContent{
915+
Attributes: Attributes{
916+
"baz": {Name: "baz"},
917+
},
918+
},
919+
},
920+
},
921+
},
922+
},
923+
{
924+
Body: &BodyContent{
925+
Attributes: Attributes{
926+
"aaa": {Name: "aaa"},
927+
"bbb": {Name: "bbb"},
928+
},
929+
},
930+
},
931+
},
932+
}
933+
934+
got := []string{}
935+
diags := body.WalkAttributes(func(a *Attribute) hcl.Diagnostics {
936+
got = append(got, a.Name)
937+
return nil
938+
})
939+
if diags.HasErrors() {
940+
t.Fatal(diags)
941+
}
942+
943+
want := []string{"foo", "bar", "baz", "aaa", "bbb"}
944+
945+
opt := cmpopts.SortSlices(func(x, y string) bool { return x < y })
946+
if diff := cmp.Diff(got, want, opt); diff != "" {
947+
t.Error(diff)
948+
}
949+
}
950+
951+
func TestCopy_Attribute(t *testing.T) {
952+
attribute := &Attribute{
953+
Name: "foo",
954+
Expr: hcl.StaticExpr(cty.StringVal("foo"), hcl.Range{}),
955+
Range: hcl.Range{Start: hcl.Pos{Line: 2}},
956+
NameRange: hcl.Range{Start: hcl.Pos{Line: 1}},
957+
}
958+
959+
must := func(v cty.Value, diags hcl.Diagnostics) cty.Value {
960+
if diags.HasErrors() {
961+
t.Fatal(diags)
962+
}
963+
return v
964+
}
965+
opts := cmp.Options{
966+
cmp.Comparer(func(x, y hcl.Expression) bool {
967+
return must(x.Value(nil)) == must(y.Value(nil))
968+
}),
969+
}
970+
if diff := cmp.Diff(attribute.Copy(), attribute, opts); diff != "" {
971+
t.Error(diff)
972+
}
973+
}
974+
975+
func TestCopy_Block(t *testing.T) {
976+
block := &Block{
977+
Type: "foo",
978+
Labels: []string{"bar", "baz"},
979+
Body: &BodyContent{
980+
Attributes: Attributes{
981+
"foo": {Name: "foo"},
982+
},
983+
Blocks: Blocks{},
984+
},
985+
DefRange: hcl.Range{Start: hcl.Pos{Line: 1}},
986+
TypeRange: hcl.Range{Start: hcl.Pos{Line: 2}},
987+
LabelRanges: []hcl.Range{
988+
{Start: hcl.Pos{Line: 3}},
989+
{Start: hcl.Pos{Line: 4}},
990+
},
991+
}
992+
993+
if diff := cmp.Diff(block.Copy(), block); diff != "" {
994+
t.Error(diff)
995+
}
996+
}

0 commit comments

Comments
 (0)