1+ import { describe , it , expect } from 'vitest' ;
2+ import { getBrowseParamsFromPathParam } from './utils' ;
3+
4+ describe ( 'getBrowseParamsFromPathParam' , ( ) => {
5+ describe ( 'tree paths' , ( ) => {
6+ it ( 'should parse tree path with trailing slash' , ( ) => {
7+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/tree/' ) ;
8+ expect ( result ) . toEqual ( {
9+ repoName : 'github.com/sourcebot-dev/zoekt' ,
10+ revisionName : 'HEAD' ,
11+ path : '' ,
12+ pathType : 'tree' ,
13+ } ) ;
14+ } ) ;
15+
16+ it ( 'should parse tree path without trailing slash' , ( ) => {
17+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/tree' ) ;
18+ expect ( result ) . toEqual ( {
19+ repoName : 'github.com/sourcebot-dev/zoekt' ,
20+ revisionName : 'HEAD' ,
21+ path : '' ,
22+ pathType : 'tree' ,
23+ } ) ;
24+ } ) ;
25+
26+ it ( 'should parse tree path with nested directory' , ( ) => {
27+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/tree/packages/web/src' ) ;
28+ expect ( result ) . toEqual ( {
29+ repoName : 'github.com/sourcebot-dev/zoekt' ,
30+ revisionName : 'HEAD' ,
31+ path : 'packages/web/src' ,
32+ pathType : 'tree' ,
33+ } ) ;
34+ } ) ;
35+
36+ it ( 'should parse tree path without revision' , ( ) => {
37+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt/-/tree/docs' ) ;
38+ expect ( result ) . toEqual ( {
39+ repoName : 'github.com/sourcebot-dev/zoekt' ,
40+ revisionName : undefined ,
41+ path : 'docs' ,
42+ pathType : 'tree' ,
43+ } ) ;
44+ } ) ;
45+ } ) ;
46+
47+ describe ( 'blob paths' , ( ) => {
48+
49+
50+ it ( 'should parse blob path with file' , ( ) => {
51+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/blob/README.md' ) ;
52+ expect ( result ) . toEqual ( {
53+ repoName : 'github.com/sourcebot-dev/zoekt' ,
54+ revisionName : 'HEAD' ,
55+ path : 'README.md' ,
56+ pathType : 'blob' ,
57+ } ) ;
58+ } ) ;
59+
60+ it ( 'should parse blob path with nested file' , ( ) => {
61+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/blob/packages/web/src/app/page.tsx' ) ;
62+ expect ( result ) . toEqual ( {
63+ repoName : 'github.com/sourcebot-dev/zoekt' ,
64+ revisionName : 'HEAD' ,
65+ path : 'packages/web/src/app/page.tsx' ,
66+ pathType : 'blob' ,
67+ } ) ;
68+ } ) ;
69+
70+ it ( 'should parse blob path without revision' , ( ) => {
71+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt/-/blob/main.go' ) ;
72+ expect ( result ) . toEqual ( {
73+ repoName : 'github.com/sourcebot-dev/zoekt' ,
74+ revisionName : undefined ,
75+ path : 'main.go' ,
76+ pathType : 'blob' ,
77+ } ) ;
78+ } ) ;
79+ } ) ;
80+
81+ describe ( 'URL decoding' , ( ) => {
82+ it ( 'should decode URL-encoded spaces in path' , ( ) => {
83+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/tree/folder%20with%20spaces' ) ;
84+ expect ( result ) . toEqual ( {
85+ repoName : 'github.com/sourcebot-dev/zoekt' ,
86+ revisionName : 'HEAD' ,
87+ path : 'folder with spaces' ,
88+ pathType : 'tree' ,
89+ } ) ;
90+ } ) ;
91+
92+ it ( 'should decode URL-encoded special characters in path' , ( ) => {
93+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/blob/file%20with%20%26%20symbols.txt' ) ;
94+ expect ( result ) . toEqual ( {
95+ repoName : 'github.com/sourcebot-dev/zoekt' ,
96+ revisionName : 'HEAD' ,
97+ path : 'file with & symbols.txt' ,
98+ pathType : 'blob' ,
99+ } ) ;
100+ } ) ;
101+ } ) ;
102+
103+ describe ( 'different revision formats' , ( ) => {
104+ it ( 'should parse with branch name' , ( ) => {
105+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@main/-/tree/' ) ;
106+ expect ( result ) . toEqual ( {
107+ repoName : 'github.com/sourcebot-dev/zoekt' ,
108+ revisionName : 'main' ,
109+ path : '' ,
110+ pathType : 'tree' ,
111+ } ) ;
112+ } ) ;
113+
114+ it ( 'should parse with commit hash' , ( ) => {
115+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@a1b2c3d/-/tree/' ) ;
116+ expect ( result ) . toEqual ( {
117+ repoName : 'github.com/sourcebot-dev/zoekt' ,
118+ revisionName : 'a1b2c3d' ,
119+ path : '' ,
120+ pathType : 'tree' ,
121+ } ) ;
122+ } ) ;
123+
124+ it ( 'should parse with tag' , ( ) => {
125+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@v1.0.0/-/tree/' ) ;
126+ expect ( result ) . toEqual ( {
127+ repoName : 'github.com/sourcebot-dev/zoekt' ,
128+ revisionName : 'v1.0.0' ,
129+ path : '' ,
130+ pathType : 'tree' ,
131+ } ) ;
132+ } ) ;
133+ } ) ;
134+
135+ describe ( 'edge cases' , ( ) => {
136+ it ( 'should handle repo name with multiple @ symbols' , ( ) => {
137+ const result = getBrowseParamsFromPathParam ( 'gitlab.com/user@domain/repo@main/-/tree/' ) ;
138+ expect ( result ) . toEqual ( {
139+ repoName : 'gitlab.com/user@domain/repo' ,
140+ revisionName : 'main' ,
141+ path : '' ,
142+ pathType : 'tree' ,
143+ } ) ;
144+ } ) ;
145+
146+ it ( 'should handle paths with @ symbols' , ( ) => {
147+ const result = getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/blob/file@v1.0.0.txt' ) ;
148+ expect ( result ) . toEqual ( {
149+ repoName : 'github.com/sourcebot-dev/zoekt' ,
150+ revisionName : 'HEAD' ,
151+ path : 'file@v1.0.0.txt' ,
152+ pathType : 'blob' ,
153+ } ) ;
154+ } ) ;
155+ } ) ;
156+
157+ describe ( 'error cases' , ( ) => {
158+ it ( 'should throw error for blob path with trailing slash and no path' , ( ) => {
159+ expect ( ( ) => {
160+ getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/blob/' ) ;
161+ } ) . toThrow ( ) ;
162+ } ) ;
163+
164+ it ( 'should throw error for blob path without trailing slash and no path' , ( ) => {
165+ expect ( ( ) => {
166+ getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/blob' ) ;
167+ } ) . toThrow ( ) ;
168+ } ) ;
169+
170+ it ( 'should throw error for invalid pattern - missing /-/' , ( ) => {
171+ expect ( ( ) => {
172+ getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/tree/' ) ;
173+ } ) . toThrow ( ) ;
174+ } ) ;
175+
176+ it ( 'should throw error for invalid pattern - missing tree/blob' , ( ) => {
177+ expect ( ( ) => {
178+ getBrowseParamsFromPathParam ( 'github.com/sourcebot-dev/zoekt@HEAD/-/invalid/' ) ;
179+ } ) . toThrow ( ) ;
180+ } ) ;
181+
182+ it ( 'should throw error for completely invalid format' , ( ) => {
183+ expect ( ( ) => {
184+ getBrowseParamsFromPathParam ( 'invalid-path' ) ;
185+ } ) . toThrow ( ) ;
186+ } ) ;
187+
188+ it ( 'should throw error for empty string' , ( ) => {
189+ expect ( ( ) => {
190+ getBrowseParamsFromPathParam ( '' ) ;
191+ } ) . toThrow ( ) ;
192+ } ) ;
193+ } ) ;
194+ } ) ;
0 commit comments