@@ -175,3 +175,67 @@ impl From<VersionReq> for OptVersionReq {
175
175
OptVersionReq :: Req ( req)
176
176
}
177
177
}
178
+
179
+ #[ cfg( test) ]
180
+ mod matches_prerelease {
181
+ use super :: OptVersionReq ;
182
+
183
+ #[ test]
184
+ fn prerelease ( ) {
185
+ // As of the writing, this test is not the final semantic of pre-release
186
+ // semver matching. Part of the behavior is buggy. This test just tracks
187
+ // the current behavior of the unstable `--precise <prerelease>`.
188
+ //
189
+ // The below transformation proposed in the RFC is hard to implement
190
+ // outside the semver crate.
191
+ //
192
+ // ```
193
+ // >=1.2.3, <2.0.0 -> >=1.2.3, <2.0.0-0
194
+ // ```
195
+ //
196
+ // The upper bound semantic is also not resolved. So, at least two
197
+ // outstanding issues are required to be fixed before the stabilization:
198
+ //
199
+ // * Bug 1: `x.y.z-pre.0` shouldn't match `x.y.z`.
200
+ // * Upper bound: Whether `>=x.y.z-0, <x.y.z` should match `x.y.z-0`.
201
+ //
202
+ // See the RFC 3493 for the unresolved upper bound issue:
203
+ // https://rust-lang.github.io/rfcs/3493-precise-pre-release-cargo-update.html#version-ranges-with-pre-release-upper-bounds
204
+ let cases = [
205
+ //
206
+ ( "1.2.3" , "1.2.3-0" , true ) , // bug, must be false
207
+ ( "1.2.3" , "1.2.3-1" , true ) , // bug, must be false
208
+ ( "1.2.3" , "1.2.4-0" , true ) ,
209
+ //
210
+ ( ">=1.2.3" , "1.2.3-0" , true ) , // bug, must be false
211
+ ( ">=1.2.3" , "1.2.3-1" , true ) , // bug, must be false
212
+ ( ">=1.2.3" , "1.2.4-0" , true ) ,
213
+ //
214
+ ( ">1.2.3" , "1.2.3-0" , false ) ,
215
+ ( ">1.2.3" , "1.2.3-1" , false ) ,
216
+ ( ">1.2.3" , "1.2.4-0" , true ) ,
217
+ //
218
+ ( ">1.2.3, <1.2.4" , "1.2.3-0" , false ) ,
219
+ ( ">1.2.3, <1.2.4" , "1.2.3-1" , false ) ,
220
+ ( ">1.2.3, <1.2.4" , "1.2.4-0" , false ) , // upper bound semantic
221
+ //
222
+ ( ">=1.2.3, <1.2.4" , "1.2.3-0" , true ) , // bug, must be false
223
+ ( ">=1.2.3, <1.2.4" , "1.2.3-1" , true ) , // bug, must be false
224
+ ( ">=1.2.3, <1.2.4" , "1.2.4-0" , false ) , // upper bound semantic
225
+ //
226
+ ( ">1.2.3, <=1.2.4" , "1.2.3-0" , false ) ,
227
+ ( ">1.2.3, <=1.2.4" , "1.2.3-1" , false ) ,
228
+ ( ">1.2.3, <=1.2.4" , "1.2.4-0" , true ) ,
229
+ //
230
+ ( ">=1.2.3-0, <1.2.3" , "1.2.3-0" , false ) , // upper bound semantic
231
+ ( ">=1.2.3-0, <1.2.3" , "1.2.3-1" , false ) , // upper bound semantic
232
+ ( ">=1.2.3-0, <1.2.3" , "1.2.4-0" , false ) ,
233
+ ] ;
234
+ for ( req, ver, expected) in cases {
235
+ let version_req = req. parse ( ) . unwrap ( ) ;
236
+ let version = ver. parse ( ) . unwrap ( ) ;
237
+ let matched = OptVersionReq :: Req ( version_req) . matches_prerelease ( & version) ;
238
+ assert_eq ! ( expected, matched, "req: {req}; ver: {ver}" ) ;
239
+ }
240
+ }
241
+ }
0 commit comments