mirror of https://github.com/garrytan/gstack.git
Merge 68f646d1e5 into a3259400a3
This commit is contained in:
commit
ca4f3da21a
|
|
@ -19,6 +19,23 @@ export interface VariantsOptions {
|
||||||
viewports?: string; // "desktop,tablet,mobile" — generates at multiple sizes
|
viewports?: string; // "desktop,tablet,mobile" — generates at multiple sizes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a requested variant count to the supported range.
|
||||||
|
*
|
||||||
|
* `--count` reaches us via `parseInt`, which yields `NaN` for non-numeric
|
||||||
|
* input and happily passes zero/negative values through. The generation loop
|
||||||
|
* only capped the upper bound, so any of those silently produced zero variants
|
||||||
|
* and emitted `"count": null`/`0`/negative in the JSON result. Clamp to the
|
||||||
|
* supported `[1, 7]` range; fall back to the default of 3 when the value is not
|
||||||
|
* a finite number (an unparseable flag, not an explicit out-of-range request).
|
||||||
|
*
|
||||||
|
* Exported for direct unit testing.
|
||||||
|
*/
|
||||||
|
export function normalizeVariantCount(count: number): number {
|
||||||
|
if (!Number.isFinite(count)) return 3;
|
||||||
|
return Math.max(1, Math.min(Math.trunc(count), 7));
|
||||||
|
}
|
||||||
|
|
||||||
const STYLE_VARIATIONS = [
|
const STYLE_VARIATIONS = [
|
||||||
"", // First variant uses the brief as-is
|
"", // First variant uses the brief as-is
|
||||||
"Use a bolder, more dramatic visual style with stronger contrast and larger typography.",
|
"Use a bolder, more dramatic visual style with stronger contrast and larger typography.",
|
||||||
|
|
@ -153,7 +170,7 @@ export async function variants(options: VariantsOptions): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const count = Math.min(options.count, 7); // Cap at 7 style variations
|
const count = normalizeVariantCount(options.count); // Clamp to [1, 7] style variations
|
||||||
const size = options.size || "1536x1024";
|
const size = options.size || "1536x1024";
|
||||||
|
|
||||||
console.error(`Generating ${count} variants...`);
|
console.error(`Generating ${count} variants...`);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { describe, test, expect, beforeEach, afterEach } from "bun:test";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { generateVariant } from "../src/variants";
|
import { generateVariant, normalizeVariantCount } from "../src/variants";
|
||||||
|
|
||||||
// 1x1 transparent PNG, base64 — valid bytes that fs.writeFileSync can write.
|
// 1x1 transparent PNG, base64 — valid bytes that fs.writeFileSync can write.
|
||||||
const TINY_PNG_BASE64 =
|
const TINY_PNG_BASE64 =
|
||||||
|
|
@ -131,3 +131,35 @@ describe("generateVariant Retry-After handling", () => {
|
||||||
expect(gap).toBeLessThan(500);
|
expect(gap).toBeLessThan(500);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("normalizeVariantCount", () => {
|
||||||
|
test("non-numeric (NaN) falls back to the default of 3", () => {
|
||||||
|
// Regression: `--count abc` -> parseInt -> NaN -> Math.min(NaN, 7) -> NaN,
|
||||||
|
// so the loop ran zero times and the JSON result emitted `"count": null`.
|
||||||
|
expect(normalizeVariantCount(NaN)).toBe(3);
|
||||||
|
expect(normalizeVariantCount(Number.parseInt("abc", 10))).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("zero and negative counts clamp up to the minimum of 1", () => {
|
||||||
|
// Regression: `--count 0` / `--count -2` produced zero variants.
|
||||||
|
expect(normalizeVariantCount(0)).toBe(1);
|
||||||
|
expect(normalizeVariantCount(-2)).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("counts above the cap clamp down to 7", () => {
|
||||||
|
expect(normalizeVariantCount(10)).toBe(7);
|
||||||
|
expect(normalizeVariantCount(7)).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("in-range counts pass through unchanged", () => {
|
||||||
|
expect(normalizeVariantCount(1)).toBe(1);
|
||||||
|
expect(normalizeVariantCount(3)).toBe(3);
|
||||||
|
expect(normalizeVariantCount(6)).toBe(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("fractional counts truncate toward zero before clamping", () => {
|
||||||
|
expect(normalizeVariantCount(2.9)).toBe(2);
|
||||||
|
expect(normalizeVariantCount(0.5)).toBe(1);
|
||||||
|
expect(normalizeVariantCount(Infinity)).toBe(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue