1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
local Purl = require "mason-core.purl"
local Result = require "mason-core.result"
describe("purl", function()
it("should parse well-formed PURLs", function()
assert.same(
Result.success {
name = "rust-analyzer",
namespace = "rust-lang",
qualifiers = {
target = "linux_x64_gnu",
download_url = "https://github.com/rust-lang/rust-analyzer/releases/download/2022-11-28/rust-analyzer-x86_64-unknown-linux-gnu.gz",
},
scheme = "pkg",
type = "github",
version = "2022-11-28",
subpath = "bin/rust-analyzer",
},
Purl.parse "pkg:github/rust-lang/rust-analyzer@2022-11-28?target=linux_x64_gnu&download_url=https://github.com/rust-lang/rust-analyzer/releases/download/2022-11-28/rust-analyzer-x86_64-unknown-linux-gnu.gz#bin/rust-analyzer"
)
assert.same(
Result.success {
scheme = "pkg",
type = "github",
namespace = "rust-lang",
name = "rust-analyzer",
version = "2025-04-20",
qualifiers = nil,
subpath = nil,
},
Purl.parse "pkg:github/rust-lang/rust-analyzer@2025-04-20"
)
assert.same(
Result.success {
scheme = "pkg",
type = "npm",
namespace = nil,
name = "typescript-language-server",
version = "10.23.1",
qualifiers = nil,
subpath = nil,
},
Purl.parse "pkg:npm/typescript-language-server@10.23.1"
)
assert.same(
Result.success {
scheme = "pkg",
type = "pypi",
namespace = nil,
name = "python-language-server",
version = nil,
qualifiers = nil,
subpath = nil,
},
Purl.parse "pkg:pypi/python-language-server"
)
assert.same(
Result.success {
name = "cli",
namespace = "@angular",
scheme = "pkg",
type = "npm",
},
Purl.parse "pkg:npm/%40angular/cli"
)
end)
it("should fail to parse invalid PURLs", function()
assert.same(Result.failure "Malformed purl (invalid scheme).", Purl.parse "scam:github/react@18.0.0")
end)
it("should treat percent-encoded components as case insensitive", function()
local purl = {
name = "sonarlint-vscode",
namespace = "sonarsource",
scheme = "pkg",
type = "github",
version = "3.18.0+70423" .. string.char(0xab),
}
assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2b70423%ab")
assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2B70423%aB")
assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2b70423%AB")
assert.same(Result.success(purl), Purl.parse "pkg:github/SonarSource/sonarlint-vscode@3.18.0%2B70423%Ab")
end)
end)
describe("purl test suite ::", function()
local fs = require "mason-core.fs"
---@type { description: string, purl: string, type: string?, namespace: string, name: string?, version: string?, is_invalid: boolean, canonical_purl: string }[]
local test_fixture = vim.json.decode(fs.sync.read_file "./tests/fixtures/purl-test-suite-data.json")
local function not_vim_nil(val)
if val == vim.NIL then
return nil
else
return val
end
end
for _, test in ipairs(test_fixture) do
it(test.description, function()
local result = Purl.parse(test.purl)
if test.is_invalid then
assert.is_true(result:is_failure())
else
assert.same(
Result.success {
scheme = "pkg",
type = not_vim_nil(test.type),
namespace = not_vim_nil(test.namespace),
name = not_vim_nil(test.name),
version = not_vim_nil(test.version),
qualifiers = not_vim_nil(test.qualifiers),
subpath = not_vim_nil(test.subpath),
},
result
)
assert.equals(test.canonical_purl, Purl.compile(result:get_or_throw()))
end
end)
end
end)
|