Skip to content

Commit

Permalink
UniqueId parsing works
Browse files Browse the repository at this point in the history
  • Loading branch information
jlink committed Mar 11, 2016
1 parent f04ca43 commit 95e5a1c
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 24 deletions.
27 changes: 25 additions & 2 deletions junit-engine-api/src/main/java/org/junit/gen5/engine/UniqueId.java
Expand Up @@ -15,27 +15,37 @@
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;


import org.junit.gen5.commons.util.Preconditions;
import org.junit.gen5.commons.util.StringUtils; import org.junit.gen5.commons.util.StringUtils;


public class UniqueId implements Cloneable { public class UniqueId implements Cloneable {


public static UniqueId parse(String uniqueIdString) {
return new UniqueIdParser(uniqueIdString, SEGMENT_DELIMITER, TYPE_VALUE_SEPARATOR).parse();
}

public static final String TYPE_ENGINE = "engine"; public static final String TYPE_ENGINE = "engine";


private static final String SEGMENT_DELIMITER = "/"; private static final String SEGMENT_DELIMITER = "/";
private static final String TYPE_VALUE_SEPARATOR = ":";


private final List<Segment> segments = new ArrayList<>(); private final List<Segment> segments = new ArrayList<>();


public UniqueId(String engineId) { public UniqueId(String engineId) {
segments.add(new Segment(TYPE_ENGINE, engineId)); segments.add(new Segment(TYPE_ENGINE, engineId));
} }


UniqueId(List<Segment> segments) {
this.segments.addAll(segments);
}

public String getUniqueString() { public String getUniqueString() {
Stream<String> segmentStream = segments.stream().map(this::describe); Stream<String> segmentStream = segments.stream().map(this::describe);
return StringUtils.join(segmentStream, SEGMENT_DELIMITER); return StringUtils.join(segmentStream, SEGMENT_DELIMITER);
} }


private String describe(Segment segment) { private String describe(Segment segment) {
return String.format("[%s:%s]", segment.getType(), segment.getValue()); return String.format("[%s%s%s]", segment.getType(), TYPE_VALUE_SEPARATOR, segment.getValue());
} }


public List<Segment> getSegments() { public List<Segment> getSegments() {
Expand Down Expand Up @@ -64,11 +74,24 @@ public static class Segment {
private final String type; private final String type;
private final String value; private final String value;


private Segment(String type, String value) { Segment(String type, String value) {
checkPrecondition(type);
checkPrecondition(value);

this.type = type; this.type = type;
this.value = value; this.value = value;
} }


private void checkPrecondition(String type) {
Preconditions.notEmpty(type, "type or value must not be empty");
Preconditions.condition(!type.contains(SEGMENT_DELIMITER),
String.format("type or value must not contain '%s'", SEGMENT_DELIMITER));
Preconditions.condition(!type.contains(TYPE_VALUE_SEPARATOR),
String.format("type or value must not contain '%s'", TYPE_VALUE_SEPARATOR));
Preconditions.condition(!type.contains("["), "type or value must not contain '['");
Preconditions.condition(!type.contains("]"), "type or value must not contain ']'");
}

public String getType() { public String getType() {
return type; return type;
} }
Expand Down
@@ -0,0 +1,56 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.junit.gen5.engine;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.junit.gen5.commons.JUnitException;
import org.junit.gen5.engine.UniqueId.Segment;

class UniqueIdParser {
private final String uniqueIdString;
private final String segmentDelimiter;
private final String typeValueSeparator;
private final Pattern segmentPattern;

public UniqueIdParser(String uniqueIdString, String segmentDelimiter, String typeValueSeparator) {
this.uniqueIdString = uniqueIdString;
this.segmentDelimiter = segmentDelimiter;
this.typeValueSeparator = typeValueSeparator;
this.segmentPattern = Pattern.compile("\\[(.+)\\" + typeValueSeparator + "(.+)\\]");
}

UniqueId parse() {
String[] parts = uniqueIdString.split(segmentDelimiter);
List<Segment> segments = Arrays.stream(parts).map(part -> createSegment(part)).collect(Collectors.toList());
checkFirstSegmentIsEngine(segments);
return new UniqueId(segments);
}

private void checkFirstSegmentIsEngine(List<Segment> segments) {
if (!segments.get(0).getType().equals(UniqueId.TYPE_ENGINE))
throw new JUnitException(String.format("UniqueId must start with engine segment but starts with type '%s'",
segments.get(0).getType()));
}

private Segment createSegment(String segmentString) {
Matcher segmentMatcher = segmentPattern.matcher(segmentString);
if (!segmentMatcher.matches())
throw new JUnitException(String.format("'%s' is not a well-formed UniqueId", uniqueIdString));
String type = segmentMatcher.group(1);
String value = segmentMatcher.group(2);
return new Segment(type, value);
}
}
86 changes: 64 additions & 22 deletions junit-tests/src/test/java/org/junit/gen5/engine/UniqueIdTests.java
Expand Up @@ -11,44 +11,86 @@
package org.junit.gen5.engine; package org.junit.gen5.engine;


import org.junit.gen5.api.Assertions; import org.junit.gen5.api.Assertions;
import org.junit.gen5.api.Nested;
import org.junit.gen5.api.Test; import org.junit.gen5.api.Test;
import org.junit.gen5.commons.JUnitException;
import org.junit.gen5.engine.UniqueId.Segment; import org.junit.gen5.engine.UniqueId.Segment;


class UniqueIdTests { class UniqueIdTests {


static final String ENGINE_ID = "junit5"; static final String ENGINE_ID = "junit5";


@Test @Nested
void uniqueIdMustBeCreatedWithEngineId() { class Creation {
UniqueId uniqueId = new UniqueId(ENGINE_ID);


Assertions.assertEquals("[engine:junit5]", uniqueId.getUniqueString()); @Test
void uniqueIdMustBeCreatedWithEngineId() {
UniqueId uniqueId = new UniqueId(ENGINE_ID);


assertSegment(uniqueId.getSegments().get(0), UniqueId.TYPE_ENGINE, "junit5"); Assertions.assertEquals("[engine:junit5]", uniqueId.getUniqueString());
} assertEngine(uniqueId, "junit5");
}

@Test
void appendingOneSegment() {
UniqueId engineId = new UniqueId(ENGINE_ID);
UniqueId classId = engineId.append("class", "org.junit.MyClass");

Assertions.assertEquals("[engine:junit5]/[class:org.junit.MyClass]", classId.getUniqueString());

Assertions.assertEquals(2, classId.getSegments().size());
assertSegment(classId.getSegments().get(1), "class", "org.junit.MyClass");
}

@Test
void appendingSeveralSegments() {
UniqueId engineId = new UniqueId(ENGINE_ID);
UniqueId uniqueId = engineId.append("t1", "v1").append("t2", "v2").append("t3", "v3");

Assertions.assertEquals("[engine:junit5]/[t1:v1]/[t2:v2]/[t3:v3]", uniqueId.getUniqueString());
Assertions.assertEquals(4, uniqueId.getSegments().size());
}


private void assertSegment(Segment segment, String expectedType, String expectedValue) {
Assertions.assertEquals(expectedType, segment.getType(), "segment type");
Assertions.assertEquals(expectedValue, segment.getValue(), "segment value");
} }


@Test @Nested
void appendingOneSegment() { class Parsing {
UniqueId engineId = new UniqueId(ENGINE_ID);
UniqueId classId = engineId.append("class", "org.junit.MyClass"); @Test
void parseError() {
Throwable throwable = Assertions.expectThrows(JUnitException.class, () -> UniqueId.parse("malformed uid"));
Assertions.assertTrue(throwable.getMessage().contains("malformed uid"));
}


Assertions.assertEquals("[engine:junit5]/[class:org.junit.MyClass]", classId.getUniqueString()); @Test
void parseEngineIdOnly() {
UniqueId parsedId = UniqueId.parse("[engine:junit5]");
assertEngine(parsedId, "junit5");
}


Assertions.assertEquals(2, classId.getSegments().size()); @Test
assertSegment(classId.getSegments().get(1), "class", "org.junit.MyClass"); void parseLongerId() {
UniqueId parsedId = UniqueId.parse("[engine:junit5]/[class:MyClass]/[method:myMethod]");
assertEngine(parsedId, "junit5");
assertSegment(parsedId.getSegments().get(1), "class", "MyClass");
assertSegment(parsedId.getSegments().get(2), "method", "myMethod");
}

@Test
void parseUniqueIdThatDoesNotStartWithEngine() {
Throwable throwable = Assertions.expectThrows(JUnitException.class,
() -> UniqueId.parse("[not-engine:anything]"));
Assertions.assertTrue(throwable.getMessage().contains("not-engine"));
}
} }


@Test private void assertEngine(UniqueId uniqueId, String expectedEngineId) {
void appendingSeveralSegments() { assertSegment(uniqueId.getSegments().get(0), UniqueId.TYPE_ENGINE, expectedEngineId);
UniqueId engineId = new UniqueId(ENGINE_ID); }
UniqueId uniqueId = engineId.append("t1", "v1").append("t2", "v2").append("t3", "v3");


Assertions.assertEquals("[engine:junit5]/[t1:v1]/[t2:v2]/[t3:v3]", uniqueId.getUniqueString()); private void assertSegment(Segment segment, String expectedType, String expectedValue) {
Assertions.assertEquals(4, uniqueId.getSegments().size()); Assertions.assertEquals(expectedType, segment.getType(), "segment type");
Assertions.assertEquals(expectedValue, segment.getValue(), "segment value");
} }

} }

0 comments on commit 95e5a1c

Please sign in to comment.