From 17d4b8048f9db3c78bd9b981b805ac22890766c7 Mon Sep 17 00:00:00 2001 From: BluJ Date: Mon, 18 Jul 2022 13:27:51 -0600 Subject: [PATCH 1/2] chore: add some documentation and somet testing --- Makefile | 6 + compat/getConfig.ts | 42 +++-- compat/properties.ts | 58 +++---- compat/setConfig.ts | 49 +++--- emver-lite/mod.ts | 17 ++ emver-lite/test.ts | 372 ++++++++++++++++++++++--------------------- test.ts | 1 + 7 files changed, 296 insertions(+), 249 deletions(-) create mode 100644 Makefile create mode 100644 test.ts diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9ea1792 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +TEST_FILES := $(shell find ./**/*.ts) + + +test: $(TEST_FILES) + deno test test.ts + deno check mod.ts \ No newline at end of file diff --git a/compat/getConfig.ts b/compat/getConfig.ts index a26dd5e..06d6878 100644 --- a/compat/getConfig.ts +++ b/compat/getConfig.ts @@ -1,4 +1,3 @@ - import { YAML } from "../dependencies.ts"; import { matches } from "../dependencies.ts"; import { ExpectedExports } from "../types.ts"; @@ -8,22 +7,31 @@ const { any, string, dictionary } = matches; const matchConfig = dictionary([string, any]); -export const getConfig = (spec: ConfigSpec): ExpectedExports.getConfig => async (effects) => { +/** + * Call with the configuration to get a standard getConfig for the expected exports + * Assumption: start9/config.yaml is where the config will be stored + * Throws: Error if there is no file + * Throws: Error if the config.yaml isn't yaml nor config shape + * @param spec + * @returns + */ +export const getConfig = (spec: ConfigSpec): ExpectedExports.getConfig => + async (effects) => { const config = await effects - .readFile({ - path: "start9/config.yaml", - volumeId: "main", - }) - .then((x) => YAML.parse(x)) - .then((x) => matchConfig.unsafeCast(x)) - .catch((e) => { - effects.info(`Got error ${e} while trying to read the config`); - return undefined; - }); + .readFile({ + path: "start9/config.yaml", + volumeId: "main", + }) + .then((x) => YAML.parse(x)) + .then((x) => matchConfig.unsafeCast(x)) + .catch((e) => { + effects.info(`Got error ${e} while trying to read the config`); + return undefined; + }); return { - result: { - config, - spec, - }, + result: { + config, + spec, + }, }; -}; + }; diff --git a/compat/properties.ts b/compat/properties.ts index 5de57d1..2dce936 100644 --- a/compat/properties.ts +++ b/compat/properties.ts @@ -1,38 +1,42 @@ import { YAML } from "../dependencies.ts"; import { exists } from "../exists.ts"; -import { ResultType, Properties, ExpectedExports, Effects } from "../types.ts"; - +import { Effects, ExpectedExports, Properties, ResultType } from "../types.ts"; // deno-lint-ignore no-explicit-any -const asResult = (result: any) => ({ result: result as Properties }) +const asResult = (result: any) => ({ result: result as Properties }); const noPropertiesFound: ResultType = { - result: { - version: 2, - data: { - "Not Ready": { - type: "string", - value: "Could not find properties. The service might still be starting", - qr: false, - copyable: false, - masked: false, - description: "Fallback Message When Properties could not be found" - } - } - } -} as const + result: { + version: 2, + data: { + "Not Ready": { + type: "string", + value: "Could not find properties. The service might still be starting", + qr: false, + copyable: false, + masked: false, + description: "Fallback Message When Properties could not be found", + }, + }, + }, +} as const; /** * Default will pull from a file (start9/stats.yaml) expected to be made on the main volume - * @param effects - * @returns + * Assumption: start9/stats.yaml is created by some process + * Throws: stats.yaml isn't yaml + * @param effects + * @returns */ export const properties: ExpectedExports.properties = async ( - effects: Effects, + effects: Effects, ) => { - if (await exists(effects, { path: "start9/stats.yaml", volumeId: "main" }) === false) { - return noPropertiesFound; - } - return await effects.readFile({ - path: "start9/stats.yaml", - volumeId: "main", - }).then(YAML.parse).then(asResult) + if ( + await exists(effects, { path: "start9/stats.yaml", volumeId: "main" }) === + false + ) { + return noPropertiesFound; + } + return await effects.readFile({ + path: "start9/stats.yaml", + volumeId: "main", + }).then(YAML.parse).then(asResult); }; diff --git a/compat/setConfig.ts b/compat/setConfig.ts index 117a3bf..5a5a9e8 100644 --- a/compat/setConfig.ts +++ b/compat/setConfig.ts @@ -1,33 +1,40 @@ import { YAML } from "../dependencies.ts"; -import { ExpectedExports, Effects, Config, SetResult, DependsOn } from "../types.ts"; +import { + Config, + DependsOn, + Effects, + ExpectedExports, + SetResult, +} from "../types.ts"; /** * Will set the config to the default start9/config.yaml - * @param effects + * Assumption: start9/config.yaml is the location of the configuration + * @param effects * @param newConfig Config to be written to start9/config.yaml * @param depends_on This would be the depends on for condition depends_on - * @returns + * @returns */ export const setConfig = async ( - effects: Effects, - newConfig: Config, - dependsOn: DependsOn = {} + effects: Effects, + newConfig: Config, + dependsOn: DependsOn = {}, ) => { - await effects.createDir({ - path: "start9", - volumeId: "main", - }); - await effects.writeFile({ - path: "start9/config.yaml", - toWrite: YAML.stringify(newConfig), - volumeId: "main", - }); + await effects.createDir({ + path: "start9", + volumeId: "main", + }); + await effects.writeFile({ + path: "start9/config.yaml", + toWrite: YAML.stringify(newConfig), + volumeId: "main", + }); - const result: SetResult = { - signal: "SIGTERM", - "depends-on": dependsOn, - }; - return { result, }; + const result: SetResult = { + signal: "SIGTERM", + "depends-on": dependsOn, + }; + return { result }; }; -const _typeConversionCheck: ExpectedExports.setConfig = setConfig +const _typeConversionCheck: ExpectedExports.setConfig = setConfig; diff --git a/emver-lite/mod.ts b/emver-lite/mod.ts index 11510b3..73e1ab3 100644 --- a/emver-lite/mod.ts +++ b/emver-lite/mod.ts @@ -125,6 +125,12 @@ export class EmVer { public lessThan(other: EmVer): boolean { return !this.greaterThanOrEqual(other); } + /** + * Return a enum string that describes (used for switching/iffs) + * to know comparison + * @param other + * @returns + */ public compare(other: EmVer) { if (this.equals(other)) { return "equal" as const; @@ -134,6 +140,11 @@ export class EmVer { return "less" as const; } } + /** + * Used when sorting emver's in a list using the sort method + * @param other + * @returns + */ public compareForSort(other: EmVer) { return matches.matches(this.compare(other)) .when("equal", () => 0 as const) @@ -250,6 +261,7 @@ export class Checker { return true; }); } + public or(...others: (Checker | string)[]): Checker { return new Checker((value) => { if (this.check(value)) { @@ -263,6 +275,11 @@ export class Checker { return false; }); } + + /** + * A useful example is making sure we don't match an exact version, like !=1.2.3 + * @returns + */ public not(): Checker { return new Checker((value) => !this.check(value)); } diff --git a/emver-lite/test.ts b/emver-lite/test.ts index 93ac26b..cdbdaa3 100644 --- a/emver-lite/test.ts +++ b/emver-lite/test.ts @@ -1,240 +1,244 @@ - import { expect } from "https://deno.land/x/expect@v0.2.9/mod.ts"; -import { notRange, rangeAnd, rangeOf, rangeOr } from "./mod.ts"; +import { EmVer, notRange, rangeAnd, rangeOf, rangeOr } from "./mod.ts"; const { test } = Deno; - { - const checker = rangeOf("*"); - test("rangeOf('*')", () => { - expect(checker.check("1")).toBe(true); - expect(checker.check("1.2")).toBe(true); - expect(checker.check("1.2.3.4")).toBe(true); - }) - test("rangeOf('*') invalid", () => { - expect(() => checker.check("a")).toThrow(); - expect(() => checker.check("")).toThrow(); - expect(() => checker.check("1..3")).toThrow(); - }) + const checker = rangeOf("*"); + test("rangeOf('*')", () => { + expect(checker.check("1")).toBe(true); + expect(checker.check("1.2")).toBe(true); + expect(checker.check("1.2.3.4")).toBe(true); + }); + test("rangeOf('*') invalid", () => { + expect(() => checker.check("a")).toThrow(); + expect(() => checker.check("")).toThrow(); + expect(() => checker.check("1..3")).toThrow(); + }); } { - const checker = rangeOf(">1.2.3.4"); - test(`rangeOf(">1.2.3.4") valid`, () => { - expect(checker.check("2")).toBe(true); - expect(checker.check("1.2.3.5")).toBe(true); - expect(checker.check("1.2.3.4.1")).toBe(true); - }) + const checker = rangeOf(">1.2.3.4"); + test(`rangeOf(">1.2.3.4") valid`, () => { + expect(checker.check("2")).toBe(true); + expect(checker.check("1.2.3.5")).toBe(true); + expect(checker.check("1.2.3.4.1")).toBe(true); + }); - test(`rangeOf(">1.2.3.4") invalid`, () => { - expect(checker.check("1.2.3.4")).toBe(false); - expect(checker.check("1.2.3")).toBe(false); - expect(checker.check("1")).toBe(false); - }) + test(`rangeOf(">1.2.3.4") invalid`, () => { + expect(checker.check("1.2.3.4")).toBe(false); + expect(checker.check("1.2.3")).toBe(false); + expect(checker.check("1")).toBe(false); + }); } { - const checker = rangeOf("=1.2.3"); - test(`rangeOf("=1.2.3") valid`, () => { - expect(checker.check("1.2.3")).toBe(true); - }) + const checker = rangeOf("=1.2.3"); + test(`rangeOf("=1.2.3") valid`, () => { + expect(checker.check("1.2.3")).toBe(true); + }); - test(`rangeOf("=1.2.3") invalid`, () => { - expect(checker.check("2")).toBe(false); - expect(checker.check("1.2.3.1")).toBe(false); - expect(checker.check("1.2")).toBe(false); - }) + test(`rangeOf("=1.2.3") invalid`, () => { + expect(checker.check("2")).toBe(false); + expect(checker.check("1.2.3.1")).toBe(false); + expect(checker.check("1.2")).toBe(false); + }); } { - const checker = rangeOf(">=1.2.3.4"); - test(`rangeOf(">=1.2.3.4") valid`, () => { - expect(checker.check("2")).toBe(true); - expect(checker.check("1.2.3.5")).toBe(true); - expect(checker.check("1.2.3.4.1")).toBe(true); - expect(checker.check("1.2.3.4")).toBe(true); - }) + const checker = rangeOf(">=1.2.3.4"); + test(`rangeOf(">=1.2.3.4") valid`, () => { + expect(checker.check("2")).toBe(true); + expect(checker.check("1.2.3.5")).toBe(true); + expect(checker.check("1.2.3.4.1")).toBe(true); + expect(checker.check("1.2.3.4")).toBe(true); + }); - test(`rangeOf(">=1.2.3.4") invalid`, () => { - expect(checker.check("1.2.3")).toBe(false); - expect(checker.check("1")).toBe(false); - }) + test(`rangeOf(">=1.2.3.4") invalid`, () => { + expect(checker.check("1.2.3")).toBe(false); + expect(checker.check("1")).toBe(false); + }); } { - const checker = rangeOf("<1.2.3.4"); - test(`rangeOf("<1.2.3.4") invalid`, () => { - expect(checker.check("2")).toBe(false); - expect(checker.check("1.2.3.5")).toBe(false); - expect(checker.check("1.2.3.4.1")).toBe(false); - expect(checker.check("1.2.3.4")).toBe(false); - }) + const checker = rangeOf("<1.2.3.4"); + test(`rangeOf("<1.2.3.4") invalid`, () => { + expect(checker.check("2")).toBe(false); + expect(checker.check("1.2.3.5")).toBe(false); + expect(checker.check("1.2.3.4.1")).toBe(false); + expect(checker.check("1.2.3.4")).toBe(false); + }); - test(`rangeOf("<1.2.3.4") valid`, () => { - expect(checker.check("1.2.3")).toBe(true); - expect(checker.check("1")).toBe(true); - }) + test(`rangeOf("<1.2.3.4") valid`, () => { + expect(checker.check("1.2.3")).toBe(true); + expect(checker.check("1")).toBe(true); + }); } { - const checker = rangeOf("<=1.2.3.4"); - test(`rangeOf("<=1.2.3.4") invalid`, () => { - expect(checker.check("2")).toBe(false); - expect(checker.check("1.2.3.5")).toBe(false); - expect(checker.check("1.2.3.4.1")).toBe(false); - }) + const checker = rangeOf("<=1.2.3.4"); + test(`rangeOf("<=1.2.3.4") invalid`, () => { + expect(checker.check("2")).toBe(false); + expect(checker.check("1.2.3.5")).toBe(false); + expect(checker.check("1.2.3.4.1")).toBe(false); + }); - test(`rangeOf("<=1.2.3.4") valid`, () => { - expect(checker.check("1.2.3")).toBe(true); - expect(checker.check("1")).toBe(true); - expect(checker.check("1.2.3.4")).toBe(true); - }) + test(`rangeOf("<=1.2.3.4") valid`, () => { + expect(checker.check("1.2.3")).toBe(true); + expect(checker.check("1")).toBe(true); + expect(checker.check("1.2.3.4")).toBe(true); + }); } { + const checkA = rangeOf(">1"); + const checkB = rangeOf("<=2"); - const checkA = rangeOf(">1"); - const checkB = rangeOf("<=2"); + const checker = rangeAnd(checkA, checkB); + test(`simple and(checkers) valid`, () => { + expect(checker.check("2")).toBe(true); - const checker = rangeAnd(checkA, checkB); - test(`simple and(checkers) valid`, () => { - expect(checker.check("2")).toBe(true); - - expect(checker.check("1.1")).toBe(true); - }) - test(`simple and(checkers) invalid`, () => { - expect(checker.check("2.1")).toBe(false); - expect(checker.check("1")).toBe(false); - expect(checker.check("0")).toBe(false); - }) + expect(checker.check("1.1")).toBe(true); + }); + test(`simple and(checkers) invalid`, () => { + expect(checker.check("2.1")).toBe(false); + expect(checker.check("1")).toBe(false); + expect(checker.check("0")).toBe(false); + }); } { + const checkA = rangeOf("<1"); + const checkB = rangeOf("=2"); - const checkA = rangeOf("<1"); - const checkB = rangeOf("=2"); - - const checker = rangeOr(checkA, checkB); - test(`simple or(checkers) valid`, () => { - expect(checker.check("2")).toBe(true); - expect(checker.check("0.1")).toBe(true); - }) - test(`simple or(checkers) invalid`, () => { - expect(checker.check("2.1")).toBe(false); - expect(checker.check("1")).toBe(false); - expect(checker.check("1.1")).toBe(false); - }) + const checker = rangeOr(checkA, checkB); + test(`simple or(checkers) valid`, () => { + expect(checker.check("2")).toBe(true); + expect(checker.check("0.1")).toBe(true); + }); + test(`simple or(checkers) invalid`, () => { + expect(checker.check("2.1")).toBe(false); + expect(checker.check("1")).toBe(false); + expect(checker.check("1.1")).toBe(false); + }); } { - const checker = rangeOf('1.2.*'); - test(`rangeOf(1.2.*) valid`, () => { - expect(checker.check("1.2")).toBe(true); - expect(checker.check("1.2.1")).toBe(true); - }) - test(`rangeOf(1.2.*) invalid`, () => { - expect(checker.check("1.3")).toBe(false); - expect(checker.check("1.3.1")).toBe(false); + const checker = rangeOf("1.2.*"); + test(`rangeOf(1.2.*) valid`, () => { + expect(checker.check("1.2")).toBe(true); + expect(checker.check("1.2.1")).toBe(true); + }); + test(`rangeOf(1.2.*) invalid`, () => { + expect(checker.check("1.3")).toBe(false); + expect(checker.check("1.3.1")).toBe(false); - expect(checker.check("1.1.1")).toBe(false); - expect(checker.check("1.1")).toBe(false); - expect(checker.check("1")).toBe(false); + expect(checker.check("1.1.1")).toBe(false); + expect(checker.check("1.1")).toBe(false); + expect(checker.check("1")).toBe(false); - - expect(checker.check("2")).toBe(false); - }) -} - - -{ - const checker = notRange(rangeOf('1.2.*')); - test(`notRange(rangeOf(1.2.*)) valid`, () => { - expect(checker.check("1.3")).toBe(true); - expect(checker.check("1.3.1")).toBe(true); - - expect(checker.check("1.1.1")).toBe(true); - expect(checker.check("1.1")).toBe(true); - expect(checker.check("1")).toBe(true); - - - expect(checker.check("2")).toBe(true); - }) - test(`notRange(rangeOf(1.2.*)) invalid `, () => { - expect(checker.check("1.2")).toBe(false); - expect(checker.check("1.2.1")).toBe(false); - }) + expect(checker.check("2")).toBe(false); + }); } { - const checker = rangeOf('!1.2.*'); - test(`!(rangeOf(1.2.*)) valid`, () => { - expect(checker.check("1.3")).toBe(true); - expect(checker.check("1.3.1")).toBe(true); + const checker = notRange(rangeOf("1.2.*")); + test(`notRange(rangeOf(1.2.*)) valid`, () => { + expect(checker.check("1.3")).toBe(true); + expect(checker.check("1.3.1")).toBe(true); - expect(checker.check("1.1.1")).toBe(true); - expect(checker.check("1.1")).toBe(true); - expect(checker.check("1")).toBe(true); + expect(checker.check("1.1.1")).toBe(true); + expect(checker.check("1.1")).toBe(true); + expect(checker.check("1")).toBe(true); - - expect(checker.check("2")).toBe(true); - }) - test(`!(rangeOf(1.2.*)) invalid `, () => { - expect(checker.check("1.2")).toBe(false); - expect(checker.check("1.2.1")).toBe(false); - }) + expect(checker.check("2")).toBe(true); + }); + test(`notRange(rangeOf(1.2.*)) invalid `, () => { + expect(checker.check("1.2")).toBe(false); + expect(checker.check("1.2.1")).toBe(false); + }); } { - test(`no and ranges`, () => { - expect(() => rangeAnd()).toThrow() - }) - test(`no or ranges`, () => { - expect(() => rangeOr()).toThrow() - }) + const checker = rangeOf("!1.2.*"); + test(`!(rangeOf(1.2.*)) valid`, () => { + expect(checker.check("1.3")).toBe(true); + expect(checker.check("1.3.1")).toBe(true); + + expect(checker.check("1.1.1")).toBe(true); + expect(checker.check("1.1")).toBe(true); + expect(checker.check("1")).toBe(true); + + expect(checker.check("2")).toBe(true); + }); + test(`!(rangeOf(1.2.*)) invalid `, () => { + expect(checker.check("1.2")).toBe(false); + expect(checker.check("1.2.1")).toBe(false); + }); +} + +{ + test(`no and ranges`, () => { + expect(() => rangeAnd()).toThrow(); + }); + test(`no or ranges`, () => { + expect(() => rangeOr()).toThrow(); + }); } { - const checker = rangeOf("!>1.2.3.4"); - test(`rangeOf("!>1.2.3.4") invalid`, () => { - expect(checker.check("2")).toBe(false); - expect(checker.check("1.2.3.5")).toBe(false); - expect(checker.check("1.2.3.4.1")).toBe(false); - }) + const checker = rangeOf("!>1.2.3.4"); + test(`rangeOf("!>1.2.3.4") invalid`, () => { + expect(checker.check("2")).toBe(false); + expect(checker.check("1.2.3.5")).toBe(false); + expect(checker.check("1.2.3.4.1")).toBe(false); + }); - test(`rangeOf("!>1.2.3.4") valid`, () => { - expect(checker.check("1.2.3.4")).toBe(true); - expect(checker.check("1.2.3")).toBe(true); - expect(checker.check("1")).toBe(true); - }) + test(`rangeOf("!>1.2.3.4") valid`, () => { + expect(checker.check("1.2.3.4")).toBe(true); + expect(checker.check("1.2.3")).toBe(true); + expect(checker.check("1")).toBe(true); + }); } test(">1 && =1.2", () => { - const checker = rangeOf(">1 && =1.2"); + const checker = rangeOf(">1 && =1.2"); - expect(checker.check("1.2")).toBe(true); - expect(checker.check("1.2.1")).toBe(false); - -}) + expect(checker.check("1.2")).toBe(true); + expect(checker.check("1.2.1")).toBe(false); +}); test("=1 || =2", () => { - const checker = rangeOf("=1 || =2"); - - expect(checker.check("1")).toBe(true); - expect(checker.check("2")).toBe(true); - expect(checker.check("3")).toBe(false); - -}) + const checker = rangeOf("=1 || =2"); + expect(checker.check("1")).toBe(true); + expect(checker.check("2")).toBe(true); + expect(checker.check("3")).toBe(false); +}); test(">1 && =1.2 || =2", () => { - const checker = rangeOf(">1 && =1.2 || =2"); + const checker = rangeOf(">1 && =1.2 || =2"); - expect(checker.check("1.2")).toBe(true); - expect(checker.check("1")).toBe(false); - expect(checker.check("2")).toBe(true); - expect(checker.check("3")).toBe(false); - -}) + expect(checker.check("1.2")).toBe(true); + expect(checker.check("1")).toBe(false); + expect(checker.check("2")).toBe(true); + expect(checker.check("3")).toBe(false); +}); test("&& before || order of operationns: <1.5 && >1 || >1.5 && <3", () => { - const checker = rangeOf("<1.5 && >1 || >1.5 && <3"); - expect(checker.check("1.1")).toBe(true); - expect(checker.check("2")).toBe(true); + const checker = rangeOf("<1.5 && >1 || >1.5 && <3"); + expect(checker.check("1.1")).toBe(true); + expect(checker.check("2")).toBe(true); - expect(checker.check("1.5")).toBe(false); - expect(checker.check("1")).toBe(false); - expect(checker.check("3")).toBe(false); + expect(checker.check("1.5")).toBe(false); + expect(checker.check("1")).toBe(false); + expect(checker.check("3")).toBe(false); +}); -}) \ No newline at end of file +test("Compare function on the emver", () => { + const a = EmVer.from("1.2.3"); + const b = EmVer.from("1.2.4"); + + expect(a.compare(b) === "less"); + expect(b.compare(a) === "greater"); + expect(a.compare(a) === "equal"); +}); +test("Compare for sort function on the emver", () => { + const a = EmVer.from("1.2.3"); + const b = EmVer.from("1.2.4"); + + expect(a.compareForSort(b) === -1); + expect(b.compareForSort(a) === 1); + expect(a.compareForSort(a) === 0); +}); diff --git a/test.ts b/test.ts new file mode 100644 index 0000000..859689e --- /dev/null +++ b/test.ts @@ -0,0 +1 @@ +import "./emver-lite/test.ts"; From 5b4a2257c7908b2db6124026b1c256f0469c925c Mon Sep 17 00:00:00 2001 From: BluJ Date: Mon, 18 Jul 2022 13:37:52 -0600 Subject: [PATCH 2/2] chore: adding in more comments --- emver-lite/mod.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/emver-lite/mod.ts b/emver-lite/mod.ts index 73e1ab3..8e94bcd 100644 --- a/emver-lite/mod.ts +++ b/emver-lite/mod.ts @@ -248,6 +248,9 @@ export class Checker { public readonly check: (value: string | EmVer) => boolean, ) {} + /** + * Used when we want the `and` condition with another checker + */ public and(...others: (Checker | string)[]): Checker { return new Checker((value) => { if (!this.check(value)) { @@ -262,6 +265,9 @@ export class Checker { }); } + /** + * Used when we want the `or` condition with another checker + */ public or(...others: (Checker | string)[]): Checker { return new Checker((value) => { if (this.check(value)) {