Skip to content

Commit

Permalink
fixup! WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Mar 24, 2024
1 parent 8898c18 commit 95718a7
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 7 deletions.
41 changes: 34 additions & 7 deletions src/declaration/kubernetes-address.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import {
applyConstraints,
type DeclarationConstraintOptions,
} from "../constraint.js";
import { createHostnameConstraint } from "../constraint/hostname.js";
import { createNetworkPortNumberConstraint } from "../constraint/network-port-number.js";
import {
Expand All @@ -8,7 +12,7 @@ import {
type ExactOptions,
} from "../declaration.js";
import { registerVariable } from "../environment.js";
import { SpecError, normalize } from "../error.js";
import { SpecError, ValueError, normalize } from "../error.js";
import { resolveExamples, type Example } from "../example.js";
import { Maybe, map, resolve } from "../maybe.js";
import {
Expand All @@ -24,10 +28,11 @@ export type KubernetesAddress = {
readonly port: number;
};

export type Options = DeclarationOptions<KubernetesAddress> & {
readonly examples?: KubernetesAddressExamples;
readonly portName?: string;
};
export type Options = DeclarationOptions<KubernetesAddress> &
DeclarationConstraintOptions<KubernetesAddress> & {
readonly examples?: KubernetesAddressExamples;
readonly portName?: string;
};

type KubernetesAddressExamples = {
readonly host?: Example<string>[];
Expand All @@ -39,6 +44,7 @@ export function kubernetesAddress<O extends Options>(
options: ExactOptions<O, Options> = {} as ExactOptions<O, Options>,
): Declaration<KubernetesAddress, O> {
const {
constraints = [],
examples: { host: hostExamples, port: portExamples } = {},
isSensitive = false,
portName,
Expand All @@ -56,7 +62,24 @@ export function kubernetesAddress<O extends Options>(
const host = resolve(hostVar.nativeValue());
const port = resolve(portVar.nativeValue());

if (host != null && port != null) return { host, port };
if (host != null && port != null) {
const address = { host, port };

try {
applyConstraints(constraints, address);
} catch (error) {
// TODO: Figure out how to associate the error with the host AND port
// TODO: Get the original value in a better way
throw new ValueError(
hName,
isSensitive,
hostVar.marshal(host),
normalize(error),
);
}

return address;
}

if (host != null) throw new PartiallyDefinedError(hName, pName);
if (port != null) throw new PartiallyDefinedError(pName, hName);
Expand All @@ -73,7 +96,7 @@ function registerHost(
def: Maybe<KubernetesAddress | undefined>,
): Variable<string> {
const hostDef = map(def, (address) => address?.host);
const schema = createString("hostname", [createHostnameConstraint()]);
const schema = createHostSchema();
let envName: string;

try {
Expand All @@ -92,6 +115,10 @@ function registerHost(
});
}

function createHostSchema(): ScalarSchema<string> {
return createString("hostname", [createHostnameConstraint()]);
}

function buildHostExamples(): Example<string>[] {
return [
{
Expand Down
78 changes: 78 additions & 0 deletions test/suite/declaration/kubernetes-address.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,4 +603,82 @@ describe("Kubernetes address declarations", () => {
});
},
);

describe("when the declaration has constraints", () => {
beforeEach(() => {
declaration = kubernetesAddress("austenite-svc", {
constraints: [
{
description: "<constraint A>",
constrain: (v) =>
v.host === "example.org" || "host must be example.org",
},
{
description: "<constraint B>",
constrain: (v) => v.port === 12345 || "port must be 12345",
},
],
examples: {
host: [{ value: "example.org", label: "example" }],
port: [{ value: 12345, label: "example" }],
},
});
});

describe("when the value satisfies the constraints", () => {
beforeEach(() => {
process.env.AUSTENITE_SVC_SERVICE_HOST = "example.org";
process.env.AUSTENITE_SVC_SERVICE_PORT = "12345";

initialize({ onInvalid: noop });
});

describe(".value()", () => {
it("returns the value", () => {
expect(declaration.value()).toEqual({
host: "example.org",
port: 12345,
});
});
});
});

describe("when the value violates the first constraint", () => {
beforeEach(() => {
process.env.AUSTENITE_SVC_SERVICE_HOST = "example.com";
process.env.AUSTENITE_SVC_SERVICE_PORT = "12345";

initialize({ onInvalid: noop });
});

describe(".value()", () => {
it("throws", () => {
expect(() => {
declaration.value();
}).toThrow(
"value of AUSTENITE_SVC_SERVICE_HOST (example.com) is invalid: host must be example.org",
);
});
});
});

describe("when the value violates the second constraint", () => {
beforeEach(() => {
process.env.AUSTENITE_SVC_SERVICE_HOST = "example.org";
process.env.AUSTENITE_SVC_SERVICE_PORT = "54321";

initialize({ onInvalid: noop });
});

describe(".value()", () => {
it("throws", () => {
expect(() => {
declaration.value();
}).toThrow(
"value of AUSTENITE_SVC_SERVICE_HOST (example.org) is invalid: port must be 12345",
);
});
});
});
});
});

0 comments on commit 95718a7

Please sign in to comment.