Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add test case for panics for invalid namespaced function expressions #383

Merged
merged 6 commits into from
Apr 5, 2024
33 changes: 33 additions & 0 deletions decoder/candidates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,39 @@ resource "random_resource" "test" {
}
}

func TestDecoder_CompletionAtPos_nil_expr(t *testing.T) {
ctx := context.Background()

// provider:: is not a traversal expression, so hcl will return a ExprSyntaxError which needs to be handled
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})

pos := hcl.Pos{Line: 1, Column: 18, Byte: 17}

candidates, err := d.CompletionAtPos(ctx, "test.tf", pos)
if err != nil {
t.Fatal(err)
}

expectedCandidates := lang.CompleteCandidates([]lang.Candidate{})

diff := cmp.Diff(expectedCandidates, candidates, ctydebug.CmpOptions)
if diff != "" {
t.Fatalf("unexpected schema for %s: %s", stringPos(pos), diff)
}

}

func TestDecoder_CompletionAtPos_AnyAttribute(t *testing.T) {
ctx := context.Background()
providersSchema := &schema.BlockSchema{
Expand Down
27 changes: 27 additions & 0 deletions decoder/hover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,33 @@ func TestDecoder_HoverAtPos_basic(t *testing.T) {
}
}

func TestDecoder_HoverAtPos_nil_expr(t *testing.T) {
// provider:: is not a traversal expression, so hcl will return a ExprSyntaxError which needs to be handled
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})

ctx := context.Background()
hoverData, err := d.HoverAtPos(ctx, "test.tf", hcl.Pos{Line: 1, Column: 16, Byte: 15})

if err != nil {
t.Fatal(err)
}

if hoverData != nil {
t.Fatalf("expected nil hover data, got: %v", hoverData)
}
}

func TestDecoder_HoverAtPos_URL(t *testing.T) {
resourceLabelSchema := []*schema.LabelSchema{
{Name: "type", IsDepKey: true},
Expand Down
27 changes: 27 additions & 0 deletions decoder/reference_origins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/reference"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/zclconf/go-cty-debug/ctydebug"
"github.com/zclconf/go-cty/cty"
)
Expand Down Expand Up @@ -763,3 +765,28 @@ func TestReferenceOriginsTargetingPos(t *testing.T) {
})
}
}

func TestCollectReferenceOrigins_nil_expr(t *testing.T) {
// provider:: is not a traversal expression, so hcl will return a ExprSyntaxError which needs to be handled
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})

targets, err := d.CollectReferenceOrigins()
if err != nil {
t.Fatal("unexpected error when collecting reference origins while there was no expr in one of them")
}

if len(targets) != 0 {
t.Fatalf("expected no targets, got %d", len(targets))
}
}
26 changes: 26 additions & 0 deletions decoder/reference_targets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/reference"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/zclconf/go-cty-debug/ctydebug"
"github.com/zclconf/go-cty/cty"
)
Expand Down Expand Up @@ -352,3 +354,27 @@ func TestReferenceTargetForOriginAtPos(t *testing.T) {
})
}
}

func TestCollectReferenceTargets_nil_expr(t *testing.T) {
// provider:: is not a traversal expression, so hcl will return a ExprSyntaxError which needs to be handled
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})
targets, err := d.CollectReferenceTargets()
if err != nil {
t.Fatal("unexpected error when collecting reference targets while there was no expr in one of them")
}

if len(targets) != 0 {
t.Fatalf("expected no targets, got %d", len(targets))
}
}
48 changes: 48 additions & 0 deletions decoder/semantic_tokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,54 @@ resource "vault_auth_backend" "blah" {
}
}

func TestDecoder_SemanticTokensInFile_nil_expr(t *testing.T) {
// provider:: is not a traversal expression, so hcl will return a ExprSyntaxError which needs to be handled
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})

ctx := context.Background()

tokens, err := d.SemanticTokensInFile(ctx, "test.tf")
if err != nil {
t.Fatal(err)
}

expectedTokens := []lang.SemanticToken{
{
Type: "hcl-attrName",
Modifiers: lang.SemanticTokenModifiers{},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 1,
Column: 5,
Byte: 4,
},
},
},
}

diff := cmp.Diff(expectedTokens, tokens)
if diff != "" {
t.Fatalf("unexpected tokens: %s", diff)
}
}

func TestDecoder_SemanticTokensInFile_dependentSchema(t *testing.T) {
bodySchema := &schema.BodySchema{
Blocks: map[string]*schema.BlockSchema{
Expand Down
Loading