github.com/hashicorp/hcl/v2@v2.20.0/traversal_for_expr_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package hcl
     5  
     6  import (
     7  	"testing"
     8  )
     9  
    10  type asTraversalSupported struct {
    11  	staticExpr
    12  	RootName string
    13  }
    14  
    15  type asTraversalSupportedAttr struct {
    16  	staticExpr
    17  	RootName string
    18  	AttrName string
    19  }
    20  
    21  type asTraversalNotSupported struct {
    22  	staticExpr
    23  }
    24  
    25  type asTraversalDeclined struct {
    26  	staticExpr
    27  }
    28  
    29  type asTraversalWrappedDelegated struct {
    30  	original Expression
    31  	staticExpr
    32  }
    33  
    34  func (e asTraversalSupported) AsTraversal() Traversal {
    35  	return Traversal{
    36  		TraverseRoot{
    37  			Name: e.RootName,
    38  		},
    39  	}
    40  }
    41  
    42  func (e asTraversalSupportedAttr) AsTraversal() Traversal {
    43  	return Traversal{
    44  		TraverseRoot{
    45  			Name: e.RootName,
    46  		},
    47  		TraverseAttr{
    48  			Name: e.AttrName,
    49  		},
    50  	}
    51  }
    52  
    53  func (e asTraversalDeclined) AsTraversal() Traversal {
    54  	return nil
    55  }
    56  
    57  func (e asTraversalWrappedDelegated) UnwrapExpression() Expression {
    58  	return e.original
    59  }
    60  
    61  func TestAbsTraversalForExpr(t *testing.T) {
    62  	tests := []struct {
    63  		Expr         Expression
    64  		WantRootName string
    65  	}{
    66  		{
    67  			asTraversalSupported{RootName: "foo"},
    68  			"foo",
    69  		},
    70  		{
    71  			asTraversalNotSupported{},
    72  			"",
    73  		},
    74  		{
    75  			asTraversalDeclined{},
    76  			"",
    77  		},
    78  		{
    79  			asTraversalWrappedDelegated{
    80  				original: asTraversalSupported{RootName: "foo"},
    81  			},
    82  			"foo",
    83  		},
    84  		{
    85  			asTraversalWrappedDelegated{
    86  				original: asTraversalWrappedDelegated{
    87  					original: asTraversalSupported{RootName: "foo"},
    88  				},
    89  			},
    90  			"foo",
    91  		},
    92  	}
    93  
    94  	for _, test := range tests {
    95  		t.Run("", func(t *testing.T) {
    96  			got, diags := AbsTraversalForExpr(test.Expr)
    97  			switch {
    98  			case got != nil:
    99  				if test.WantRootName == "" {
   100  					t.Fatalf("traversal was returned; want error")
   101  				}
   102  				if len(got) != 1 {
   103  					t.Fatalf("wrong traversal length %d; want 1", len(got))
   104  				}
   105  				gotRoot, ok := got[0].(TraverseRoot)
   106  				if !ok {
   107  					t.Fatalf("first traversal step is %T; want hcl.TraverseRoot", got[0])
   108  				}
   109  				if gotRoot.Name != test.WantRootName {
   110  					t.Errorf("wrong root name %q; want %q", gotRoot.Name, test.WantRootName)
   111  				}
   112  			default:
   113  				if !diags.HasErrors() {
   114  					t.Errorf("returned nil traversal without error diagnostics")
   115  				}
   116  				if test.WantRootName != "" {
   117  					t.Errorf("traversal was not returned; want TraverseRoot(%q)", test.WantRootName)
   118  				}
   119  			}
   120  		})
   121  	}
   122  }
   123  
   124  func TestRelTraversalForExpr(t *testing.T) {
   125  	tests := []struct {
   126  		Expr          Expression
   127  		WantFirstName string
   128  	}{
   129  		{
   130  			asTraversalSupported{RootName: "foo"},
   131  			"foo",
   132  		},
   133  		{
   134  			asTraversalNotSupported{},
   135  			"",
   136  		},
   137  		{
   138  			asTraversalDeclined{},
   139  			"",
   140  		},
   141  	}
   142  
   143  	for _, test := range tests {
   144  		t.Run("", func(t *testing.T) {
   145  			got, diags := RelTraversalForExpr(test.Expr)
   146  			switch {
   147  			case got != nil:
   148  				if test.WantFirstName == "" {
   149  					t.Fatalf("traversal was returned; want error")
   150  				}
   151  				if len(got) != 1 {
   152  					t.Fatalf("wrong traversal length %d; want 1", len(got))
   153  				}
   154  				gotRoot, ok := got[0].(TraverseAttr)
   155  				if !ok {
   156  					t.Fatalf("first traversal step is %T; want hcl.TraverseAttr", got[0])
   157  				}
   158  				if gotRoot.Name != test.WantFirstName {
   159  					t.Errorf("wrong root name %q; want %q", gotRoot.Name, test.WantFirstName)
   160  				}
   161  			default:
   162  				if !diags.HasErrors() {
   163  					t.Errorf("returned nil traversal without error diagnostics")
   164  				}
   165  				if test.WantFirstName != "" {
   166  					t.Errorf("traversal was not returned; want TraverseAttr(%q)", test.WantFirstName)
   167  				}
   168  			}
   169  		})
   170  	}
   171  }
   172  
   173  func TestExprAsKeyword(t *testing.T) {
   174  	tests := []struct {
   175  		Expr Expression
   176  		Want string
   177  	}{
   178  		{
   179  			asTraversalSupported{RootName: "foo"},
   180  			"foo",
   181  		},
   182  		{
   183  			asTraversalSupportedAttr{
   184  				RootName: "foo",
   185  				AttrName: "bar",
   186  			},
   187  			"",
   188  		},
   189  		{
   190  			asTraversalNotSupported{},
   191  			"",
   192  		},
   193  		{
   194  			asTraversalDeclined{},
   195  			"",
   196  		},
   197  		{
   198  			asTraversalWrappedDelegated{
   199  				original: asTraversalSupported{RootName: "foo"},
   200  			},
   201  			"foo",
   202  		},
   203  		{
   204  			asTraversalWrappedDelegated{
   205  				original: asTraversalWrappedDelegated{
   206  					original: asTraversalSupported{RootName: "foo"},
   207  				},
   208  			},
   209  			"foo",
   210  		},
   211  	}
   212  
   213  	for _, test := range tests {
   214  		t.Run("", func(t *testing.T) {
   215  			got := ExprAsKeyword(test.Expr)
   216  			if got != test.Want {
   217  				t.Errorf("wrong result %q; want %q\ninput: %T", got, test.Want, test.Expr)
   218  			}
   219  		})
   220  	}
   221  }