164 lines · 5.0 KB · TypeScript
RawDownload
import type { FileDiffMetadata } from "@pierre/diffs";import { describe, expect, it } from "vite-plus/test"; import { orderDiffFiles } from "./pullRequestFileOrder.logic"; /** Only the path and the patch's own lines matter here; the viewer fills the rest in. */function file(name: string, additionLines: ReadonlyArray<string> = []): FileDiffMetadata {  return { name, hunks: [], additionLines, deletionLines: [] } as unknown as FileDiffMetadata;} function order(files: ReadonlyArray<FileDiffMetadata>): Array<string> {  return orderDiffFiles(files).map((entry) => entry.name);} describe("orderDiffFiles", () => {  it("places source before tests and generated files across path conventions", () => {    const source = ["src/app.ts", "src/dist.ts", "src/testing.ts"];    const tests = [      "src/__tests__/app.ts",      "src/app.spec.tsx",      "src/app.test.ts",      "test/app.ts",      "tests/helpers/app.ts",    ];    const generated = [      "apps/web/package-lock.json",      "dist/app.js",      "packages/core/vendor/lib.js",      "pnpm-lock.yaml",      "public/app.min.js",      "src/__snapshots__/app.ts",      "src/api.generated.ts",      "src/app.test.ts.snap",    ];    expect(      order([...generated, ...tests, ...source].toReversed().map((path) => file(path))),    ).toEqual([...source, ...tests, ...generated]);  });   it("answers an empty diff with an empty order", () => {    expect(order([])).toEqual([]);  });   it("puts a dependency before what imports it", () => {    expect(order([file("src/a.ts", ['import { b } from "./b";']), file("src/b.ts")])).toEqual([      "src/b.ts",      "src/a.ts",    ]);  });   it("follows a chain the whole way down", () => {    expect(      order([        file("src/a.ts", ['import { b } from "./b";']),        file("src/b.ts", ['import { c } from "./c";']),        file("src/c.ts"),      ]),    ).toEqual(["src/c.ts", "src/b.ts", "src/a.ts"]);  });   it("resolves a specifier that climbs out of the importer's directory", () => {    expect(      order([file("src/ui/a.ts", ['import { b } from "../lib/b";']), file("src/lib/b.ts")]),    ).toEqual(["src/lib/b.ts", "src/ui/a.ts"]);  });   it("resolves a directory specifier to that directory's index file", () => {    expect(      order([file("src/a.ts", ['import { b } from "./lib";']), file("src/lib/index.ts")]),    ).toEqual(["src/lib/index.ts", "src/a.ts"]);  });   it("falls back to the specifier's last segment when the path does not line up", () => {    // An aliased import (`~/lib/b`) resolves to nothing on disk here, but the diff has only one    // file that could be meant.    expect(order([file("src/a.ts", ['import { b } from "~/lib/b";']), file("lib/b.ts")])).toEqual([      "lib/b.ts",      "src/a.ts",    ]);  });   it("ignores an ambiguous last segment rather than guessing", () => {    expect(      order([        file("src/a.ts", ['import { b } from "~/somewhere/b";']),        file("one/b.ts"),        file("two/b.ts"),      ]),    ).toEqual(["one/b.ts", "src/a.ts", "two/b.ts"]);  });   it("resolves a specifier naming an extension, including the .js beside a .ts", () => {    expect(order([file("src/a.ts", ['import { b } from "./b.js";']), file("src/b.ts")])).toEqual([      "src/b.ts",      "src/a.ts",    ]);  });   it("reads require and bare imports too", () => {    expect(      order([        file("src/a.ts", ['const b = require("./b");', 'import "./c";']),        file("src/b.ts"),        file("src/c.ts"),      ]),    ).toEqual(["src/b.ts", "src/c.ts", "src/a.ts"]);  });   it("falls back to path order inside a cycle", () => {    expect(      order([        file("src/b.ts", ['import { a } from "./a";']),        file("src/a.ts", ['import { b } from "./b";']),      ]),    ).toEqual(["src/a.ts", "src/b.ts"]);  });   it("clusters unrelated files by path", () => {    expect(order([file("src/ui/b.ts"), file("src/lib/z.ts"), file("src/lib/a.ts")])).toEqual([      "src/lib/a.ts",      "src/lib/z.ts",      "src/ui/b.ts",    ]);  });   it("keeps the tiers apart and orders tests by the source they cover", () => {    expect(      order([        file("pnpm-lock.yaml"),        file("src/a.test.ts"),        file("src/__tests__/b.ts"),        file("src/a.ts", ['import { b } from "./b";']),        file("src/b.ts"),        file("dist/a.js"),      ]),    ).toEqual([      "src/b.ts",      "src/a.ts",      "src/__tests__/b.ts",      "src/a.test.ts",      "dist/a.js",      "pnpm-lock.yaml",    ]);  });   it("puts a test with no source in the diff after the ones that have theirs", () => {    expect(order([file("src/orphan.spec.ts"), file("src/a.test.ts"), file("src/a.ts")])).toEqual([      "src/a.ts",      "src/a.test.ts",      "src/orphan.spec.ts",    ]);  });   it("orders the same diff the same way whatever order it arrives in", () => {    const files = [      file("src/a.ts", ['import { b } from "./b";']),      file("src/b.ts"),      file("src/c.ts"),      file("src/a.test.ts"),      file("yarn.lock"),    ];    expect(order(files)).toEqual(order(files.toReversed()));  });});