This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / repo / DiffView.stories.svelte
4.9 kB 139 lines
1<script module lang="ts"> 2 import { defineMeta, type StoryContext } from "@storybook/addon-svelte-csf"; 3 import { expect, waitFor } from "storybook/test"; 4 import type { DiffFile } from "$lib/api/diff"; 5 import DiffView from "./DiffView.svelte"; 6 7 const textFile: DiffFile = { 8 name: { old: "src/colors.ts", new: "src/colors.ts" }, 9 text_fragments: [ 10 { 11 OldPosition: 1, 12 OldLines: 3, 13 NewPosition: 1, 14 NewLines: 4, 15 LinesAdded: 2, 16 LinesDeleted: 1, 17 Lines: [ 18 { Op: 0, Line: "export const palette = {\n" }, 19 { Op: 1, Line: '\tbackground: "white",\n' }, 20 { Op: 2, Line: '\tbackground: "oklch(0.98 0 0)",\n' }, 21 { Op: 2, Line: '\tforeground: "oklch(0.2 0 0)",\n' }, 22 { Op: 0, Line: "};\n" } 23 ] 24 } 25 ] 26 }; 27 28 const binaryFile: DiffFile = { 29 name: { old: "assets/logo.png", new: "assets/logo.png" }, 30 is_binary: true 31 }; 32 33 const downloadUrls = { 34 patch: "/dawn/tangled/commit/0123456789abcdef0123456789abcdef01234567.patch", 35 diff: "/dawn/tangled/commit/0123456789abcdef0123456789abcdef01234567.diff" 36 }; 37 38 const blobBase = "/dawn/tangled/blob/0123456789abcdef0123456789abcdef01234567"; 39 40 type PlayContext = Pick< 41 StoryContext<Record<string, unknown>>, 42 "canvas" | "canvasElement" | "userEvent" 43 >; 44 45 // pierre renders inside a shadow root, diff content is invisible to canvas 46 const shadowText = (canvasElement: HTMLElement) => 47 [...canvasElement.querySelectorAll("diffs-container")] 48 .map((host) => host.shadowRoot?.textContent ?? "") 49 .join("\n"); 50 51 const hasSplitColumns = (canvasElement: HTMLElement) => 52 [...canvasElement.querySelectorAll("diffs-container")].some( 53 (host) => 54 host.shadowRoot?.querySelector("[data-deletions]") && 55 host.shadowRoot?.querySelector("[data-additions]") 56 ); 57 58 // the per-file cards, excluding the file tree's directory <details> 59 const fileCards = (canvasElement: HTMLElement) => [ 60 ...canvasElement.querySelectorAll<HTMLDetailsElement>("details[id^='file-']") 61 ]; 62 63 const mixedFiles = async ({ canvas, canvasElement, userEvent }: PlayContext) => { 64 await expect(canvas.getAllByText("+2")).toHaveLength(2); 65 await expect(canvas.getAllByText("-1")).toHaveLength(2); 66 await expect(canvas.getByText("2 changed files")).toBeVisible(); 67 68 await expect(canvas.getByText("src/colors.ts")).toBeVisible(); 69 await waitFor(() => expect(shadowText(canvasElement)).toContain("palette")); 70 expect(shadowText(canvasElement)).not.toContain("src/colors.ts"); 71 expect(hasSplitColumns(canvasElement)).toBe(false); 72 73 await expect(canvas.getByText("assets/logo.png")).toBeVisible(); 74 await expect( 75 canvas.getByText("This is a binary file and will not be displayed.") 76 ).toBeVisible(); 77 expect(shadowText(canvasElement)).not.toContain("assets/logo.png"); 78 79 await expect(canvas.getByRole("link", { name: "colors.ts" })).toHaveAttribute( 80 "href", 81 "#file-src/colors.ts" 82 ); 83 84 await expect(canvas.getByRole("link", { name: ".patch" })).toHaveAttribute( 85 "href", 86 downloadUrls.patch 87 ); 88 await expect(canvas.getByRole("link", { name: "Split diff" })).toHaveAttribute( 89 "href", 90 "?diff=split" 91 ); 92 await expect(canvas.getByRole("link", { name: "Unified diff" })).toHaveAttribute( 93 "href", 94 "?diff=unified" 95 ); 96 97 expect(fileCards(canvasElement).every((card) => card.open)).toBe(true); 98 const firstCard = fileCards(canvasElement)[0]; 99 await userEvent.click(firstCard.querySelector("summary")!); 100 expect(firstCard.open).toBe(false); 101 expect(fileCards(canvasElement)[1].open).toBe(true); 102 103 await userEvent.click(canvas.getByRole("button", { name: "Expand all" })); 104 expect(fileCards(canvasElement).every((card) => card.open)).toBe(true); 105 await userEvent.click(canvas.getByRole("button", { name: "Collapse all" })); 106 expect(fileCards(canvasElement).every((card) => !card.open)).toBe(true); 107 }; 108 109 const splitView = async ({ canvasElement }: PlayContext) => { 110 await waitFor(() => expect(shadowText(canvasElement)).toContain("palette")); 111 await waitFor(() => expect(hasSplitColumns(canvasElement)).toBe(true)); 112 }; 113 114 const viewFileLinks = async ({ canvas }: PlayContext) => { 115 const links = canvas.getAllByRole("link", { name: "View file" }); 116 await expect(links).toHaveLength(2); 117 await expect(links[0]).toHaveAttribute("href", `${blobBase}/src/colors.ts`); 118 await expect(links[1]).toHaveAttribute("href", `${blobBase}/assets/logo.png`); 119 }; 120 121 const { Story } = defineMeta({ 122 title: "Repo/DiffView", 123 component: DiffView, 124 tags: ["autodocs"], 125 args: { 126 files: [textFile, binaryFile], 127 stat: { insertions: 2, deletions: 1, files_changed: 2 }, 128 downloadUrls 129 } 130 }); 131</script> 132 133<Story name="Mixed text and binary" play={mixedFiles} /> 134 135<Story name="Split" args={{ diffStyle: "split" }} play={splitView} /> 136 137<Story name="With blob base" args={{ blobBase }} play={viewFileLinks} /> 138 139<Story name="No downloads" args={{ downloadUrls: undefined }} />