Skip to content

Commit

Permalink
Implement testing module
Browse files Browse the repository at this point in the history
  • Loading branch information
Musa Talluzi authored and ge0ffrey committed Jul 27, 2018
1 parent 03018b3 commit a8b7629
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 41 deletions.
Expand Up @@ -21,9 +21,20 @@
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;


import org.apache.commons.lang3.tuple.Pair;
import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Before; import org.junit.Before;
Expand All @@ -34,6 +45,10 @@
import org.optaplanner.examples.common.persistence.AbstractXlsxSolutionFileIO; import org.optaplanner.examples.common.persistence.AbstractXlsxSolutionFileIO;
import org.optaplanner.examples.conferencescheduling.app.ConferenceSchedulingApp; import org.optaplanner.examples.conferencescheduling.app.ConferenceSchedulingApp;
import org.optaplanner.examples.conferencescheduling.domain.ConferenceSolution; import org.optaplanner.examples.conferencescheduling.domain.ConferenceSolution;
import org.optaplanner.examples.conferencescheduling.domain.Room;
import org.optaplanner.examples.conferencescheduling.domain.Talk;
import org.optaplanner.examples.conferencescheduling.domain.Timeslot;
import org.optaplanner.examples.conferencescheduling.persistence.ConferenceSchedulingXlsxFileIO;
import org.optaplanner.test.impl.score.buildin.hardsoft.HardSoftScoreVerifier; import org.optaplanner.test.impl.score.buildin.hardsoft.HardSoftScoreVerifier;


public class ConferenceSchedulingScoreRulesXlsxTest { public class ConferenceSchedulingScoreRulesXlsxTest {
Expand All @@ -42,23 +57,23 @@ public class ConferenceSchedulingScoreRulesXlsxTest {
private String currentPackage; private String currentPackage;
private String currentConstraint; private String currentConstraint;
private int expectedHardScore, expectedSoftScore; private int expectedHardScore, expectedSoftScore;
private final String testFileName = "org/optaplanner/examples/conferencescheduling/testConferenceSchedulingScoreRules.xlsx";
private final String testFileName = "testConferenceSchedulingScoreRules.xlsx";
private HardSoftScoreVerifier<ConferenceSolution> scoreVerifier = new HardSoftScoreVerifier<>( private HardSoftScoreVerifier<ConferenceSolution> scoreVerifier = new HardSoftScoreVerifier<>(
SolverFactory.createFromXmlResource(ConferenceSchedulingApp.SOLVER_CONFIG)); SolverFactory.createFromXmlResource(ConferenceSchedulingApp.SOLVER_CONFIG));
private testConferenceSchedulingScoreRulesReader testFileReader; private testConferenceSchedulingScoreRulesReader testFileReader;


@Before @Before
public void setup() { public void setup() {
try (InputStream in = new BufferedInputStream(new FileInputStream(testFileName))) { File testFile = new File(getClass().getResource(testFileName).getFile());
try (InputStream in = new BufferedInputStream(new FileInputStream(testFile))) {
XSSFWorkbook workbook = new XSSFWorkbook(in); XSSFWorkbook workbook = new XSSFWorkbook(in);
this.currentSolution = new ConferenceSchedulingXlsxFileIO().read(testFile);
this.testFileReader = new testConferenceSchedulingScoreRulesReader(workbook); this.testFileReader = new testConferenceSchedulingScoreRulesReader(workbook);
this.currentSolution = testFileReader.read();
} catch (IOException | RuntimeException e) { } catch (IOException | RuntimeException e) {
throw new IllegalStateException("Failed reading inputSolutionFile (" throw new IllegalStateException("Failed reading inputSolutionFile ("
+ testFileName + ").", e); + testFileName + ").", e);
} }
this.expectedHardScore = currentSolution.getScore().getHardScore();
this.expectedSoftScore = currentSolution.getScore().getSoftScore();
} }


@Test @Test
Expand All @@ -71,34 +86,53 @@ public void testRules() {


private class testConferenceSchedulingScoreRulesReader extends AbstractXlsxSolutionFileIO.AbstractXslxReader<ConferenceSolution> { private class testConferenceSchedulingScoreRulesReader extends AbstractXlsxSolutionFileIO.AbstractXslxReader<ConferenceSolution> {


private int numberOfSheets, currentSheetIndex; private int numberOfSheets, currentTestSheetIndex;
Map<Integer, String> cellColumnIndexToDateStringMap; private Map<String, Room> roomMap;
Map<Integer, String> cellColumnIndexToTimeStringMap; private Map<String, Talk> talkMap;
private Map<Pair<LocalDateTime, LocalDateTime>, Timeslot> timeslotMap;
private Map<Integer, LocalDate> columnIndexToDateMap;
private Map<Integer, LocalTime> columnIndexToStartTimeMap;
private Map<Integer, LocalTime> columnIndexToEndTimeMap;

private final FieldAccessingSolutionCloner<ConferenceSolution> solutionCloner = new FieldAccessingSolutionCloner<>(new SolutionDescriptor<>(ConferenceSolution.class)); private final FieldAccessingSolutionCloner<ConferenceSolution> solutionCloner = new FieldAccessingSolutionCloner<>(new SolutionDescriptor<>(ConferenceSolution.class));
private final Pattern VALID_SCORE_PATTERN = Pattern.compile("-?\\d+ hard/-?\\d+ soft");
private final String ONLY_DIGITS_AND_SPACES_REGEX = "[^\\d\\s-]";

final DateTimeFormatter DAY_FORMATTER
= DateTimeFormatter.ofPattern("E yyyy-MM-dd", Locale.ENGLISH);
final DateTimeFormatter TIME_FORMATTER
= DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);


public testConferenceSchedulingScoreRulesReader(XSSFWorkbook workbook) { public testConferenceSchedulingScoreRulesReader(XSSFWorkbook workbook) {
super(workbook); super(workbook);
this.numberOfSheets = workbook.getNumberOfSheets(); this.numberOfSheets = workbook.getNumberOfSheets();
this.currentSheetIndex = 0; this.currentTestSheetIndex = workbook.getSheetIndex("Talks") + 1;
roomMap = currentSolution.getRoomList().stream().collect(
Collectors.toMap(Room::getName, Function.identity()));
talkMap = currentSolution.getTalkList().stream().collect(
Collectors.toMap(Talk::getCode, Function.identity()));
timeslotMap = currentSolution.getTimeslotList().stream().collect(
Collectors.toMap(timeslot -> Pair.of(timeslot.getStartDateTime(), timeslot.getEndDateTime()),
Function.identity()));
this.columnIndexToDateMap = new HashMap<>(timeslotMap.size());
this.columnIndexToStartTimeMap = new HashMap<>(timeslotMap.size());
this.columnIndexToEndTimeMap = new HashMap<>(timeslotMap.size());
} }


@Override @Override
public ConferenceSolution read() { public ConferenceSolution read() {
return solution; return currentSolution;
} }


public ConferenceSolution nextSolution() { public ConferenceSolution nextSolution() {
if (currentSheetIndex >= numberOfSheets) { if (currentTestSheetIndex >= numberOfSheets) {
return null; return null;
} }
nextSheet(workbook.getSheetName(currentSheetIndex++)); nextSheet(workbook.getSheetName(currentTestSheetIndex++));


ConferenceSolution nextSheetSolution = null; ConferenceSolution nextSheetSolution = solutionCloner.cloneSolution(currentSolution);
try { talkMap = nextSheetSolution.getTalkList().stream().collect(
nextSheetSolution = (ConferenceSolution) clone(); Collectors.toMap(Talk::getCode, Function.identity()));
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}


nextRow(false); nextRow(false);
readHeaderCell("Constraint package"); readHeaderCell("Constraint package");
Expand All @@ -108,43 +142,89 @@ public ConferenceSolution nextSolution() {
currentConstraint = nextStringCell().getStringCellValue(); currentConstraint = nextStringCell().getStringCellValue();
nextRow(false); nextRow(false);
readHeaderCell("Score"); readHeaderCell("Score");
String[] scoresAsString = nextStringCell().getStringCellValue().split("/"); String scoreAsString = nextStringCell().getStringCellValue();
expectedHardScore = Integer.parseInt(scoresAsString[0]); if (!VALID_SCORE_PATTERN.matcher(scoreAsString).matches()) {
expectedSoftScore = Integer.parseInt(scoresAsString[1]); throw new IllegalStateException(currentPosition() + ": The score (" + scoreAsString
+ ") must match to the regular expression (" + VALID_SCORE_PATTERN + ").");
}
String[] scoresStringArray = scoreAsString.replaceAll(ONLY_DIGITS_AND_SPACES_REGEX, "").split(" +");
expectedHardScore = Integer.parseInt(scoresStringArray[0]);
expectedSoftScore = Integer.parseInt(scoresStringArray[1]);


nextRow(); nextRow();
cellColumnIndexToDateStringMap = readTimeslotDays(); readTimeslotDays();
nextRow(false); nextRow(false);
readHeaderCell("Room"); readHeaderCell("Room");
cellColumnIndexToTimeStringMap = readTiemslotHours(); readTiemslotHours();
while (nextRow()) { while (nextRow()) {

String roomName = nextStringCell().getStringCellValue();
Room room = roomMap.get(roomName);
if (room == null) {
throw new IllegalStateException(currentPosition() + ": The room (" + roomName
+ ") does not exist in the room list.");
}
for (int i = 0; i < columnIndexToStartTimeMap.size(); i++) {
String talkCode = nextCell().getStringCellValue();
if (!talkCode.isEmpty()) {
Talk talk = talkMap.get(talkCode);
if (talk == null) {
throw new IllegalStateException(currentPosition() + ": Talk (" + talkCode
+ ") does not exist in the talk list.");
}

LocalDateTime startDateTime = LocalDateTime.of(columnIndexToDateMap.get(currentColumnNumber), columnIndexToStartTimeMap.get(currentColumnNumber));
LocalDateTime endDateTime = LocalDateTime.of(columnIndexToDateMap.get(currentColumnNumber), columnIndexToEndTimeMap.get(currentColumnNumber));

Timeslot timeslot = timeslotMap.get(Pair.of(startDateTime, endDateTime));
if (timeslot == null) {
throw new IllegalStateException(currentPosition() + ": The timeslot with date (" + startDateTime.toLocalDate().toString()
+ "), startTime (" + startDateTime.toLocalTime().toString() + ") and endTime (" + endDateTime.toLocalTime().toString()
+ ") that doesn't exist in the other sheet (Timeslots).");
}
talk.setRoom(room);
talk.setTimeslot(timeslot);
}
}
} }


return nextSheetSolution; return nextSheetSolution;
} }


private Map<Integer, String> readTimeslotDays() { private void readTimeslotDays() {
Map<Integer, String> cellIndexToDateStringMap = new HashMap<>(); String previousDateString = null;
XSSFCell cell; for (int i = 0; i < currentRow.getLastCellNum(); i++) {
while ((cell = currentRow == null ? null : nextStringCell()) != null) { XSSFCell cell = currentRow.getCell(i);
if (cell != null) { if (cell.getStringCellValue().isEmpty() && previousDateString == null) {

continue;
cellIndexToDateStringMap.put(cell.getColumnIndex(), cell.getStringCellValue()); } else {
if ((!cell.getStringCellValue().isEmpty())) {
previousDateString = cell.getStringCellValue();
}
try {
columnIndexToDateMap.put(i, LocalDate.parse(previousDateString, DAY_FORMATTER));
} catch (DateTimeParseException e) {
throw new IllegalStateException(currentPosition() + ": The date (" + cell.getStringCellValue()
+ "does not parse as a date.");
}
} }
} }
return cellIndexToDateStringMap;
} }


private Map<Integer, String> readTiemslotHours() { private void readTiemslotHours() {
Map<Integer, String> cellIndexToTimeStringMap = new HashMap<>(); StreamSupport.stream(currentRow.spliterator(), false)
XSSFCell cell; .forEach(cell -> {
while ((cell = currentRow == null ? null : nextStringCell()) != null) { if (!cell.getStringCellValue().isEmpty() && !cell.getStringCellValue().equals("Room")) {
if (cell != null) { String[] startAndEndTimeStringArray = cell.getStringCellValue().split("-");
cellIndexToTimeStringMap.put(cell.getColumnIndex(), cell.getStringCellValue()); try {
} columnIndexToStartTimeMap.put(cell.getColumnIndex(), LocalTime.parse(startAndEndTimeStringArray[0], TIME_FORMATTER));
} columnIndexToEndTimeMap.put(cell.getColumnIndex(), LocalTime.parse(startAndEndTimeStringArray[1], TIME_FORMATTER));
return cellIndexToTimeStringMap; } catch (DateTimeParseException e) {
throw new IllegalStateException(currentPosition() + ": The startTime (" + startAndEndTimeStringArray[0]
+ ") or endTime (" + startAndEndTimeStringArray[1]
+ ") doesn't parse as a time.", e);
}
}
});
} }
} }
} }
Binary file not shown.
Binary file not shown.

0 comments on commit a8b7629

Please sign in to comment.