Skip to content

Commit d60f34e

Browse files
fix(cli): reject inherited motion assertion kinds
1 parent 042ec2e commit d60f34e

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

‎packages/cli/src/utils/motionSpec.test.ts‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ describe("parseMotionSpec", () => {
4747
if (!result.ok) expect(result.errors[0]).toContain("unknown assertion kind");
4848
});
4949

50+
it.each(["constructor", "__proto__", "hasOwnProperty", "toString", "valueOf"])(
51+
"rejects inherited validator name %s as an unknown assertion kind",
52+
(kind) => {
53+
expect(parseMotionSpec({ assertions: [{ kind }] })).toEqual({
54+
ok: false,
55+
errors: [`assertions[0]: unknown assertion kind ${JSON.stringify(kind)}`],
56+
});
57+
},
58+
);
59+
5060
it("reports per-field errors for missing required fields", () => {
5161
const result = parseMotionSpec({
5262
assertions: [
@@ -160,6 +170,22 @@ describe("readMotionSpec", () => {
160170
if (!result.ok) expect(result.errors[0]).toContain("no assertions");
161171
});
162172

173+
it("reports an inherited kind alongside other validation errors from a sidecar", () => {
174+
const dir = tempDir("motion-inherited-");
175+
const path = join(dir, "index.motion.json");
176+
writeFileSync(
177+
path,
178+
JSON.stringify({ assertions: [{ kind: "__proto__" }, { kind: "before", a: "#a" }] }),
179+
);
180+
expect(readMotionSpec(path)).toEqual({
181+
ok: false,
182+
errors: [
183+
'assertions[0]: unknown assertion kind "__proto__"',
184+
'assertions[1] (before): "b" must be a non-empty string',
185+
],
186+
});
187+
});
188+
163189
it("parses a valid sidecar file", () => {
164190
const dir = tempDir("motion-valid-");
165191
const path = join(dir, "main.motion.json");

‎packages/cli/src/utils/motionSpec.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ const VALIDATORS: Record<string, Validator> = {
6969
function validateAssertion(raw: unknown, index: number): MotionAssertion | string {
7070
const at = `assertions[${index}]`;
7171
if (!isObject(raw)) return `${at}: must be an object`;
72-
const validator = typeof raw.kind === "string" ? VALIDATORS[raw.kind] : undefined;
72+
const validator =
73+
typeof raw.kind === "string" && Object.hasOwn(VALIDATORS, raw.kind)
74+
? VALIDATORS[raw.kind]
75+
: undefined;
7376
if (!validator) return `${at}: unknown assertion kind ${JSON.stringify(raw.kind)}`;
7477
return validator(raw, at);
7578
}

0 commit comments

Comments
 (0)