vimonkey 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chaos/index.mjs +121 -0
- package/dist/fuzz/index.mjs +2 -0
- package/dist/index.mjs +37 -0
- package/dist/plugin.mjs +14 -0
- package/dist/test-fuzz-ZgFKEVq-.mjs +550 -0
- package/package.json +24 -9
- package/src/chaos/index.ts +0 -180
- package/src/env.ts +0 -63
- package/src/fuzz/context.ts +0 -59
- package/src/fuzz/gen.ts +0 -157
- package/src/fuzz/index.ts +0 -90
- package/src/fuzz/regression.ts +0 -115
- package/src/fuzz/shrink.ts +0 -115
- package/src/fuzz/test-fuzz.ts +0 -241
- package/src/index.ts +0 -37
- package/src/plugin.ts +0 -96
- package/src/random.ts +0 -181
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
//#region src/chaos/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Skip items with probability `rate`.
|
|
4
|
+
* Simulates message loss, queue overflow, network drops.
|
|
5
|
+
*/
|
|
6
|
+
async function* drop(source, rate, rng) {
|
|
7
|
+
for await (const item of source) if (!rng.bool(rate)) yield item;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Buffer up to `windowSize` items, shuffle, yield when buffer is full.
|
|
11
|
+
* Simulates out-of-order delivery, non-deterministic event ordering.
|
|
12
|
+
*/
|
|
13
|
+
async function* reorder(source, windowSize, rng) {
|
|
14
|
+
const buffer = [];
|
|
15
|
+
for await (const item of source) {
|
|
16
|
+
buffer.push(item);
|
|
17
|
+
if (buffer.length >= windowSize) {
|
|
18
|
+
const shuffled = rng.shuffle(buffer);
|
|
19
|
+
buffer.length = 0;
|
|
20
|
+
for (const e of shuffled) yield e;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (buffer.length > 0) {
|
|
24
|
+
const shuffled = rng.shuffle(buffer);
|
|
25
|
+
for (const e of shuffled) yield e;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* With probability `rate`, yield the item twice.
|
|
30
|
+
* Simulates duplicate delivery, at-least-once semantics.
|
|
31
|
+
*/
|
|
32
|
+
async function* duplicate(source, rate, rng) {
|
|
33
|
+
for await (const item of source) {
|
|
34
|
+
yield item;
|
|
35
|
+
if (rng.bool(rate)) yield item;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Collect `burstSize` items, then yield them all at once.
|
|
40
|
+
* Simulates bursty delivery, batched network packets.
|
|
41
|
+
*/
|
|
42
|
+
async function* burst(source, burstSize) {
|
|
43
|
+
const buffer = [];
|
|
44
|
+
for await (const item of source) {
|
|
45
|
+
buffer.push(item);
|
|
46
|
+
if (buffer.length >= burstSize) {
|
|
47
|
+
for (const e of buffer) yield e;
|
|
48
|
+
buffer.length = 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const e of buffer) yield e;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Skip the first `count` items.
|
|
55
|
+
* Simulates missed events during initialization, late subscriber.
|
|
56
|
+
*/
|
|
57
|
+
async function* initGap(source, count) {
|
|
58
|
+
let skipped = 0;
|
|
59
|
+
for await (const item of source) {
|
|
60
|
+
if (skipped < count) {
|
|
61
|
+
skipped++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
yield item;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Add a random delay before yielding each item.
|
|
69
|
+
* Simulates slow I/O, network latency, disk delays.
|
|
70
|
+
*/
|
|
71
|
+
async function* delay(source, minMs, maxMs, rng) {
|
|
72
|
+
for await (const item of source) {
|
|
73
|
+
const ms = rng.int(minMs, maxMs);
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
75
|
+
yield item;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Built-in transformer registry (works for any T) */
|
|
79
|
+
const BUILTIN_REGISTRY = {
|
|
80
|
+
drop: (s, p, rng) => drop(s, p.rate ?? .2, rng),
|
|
81
|
+
reorder: (s, p, rng) => reorder(s, p.windowSize ?? 5, rng),
|
|
82
|
+
duplicate: (s, p, rng) => duplicate(s, p.rate ?? .3, rng),
|
|
83
|
+
burst: (s, p) => burst(s, p.burstSize ?? 10),
|
|
84
|
+
initGap: (s, p) => initGap(s, p.count ?? 5),
|
|
85
|
+
delay: (s, p, rng) => delay(s, p.minMs ?? 1, p.maxMs ?? 5, rng)
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Compose multiple chaos transformer configs into a single async iterable pipeline.
|
|
89
|
+
*
|
|
90
|
+
* Uses built-in transformers by default. Pass a custom `registry` to add
|
|
91
|
+
* domain-specific transformers (e.g., FS-specific atomicSave, coalesce).
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* const chaotic = chaos(source, [
|
|
96
|
+
* { type: "drop", params: { rate: 0.2 } },
|
|
97
|
+
* { type: "reorder", params: { windowSize: 5 } },
|
|
98
|
+
* ], rng)
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @example Custom registry
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const chaotic = chaos(source, configs, rng, {
|
|
104
|
+
* ...builtinChaosRegistry,
|
|
105
|
+
* atomic_save: (s, p, rng) => atomicSave(s, p.rate, rng),
|
|
106
|
+
* })
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
function chaos(source, configs, rng, registry) {
|
|
110
|
+
const reg = registry ?? BUILTIN_REGISTRY;
|
|
111
|
+
let pipeline = source;
|
|
112
|
+
for (const config of configs) {
|
|
113
|
+
const factory = reg[config.type];
|
|
114
|
+
if (factory) pipeline = factory(pipeline, config.params, rng);
|
|
115
|
+
}
|
|
116
|
+
return pipeline;
|
|
117
|
+
}
|
|
118
|
+
/** Re-export the built-in registry for extension */
|
|
119
|
+
const builtinChaosRegistry = BUILTIN_REGISTRY;
|
|
120
|
+
//#endregion
|
|
121
|
+
export { builtinChaosRegistry, burst, chaos, delay, drop, duplicate, initGap, reorder };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { C as getFuzzContext, D as parseRepeats, E as deriveSeeds, O as parseSeed, S as fuzzContext, T as createSeededRandom, _ as shrinkSequence, a as beforeEach, b as createFuzzContext, c as it, d as deleteCase, f as getFuzzCasesDir, g as formatShrinkResult, h as saveCase, i as beforeAll, k as weightedPickFromTuples, l as test, m as loadCasesForTest, n as afterAll, o as describe, p as loadCases, r as afterEach, s as expect, t as FuzzError, u as clearCases, v as gen, w as isInFuzzContext, x as createReplayContext, y as take } from "../test-fuzz-ZgFKEVq-.mjs";
|
|
2
|
+
export { FuzzError, afterAll, afterEach, beforeAll, beforeEach, clearCases, createFuzzContext, createReplayContext, createSeededRandom, deleteCase, deriveSeeds, describe, expect, formatShrinkResult, fuzzContext, gen, getFuzzCasesDir, getFuzzContext, isInFuzzContext, it, loadCases, loadCasesForTest, parseRepeats, parseSeed, saveCase, shrinkSequence, take, test, weightedPickFromTuples };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { C as getFuzzContext, D as parseRepeats, E as deriveSeeds, O as parseSeed, S as fuzzContext, T as createSeededRandom, _ as shrinkSequence, a as beforeEach, b as createFuzzContext, c as it, d as deleteCase, f as getFuzzCasesDir, g as formatShrinkResult, h as saveCase, i as beforeAll, k as weightedPickFromTuples, l as test, m as loadCasesForTest, n as afterAll, o as describe, p as loadCases, r as afterEach, s as expect, t as FuzzError, u as clearCases, v as gen, w as isInFuzzContext, x as createReplayContext, y as take } from "./test-fuzz-ZgFKEVq-.mjs";
|
|
2
|
+
//#region src/env.ts
|
|
3
|
+
const VALID_VALUES = [
|
|
4
|
+
"fake",
|
|
5
|
+
"real:mem",
|
|
6
|
+
"real:disk"
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* Get the current TEST_SYS value
|
|
10
|
+
*
|
|
11
|
+
* @returns The test system type, defaults to 'fake'
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { getTestSys } from 'vimonkey'
|
|
16
|
+
*
|
|
17
|
+
* const sys = getTestSys()
|
|
18
|
+
* if (sys === 'fake') {
|
|
19
|
+
* // use mock
|
|
20
|
+
* } else if (sys === 'real:mem') {
|
|
21
|
+
* // use real with in-memory storage
|
|
22
|
+
* } else {
|
|
23
|
+
* // use real with disk storage
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function getTestSys() {
|
|
28
|
+
const value = process.env.TEST_SYS;
|
|
29
|
+
if (!value) return "fake";
|
|
30
|
+
if (!VALID_VALUES.includes(value)) {
|
|
31
|
+
console.warn(`Invalid TEST_SYS value: "${value}". Valid values: ${VALID_VALUES.join(", ")}. Defaulting to "fake".`);
|
|
32
|
+
return "fake";
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { FuzzError, afterAll, afterEach, beforeAll, beforeEach, clearCases, createFuzzContext, createReplayContext, createSeededRandom, deleteCase, deriveSeeds, describe, expect, formatShrinkResult, fuzzContext, gen, getFuzzCasesDir, getFuzzContext, getTestSys, isInFuzzContext, it, loadCases, loadCasesForTest, parseRepeats, parseSeed, saveCase, shrinkSequence, take, test, weightedPickFromTuples };
|
package/dist/plugin.mjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/plugin.ts
|
|
2
|
+
/**
|
|
3
|
+
* Creates the vimonkey plugin for Vitest
|
|
4
|
+
*/
|
|
5
|
+
function viMonkey(options = {}) {
|
|
6
|
+
const { fuzz = {}, ai = {}, doc = {} } = options;
|
|
7
|
+
return {
|
|
8
|
+
name: "vimonkey",
|
|
9
|
+
config() {},
|
|
10
|
+
configureServer(server) {}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { viMonkey as default, viMonkey };
|