@tallyrelease/core 0.5.0-beta.39 → 0.5.0-beta.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,7 @@ renderTag({ id: "web", tagFormat: "{id}-v{version}" }, "1.2.0"); // "web-v1.2.0"
40
40
 
41
41
  ## Testing
42
42
 
43
- The `@tallyrelease/core/testing` export provides in-memory fakes: `memoryFs`, `memoryCtx` and `memoryGit`. The `@tallyrelease/core/testing/conformance` export provides `gitReaderConformance`, a shared `GitReader` spec that requires vitest.
43
+ The `@tallyrelease/core/testing` export provides in-memory fakes: `memoryFs`, `memoryCtx` and `memoryGit`. The `@tallyrelease/core/testing/conformance` export provides `gitReaderConformance` and `schemeConformance`, shared `GitReader` and `VersionScheme` specs that require vitest.
44
44
 
45
45
  ## Licence
46
46
 
@@ -1,5 +1,5 @@
1
1
  import type { Dag } from "./index.js";
2
- import type { GitReader, MaybePromise } from "../plugin.js";
2
+ import type { GitReader, MaybePromise, VersionScheme } from "../plugin.js";
3
3
  /** Builds a reader for `dag`; `sha` maps a commit id to the reader's sha. */
4
4
  export type ReaderFactory = (dag: Dag) => MaybePromise<{
5
5
  git: GitReader;
@@ -13,3 +13,9 @@ export type ReaderFactory = (dag: Dag) => MaybePromise<{
13
13
  * `introduced` runs on its own fixture.
14
14
  */
15
15
  export declare const gitReaderConformance: (makeReader: ReaderFactory) => void;
16
+ /**
17
+ * Shared `VersionScheme` spec. Versions are derived from `initial()`:
18
+ * `parse`/`format` round-trip, `compare` order, `bump` monotonicity per level,
19
+ * and `release`/`prerelease` keeping the core triple.
20
+ */
21
+ export declare const schemeConformance: <V>(scheme: VersionScheme<V>) => void;
@@ -202,3 +202,94 @@ export const gitReaderConformance = (makeReader) => {
202
202
  });
203
203
  });
204
204
  };
205
+ const LEVELS = ["major", "minor", "patch"];
206
+ const PRE_CTX = {
207
+ unit: {
208
+ id: "u",
209
+ root: ".",
210
+ plugin: "conformance",
211
+ include: [],
212
+ exclude: [],
213
+ version: "tag",
214
+ scheme: "conformance",
215
+ tagFormat: "v{version}",
216
+ propagate: "auto",
217
+ tags: [],
218
+ initialVersion: null,
219
+ meta: {},
220
+ },
221
+ head: "0".repeat(40),
222
+ baseTag: null,
223
+ tags: [],
224
+ firstParent: { sinceLineBase: 3, total: 7 },
225
+ channel: "rc",
226
+ };
227
+ /**
228
+ * Shared `VersionScheme` spec. Versions are derived from `initial()`:
229
+ * `parse`/`format` round-trip, `compare` order, `bump` monotonicity per level,
230
+ * and `release`/`prerelease` keeping the core triple.
231
+ */
232
+ export const schemeConformance = (scheme) => {
233
+ describe("VersionScheme conformance", () => {
234
+ const initial = scheme.initial();
235
+ const bumped = (level) => scheme.bump(initial, level);
236
+ it("round-trips parse and format", () => {
237
+ for (const v of [initial, ...LEVELS.map(bumped)]) {
238
+ const raw = scheme.format(v);
239
+ const parsed = scheme.parse(raw);
240
+ expect(parsed).toBeDefined();
241
+ expect(scheme.format(parsed)).toBe(raw);
242
+ expect(scheme.compare(parsed, v)).toBe(0);
243
+ }
244
+ });
245
+ it("rejects input that is not a version", () => {
246
+ expect(scheme.parse("")).toBeUndefined();
247
+ expect(scheme.parse("not a version")).toBeUndefined();
248
+ });
249
+ it("compares consistently", () => {
250
+ const low = initial;
251
+ const high = bumped("patch");
252
+ expect(scheme.compare(low, low)).toBe(0);
253
+ expect(scheme.compare(low, high)).toBeLessThan(0);
254
+ expect(scheme.compare(high, low)).toBeGreaterThan(0);
255
+ });
256
+ it.each(LEVELS)("bumps %s above the previous version", (level) => {
257
+ const next = bumped(level);
258
+ expect(scheme.compare(next, initial)).toBeGreaterThan(0);
259
+ expect(scheme.isPrerelease(next)).toBe(false);
260
+ });
261
+ it("orders bump levels major > minor > patch", () => {
262
+ const [major, minor, patch] = LEVELS.map(bumped);
263
+ expect(scheme.compare(major, minor)).toBeGreaterThan(0);
264
+ expect(scheme.compare(minor, patch)).toBeGreaterThan(0);
265
+ });
266
+ it("resets lower core parts on a bump", () => {
267
+ const { major, minor, patch } = scheme.core(initial);
268
+ expect(scheme.core(bumped("major"))).toEqual({
269
+ major: major + 1,
270
+ minor: 0,
271
+ patch: 0,
272
+ });
273
+ expect(scheme.core(bumped("minor"))).toEqual({
274
+ major,
275
+ minor: minor + 1,
276
+ patch: 0,
277
+ });
278
+ expect(scheme.core(bumped("patch"))).toEqual({
279
+ major,
280
+ minor,
281
+ patch: patch + 1,
282
+ });
283
+ });
284
+ it("keeps the core when releasing or prereleasing", () => {
285
+ const next = bumped("minor");
286
+ const release = scheme.release(next, PRE_CTX);
287
+ const pre = scheme.prerelease(next, PRE_CTX);
288
+ expect(scheme.core(release)).toEqual(scheme.core(next));
289
+ expect(scheme.core(pre)).toEqual(scheme.core(next));
290
+ expect(scheme.isPrerelease(release)).toBe(false);
291
+ expect(scheme.compare(pre, release)).toBeLessThanOrEqual(0);
292
+ expect(scheme.parse(scheme.format(pre))).toBeDefined();
293
+ });
294
+ });
295
+ };
@@ -1,5 +1,4 @@
1
1
  import type { Ctx, GitReader, ReadonlyFs } from "../plugin.js";
2
- import type { ReaderFactory } from "./conformance.js";
3
2
  /** In-memory `ReadonlyFs` over a path-to-content map. */
4
3
  export declare const memoryFs: (files: Record<string, string>) => ReadonlyFs;
5
4
  export interface MemoryCtxOptions<O> {
@@ -43,6 +42,3 @@ export interface MemoryGit extends GitReader {
43
42
  }
44
43
  /** In-memory `GitReader` over a commit graph. */
45
44
  export declare const memoryGit: (dag: Dag) => MemoryGit;
46
- export type { ReaderFactory } from "./conformance.js";
47
- /** Re-export of `@tallyrelease/core/testing/conformance`; requires vitest. */
48
- export declare const gitReaderConformance: (makeReader: ReaderFactory) => void;
@@ -1,13 +1,5 @@
1
1
  import picomatch from "picomatch/posix.js";
2
2
  import { compare, uniqueSorted } from "../util.js";
3
- // Loaded optionally so the fakes work without vitest installed.
4
- // eslint-disable-next-line no-restricted-syntax
5
- const conformance = await import("./conformance.js").catch((error) => {
6
- if (error.code === "ERR_MODULE_NOT_FOUND") {
7
- return null;
8
- }
9
- throw error;
10
- });
11
3
  const SKIPPED = new Set([".git", "node_modules"]);
12
4
  const changed = (a, b) => uniqueSorted([...a.keys(), ...b.keys()]).filter((p) => a.get(p) !== b.get(p));
13
5
  /** In-memory `ReadonlyFs` over a path-to-content map. */
@@ -149,10 +141,3 @@ export const memoryGit = (dag) => {
149
141
  parents: (ref) => [...node(ref).parents],
150
142
  };
151
143
  };
152
- /** Re-export of `@tallyrelease/core/testing/conformance`; requires vitest. */
153
- export const gitReaderConformance = (makeReader) => {
154
- if (conformance === null) {
155
- throw new Error("gitReaderConformance requires vitest");
156
- }
157
- conformance.gitReaderConformance(makeReader);
158
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tallyrelease/core",
3
- "version": "0.5.0-beta.39",
3
+ "version": "0.5.0-beta.44",
4
4
  "description": "Pure planning core of tallyrelease",
5
5
  "repository": {
6
6
  "type": "git",