Skip to content
Source
Sign inSign up
Open History to see the last commit

pullRequestComposerTrigger.test.ts

120 lines4.4 KB

1import { describe, expect, it } from "vite-plus/test";
2​
3import {
4 debouncedPullRequestCompletionSearch,
5 detectPullRequestComposerTrigger,
6 insertPullRequestCompletion,
7 narrowPullRequestMentions,
8 narrowPullRequestReferences,
9} from "./pullRequestComposerTrigger.ts";
10​
11const GITLAB = { mentions: true, referenceSigils: ["#", "!"] } as const;
12​
13describe("detectPullRequestComposerTrigger", () => {
14 it.each([
15 ["@", 0, "@", ""],
16 ["cc @ju", 3, "@", "ju"],
17 ["line one\n@first.last", 9, "@", "first.last"],
18 ["@jane-doe more", 0, "@", "jane-doe"],
19 ["fixes #", 6, "#", ""],
20 ["see #12", 4, "#", "12"],
21 ["after !5", 6, "!", "5"],
22 ["#crash", 0, "#", "crash"],
23 ])("finds the trigger in %j", (text, rangeStart, sigil, query) => {
24 const cursor = rangeStart + 1 + query.length;
25 expect(detectPullRequestComposerTrigger(text, cursor, GITLAB)).toEqual({
26 kind: sigil === "@" ? "mention" : "reference",
27 sigil,
28 query,
29 rangeStart,
30 rangeEnd: cursor,
31 });
32 });
33​
34 it.each([
35 ["mail me at jane@example.com", "mail me at jane@example.com".length],
36 ["@jane done", "@jane done".length],
37 ["@-jane", "@-jane".length],
38 ["`@decorator`", "`@decorator".length],
39 ["@jane", 3],
40 ["C#", 2],
41 ["![image", "![image".length],
42 ["## Heading", 2],
43 ])("ignores %j", (text, cursor) => {
44 expect(detectPullRequestComposerTrigger(text, cursor, GITLAB)).toBeNull();
45 });
46​
47 it.each([
48 ["@ju", {}],
49 ["#12", { mentions: true }],
50 ["!important", { mentions: true, referenceSigils: ["#"] }],
51 ["#12", { mentions: true, referenceSigils: [] }],
52 ] as const)("ignores %j on a host that cannot complete it", (text, support) => {
53 expect(detectPullRequestComposerTrigger(text, text.length, support)).toBeNull();
54 });
55});
56​
57describe("insertPullRequestCompletion", () => {
58 it.each(["", "\nnext line", "\r\nnext line"])(
59 "replaces the partial token and adds a space before %j",
60 (suffix) => {
61 const text = `thanks @ju${suffix}`;
62 const trigger = detectPullRequestComposerTrigger(text, "thanks @ju".length, GITLAB)!;
63 expect(insertPullRequestCompletion(text, trigger, "@julius")).toEqual({
64 text: `thanks @julius ${suffix}`,
65 cursor: "thanks @julius ".length,
66 });
67 },
68 );
69​
70 it("reuses the space that already follows and moves past it", () => {
71 const text = "#1 please look";
72 const trigger = detectPullRequestComposerTrigger(text, 2, GITLAB)!;
73 const inserted = insertPullRequestCompletion(text, trigger, "#123");
74 expect(inserted).toEqual({ text: "#123 please look", cursor: "#123 ".length });
75 expect(detectPullRequestComposerTrigger(inserted.text, inserted.cursor, GITLAB)).toBeNull();
76 });
77});
78​
79describe("debouncedPullRequestCompletionSearch", () => {
80 it.each([
81 ["a settled search", { sigil: "#" }, "#crash", "crash"],
82 ["a settled bare sigil", { sigil: "@" }, "@", undefined],
83 ["a lagging search", { sigil: "#" }, "#cra", "cra"],
84 ["the other sigil's key", { sigil: "!" }, "#12", undefined],
85 ["no key yet", { sigil: "#" }, null, undefined],
86 ] as const)("sends %s as the host search", (_, trigger, key, sent) => {
87 expect(debouncedPullRequestCompletionSearch(trigger, key)).toBe(sent);
88 });
89});
90​
91describe("narrowPullRequestMentions", () => {
92 it("matches login or name, case-insensitively, up to the limit", () => {
93 const users = [
94 { login: "TonybynMp4", name: null },
95 { login: "16g", name: "Tom" },
96 { login: "theo", name: "Theo" },
97 ];
98 expect(narrowPullRequestMentions(users, "to", 5).map((u) => u.login)).toEqual([
99 "TonybynMp4",
100 "16g",
101 ]);
102 expect(narrowPullRequestMentions(users, "", 2)).toHaveLength(2);
103 });
104});
105​
106describe("narrowPullRequestReferences", () => {
107 it("keeps the sigil's kind and matches a number prefix or the title", () => {
108 const candidates = [
109 { reference: "#12", number: 12, title: "Crash on start" },
110 { reference: "!12", number: 12, title: "Fix the crash" },
111 { reference: "#3", number: 3, title: "Issue 12 follow-up" },
112 { reference: "#120", number: 120, title: "Docs" },
113 ];
114 const narrowed = (sigil: "#" | "!", query: string) =>
115 narrowPullRequestReferences(candidates, { sigil, query }, 5).map((c) => c.reference);
116 expect(narrowed("#", "12")).toEqual(["#12", "#3", "#120"]);
117 expect(narrowed("!", "CRASH")).toEqual(["!12"]);
118 expect(narrowed("#", "")).toEqual(["#12", "#3", "#120"]);
119 });
120});