Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 6x 6x 6x 6x 6x 90x 20271x 20271x 793714x 20271x 20271x 7039x 7039x 6933x 6933x 5538x 5402x 5402x 5319x 5319x 2784x 2530x 2369x 1049x 1049x 1049x 1049x 316x 273x 133x 65x 5644x 5644x 2867x 2867x 1483x 1483x 361x 361x 359x 1122x 1122x | import {DelOp, InsObjOp, InsStrOp, InsBinOp, InsArrOp, UpdArrOp} from '../../../json-crdt-patch/operations'; import {RandomJson} from '@jsonjoy.com/util/lib/json-random'; import type {JsonNode, ObjNode, ArrNode, BinNode, StrNode} from '../../nodes'; import type {Model} from '../../model/Model'; import {Fuzzer} from '@jsonjoy.com/util/lib/Fuzzer'; import type {FuzzerOptions} from './types'; type StringOp = typeof InsStrOp | typeof DelOp; type BinaryOp = typeof InsBinOp | typeof DelOp; type ArrayOp = typeof InsArrOp | typeof DelOp | typeof UpdArrOp; type ObjectOp = typeof InsObjOp | typeof DelOp; const commonKeys = ['a', 'op', 'test', 'name', '', '__proto__']; /** * This class picks random nodes from a model and picks a random * operation to apply to that node. */ export class Picker { constructor(public opts: FuzzerOptions) {} public pickNode(model: Model): JsonNode | null { const nodes: JsonNode[] = []; const index = model.index; // biome-ignore lint: index is not iterable index.forEach(({v: node}) => nodes.push(node)); Iif (!nodes.length) return null; return Fuzzer.pick(nodes); } public pickStringOperation(node: StrNode): StringOp { const length = node.length(); if (!length) return InsStrOp; Iif (length >= this.opts.maxStringLength) return DelOp; if (Math.random() < this.opts.stringDeleteProbability) return DelOp; return InsStrOp; } public pickBinaryOperation(node: BinNode): BinaryOp { const length = node.length(); if (!length) return InsBinOp; Iif (length >= this.opts.maxStringLength) return DelOp; if (Math.random() < this.opts.binaryDeleteProbability) return DelOp; return InsBinOp; } public pickObjectOperation(node: ObjNode): [key: string, opcode: ObjectOp] { if (!node.keys.size) return [this.generateObjectKey(), InsObjOp]; if (Math.random() > 0.45) return [this.generateObjectKey(), InsObjOp]; const keys = [...node.keys.keys()]; Iif (!keys.length) return [this.generateObjectKey(), InsObjOp]; const key = Fuzzer.pick(keys); return [key, DelOp]; } public pickArrayOperation(node: ArrNode): ArrayOp { if (!node.length()) return InsArrOp; if (Math.random() > 0.45) return InsArrOp; if (Math.random() > 0.45) return UpdArrOp; else return DelOp; } public generateSubstring(): string { const length = Math.floor(Math.random() * this.opts.maxSubstringLength) + 1; return RandomJson.genString(length); } public generateBinaryData(): Uint8Array { const length = Math.floor(Math.random() * this.opts.maxBinaryChunkLength) + 1; return RandomJson.genBinary(length); } public generateObjectKey(): string { const useCommonKey = Math.random() < 0.25; if (useCommonKey) { const str = Fuzzer.pick(commonKeys); if (this.opts.noProtoString && str === '__proto__') return this.generateObjectKey(); return str; } else { const length = Math.floor(Math.random() * 20) + 1; return RandomJson.genString(length); } } } |