import { expect } from "@std/expect";
import { describe, it } from "@std/testing/bdd";
import type { TransformationDiagnostic } from "../src/mod.ts";
import { COMMONFABRIC_TYPES } from "./commonfabric-test-types.ts";
import { parseModule, patternSchemas } from "./transformed-ast.ts";
import { transformFiles } from "./utils.ts";
describe("qualified CFC metadata", () => {
const policy = {
type: "https://commonfabric.org/cfc/atom/Policy",
policyRefKind: "module",
moduleIdentity: "sha256:rules",
symbol: "rules",
policyDigest: expect.any(String),
subject: { __ctOwningSpace: true },
};
for (
const [spelling, imports, choice, binding, expectedChoice, expectedPolicy]
of [
[
"the main library namespace",
'import * as cf from "commonfabric";',
"cf.AnyOf",
"cf.PolicyOf",
{ anyOf: ["reader"] },
policy,
],
[
"the companion library namespace",
'import * as cf from "commonfabric/cfc";',
"cf.AnyOf",
"cf.PolicyOf",
{ anyOf: ["reader"] },
policy,
],
[
"renamed library re-exports",
'import * as cf from "./barrel.ts";',
"cf.Choice",
"cf.Policy",
{ anyOf: ["reader"] },
policy,
],
[
"a re-exported library namespace",
'import * as outer from "./namespace.ts";',
"outer.cf.AnyOf",
"outer.cf.PolicyOf",
{ anyOf: ["reader"] },
policy,
],
[
"authored names beside library re-exports",
'import * as other from "./other.ts";',
"other.AnyOf",
"other.PolicyOf",
{ label: "ordinary choice" },
{ label: "ordinary policy" },
],
] as const
) {
it(`reads metadata from ${spelling}`, async () => {
const diagnostics: TransformationDiagnostic[] = [];
const files = await transformFiles({
"/rules.ts": `///
import { cfcPattern, exchangeRule, exchangeRules, THIS_POLICY, v } from "commonfabric/cfc";
export const release = exchangeRule({
appliesTo: THIS_POLICY,
pre: { integrity: [cfcPattern.hasRole(v("user"), THIS_POLICY.subject, "reader")] },
post: { addAlternatives: [cfcPattern.user(v("user"))] },
});
export const rules = exchangeRules([release]);`,
"/barrel.ts":
'export type { AnyOf as Choice, PolicyOf as Policy } from "commonfabric/cfc";',
"/namespace.ts": 'export * as cf from "commonfabric/cfc";',
"/other.ts":
`export type { PolicyOf as RealPolicy } from "commonfabric/cfc";
export type AnyOf = { label: "ordinary choice" };
export type PolicyOf = { label: "ordinary policy" };`,
"/main.tsx": `///
import { Cfc, pattern } from "commonfabric";
import { rules } from "./rules.ts";
${imports}
export default pattern<{
either: Cfc] }>;
controlled: Cfc] }>;
}>(({ either, controlled }) => ({ either, controlled }));`,
}, {
types: COMMONFABRIC_TYPES,
typeCheck: true,
moduleIdentities: new Map([["/rules.ts", "sha256:rules"]]),
pipelineDiagnostics: diagnostics,
});
expect(diagnostics.filter((entry) => entry.severity === "error"))
.toEqual([]);
const { input, output } = patternSchemas(parseModule(files["/main.tsx"]));
const expected = {
properties: {
either: {
type: "string",
ifc: { confidentiality: [expectedChoice] },
},
controlled: {
type: "string",
ifc: { confidentiality: [expectedPolicy] },
},
},
};
expect(input).toMatchObject(expected);
expect(output).toMatchObject(expected);
});
}
});