Files
anthonyrawlins e89f2f4b7b Add comprehensive development roadmap via GitHub Issues
Created 10 detailed GitHub issues covering:
- Project activation and management UI (#1-2)
- Worker node coordination and visualization (#3-4)
- Automated GitHub repository scanning (#5)
- Intelligent model-to-issue matching (#6)
- Multi-model task execution system (#7)
- N8N workflow integration (#8)
- Hive-Bzzz P2P bridge (#9)
- Peer assistance protocol (#10)

Each issue includes detailed specifications, acceptance criteria,
technical implementation notes, and dependency mapping.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-12 19:41:01 +10:00

192 lines
5.5 KiB
JavaScript

import * as tinyspy from 'tinyspy';
const mocks = new Set();
function isMockFunction(fn) {
return typeof fn === "function" && "_isMockFunction" in fn && fn._isMockFunction;
}
function spyOn(obj, method, accessType) {
const dictionary = {
get: "getter",
set: "setter"
};
const objMethod = accessType ? { [dictionary[accessType]]: method } : method;
let state;
const descriptor = getDescriptor(obj, method);
const fn = descriptor && descriptor[accessType || "value"];
// inherit implementations if it was already mocked
if (isMockFunction(fn)) {
state = fn.mock._state();
}
try {
const stub = tinyspy.internalSpyOn(obj, objMethod);
const spy = enhanceSpy(stub);
if (state) {
spy.mock._state(state);
}
return spy;
} catch (error) {
if (error instanceof TypeError && Symbol.toStringTag && obj[Symbol.toStringTag] === "Module" && (error.message.includes("Cannot redefine property") || error.message.includes("Cannot replace module namespace") || error.message.includes("can't redefine non-configurable property"))) {
throw new TypeError(`Cannot spy on export "${String(objMethod)}". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/browser/#limitations`, { cause: error });
}
throw error;
}
}
let callOrder = 0;
function enhanceSpy(spy) {
const stub = spy;
let implementation;
let onceImplementations = [];
let implementationChangedTemporarily = false;
let instances = [];
let contexts = [];
let invocations = [];
const state = tinyspy.getInternalState(spy);
const mockContext = {
get calls() {
return state.calls;
},
get contexts() {
return contexts;
},
get instances() {
return instances;
},
get invocationCallOrder() {
return invocations;
},
get results() {
return state.results.map(([callType, value]) => {
const type = callType === "error" ? "throw" : "return";
return {
type,
value
};
});
},
get settledResults() {
return state.resolves.map(([callType, value]) => {
const type = callType === "error" ? "rejected" : "fulfilled";
return {
type,
value
};
});
},
get lastCall() {
return state.calls[state.calls.length - 1];
},
_state(state) {
if (state) {
implementation = state.implementation;
onceImplementations = state.onceImplementations;
implementationChangedTemporarily = state.implementationChangedTemporarily;
}
return {
implementation,
onceImplementations,
implementationChangedTemporarily
};
}
};
function mockCall(...args) {
instances.push(this);
contexts.push(this);
invocations.push(++callOrder);
const impl = implementationChangedTemporarily ? implementation : onceImplementations.shift() || implementation || state.getOriginal() || (() => {});
return impl.apply(this, args);
}
let name = stub.name;
stub.getMockName = () => name || "vi.fn()";
stub.mockName = (n) => {
name = n;
return stub;
};
stub.mockClear = () => {
state.reset();
instances = [];
contexts = [];
invocations = [];
return stub;
};
stub.mockReset = () => {
stub.mockClear();
implementation = undefined;
onceImplementations = [];
return stub;
};
stub.mockRestore = () => {
stub.mockReset();
state.restore();
return stub;
};
if (Symbol.dispose) {
stub[Symbol.dispose] = () => stub.mockRestore();
}
stub.getMockImplementation = () => implementationChangedTemporarily ? implementation : onceImplementations.at(0) || implementation;
stub.mockImplementation = (fn) => {
implementation = fn;
state.willCall(mockCall);
return stub;
};
stub.mockImplementationOnce = (fn) => {
onceImplementations.push(fn);
return stub;
};
function withImplementation(fn, cb) {
const originalImplementation = implementation;
implementation = fn;
state.willCall(mockCall);
implementationChangedTemporarily = true;
const reset = () => {
implementation = originalImplementation;
implementationChangedTemporarily = false;
};
const result = cb();
if (typeof result === "object" && result && typeof result.then === "function") {
return result.then(() => {
reset();
return stub;
});
}
reset();
return stub;
}
stub.withImplementation = withImplementation;
stub.mockReturnThis = () => stub.mockImplementation(function() {
return this;
});
stub.mockReturnValue = (val) => stub.mockImplementation(() => val);
stub.mockReturnValueOnce = (val) => stub.mockImplementationOnce(() => val);
stub.mockResolvedValue = (val) => stub.mockImplementation(() => Promise.resolve(val));
stub.mockResolvedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.resolve(val));
stub.mockRejectedValue = (val) => stub.mockImplementation(() => Promise.reject(val));
stub.mockRejectedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.reject(val));
Object.defineProperty(stub, "mock", { get: () => mockContext });
state.willCall(mockCall);
mocks.add(stub);
return stub;
}
function fn(implementation) {
const enhancedSpy = enhanceSpy(tinyspy.internalSpyOn({ spy: implementation || function() {} }, "spy"));
if (implementation) {
enhancedSpy.mockImplementation(implementation);
}
return enhancedSpy;
}
function getDescriptor(obj, method) {
const objDescriptor = Object.getOwnPropertyDescriptor(obj, method);
if (objDescriptor) {
return objDescriptor;
}
let currentProto = Object.getPrototypeOf(obj);
while (currentProto !== null) {
const descriptor = Object.getOwnPropertyDescriptor(currentProto, method);
if (descriptor) {
return descriptor;
}
currentProto = Object.getPrototypeOf(currentProto);
}
}
export { fn, isMockFunction, mocks, spyOn };