Skip to content

Commit

Permalink
fix: ajusta lib
Browse files Browse the repository at this point in the history
  • Loading branch information
drusco committed Aug 27, 2023
1 parent db844d6 commit 8696da1
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 52 deletions.
8 changes: 6 additions & 2 deletions src/Emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ export default class Emulator extends EventEmitter implements Exotic.Emulator {
return lib.methods.revokeAll(this);
}

include(origin: Exotic.proxy.origin, target?: any): any {
return lib.methods.include(this, origin, target);
include(
encodedProxy: string,
origin: Exotic.proxy.origin,
target?: any,
): any {
return lib.methods.include(this, encodedProxy, origin, target);
}

getId(value: any): number {
Expand Down
11 changes: 7 additions & 4 deletions src/lib/constructor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import { map } from "../utils";

describe("(constructor)", () => {
it("Creates a new emulator", () => {
const config: Exotic.emulator.options = { traceErrors: false };
const config: Exotic.emulator.options = {
traceErrors: false,
};
const emulator = new Emulator(config);
const data: Record<string, any> = map.emulators.get(emulator) || {};
const dataProps = ["options", "refs", "counter", "proxySet"];
const { options, refs, counter } = data;
const dataProps = ["options", "refs", "links", "counter", "proxySet"];
const { options, refs, links, counter } = data;

expect(map.emulators.has(emulator)).toBe(true);
expect(Object.keys(data)).toEqual(dataProps);
expect(options).toEqual(config);
expect(Reflect.ownKeys(refs).length).toBe(0);
expect(Object.keys(refs).length).toBe(0);
expect(Object.keys(links).length).toBe(0);
expect(counter).toBe(0);
});
});
5 changes: 4 additions & 1 deletion src/lib/constructor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ export default function constructor(
options?: Exotic.emulator.options,
): void {
// set config defaults
const config = { traceErrors: false };
const config: Exotic.emulator.options = {
traceErrors: false,
};
if (options) {
Object.assign(config, options);
}
const data: Exotic.emulator.data = {
options: config,
refs: Object.create(null),
links: Object.create(null),
counter: 0,
proxySet: new Set(),
};
Expand Down
27 changes: 20 additions & 7 deletions src/lib/methods/include.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe("(method) include", () => {
it("Creates a proxy from an origin without action", () => {
const target = 360;
const origin: Exotic.proxy.origin = {};
const proxy = $.include(origin, target);
const proxy = $.include("", origin, target);
expect($.target(proxy)).toBe(target);
});

Expand All @@ -16,7 +16,7 @@ describe("(method) include", () => {
const target = ["example"];
const origin: Exotic.proxy.origin = { ref: reference };

await $.include(origin, target);
await $.include("", origin, target);

expect($.refs.includes(reference)).toBe(true);
expect($.useRef(reference)).toBe($.use(target));
Expand All @@ -34,7 +34,7 @@ describe("(method) include", () => {
use();
});

await $.include(origin, target);
await $.include("", origin, target);

expect($.refs.includes(reference)).toBe(true);
expect($.useRef(reference)).toBe($.use(target));
Expand All @@ -49,7 +49,7 @@ describe("(method) include", () => {
value,
proxy,
};
$.include(origin);
$.include("", origin);
expect($.target(proxy.test)).toBe(value);
});

Expand All @@ -61,7 +61,7 @@ describe("(method) include", () => {
that: proxy,
args: [10],
};
const newProxy = $.include(origin);
const newProxy = $.include("", origin);
expect($.target(newProxy)).toBe("test10");
});

Expand All @@ -73,7 +73,7 @@ describe("(method) include", () => {
proxy,
args: [10],
};
const instance = $.include(origin);
const instance = $.include("", origin);
expect($.target(instance) instanceof MyClass).toBe(true);
});

Expand All @@ -85,7 +85,20 @@ describe("(method) include", () => {
proxy,
key: "test",
};
const proxyFromGet = $.include(origin);
const proxyFromGet = $.include("", origin);
expect($.target(proxyFromGet)).toBe(array);
});

it("Creates a link between an existing proxy and a new proxy", () => {
const proxy = $.use();
const origin: Exotic.proxy.origin = {
action: "get",
proxy,
key: "test",
};
const proxyLink = $.encode(proxy);
const newProxy = $.include(proxyLink, origin);
expect($.decode(proxyLink)).toBe(newProxy);
expect(proxy).not.toBe(newProxy);
});
});
31 changes: 23 additions & 8 deletions src/lib/methods/include.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ import {
traps,
createProxy,
decode,
encode,
findProxy,
} from "../../utils/index.js";

export default function include(
scope: Exotic.Emulator,
encodedProxy: string,
origin: Exotic.proxy.origin,
target?: any,
): any {
const decodedOrigin = decode(scope, origin);
const decodedTarget = decode(scope, target);
const targetProxy = findProxy(decodedTarget);
const newTarget = targetProxy ? targetProxy : target;
const proxyAsTarget = findProxy(decodedTarget);
const newTarget = proxyAsTarget ? proxyAsTarget : target;
const { action, proxy, key, value, that, args, ref } = decodedOrigin;

if (ref) {
Expand All @@ -39,24 +41,37 @@ export default function include(
}

const originData = map.proxies.get(proxy);
const { links } = map.emulators.get(scope);

if (!originData) {
return;
}

const { mock, sandbox } = originData;
let proxyFromTrap: Exotic.Proxy | undefined;

switch (action) {
case "get":
if (!key) return;
return traps.get(mock, key);
proxyFromTrap = traps.get(mock, key);
break;
case "set":
if (!key) return;
traps.set(mock, key, value);
return sandbox[key];
proxyFromTrap = sandbox[key];
break;
case "apply":
return traps.apply(mock, that, args);
proxyFromTrap = traps.apply(mock, that, args);
break;
case "construct":
return traps.construct(mock, args);
proxyFromTrap = traps.construct(mock, args);
break;
}

if (proxyFromTrap) {
const localEncodedProxy = encode(proxyFromTrap);
if (localEncodedProxy !== encodedProxy) {
links[encodedProxy] = localEncodedProxy;
}
}

return proxyFromTrap;
}
5 changes: 3 additions & 2 deletions src/types/Exotic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ declare namespace Exotic {
interface Emulator extends EventEmitter {
use(value?: any): Proxy;
useRef(ref: key, value?: any): Proxy;
include(origin: proxy.origin, target?: any): any;
include(encodedProxy: string, origin: proxy.origin, target?: any): any;
target(value?: any): any;
parent(value?: traceable): undefined | Proxy;
values(value?: traceable): Proxy[];
Expand All @@ -27,12 +27,13 @@ declare namespace Exotic {

namespace emulator {
interface options {
traceErrors: boolean;
traceErrors?: boolean;
}

interface data {
options: options;
refs: Record<key, Proxy>;
links: Record<key, key>;
counter: number;
proxySet: Set<Proxy>;
}
Expand Down
31 changes: 19 additions & 12 deletions src/utils/createProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import isTraceable from "./isTraceable.js";
import mockPrototype from "./mockPrototype.js";
import traps from "./traps/index.js";
import encode from "./encode.js";
//import decode from "./decode.js";

const createProxy = (
scope: Exotic.Emulator,
Expand All @@ -14,24 +13,24 @@ const createProxy = (
): Exotic.Proxy => {
const data: Exotic.emulator.data = map.emulators.get(scope);
const { refs, options, proxySet } = data;
//const decodedTarget = decode(scope, target);
const usableProxy = findProxy(target);
const error = options.traceErrors ? new Error() : undefined;

// console.log("[createProxy]", data.counter + 1);

scope.emit("proxy", encode(origin), encode(target), error);
const usableProxy = findProxy(target);
const encodedOrigin = encode(origin);
const encodedTarget = encode(target);

if (usableProxy) {
// proxy already exists
if (
origin.action === "apply" ||
origin.action === "construct" ||
origin.action === "get" ||
origin.action === "set"
) {
if (origin.action) {
data.counter++;
}
scope.emit(
"proxy",
encode(usableProxy),
encodedOrigin,
encodedTarget,
error,
);
return usableProxy;
}

Expand All @@ -43,6 +42,13 @@ const createProxy = (
// proxy reference exists
const proxyRef = refs[reference];
if (proxyRef) {
scope.emit(
"proxy",
encode(proxyRef),
encodedOrigin,
encodedTarget,
error,
);
return proxyRef;
}
}
Expand Down Expand Up @@ -91,6 +97,7 @@ const createProxy = (
map.targets.set(target, proxy);
}

scope.emit("proxy", encode(proxy), encodedOrigin, encodedTarget, error);
return proxy;
};

Expand Down
5 changes: 4 additions & 1 deletion src/utils/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import findProxy from "./findProxy.js";
import findProxyById from "./findProxyById.js";
import isPayload from "./isPayload.js";
import isTraceable from "./isTraceable.js";
import map from "./map.js";

export default function decode(
scope: Exotic.Emulator,
Expand All @@ -12,13 +13,15 @@ export default function decode(
const traceable = isTraceable(value);
const proxy = findProxy(value);
const payload = isPayload(value);
const { links } = map.emulators.get(scope);

if (proxy) {
return proxy;
}

if (payload) {
return findProxyById(scope, parseInt(value.substring(1)));
const link = links[value] || value;
return findProxyById(scope, parseInt(link.substring(1)));
}

if (traceable) {
Expand Down
6 changes: 4 additions & 2 deletions src/utils/revokeProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ const revokeProxy = (value: Exotic.traceable): boolean => {
}

const proxyData = map.proxies.get(proxy);
const { mock, revoke, target, origin, revoked, key, scope } = proxyData;
const { id, mock, revoke, target, origin, revoked, key, scope } = proxyData;

if (revoked) {
return true;
}

const data = map.emulators.get(scope);
const { refs, proxySet } = data;
const { refs, proxySet, links } = data;
const validKey = key !== undefined;

if (validKey) {
Expand Down Expand Up @@ -48,6 +48,7 @@ const revokeProxy = (value: Exotic.traceable): boolean => {
map.mocks.delete(mock);
map.targets.delete(target);
proxySet.delete(proxy);
delete links[`⁠${id}`];

// keep in proxies map
// prevents proxy out of revoked proxy (throws)
Expand All @@ -69,6 +70,7 @@ const revokeProxy = (value: Exotic.traceable): boolean => {
// clean internal state
Object.assign(data, {
refs: Object.create(null),
links: Object.create(null),
counter: 0,
} as Exotic.emulator.data);
}
Expand Down
11 changes: 1 addition & 10 deletions src/utils/traps/apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import createProxy from "../createProxy.js";
import findProxy from "../findProxy.js";
import map from "../map.js";

const apply = (mock: Exotic.Mock, that?: any, args?: any[]): any => {
const apply = (mock: Exotic.Mock, that?: any, args?: any[]): Exotic.Proxy => {
const proxy = findProxy(mock);
const { scope, target } = map.proxies.get(proxy);

Expand All @@ -22,17 +22,8 @@ const apply = (mock: Exotic.Mock, that?: any, args?: any[]): any => {
scope.target(that),
origin.args.map((arg) => scope.target(arg)),
);
// console.log(
// scope.target(target),
// scope.target(that),
// args,
// origin.args,
// origin.args.map((arg) => scope.target(arg)),
// );
}

//console.log("[trap_apply]", args, scope.encode(origin), value);

return createProxy(scope, origin, value);
};

Expand Down
4 changes: 2 additions & 2 deletions src/utils/traps/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import createProxy from "../createProxy.js";
import findProxy from "../findProxy.js";
import map from "../map.js";

const construct = (mock: Exotic.Mock, args: any[]): object => {
const construct = (mock: Exotic.Mock, args: any[]): Exotic.Proxy => {
const proxy = findProxy(mock);
const { scope, target } = map.proxies.get(proxy);

Expand All @@ -18,7 +18,7 @@ const construct = (mock: Exotic.Mock, args: any[]): object => {
if (typeof target === "function") {
value = Reflect.construct(
scope.target(target),
args.map((arg) => scope.target(arg)),
origin.args.map((arg) => scope.target(arg)),
);
}

Expand Down
Loading

0 comments on commit 8696da1

Please sign in to comment.