mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(studio): a timeline edit on a clip the file lacks says how the clip was looked up (#6661)
* fix(studio): a timeline edit on a clip the file lacks says how the clip was looked up * fix(studio): name only the lookups a missing clip was really found by * refactor(studio): split the missing-clip lookup words into small helpers * refactor(studio): fit the missing-clip lookup words under the no-visible-change size
This commit is contained in:
@@ -414,6 +414,31 @@ describe("persistTimelineBatchEdit", () => {
|
||||
).rejects.toThrow("Unable to patch timeline element ghost in index.html");
|
||||
expect(writes).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("names which lookups a missing clip had, never their values", async () => {
|
||||
stubReadFileContent(SOURCE);
|
||||
// As the timeline builds them: a clip with an id also carries `#id` as its selector.
|
||||
const missing = (element: Partial<TimelineElement>) => {
|
||||
const change = moveMember("ghost", 3, 0, 2);
|
||||
change.element = { ...change.element, ...element };
|
||||
return persistTimelineBatchEdit(batchInput([change], []));
|
||||
};
|
||||
await expect(
|
||||
missing({
|
||||
domId: "intro__hf2",
|
||||
hfId: "hf-zz9q",
|
||||
selector: "#intro__hf2",
|
||||
sourceFile: "compositions/intro.html",
|
||||
}),
|
||||
).rejects.toThrow("(by hf-id, runtime-renamed id; file from the clip)");
|
||||
await expect(missing({ selector: "#ghost" })).rejects.toThrow("(by id; no file on the clip)");
|
||||
await expect(
|
||||
missing({ domId: undefined, selector: ".caption", selectorIndex: 4 }),
|
||||
).rejects.toThrow("(by class; no file on the clip)");
|
||||
await expect(
|
||||
missing({ domId: undefined, selector: '[data-composition-id="intro__hf2"]' }),
|
||||
).rejects.toThrow("(by runtime-renamed composition id; no file on the clip)");
|
||||
});
|
||||
});
|
||||
|
||||
describe("persistTimelineEdit", () => {
|
||||
|
||||
@@ -387,6 +387,20 @@ export function operationChanges(
|
||||
}));
|
||||
}
|
||||
|
||||
const RENAMED_MOUNT = /__hf\d+"?\]?$/;
|
||||
const lookup = (value: string, kind: string) =>
|
||||
RENAMED_MOUNT.test(value) ? `runtime-renamed ${kind}` : kind;
|
||||
const selectorLookup = (selector: string) =>
|
||||
selector.startsWith("[data-composition-id=")
|
||||
? lookup(selector, "composition id")
|
||||
: /^\.[\w-]+$/.test(selector) && "class";
|
||||
|
||||
function missedLookups(element: Pick<TimelineElement, "sourceFile">, target: PatchTarget): string {
|
||||
const kinds = [target.hfId && "hf-id", target.id && lookup(target.id, "id")];
|
||||
const by = [...kinds, target.selector && selectorLookup(target.selector)].filter(Boolean);
|
||||
return `by ${by.join(", ") || "nothing"}; ${element.sourceFile ? "file from the clip" : "no file on the clip"}`;
|
||||
}
|
||||
|
||||
/** Patches each change into `source`, failing loudly on a target the file does not hold. */
|
||||
export function patchTimelineChangesInSource(
|
||||
source: string,
|
||||
@@ -399,7 +413,9 @@ export function patchTimelineChangesInSource(
|
||||
if (!target) throw new Error(`Timeline element ${element.id} is missing a patchable target`);
|
||||
// Resolve first: a member already at its target values patches to the same string, a missing one must throw.
|
||||
if (!findTagByTarget(current, target)) {
|
||||
throw new Error(`Unable to patch timeline element ${element.id} in ${targetPath}`);
|
||||
throw new Error(
|
||||
`Unable to patch timeline element ${element.id} in ${targetPath} (${missedLookups(element, target)})`,
|
||||
);
|
||||
}
|
||||
current = buildPatches(current, target);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user