...

Source file src/github.com/PaesslerAG/gval/evaluable_test.go

Documentation: github.com/PaesslerAG/gval

     1  package gval
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  )
    10  
    11  func TestEvaluable_IsConst(t *testing.T) {
    12  	p := Parser{}
    13  	tests := []struct {
    14  		name string
    15  		e    Evaluable
    16  		want bool
    17  	}{
    18  		{
    19  			"const",
    20  			p.Const(80.5),
    21  			true,
    22  		},
    23  		{
    24  			"var",
    25  			p.Var(),
    26  			false,
    27  		},
    28  	}
    29  	for _, tt := range tests {
    30  		t.Run(tt.name, func(t *testing.T) {
    31  			if got := tt.e.IsConst(); got != tt.want {
    32  				t.Errorf("Evaluable.IsConst() = %v, want %v", got, tt.want)
    33  			}
    34  		})
    35  	}
    36  }
    37  
    38  func TestEvaluable_EvalInt(t *testing.T) {
    39  	tests := []struct {
    40  		name    string
    41  		e       Evaluable
    42  		want    int
    43  		wantErr bool
    44  	}{
    45  		{
    46  			"point",
    47  			constant("5.3"),
    48  			5,
    49  			false,
    50  		},
    51  		{
    52  			"number",
    53  			constant(255.),
    54  			255,
    55  			false,
    56  		},
    57  		{
    58  			"error",
    59  			constant("5.3 cm"),
    60  			0,
    61  			true,
    62  		},
    63  	}
    64  	for _, tt := range tests {
    65  		t.Run(tt.name, func(t *testing.T) {
    66  			got, err := tt.e.EvalInt(context.Background(), nil)
    67  			if (err != nil) != tt.wantErr {
    68  				t.Errorf("Evaluable.EvalInt() error = %v, wantErr %v", err, tt.wantErr)
    69  				return
    70  			}
    71  			if got != tt.want {
    72  				t.Errorf("Evaluable.EvalInt() = %v, want %v", got, tt.want)
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func TestEvaluable_EvalFloat64(t *testing.T) {
    79  	tests := []struct {
    80  		name    string
    81  		e       Evaluable
    82  		want    float64
    83  		wantErr bool
    84  	}{
    85  		{
    86  			"point",
    87  			constant("5.3"),
    88  			5.3,
    89  			false,
    90  		},
    91  		{
    92  			"number",
    93  			constant(255.),
    94  			255,
    95  			false,
    96  		},
    97  		{
    98  			"error",
    99  			constant("5.3 cm"),
   100  			0,
   101  			true,
   102  		},
   103  	}
   104  	for _, tt := range tests {
   105  		t.Run(tt.name, func(t *testing.T) {
   106  			got, err := tt.e.EvalFloat64(context.Background(), nil)
   107  			if (err != nil) != tt.wantErr {
   108  				t.Errorf("Evaluable.EvalFloat64() error = %v, wantErr %v", err, tt.wantErr)
   109  				return
   110  			}
   111  			if got != tt.want {
   112  				t.Errorf("Evaluable.EvalFloat64() = %v, want %v", got, tt.want)
   113  			}
   114  		})
   115  	}
   116  }
   117  
   118  type testSelector struct {
   119  	str string
   120  	Map map[string]interface{}
   121  }
   122  
   123  func (s testSelector) SelectGVal(ctx context.Context, k string) (interface{}, error) {
   124  	if k == "str" {
   125  		return s.str, nil
   126  	}
   127  
   128  	if k == "map" {
   129  		return s.Map, nil
   130  	}
   131  
   132  	if strings.HasPrefix(k, "deep") {
   133  		return s, nil
   134  	}
   135  
   136  	return nil, fmt.Errorf("unknown-key")
   137  
   138  }
   139  
   140  func TestEvaluable_CustomSelector(t *testing.T) {
   141  	var (
   142  		lang  = Base()
   143  		tests = []struct {
   144  			name    string
   145  			expr    string
   146  			params  interface{}
   147  			want    interface{}
   148  			wantErr bool
   149  		}{
   150  			{
   151  				"unknown",
   152  				"s.Foo",
   153  				map[string]interface{}{"s": &testSelector{}},
   154  				nil,
   155  				true,
   156  			},
   157  			{
   158  				"field directly",
   159  				"s.Str",
   160  				map[string]interface{}{"s": &testSelector{str: "test-value"}},
   161  				nil,
   162  				true,
   163  			},
   164  			{
   165  				"field via selector",
   166  				"s.str",
   167  				map[string]interface{}{"s": &testSelector{str: "test-value"}},
   168  				"test-value",
   169  				false,
   170  			},
   171  			{
   172  				"flat",
   173  				"str",
   174  				&testSelector{str: "test-value"},
   175  				"test-value",
   176  				false,
   177  			},
   178  			{
   179  				"map field",
   180  				"s.map.foo",
   181  				map[string]interface{}{"s": &testSelector{Map: map[string]interface{}{"foo": "bar"}}},
   182  				"bar",
   183  				false,
   184  			},
   185  			{
   186  				"crawl to val",
   187  				"deep.deeper.deepest.str",
   188  				&testSelector{str: "foo"},
   189  				"foo",
   190  				false,
   191  			},
   192  			{
   193  				"crawl to struct",
   194  				"deep.deeper.deepest",
   195  				&testSelector{},
   196  				testSelector{},
   197  				false,
   198  			},
   199  		}
   200  	)
   201  
   202  	for _, tt := range tests {
   203  		t.Run(tt.name, func(t *testing.T) {
   204  			got, err := lang.Evaluate(tt.expr, tt.params)
   205  			if (err != nil) != tt.wantErr {
   206  				t.Errorf("Evaluable.Evaluate() error = %v, wantErr %v", err, tt.wantErr)
   207  				return
   208  			}
   209  			if !reflect.DeepEqual(got, tt.want) {
   210  				t.Errorf("Evaluable.Evaluate() = %v, want %v", got, tt.want)
   211  			}
   212  		})
   213  	}
   214  }
   215  

View as plain text