github.com/expr-lang/expr@v1.16.9/test/time/time_test.go (about)

     1  package time_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/expr-lang/expr/internal/testify/require"
     9  
    10  	"github.com/expr-lang/expr"
    11  	"github.com/expr-lang/expr/checker"
    12  	"github.com/expr-lang/expr/compiler"
    13  	"github.com/expr-lang/expr/conf"
    14  	"github.com/expr-lang/expr/parser"
    15  	"github.com/expr-lang/expr/vm"
    16  )
    17  
    18  func TestTime(t *testing.T) {
    19  	testTime := time.Date(2000, time.Month(1), 1, 0, 0, 0, 0, time.UTC)
    20  	testDuration := time.Duration(1)
    21  
    22  	tests := []struct {
    23  		a       any
    24  		b       any
    25  		op      string
    26  		want    any
    27  		wantErr bool
    28  	}{
    29  		{a: testTime, b: testTime, op: "<", wantErr: false, want: false},
    30  		{a: testTime, b: testTime, op: ">", wantErr: false, want: false},
    31  		{a: testTime, b: testTime, op: "<=", wantErr: false, want: true},
    32  		{a: testTime, b: testTime, op: ">=", wantErr: false, want: true},
    33  		{a: testTime, b: testTime, op: "==", wantErr: false, want: true},
    34  		{a: testTime, b: testTime, op: "!=", wantErr: false, want: false},
    35  		{a: testTime, b: testTime, op: "-", wantErr: false},
    36  		{a: testTime, b: testDuration, op: "+", wantErr: false},
    37  		{a: testTime, b: testDuration, op: "-", wantErr: false},
    38  
    39  		// error cases
    40  		{a: testTime, b: int64(1), op: "<", wantErr: true},
    41  		{a: testTime, b: float64(1), op: "<", wantErr: true},
    42  		{a: testTime, b: testDuration, op: "<", wantErr: true},
    43  
    44  		{a: testTime, b: int64(1), op: ">", wantErr: true},
    45  		{a: testTime, b: float64(1), op: ">", wantErr: true},
    46  		{a: testTime, b: testDuration, op: ">", wantErr: true},
    47  
    48  		{a: testTime, b: int64(1), op: "<=", wantErr: true},
    49  		{a: testTime, b: float64(1), op: "<=", wantErr: true},
    50  		{a: testTime, b: testDuration, op: "<=", wantErr: true},
    51  
    52  		{a: testTime, b: int64(1), op: ">=", wantErr: true},
    53  		{a: testTime, b: float64(1), op: ">=", wantErr: true},
    54  		{a: testTime, b: testDuration, op: ">=", wantErr: true},
    55  
    56  		{a: testTime, b: int64(1), op: "==", wantErr: false, want: false},
    57  		{a: testTime, b: float64(1), op: "==", wantErr: false, want: false},
    58  		{a: testTime, b: testDuration, op: "==", wantErr: false, want: false},
    59  
    60  		{a: testTime, b: int64(1), op: "!=", wantErr: false, want: true},
    61  		{a: testTime, b: float64(1), op: "!=", wantErr: false, want: true},
    62  		{a: testTime, b: testDuration, op: "!=", wantErr: false, want: true},
    63  
    64  		{a: testTime, b: int64(1), op: "-", wantErr: true},
    65  		{a: testTime, b: float64(1), op: "-", wantErr: true},
    66  
    67  		{a: testTime, b: testTime, op: "+", wantErr: true},
    68  		{a: testTime, b: int64(1), op: "+", wantErr: true},
    69  		{a: testTime, b: float64(1), op: "+", wantErr: true},
    70  		{a: testDuration, b: testTime, op: "+", wantErr: false},
    71  	}
    72  
    73  	for _, tt := range tests {
    74  		t.Run(fmt.Sprintf("time helper test `%T %s %T`", tt.a, tt.op, tt.b), func(t *testing.T) {
    75  			input := fmt.Sprintf("a %v b", tt.op)
    76  			env := map[string]any{
    77  				"a": tt.a,
    78  				"b": tt.b,
    79  			}
    80  
    81  			config := conf.CreateNew()
    82  
    83  			tree, err := parser.Parse(input)
    84  			require.NoError(t, err)
    85  
    86  			_, err = checker.Check(tree, config)
    87  			require.NoError(t, err)
    88  
    89  			program, err := compiler.Compile(tree, config)
    90  			require.NoError(t, err)
    91  
    92  			got, err := vm.Run(program, env)
    93  			if tt.wantErr {
    94  				require.Error(t, err)
    95  			} else {
    96  				require.NoError(t, err)
    97  
    98  				if tt.want != nil {
    99  					require.Equal(t, tt.want, got)
   100  				}
   101  			}
   102  		})
   103  	}
   104  }
   105  
   106  func TestTime_duration(t *testing.T) {
   107  	env := map[string]any{
   108  		"foo": time.Date(2000, time.Month(1), 1, 0, 0, 0, 0, time.UTC),
   109  	}
   110  	program, err := expr.Compile(`now() - duration("1h") < now() && foo + duration("24h") < now()`, expr.Env(env))
   111  	require.NoError(t, err)
   112  
   113  	output, err := expr.Run(program, env)
   114  	require.NoError(t, err)
   115  	require.Equal(t, true, output)
   116  }
   117  
   118  func TestTime_date(t *testing.T) {
   119  	var tests = []struct {
   120  		input string
   121  		want  time.Time
   122  	}{
   123  		{
   124  			`date('2017-10-23')`,
   125  			time.Date(2017, 10, 23, 0, 0, 0, 0, time.UTC),
   126  		},
   127  		{
   128  			`date('24.11.1987 20:30', "02.01.2006 15:04", "Europe/Zurich")`,
   129  			time.Date(1987, 11, 24, 20, 30, 0, 0, time.FixedZone("Europe/Zurich", 3600)),
   130  		},
   131  		{
   132  			`date('24.11.1987 20:30 MSK', "02.01.2006 15:04 MST", "Europe/Zurich")`,
   133  			time.Date(1987, 11, 24, 20, 30, 0, 0, time.FixedZone("MSK", 0)),
   134  		},
   135  	}
   136  	for _, test := range tests {
   137  		t.Run(test.input, func(t *testing.T) {
   138  			program, err := expr.Compile(test.input)
   139  			require.NoError(t, err)
   140  
   141  			output, err := expr.Run(program, nil)
   142  			require.NoError(t, err)
   143  			require.Truef(t, test.want.Equal(output.(time.Time)), "want %v, got %v", test.want, output)
   144  		})
   145  	}
   146  }