This commit is contained in:
garronej
2021-07-03 02:39:39 +02:00
parent 84fc81f531
commit 5dd3103aba
3 changed files with 220 additions and 183 deletions
src

@ -8,9 +8,9 @@ import { deepAssign } from "../tools/deepAssign";
export type ExtendsKcContextBase< export type ExtendsKcContextBase<
KcContextExtended extends ({ pageId: string; } | undefined) KcContextExtended extends { pageId: string; }
> = > =
KcContextExtended extends undefined ? [KcContextExtended] extends [never] ?
KcContextBase : KcContextBase :
AndByDiscriminatingKey< AndByDiscriminatingKey<
"pageId", "pageId",
@ -18,7 +18,7 @@ export type ExtendsKcContextBase<
KcContextBase KcContextBase
>; >;
export function getKcContext<KcContextExtended extends ({ pageId: string; } | undefined) = undefined>( export function getKcContext<KcContextExtended extends { pageId: string; } = never>(
params?: { params?: {
mockPageId?: ExtendsKcContextBase<KcContextExtended>["pageId"]; mockPageId?: ExtendsKcContextBase<KcContextExtended>["pageId"];
mockData?: readonly DeepPartial<ExtendsKcContextBase<KcContextExtended>>[]; mockData?: readonly DeepPartial<ExtendsKcContextBase<KcContextExtended>>[];
@ -51,22 +51,15 @@ export function getKcContext<KcContextExtended extends ({ pageId: string; } | un
} }
const kcContext: any = { "pageId": mockPageId }; const kcContext: any = {};
deepAssign({ deepAssign({
"target": kcContext, "target": kcContext,
"source": kcContextCommonMock "source": kcContextDefaultMock !== undefined ?
kcContextDefaultMock :
{ "pageId": mockPageId, ...kcContextCommonMock, }
}); });
if (kcContextDefaultMock !== undefined) {
deepAssign({
"target": kcContext,
"source": kcContextDefaultMock
});
}
if (partialKcContextCustomMock !== undefined) { if (partialKcContextCustomMock !== undefined) {
deepAssign({ deepAssign({

@ -2,6 +2,7 @@
import { assert } from "tsafe/assert"; import { assert } from "tsafe/assert";
import { is } from "tsafe/is"; import { is } from "tsafe/is";
//Warning: Be mindful that because of array this is not idempotent.
export function deepAssign( export function deepAssign(
params: { params: {
target: Record<string, unknown>; target: Record<string, unknown>;

@ -6,202 +6,245 @@ import { same } from "evt/tools/inDepth";
import { doExtends } from "tsafe/doExtends"; import { doExtends } from "tsafe/doExtends";
import { assert } from "tsafe/assert"; import { assert } from "tsafe/assert";
import { kcContextMocks, kcContextCommonMock } from "../../lib/getKcContext/kcContextMocks"; import { kcContextMocks, kcContextCommonMock } from "../../lib/getKcContext/kcContextMocks";
import { deepClone } from "../../lib/tools/deepClone"; import { deepClone } from "../../lib/tools/deepClone";
import type { Any } from "ts-toolbelt"; import type { Any } from "ts-toolbelt";
{
const authorizedMailDomains = [ const authorizedMailDomains = [
"example.com", "example.com",
"another-example.com", "another-example.com",
"*.yet-another-example.com", "*.yet-another-example.com",
"*.example.com", "*.example.com",
"hello-world.com" "hello-world.com"
]; ];
const displayName = "this is an overwritten common value"; const displayName = "this is an overwritten common value";
const aNonStandardValue = "a non standard value"; const aNonStandardValue1 = "a non standard value 1";
const aNonStandardValue2 = "a non standard value 2";
type KcContextExtended = { type KcContextExtended = {
pageId: "register.ftl"; pageId: "register.ftl";
authorizedMailDomains: string[]; authorizedMailDomains: string[];
} | { } | {
pageId: "my-extra-page-1.ftl"; pageId: "info.ftl";
} | { aNonStandardValue1: string;
pageId: "my-extra-page-2.ftl"; } | {
aNonStandardValue: string; pageId: "my-extra-page-1.ftl";
}; } | {
pageId: "my-extra-page-2.ftl";
aNonStandardValue2: string;
};
const getKcContextProxy = (
params: {
mockPageId: ExtendsKcContextBase<KcContextExtended>["pageId"];
}
) => {
const { mockPageId } = params;
const { kcContext } = getKcContext<KcContextExtended>({
mockPageId,
"mockData": [
{
"pageId": "login.ftl",
"realm": { displayName }
},
{
"pageId": "info.ftl",
aNonStandardValue1
},
{
"pageId": "register.ftl",
authorizedMailDomains
},
{
"pageId": "my-extra-page-2.ftl",
aNonStandardValue2
}
]
});
return { kcContext };
};
{
const pageId = "login.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
assert(kcContext?.pageId === pageId);
doExtends<Any.Equals<typeof kcContext, KcContextBase.Login>, 1>();
assert(same(
//NOTE: deepClone for printIfExists or other functions...
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!);
mock.realm.displayName = displayName;
return mock;
})()
));
console.log(`PASS ${pageId}`);
function getKcContextProxy(
params: {
mockPageId: ExtendsKcContextBase<KcContextExtended>["pageId"];
} }
) {
const { mockPageId } = params; {
const pageId = "info.ftl";
const { kcContext } = getKcContext<KcContextExtended>({ const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
mockPageId,
"mockData": [ assert(kcContext?.pageId === pageId);
{
"pageId": "login.ftl", //NOTE: I don't understand the need to add: pageId: typeof pageId; ...
"realm": { displayName } doExtends<Any.Equals<typeof kcContext, KcContextBase.Info & { pageId: typeof pageId; aNonStandardValue1: string; }>, 1>();
},
{ assert(same(
"pageId": "register.ftl", deepClone(kcContext),
authorizedMailDomains (() => {
},
{ const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!);
"pageId": "my-extra-page-2.ftl",
aNonStandardValue Object.assign(mock, { aNonStandardValue1 });
}
] return mock;
})()
));
console.log(`PASS ${pageId}`);
}
{
const pageId = "register.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
assert(kcContext?.pageId === pageId);
//NOTE: I don't understand the need to add: pageId: typeof pageId; ...
doExtends<Any.Equals<typeof kcContext, KcContextBase.Register & { pageId: typeof pageId; authorizedMailDomains: string[]; }>, 1>();
assert(same(
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!);
Object.assign(mock, { authorizedMailDomains });
return mock;
})()
));
console.log(`PASS ${pageId}`);
}
{
const pageId = "my-extra-page-2.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
assert(kcContext?.pageId === pageId);
doExtends<Any.Equals<typeof kcContext, KcContextBase.Common & { pageId: typeof pageId; aNonStandardValue2: string; }>, 1>();
kcContext.aNonStandardValue2;
assert(same(
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextCommonMock);
Object.assign(mock, { pageId, aNonStandardValue2 });
return mock;
})()
));
console.log(`PASS ${pageId}`);
}
{
const pageId = "my-extra-page-1.ftl";
console.log("We expect a warning here =>");
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
assert(kcContext?.pageId === pageId);
doExtends<Any.Equals<typeof kcContext, KcContextBase.Common & { pageId: typeof pageId; }>, 1>();
assert(same(
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextCommonMock);
Object.assign(mock, { pageId });
return mock;
})()
));
console.log(`PASS ${pageId}`);
}
}
{
const pageId = "login.ftl";
const { kcContext } = getKcContext({
"mockPageId": pageId
}); });
return { kcContext }; doExtends<Any.Equals<typeof kcContext, KcContextBase | undefined>, 1>();
}
{
const pageId= "login.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
//@ts-expect-error
doExtends<Any.Equals<typeof kcContext, any>, 1>();
assert(kcContext?.pageId === pageId);
doExtends<typeof kcContext, KcContextBase.Login>();
assert(same(
//NOTE: deepClone for printIfExists or other functions...
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!);
mock.realm.displayName = displayName;
return mock;
})()
));
console.log(`PASS ${pageId}`);
}
{
const pageId = "register.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
//@ts-expect-error
doExtends<Any.Equals<typeof kcContext, any>, 1>();
assert(kcContext?.pageId === pageId);
doExtends<typeof kcContext, KcContextBase.Register>();
assert(same( assert(same(
deepClone(kcContext), deepClone(kcContext),
(() => { deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!)
const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!);
Object.assign(mock, { authorizedMailDomains });
return mock;
})()
)); ));
console.log(`PASS ${pageId}`); console.log("PASS no extension");
}
{
const pageId = "my-extra-page-2.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
//@ts-expect-error
doExtends<Any.Equals<typeof kcContext, any>, 1>();
assert(kcContext?.pageId === pageId);
//@ts-expect-error
doExtends<typeof kcContext, KcContextBase>();
doExtends<typeof kcContext, KcContextBase.Common>();
assert(same(
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextCommonMock);
Object.assign(mock, { pageId, aNonStandardValue });
return mock;
})()
));
console.log(`PASS ${pageId}`);
} }
{
const pageId = "my-extra-page-1.ftl";
console.log("We expect a warning here =>");
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
//@ts-expect-error
doExtends<Any.Equals<typeof kcContext, any>, 1>();
assert(kcContext?.pageId === pageId);
//@ts-expect-error
doExtends<typeof kcContext, KcContextBase>();
doExtends<typeof kcContext, KcContextBase.Common>();
assert(same(
deepClone(kcContext),
(() => {
const mock = deepClone(kcContextCommonMock);
Object.assign(mock, { pageId });
return mock;
})()
));
console.log(`PASS ${pageId}`);
}
{ {
const { kcContext } = getKcContext(); const { kcContext } = getKcContext();
//@ts-expect-error doExtends<Any.Equals<typeof kcContext, KcContextBase | undefined>, 1>();
doExtends<Any.Equals<typeof kcContext, any>, 1>();
doExtends<typeof kcContext, KcContextBase | undefined>(); assert(kcContext === undefined);
console.log("PASS no extension, no mock");
} }