1// Copyright 2021 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14import { buildVectorMatching } from './vector'; 15import { createEditorState } from '../test/utils.test'; 16import { walkThrough } from './path-finder'; 17import { BinaryExpr, Expr } from '../grammar/parser.terms'; 18import chai from 'chai'; 19import { syntaxTree } from '@codemirror/language'; 20import { VectorMatchCardinality } from '../types'; 21 22describe('buildVectorMatching test', () => { 23 const testCases = [ 24 { 25 binaryExpr: 'foo * bar', 26 expectedVectorMatching: { card: VectorMatchCardinality.CardOneToOne, matchingLabels: [], on: false, include: [] }, 27 }, 28 { 29 binaryExpr: 'foo * sum', 30 expectedVectorMatching: { card: VectorMatchCardinality.CardOneToOne, matchingLabels: [], on: false, include: [] }, 31 }, 32 { 33 binaryExpr: 'foo == 1', 34 expectedVectorMatching: { card: VectorMatchCardinality.CardOneToOne, matchingLabels: [], on: false, include: [] }, 35 }, 36 { 37 binaryExpr: 'foo == bool 1', 38 expectedVectorMatching: { card: VectorMatchCardinality.CardOneToOne, matchingLabels: [], on: false, include: [] }, 39 }, 40 { 41 binaryExpr: '2.5 / bar', 42 expectedVectorMatching: { card: VectorMatchCardinality.CardOneToOne, matchingLabels: [], on: false, include: [] }, 43 }, 44 { 45 binaryExpr: 'foo and bar', 46 expectedVectorMatching: { 47 card: VectorMatchCardinality.CardManyToMany, 48 matchingLabels: [], 49 on: false, 50 include: [], 51 }, 52 }, 53 { 54 binaryExpr: 'foo or bar', 55 expectedVectorMatching: { 56 card: VectorMatchCardinality.CardManyToMany, 57 matchingLabels: [], 58 on: false, 59 include: [], 60 }, 61 }, 62 { 63 binaryExpr: 'foo unless bar', 64 expectedVectorMatching: { 65 card: VectorMatchCardinality.CardManyToMany, 66 matchingLabels: [], 67 on: false, 68 include: [], 69 }, 70 }, 71 { 72 // Test and/or precedence and reassigning of operands. 73 // Here it will test only the first VectorMatching so (a + b) or (c and d) ==> ManyToMany 74 binaryExpr: 'foo + bar or bla and blub', 75 expectedVectorMatching: { 76 card: VectorMatchCardinality.CardManyToMany, 77 matchingLabels: [], 78 on: false, 79 include: [], 80 }, 81 }, 82 { 83 // Test and/or/unless precedence. 84 // Here it will test only the first VectorMatching so ((a and b) unless c) or d ==> ManyToMany 85 binaryExpr: 'foo and bar unless baz or qux', 86 expectedVectorMatching: { 87 card: VectorMatchCardinality.CardManyToMany, 88 matchingLabels: [], 89 on: false, 90 include: [], 91 }, 92 }, 93 { 94 binaryExpr: 'foo * on(test,blub) bar', 95 expectedVectorMatching: { 96 card: VectorMatchCardinality.CardOneToOne, 97 matchingLabels: ['test', 'blub'], 98 on: true, 99 include: [], 100 }, 101 }, 102 { 103 binaryExpr: 'foo * on(test,blub) group_left bar', 104 expectedVectorMatching: { 105 card: VectorMatchCardinality.CardManyToOne, 106 matchingLabels: ['test', 'blub'], 107 on: true, 108 include: [], 109 }, 110 }, 111 { 112 binaryExpr: 'foo and on(test,blub) bar', 113 expectedVectorMatching: { 114 card: VectorMatchCardinality.CardManyToMany, 115 matchingLabels: ['test', 'blub'], 116 on: true, 117 include: [], 118 }, 119 }, 120 { 121 binaryExpr: 'foo and on() bar', 122 expectedVectorMatching: { 123 card: VectorMatchCardinality.CardManyToMany, 124 matchingLabels: [], 125 on: true, 126 include: [], 127 }, 128 }, 129 { 130 binaryExpr: 'foo and ignoring(test,blub) bar', 131 expectedVectorMatching: { 132 card: VectorMatchCardinality.CardManyToMany, 133 matchingLabels: ['test', 'blub'], 134 on: false, 135 include: [], 136 }, 137 }, 138 { 139 binaryExpr: 'foo and ignoring() bar', 140 expectedVectorMatching: { 141 card: VectorMatchCardinality.CardManyToMany, 142 matchingLabels: [], 143 on: false, 144 include: [], 145 }, 146 }, 147 { 148 binaryExpr: 'foo unless on(bar) baz', 149 expectedVectorMatching: { 150 card: VectorMatchCardinality.CardManyToMany, 151 matchingLabels: ['bar'], 152 on: true, 153 include: [], 154 }, 155 }, 156 { 157 binaryExpr: 'foo / on(test,blub) group_left(bar) bar', 158 expectedVectorMatching: { 159 card: VectorMatchCardinality.CardManyToOne, 160 matchingLabels: ['test', 'blub'], 161 on: true, 162 include: ['bar'], 163 }, 164 }, 165 { 166 binaryExpr: 'foo / ignoring(test,blub) group_left(blub) bar', 167 expectedVectorMatching: { 168 card: VectorMatchCardinality.CardManyToOne, 169 matchingLabels: ['test', 'blub'], 170 on: false, 171 include: ['blub'], 172 }, 173 }, 174 { 175 binaryExpr: 'foo / ignoring(test,blub) group_left(bar) bar', 176 expectedVectorMatching: { 177 card: VectorMatchCardinality.CardManyToOne, 178 matchingLabels: ['test', 'blub'], 179 on: false, 180 include: ['bar'], 181 }, 182 }, 183 { 184 binaryExpr: 'foo - on(test,blub) group_right(bar,foo) bar', 185 expectedVectorMatching: { 186 card: VectorMatchCardinality.CardOneToMany, 187 matchingLabels: ['test', 'blub'], 188 on: true, 189 include: ['bar', 'foo'], 190 }, 191 }, 192 { 193 binaryExpr: 'foo - ignoring(test,blub) group_right(bar,foo) bar', 194 expectedVectorMatching: { 195 card: VectorMatchCardinality.CardOneToMany, 196 matchingLabels: ['test', 'blub'], 197 on: false, 198 include: ['bar', 'foo'], 199 }, 200 }, 201 ]; 202 testCases.forEach((value) => { 203 it(value.binaryExpr, () => { 204 const state = createEditorState(value.binaryExpr); 205 const node = walkThrough(syntaxTree(state).topNode, Expr, BinaryExpr); 206 chai.expect(node).to.not.null; 207 chai.expect(node).to.not.undefined; 208 if (node) { 209 chai.expect(value.expectedVectorMatching).to.deep.equal(buildVectorMatching(state, node)); 210 } 211 }); 212 }); 213}); 214