github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/query/math_test.go (about)

     1  /*
     2   * Copyright 2018 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package query
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/dgraph-io/dgraph/types"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  func TestProcessBinary(t *testing.T) {
    27  	tests := []struct {
    28  		in  *mathTree
    29  		out types.Val
    30  	}{
    31  		{in: &mathTree{
    32  			Fn: "+",
    33  			Child: []*mathTree{
    34  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
    35  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
    36  			}},
    37  			out: types.Val{Tid: types.FloatID, Value: 4.0},
    38  		},
    39  		{in: &mathTree{
    40  			Fn: "-",
    41  			Child: []*mathTree{
    42  				{Const: types.Val{Tid: types.IntID, Value: int64(100)}},
    43  				{Const: types.Val{Tid: types.IntID, Value: int64(1)}},
    44  			}},
    45  			out: types.Val{Tid: types.FloatID, Value: 99.0},
    46  		},
    47  		{in: &mathTree{
    48  			Fn: "*",
    49  			Child: []*mathTree{
    50  				{Const: types.Val{Tid: types.IntID, Value: int64(3)}},
    51  				{Const: types.Val{Tid: types.IntID, Value: int64(3)}},
    52  			}},
    53  			out: types.Val{Tid: types.FloatID, Value: 9.0},
    54  		},
    55  		{in: &mathTree{
    56  			Fn: "/",
    57  			Child: []*mathTree{
    58  				{Const: types.Val{Tid: types.IntID, Value: int64(12)}},
    59  				{Const: types.Val{Tid: types.IntID, Value: int64(4)}},
    60  			}},
    61  			out: types.Val{Tid: types.FloatID, Value: 3.0},
    62  		},
    63  		{in: &mathTree{
    64  			Fn: "%",
    65  			Child: []*mathTree{
    66  				{Const: types.Val{Tid: types.IntID, Value: int64(10)}},
    67  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
    68  			}},
    69  			out: types.Val{Tid: types.FloatID, Value: 0.0},
    70  		},
    71  		{in: &mathTree{
    72  			Fn: "max",
    73  			Child: []*mathTree{
    74  				{Const: types.Val{Tid: types.IntID, Value: int64(1)}},
    75  				{Const: types.Val{Tid: types.IntID, Value: int64(100)}},
    76  			}},
    77  			out: types.Val{Tid: types.FloatID, Value: 100.0},
    78  		},
    79  		{in: &mathTree{
    80  			Fn: "min",
    81  			Child: []*mathTree{
    82  				{Const: types.Val{Tid: types.IntID, Value: int64(1)}},
    83  				{Const: types.Val{Tid: types.IntID, Value: int64(100)}},
    84  			}},
    85  			out: types.Val{Tid: types.FloatID, Value: 1.0},
    86  		},
    87  		{in: &mathTree{
    88  			Fn: "logbase",
    89  			Child: []*mathTree{
    90  				{Const: types.Val{Tid: types.IntID, Value: int64(16)}},
    91  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
    92  			}},
    93  			out: types.Val{Tid: types.FloatID, Value: 4.0},
    94  		},
    95  		{in: &mathTree{
    96  			Fn: "pow",
    97  			Child: []*mathTree{
    98  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
    99  				{Const: types.Val{Tid: types.IntID, Value: int64(3)}},
   100  			}},
   101  			out: types.Val{Tid: types.FloatID, Value: 8.0},
   102  		},
   103  	}
   104  	for _, tc := range tests {
   105  		t.Logf("Test %s", tc.in.Fn)
   106  		err := processBinary(tc.in)
   107  		require.NoError(t, err)
   108  		require.EqualValues(t, tc.out, tc.in.Const)
   109  	}
   110  }
   111  
   112  func TestProcessUnary(t *testing.T) {
   113  	tests := []struct {
   114  		in  *mathTree
   115  		out types.Val
   116  	}{
   117  		{in: &mathTree{
   118  			Fn: "u-",
   119  			Child: []*mathTree{
   120  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   121  			}},
   122  			out: types.Val{Tid: types.FloatID, Value: -2.0},
   123  		},
   124  		{in: &mathTree{
   125  			Fn: "ln",
   126  			Child: []*mathTree{
   127  				{Const: types.Val{Tid: types.IntID, Value: int64(15)}},
   128  			}},
   129  			out: types.Val{Tid: types.FloatID, Value: 2.70805020110221},
   130  		},
   131  		{in: &mathTree{
   132  			Fn: "exp",
   133  			Child: []*mathTree{
   134  				{Const: types.Val{Tid: types.IntID, Value: int64(1)}},
   135  			}},
   136  			out: types.Val{Tid: types.FloatID, Value: 2.718281828459045},
   137  		},
   138  		{in: &mathTree{
   139  			Fn: "sqrt",
   140  			Child: []*mathTree{
   141  				{Const: types.Val{Tid: types.FloatID, Value: 9.0}},
   142  			}},
   143  			out: types.Val{Tid: types.FloatID, Value: 3.0},
   144  		},
   145  		{in: &mathTree{
   146  			Fn: "floor",
   147  			Child: []*mathTree{
   148  				{Const: types.Val{Tid: types.FloatID, Value: 2.5}},
   149  			}},
   150  			out: types.Val{Tid: types.FloatID, Value: 2.0},
   151  		},
   152  		{in: &mathTree{
   153  			Fn: "ceil",
   154  			Child: []*mathTree{
   155  				{Const: types.Val{Tid: types.FloatID, Value: 2.5}},
   156  			}},
   157  			out: types.Val{Tid: types.FloatID, Value: 3.0},
   158  		},
   159  	}
   160  	for _, tc := range tests {
   161  		t.Logf("Test %s", tc.in.Fn)
   162  		err := processUnary(tc.in)
   163  		require.NoError(t, err)
   164  		require.EqualValues(t, tc.out, tc.in.Const)
   165  	}
   166  }
   167  
   168  func TestProcessBinaryBoolean(t *testing.T) {
   169  	tests := []struct {
   170  		in  *mathTree
   171  		out types.Val
   172  	}{
   173  		{in: &mathTree{
   174  			Fn: "<",
   175  			Child: []*mathTree{
   176  				{Val: map[uint64]types.Val{
   177  					0: {Tid: types.IntID, Value: int64(1)}}},
   178  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   179  			}},
   180  			out: types.Val{Tid: types.BoolID, Value: true},
   181  		},
   182  		{in: &mathTree{
   183  			Fn: ">",
   184  			Child: []*mathTree{
   185  				{Val: map[uint64]types.Val{
   186  					0: {Tid: types.IntID, Value: int64(1)}}},
   187  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   188  			}},
   189  			out: types.Val{Tid: types.BoolID, Value: false},
   190  		},
   191  		{in: &mathTree{
   192  			Fn: "<=",
   193  			Child: []*mathTree{
   194  				{Val: map[uint64]types.Val{
   195  					0: {Tid: types.IntID, Value: int64(1)}}},
   196  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   197  			}},
   198  			out: types.Val{Tid: types.BoolID, Value: true},
   199  		},
   200  		{in: &mathTree{
   201  			Fn: ">=",
   202  			Child: []*mathTree{
   203  				{Val: map[uint64]types.Val{
   204  					0: {Tid: types.IntID, Value: int64(1)}}},
   205  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   206  			}},
   207  			out: types.Val{Tid: types.BoolID, Value: false},
   208  		},
   209  		{in: &mathTree{
   210  			Fn: "==",
   211  			Child: []*mathTree{
   212  				{Val: map[uint64]types.Val{
   213  					0: {Tid: types.IntID, Value: int64(1)}}},
   214  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   215  			}},
   216  			out: types.Val{Tid: types.BoolID, Value: false},
   217  		},
   218  		{in: &mathTree{
   219  			Fn: "!=",
   220  			Child: []*mathTree{
   221  				{Val: map[uint64]types.Val{
   222  					0: {Tid: types.IntID, Value: int64(1)}}},
   223  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   224  			}},
   225  			out: types.Val{Tid: types.BoolID, Value: true},
   226  		},
   227  	}
   228  	for _, tc := range tests {
   229  		t.Logf("Test %s", tc.in.Fn)
   230  		err := processBinaryBoolean(tc.in)
   231  		require.NoError(t, err)
   232  		require.EqualValues(t, tc.out, tc.in.Val[0])
   233  	}
   234  }
   235  
   236  func TestProcessTernary(t *testing.T) {
   237  	tests := []struct {
   238  		in  *mathTree
   239  		out types.Val
   240  	}{
   241  		{in: &mathTree{
   242  			Fn: "cond",
   243  			Child: []*mathTree{
   244  				{Val: map[uint64]types.Val{0: {Tid: types.BoolID, Value: true}}},
   245  				{Const: types.Val{Tid: types.IntID, Value: int64(1)}},
   246  				{Const: types.Val{Tid: types.IntID, Value: int64(2)}},
   247  			}},
   248  			out: types.Val{Tid: types.IntID, Value: int64(1)},
   249  		},
   250  		{in: &mathTree{
   251  			Fn: "cond",
   252  			Child: []*mathTree{
   253  				{Val: map[uint64]types.Val{0: {Tid: types.BoolID, Value: false}}},
   254  				{Const: types.Val{Tid: types.FloatID, Value: 1.0}},
   255  				{Const: types.Val{Tid: types.FloatID, Value: 2.0}},
   256  			}},
   257  			out: types.Val{Tid: types.FloatID, Value: 2.0},
   258  		},
   259  	}
   260  	for _, tc := range tests {
   261  		t.Logf("Test %s", tc.in.Fn)
   262  		err := processTernary(tc.in)
   263  		require.NoError(t, err)
   264  		require.EqualValues(t, tc.out, tc.in.Val[0])
   265  	}
   266  }
   267  
   268  func TestEvalMathTree(t *testing.T) {}