github.com/markdia/terraform@v0.5.1-0.20150508012022-f1ae920aa970/config/lang/parse_test.go (about)

     1  package lang
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/config/lang/ast"
     8  )
     9  
    10  func TestParse(t *testing.T) {
    11  	cases := []struct {
    12  		Input  string
    13  		Error  bool
    14  		Result ast.Node
    15  	}{
    16  		{
    17  			"",
    18  			false,
    19  			&ast.LiteralNode{
    20  				Value: "",
    21  				Typex: ast.TypeString,
    22  				Posx:  ast.Pos{Column: 1, Line: 1},
    23  			},
    24  		},
    25  
    26  		{
    27  			"foo",
    28  			false,
    29  			&ast.LiteralNode{
    30  				Value: "foo",
    31  				Typex: ast.TypeString,
    32  				Posx:  ast.Pos{Column: 1, Line: 1},
    33  			},
    34  		},
    35  
    36  		{
    37  			"$${var.foo}",
    38  			false,
    39  			&ast.LiteralNode{
    40  				Value: "${var.foo}",
    41  				Typex: ast.TypeString,
    42  				Posx:  ast.Pos{Column: 1, Line: 1},
    43  			},
    44  		},
    45  
    46  		{
    47  			"foo ${var.bar}",
    48  			false,
    49  			&ast.Concat{
    50  				Posx: ast.Pos{Column: 1, Line: 1},
    51  				Exprs: []ast.Node{
    52  					&ast.LiteralNode{
    53  						Value: "foo ",
    54  						Typex: ast.TypeString,
    55  						Posx:  ast.Pos{Column: 1, Line: 1},
    56  					},
    57  					&ast.VariableAccess{
    58  						Name: "var.bar",
    59  						Posx: ast.Pos{Column: 7, Line: 1},
    60  					},
    61  				},
    62  			},
    63  		},
    64  
    65  		{
    66  			"foo ${var.bar} baz",
    67  			false,
    68  			&ast.Concat{
    69  				Posx: ast.Pos{Column: 1, Line: 1},
    70  				Exprs: []ast.Node{
    71  					&ast.LiteralNode{
    72  						Value: "foo ",
    73  						Typex: ast.TypeString,
    74  						Posx:  ast.Pos{Column: 1, Line: 1},
    75  					},
    76  					&ast.VariableAccess{
    77  						Name: "var.bar",
    78  						Posx: ast.Pos{Column: 7, Line: 1},
    79  					},
    80  					&ast.LiteralNode{
    81  						Value: " baz",
    82  						Typex: ast.TypeString,
    83  						Posx:  ast.Pos{Column: 15, Line: 1},
    84  					},
    85  				},
    86  			},
    87  		},
    88  
    89  		{
    90  			"foo ${\"bar\"}",
    91  			false,
    92  			&ast.Concat{
    93  				Posx: ast.Pos{Column: 1, Line: 1},
    94  				Exprs: []ast.Node{
    95  					&ast.LiteralNode{
    96  						Value: "foo ",
    97  						Typex: ast.TypeString,
    98  						Posx:  ast.Pos{Column: 1, Line: 1},
    99  					},
   100  					&ast.LiteralNode{
   101  						Value: "bar",
   102  						Typex: ast.TypeString,
   103  						Posx:  ast.Pos{Column: 7, Line: 1},
   104  					},
   105  				},
   106  			},
   107  		},
   108  
   109  		{
   110  			`foo ${func('baz')}`,
   111  			true,
   112  			nil,
   113  		},
   114  
   115  		{
   116  			"foo ${42}",
   117  			false,
   118  			&ast.Concat{
   119  				Posx: ast.Pos{Column: 1, Line: 1},
   120  				Exprs: []ast.Node{
   121  					&ast.LiteralNode{
   122  						Value: "foo ",
   123  						Typex: ast.TypeString,
   124  						Posx:  ast.Pos{Column: 1, Line: 1},
   125  					},
   126  					&ast.LiteralNode{
   127  						Value: 42,
   128  						Typex: ast.TypeInt,
   129  						Posx:  ast.Pos{Column: 7, Line: 1},
   130  					},
   131  				},
   132  			},
   133  		},
   134  
   135  		{
   136  			"foo ${3.14159}",
   137  			false,
   138  			&ast.Concat{
   139  				Posx: ast.Pos{Column: 1, Line: 1},
   140  				Exprs: []ast.Node{
   141  					&ast.LiteralNode{
   142  						Value: "foo ",
   143  						Typex: ast.TypeString,
   144  						Posx:  ast.Pos{Column: 1, Line: 1},
   145  					},
   146  					&ast.LiteralNode{
   147  						Value: 3.14159,
   148  						Typex: ast.TypeFloat,
   149  						Posx:  ast.Pos{Column: 7, Line: 1},
   150  					},
   151  				},
   152  			},
   153  		},
   154  
   155  		{
   156  			"foo ${42+1}",
   157  			false,
   158  			&ast.Concat{
   159  				Posx: ast.Pos{Column: 1, Line: 1},
   160  				Exprs: []ast.Node{
   161  					&ast.LiteralNode{
   162  						Value: "foo ",
   163  						Typex: ast.TypeString,
   164  						Posx:  ast.Pos{Column: 1, Line: 1},
   165  					},
   166  					&ast.Arithmetic{
   167  						Op: ast.ArithmeticOpAdd,
   168  						Exprs: []ast.Node{
   169  							&ast.LiteralNode{
   170  								Value: 42,
   171  								Typex: ast.TypeInt,
   172  								Posx:  ast.Pos{Column: 7, Line: 1},
   173  							},
   174  							&ast.LiteralNode{
   175  								Value: 1,
   176  								Typex: ast.TypeInt,
   177  								Posx:  ast.Pos{Column: 10, Line: 1},
   178  							},
   179  						},
   180  						Posx: ast.Pos{Column: 7, Line: 1},
   181  					},
   182  				},
   183  			},
   184  		},
   185  
   186  		{
   187  			"${foo()}",
   188  			false,
   189  			&ast.Concat{
   190  				Posx: ast.Pos{Column: 3, Line: 1},
   191  				Exprs: []ast.Node{
   192  					&ast.Call{
   193  						Func: "foo",
   194  						Args: nil,
   195  						Posx: ast.Pos{Column: 3, Line: 1},
   196  					},
   197  				},
   198  			},
   199  		},
   200  
   201  		{
   202  			"${foo(bar)}",
   203  			false,
   204  			&ast.Concat{
   205  				Posx: ast.Pos{Column: 3, Line: 1},
   206  				Exprs: []ast.Node{
   207  					&ast.Call{
   208  						Func: "foo",
   209  						Posx: ast.Pos{Column: 3, Line: 1},
   210  						Args: []ast.Node{
   211  							&ast.VariableAccess{
   212  								Name: "bar",
   213  								Posx: ast.Pos{Column: 7, Line: 1},
   214  							},
   215  						},
   216  					},
   217  				},
   218  			},
   219  		},
   220  
   221  		{
   222  			"${foo(bar, baz)}",
   223  			false,
   224  			&ast.Concat{
   225  				Posx: ast.Pos{Column: 3, Line: 1},
   226  				Exprs: []ast.Node{
   227  					&ast.Call{
   228  						Func: "foo",
   229  						Posx: ast.Pos{Column: 3, Line: 1},
   230  						Args: []ast.Node{
   231  							&ast.VariableAccess{
   232  								Name: "bar",
   233  								Posx: ast.Pos{Column: 7, Line: 1},
   234  							},
   235  							&ast.VariableAccess{
   236  								Name: "baz",
   237  								Posx: ast.Pos{Column: 11, Line: 1},
   238  							},
   239  						},
   240  					},
   241  				},
   242  			},
   243  		},
   244  
   245  		{
   246  			"${foo(bar(baz))}",
   247  			false,
   248  			&ast.Concat{
   249  				Posx: ast.Pos{Column: 3, Line: 1},
   250  				Exprs: []ast.Node{
   251  					&ast.Call{
   252  						Func: "foo",
   253  						Posx: ast.Pos{Column: 3, Line: 1},
   254  						Args: []ast.Node{
   255  							&ast.Call{
   256  								Func: "bar",
   257  								Posx: ast.Pos{Column: 7, Line: 1},
   258  								Args: []ast.Node{
   259  									&ast.VariableAccess{
   260  										Name: "baz",
   261  										Posx: ast.Pos{Column: 11, Line: 1},
   262  									},
   263  								},
   264  							},
   265  						},
   266  					},
   267  				},
   268  			},
   269  		},
   270  
   271  		{
   272  			`foo ${"bar ${baz}"}`,
   273  			false,
   274  			&ast.Concat{
   275  				Posx: ast.Pos{Column: 1, Line: 1},
   276  				Exprs: []ast.Node{
   277  					&ast.LiteralNode{
   278  						Value: "foo ",
   279  						Typex: ast.TypeString,
   280  						Posx:  ast.Pos{Column: 1, Line: 1},
   281  					},
   282  					&ast.Concat{
   283  						Posx: ast.Pos{Column: 7, Line: 1},
   284  						Exprs: []ast.Node{
   285  							&ast.LiteralNode{
   286  								Value: "bar ",
   287  								Typex: ast.TypeString,
   288  								Posx:  ast.Pos{Column: 7, Line: 1},
   289  							},
   290  							&ast.VariableAccess{
   291  								Name: "baz",
   292  								Posx: ast.Pos{Column: 14, Line: 1},
   293  							},
   294  						},
   295  					},
   296  				},
   297  			},
   298  		},
   299  
   300  		{
   301  			`foo ${bar ${baz}}`,
   302  			true,
   303  			nil,
   304  		},
   305  
   306  		{
   307  			`foo ${${baz}}`,
   308  			true,
   309  			nil,
   310  		},
   311  
   312  		{
   313  			"${var",
   314  			true,
   315  			nil,
   316  		},
   317  	}
   318  
   319  	for _, tc := range cases {
   320  		actual, err := Parse(tc.Input)
   321  		if (err != nil) != tc.Error {
   322  			t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
   323  		}
   324  		if !reflect.DeepEqual(actual, tc.Result) {
   325  			t.Fatalf("Bad: %#v\n\nInput: %s", actual, tc.Input)
   326  		}
   327  	}
   328  }