Best JavaScript code snippet using fast-check-monorepo
state.ts
Source:state.ts
1///<reference path="../../typings.d.ts" />2import memory = require('../memory');3import syscall = require('./syscall');4import Memory = memory.Memory;5import ISyscallManager = syscall.ISyscallManager;6export enum CpuSpecialAddresses {7 EXIT_THREAD = 0x0FFFFFFF,8}9export interface IExecutor {10 execute(maxIterations: number): void;11 executeWithoutCatch(maxIterations: number): void;12 executeUntilPCReachesWithoutCall(pc: number): void;13}14class VfpuPrefixBase {15 enabled = false;16 constructor(private vfrc: number[], private index: number) {17 }18 _info: number;19 _readInfo() {20 this._info = this.getInfo();21 }22 eat() {23 this.enabled = false;24 }25 getInfo() {26 return this.vfrc[this.index];27 }28 setInfo(info: number) {29 this.vfrc[this.index] = info;30 this.enabled = true;31 }32}33class VfpuPrefixRead extends VfpuPrefixBase {34 //private getSourceIndex(i: number) { return BitUtils.extract(this._info, 0 + i * 2, 2); }35 //private getSourceAbsolute(i: number) { return BitUtils.extractBool(this._info, 8 + i * 1); }36 //private getSourceConstant(i: number) { return BitUtils.extractBool(this._info, 12 + i * 1); }37 //private getSourceNegate(i: number) { return BitUtils.extractBool(this._info, 16 + i * 1); }38 transformValues(input: number[], output: any) {39 this._readInfo();40 var info = this._info;41 if (!this.enabled) {42 for (var n = 0; n < input.length; n++) output[n] = input[n];43 } else {44 for (var n = 0; n < input.length; n++) {45 //var sourceIndex = this.getSourceIndex(n);46 //var sourceAbsolute = this.getSourceAbsolute(n);47 //var sourceConstant = this.getSourceConstant(n);48 //var sourceNegate = this.getSourceNegate(n);49 var sourceIndex = (info >> (0 + n * 2)) & 3;50 var sourceAbsolute = (info >> (8 + n * 1)) & 1;51 var sourceConstant = (info >> (12 + n * 1)) & 1;52 var sourceNegate = (info >> (16 + n * 1)) & 1;53 var value;54 if (sourceConstant) {55 switch (sourceIndex) {56 case 0: value = sourceAbsolute ? (3) : (0); break;57 case 1: value = sourceAbsolute ? (1 / 3) : (1); break;58 case 2: value = sourceAbsolute ? (1 / 4) : (2); break;59 case 3: value = sourceAbsolute ? (1 / 6) : (1 / 2); break;60 default: throw (new Error("Invalid operation")); break;61 }62 } else {63 //debugger;64 value = input[sourceIndex];65 if (sourceAbsolute) value = Math.abs(value);66 }67 if (sourceNegate) value = MathFloat.neg(value);68 output[n] = value;69 }70 }71 }72}73class VfpuPrefixWrite extends VfpuPrefixBase {74 //getDestinationSaturation(i: number) { return (this._info >> (0 + i * 2)) & 3; }75 //getDestinationMask(i: number) { return (this._info >> (8 + i * 1)) & 1; }76 storeTransformedValues(vfpr: any, indices: number[], values: number[]) {77 this._readInfo();78 var info = this._info;79 if (!this.enabled) {80 for (var n = 0; n < indices.length; n++) {81 vfpr[indices[n]] = values[n];82 }83 } else {84 //debugger;85 for (var n = 0; n < indices.length; n++) {86 //var destinationSaturation = this.getDestinationSaturation(n);87 //var destinationMask = this.getDestinationMask(n);88 var destinationSaturation = (info >> (0 + n * 2)) & 3;89 var destinationMask = (info >> (8 + n * 1)) & 1;90 if (destinationMask) {91 // Masked. No write value.92 } else {93 var value = values[n];94 switch (destinationSaturation) {95 case 1: value = MathFloat.sat0(value); break;96 case 3: value = MathFloat.sat1(value); break;97 default: break;98 }99 vfpr[indices[n]] = value;100 }101 }102 }103 }104}105export enum VFPU_CTRL {106 SPREFIX, TPREFIX, DPREFIX, CC, INF4, RSV5, RSV6, REV,107 RCX0, RCX1, RCX2, RCX3, RCX4, RCX5, RCX6, RCX7, MAX,108}109export enum VCondition {110 FL, EQ, LT, LE, TR, NE, GE, GT,111 EZ, EN, EI, ES, NZ, NN, NI, NS112};113export class CpuState {114 gpr_Buffer = new ArrayBuffer(32 * 4);115 gpr = new Int32Array(this.gpr_Buffer);116 gpr_f = new Float32Array(this.gpr_Buffer);117 executor: IExecutor;118 temp = new Array(16);119 fpr_Buffer = new ArrayBuffer(32 * 4);120 fpr = new Float32Array(this.fpr_Buffer);121 fpr_i = new Int32Array(this.fpr_Buffer);122 //fpr: Float32Array = new Float32Array(32);123 vfpr_Buffer = new ArrayBuffer(128 * 4);124 vfpr: Float32Array = new Float32Array(this.vfpr_Buffer);125 vfpr_i: Float32Array = new Int32Array(this.vfpr_Buffer);126 vfprc = [0, 0, 0, 0xFF, 0, 0, 0, 0, 0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000];127 setVfrCc(index: number, value: boolean) {128 if (value) {129 this.vfprc[VFPU_CTRL.CC] |= (1 << index);130 } else {131 this.vfprc[VFPU_CTRL.CC] &= ~(1 << index);132 }133 }134 vrnds() { }135 vrndi() {136 var v = 0;137 for (var n = 0; n < 4; n++) {138 v <<= 8;139 v |= (Math.round(Math.random() * 255) & 0xFF);140 }141 return v;142 }143 vrndf1() { return Math.random() * 2; }144 vrndf2() { return Math.random() * 4; }145 getVfrCc(index: number) {146 return ((this.vfprc[VFPU_CTRL.CC] & (1 << index)) != 0);147 }148 vcmp(cond: VCondition, vsValues: number[], vtValues: number[]) {149 var vectorSize = vsValues.length;150 this.loadVs_prefixed(vsValues);151 this.loadVt_prefixed(vtValues);152 var s = this.vector_vs;153 var t = this.vector_vt;154 var cc = 0;155 var or_val = 0;156 var and_val = 1;157 var affected_bits = (1 << 4) | (1 << 5); // 4 and 5158 for (var i = 0; i < vectorSize; i++) {159 var c = false;160 switch (cond) {161 case VCondition.FL: c = false; break;162 case VCondition.EQ: c = s[i] == t[i]; break;163 case VCondition.LT: c = s[i] < t[i]; break;164 case VCondition.LE: c = s[i] <= t[i]; break;165 case VCondition.TR: c = true; break;166 case VCondition.NE: c = s[i] != t[i]; break;167 case VCondition.GE: c = s[i] >= t[i]; break;168 case VCondition.GT: c = s[i] > t[i]; break;169 170 case VCondition.EZ: c = s[i] == 0.0 || s[i] == -0.0; break;171 case VCondition.EN: c = MathFloat.isnan(s[i]); break;172 case VCondition.EI: c = MathFloat.isinf(s[i]); break;173 case VCondition.ES: c = MathFloat.isnanorinf(s[i]); break; // Tekken Dark Resurrection174 175 case VCondition.NZ: c = s[i] != 0; break;176 case VCondition.NN: c = !MathFloat.isnan(s[i]); break;177 case VCondition.NI: c = !MathFloat.isinf(s[i]); break;178 case VCondition.NS: c = !(MathFloat.isnanorinf(s[i])); break; // How about t[i] ? 179 }180 var c_i = (c ? 1 : 0);181 cc |= (c_i << i);182 or_val |= c_i;183 and_val &= c_i;184 affected_bits |= 1 << i;185 }186 this.vfprc[VFPU_CTRL.CC] = (this.vfprc[VFPU_CTRL.CC] & ~affected_bits) | ((cc | (or_val << 4) | (and_val << 5)) & affected_bits);187 this.eatPrefixes();188 }189 vcmovtf(register: number, _true: boolean, vdRegs: number[], vsRegs: number[]) {190 var vectorSize = vdRegs.length;191 this.loadVs_prefixed(vsRegs.map(reg => this.vfpr[reg]));192 this.loadVdRegs(vdRegs);193 var compare = _true ? 1 : 0;194 var cc = this.vfprc[VFPU_CTRL.CC];195 if (register < 6) {196 if (((cc >> register) & 1) == compare) {197 for (var n = 0; n < vectorSize; n++) {198 this.vector_vd[n] = this.vector_vs[n];199 }200 }201 } if (register == 6) {202 for (var n = 0; n < vectorSize; n++) {203 if (((cc >> n) & 1) == compare) {204 this.vector_vd[n] = this.vector_vs[n];205 }206 }207 } else {208 }209 this.storeVdRegsWithPrefix(vdRegs);210 }211 private vpfxs = new VfpuPrefixRead(this.vfprc, VFPU_CTRL.SPREFIX);212 private vpfxt = new VfpuPrefixRead(this.vfprc, VFPU_CTRL.TPREFIX);213 private vpfxd = new VfpuPrefixWrite(this.vfprc, VFPU_CTRL.DPREFIX);214 setVpfxt(value: number) { this.vpfxt.setInfo(value); }215 setVpfxs(value: number) { this.vpfxs.setInfo(value); }216 setVpfxd(value: number) { this.vpfxd.setInfo(value); }217 vector_vs = [0, 0, 0, 0];218 vector_vt = [0, 0, 0, 0];219 vector_vd = [0, 0, 0, 0];220 get vfpumatrix0() { return this.getVfpumatrix(0); }221 get vfpumatrix1() { return this.getVfpumatrix(1); }222 get vfpumatrix2() { return this.getVfpumatrix(2); }223 get vfpumatrix3() { return this.getVfpumatrix(3); }224 get vfpumatrix4() { return this.getVfpumatrix(4); }225 get vfpumatrix5() { return this.getVfpumatrix(5); }226 get vfpumatrix6() { return this.getVfpumatrix(6); }227 get vfpumatrix7() { return this.getVfpumatrix(7); }228 eatPrefixes() {229 this.vpfxd.eat();230 this.vpfxt.eat();231 this.vpfxs.eat();232 }233 getVfpumatrix(index: number) {234 var values = [];235 for (var r = 0; r < 4; r++) {236 for (var c = 0; c < 4; c++) {237 values.push(this.vfpr[r * 32 + index * 4 + c]);238 }239 }240 return values;241 }242 loadVdRegs(regs: number[]) {243 for (var n = 0; n < regs.length; n++) {244 this.vector_vd[n] = this.vfpr[regs[n]];245 }246 }247 storeVdRegsWithPrefix(regs: number[]) {248 this.vpfxd.storeTransformedValues(this.vfpr, regs, this.vector_vd);249 this.vpfxd.eat();250 this.storeVdRegs(regs);251 }252 storeVdRegsWithPrefix1(regs: number[]) {253 this.vpfxd.storeTransformedValues(this.vfpr, regs, this.vector_vd);254 this.vpfxd.eat();255 this.storeVdRegs(regs);256 }257 storeVdRegs(regs: number[]) {258 for (var n = 0; n < regs.length; n++) this.vfpr[regs[n]] = this.vector_vd[n];259 }260 loadVs_prefixed(values: number[]) {261 this.vpfxs.transformValues(values, this.vector_vs);262 this.vpfxs.eat();263 }264 loadVt_prefixed(values: number[]) {265 this.vpfxt.transformValues(values, this.vector_vt);266 this.vpfxt.eat();267 }268 storeVd_prefixed(indices: number[], values: number[]) {269 this.vpfxd.storeTransformedValues(this.vfpr, indices, values);270 this.vpfxd.eat();271 }272 storeVd_prefixed_i(indices: number[], values: number[]) {273 this.vpfxd.storeTransformedValues(this.vfpr_i, indices, values);274 this.vpfxd.eat();275 }276 _vt4444_step(i0: number, i1: number) {277 var o = 0;278 o |= ((i0 >> 4) & 15) << 0;279 o |= ((i0 >> 12) & 15) << 4;280 o |= ((i0 >> 20) & 15) << 8;281 o |= ((i0 >> 28) & 15) << 12;282 o |= ((i1 >> 4) & 15) << 16;283 o |= ((i1 >> 12) & 15) << 20;284 o |= ((i1 >> 20) & 15) << 24;285 o |= ((i1 >> 28) & 15) << 28;286 return o;287 }288 _vt5551_step(i0: number, i1: number) {289 var o = 0;290 o |= ((i0 >> 3) & 31) << 0;291 o |= ((i0 >> 11) & 31) << 5;292 o |= ((i0 >> 19) & 31) << 10;293 o |= ((i0 >> 31) & 1) << 15;294 o |= ((i1 >> 3) & 31) << 16;295 o |= ((i1 >> 11) & 31) << 21;296 o |= ((i1 >> 19) & 31) << 26;297 o |= ((i1 >> 31) & 1) << 31;298 return o;299 }300 _vt5650_step(i0: number, i1: number) {301 var o = 0;302 o |= ((i0 >> 3) & 31) << 0;303 o |= ((i0 >> 10) & 63) << 5;304 o |= ((i0 >> 19) & 31) << 11;305 o |= ((i1 >> 3) & 31) << 16;306 o |= ((i1 >> 10) & 63) << 21;307 o |= ((i1 >> 19) & 31) << 27;308 return o;309 }310 svl_q(address: number, r: number[]) {311 var k = (3 - ((address >>> 2) & 3));312 address &= ~0xF;313 for (var n = k; n < 4; n++, address += 4) this.memory.writeInt32(address, this.vfpr_i[r[n]]);314 }315 svr_q(address: number, r: number[]) {316 var k = (4 - ((address >>> 2) & 3));317 for (var n = 0; n < k; n++, address += 4) this.memory.writeInt32(address, this.vfpr_i[r[n]]);318 }319 lvl_q(address: number, r: number[]) {320 var k = (3 - ((address >>> 2) & 3));321 address &= ~0xF;322 for (var n = k; n < 4; n++, address += 4) this.vfpr_i[r[n]] = this.memory.readInt32(address);323 }324 lvr_q(address: number, r: number[]) {325 var k = (4 - ((address >>> 2) & 3));326 for (var n = 0; n < k; n++, address += 4) this.vfpr_i[r[n]] = this.memory.readInt32(address);327 }328 storeFloats(address: number, values: number[]) {329 for (var n = 0; n < values.length; n++) {330 this.memory.writeFloat32(address + n * 4, values[n]);331 }332 }333 vfpuStore(indices: number[], values: number[]) { for (var n = 0; n < indices.length; n++) this.vfpr[indices[n]] = values[n]; }334 vfpuStore_i(indices: number[], values: number[]) { for (var n = 0; n < indices.length; n++) this.vfpr_i[indices[n]] = values[n]; }335 vfpuSetMatrix(m: number, values: number[]) {336 // @TODO337 this.vfpr[0] = 0;338 }339 BRANCHFLAG: boolean = false;340 BRANCHPC: number = 0;341 PC: number = 0;342 IC: number = 0;343 LO: number = 0;344 HI: number = 0;345 thread: any = null;346 preserveRegisters(callback: () => void) {347 var temp = new CpuState(this.memory, this.syscallManager);348 temp.copyRegistersFrom(this);349 try {350 callback();351 } finally {352 this.copyRegistersFrom(temp);353 }354 }355 copyRegistersFrom(other: CpuState) {356 this.PC = other.PC;357 this.IC = other.IC;358 this.LO = other.LO;359 this.HI = other.HI;360 for (var n = 0; n < 32; n++) this.gpr[n] = other.gpr[n];361 for (var n = 0; n < 32; n++) this.fpr[n] = other.fpr[n];362 for (var n = 0; n < 128; n++) this.vfpr[n] = other.vfpr[n];363 for (var n = 0; n < 8; n++) this.vfprc[n] = other.vfprc[n];364 }365 get V0():number { return this.gpr[2]; } set V0(value: number) { this.gpr[2] = value; }366 get V1():number { return this.gpr[3]; } set V1(value: number) { this.gpr[3] = value; }367 get K0():number { return this.gpr[26]; } set K0(value: number) { this.gpr[26] = value; }368 get GP():number { return this.gpr[28]; } set GP(value: number) { this.gpr[28] = value; }369 get SP():number { return this.gpr[29]; } set SP(value: number) { this.gpr[29] = value; }370 get FP():number { return this.gpr[30]; } set FP(value: number) { this.gpr[30] = value; }371 get RA(): number { return this.gpr[31]; } set RA(value: number) { this.gpr[31] = value; }372 getRA(): number { return this.gpr[31]; } setRA(value: number) { this.gpr[31] = value; }373 private callstack: number[] = [];374 callstackPush(PC: number) {375 //this.callstack.push(PC);376 }377 callstackPop() {378 //this.callstack.pop();379 }380 printCallstack(symbolLookup: any = null) {381 this.getCallstack().forEach((PC) => {382 var line = sprintf("%08X", PC);383 if (symbolLookup) {384 line += sprintf(' : %s', symbolLookup.getSymbolAt(PC));385 }386 console.log(line);387 });388 }389 getCallstack() {390 return this.callstack.slice(0);391 }392 getPointerStream(address: number, size?: number) {393 return this.memory.getPointerStream(address, size);394 }395 getPointerU8Array(address: number, size?: number) {396 return this.memory.getPointerU8Array(address, size)397 }398 get REGS() {399 return sprintf('r1: %08X, r2: %08X, r3: %08X, r3: %08X', this.gpr[1], this.gpr[2], this.gpr[3], this.gpr[4]);400 }401 constructor(public memory: Memory, public syscallManager: ISyscallManager) {402 this.fcr0 = 0x00003351;403 this.fcr31 = 0x00000e00;404 }405 fcr31_rm: number = 0;406 fcr31_2_21: number = 0;407 fcr31_25_7: number = 0;408 fcr31_cc: boolean = false;409 fcr31_fs: boolean = false;410 fcr0 = 0x00003351;411 _trace_state() {412 console.info(this);413 throw ('_trace_state');414 }415 get fcr31() {416 var value = 0;417 value = BitUtils.insert(value, 0, 2, this.fcr31_rm);418 value = BitUtils.insert(value, 2, 21, this.fcr31_2_21);419 value = BitUtils.insert(value, 23, 1, this.fcr31_cc ? 1 : 0);420 value = BitUtils.insert(value, 24, 1, this.fcr31_fs ? 1 : 0);421 value = BitUtils.insert(value, 25, 7, this.fcr31_25_7);422 return value;423 }424 425 set fcr31(value: number) {426 this.fcr31_rm = BitUtils.extract(value, 0, 2);427 this.fcr31_2_21 = BitUtils.extract(value, 2, 21);428 this.fcr31_cc = (BitUtils.extract(value, 23, 1) != 0);429 this.fcr31_fs = (BitUtils.extract(value, 24, 1) != 0);430 this.fcr31_25_7 = BitUtils.extract(value, 25, 7);431 }432 get fcr0_rev() { return BitUtils.extract(this.fcr0, 0, 8); }433 get fcr0_imp() { return BitUtils.extract(this.fcr0, 8, 24); }434 _cfc1_impl(d: number, t: number) {435 switch (d) {436 case 0: this.gpr[t] = this.fcr0; break;437 case 31: this.gpr[t] = this.fcr31; break;438 default: this.gpr[t] = 0; break;439 }440 }441 _ctc1_impl(d: number, t: number) {442 switch (d) {443 case 31: this.fcr31 = t; break;444 }445 }446 _comp_impl(s: number, t: number, fc_unordererd: boolean, fc_equal: boolean, fc_less: boolean, fc_inv_qnan: boolean) {447 if (isNaN(s) || isNaN(t)) {448 this.fcr31_cc = fc_unordererd;449 }450 else {451 //bool cc = false;452 //if (fc_equal) cc = cc || (s == t);453 //if (fc_less) cc = cc || (s < t);454 //return cc;455 var equal = (fc_equal) && (s == t);456 var less = (fc_less) && (s < t);457 this.fcr31_cc = (less || equal);458 }459 }460 _cvt_w_s_impl(FS: number) {461 //Console.WriteLine("_cvt_w_s_impl: {0}", CpuThreadState.FPR[FS]);462 switch (this.fcr31_rm) {463 case 0: return MathFloat.rint(FS); // rint: round nearest464 case 1: return MathFloat.cast(FS); // round to zero465 case 2: return MathFloat.ceil(FS); // round up (ceil)466 case 3: return MathFloat.floor(FS); // round down (floor)467 }468 throw ("RM has an invalid value!!");469 }470 cache(rs: number, type: number, offset: number) {471 //if (DebugOnce('state.cache', 100)) console.warn(sprintf('cache opcode! %08X+%d, type: %d', rs, offset, type));472 }473 syscall(id: number) { this.syscallManager.call(this, id); }474 sb(value: number, address: number) { this.memory.writeInt8(address, value); }475 sh(value: number, address: number) { this.memory.writeInt16(address, value); }476 sw(value: number, address: number) { this.memory.writeInt32(address, value); }477 swc1(value: number, address: number) { this.memory.writeFloat32(address, value); }478 lb(address: number) { return this.memory.readInt8(address); }479 lbu(address: number) { return this.memory.readUInt8(address); }480 lh(address: number) { return this.memory.readInt16(address); }481 lhu(address: number) { return this.memory.readUInt16(address); }482 lw(address: number) { return this.memory.readInt32(address); }483 lwc1(address: number) { return this.memory.readFloat32(address); }484 min(a: number, b: number) { return ((a | 0) < (b | 0)) ? a : b; }485 max(a: number, b: number) { return ((a | 0) > (b | 0)) ? a : b; }486 slt(a: number, b: number) { return ((a | 0) < (b | 0)) ? 1 : 0; }487 sltu(a: number, b: number) { return ((a >>> 0) < (b >>> 0)) ? 1 : 0; }488 private static LwrMask = [ 0x00000000, 0xFF000000, 0xFFFF0000, 0xFFFFFF00 ];489 private static LwrShift = [ 0, 8, 16, 24 ];490 private static LwlMask = [ 0x00FFFFFF, 0x0000FFFF, 0x000000FF, 0x00000000 ];491 private static LwlShift = [ 24, 16, 8, 0 ];492 lwl(RS: number, Offset: number, ValueToWrite: number) {493 var Address = (RS + Offset);494 var AddressAlign = Address & 3;495 var Value = this.memory.readInt32(Address & ~3);496 return ((Value << CpuState.LwlShift[AddressAlign]) | (ValueToWrite & CpuState.LwlMask[AddressAlign]));497 }498 lwr(RS: number, Offset: number, ValueToWrite: number) {499 var Address = (RS + Offset);500 var AddressAlign = Address & 3;501 var Value = this.memory.readInt32(Address & ~3);502 return ((Value >>> CpuState.LwrShift[AddressAlign]) | (ValueToWrite & CpuState.LwrMask[AddressAlign]));503 }504 private static SwlMask = [ 0xFFFFFF00, 0xFFFF0000, 0xFF000000, 0x00000000 ];505 private static SwlShift = [24, 16, 8, 0];506 private static SwrMask = [0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF];507 private static SwrShift = [0, 8, 16, 24];508 swl(RS: number, Offset: number, ValueToWrite: number) {509 var Address = (RS + Offset);510 var AddressAlign = Address & 3;511 var AddressPointer = Address & ~3;512 var WordToWrite = (ValueToWrite >>> CpuState.SwlShift[AddressAlign]) | (this.memory.readInt32(AddressPointer) & CpuState.SwlMask[AddressAlign]);513 this.memory.writeInt32(AddressPointer, WordToWrite);514 }515 swr(RS: number, Offset: number, ValueToWrite: number) {516 var Address = (RS + Offset);517 var AddressAlign = Address & 3;518 var AddressPointer = Address & ~3;519 var WordToWrite = (ValueToWrite << CpuState.SwrShift[AddressAlign]) | (this.memory.readInt32(AddressPointer) & CpuState.SwrMask[AddressAlign]);520 this.memory.writeInt32(AddressPointer, WordToWrite);521 }522 div(rs: number, rt: number) {523 rs |= 0; // signed524 rt |= 0; // signed525 this.LO = (rs / rt) | 0;526 this.HI = (rs % rt) | 0;527 }528 divu(rs: number, rt: number) {529 rs >>>= 0; // unsigned530 rt >>>= 0; // unsigned531 this.LO = (rs / rt) | 0;532 this.HI = (rs % rt) | 0;533 }534 private static _mult_temp = [0, 0];535 mult(rs: number, rt: number) {536 Math.imul32_64(rs, rt, CpuState._mult_temp);537 this.LO = CpuState._mult_temp[0];538 this.HI = CpuState._mult_temp[1];539 }540 madd(rs: number, rt: number) {541 var a64 = Integer64.fromInt(rs);542 var b64 = Integer64.fromInt(rt);543 var result = Integer64.fromBits(this.LO, this.HI).add(a64.multiply(b64));544 this.HI = result.high;545 this.LO = result.low;546 }547 msub(rs: number, rt: number) {548 var a64 = Integer64.fromInt(rs);549 var b64 = Integer64.fromInt(rt);550 var result = Integer64.fromBits(this.LO, this.HI).sub(a64.multiply(b64));551 this.HI = result.high;552 this.LO = result.low;553 }554 multu(rs: number, rt: number) {555 var info = Math.umul32_64(rs, rt, CpuState._mult_temp);556 this.LO = info[0];557 this.HI = info[1];558 }559 maddu(rs: number, rt: number) {560 var a64 = Integer64.fromUnsignedInt(rs);561 var b64 = Integer64.fromUnsignedInt(rt);562 var result = Integer64.fromBits(this.LO, this.HI).add(a64.multiply(b64));563 this.HI = result.high;564 this.LO = result.low;565 }566 msubu(rs: number, rt: number) {567 var a64 = Integer64.fromUnsignedInt(rs);568 var b64 = Integer64.fromUnsignedInt(rt);569 var result = Integer64.fromBits(this.LO, this.HI).sub(a64.multiply(b64));570 this.HI = result.high;571 this.LO = result.low;572 }573 callPC(pc: number) {574 this.PC = pc;575 var ra = this.getRA();576 this.executor.executeUntilPCReachesWithoutCall(ra);577 }578 callPCSafe(pc: number) {579 this.PC = pc;580 var ra = this.getRA();581 while (this.PC != ra) {582 /*583 if (DebugOnce('test', 10)) {584 console.log(this.PC, this.RA, ra);585 } else {586 throw(new Error("TOO BAD!"));587 }588 */589 try {590 this.executor.executeUntilPCReachesWithoutCall(ra);591 } catch (e) {592 if (!(e instanceof CpuBreakException)) {593 console.error(e);594 console.error(e['stack']);595 throw (e);596 }597 }598 }599 }600 break() { throw (new CpuBreakException()); }...
BigIntArbitrary.spec.ts
Source:BigIntArbitrary.spec.ts
1import * as fc from 'fast-check';2import { BigIntArbitrary } from '../../../../src/arbitrary/_internals/BigIntArbitrary';3import { Value } from '../../../../src/check/arbitrary/definition/Value';4import { fakeRandom } from '../__test-helpers__/RandomHelpers';5import {6 assertProduceValuesShrinkableWithoutContext,7 assertProduceCorrectValues,8 assertShrinkProducesSameValueWithoutInitialContext,9 assertShrinkProducesStrictlySmallerValue,10 assertProduceSameValueGivenSameSeed,11} from '../__test-helpers__/ArbitraryAssertions';12import { buildShrinkTree, renderTree, walkTree } from '../__test-helpers__/ShrinkTree';13import { Stream } from '../../../../src/stream/Stream';14import * as BiasNumericRangeMock from '../../../../src/arbitrary/_internals/helpers/BiasNumericRange';15import * as ShrinkBigIntMock from '../../../../src/arbitrary/_internals/helpers/ShrinkBigInt';16function beforeEachHook() {17 jest.resetModules();18 jest.restoreAllMocks();19 fc.configureGlobal({ beforeEach: beforeEachHook });20}21beforeEach(beforeEachHook);22describe('BigIntArbitrary', () => {23 if (typeof BigInt === 'undefined') {24 it('no test', () => {25 expect(true).toBe(true);26 });27 return;28 }29 describe('generate', () => {30 it('should never bias and generate the full range when biasFactor is not specified', () =>31 fc.assert(32 fc.property(fc.bigInt(), fc.bigInt(), fc.bigInt(), (a, b, c) => {33 // Arrange34 const [min, mid, max] = [a, b, c].sort((v1, v2) => Number(v1 - v2));35 const { instance: mrng, nextBigInt } = fakeRandom();36 nextBigInt.mockReturnValueOnce(mid);37 // Act38 const arb = new BigIntArbitrary(min, max);39 const out = arb.generate(mrng, undefined);40 // Assert41 expect(out.value).toBe(mid);42 expect(nextBigInt).toHaveBeenCalledTimes(1);43 expect(nextBigInt).toHaveBeenCalledWith(min, max);44 })45 ));46 it('should not always bias values (expect 1 times over biasFreq) and still generate full range when unbiased', () =>47 fc.assert(48 fc.property(fc.bigInt(), fc.bigInt(), fc.bigInt(), fc.maxSafeInteger(), (a, b, c, biasFactor) => {49 // Arrange50 const [min, mid, max] = [a, b, c].sort((v1, v2) => Number(v1 - v2));51 const { instance: mrng, nextInt, nextBigInt } = fakeRandom();52 nextInt.mockReturnValueOnce(2); // 1 means bias, all others are unbiased53 nextBigInt.mockReturnValueOnce(mid);54 // Act55 const arb = new BigIntArbitrary(min, max);56 const out = arb.generate(mrng, biasFactor);57 // Assert58 expect(out.value).toBe(mid);59 expect(nextInt).toHaveBeenCalledTimes(1);60 expect(nextInt).toHaveBeenCalledWith(1, biasFactor);61 expect(nextBigInt).toHaveBeenCalledTimes(1);62 expect(nextBigInt).toHaveBeenCalledWith(min, max);63 })64 ));65 it('should bias values (1 times over biasFreq) by using one of the ranges from biasNumericRange', () =>66 fc.assert(67 fc.property(68 fc.bigInt(),69 fc.bigInt(),70 fc.bigInt(),71 fc.maxSafeInteger(),72 fc.maxSafeInteger(),73 // Remark:74 // Following biasNumericRange is not fully identical to the onces that would be provided.75 // Range (in this stub) can be larger than the requested one. Not impacting from a unit-test point of view.76 fc.array(77 fc.tuple(fc.bigInt(), fc.bigInt()).map(([a, b]) => (a < b ? { min: a, max: b } : { min: b, max: a })),78 { minLength: 1 }79 ),80 (a, b, c, biasFactor, mod, ranges) => {81 // Arrange82 const [min, mid, max] = [a, b, c].sort((v1, v2) => Number(v1 - v2));83 const { instance: mrng, nextInt, nextBigInt } = fakeRandom();84 nextInt.mockReturnValueOnce(1); // 1 means bias85 if (ranges.length !== 1) {86 nextInt.mockImplementationOnce((min, max) => min + (mod % (max - min + 1)));87 }88 nextBigInt.mockReturnValueOnce(mid); // Remark: this value will most of the time be outside of requested range89 const biasNumericRange = jest.spyOn(90 BiasNumericRangeMock,91 'biasNumericRange'92 ) as unknown as jest.SpyInstance<{ min: bigint; max: bigint }[], [bigint, bigint, () => bigint]>;93 biasNumericRange.mockReturnValueOnce(ranges);94 // Act95 const arb = new BigIntArbitrary(min, max);96 const out = arb.generate(mrng, biasFactor);97 // Assert98 expect(out.value).toBe(mid);99 expect(biasNumericRange).toHaveBeenCalledTimes(1);100 expect(biasNumericRange).toHaveBeenCalledWith(min, max, expect.any(Function));101 if (ranges.length === 1) {102 expect(nextInt).toHaveBeenCalledTimes(1);103 expect(nextInt).toHaveBeenCalledWith(1, biasFactor);104 expect(nextBigInt).toHaveBeenCalledTimes(1);105 expect(nextBigInt).toHaveBeenCalledWith(ranges[0].min, ranges[0].max);106 } else {107 expect(nextInt).toHaveBeenCalledTimes(2);108 expect(nextInt).toHaveBeenCalledWith(1, biasFactor);109 const secondNextIntParams = nextInt.mock.calls[1];110 expect(secondNextIntParams[0]).toBeLessThan(0); // arbitrary is supposed to prefer the first entry111 expect(secondNextIntParams[1]).toBe(ranges.length - 2); // other entries do not have any special treatments112 // negative values for [0], positive value n means ranges[n+1]113 const secondNextIntResult = nextInt.mock.results[1].value;114 const selectedRange = secondNextIntResult < 0 ? 0 : secondNextIntResult + 1;115 expect(nextBigInt).toHaveBeenCalledWith(ranges[selectedRange].min, ranges[selectedRange].max);116 }117 }118 )119 ));120 });121 describe('canShrinkWithoutContext', () => {122 it('should always tells it can generate values included in the requested range', () =>123 fc.assert(124 fc.property(fc.bigInt(), fc.bigInt(), fc.bigInt(), (a, b, c) => {125 // Arrange126 const [min, mid, max] = [a, b, c].sort((v1, v2) => Number(v1 - v2));127 // Act128 const arb = new BigIntArbitrary(min, max);129 const out = arb.canShrinkWithoutContext(mid);130 // Assert131 expect(out).toBe(true);132 })133 ));134 it('should always reject values outside of the requested range', () =>135 fc.assert(136 fc.property(137 fc.bigInt(),138 fc.bigInt(),139 fc.bigInt(),140 fc.constantFrom(...(['lower', 'higher'] as const)),141 (a, b, c, position) => {142 // Arrange143 const s = [a, b, c].sort((v1, v2) => Number(v1 - v2));144 const [min, max, requested] = position === 'lower' ? [s[1], s[2], s[0]] : [s[0], s[1], s[2]];145 fc.pre(requested !== min && requested !== max);146 // Act147 const arb = new BigIntArbitrary(min, max);148 const out = arb.canShrinkWithoutContext(requested);149 // Assert150 expect(out).toBe(false);151 }152 )153 ));154 it.each`155 requested156 ${'1'}157 ${1}158 ${'1n'}159 ${1.5}160 ${-0}161 ${Number.NaN}162 ${''}163 ${{}}164 `('should always reject non bigint values like $requested', ({ requested }) => {165 // Arrange166 const min = BigInt(0);167 const max = BigInt(100);168 // Act169 const arb = new BigIntArbitrary(min, max);170 const out = arb.canShrinkWithoutContext(requested);171 // Assert172 expect(out).toBe(false);173 });174 });175 describe('shrink', () => {176 it('should always call shrink helper when no context provided', () =>177 fc.assert(178 fc.property(fc.bigInt(), fc.bigInt(), fc.bigInt(), (a, b, c) => {179 // Arrange180 const [min, mid, max] = [a, b, c].sort((v1, v2) => Number(v1 - v2));181 const expectedShrinks = Stream.nil<Value<bigint>>();182 const shrinkBigInt = jest.spyOn(ShrinkBigIntMock, 'shrinkBigInt');183 shrinkBigInt.mockReturnValueOnce(expectedShrinks);184 // Act185 const arb = new BigIntArbitrary(min, max);186 const shrinks = arb.shrink(mid, undefined);187 // Assert188 expect(shrinks).toBe(expectedShrinks);189 expect(shrinkBigInt).toHaveBeenCalledTimes(1);190 expect(shrinkBigInt).toHaveBeenCalledWith(mid, expect.any(BigInt), true);191 })192 ));193 });194});195describe('BigIntArbitrary (integration)', () => {196 if (typeof BigInt === 'undefined') {197 it('no test', () => {198 expect(true).toBe(true);199 });200 return;201 }202 type Extra = { min: bigint; max: bigint };203 const extraParameters: fc.Arbitrary<Extra> = fc204 .tuple(fc.bigInt(), fc.bigInt())205 .map(([a, b]) => (a < b ? { min: a, max: b } : { min: b, max: a }));206 const isCorrect = (value: bigint, extra: Extra) =>207 typeof value === 'bigint' && extra.min <= value && value <= extra.max;208 const isStrictlySmaller = (v1: bigint, v2: bigint) => {209 const absV1 = v1 < BigInt(0) ? -v1 : v1;210 const absV2 = v2 < BigInt(0) ? -v2 : v2;211 return absV1 < absV2;212 };213 const bigIntBuilder = (extra: Extra) => new BigIntArbitrary(extra.min, extra.max);214 it('should produce the same values given the same seed', () => {215 assertProduceSameValueGivenSameSeed(bigIntBuilder, { extraParameters });216 });217 it('should only produce correct values', () => {218 assertProduceCorrectValues(bigIntBuilder, isCorrect, { extraParameters });219 });220 it('should produce values seen as shrinkable without any context', () => {221 assertProduceValuesShrinkableWithoutContext(bigIntBuilder, { extraParameters });222 });223 it('should be able to shrink to the same values without initial context', () => {224 assertShrinkProducesSameValueWithoutInitialContext(bigIntBuilder, { extraParameters });225 });226 it('should shrink towards strictly smaller values', () => {227 assertShrinkProducesStrictlySmallerValue(bigIntBuilder, isStrictlySmaller, { extraParameters });228 });229 describe('shrink', () => {230 it('should build a mirrored version of the shrinking tree if we negate all the values', () =>231 fc.assert(232 fc.property(233 fc.bigInt(),234 fc.bigUint({ max: BigInt(20) }), // larger trees might be too wide235 fc.bigUint({ max: BigInt(20) }),236 (start, o1, o2) => {237 // Arrange238 const min = start;239 const [mid, max] = o1 < o2 ? [min + o1, min + o2] : [min + o2, min + o1];240 const arb = new BigIntArbitrary(min, max);241 const arbNegate = new BigIntArbitrary(-max, -min);242 // Act243 const source = new Value(mid, undefined);244 const sourceNegate = new Value(-mid, undefined);245 const tree = buildShrinkTree(arb, source);246 const treeNegate = buildShrinkTree(arbNegate, sourceNegate);247 const flat: bigint[] = [];248 const flatNegate: bigint[] = [];249 walkTree(tree, (v) => flat.push(v));250 walkTree(treeNegate, (v) => flatNegate.push(-v));251 // Assert252 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);253 expect(arbNegate.canShrinkWithoutContext(sourceNegate.value)).toBe(true);254 expect(flatNegate).toEqual(flat);255 }256 )257 ));258 it('should build an offset version of the shrinking tree if we offset all the values (keep every value >=0)', () =>259 fc.assert(260 fc.property(261 fc.bigUint(),262 fc.bigUint({ max: BigInt(20) }), // larger trees might be too wide263 fc.bigUint({ max: BigInt(20) }),264 fc.bigUint(),265 (start, o1, o2, offset) => {266 // Arrange267 fc.pre(start + o1 + offset <= Number.MAX_SAFE_INTEGER);268 fc.pre(start + o2 + offset <= Number.MAX_SAFE_INTEGER);269 const min = start;270 const [mid, max] = o1 < o2 ? [min + o1, min + o2] : [min + o2, min + o1];271 const arb = new BigIntArbitrary(min, max);272 const arbOffset = new BigIntArbitrary(min + offset, max + offset);273 // Act274 const source = new Value(mid, undefined);275 const sourceOffset = new Value(mid + offset, undefined);276 const tree = buildShrinkTree(arb, source);277 const treeOffset = buildShrinkTree(arbOffset, sourceOffset);278 const flat: bigint[] = [];279 const flatOffset: bigint[] = [];280 walkTree(tree, (v) => flat.push(v));281 walkTree(treeOffset, (v) => flatOffset.push(v - offset));282 // Assert283 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);284 expect(arbOffset.canShrinkWithoutContext(sourceOffset.value)).toBe(true);285 expect(flatOffset).toEqual(flat);286 }287 )288 ));289 it('should shrink strictly positive value for positive range including zero', () => {290 // Arrange291 const arb = new BigIntArbitrary(BigInt(0), BigInt(10));292 const source = new Value(BigInt(8), undefined);293 // Act294 const tree = buildShrinkTree(arb, source);295 const renderedTree = renderTree(tree).join('\n');296 // Assert297 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);298 // When there is no more option, the shrinker retry one time with the value299 // current-1 to check if something that changed outside (another value not itself)300 // may have changed the situation.301 expect(renderedTree).toMatchInlineSnapshot(`302 "8n303 â> 0n304 â> 4n305 | â> 2n306 | | â> 1n307 | | â> 0n308 | â> 3n309 | â> 2n310 | â> 0n311 | â> 1n312 | â> 0n313 â> 6n314 | â> 5n315 | â> 4n316 | â> 0n317 | â> 2n318 | | â> 1n319 | | â> 0n320 | â> 3n321 | â> 2n322 | â> 0n323 | â> 1n324 | â> 0n325 â> 7n326 â> 6n327 â> 0n328 â> 3n329 | â> 2n330 | â> 1n331 | â> 0n332 â> 5n333 â> 4n334 â> 3n335 â> 0n336 â> 2n337 â> 1n338 â> 0n"339 `);340 // Remarks:341 // * When we shrink 5 in path 8 > 6 > 5342 // we already now that 4 passed so we now that the smallest failing case343 // to look for is >= 5344 // * Same thing when we shrink 6 in path 8 > 6345 // * When we shrink 7 in path 8 > 7346 // we already now that 6 passed so we now that the smallest failing case347 // to look for is >= 7348 });349 it('should shrink strictly positive value for range not including zero', () => {350 // Arrange351 const arb = new BigIntArbitrary(BigInt(10), BigInt(20));352 const source = new Value(BigInt(18), undefined);353 // Act354 const tree = buildShrinkTree(arb, source);355 const renderedTree = renderTree(tree).join('\n');356 // Assert357 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);358 // As the range [10, 20] and the value 18359 // are just offset by +10 compared to the first case,360 // the rendered tree will be offset by 10 too361 expect(renderedTree).toMatchInlineSnapshot(`362 "18n363 â> 10n364 â> 14n365 | â> 12n366 | | â> 11n367 | | â> 10n368 | â> 13n369 | â> 12n370 | â> 10n371 | â> 11n372 | â> 10n373 â> 16n374 | â> 15n375 | â> 14n376 | â> 10n377 | â> 12n378 | | â> 11n379 | | â> 10n380 | â> 13n381 | â> 12n382 | â> 10n383 | â> 11n384 | â> 10n385 â> 17n386 â> 16n387 â> 10n388 â> 13n389 | â> 12n390 | â> 11n391 | â> 10n392 â> 15n393 â> 14n394 â> 13n395 â> 10n396 â> 12n397 â> 11n398 â> 10n"399 `);400 });401 it('should shrink strictly negative value for negative range including zero', () => {402 // Arrange403 const arb = new BigIntArbitrary(BigInt(-10), BigInt(0));404 const source = new Value(BigInt(-8), undefined);405 // Act406 const tree = buildShrinkTree(arb, source);407 const renderedTree = renderTree(tree).join('\n');408 // Assert409 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);410 // As the range [-10, 0] and the value -8411 // are the opposite of first case, the rendered tree will be the same except412 // it contains opposite values413 expect(renderedTree).toMatchInlineSnapshot(`414 "-8n415 â> 0n416 â> -4n417 | â> -2n418 | | â> -1n419 | | â> 0n420 | â> -3n421 | â> -2n422 | â> 0n423 | â> -1n424 | â> 0n425 â> -6n426 | â> -5n427 | â> -4n428 | â> 0n429 | â> -2n430 | | â> -1n431 | | â> 0n432 | â> -3n433 | â> -2n434 | â> 0n435 | â> -1n436 | â> 0n437 â> -7n438 â> -6n439 â> 0n440 â> -3n441 | â> -2n442 | â> -1n443 | â> 0n444 â> -5n445 â> -4n446 â> -3n447 â> 0n448 â> -2n449 â> -1n450 â> 0n"451 `);452 });453 });...
IntegerArbitrary.spec.ts
Source:IntegerArbitrary.spec.ts
1import * as fc from 'fast-check';2import { IntegerArbitrary } from '../../../../src/arbitrary/_internals/IntegerArbitrary';3import { Value } from '../../../../src/check/arbitrary/definition/Value';4import { fakeRandom } from '../__test-helpers__/RandomHelpers';5import {6 assertProduceValuesShrinkableWithoutContext,7 assertProduceCorrectValues,8 assertShrinkProducesSameValueWithoutInitialContext,9 assertShrinkProducesStrictlySmallerValue,10 assertProduceSameValueGivenSameSeed,11} from '../__test-helpers__/ArbitraryAssertions';12import { buildShrinkTree, renderTree, walkTree } from '../__test-helpers__/ShrinkTree';13import * as BiasNumericRangeMock from '../../../../src/arbitrary/_internals/helpers/BiasNumericRange';14import * as ShrinkIntegerMock from '../../../../src/arbitrary/_internals/helpers/ShrinkInteger';15import { Stream } from '../../../../src/stream/Stream';16function beforeEachHook() {17 jest.resetModules();18 jest.restoreAllMocks();19 fc.configureGlobal({ beforeEach: beforeEachHook });20}21beforeEach(beforeEachHook);22describe('IntegerArbitrary', () => {23 describe('generate', () => {24 it('should never bias and generate the full range when biasFactor is not specified', () =>25 fc.assert(26 fc.property(fc.maxSafeInteger(), fc.maxSafeInteger(), fc.maxSafeInteger(), (a, b, c) => {27 // Arrange28 const [min, mid, max] = [a, b, c].sort((v1, v2) => v1 - v2);29 const { instance: mrng, nextInt } = fakeRandom();30 nextInt.mockReturnValueOnce(mid);31 // Act32 const arb = new IntegerArbitrary(min, max);33 const out = arb.generate(mrng, undefined);34 // Assert35 expect(out.value).toBe(mid);36 expect(nextInt).toHaveBeenCalledTimes(1);37 expect(nextInt).toHaveBeenCalledWith(min, max);38 })39 ));40 it('should not always bias values (expect 1 times over biasFreq) and still generate full range when unbiased', () =>41 fc.assert(42 fc.property(43 fc.maxSafeInteger(),44 fc.maxSafeInteger(),45 fc.maxSafeInteger(),46 fc.maxSafeInteger(),47 (a, b, c, biasFactor) => {48 // Arrange49 const [min, mid, max] = [a, b, c].sort((v1, v2) => v1 - v2);50 const { instance: mrng, nextInt } = fakeRandom();51 nextInt.mockReturnValueOnce(2); // 1 means bias, all others are unbiased52 nextInt.mockReturnValueOnce(mid);53 // Act54 const arb = new IntegerArbitrary(min, max);55 const out = arb.generate(mrng, biasFactor);56 // Assert57 expect(out.value).toBe(mid);58 expect(nextInt).toHaveBeenCalledTimes(2);59 expect(nextInt).toHaveBeenCalledWith(1, biasFactor);60 expect(nextInt).toHaveBeenCalledWith(min, max);61 }62 )63 ));64 it('should bias values (1 times over biasFreq) by using one of the ranges from biasNumericRange', () =>65 fc.assert(66 fc.property(67 fc.maxSafeInteger(),68 fc.maxSafeInteger(),69 fc.maxSafeInteger(),70 fc.maxSafeInteger(),71 fc.maxSafeInteger(),72 // Remark:73 // Following biasNumericRange is not fully identical to the onces that would be provided.74 // Range (in this stub) can be larger than the requested one. Not impacting from a unit-test point of view.75 fc.array(76 fc77 .tuple(fc.maxSafeInteger(), fc.maxSafeInteger())78 .map(([a, b]) => (a < b ? { min: a, max: b } : { min: b, max: a })),79 { minLength: 1 }80 ),81 (a, b, c, biasFactor, mod, ranges) => {82 // Arrange83 const [min, mid, max] = [a, b, c].sort((v1, v2) => v1 - v2);84 const { instance: mrng, nextInt } = fakeRandom();85 nextInt.mockReturnValueOnce(1); // 1 means bias86 if (ranges.length !== 1) {87 nextInt.mockImplementationOnce((min, max) => min + (mod % (max - min + 1)));88 }89 nextInt.mockReturnValueOnce(mid); // Remark: this value will most of the time be outside of requested range90 const biasNumericRange = jest.spyOn(91 BiasNumericRangeMock,92 'biasNumericRange'93 ) as unknown as jest.SpyInstance<{ min: number; max: number }[], [number, number, () => number]>;94 biasNumericRange.mockReturnValueOnce(ranges);95 // Act96 const arb = new IntegerArbitrary(min, max);97 const out = arb.generate(mrng, biasFactor);98 // Assert99 expect(out.value).toBe(mid);100 expect(biasNumericRange).toHaveBeenCalledTimes(1);101 expect(biasNumericRange).toHaveBeenCalledWith(min, max, expect.any(Function));102 if (ranges.length === 1) {103 expect(nextInt).toHaveBeenCalledTimes(2);104 expect(nextInt).toHaveBeenCalledWith(1, biasFactor);105 expect(nextInt).toHaveBeenCalledWith(ranges[0].min, ranges[0].max);106 } else {107 expect(nextInt).toHaveBeenCalledTimes(3);108 expect(nextInt).toHaveBeenCalledWith(1, biasFactor);109 const secondNextIntParams = nextInt.mock.calls[1];110 expect(secondNextIntParams[0]).toBeLessThan(0); // arbitrary is supposed to prefer the first entry111 expect(secondNextIntParams[1]).toBe(ranges.length - 2); // other entries do not have any special treatments112 // negative values for [0], positive value n means ranges[n+1]113 const secondNextIntResult = nextInt.mock.results[1].value;114 const selectedRange = secondNextIntResult < 0 ? 0 : secondNextIntResult + 1;115 expect(nextInt).toHaveBeenCalledWith(ranges[selectedRange].min, ranges[selectedRange].max);116 }117 }118 )119 ));120 });121 describe('canShrinkWithoutContext', () => {122 it('should always tells it can generate values included in the requested range', () =>123 fc.assert(124 fc.property(fc.maxSafeInteger(), fc.maxSafeInteger(), fc.maxSafeInteger(), (a, b, c) => {125 // Arrange126 const [min, mid, max] = [a, b, c].sort((v1, v2) => v1 - v2);127 // Act128 const arb = new IntegerArbitrary(min, max);129 const out = arb.canShrinkWithoutContext(mid);130 // Assert131 expect(out).toBe(true);132 })133 ));134 it('should always reject values outside of the requested range', () =>135 fc.assert(136 fc.property(137 fc.maxSafeInteger(),138 fc.maxSafeInteger(),139 fc.maxSafeInteger(),140 fc.constantFrom(...(['lower', 'higher'] as const)),141 (a, b, c, position) => {142 // Arrange143 const s = [a, b, c].sort((v1, v2) => v1 - v2);144 const [min, max, requested] = position === 'lower' ? [s[1], s[2], s[0]] : [s[0], s[1], s[2]];145 fc.pre(requested !== min && requested !== max);146 // Act147 const arb = new IntegerArbitrary(min, max);148 const out = arb.canShrinkWithoutContext(requested);149 // Assert150 expect(out).toBe(false);151 }152 )153 ));154 it.each`155 requested156 ${'1'}157 ${1.5}158 ${-0}159 ${Number.NaN}160 ${''}161 ${{}}162 `('should always reject non integral values like $requested', ({ requested }) => {163 // Arrange164 const min = 0;165 const max = 100;166 // Act167 const arb = new IntegerArbitrary(min, max);168 const out = arb.canShrinkWithoutContext(requested);169 // Assert170 expect(out).toBe(false);171 });172 });173 describe('shrink', () => {174 it('should always call shrink helper when no context provided', () =>175 fc.assert(176 fc.property(fc.maxSafeNat(), fc.maxSafeNat(), fc.maxSafeNat(), (a, b, c) => {177 // Arrange178 const [min, mid, max] = [a, b, c].sort((v1, v2) => v1 - v2);179 const expectedShrinks = Stream.nil<Value<number>>();180 const shrinkInteger = jest.spyOn(ShrinkIntegerMock, 'shrinkInteger');181 shrinkInteger.mockReturnValueOnce(expectedShrinks);182 // Act183 const arb = new IntegerArbitrary(min, max);184 const shrinks = arb.shrink(mid, undefined);185 // Assert186 expect(shrinks).toBe(expectedShrinks);187 expect(shrinkInteger).toHaveBeenCalledTimes(1);188 expect(shrinkInteger).toHaveBeenCalledWith(mid, expect.any(Number), true);189 })190 ));191 });192});193describe('IntegerArbitrary (integration)', () => {194 type Extra = { min: number; max: number };195 const extraParameters: fc.Arbitrary<Extra> = fc196 .tuple(fc.maxSafeInteger(), fc.maxSafeInteger())197 .map(([a, b]) => (a < b ? { min: a, max: b } : { min: b, max: a }));198 const isCorrect = (value: number, extra: Extra) =>199 typeof value === 'number' &&200 Number.isInteger(value) &&201 !Object.is(value, -0) &&202 extra.min <= value &&203 value <= extra.max;204 const isStrictlySmaller = (v1: number, v2: number) => Math.abs(v1) < Math.abs(v2);205 const integerBuilder = (extra: Extra) => new IntegerArbitrary(extra.min, extra.max);206 it('should produce the same values given the same seed', () => {207 assertProduceSameValueGivenSameSeed(integerBuilder, { extraParameters });208 });209 it('should only produce correct values', () => {210 assertProduceCorrectValues(integerBuilder, isCorrect, { extraParameters });211 });212 it('should produce values seen as shrinkable without any context', () => {213 assertProduceValuesShrinkableWithoutContext(integerBuilder, { extraParameters });214 });215 it('should be able to shrink to the same values without initial context', () => {216 assertShrinkProducesSameValueWithoutInitialContext(integerBuilder, { extraParameters });217 });218 it('should shrink towards strictly smaller values', () => {219 assertShrinkProducesStrictlySmallerValue(integerBuilder, isStrictlySmaller, { extraParameters });220 });221 describe('shrink', () => {222 it('should build a mirrored version of the shrinking tree if we negate all the values', () =>223 fc.assert(224 fc.property(225 fc.maxSafeInteger(),226 fc.integer({ min: 0, max: 20 }), // larger trees might be too wide227 fc.integer({ min: 0, max: 20 }),228 (start, o1, o2) => {229 // Arrange230 fc.pre(start + o1 <= Number.MAX_SAFE_INTEGER);231 fc.pre(start + o2 <= Number.MAX_SAFE_INTEGER);232 const min = start;233 const [mid, max] = o1 < o2 ? [min + o1, min + o2] : [min + o2, min + o1];234 const arb = new IntegerArbitrary(min, max);235 const arbNegate = new IntegerArbitrary(max !== 0 ? -max : 0, min !== 0 ? -min : min); // !==0 to avoid -0236 // Act237 const source = new Value(mid, undefined);238 const sourceNegate = new Value(mid !== 0 ? -mid : 0, undefined); // !==0 to avoid -0239 const tree = buildShrinkTree(arb, source);240 const treeNegate = buildShrinkTree(arbNegate, sourceNegate);241 const flat: number[] = [];242 const flatNegate: number[] = [];243 walkTree(tree, (v) => flat.push(v));244 walkTree(treeNegate, (v) => flatNegate.push(v !== 0 ? -v : 0));245 // Assert246 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);247 expect(arbNegate.canShrinkWithoutContext(sourceNegate.value)).toBe(true);248 expect(flatNegate).toEqual(flat);249 }250 )251 ));252 it('should build an offset version of the shrinking tree if we offset all the values (keep every value >=0)', () =>253 fc.assert(254 fc.property(255 fc.integer({ min: 0, max: Number.MAX_SAFE_INTEGER }),256 fc.integer({ min: 0, max: 20 }), // larger trees might be too wide257 fc.integer({ min: 0, max: 20 }),258 fc.integer({ min: 0, max: Number.MAX_SAFE_INTEGER }),259 (start, o1, o2, offset) => {260 // Arrange261 fc.pre(start + o1 + offset <= Number.MAX_SAFE_INTEGER);262 fc.pre(start + o2 + offset <= Number.MAX_SAFE_INTEGER);263 const min = start;264 const [mid, max] = o1 < o2 ? [min + o1, min + o2] : [min + o2, min + o1];265 const arb = new IntegerArbitrary(min, max);266 const arbOffset = new IntegerArbitrary(min + offset, max + offset);267 // Act268 const source = new Value(mid, undefined);269 const sourceOffset = new Value(mid + offset, undefined);270 const tree = buildShrinkTree(arb, source);271 const treeOffset = buildShrinkTree(arbOffset, sourceOffset);272 const flat: number[] = [];273 const flatOffset: number[] = [];274 walkTree(tree, (v) => flat.push(v));275 walkTree(treeOffset, (v) => flatOffset.push(v - offset));276 // Assert277 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);278 expect(arbOffset.canShrinkWithoutContext(sourceOffset.value)).toBe(true);279 expect(flatOffset).toEqual(flat);280 }281 )282 ));283 it('should shrink strictly positive value for positive range including zero', () => {284 // Arrange285 const arb = new IntegerArbitrary(0, 10);286 const source = new Value(8, undefined);287 // Act288 const tree = buildShrinkTree(arb, source);289 const renderedTree = renderTree(tree).join('\n');290 // Assert291 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);292 // When there is no more option, the shrinker retry one time with the value293 // current-1 to check if something that changed outside (another value not itself)294 // may have changed the situation.295 expect(renderedTree).toMatchInlineSnapshot(`296 "8297 â> 0298 â> 4299 | â> 2300 | | â> 1301 | | â> 0302 | â> 3303 | â> 2304 | â> 0305 | â> 1306 | â> 0307 â> 6308 | â> 5309 | â> 4310 | â> 0311 | â> 2312 | | â> 1313 | | â> 0314 | â> 3315 | â> 2316 | â> 0317 | â> 1318 | â> 0319 â> 7320 â> 6321 â> 0322 â> 3323 | â> 2324 | â> 1325 | â> 0326 â> 5327 â> 4328 â> 3329 â> 0330 â> 2331 â> 1332 â> 0"333 `);334 // Remarks:335 // * When we shrink 5 in path 8 > 6 > 5336 // we already now that 4 passed so we now that the smallest failing case337 // to look for is >= 5338 // * Same thing when we shrink 6 in path 8 > 6339 // * When we shrink 7 in path 8 > 7340 // we already now that 6 passed so we now that the smallest failing case341 // to look for is >= 7342 });343 it('should shrink strictly positive value for range not including zero', () => {344 // Arrange345 const arb = new IntegerArbitrary(10, 20);346 const source = new Value(18, undefined);347 // Act348 const tree = buildShrinkTree(arb, source);349 const renderedTree = renderTree(tree).join('\n');350 // Assert351 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);352 // As the range [10, 20] and the value 18353 // are just offset by +10 compared to the first case,354 // the rendered tree will be offset by 10 too355 expect(renderedTree).toMatchInlineSnapshot(`356 "18357 â> 10358 â> 14359 | â> 12360 | | â> 11361 | | â> 10362 | â> 13363 | â> 12364 | â> 10365 | â> 11366 | â> 10367 â> 16368 | â> 15369 | â> 14370 | â> 10371 | â> 12372 | | â> 11373 | | â> 10374 | â> 13375 | â> 12376 | â> 10377 | â> 11378 | â> 10379 â> 17380 â> 16381 â> 10382 â> 13383 | â> 12384 | â> 11385 | â> 10386 â> 15387 â> 14388 â> 13389 â> 10390 â> 12391 â> 11392 â> 10"393 `);394 });395 it('should shrink strictly negative value for negative range including zero', () => {396 // Arrange397 const arb = new IntegerArbitrary(-10, 0);398 const source = new Value(-8, undefined);399 // Act400 const tree = buildShrinkTree(arb, source);401 const renderedTree = renderTree(tree).join('\n');402 // Assert403 expect(arb.canShrinkWithoutContext(source.value)).toBe(true);404 // As the range [-10, 0] and the value -8405 // are the opposite of first case, the rendered tree will be the same except406 // it contains opposite values407 expect(renderedTree).toMatchInlineSnapshot(`408 "-8409 â> 0410 â> -4411 | â> -2412 | | â> -1413 | | â> 0414 | â> -3415 | â> -2416 | â> 0417 | â> -1418 | â> 0419 â> -6420 | â> -5421 | â> -4422 | â> 0423 | â> -2424 | | â> -1425 | | â> 0426 | â> -3427 | â> -2428 | â> 0429 | â> -1430 | â> 0431 â> -7432 â> -6433 â> 0434 â> -3435 | â> -2436 | â> -1437 | â> 0438 â> -5439 â> -4440 â> -3441 â> 0442 â> -2443 â> -1444 â> 0"445 `);446 });447 });...
Using AI Code Generation
1const fc = require("fast-check");2const { sourceNegate } = require("fast-check-monorepo");3const isEven = (n) => n % 2 === 0;4const isOdd = sourceNegate(isEven);5fc.assert(6 fc.property(fc.integer(), (n) => {7 return isOdd(n) === !isEven(n);8 })9);10const fc = require("fast-check");11const { sourceNegate } = require("fast-check-monorepo");12const isEven = (n) => n % 2 === 0;13const isOdd = sourceNegate(isEven);14fc.assert(15 fc.property(fc.integer(), (n) => {16 return isOdd(n) === !isEven(n);17 })18);
Using AI Code Generation
1const { sourceNegate } = require('fast-check-monorepo');2const fc = require('fast-check');3const isEven = (n) => n % 2 === 0;4const isOdd = sourceNegate(isEven);5fc.assert(6 fc.property(fc.integer(), (n) => isOdd(n) === !isEven(n))7);
Using AI Code Generation
1const fc = require('fast-check');2const { sourceNegate } = require('fast-check-monorepo');3const isEven = (n) => n % 2 === 0;4fc.assert(5 fc.property(6 fc.integer(),7 sourceNegate(isEven),8 (n, isOdd) => isOdd(n) === !isEven(n)9);10const fc = require('fast-check');11const { sourceNegate } = require('fast-check-monorepo');12const isEven = (n) => n % 2 === 0;13fc.assert(14 fc.property(15 fc.integer(),16 sourceNegate(isEven),17 (n, isOdd) => isOdd(n) === !isEven(n)18);19const fc = require('fast-check');20const { sourceNegate } = require('fast-check-monorepo');21const isEven = (n) => n % 2 === 0;22fc.assert(23 fc.property(24 fc.integer(),25 sourceNegate(isEven),26 (n, isOdd) => isOdd(n) === !isEven(n)27);28const fc = require('fast-check');29const { sourceNegate } = require('fast-check-monorepo');30const isEven = (n) => n % 2 === 0;31fc.assert(32 fc.property(33 fc.integer(),34 sourceNegate(isEven),35 (n, isOdd) => isOdd(n) === !isEven(n)36);37const fc = require('fast-check');38const { sourceNegate } = require('fast-check-monorepo');39const isEven = (n) => n % 2 === 0;40fc.assert(41 fc.property(42 fc.integer(),43 sourceNegate(isEven),44 (n, isOdd) => isOdd(n) === !isEven(n)45);
Using AI Code Generation
1const fc = require('fast-check')2const { sourceNegate } = require('fast-check-monorepo')3const { sourceMap } = require('fast-check-monorepo')4const { sourceFilter } = require('fast-check-monorepo')5const { sourceFlatMap } = require('fast-check-monorepo')6const { sourceShrinkableFor } = require('fast-check-monorepo')7const { sourceShrinkableNoop } = require('fast-check-monorepo')8const { sourceShrinkableArray } = require('fast-check-monorepo')9const { sourceShrinkableMap } = require('fast-check-monorepo')10const { sourceShrinkableObject } = require('fast-check-monorepo')11const { sourceShrinkableValue } = require('fast-check-monorepo')12const { sourceShrinkable } = require('fast-check-monorepo')13const { sourceShrinkableFrom } = require('fast-check-monorepo')14const { sourceShrinkableSequence } = require('fast-check-monorepo')15const { sourceShrinkableTree } = require('fast-check-monorepo')16const { sourceShrinkableValueOrTree } = require('fast-check-monorepo')17const { sourceShrinkableValueOrSequence } = require('fast-check-monorepo')18const { sourceShrinkableValueOrMap } = require('fast-check-monorepo')19const { sourceShrinkableValueOrObject } = require('fast-check-monorepo')20const { sourceShrinkableValueOrArray } = require('fast-check-monorepo')21const { sourceShrinkableValueOrValue } = require('fast-check-monorepo')22const { sourceShrinkableValueOrNoop } = require('fast-check-monorepo')23const { sourceShrinkableValueOrFrom } = require('fast-check-monorepo')24const { sourceShrinkableNoopOrValue } = require('fast-check-monorepo')25const { sourceShrinkableNoopOrFrom } = require('fast-check-monorepo')26const { sourceShrinkableNoopOrNoop } = require('fast-check-monorepo')27const { sourceShrinkableArrayOrValue } = require('fast-check-monorepo')28const { sourceShrinkableArrayOrFrom } = require('fast-check-monorepo')29const { sourceShrinkableArrayOrNoop
Using AI Code Generation
1const fc = require('fast-check');2const { sourceNegate } = require('fast-check-monorepo');3const isOdd = (n) => n % 2 === 1;4const isEven = sourceNegate(isOdd);5fc.assert(6 fc.property(fc.integer(), (n) => {7 return isEven(n) === !isOdd(n);8 })9);10const fc = require('fast-check');11const { sourceNegate } = require('fast-check-monorepo');12const isOdd = (n) => n % 2 === 1;13const isEven = sourceNegate(isOdd);14fc.assert(15 fc.property(fc.integer(), (n) => {16 return isEven(n) === !isOdd(n);17 }),18 { verbose: true }19);
Using AI Code Generation
1const fc = require('fast-check');2const arb = fc.integer(0, 1000);3const arb2 = arb.sourceNegate(x => x % 2 === 0);4fc.assert(fc.property(arb2, x => x % 2 !== 0));5const fc = require('fast-check');6const arb = fc.integer(0, 1000);7const arb2 = arb.sourceMap(x => x * 2);8fc.assert(fc.property(arb2, x => x % 2 === 0));9const fc = require('fast-check');10const arb = fc.integer(0, 1000);11const arb2 = arb.sourceFilter(x => x % 2 === 0);12fc.assert(fc.property(arb2, x => x % 2 === 0));13const fc = require('fast-check');14const arb = fc.integer(0, 1000);15const arb2 = arb.sourceShrink(x => [x - 1]);16fc.assert(fc.property(arb2, x => x >= 0));17const fc = require('fast-check');18const arb = fc.integer(0, 1000);19const arb2 = arb.sourceShrink(x => [x - 1]);20fc.assert(fc.property(arb2, x => x >= 0));21const fc = require('fast-check');22const arb = fc.integer(0, 1000);23const arb2 = arb.sourceShrink(x => [x - 1]);24fc.assert(fc.property(arb2, x => x >= 0));25const fc = require('fast-check');26const arb = fc.integer(0, 1000);27const arb2 = arb.sourceShrink(x => [x - 1]);28fc.assert(fc.property(arb2, x => x >= 0));
Using AI Code Generation
1const fc = require('fast-check');2const { sourceNegate } = require('fast-check-monorepo');3const { sourceNegate } = require('fast-check-monorepo');4const { sourceNegate } = require('fast-check-monorepo');5const fc = require('fast-check');6const { sourceNegate } = require('fast-check-monorepo');7const { sourceNegate } = require('fast-check-monorepo');8const { sourceNegate } = require('fast-check-monorepo');9const fc = require('fast-check');10const { sourceNegate } = require('fast-check-monorepo');11const { sourceNegate } = require('fast-check-monorepo');12const { sourceNegate } = require('fast-check-monorepo');13const fc = require('fast-check');14const { sourceNegate } = require('fast-check-monorepo');15const { sourceNegate } = require('fast-check-monorepo');16const { sourceNegate } = require('fast-check-monorepo');17const fc = require('fast-check');18const { sourceNegate } = require('fast-check-monorepo');19const { sourceNegate } = require('fast-check-monorepo');20const { sourceNegate } = require('fast-check-monorepo');21const fc = require('fast-check');22const { sourceNegate } = require('fast-check-monorepo');23const { sourceNegate } = require('fast-check-monorepo');24const { sourceNegate } = require('fast-check-monorepo');25const fc = require('fast-check');26const { sourceNegate } = require('fast-check-monorepo');27const { sourceNegate } = require('fast-check-monorepo');28const { sourceNegate } = require('fast-check-monorepo');29const fc = require('fast-check');30const { sourceNegate } = require('fast-check-monorepo');31const { sourceNegate } = require('fast-check-monorepo');32const { sourceNegate } = require('fast-check-monorepo');33const fc = require('fast-check');34const { sourceNegate } = require('fast-check-monorepo');35const { sourceNegate }
Using AI Code Generation
1const fc = require('fast-check');2const {sourceNegate} = require('./sourceNegate.js');3const arbitrary = fc.integer(0, 100);4const isEven = (x) => x % 2 === 0;5const isOdd = sourceNegate(isEven);6fc.assert(7 fc.property(arbitrary, (x) => {8 return isOdd(x) === !isEven(x);9 }),10);11console.log('All tests passed!');
Using AI Code Generation
1const fc = require('fast-check');2const {3} = require('fast-check/lib/types/arbitrary/definition/SourceArbitrary');4const { integer } = require('fast-check/lib/types/arbitrary/IntegerArbitrary');5const { array } = require('fast-check/lib/types/arbitrary/ArrayArbitrary');6const negate = (arbitrary) => sourceNegate(arbitrary, (v) => -v);7const arb = array(integer(), 1, 10).map((arr) => {8 return arr.reduce((a, b) => a + b, 0);9});10const arb2 = negate(arb);11fc.assert(12 fc.property(arb2, (v) => {13 return v < 0;14 })15);16console.log('done');17In the meantime, could you tell me which version of fast-check you are using? (I saw you are using fast-check-monorepo but I would like to know the version of fast-check you are using)18{ "name" : "test" , "version" : "1.0.0" , "description" : "" , "main" : "index.js" , "scripts" : { "test" : "node test.js" }, "author" : "" , "license" : "ISC" , "dependencies" : { "fast-check" : "^2.16.0" } }
Using AI Code Generation
1const fc = require('fast-check');2const { sourceNegate } = require('fast-check-monorepo/packages/arbitrary/integer');3const negativeNumbers = sourceNegate(fc.integer());4fc.assert(5 fc.property(negativeNumbers, (x) => {6 return x < 0;7 })8);9const fc = require('fast-check');10const { sourceNegate } = require('fast-check-monorepo/packages/arbitrary/integer');11const negativeNumbers = sourceNegate(fc.integer());12fc.assert(13 fc.property(negativeNumbers, (x) => {14 return x < 0;15 })16);17const fc = require('fast-check');18const { sourceNegate } = require('fast-check-monorepo/packages/arbitrary/integer');19const negativeNumbers = sourceNegate(fc.integer());20fc.assert(21 fc.property(negativeNumbers, (x) => {22 return x < 0;23 })24);25const fc = require('fast-check');26const { sourceNegate } = require('fast-check-monorepo/packages/arbitrary/integer');27const negativeNumbers = sourceNegate(fc.integer());28fc.assert(29 fc.property(negativeNumbers, (x) => {30 return x < 0;31 })32);33const fc = require('fast-check');34const { sourceNegate } = require('fast-check-monorepo/packages/arbitrary/integer');35const negativeNumbers = sourceNegate(fc.integer());36fc.assert(37 fc.property(negativeNumbers, (x) => {38 return x < 0;39 })40);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!