github.com/jgadling/terraform@v0.3.8-0.20150227214559-abd68c2c87bc/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 ${rand()}",
   139  			&ast.BasicScope{
   140  				FuncMap: map[string]ast.Function{
   141  					"rand": ast.Function{
   142  						ReturnType: ast.TypeString,
   143  						Callback: func([]interface{}) (interface{}, error) {
   144  							return "42", nil
   145  						},
   146  					},
   147  				},
   148  			},
   149  			false,
   150  			"foo 42",
   151  			ast.TypeString,
   152  		},
   153  
   154  		{
   155  			`foo ${rand("foo", "bar")}`,
   156  			&ast.BasicScope{
   157  				FuncMap: map[string]ast.Function{
   158  					"rand": ast.Function{
   159  						ReturnType:   ast.TypeString,
   160  						Variadic:     true,
   161  						VariadicType: ast.TypeString,
   162  						Callback: func(args []interface{}) (interface{}, error) {
   163  							var result string
   164  							for _, a := range args {
   165  								result += a.(string)
   166  							}
   167  							return result, nil
   168  						},
   169  					},
   170  				},
   171  			},
   172  			false,
   173  			"foo foobar",
   174  			ast.TypeString,
   175  		},
   176  
   177  		// Testing implicit type conversions
   178  
   179  		{
   180  			"foo ${bar}",
   181  			&ast.BasicScope{
   182  				VarMap: map[string]ast.Variable{
   183  					"bar": ast.Variable{
   184  						Value: 42,
   185  						Type:  ast.TypeInt,
   186  					},
   187  				},
   188  			},
   189  			false,
   190  			"foo 42",
   191  			ast.TypeString,
   192  		},
   193  
   194  		{
   195  			`foo ${foo("42")}`,
   196  			&ast.BasicScope{
   197  				FuncMap: map[string]ast.Function{
   198  					"foo": ast.Function{
   199  						ArgTypes:   []ast.Type{ast.TypeInt},
   200  						ReturnType: ast.TypeString,
   201  						Callback: func(args []interface{}) (interface{}, error) {
   202  							return strconv.FormatInt(int64(args[0].(int)), 10), nil
   203  						},
   204  					},
   205  				},
   206  			},
   207  			false,
   208  			"foo 42",
   209  			ast.TypeString,
   210  		},
   211  	}
   212  
   213  	for _, tc := range cases {
   214  		node, err := Parse(tc.Input)
   215  		if err != nil {
   216  			t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
   217  		}
   218  
   219  		out, outType, err := Eval(node, &EvalConfig{GlobalScope: tc.Scope})
   220  		if (err != nil) != tc.Error {
   221  			t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
   222  		}
   223  		if outType != tc.ResultType {
   224  			t.Fatalf("Bad: %s\n\nInput: %s", outType, tc.Input)
   225  		}
   226  		if !reflect.DeepEqual(out, tc.Result) {
   227  			t.Fatalf("Bad: %#v\n\nInput: %s", out, tc.Input)
   228  		}
   229  	}
   230  }