@@ -111,6 +111,19 @@ livekit-agents = ">=1.0.0"`,
111111 expectError : true ,
112112 errorMsg : "too old" ,
113113 },
114+ {
115+ name : "Node package.json with good version" ,
116+ projectType : ProjectTypeNode ,
117+ setupFiles : map [string ]string {
118+ "package.json" : `{
119+ "dependencies": {
120+ "@livekit/agents": "^1.1.1"
121+ }
122+ }` ,
123+ },
124+ expectError : false ,
125+ },
126+
114127 {
115128 name : "Node package-lock.json with valid version" ,
116129 projectType : ProjectTypeNode ,
@@ -207,19 +220,24 @@ func TestIsVersionSatisfied(t *testing.T) {
207220 {"0.9.0" , "1.0.0" , SourceTypeLock , false , false },
208221 {"1.5.0" , "2.0.0" , SourceTypeLock , false , false },
209222 {"2.0.0" , "2.0.0" , SourceTypeLock , true , false },
210-
223+
211224 // Package file tests (constraint satisfaction)
212225 {">=1.5.0" , "1.0.0" , SourceTypePackage , true , false },
213226 {"<2.0.0" , "1.0.0" , SourceTypePackage , true , false },
214227 {">=2.0.0" , "1.0.0" , SourceTypePackage , true , false },
215228 {"~1.2.0" , "1.0.0" , SourceTypePackage , true , false },
216229 {"^1.0.0" , "1.0.0" , SourceTypePackage , true , false },
217-
230+ // Test the specific case that was failing: ^0.7.9 should satisfy minimum 0.0.7
231+ {"^0.7.9" , "0.0.7" , SourceTypePackage , true , false },
232+ // Test other caret scenarios
233+ {"^0.5.0" , "0.0.7" , SourceTypePackage , true , false }, // ^0.5.0 allows 0.5.0+ which >= 0.0.7
234+ {"^1.0.0" , "0.0.7" , SourceTypePackage , true , false }, // 1.0.0+ >= 0.0.7
235+
218236 // Special cases
219237 {"latest" , "1.0.0" , SourceTypeLock , true , false },
220238 {"*" , "1.0.0" , SourceTypeLock , true , false },
221239 {"" , "1.0.0" , SourceTypeLock , true , false },
222-
240+
223241 // Error cases
224242 {"invalid" , "1.0.0" , SourceTypeLock , false , true },
225243 {"1.5.0" , "invalid" , SourceTypeLock , false , true },
@@ -251,25 +269,45 @@ func TestIsVersionSatisfied(t *testing.T) {
251269
252270func TestNormalizeVersion (t * testing.T ) {
253271 tests := []struct {
254- input string
255- expected string
272+ input string
273+ sourceType SourceType
274+ expected string
275+ description string
256276 }{
257- {"1.5.0" , "1.5.0" },
258- {"^1.5.0" , "1.5.0" },
259- {"~1.5.0" , "1.5.0" },
260- {">=1.5.0" , ">=1.5.0" },
261- {"<2.0.0" , "<2.0.0" },
262- {"==1.5.0" , "==1.5.0" },
263- {" 1.5.0 " , "1.5.0" },
264- {`"1.5.0"` , "1.5.0" },
265- {`'1.5.0'` , "1.5.0" },
266- {"*" , "*" },
267- {"latest" , "latest" },
277+ // Lock file tests (should remove ^ and ~)
278+ {"1.5.0" , SourceTypeLock , "1.5.0" , "exact version" },
279+ {"^1.5.0" , SourceTypeLock , "1.5.0" , "npm caret removed for lock file" },
280+ {"~1.5.0" , SourceTypeLock , "1.5.0" , "npm tilde removed for lock file" },
281+ {">=1.5.0" , SourceTypeLock , ">=1.5.0" , "semver operators preserved for lock file" },
282+ {"<2.0.0" , SourceTypeLock , "<2.0.0" , "semver operators preserved for lock file" },
283+ {"==1.5.0" , SourceTypeLock , "==1.5.0" , "semver operators preserved for lock file" },
284+ {" 1.5.0 " , SourceTypeLock , "1.5.0" , "whitespace removed" },
285+ {`"1.5.0"` , SourceTypeLock , "1.5.0" , "quotes removed" },
286+ {`'1.5.0'` , SourceTypeLock , "1.5.0" , "quotes removed" },
287+ {"*" , SourceTypeLock , "*" , "wildcard preserved" },
288+ {"latest" , SourceTypeLock , "latest" , "latest preserved" },
289+
290+ // Package file tests (should preserve ^ and ~)
291+ {"1.5.0" , SourceTypePackage , "1.5.0" , "exact version" },
292+ {"^1.5.0" , SourceTypePackage , "^1.5.0" , "npm caret preserved for package file" },
293+ {"~1.5.0" , SourceTypePackage , "~1.5.0" , "npm tilde preserved for package file" },
294+ {">=1.5.0" , SourceTypePackage , ">=1.5.0" , "semver operators preserved for package file" },
295+ {"<2.0.0" , SourceTypePackage , "<2.0.0" , "semver operators preserved for package file" },
296+ {"==1.5.0" , SourceTypePackage , "==1.5.0" , "semver operators preserved for package file" },
297+ {" 1.5.0 " , SourceTypePackage , "1.5.0" , "whitespace removed" },
298+ {`"1.5.0"` , SourceTypePackage , "1.5.0" , "quotes removed" },
299+ {`'1.5.0'` , SourceTypePackage , "1.5.0" , "quotes removed" },
300+ {"*" , SourceTypePackage , "*" , "wildcard preserved" },
301+ {"latest" , SourceTypePackage , "latest" , "latest preserved" },
268302 }
269303
270304 for _ , tt := range tests {
271- t .Run (tt .input , func (t * testing.T ) {
272- result := normalizeVersion (tt .input )
305+ sourceTypeStr := "Package"
306+ if tt .sourceType == SourceTypeLock {
307+ sourceTypeStr = "Lock"
308+ }
309+ t .Run (fmt .Sprintf ("%s_%s_%s" , tt .input , sourceTypeStr , tt .description ), func (t * testing.T ) {
310+ result := normalizeVersion (tt .input , tt .sourceType )
273311 if result != tt .expected {
274312 t .Errorf ("Expected %s but got %s" , tt .expected , result )
275313 }
0 commit comments