Refactor VersionParser to handle illegal inputs

This commit is contained in:
Zafar Khaja 2014-01-23 18:43:11 +04:00
parent b312d18eaf
commit 988059b444
4 changed files with 69 additions and 36 deletions

View File

@ -85,19 +85,29 @@ public class Version implements Comparable<Version> {
*/
private String build;
/**
* Constructs a {@code Builder} instance.
*/
public Builder() {
}
/**
* Constructs a {@code Builder} instance with the
* string representation of the normal version.
*
* @param normal the string representation of the normal version
* @throws NullPointerException if the specified normal version is null
*/
public Builder(String normal) {
if (normal == null) {
throw new NullPointerException(
"Normal version MUST NOT be NULL"
);
}
this.normal = normal;
}
/**
* Sets the normal version.
*
* @param normal the string representation of the normal version
*/
public void setNormalVersion(String normal) {
this.normal = normal;
}
@ -125,11 +135,27 @@ public class Version implements Comparable<Version> {
* @return a newly built {@code Version} instance
*/
public Version build() {
return new Version(
VersionParser.parseVersionCore(normal),
VersionParser.parsePreRelease(preRelease),
VersionParser.parseBuild(build)
);
StringBuilder sb = new StringBuilder();
if (isFilled(normal)) {
sb.append(normal);
}
if (isFilled(preRelease)) {
sb.append(PRE_RELEASE_PREFIX).append(preRelease);
}
if (isFilled(build)) {
sb.append(BUILD_PREFIX).append(build);
}
return VersionParser.parseValidSemVer(sb.toString());
}
/**
* Checks if a string has a usable value.
*
* @param str the string to check
* @return {@code true} if the string is filled or {@code false} otherwise
*/
private boolean isFilled(String str) {
return str != null && !str.isEmpty();
}
}
@ -221,6 +247,7 @@ public class Version implements Comparable<Version> {
*
* @param version the version string to parse
* @return a new instance of the {@code Version} class
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
public static Version valueOf(String version) {
return VersionParser.parseValidSemVer(version);
@ -294,6 +321,7 @@ public class Version implements Comparable<Version> {
*
* @param preRelease the pre-release version to append
* @return a new instance of the {@code Version} class
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
public Version incrementMajorVersion(String preRelease) {
return new Version(
@ -316,6 +344,7 @@ public class Version implements Comparable<Version> {
*
* @param preRelease the pre-release version to append
* @return a new instance of the {@code Version} class
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
public Version incrementMinorVersion(String preRelease) {
return new Version(
@ -338,6 +367,7 @@ public class Version implements Comparable<Version> {
*
* @param preRelease the pre-release version to append
* @return a new instance of the {@code Version} class
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
public Version incrementPatchVersion(String preRelease) {
return new Version(
@ -369,6 +399,7 @@ public class Version implements Comparable<Version> {
*
* @param preRelease the pre-release version to set
* @return a new instance of the {@code Version} class
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
public Version setPreReleaseVersion(String preRelease) {
return new Version(normal, VersionParser.parsePreRelease(preRelease));
@ -379,6 +410,7 @@ public class Version implements Comparable<Version> {
*
* @param build the build metadata to set
* @return a new instance of the {@code Version} class
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
public Version setBuildMetadata(String build) {
return new Version(normal, preRelease, VersionParser.parseBuild(build));

View File

@ -124,8 +124,12 @@ class VersionParser implements Parser<Version> {
* with the input string to parse.
*
* @param input the input string to parse
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
*/
VersionParser(String input) {
if (input == null || input.isEmpty()) {
throw new IllegalArgumentException("Input string is NULL or empty");
}
Character[] elements = new Character[input.length()];
for (int i = 0; i < input.length(); i++) {
elements[i] = Character.valueOf(input.charAt(i));
@ -152,6 +156,7 @@ class VersionParser implements Parser<Version> {
*
* @param version the version string to parse
* @return a valid version object
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
* @throws ParseException when there is an error defined in
* the SemVer or the formal grammar
* @throws UnexpectedElementException when encounters an unexpected character type
@ -166,6 +171,7 @@ class VersionParser implements Parser<Version> {
*
* @param versionCore the version core string to parse
* @return a valid normal version object
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
* @throws ParseException when there is an error defined in
* the SemVer or the formal grammar
* @throws UnexpectedElementException when encounters an unexpected character type
@ -180,13 +186,11 @@ class VersionParser implements Parser<Version> {
*
* @param preRelease the pre-release version string to parse
* @return a valid pre-release version object
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
* @throws ParseException when there is an error defined in
* the SemVer or the formal grammar
*/
static MetadataVersion parsePreRelease(String preRelease) {
if (preRelease == null) {
return MetadataVersion.NULL;
}
VersionParser parser = new VersionParser(preRelease);
return parser.parsePreRelease();
}
@ -196,13 +200,11 @@ class VersionParser implements Parser<Version> {
*
* @param build the build metadata string to parse
* @return a valid build metadata object
* @throws IllegalArgumentException if the input string is {@code NULL} or empty
* @throws ParseException when there is an error defined in
* the SemVer or the formal grammar
*/
static MetadataVersion parseBuild(String build) {
if (build == null) {
return MetadataVersion.NULL;
}
VersionParser parser = new VersionParser(build);
return parser.parseBuild();
}

View File

@ -54,12 +54,6 @@ public class VersionParserTest {
assertEquals(new MetadataVersion(new String[] {"beta-1", "1"}), preRelease);
}
@Test
public void shouldReturnNullMetadataVersionIfPreReleaseIsNull() {
MetadataVersion preRelease = VersionParser.parsePreRelease(null);
assertEquals(MetadataVersion.NULL, preRelease);
}
@Test
public void shouldNotAllowDigitsInPreReleaseVersion() {
try {
@ -86,12 +80,6 @@ public class VersionParserTest {
assertEquals(new MetadataVersion(new String[] {"build", "1"}), build);
}
@Test
public void shouldReturnNullMetadataVersionIfBuildIsNull() {
MetadataVersion build = VersionParser.parseBuild(null);
assertEquals(MetadataVersion.NULL, build);
}
@Test
public void shouldAllowDigitsInBuildMetadata() {
try {
@ -124,4 +112,16 @@ public class VersionParserTest {
version
);
}
@Test
public void shouldRaiseErrorForIllegalInputString() {
for (String illegal : new String[] { "", null }) {
try {
new VersionParser(illegal);
} catch (IllegalArgumentException e) {
continue;
}
fail("Should raise error for illegal input string");
}
}
}

View File

@ -394,13 +394,12 @@ public class VersionTest {
public static class BuilderTest {
@Test
public void shouldThrowNullPointerExceptionIfNormalVersionIsNull() {
try {
new Version.Builder(null);
} catch (NullPointerException e) {
return;
}
fail("Builder was expected to throw NullPointerException");
public void shouldBuildVersionInSteps() {
Version.Builder builder = new Version.Builder();
builder.setNormalVersion("1.0.0");
builder.setPreReleaseVersion("alpha");
builder.setBuildMetadata("build");
assertEquals(Version.valueOf("1.0.0-alpha+build"), builder.build());
}
@Test