[GH-ISSUE #833] A list of examples with proper precedence to help writing unit tests. #3260

Open
opened 2026-04-25 17:36:12 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @NikolaiRuhe on GitHub (May 10, 2022).
Original GitHub issue: https://github.com/semver/semver/issues/833

Implementing a SemVer type is somewhat complex. This is mostly due to some subtle precedence rules.

To help with that it would be great to have a list of version strings to be used in unit tests. Ideally there would be...

  • a table of valid strings
  • a table of invalid strings
  • a table of valid string pairs (in order of precedence)

These test tables should cover various edge cases and are designed to detect flaws in the implementation.

To illustrate what I mean I'll add some of my own tests (from a Swift implementation of SemVer):

// valid
"1.2.3--"
"1.2.3--.-.-"
"1.2.3-----"
"1.2.3-4.3.2.1"
"1.2.3--1.-.abc+000001.-2.3e7"

// invalid
"1.2.3-00"
"1.2.3-01"
"1.2.3-.1"
"1.2.3-a."
"1.2.3-..."
"1️⃣.2.3"
"⒈2.3"
"⒈.2.3"
"①.2.3"
"𝟷.2.3"
"².2.3"
"₂.2.3"

// precedence
"0.9.99"           < "1.0.0"
"0.9.0"            < "0.10.0"
"1.0.0-0.0"        < "1.0.0-0.0.0"
"1.0.0-9999"       < "1.0.0--"
"1.0.0-99"         < "1.0.0-100"
"1.0.0-alpha"      < "1.0.0-alpha.1"
"1.0.0-alpha.1"    < "1.0.0-alpha.beta"
"1.0.0-alpha.beta" < "1.0.0-beta"
"1.0.0-beta"       < "1.0.0-beta.2"
"1.0.0-beta.2"     < "1.0.0-beta.11"
"1.0.0-beta.11"    < "1.0.0-rc.1"
"1.0.0-rc.1"       < "1.0.0"
"1.0.0-0"          < "1.0.0--1"
"1.0.0-0"          < "1.0.0-1"
"1.0.0-1.0"        < "1.0.0-1.-1"

// equivalence
"1.0.0"           == "1.0.0+a"
Originally created by @NikolaiRuhe on GitHub (May 10, 2022). Original GitHub issue: https://github.com/semver/semver/issues/833 Implementing a `SemVer` type is somewhat complex. This is mostly due to some subtle precedence rules. To help with that it would be great to have a list of version strings to be used in unit tests. Ideally there would be... - a table of valid strings - a table of invalid strings - a table of valid string pairs (in order of precedence) These test tables should cover various edge cases and are designed to detect flaws in the implementation. To illustrate what I mean I'll add some of my own tests (from a Swift implementation of SemVer): ``` // valid "1.2.3--" "1.2.3--.-.-" "1.2.3-----" "1.2.3-4.3.2.1" "1.2.3--1.-.abc+000001.-2.3e7" // invalid "1.2.3-00" "1.2.3-01" "1.2.3-.1" "1.2.3-a." "1.2.3-..." "1️⃣.2.3" "⒈2.3" "⒈.2.3" "①.2.3" "𝟷.2.3" "².2.3" "₂.2.3" // precedence "0.9.99" < "1.0.0" "0.9.0" < "0.10.0" "1.0.0-0.0" < "1.0.0-0.0.0" "1.0.0-9999" < "1.0.0--" "1.0.0-99" < "1.0.0-100" "1.0.0-alpha" < "1.0.0-alpha.1" "1.0.0-alpha.1" < "1.0.0-alpha.beta" "1.0.0-alpha.beta" < "1.0.0-beta" "1.0.0-beta" < "1.0.0-beta.2" "1.0.0-beta.2" < "1.0.0-beta.11" "1.0.0-beta.11" < "1.0.0-rc.1" "1.0.0-rc.1" < "1.0.0" "1.0.0-0" < "1.0.0--1" "1.0.0-0" < "1.0.0-1" "1.0.0-1.0" < "1.0.0-1.-1" // equivalence "1.0.0" == "1.0.0+a" ```
Author
Owner

@jwdonahue commented on GitHub (May 11, 2022):

Look for the thread(s) where we honed the example regex. You should find some valid and invalid examples.

<!-- gh-comment-id:1123200316 --> @jwdonahue commented on GitHub (May 11, 2022): Look for the thread(s) where we honed the example regex. You should find some valid and invalid examples.
Author
Owner

@mark-wiemer commented on GitHub (Jul 18, 2022):

See https://regex101.com/r/vkijKf/1/. Not in precedence order, but otherwise a pretty good list.

Valid Semantic Versions

0.0.4
1.2.3
10.20.30
1.1.2-prerelease+meta
1.1.2+meta
1.1.2+meta-valid
1.0.0-alpha
1.0.0-beta
1.0.0-alpha.beta
1.0.0-alpha.beta.1
1.0.0-alpha.1
1.0.0-alpha0.valid
1.0.0-alpha.0valid
1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay
1.0.0-rc.1+build.1
2.0.0-rc.1+build.123
1.2.3-beta
10.2.3-DEV-SNAPSHOT
1.2.3-SNAPSHOT-123
1.0.0
2.0.0
1.1.7
2.0.0+build.1848
2.0.1-alpha.1227
1.0.0-alpha+beta
1.2.3----RC-SNAPSHOT.12.9.1--.12+788
1.2.3----R-S.12.9.1--.12+meta
1.2.3----RC-SNAPSHOT.12.9.1--.12
1.0.0+0.build.1-rc.10000aaa-kk-0.1
99999999999999999999999.999999999999999999.99999999999999999
1.0.0-0A.is.legal


Invalid Semantic Versions

1
1.2
1.2.3-0123
1.2.3-0123.0123
1.1.2+.123
+invalid
-invalid
-invalid+invalid
-invalid.01
alpha
alpha.beta
alpha.beta.1
alpha.1
alpha+beta
alpha_beta
alpha.
alpha..
beta
1.0.0-alpha_beta
-alpha.
1.0.0-alpha..
1.0.0-alpha..1
1.0.0-alpha...1
1.0.0-alpha....1
1.0.0-alpha.....1
1.0.0-alpha......1
1.0.0-alpha.......1
01.1.1
1.01.1
1.1.01
1.2
1.2.3.DEV
1.2-SNAPSHOT
1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788
1.2-RC-SNAPSHOT
-1.0.3-gamma+b7718
+justmeta
9.8.7+meta+meta
9.8.7-whatever+meta+meta
99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12
<!-- gh-comment-id:1186845563 --> @mark-wiemer commented on GitHub (Jul 18, 2022): See https://regex101.com/r/vkijKf/1/. Not in precedence order, but otherwise a pretty good list. ``` Valid Semantic Versions 0.0.4 1.2.3 10.20.30 1.1.2-prerelease+meta 1.1.2+meta 1.1.2+meta-valid 1.0.0-alpha 1.0.0-beta 1.0.0-alpha.beta 1.0.0-alpha.beta.1 1.0.0-alpha.1 1.0.0-alpha0.valid 1.0.0-alpha.0valid 1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay 1.0.0-rc.1+build.1 2.0.0-rc.1+build.123 1.2.3-beta 10.2.3-DEV-SNAPSHOT 1.2.3-SNAPSHOT-123 1.0.0 2.0.0 1.1.7 2.0.0+build.1848 2.0.1-alpha.1227 1.0.0-alpha+beta 1.2.3----RC-SNAPSHOT.12.9.1--.12+788 1.2.3----R-S.12.9.1--.12+meta 1.2.3----RC-SNAPSHOT.12.9.1--.12 1.0.0+0.build.1-rc.10000aaa-kk-0.1 99999999999999999999999.999999999999999999.99999999999999999 1.0.0-0A.is.legal Invalid Semantic Versions 1 1.2 1.2.3-0123 1.2.3-0123.0123 1.1.2+.123 +invalid -invalid -invalid+invalid -invalid.01 alpha alpha.beta alpha.beta.1 alpha.1 alpha+beta alpha_beta alpha. alpha.. beta 1.0.0-alpha_beta -alpha. 1.0.0-alpha.. 1.0.0-alpha..1 1.0.0-alpha...1 1.0.0-alpha....1 1.0.0-alpha.....1 1.0.0-alpha......1 1.0.0-alpha.......1 01.1.1 1.01.1 1.1.01 1.2 1.2.3.DEV 1.2-SNAPSHOT 1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788 1.2-RC-SNAPSHOT -1.0.3-gamma+b7718 +justmeta 9.8.7+meta+meta 9.8.7-whatever+meta+meta 99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12 ```
Author
Owner

@mrjbq7 commented on GitHub (Jan 24, 2023):

Should 1.0.0-rc3 sort before or after 1.0.0-rc12?

<!-- gh-comment-id:1402765175 --> @mrjbq7 commented on GitHub (Jan 24, 2023): Should ``1.0.0-rc3`` sort before or after ``1.0.0-rc12``?
Author
Owner

@ljharb commented on GitHub (Jan 24, 2023):

i'd expect after, which is why usually one would do 1.0.0-rc.3 vs 1.0.0-rc.12, where i'd expect before.

<!-- gh-comment-id:1402766897 --> @ljharb commented on GitHub (Jan 24, 2023): i'd expect after, which is why usually one would do `1.0.0-rc.3` vs `1.0.0-rc.12`, where i'd expect before.
Author
Owner

@steveklabnik commented on GitHub (Feb 6, 2023):

I would also support something like this; I wanted to make the semver crate from Rust's test suite operate on examples like this, but never got around to it.

<!-- gh-comment-id:1419854295 --> @steveklabnik commented on GitHub (Feb 6, 2023): I would also support something like this; I wanted to make the `semver` crate from Rust's test suite operate on examples like this, but never got around to it.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#3260