@@ -68,6 +68,17 @@ describe('semver satisfies', () => {
6868 expect ( satisfies ( '3.5.0' , '>=1.0.0 <2.0.0 || >=3.0.0 <4.0.0' ) ) . toBe ( true ) ;
6969 expect ( satisfies ( '2.5.0' , '>=1.0.0 <2.0.0 || >=3.0.0 <4.0.0' ) ) . toBe ( false ) ;
7070 } ) ;
71+
72+ it ( 'handles major-only bound ranges' , ( ) => {
73+ const range = '>=4.0.0 <6' ;
74+ expect ( satisfies ( '4.0.0' , range ) ) . toBe ( true ) ;
75+ expect ( satisfies ( '4.18.2' , range ) ) . toBe ( true ) ;
76+ expect ( satisfies ( '5.0.0' , range ) ) . toBe ( true ) ;
77+ expect ( satisfies ( '5.99.99' , range ) ) . toBe ( true ) ;
78+ expect ( satisfies ( '3.9.9' , range ) ) . toBe ( false ) ;
79+ expect ( satisfies ( '6.0.0' , range ) ) . toBe ( false ) ;
80+ expect ( satisfies ( '6.0.0-alpha' , range ) ) . toBe ( true ) ;
81+ } ) ;
7182 } ) ;
7283
7384 describe ( 'pre-release versions' , ( ) => {
@@ -119,5 +130,74 @@ describe('semver satisfies', () => {
119130 it ( 'still attempts to match but warns for x-ranges' , ( ) => {
120131 expect ( satisfies ( '1.5.0' , '1.x' ) ) . toBe ( false ) ;
121132 } ) ;
133+
134+ it ( 'warns for hyphen ranges (space-hyphen-space)' , ( ) => {
135+ expect ( satisfies ( '1.5.0' , '1.0.0 - 2.0.0' ) ) . toBe ( false ) ;
136+ } ) ;
137+ } ) ;
138+
139+ describe ( 'version string formats' , ( ) => {
140+ it ( 'accepts an optional v prefix on the version' , ( ) => {
141+ expect ( satisfies ( 'v1.2.3' , '>=1.0.0' ) ) . toBe ( true ) ;
142+ expect ( satisfies ( 'v0.0.1' , '<1.0.0' ) ) . toBe ( true ) ;
143+ expect ( satisfies ( 'v10.20.30' , '>=10.0.0' ) ) . toBe ( true ) ;
144+ } ) ;
145+
146+ it ( 'parses build metadata on versions but not on comparators' , ( ) => {
147+ expect ( satisfies ( '1.0.0+build.1' , '1.0.0' ) ) . toBe ( true ) ;
148+ expect ( satisfies ( '1.0.0+build' , '>=1.0.0' ) ) . toBe ( true ) ;
149+ expect ( satisfies ( '2.0.0+meta' , '>1.0.0' ) ) . toBe ( true ) ;
150+ // Build metadata is not part of `COMPARATOR_REGEXP`; cannot express `1.0.0+foo` as a range bound.
151+ expect ( satisfies ( '1.0.0+githash' , '1.0.0+other' ) ) . toBe ( false ) ;
152+ } ) ;
153+
154+ it ( 'parses prerelease plus build metadata together' , ( ) => {
155+ expect ( satisfies ( '1.0.0-rc.1+exp.sha512' , '>=1.0.0-rc.0' ) ) . toBe ( true ) ;
156+ expect ( satisfies ( '1.0.0-rc.1+exp' , '1.0.0-rc.1' ) ) . toBe ( true ) ;
157+ expect ( satisfies ( '1.0.0-alpha.beta+build' , '<1.0.0' ) ) . toBe ( true ) ;
158+ } ) ;
159+
160+ it ( 'rejects versions that do not match strict semver numeric rules' , ( ) => {
161+ expect ( satisfies ( '01.2.3' , '>=0.0.0' ) ) . toBe ( false ) ;
162+ expect ( satisfies ( '1.02.3' , '>=0.0.0' ) ) . toBe ( false ) ;
163+ expect ( satisfies ( '1.2.03' , '>=0.0.0' ) ) . toBe ( false ) ;
164+ } ) ;
165+
166+ it ( 'rejects missing segments or extra segments' , ( ) => {
167+ expect ( satisfies ( '1.0' , '>=1.0.0' ) ) . toBe ( false ) ;
168+ expect ( satisfies ( '1' , '>=1.0.0' ) ) . toBe ( false ) ;
169+ expect ( satisfies ( '1.0.0.1' , '>=1.0.0' ) ) . toBe ( false ) ;
170+ expect ( satisfies ( '' , '>=1.0.0' ) ) . toBe ( false ) ;
171+ } ) ;
172+ } ) ;
173+
174+ describe ( 'comparator string formats' , ( ) => {
175+ it ( 'accepts an optional v prefix on comparators' , ( ) => {
176+ expect ( satisfies ( '1.5.0' , '>=v1.0.0' ) ) . toBe ( true ) ;
177+ expect ( satisfies ( '1.0.0' , '=v1.0.0' ) ) . toBe ( true ) ;
178+ expect ( satisfies ( '2.0.0' , '>v1.9.9' ) ) . toBe ( true ) ;
179+ expect ( satisfies ( '1.0.0-rc.1' , '>=v1.0.0-alpha' ) ) . toBe ( true ) ;
180+ } ) ;
181+
182+ it ( 'does not support build metadata on comparators (invalid comparator)' , ( ) => {
183+ expect ( satisfies ( '1.0.0' , '>=1.0.0+build' ) ) . toBe ( false ) ;
184+ } ) ;
185+
186+ it ( 'handles multi-part prerelease in comparators' , ( ) => {
187+ expect ( satisfies ( '1.0.0-rc.2' , '>=1.0.0-rc.1' ) ) . toBe ( true ) ;
188+ expect ( satisfies ( '1.0.0' , '>=1.0.0-rc.99' ) ) . toBe ( true ) ;
189+ } ) ;
190+ } ) ;
191+
192+ describe ( 'prerelease ordering (additional cases)' , ( ) => {
193+ it ( 'orders numeric vs non-numeric prerelease identifiers per semver rules' , ( ) => {
194+ // Numeric identifiers have lower precedence than non-numeric (semver 2.0.0).
195+ expect ( satisfies ( '1.0.0-alpha' , '>1.0.0-1' ) ) . toBe ( true ) ;
196+ expect ( satisfies ( '1.0.0-1' , '>1.0.0-alpha' ) ) . toBe ( false ) ;
197+ } ) ;
198+
199+ it ( 'shorter identifier list has lower precedence when shared prefix matches' , ( ) => {
200+ expect ( satisfies ( '1.0.0-alpha.1' , '>1.0.0-alpha' ) ) . toBe ( true ) ;
201+ } ) ;
122202 } ) ;
123203} ) ;
0 commit comments