2
0

wildcard.test.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { test, expect } from "bun:test"
  2. import { Wildcard } from "../../src/util/wildcard"
  3. test("match handles glob tokens", () => {
  4. expect(Wildcard.match("file1.txt", "file?.txt")).toBe(true)
  5. expect(Wildcard.match("file12.txt", "file?.txt")).toBe(false)
  6. expect(Wildcard.match("foo+bar", "foo+bar")).toBe(true)
  7. })
  8. test("match with trailing space+wildcard matches command with or without args", () => {
  9. // "ls *" should match "ls" (no args) and "ls -la" (with args)
  10. expect(Wildcard.match("ls", "ls *")).toBe(true)
  11. expect(Wildcard.match("ls -la", "ls *")).toBe(true)
  12. expect(Wildcard.match("ls foo bar", "ls *")).toBe(true)
  13. // "ls*" (no space) should NOT match "ls" alone — wait, it should because .* matches empty
  14. // but it WILL match "lstmeval" which is the dangerous case users should avoid
  15. expect(Wildcard.match("ls", "ls*")).toBe(true)
  16. expect(Wildcard.match("lstmeval", "ls*")).toBe(true)
  17. // "ls *" (with space) should NOT match "lstmeval"
  18. expect(Wildcard.match("lstmeval", "ls *")).toBe(false)
  19. // multi-word commands
  20. expect(Wildcard.match("git status", "git *")).toBe(true)
  21. expect(Wildcard.match("git", "git *")).toBe(true)
  22. expect(Wildcard.match("git commit -m foo", "git *")).toBe(true)
  23. })
  24. test("all picks the most specific pattern", () => {
  25. const rules = {
  26. "*": "deny",
  27. "git *": "ask",
  28. "git status": "allow",
  29. }
  30. expect(Wildcard.all("git status", rules)).toBe("allow")
  31. expect(Wildcard.all("git log", rules)).toBe("ask")
  32. expect(Wildcard.all("echo hi", rules)).toBe("deny")
  33. })
  34. test("allStructured matches command sequences", () => {
  35. const rules = {
  36. "git *": "ask",
  37. "git status*": "allow",
  38. }
  39. expect(Wildcard.allStructured({ head: "git", tail: ["status", "--short"] }, rules)).toBe("allow")
  40. expect(Wildcard.allStructured({ head: "npm", tail: ["run", "build", "--watch"] }, { "npm run *": "allow" })).toBe(
  41. "allow",
  42. )
  43. expect(Wildcard.allStructured({ head: "ls", tail: ["-la"] }, rules)).toBeUndefined()
  44. })
  45. test("allStructured prioritizes flag-specific patterns", () => {
  46. const rules = {
  47. "find *": "allow",
  48. "find * -delete*": "ask",
  49. "sort*": "allow",
  50. "sort -o *": "ask",
  51. }
  52. expect(Wildcard.allStructured({ head: "find", tail: ["src", "-delete"] }, rules)).toBe("ask")
  53. expect(Wildcard.allStructured({ head: "find", tail: ["src", "-print"] }, rules)).toBe("allow")
  54. expect(Wildcard.allStructured({ head: "sort", tail: ["-o", "out.txt"] }, rules)).toBe("ask")
  55. expect(Wildcard.allStructured({ head: "sort", tail: ["--reverse"] }, rules)).toBe("allow")
  56. })
  57. test("allStructured handles sed flags", () => {
  58. const rules = {
  59. "sed * -i*": "ask",
  60. "sed -n*": "allow",
  61. }
  62. expect(Wildcard.allStructured({ head: "sed", tail: ["-i", "file"] }, rules)).toBe("ask")
  63. expect(Wildcard.allStructured({ head: "sed", tail: ["-i.bak", "file"] }, rules)).toBe("ask")
  64. expect(Wildcard.allStructured({ head: "sed", tail: ["-n", "1p", "file"] }, rules)).toBe("allow")
  65. expect(Wildcard.allStructured({ head: "sed", tail: ["-i", "-n", "/./p", "myfile.txt"] }, rules)).toBe("ask")
  66. })