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) {}