github.com/franklinhu/terraform@v0.6.9-0.20151202232446-81f7fb1e6f9e/config/lang/eval_test.go (about)

     1  package lang
     2  
     3  import (
     4  	"reflect"
     5  	"strconv"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/config/lang/ast"
     9  )
    10  
    11  func TestEval(t *testing.T) {
    12  	cases := []struct {
    13  		Input      string
    14  		Scope      *ast.BasicScope
    15  		Error      bool
    16  		Result     interface{}
    17  		ResultType ast.Type
    18  	}{
    19  		{
    20  			"foo",
    21  			nil,
    22  			false,
    23  			"foo",
    24  			ast.TypeString,
    25  		},
    26  
    27  		{
    28  			"foo ${bar}",
    29  			&ast.BasicScope{
    30  				VarMap: map[string]ast.Variable{
    31  					"bar": ast.Variable{
    32  						Value: "baz",
    33  						Type:  ast.TypeString,
    34  					},
    35  				},
    36  			},
    37  			false,
    38  			"foo baz",
    39  			ast.TypeString,
    40  		},
    41  
    42  		{
    43  			"foo ${42+1}",
    44  			nil,
    45  			false,
    46  			"foo 43",
    47  			ast.TypeString,
    48  		},
    49  
    50  		{
    51  			"foo ${42-1}",
    52  			nil,
    53  			false,
    54  			"foo 41",
    55  			ast.TypeString,
    56  		},
    57  
    58  		{
    59  			"foo ${42*2}",
    60  			nil,
    61  			false,
    62  			"foo 84",
    63  			ast.TypeString,
    64  		},
    65  
    66  		{
    67  			"foo ${42/2}",
    68  			nil,
    69  			false,
    70  			"foo 21",
    71  			ast.TypeString,
    72  		},
    73  
    74  		{
    75  			"foo ${42%4}",
    76  			nil,
    77  			false,
    78  			"foo 2",
    79  			ast.TypeString,
    80  		},
    81  
    82  		{
    83  			"foo ${42.0+1.0}",
    84  			nil,
    85  			false,
    86  			"foo 43",
    87  			ast.TypeString,
    88  		},
    89  
    90  		{
    91  			"foo ${42.0+1}",
    92  			nil,
    93  			false,
    94  			"foo 43",
    95  			ast.TypeString,
    96  		},
    97  
    98  		{
    99  			"foo ${42+1.0}",
   100  			nil,
   101  			false,
   102  			"foo 43",
   103  			ast.TypeString,
   104  		},
   105  
   106  		{
   107  			"foo ${42+2*2}",
   108  			nil,
   109  			false,
   110  			"foo 88",
   111  			ast.TypeString,
   112  		},
   113  
   114  		{
   115  			"foo ${42+(2*2)}",
   116  			nil,
   117  			false,
   118  			"foo 46",
   119  			ast.TypeString,
   120  		},
   121  
   122  		{
   123  			"foo ${bar+1}",
   124  			&ast.BasicScope{
   125  				VarMap: map[string]ast.Variable{
   126  					"bar": ast.Variable{
   127  						Value: 41,
   128  						Type:  ast.TypeInt,
   129  					},
   130  				},
   131  			},
   132  			false,
   133  			"foo 42",
   134  			ast.TypeString,
   135  		},
   136  
   137  		{
   138  			"foo ${bar+1}",
   139  			&ast.BasicScope{
   140  				VarMap: map[string]ast.Variable{
   141  					"bar": ast.Variable{
   142  						Value: "41",
   143  						Type:  ast.TypeString,
   144  					},
   145  				},
   146  			},
   147  			false,
   148  			"foo 42",
   149  			ast.TypeString,
   150  		},
   151  
   152  		{
   153  			"foo ${bar+baz}",
   154  			&ast.BasicScope{
   155  				VarMap: map[string]ast.Variable{
   156  					"bar": ast.Variable{
   157  						Value: "41",
   158  						Type:  ast.TypeString,
   159  					},
   160  					"baz": ast.Variable{
   161  						Value: "1",
   162  						Type:  ast.TypeString,
   163  					},
   164  				},
   165  			},
   166  			false,
   167  			"foo 42",
   168  			ast.TypeString,
   169  		},
   170  
   171  		{
   172  			"foo ${rand()}",
   173  			&ast.BasicScope{
   174  				FuncMap: map[string]ast.Function{
   175  					"rand": ast.Function{
   176  						ReturnType: ast.TypeString,
   177  						Callback: func([]interface{}) (interface{}, error) {
   178  							return "42", nil
   179  						},
   180  					},
   181  				},
   182  			},
   183  			false,
   184  			"foo 42",
   185  			ast.TypeString,
   186  		},
   187  
   188  		{
   189  			`foo ${rand("foo", "bar")}`,
   190  			&ast.BasicScope{
   191  				FuncMap: map[string]ast.Function{
   192  					"rand": ast.Function{
   193  						ReturnType:   ast.TypeString,
   194  						Variadic:     true,
   195  						VariadicType: ast.TypeString,
   196  						Callback: func(args []interface{}) (interface{}, error) {
   197  							var result string
   198  							for _, a := range args {
   199  								result += a.(string)
   200  							}
   201  							return result, nil
   202  						},
   203  					},
   204  				},
   205  			},
   206  			false,
   207  			"foo foobar",
   208  			ast.TypeString,
   209  		},
   210  
   211  		// Testing implicit type conversions
   212  
   213  		{
   214  			"foo ${bar}",
   215  			&ast.BasicScope{
   216  				VarMap: map[string]ast.Variable{
   217  					"bar": ast.Variable{
   218  						Value: 42,
   219  						Type:  ast.TypeInt,
   220  					},
   221  				},
   222  			},
   223  			false,
   224  			"foo 42",
   225  			ast.TypeString,
   226  		},
   227  
   228  		{
   229  			`foo ${foo("42")}`,
   230  			&ast.BasicScope{
   231  				FuncMap: map[string]ast.Function{
   232  					"foo": ast.Function{
   233  						ArgTypes:   []ast.Type{ast.TypeInt},
   234  						ReturnType: ast.TypeString,
   235  						Callback: func(args []interface{}) (interface{}, error) {
   236  							return strconv.FormatInt(int64(args[0].(int)), 10), nil
   237  						},
   238  					},
   239  				},
   240  			},
   241  			false,
   242  			"foo 42",
   243  			ast.TypeString,
   244  		},
   245  
   246  		// Multiline
   247  		{
   248  			"foo ${42+\n1.0}",
   249  			nil,
   250  			false,
   251  			"foo 43",
   252  			ast.TypeString,
   253  		},
   254  	}
   255  
   256  	for _, tc := range cases {
   257  		node, err := Parse(tc.Input)
   258  		if err != nil {
   259  			t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
   260  		}
   261  
   262  		out, outType, err := Eval(node, &EvalConfig{GlobalScope: tc.Scope})
   263  		if err != nil != tc.Error {
   264  			t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
   265  		}
   266  		if outType != tc.ResultType {
   267  			t.Fatalf("Bad: %s\n\nInput: %s", outType, tc.Input)
   268  		}
   269  		if !reflect.DeepEqual(out, tc.Result) {
   270  			t.Fatalf("Bad: %#v\n\nInput: %s", out, tc.Input)
   271  		}
   272  	}
   273  }