All files / json-crdt/__tests__/fuzzer JsonCrdtFuzzer.ts

92.3% Statements 24/26
83.33% Branches 5/6
100% Functions 3/3
100% Lines 24/24

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 586x 6x 6x   6x 6x 6x     6x                             6x       90x     90x 90x 90x         90x     90x 90x 90x 90x 90x       1000x 1000x 1000x 1000x 1000x 1000x      
import {Model} from '../../model/Model';
import {SessionLogical} from './SessionLogical';
import {Picker} from './Picker';
import type {FuzzerOptions} from './types';
import {RandomJson} from '@jsonjoy.com/util/lib/json-random/RandomJson';
import {generateInteger} from './util';
import {PatchBuilder} from '../../../json-crdt-patch/PatchBuilder';
import type {Patch} from '../../../json-crdt-patch';
 
export const defaultFuzzerOptions: FuzzerOptions = {
  startingValue: undefined,
  stringDeleteProbability: 0.2,
  binaryDeleteProbability: 0.2,
  maxStringDeleteLength: 64,
  maxSubstringLength: 16,
  maxBinaryChunkLength: 33,
  maxStringLength: 512,
  maxBinaryLength: 4049,
  concurrentPeers: [1, 6],
  patchesPerPeer: [0, 12],
  testCodecs: true,
  collectPatches: false,
};
 
export class JsonCrdtFuzzer {
  public opts: FuzzerOptions;
  public model: Model;
  public picker: Picker;
  public patches: Patch[] = [];
 
  constructor(opts: Partial<FuzzerOptions> = {}) {
    this.opts = {...defaultFuzzerOptions, ...opts};
    this.model = Model.withLogicalClock();
    this.picker = new Picker(this.opts);
  }
 
  public setupModel() {
    const json =
      this.opts.startingValue === undefined
        ? RandomJson.generate({nodeCount: 8, rootNode: Math.random() > 0.5 ? 'object' : 'array'})
        : this.opts.startingValue;
    const builder = new PatchBuilder(this.model.clock);
    builder.root(builder.json(json));
    const patch = builder.flush();
    this.patches.push(patch);
    this.model.applyPatch(patch);
  }
 
  public executeConcurrentSession(): SessionLogical {
    const concurrency = generateInteger(...this.opts.concurrentPeers);
    const session = new SessionLogical(this, concurrency);
    session.generateEdits();
    session.synchronize();
    Iif (this.opts.collectPatches) for (const patches of session.patches) this.patches.push(...patches);
    return session;
  }
}