Added exceptions for minor version number. A single major version number can be parsed, but will not be output in toString().
parent
561f050df1
commit
e1a8278cd5
|
@ -45,6 +45,7 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
* The minor version number.
|
||||
*/
|
||||
private final long minor;
|
||||
protected final boolean minorSpecified;
|
||||
|
||||
/**
|
||||
* The patch version number.
|
||||
|
@ -52,6 +53,18 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
private final long patch;
|
||||
protected final boolean patchSpecified;
|
||||
|
||||
/**
|
||||
* Constructs a {@code NormalVersion} with the
|
||||
* major version number.
|
||||
*
|
||||
* @param major the major version number
|
||||
*
|
||||
* @throws IllegalArgumentException if one of the version numbers is a negative integer
|
||||
*/
|
||||
NormalVersion(long major) {
|
||||
this(major, 0, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code NormalVersion} with the
|
||||
* major and minor version numbers.
|
||||
|
@ -62,7 +75,7 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
* @throws IllegalArgumentException if one of the version numbers is a negative integer
|
||||
*/
|
||||
NormalVersion(long major, long minor) {
|
||||
this(major, minor, 0, false);
|
||||
this(major, minor, 0, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +89,7 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
* @throws IllegalArgumentException if one of the version numbers is a negative integer
|
||||
*/
|
||||
NormalVersion(long major, long minor, long patch) {
|
||||
this(major, minor, patch, true);
|
||||
this(major, minor, patch, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,12 +99,13 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
* @param major the major version number
|
||||
* @param minor the minor version number
|
||||
* @param patch the patch version number
|
||||
* @param minorSpecified true if the minor version number was specified
|
||||
* @param patchSpecified true if the patch version number was specified
|
||||
*
|
||||
* @throws IllegalArgumentException if one of the version numbers is a negative integer
|
||||
*/
|
||||
private
|
||||
NormalVersion(long major, long minor, long patch, boolean patchSpecified) {
|
||||
NormalVersion(long major, long minor, long patch, boolean minorSpecified, boolean patchSpecified) {
|
||||
if (major < 0 || minor < 0 || patch < 0) {
|
||||
throw new IllegalArgumentException("Major, minor and patch versions MUST be non-negative integers.");
|
||||
}
|
||||
|
@ -99,6 +113,7 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.minorSpecified = minorSpecified;
|
||||
this.patchSpecified = patchSpecified;
|
||||
}
|
||||
|
||||
|
@ -210,28 +225,36 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
/**
|
||||
* Increments the major version number.
|
||||
*
|
||||
* 1.2.3 -> 1.2
|
||||
* 1 -> 1.0
|
||||
*
|
||||
* @return a new instance of the {@code NormalVersion} class
|
||||
*/
|
||||
NormalVersion incrementMajor() {
|
||||
return new NormalVersion(major + 1, 0, 0, false);
|
||||
return new NormalVersion(major + 1, 0, 0, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the minor version number.
|
||||
*
|
||||
* 1.2.3 -> 1.3
|
||||
* 1.2 -> 1.3
|
||||
*
|
||||
* @return a new instance of the {@code NormalVersion} class
|
||||
*/
|
||||
NormalVersion incrementMinor() {
|
||||
return new NormalVersion(major, minor + 1, 0, false);
|
||||
return new NormalVersion(major, minor + 1, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the patch version number.
|
||||
*
|
||||
* 1.2.3 -> 1.2.4
|
||||
*
|
||||
* @return a new instance of the {@code NormalVersion} class
|
||||
*/
|
||||
NormalVersion incrementPatch() {
|
||||
return new NormalVersion(major, minor, patch + 1, true);
|
||||
return new NormalVersion(major, minor, patch + 1, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,7 +269,10 @@ class NormalVersion implements Comparable<NormalVersion>, Serializable {
|
|||
@Override
|
||||
public
|
||||
String toString() {
|
||||
if (!patchSpecified && patch == 0) {
|
||||
if (!minorSpecified && !patchSpecified && minor == 0 && patch == 0) {
|
||||
return String.format("%d", major);
|
||||
}
|
||||
else if (!patchSpecified && patch == 0) {
|
||||
return String.format("%d.%d", major, minor);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -29,6 +29,7 @@ import static com.dorkbox.version.VersionParser.CharType.EOI;
|
|||
import static com.dorkbox.version.VersionParser.CharType.HYPHEN;
|
||||
import static com.dorkbox.version.VersionParser.CharType.LETTER;
|
||||
import static com.dorkbox.version.VersionParser.CharType.PLUS;
|
||||
import static com.dorkbox.version.VersionParser.CharType.SPACE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
@ -84,6 +85,23 @@ class VersionParser implements Parser<Version> {
|
|||
}
|
||||
return (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z');
|
||||
}
|
||||
}, SPACE {
|
||||
/**
|
||||
* Checks if the specified element matches this type.
|
||||
*
|
||||
* @param chr the element to be tested
|
||||
*
|
||||
* @return {@code true} if the element matches this type
|
||||
* or {@code false} otherwise
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
boolean isMatchedBy(Character chr) {
|
||||
if (chr == null) {
|
||||
return false;
|
||||
}
|
||||
return chr == ' ';
|
||||
}
|
||||
}, DOT {
|
||||
/**
|
||||
* Checks if the specified element matches this type.
|
||||
|
@ -556,11 +574,10 @@ class VersionParser implements Parser<Version> {
|
|||
MetadataVersion preRelease = MetadataVersion.NULL;
|
||||
MetadataVersion build = MetadataVersion.NULL;
|
||||
|
||||
// if we have no patch information, then we have an EXCEPTION to SemVer
|
||||
if (!normal.patchSpecified) {
|
||||
// EXCEPTION TO SEMVER
|
||||
// EXCEPTION to SemVer??
|
||||
if (!(normal.minorSpecified && normal.patchSpecified)) {
|
||||
if (checkNextCharacter(LETTER, DIGIT)) {
|
||||
// NOTE: build INSTEAD OF patch is not valid for semver, however when parsing we want to ALLOW parsing as much.
|
||||
// NOTE: build INSTEAD OF minor/patch is not valid for semver, however when parsing we want to ALLOW parsing as much.
|
||||
// straight away to 4.1.Final
|
||||
// this is not valid semver, but we want to parse it anyways.
|
||||
// when writing this information, IT WILL NOT be in the format, as it will follow semver.
|
||||
|
@ -569,6 +586,11 @@ class VersionParser implements Parser<Version> {
|
|||
|
||||
// we can have other info.
|
||||
if (!checkNextCharacter(HYPHEN, PLUS, EOI)) {
|
||||
if (!normal.minorSpecified && checkNextCharacter(SPACE)) {
|
||||
// fail. but we want to be specific with the error
|
||||
consumeNextCharacter(DOT);
|
||||
}
|
||||
|
||||
// fail. but we want to be specific with the error
|
||||
consumeNextCharacter(DIGIT);
|
||||
}
|
||||
|
@ -585,6 +607,11 @@ class VersionParser implements Parser<Version> {
|
|||
build = parseBuild();
|
||||
}
|
||||
|
||||
if (checkNextCharacter(SPACE)) {
|
||||
// fail. but we want to be specific with the error
|
||||
consumeNextCharacter(DIGIT);
|
||||
}
|
||||
|
||||
Character next = consumeNextCharacter(HYPHEN, PLUS, EOI);
|
||||
if (HYPHEN.isMatchedBy(next)) {
|
||||
preRelease = parsePreRelease();
|
||||
|
@ -604,6 +631,7 @@ class VersionParser implements Parser<Version> {
|
|||
*
|
||||
* <pre>
|
||||
* {@literal
|
||||
* <version core> ::= <major>
|
||||
* <version core> ::= <major> "." <minor>
|
||||
* <version core> ::= <major> "." <minor> "." <patch>
|
||||
* <version core> ::= <major> "." <minor> "." <build>
|
||||
|
@ -615,6 +643,11 @@ class VersionParser implements Parser<Version> {
|
|||
private
|
||||
NormalVersion parseVersionCore() {
|
||||
long major = Long.parseLong(numericIdentifier());
|
||||
if (!checkNextCharacter(DOT)) {
|
||||
// only major!
|
||||
return new NormalVersion(major);
|
||||
}
|
||||
|
||||
consumeNextCharacter(DOT);
|
||||
|
||||
long minor = Long.parseLong(numericIdentifier());
|
||||
|
|
|
@ -54,7 +54,8 @@ class ParserErrorHandlingTest {
|
|||
public static
|
||||
Collection<Object[]> parameters() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{"1", null, 1, new CharType[] {DOT}},
|
||||
// {"1", null, 1, new CharType[] {DOT}}, // exception to semver, is that '1' is permitted (ie: leaving out the minor number)
|
||||
{"1.FINAL", 'F', 2, new CharType[] {DIGIT}}, // double check for exception to SEMVER
|
||||
{"1 ", ' ', 1, new CharType[] {DOT}},
|
||||
{"1.", null, 2, new CharType[] {DIGIT}},
|
||||
// {"1.2", null, 3, new CharType[] {DOT}}, // exception to semver, is that 1.2 is permitted (ie: leaving out the patch number)
|
||||
|
|
|
@ -52,6 +52,16 @@ class VersionTest {
|
|||
public static
|
||||
class CoreFunctionalityTest {
|
||||
|
||||
// MODIFY TEST
|
||||
@Test
|
||||
public
|
||||
void onlyMajor() {
|
||||
// not valid, but we should STILL be able to parse it (we just cannot write it).
|
||||
Version v = Version.from("20180813");
|
||||
assertEquals(20180813, v.getMajorVersion());
|
||||
assertEquals(0, v.getMinorVersion());
|
||||
}
|
||||
|
||||
// MODIFY TEST
|
||||
@Test
|
||||
public
|
||||
|
|
Loading…
Reference in New Issue