Skip to content

Commit

Permalink
Avoid completing static block inside a dynamic label (#165)
Browse files Browse the repository at this point in the history
* Add test case for label completion

* Only check block length if there is no dependent body

* Turn else into else if
  • Loading branch information
dbanck authored Nov 30, 2022
1 parent 13e06fb commit e6f0252
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
72 changes: 66 additions & 6 deletions decoder/body_extensions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,7 @@ func TestCompletionAtPos_BodySchema_Extensions_DynamicBlock(t *testing.T) {
cfg string
pos hcl.Pos
expectedCandidates lang.Candidates
expectedErr string
}{
{
"dynamic block does not complete if not enabled",
Expand Down Expand Up @@ -1728,6 +1729,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
Byte: 77,
},
lang.CompleteCandidates([]lang.Candidate{}),
"",
},
{
"dynamic block does not complete without blocks",
Expand Down Expand Up @@ -1783,6 +1785,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
Kind: lang.AttributeCandidateKind,
},
}),
"",
},
{
"dynamic block completion",
Expand Down Expand Up @@ -1878,6 +1881,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
{
"dynamic block inner completion",
Expand Down Expand Up @@ -2001,6 +2005,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
{
"dynamic block content attribute completion",
Expand Down Expand Up @@ -2074,6 +2079,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
{
"dynamic block label only completes dependent blocks",
Expand Down Expand Up @@ -2136,6 +2142,52 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
{
"dynamic block label never completes static blocks",
&schema.BodySchema{
Blocks: map[string]*schema.BlockSchema{
"resource": {
Labels: []*schema.LabelSchema{
{
Name: "type",
IsDepKey: true,
Completable: true,
},
{Name: "name"},
},
Body: &schema.BodySchema{
Extensions: &schema.BodyExtensions{
DynamicBlocks: true,
},
Blocks: map[string]*schema.BlockSchema{
"lifecycle": {
Body: schema.NewBodySchema(),
},
},
},
DependentBody: map[schema.SchemaKey]*schema.BodySchema{
schema.NewSchemaKey(schema.DependencyKeys{
Labels: []schema.LabelDependent{
{Index: 0, Value: "aws_instance"},
},
}): {
Blocks: make(map[string]*schema.BlockSchema, 0),
},
},
},
},
},
`resource "aws_instance" "example" {
name = "example"
dynamic "" {
}
}`,
hcl.Pos{Line: 3, Column: 12, Byte: 66},
lang.CompleteCandidates([]lang.Candidate{}),
`test.tf (3,12): unknown block type "dynamic"`,
},
// completion nesting should work
{
Expand Down Expand Up @@ -2245,6 +2297,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
// completion after the thing =
{
Expand Down Expand Up @@ -2333,6 +2386,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
// check allows more than one dynamic
{
Expand Down Expand Up @@ -2409,6 +2463,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
// allows dynamic blocks in blocks
{
Expand Down Expand Up @@ -2496,6 +2551,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
// never complete dynamic as a dynamic label
{
Expand Down Expand Up @@ -2562,6 +2618,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
},
}),
"",
},
}

Expand All @@ -2576,14 +2633,17 @@ resource "aws_elastic_beanstalk_environment" "example" {
},
})

// We're triggering completion twice her, to cover any unintended side effects
_, err := d.CandidatesAtPos(ctx, "test.tf", tc.pos)
if err != nil {
t.Fatal(err)
}
candidates, err := d.CandidatesAtPos(ctx, "test.tf", tc.pos)

if err != nil {
t.Fatal(err)
if tc.expectedErr != "" && err.Error() != tc.expectedErr {
t.Fatalf("unexpected error: %q\nexpected: %q\n",
err, tc.expectedErr)
} else if tc.expectedErr == "" {
t.Fatal(err)
}
} else if tc.expectedErr != "" {
t.Fatalf("expected error: %q", tc.expectedErr)
}

if diff := cmp.Diff(tc.expectedCandidates, candidates); diff != "" {
Expand Down
6 changes: 2 additions & 4 deletions decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ func mergeBlockBodySchemas(block *hcl.Block, blockSchema *schema.BlockSchema) (*
mergedSchema.ImpliedOrigins = make([]schema.ImpliedOrigin, 0)
}

if mergedSchema.Extensions != nil && mergedSchema.Extensions.DynamicBlocks && len(mergedSchema.Blocks) > 0 {
mergedSchema.Blocks["dynamic"] = buildDynamicBlockSchema(mergedSchema)
}

depSchema, _, ok := NewBlockSchema(blockSchema).DependentBodySchema(block)
if ok {
for name, attr := range depSchema.Attributes {
Expand Down Expand Up @@ -97,6 +93,8 @@ func mergeBlockBodySchemas(block *hcl.Block, blockSchema *schema.BlockSchema) (*
if depSchema.Extensions != nil {
mergedSchema.Extensions = depSchema.Extensions.Copy()
}
} else if !ok && mergedSchema.Extensions != nil && mergedSchema.Extensions.DynamicBlocks && len(mergedSchema.Blocks) > 0 {
mergedSchema.Blocks["dynamic"] = buildDynamicBlockSchema(mergedSchema)
}

return mergedSchema, nil
Expand Down

0 comments on commit e6f0252

Please sign in to comment.