github.com/qapquiz/xk6-dotenv@v0.1.2-0.20220614041208-d05c37e5dd7e/test/expect.js (about) 1 /** 2 * MIT License 3 * 4 * Copyright (c) 2021 Iván Szkiba 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 // modified version https://jslib.k6.io/expect/0.0.5/index.js 26 27 import { check, group } from "k6"; 28 import { Rate } from "k6/metrics"; 29 30 export let errors = new Rate("errors"); 31 export let options = { thresholds: { errors: ["rate==0"] } }; 32 33 export class FunkBrokenChainException extends Error { 34 constructor(message) { 35 super(message); 36 this.brokenChain = true; 37 this.name = this.constructor.name; 38 if (typeof Error.captureStackTrace === "function") { 39 Error.captureStackTrace(this, this.constructor); 40 } else { 41 this.stack = new Error(message).stack; 42 } 43 } 44 } 45 46 class Funk { 47 constructor() { 48 this.leftHandValue = null; // resp.status 49 this.leftHandValueName = null; // "my status" 50 this.rightHandValue = null; // 200 51 this.chainBroken = false; 52 this.printedBrokenChainWarning = false; // print only one warning. 53 } 54 55 as(name) { 56 this.leftHandValueName = name; 57 return this; 58 } 59 60 _brokenChainCheck() { 61 if (this.chainBroken) { 62 if (!this.printedBrokenChainWarning) { 63 console.warn("This check has been aborted because the previous check in the chain has failed"); 64 this.printedBrokenChainWarning = true; 65 } 66 return true; 67 } 68 return false; 69 } 70 71 _recordCheck(checkName, isSuccessful, value) { 72 if (value !== undefined) { 73 check( 74 null, 75 { 76 [checkName]: isSuccessful, 77 }, 78 { 79 value: value, 80 } 81 ); 82 } else { 83 check(null, { 84 [checkName]: isSuccessful, 85 }); 86 } 87 } 88 89 _breakTheChain() { 90 this.chainBroken = true; 91 throw new FunkBrokenChainException("Chain broke, skipping this check"); 92 } 93 94 toEqual(rhv) { 95 if (this._brokenChainCheck()) return this; 96 this.rightHandValue = rhv; 97 98 let checkName = `${this.leftHandValue} is ${this.rightHandValue}`; 99 100 let checkIsSuccessful = this.leftHandValue === this.rightHandValue; 101 102 if (this.leftHandValueName) { 103 checkName = `${this.leftHandValueName} is ${this.leftHandValue}.`; 104 105 if (!checkIsSuccessful) { 106 checkName += ` Expected '${this.rightHandValue}'`; 107 } 108 } 109 110 this._recordCheck(checkName, checkIsSuccessful, this.rightHandValue); 111 112 if (!checkIsSuccessful) this._breakTheChain(); 113 114 return this; 115 } 116 117 toBeGreaterThan(rhv) { 118 if (this._brokenChainCheck()) return this; 119 120 this.rightHandValue = rhv; 121 122 let checkName = `${this.leftHandValueName || this.leftHandValue} is greater than ${this.rightHandValue}`; 123 124 let checkIsSuccessful = this.leftHandValue > this.rightHandValue; 125 126 this._recordCheck(checkName, checkIsSuccessful, this.leftHandValue); 127 128 if (!checkIsSuccessful) this._breakTheChain(); 129 130 return this; 131 } 132 133 toBeGreaterThanOrEqual(rhv) { 134 if (this._brokenChainCheck()) return this; 135 136 this.rightHandValue = rhv; 137 138 let checkName = `${this.leftHandValueName || this.leftHandValue} is greater or equal to ${this.rightHandValue}`; 139 140 let checkIsSuccessful = this.leftHandValue >= this.rightHandValue; 141 142 this._recordCheck(checkName, checkIsSuccessful, this.leftHandValue); 143 144 if (!checkIsSuccessful) this._breakTheChain(); 145 146 return this; 147 } 148 toBeLessThan(rhv) { 149 if (this._brokenChainCheck()) return this; 150 151 this.rightHandValue = rhv; 152 153 let checkName = `${this.leftHandValueName || this.leftHandValue} is less than ${this.rightHandValue}`; 154 155 let checkIsSuccessful = this.leftHandValue < this.rightHandValue; 156 157 this._recordCheck(checkName, checkIsSuccessful, this.leftHandValue); 158 159 if (!checkIsSuccessful) this._breakTheChain(); 160 161 return this; 162 } 163 toBeLessThanOrEqual(rhv) { 164 if (this._brokenChainCheck()) return this; 165 166 this.rightHandValue = rhv; 167 168 let checkName = `${this.leftHandValueName || this.leftHandValue} is less or equal to ${this.rightHandValue}`; 169 170 let checkIsSuccessful = this.leftHandValue <= this.rightHandValue; 171 172 this._recordCheck(checkName, checkIsSuccessful, this.leftHandValue); 173 174 if (!checkIsSuccessful) this._breakTheChain(); 175 176 return this; 177 } 178 179 toBeTruthy() { 180 if (this._brokenChainCheck()) return this; 181 182 let checkName = `${this.leftHandValueName || this.leftHandValue} is truthy.`; 183 184 let checkIsSuccessful = this.leftHandValue ? true : false; 185 186 this._recordCheck(checkName, checkIsSuccessful, this.leftHandValue); 187 188 if (!checkIsSuccessful) this._breakTheChain(); 189 190 return this; 191 } 192 193 toBeBetween(from, to) { 194 if (this._brokenChainCheck()) return this; 195 196 this.rightHandValue = `${from} - ${to}`; 197 198 let checkName = `${this.leftHandValueName || this.leftHandValue} is between ${this.rightHandValue}`; 199 200 let checkIsSuccessful = this.leftHandValue >= from && this.leftHandValue <= to; 201 202 this._recordCheck(checkName, checkIsSuccessful, this.leftHandValue); 203 204 if (!checkIsSuccessful) this._breakTheChain(); 205 206 return this; 207 } 208 209 and(lhv) { 210 // same as expect() but chained. 211 if (this._brokenChainCheck()) return this; 212 this.leftHandValue = lhv; 213 this.leftHandValueName = null; // clearing the previous .as() 214 return this; 215 } 216 } 217 218 let expect = function (value1) { 219 let state = new Funk(); 220 state.leftHandValue = value1; 221 return state; 222 }; 223 224 function handleUnexpectedException(e, testName) { 225 console.error(`Exception raised in test "${testName}". Failing the test and continuing. \n${e}`); 226 227 check(null, { 228 [`Exception raised "${e}"`]: false, 229 }); 230 } 231 232 let describe = function (testName, callback) { 233 let t = { 234 expect, 235 }; 236 237 let success = true; 238 239 group(testName, () => { 240 try { 241 callback(t); 242 success = true; 243 } catch (e) { 244 if (e.brokenChain) { 245 success = false; 246 } else { 247 success = false; 248 handleUnexpectedException(e, testName); 249 } 250 } 251 }); 252 253 errors.add(!success); 254 255 return success; 256 }; 257 258 export { describe };