diff --git a/pom.xml b/pom.xml index f43d288..2d38af7 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,10 @@ 0.2.0-SNAPSHOT jar + + 3.0.0 + + Apache License, Version 2.0 @@ -55,6 +59,18 @@ junit junit 4.12-beta-1 + test + + + org.mockito + mockito-core + 1.9.5 + test + + + ch.qos.logback + logback-classic + 1.1.2 @@ -87,7 +103,7 @@ org.eluder.coveralls coveralls-maven-plugin - 2.1.0 + 2.2.0 ${env.COVERALLS_TOKEN} @@ -105,7 +121,7 @@ org.apache.maven.plugins maven-jar-plugin - 2.4 + 2.5 @@ -125,7 +141,7 @@ org.apache.maven.plugins maven-dependency-plugin - 2.1 + 2.8 copy-dependencies @@ -143,7 +159,7 @@ org.apache.maven.plugins maven-assembly-plugin - 2.3 + 2.4.1 package @@ -166,7 +182,7 @@ org.codehaus.mojo exec-maven-plugin - 1.2.1 + 1.3.2 diff --git a/src/main/java/sk/gymy/seminar/app/SeminarApp.java b/src/main/java/sk/gymy/seminar/app/SeminarApp.java index b26bb44..8a8adc9 100644 --- a/src/main/java/sk/gymy/seminar/app/SeminarApp.java +++ b/src/main/java/sk/gymy/seminar/app/SeminarApp.java @@ -42,6 +42,8 @@ import sk.gymy.seminar.swingui.SeminarPanel; import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -49,12 +51,11 @@ public class SeminarApp extends CommonApp { - public static final String SOLVER_CONFIG - = "sk/gymy/seminar/solver/seminarSolverConfig.xml"; + public static final String SOLVER_CONFIG = "sk/gymy/seminar/solver/seminarSolverConfig.xml"; - public static void main(String[] args) { + public static void main(String[] args) throws IOException { prepareSwingEnvironment(); - prepareDataDirStructure(); + prepareDataDirStructure(Paths.get("").toAbsolutePath().toFile()); new SeminarApp().init(); } @@ -141,17 +142,28 @@ protected AbstractSolutionExporter createSolutionExporter() { return new SeminarExporter(); } - private static void prepareDataDirStructure() { - String dataDirPath = "data/" + SeminarDao.dataDirName + "/"; + /** + * Constructs a tree of data directories inside the base directory. + * + * SeminarApp makes no assumptions about deleting them afterwards. + * + * @param baseDir must be a directory and must exists + */ + protected static void prepareDataDirStructure(File baseDir) throws IOException { + logger.info("BaseDir is: {}", baseDir); + if (!baseDir.exists() || !baseDir.isDirectory()) { + logger.error("BaseDir doesn't exist or isn't a directory!"); + throw new IllegalArgumentException("BaseDir doesn't exist or isn't a directory"); + } + String dataDirPath = baseDir.getPath() + "/data/" + SeminarDao.dataDirName + "/"; List dataDirs = Arrays.asList("import", "export", "solved", "unsolved"); File dir; - for(String curDataDir : dataDirs) { dir = new File(dataDirPath + curDataDir); if (!dir.exists()) { logger.info("Data directory {} doesn't exist, creating it.", dir.toString()); if (!dir.mkdirs()) { - throw new IllegalStateException("Failed to create dataDir folders: " + dir.toString()); + throw new IOException("Failed to recursively create data directory: " + dir.toString()); } } } diff --git a/src/main/java/sk/gymy/seminar/app/SeminarBenchmarkApp.java b/src/main/java/sk/gymy/seminar/app/SeminarBenchmarkApp.java index 9248599..3d95211 100644 --- a/src/main/java/sk/gymy/seminar/app/SeminarBenchmarkApp.java +++ b/src/main/java/sk/gymy/seminar/app/SeminarBenchmarkApp.java @@ -26,12 +26,9 @@ public static void main(String[] args) { public SeminarBenchmarkApp() { super( - new ArgOption("default", - "/sk/gymy/seminar/benchmark/seminarBenchmarkConfig.xml"), - new ArgOption("stepLimit", - "/sk/gymy/seminar/benchmark/seminarStepLimitBenchmarkConfig.xml"), - new ArgOption("scoreDirector", - "/sk/gymy/seminar/benchmark/seminarScoreDirectorBenchmarkConfig.xml") + new ArgOption("default", "sk/gymy/seminar/benchmark/seminarBenchmarkConfig.xml"), + new ArgOption("stepLimit", "sk/gymy/seminar/benchmark/seminarStepLimitBenchmarkConfig.xml"), + new ArgOption("scoreDirector", "sk/gymy/seminar/benchmark/seminarScoreDirectorBenchmarkConfig.xml") ); } diff --git a/src/main/java/sk/gymy/seminar/app/SeminarHelloWorld.java b/src/main/java/sk/gymy/seminar/app/SeminarHelloWorld.java index 675deaf..793dd71 100644 --- a/src/main/java/sk/gymy/seminar/app/SeminarHelloWorld.java +++ b/src/main/java/sk/gymy/seminar/app/SeminarHelloWorld.java @@ -29,6 +29,10 @@ public class SeminarHelloWorld { public static void main(String[] args) { + System.out.println(solveHelloWorld()); + } + + public static String solveHelloWorld() { // Build the Solver SolverFactory solverFactory = SolverFactory.createFromXmlResource( "sk/gymy/seminar/solver/seminarSolverConfig.xml"); @@ -44,7 +48,7 @@ public static void main(String[] args) { Groups solved5Seminars = (Groups) solver.getBestSolution(); // Display the result - System.out.print("\nSolved 5 Seminars:\n" + toDisplayString(solved5Seminars)); + return "\nSolved 5 Seminars:\n" + toDisplayString(solved5Seminars); } public static String toDisplayString(Groups groups) { diff --git a/src/main/java/sk/gymy/seminar/domain/Group.java b/src/main/java/sk/gymy/seminar/domain/Group.java index 2cb00d0..b47cce0 100644 --- a/src/main/java/sk/gymy/seminar/domain/Group.java +++ b/src/main/java/sk/gymy/seminar/domain/Group.java @@ -24,6 +24,15 @@ public class Group extends AbstractPersistable { private int index; + public Group() { + super(); + } + + public Group(int index) { + super(); + this.index = index; + } + public int getIndex() { return index; } @@ -37,4 +46,16 @@ public String toString() { return "G" + index; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Group group = (Group) o; + return index == group.index; + } + + @Override + public int hashCode() { + return index; + } } diff --git a/src/main/java/sk/gymy/seminar/domain/Groups.java b/src/main/java/sk/gymy/seminar/domain/Groups.java index 0f6106c..c917800 100644 --- a/src/main/java/sk/gymy/seminar/domain/Groups.java +++ b/src/main/java/sk/gymy/seminar/domain/Groups.java @@ -107,6 +107,11 @@ public void setScore(HardSoftScore score) { this.score = score; } + @Override + public String toString() { + return "Groups{name=" + name + ", score=" + score + ", seminarList=" + seminarList + "}"; + } + // ************************************************************************ // Complex methods // ************************************************************************ diff --git a/src/main/java/sk/gymy/seminar/domain/Person.java b/src/main/java/sk/gymy/seminar/domain/Person.java new file mode 100644 index 0000000..339610a --- /dev/null +++ b/src/main/java/sk/gymy/seminar/domain/Person.java @@ -0,0 +1,75 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.domain; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.optaplanner.examples.common.domain.AbstractPersistable; + +public class Person extends AbstractPersistable { + + private int index; + private String name; + + public Person() { + super(); + } + + public Person(int index, String name) { + super(); + this.index = index; + this.name = name; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Person person = (Person) o; + return new EqualsBuilder() + .append(getName(), person.getName()) + .append(getIndex(), person.getIndex()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(name).append(index).toHashCode(); + } +} diff --git a/src/main/java/sk/gymy/seminar/domain/Seminar.java b/src/main/java/sk/gymy/seminar/domain/Seminar.java index 7571982..7001b57 100644 --- a/src/main/java/sk/gymy/seminar/domain/Seminar.java +++ b/src/main/java/sk/gymy/seminar/domain/Seminar.java @@ -17,6 +17,8 @@ package sk.gymy.seminar.domain; import com.thoughtworks.xstream.annotations.XStreamAlias; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.optaplanner.core.api.domain.entity.PlanningEntity; import org.optaplanner.core.api.domain.variable.PlanningVariable; import org.optaplanner.examples.common.domain.AbstractPersistable; @@ -40,6 +42,20 @@ public class Seminar extends AbstractPersistable { //planning variable private Group group; + public Seminar() { + super(); + } + + public Seminar(int index, String name, boolean locked, Teacher teacher, List students, Group group) { + super(); + this.index = index; + this.name = name; + this.locked = locked; + this.teacher = teacher; + this.students = students; + this.group = group; + } + @PlanningVariable(valueRangeProviderRefs = {"groupRange"}, strengthWeightFactoryClass = GroupStrengthWeightFactory.class) public Group getGroup() { return group; @@ -94,4 +110,25 @@ public String toString() { return name + ": " + group; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Seminar seminar = (Seminar) o; + + return new EqualsBuilder() // do not append Group! + .append(getIndex(), seminar.getIndex()) + .append(getName(), seminar.getName()) + .append(getStudents(), seminar.getStudents()) + .append(getTeacher(), seminar.getTeacher()) + .append(isLocked(), seminar.isLocked()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(index).append(name) // do not append Group! + .append(students).append(teacher).append(locked).toHashCode(); + } } diff --git a/src/main/java/sk/gymy/seminar/domain/Student.java b/src/main/java/sk/gymy/seminar/domain/Student.java index 060ccbc..759bb17 100644 --- a/src/main/java/sk/gymy/seminar/domain/Student.java +++ b/src/main/java/sk/gymy/seminar/domain/Student.java @@ -17,33 +17,16 @@ package sk.gymy.seminar.domain; import com.thoughtworks.xstream.annotations.XStreamAlias; -import org.optaplanner.examples.common.domain.AbstractPersistable; @XStreamAlias("Student") -public class Student extends AbstractPersistable { +public class Student extends Person { - private int index; - private String name; - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; + public Student() { + super(); } - @Override - public String toString() { - return getName(); + public Student(int index, String name) { + super(index, name); } } diff --git a/src/main/java/sk/gymy/seminar/domain/Teacher.java b/src/main/java/sk/gymy/seminar/domain/Teacher.java index 4c70111..998553d 100644 --- a/src/main/java/sk/gymy/seminar/domain/Teacher.java +++ b/src/main/java/sk/gymy/seminar/domain/Teacher.java @@ -1,32 +1,31 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package sk.gymy.seminar.domain; import com.thoughtworks.xstream.annotations.XStreamAlias; -import org.optaplanner.examples.common.domain.AbstractPersistable; @XStreamAlias("Teacher") -public class Teacher extends AbstractPersistable { - - private int index; - private String name; - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - public String getName() { - return name; - } +public class Teacher extends Person { - public void setName(String name) { - this.name = name; + public Teacher() { + super(); } - @Override - public String toString() { - return getName(); + public Teacher(int index, String name) { + super(index, name); } } diff --git a/src/main/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactory.java b/src/main/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactory.java index a321798..47a623f 100644 --- a/src/main/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactory.java +++ b/src/main/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactory.java @@ -18,6 +18,8 @@ import org.apache.commons.lang.builder.CompareToBuilder; import org.optaplanner.core.impl.heuristic.selector.common.decorator.SelectionSorterWeightFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import sk.gymy.seminar.domain.Group; import sk.gymy.seminar.domain.Groups; import sk.gymy.seminar.domain.Seminar; @@ -26,15 +28,21 @@ public class GroupStrengthWeightFactory implements SelectionSorterWeightFactory { + final private static Logger LOGGER = LoggerFactory.getLogger(GroupStrengthWeightFactory.class); + public Comparable createSorterWeight(Groups groups, Group group) { int seminarCount = countSeminars(group, groups.getSeminarList()); return new GroupStrengthWeight(group, seminarCount); } private static int countSeminars(Group group, List seminarList) { + if (group == null) { + LOGGER.error("Group to count seminars is null, returning 0 seminar count"); + return 0; + } int counter = 0; for (Seminar seminar : seminarList) { - if (seminar.getGroup() == group) { + if (seminar.getGroup() != null && seminar.getGroup().equals(group)) { counter++; } } @@ -51,11 +59,19 @@ public GroupStrengthWeight(Group group, int seminarCount) { this.seminarCount = seminarCount; } + public Group getGroup() { + return group; + } + + public int getSeminarCount() { + return seminarCount; + } + public int compareTo(GroupStrengthWeight other) { return new CompareToBuilder() - // The stronger rows are on the side, so they have a higher distance to the middle + // The stronger groups are those with more seminars .append(seminarCount, other.seminarCount) - .append(group.getIndex(), other.group.getIndex()) + .append(group.getIndex(), other.group.getIndex()) // Tie-breaker .toComparison(); } diff --git a/src/main/java/sk/gymy/seminar/domain/solver/SeminarDifficultyWeightFactory.java b/src/main/java/sk/gymy/seminar/domain/solver/SeminarDifficultyWeightFactory.java index 88bf8e0..aec270c 100644 --- a/src/main/java/sk/gymy/seminar/domain/solver/SeminarDifficultyWeightFactory.java +++ b/src/main/java/sk/gymy/seminar/domain/solver/SeminarDifficultyWeightFactory.java @@ -38,11 +38,10 @@ public SeminarDifficultyWeight(Seminar seminar, int studentsCount) { } public int compareTo(SeminarDifficultyWeight other) { - return new CompareToBuilder() + return new CompareToBuilder() // Decreasing order // The more difficult seminars have a higher number of students - .append(other.studentsCount, studentsCount) // Decreasing - // Tie breaker - .append(seminar.getIndex(), other.seminar.getIndex()) + .append(other.studentsCount, studentsCount) + .append(other.seminar.getIndex(), seminar.getIndex()) // Tie-breaker .toComparison(); } diff --git a/src/main/java/sk/gymy/seminar/persistence/SeminarExporter.java b/src/main/java/sk/gymy/seminar/persistence/SeminarExporter.java index 21f479d..2053ba7 100644 --- a/src/main/java/sk/gymy/seminar/persistence/SeminarExporter.java +++ b/src/main/java/sk/gymy/seminar/persistence/SeminarExporter.java @@ -26,7 +26,7 @@ public class SeminarExporter extends AbstractTxtSolutionExporter { - private static final String OUTPUT_FILE_SUFFIX = ".sem.txt"; + private static final String OUTPUT_FILE_SUFFIX = "sem.txt"; public static void main(String[] args) { new SeminarExporter().convertAll(); diff --git a/src/main/java/sk/gymy/seminar/persistence/SeminarGenerator.java b/src/main/java/sk/gymy/seminar/persistence/SeminarGenerator.java index 3c40462..31f9a86 100644 --- a/src/main/java/sk/gymy/seminar/persistence/SeminarGenerator.java +++ b/src/main/java/sk/gymy/seminar/persistence/SeminarGenerator.java @@ -33,17 +33,22 @@ public class SeminarGenerator extends LoggingMain { - private static final File outputDir = new File("data/seminar/unsolved/"); - - protected SolutionDao solutionDao; + private SolutionDao solutionDao; private Multiset studentSeminars; private Random random; public SeminarGenerator() { - random = new Random(); - studentSeminars = HashMultiset.create(); + this.random = new Random(); + this.studentSeminars = HashMultiset.create(); + this.solutionDao = new SeminarDao(); + } + + public SeminarGenerator(SolutionDao solutionDao) { + this.random = new Random(); + this.studentSeminars = HashMultiset.create(); + this.solutionDao = solutionDao; } public static void main(String[] args) { @@ -51,8 +56,7 @@ public static void main(String[] args) { } public void generate() { - solutionDao = new SeminarDao(); - //writeGroups(3, 20, 6, 18); + writeGroups(3, 20, 6, 18); //writeGroups(3, 200, 60, 180); //writeGroups(3, 2000, 600, 1800); //writeGroups(3, 2000, 600, 100); @@ -60,15 +64,15 @@ public void generate() { private void writeGroups(int N, int studentN, int teacherN, int seminarN) { String outputFileName = "G" + N + "St" + studentN + "Tea" + teacherN + "Sem" + seminarN + "-seminar.xml"; - File outputFile = new File(outputDir, outputFileName); Groups groups = createGroups(N, studentN, teacherN, seminarN); - solutionDao.writeSolution(groups, outputFile); + solutionDao.writeSolution(groups, new File(solutionDao.getDataDir().getPath() + "/unsolved/" + outputFileName)); } public Groups createGroups(int N, int studentN, int teacherN, int seminarN) { Groups groups = new Groups(); groups.setId(0L); groups.setN(N); + groups.setName("G" + N + "St" + studentN + "Tea" + teacherN + "Sem" + seminarN); groups.setStudentList(createStudentList(groups, studentN)); groups.setTeacherList(createTeacherList(groups, teacherN)); groups.setGroupList(createGroupList(groups, groups.getN())); diff --git a/src/main/java/sk/gymy/seminar/persistence/SeminarImporter.java b/src/main/java/sk/gymy/seminar/persistence/SeminarImporter.java index bf02dc0..9bb57bf 100644 --- a/src/main/java/sk/gymy/seminar/persistence/SeminarImporter.java +++ b/src/main/java/sk/gymy/seminar/persistence/SeminarImporter.java @@ -48,11 +48,11 @@ public String getInputFileSuffix() { } public static String calculatePossibleSolutionSize(Groups groups) { - int studentN = groups.getStudentList().size(); int seminarN = groups.getSeminarList().size(); - //TODO int teacherN = groups.getTeacherList.size(); - int N = groups.getN(); - BigInteger possibleSolutionSize = BigIntegerMath.binomial(studentN, (N*studentN)/seminarN).multiply(BigInteger.valueOf(seminarN)); + int groupsN = groups.getN(); + int n = groupsN*seminarN; + int k = seminarN; + BigInteger possibleSolutionSize = BigIntegerMath.binomial(n, k); return getFlooredPossibleSolutionSize(possibleSolutionSize); } diff --git a/src/main/java/sk/gymy/seminar/swingui/SeminarPanel.java b/src/main/java/sk/gymy/seminar/swingui/SeminarPanel.java index fde051f..93e7931 100644 --- a/src/main/java/sk/gymy/seminar/swingui/SeminarPanel.java +++ b/src/main/java/sk/gymy/seminar/swingui/SeminarPanel.java @@ -41,7 +41,7 @@ public SeminarPanel() { } private Groups getGroups() { - return (Groups) solutionBusiness.getSolution(); + return (Groups) getSolutionBusiness().getSolution(); } public void resetPanel(Solution solution) { diff --git a/src/main/resources/sk/gymy/seminar/benchmark/seminarBenchmarkConfig.xml b/src/main/resources/sk/gymy/seminar/benchmark/seminarBenchmarkConfig.xml index e2e80e4..976a407 100644 --- a/src/main/resources/sk/gymy/seminar/benchmark/seminarBenchmarkConfig.xml +++ b/src/main/resources/sk/gymy/seminar/benchmark/seminarBenchmarkConfig.xml @@ -10,9 +10,9 @@ data/seminar/unsolved/simple5.xml data/seminar/unsolved/gymy2014-2.xml data/seminar/unsolved/gymy2014-4.xml - data/seminar/unsolved/G3St20Sem18-seminar.xml - data/seminar/unsolved/G3St200Sem180-seminar.xml - data/seminar/unsolved/G3St2000Sem1800-seminar.xml + data/seminar/unsolved/G3St20Tea6Sem18-seminar.xml + data/seminar/unsolved/G3St200Tea60Sem180-seminar.xml + data/seminar/unsolved/G3St2000Tea600Sem1800-seminar.xml true BEST_SCORE @@ -26,7 +26,7 @@ OR - 0/0 + 0hard/0soft 60 diff --git a/src/main/resources/sk/gymy/seminar/benchmark/seminarStepLimitBenchmarkConfig.xml b/src/main/resources/sk/gymy/seminar/benchmark/seminarStepLimitBenchmarkConfig.xml index a6fdbc4..17cf2ae 100644 --- a/src/main/resources/sk/gymy/seminar/benchmark/seminarStepLimitBenchmarkConfig.xml +++ b/src/main/resources/sk/gymy/seminar/benchmark/seminarStepLimitBenchmarkConfig.xml @@ -6,11 +6,11 @@ sk.gymy.seminar.domain.Groups data/seminar/unsolved/simple5.xml - data/seminar/unsolved/gymy-2014-4.xml - data/seminar/unsolved/gyny-2014-2.xml - data/seminar/unsolved/G3St20Sem18-seminar.xml - data/seminar/unsolved/G3St200Sem180-seminar.xml - data/seminar/unsolved/G3St2000Sem1800-seminar.xml + data/seminar/unsolved/gymy2014-2.xml + data/seminar/unsolved/gymy2014-4.xml + data/seminar/unsolved/G3St20Tea6Sem18-seminar.xml + data/seminar/unsolved/G3St200Tea60Sem180-seminar.xml + data/seminar/unsolved/G3St2000Tea600Sem1800-seminar.xml sk.gymy.seminar.domain.Groups diff --git a/src/main/resources/sk/gymy/seminar/solver/seminarSolverConfig.xml b/src/main/resources/sk/gymy/seminar/solver/seminarSolverConfig.xml index 2a3391a..9ad72aa 100644 --- a/src/main/resources/sk/gymy/seminar/solver/seminarSolverConfig.xml +++ b/src/main/resources/sk/gymy/seminar/solver/seminarSolverConfig.xml @@ -22,14 +22,8 @@ HARD_SOFT - - - sk/gymy/seminar/solver/seminarScoreRules.drl ONLY_DOWN - - - @@ -50,18 +44,4 @@ - - - - - - - - - - - - - - diff --git a/src/test/java/sk/gymy/seminar/app/SeminarAppTest.java b/src/test/java/sk/gymy/seminar/app/SeminarAppTest.java index ce9905a..e5f5e8e 100644 --- a/src/test/java/sk/gymy/seminar/app/SeminarAppTest.java +++ b/src/test/java/sk/gymy/seminar/app/SeminarAppTest.java @@ -16,18 +16,111 @@ package sk.gymy.seminar.app; +import com.google.common.io.Files; +import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; -import org.optaplanner.core.api.solver.Solver; +import javax.swing.*; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; public class SeminarAppTest { + private SeminarApp seminarApp; + + @Before + public void setUp() { + seminarApp = new SeminarApp(); + } + + @Test + @Ignore("No X11 DISPLAY variable was set, but this program performed an operation which requires it.") + public void testSwingUI() throws IOException { + SeminarApp.prepareSwingEnvironment(); + SeminarApp.prepareDataDirStructure(Files.createTempDir()); + JWindow window = new JWindow(); + seminarApp.init(window, true); + assertNotNull(seminarApp); + window.dispose(); + } + @Test - public void createSolverByApi() { - SeminarApp seminarApp = new SeminarApp(); - Solver solver = seminarApp.createSolverByApi(); - assertNotNull(solver); + public void testCreateMethods() { + assertNotNull(seminarApp.createSolutionDao()); + assertNotNull(seminarApp.createSolutionImporter()); + assertNotNull(seminarApp.createSolutionExporter()); + assertNotNull(seminarApp.createSolutionPanel()); + assertNotNull(seminarApp.createSolver()); + assertNotNull(seminarApp.createSolverByApi()); + assertNotNull(seminarApp.createSolverByXml()); + assertNotNull(seminarApp.createSolutionBusiness()); + } + + @Test + public void testPrepareDataDirStructure() throws IOException { + File baseDir = Files.createTempDir(); + assertTrue(baseDir.exists()); + assertTrue(baseDir.isDirectory()); + SeminarApp.prepareDataDirStructure(baseDir); + File dataDir = new File(baseDir.getPath() + "/data/seminar"); + assertTrue(dataDir.exists()); + assertTrue(dataDir.isDirectory()); + String[] dirNames = {"export", "import", "solved", "unsolved"}; + String[] dataDirList = dataDir.list(); + Arrays.sort(dataDirList); + assertArrayEquals(dirNames, dataDirList); + for (String dirName : dirNames) { + File dir = new File(dataDir.getPath() + "/" + dirName); + assertTrue(dir.exists()); + assertTrue(dir.isDirectory()); + assertEquals(0, dir.listFiles().length); + assertTrue(dir.delete()); + assertFalse(dir.exists()); + } + assertTrue(dataDir.delete()); + assertFalse(dataDir.exists()); + assertTrue(dataDir.getParentFile().delete()); + assertFalse(dataDir.getParentFile().exists()); + assertTrue(baseDir.delete()); + assertFalse(baseDir.exists()); + } + + @Test(expected = IllegalArgumentException.class) + public void testPrepareDataDirStructureBaseDirNotDir() throws IOException { + File baseDir = File.createTempFile("dataDir", ""); + assertTrue(baseDir.exists()); + assertFalse(baseDir.isDirectory()); + try { + SeminarApp.prepareDataDirStructure(baseDir); + } catch (IllegalArgumentException iae) { + assertTrue(baseDir.delete()); + assertFalse(baseDir.exists()); + throw iae; + } + } + + @Test(expected = IOException.class) + public void testPrepareDataDirStructureBaseDirIllegal() throws IOException { + File baseDir = Files.createTempDir(); + assertTrue(baseDir.setReadOnly()); + assertTrue(baseDir.exists()); + assertTrue(baseDir.isDirectory()); + try { + SeminarApp.prepareDataDirStructure(baseDir); + } catch (IOException ioe) { + assertTrue(baseDir.delete()); + assertFalse(baseDir.exists()); + throw ioe; + } } } diff --git a/src/test/java/sk/gymy/seminar/app/SeminarBenchmarkAppTest.java b/src/test/java/sk/gymy/seminar/app/SeminarBenchmarkAppTest.java new file mode 100644 index 0000000..9d90376 --- /dev/null +++ b/src/test/java/sk/gymy/seminar/app/SeminarBenchmarkAppTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.app; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Ignore; +import org.junit.Test; + +public class SeminarBenchmarkAppTest { + + @Test + public void testSeminarBenchmarkApp() { + SeminarBenchmarkApp sba = new SeminarBenchmarkApp(); + assertNotNull(sba); + //sba.buildAndBenchmark(new String[0]); + } + + @Test + @Ignore + public void testBuildAndBenchmark() { + SeminarBenchmarkApp sba = new SeminarBenchmarkApp(); + assertNotNull(sba); + sba.buildAndBenchmark(new String[0]); + } +} diff --git a/src/test/java/sk/gymy/seminar/app/GroupsBenchmarkTest.java b/src/test/java/sk/gymy/seminar/app/SeminarBenchmarkTest.java similarity index 94% rename from src/test/java/sk/gymy/seminar/app/GroupsBenchmarkTest.java rename to src/test/java/sk/gymy/seminar/app/SeminarBenchmarkTest.java index a5520a4..e842150 100644 --- a/src/test/java/sk/gymy/seminar/app/GroupsBenchmarkTest.java +++ b/src/test/java/sk/gymy/seminar/app/SeminarBenchmarkTest.java @@ -21,7 +21,7 @@ import java.io.File; -public class GroupsBenchmarkTest extends PlannerBenchmarkTest { +public class SeminarBenchmarkTest extends PlannerBenchmarkTest { @Override protected String createBenchmarkConfigResource() { diff --git a/src/test/java/sk/gymy/seminar/app/GroupsBranchAndBoundTest.java b/src/test/java/sk/gymy/seminar/app/SeminarBranchAndBoundTest.java similarity index 83% rename from src/test/java/sk/gymy/seminar/app/GroupsBranchAndBoundTest.java rename to src/test/java/sk/gymy/seminar/app/SeminarBranchAndBoundTest.java index 7e87f7b..02ed8f6 100644 --- a/src/test/java/sk/gymy/seminar/app/GroupsBranchAndBoundTest.java +++ b/src/test/java/sk/gymy/seminar/app/SeminarBranchAndBoundTest.java @@ -29,7 +29,7 @@ import java.io.File; import java.util.Collections; -public class GroupsBranchAndBoundTest extends SolverPerformanceTest { +public class SeminarBranchAndBoundTest extends SolverPerformanceTest { @Override protected String createSolverConfigResource() { @@ -57,24 +57,24 @@ protected SolverFactory buildSolverFactory(String bestScoreLimitString, Environm // Tests // ************************************************************************ - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_simple5() { runSpeedTest(new File("data/seminar/unsolved/simple5.xml"), "0hard/0soft", EnvironmentMode.REPRODUCIBLE); } - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_unsolvable5() { runSpeedTest(new File("data/seminar/unsolved/unsolvable5.xml"), "0hard/-1soft", EnvironmentMode.REPRODUCIBLE); } - @Test(timeout = 600000) - public void solveModel_gymy2014_2() { - runSpeedTest(new File("data/seminar/unsolved/gymy2014-2.xml"), "-22hard/-17soft", EnvironmentMode.REPRODUCIBLE); + @Test(timeout = 60000) + public void solveModel_gymy2014_2() { // TODO BranchAndBound can't solve to the best score, which is "-22hard/-10soft" + runSpeedTest(new File("data/seminar/unsolved/gymy2014-2.xml"), "-22hard/-18soft", EnvironmentMode.PRODUCTION); } - @Test(timeout = 600000) - public void solveModel_gymy2014_4() { - runSpeedTest(new File("data/seminar/unsolved/gymy2014-4.xml"), "-8hard/-4soft", EnvironmentMode.REPRODUCIBLE); + @Test(timeout = 60000) + public void solveModel_gymy2014_4() { // TODO BranchAndBound can't solve to the best score, which is "-8hard/-3soft" + runSpeedTest(new File("data/seminar/unsolved/gymy2014-4.xml"), "-8hard/-4soft", EnvironmentMode.PRODUCTION); } } diff --git a/src/test/java/sk/gymy/seminar/app/GroupsBruteForceTest.java b/src/test/java/sk/gymy/seminar/app/SeminarBruteForceTest.java similarity index 87% rename from src/test/java/sk/gymy/seminar/app/GroupsBruteForceTest.java rename to src/test/java/sk/gymy/seminar/app/SeminarBruteForceTest.java index 3048081..30c45d1 100644 --- a/src/test/java/sk/gymy/seminar/app/GroupsBruteForceTest.java +++ b/src/test/java/sk/gymy/seminar/app/SeminarBruteForceTest.java @@ -16,6 +16,7 @@ package sk.gymy.seminar.app; +import org.junit.Ignore; import org.junit.Test; import org.optaplanner.core.api.solver.SolverFactory; import org.optaplanner.core.config.exhaustivesearch.ExhaustiveSearchPhaseConfig; @@ -29,7 +30,7 @@ import java.io.File; import java.util.Collections; -public class GroupsBruteForceTest extends SolverPerformanceTest { +public class SeminarBruteForceTest extends SolverPerformanceTest { @Override protected String createSolverConfigResource() { @@ -56,24 +57,26 @@ protected SolverFactory buildSolverFactory(String bestScoreLimitString, Environm // Tests // ************************************************************************ - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_simple5() { runSpeedTest(new File("data/seminar/unsolved/simple5.xml"), "0hard/0soft", EnvironmentMode.REPRODUCIBLE); } - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_unsolvable5() { runSpeedTest(new File("data/seminar/unsolved/unsolvable5.xml"), "0hard/-1soft", EnvironmentMode.REPRODUCIBLE); } - @Test(timeout = 600000) + @Test(timeout = 60000) + @Ignore("Test takes too long.") public void solveModel_gymy2014_2() { - runSpeedTest(new File("data/seminar/unsolved/gymy2014-2.xml"), "-22hard/-17soft", EnvironmentMode.REPRODUCIBLE); + runSpeedTest(new File("data/seminar/unsolved/gymy2014-2.xml"), "-22hard/-10soft", EnvironmentMode.REPRODUCIBLE); } - @Test(timeout = 600000) + @Test(timeout = 60000) + @Ignore("Test takes too long.") public void solveModel_gymy2014_4() { - runSpeedTest(new File("data/seminar/unsolved/gymy2014-4.xml"), "-8hard/-4soft", EnvironmentMode.REPRODUCIBLE); + runSpeedTest(new File("data/seminar/unsolved/gymy2014-4.xml"), "-8hard/-3soft", EnvironmentMode.REPRODUCIBLE); } } diff --git a/src/test/java/sk/gymy/seminar/app/SeminarHelloWorldTest.java b/src/test/java/sk/gymy/seminar/app/SeminarHelloWorldTest.java new file mode 100644 index 0000000..b774bc9 --- /dev/null +++ b/src/test/java/sk/gymy/seminar/app/SeminarHelloWorldTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.app; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SeminarHelloWorldTest { + + @Test + public void testHelloWorldMain() { + SeminarHelloWorld.main(new String[0]); + } + + @Test + public void testHelloWorld() { + final String expected = "\nSolved 5 Seminars:\n" + + "Group 0: s02, s03, \n" + + "Group 1: s04, \n" + + "Group 2: s01, s05, \n"; + String result = SeminarHelloWorld.solveHelloWorld(); + assertEquals(expected, result); + } +} + diff --git a/src/test/java/sk/gymy/seminar/app/GroupsPerformanceTest.java b/src/test/java/sk/gymy/seminar/app/SeminarPerformanceTest.java similarity index 87% rename from src/test/java/sk/gymy/seminar/app/GroupsPerformanceTest.java rename to src/test/java/sk/gymy/seminar/app/SeminarPerformanceTest.java index feef6cb..6e46edf 100644 --- a/src/test/java/sk/gymy/seminar/app/GroupsPerformanceTest.java +++ b/src/test/java/sk/gymy/seminar/app/SeminarPerformanceTest.java @@ -24,7 +24,7 @@ import java.io.File; -public class GroupsPerformanceTest extends SolverPerformanceTest { +public class SeminarPerformanceTest extends SolverPerformanceTest { @Override protected String createSolverConfigResource() { @@ -40,19 +40,19 @@ protected SolutionDao createSolutionDao() { // Tests // ************************************************************************ - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_gymy2014_4() { runSpeedTest(new File("data/seminar/unsolved/gymy2014-4.xml"), - "-10hard/-5soft"); + "-8hard/-3soft"); } - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_gymy2014_2_FastAssert() { runSpeedTest(new File("data/seminar/unsolved/gymy2014-2.xml"), - "-22hard/-17soft", EnvironmentMode.FAST_ASSERT); + "-22hard/-10soft", EnvironmentMode.FAST_ASSERT); } - @Test(timeout = 600000) + @Test(timeout = 60000) public void solveModel_simple5FullAssert() { runSpeedTest(new File("data/seminar/unsolved/simple5.xml"), "0hard/0soft", EnvironmentMode.FULL_ASSERT); diff --git a/src/test/java/sk/gymy/seminar/app/GroupsSolveAllTurtleTest.java b/src/test/java/sk/gymy/seminar/app/SeminarSolveAllTurtleTest.java similarity index 90% rename from src/test/java/sk/gymy/seminar/app/GroupsSolveAllTurtleTest.java rename to src/test/java/sk/gymy/seminar/app/SeminarSolveAllTurtleTest.java index a310c15..988a0c5 100644 --- a/src/test/java/sk/gymy/seminar/app/GroupsSolveAllTurtleTest.java +++ b/src/test/java/sk/gymy/seminar/app/SeminarSolveAllTurtleTest.java @@ -24,14 +24,14 @@ import java.io.File; import java.util.Collection; -public class GroupsSolveAllTurtleTest extends UnsolvedDirSolveAllTurtleTest { +public class SeminarSolveAllTurtleTest extends UnsolvedDirSolveAllTurtleTest { @Parameterized.Parameters(name = "{index}: {0}") public static Collection getSolutionFilesAsParameters() { return getUnsolvedDirFilesAsParameters(new SeminarDao()); } - public GroupsSolveAllTurtleTest(File unsolvedDataFile) { + public SeminarSolveAllTurtleTest(File unsolvedDataFile) { super(unsolvedDataFile); } diff --git a/src/test/java/sk/gymy/seminar/domain/GroupTest.java b/src/test/java/sk/gymy/seminar/domain/GroupTest.java new file mode 100644 index 0000000..04abd9f --- /dev/null +++ b/src/test/java/sk/gymy/seminar/domain/GroupTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sk.gymy.seminar.domain; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; + +public class GroupTest { + + @Test + public void equalsAndHashCodeTest() { + Group g1 = new Group(); + Group g2 = new Group(); + assertEquals(g1, g2); + assertFalse(g1 == g2); + assertEquals(g1.hashCode(), g2.hashCode()); + g1.setIndex(1); + assertNotEquals(g1, g2); + assertFalse(g1 == g2); + assertNotEquals(g1.hashCode(), g2.hashCode()); + g2.setIndex(1); + assertEquals(g1, g2); + assertFalse(g1 == g2); + assertEquals(g1.hashCode(), g2.hashCode()); + g1.setIndex(2); + assertNotEquals(g1, g2); + assertFalse(g1 == g2); + assertNotEquals(g1.hashCode(), g2.hashCode()); + } + + @Test + public void toStringTest() { + Group g = new Group(); + assertEquals("G0", g.toString()); + g.setIndex(1234); + assertEquals("G1234", g.toString()); + g.setIndex(-5); + assertEquals("G-5", g.toString()); + } + +} diff --git a/src/test/java/sk/gymy/seminar/domain/PersonTest.java b/src/test/java/sk/gymy/seminar/domain/PersonTest.java new file mode 100644 index 0000000..664ff9d --- /dev/null +++ b/src/test/java/sk/gymy/seminar/domain/PersonTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.domain; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; + +public class PersonTest { + + @Test + public void equalsAndHashCodeTest() { + Person p1 = new Person(); + Person p2 = new Person(); + assertEquals(p1, p2); + assertFalse(p1 == p2); + assertEquals(p1.hashCode(), p2.hashCode()); + p1.setIndex(1); + assertNotEquals(p1, p2); + assertFalse(p1 == p2); + assertNotEquals(p1.hashCode(), p2.hashCode()); + p2.setIndex(1); + assertEquals(p1, p2); + assertFalse(p1 == p2); + assertEquals(p1.hashCode(), p2.hashCode()); + p1.setIndex(2); + assertNotEquals(p1, p2); + assertFalse(p1 == p2); + assertNotEquals(p1.hashCode(), p2.hashCode()); + p2.setIndex(p1.getIndex()); + p1.setName(""); + p2.setName(""); + assertEquals(p1, p2); + assertFalse(p1 == p2); + assertEquals(p1.hashCode(), p2.hashCode()); + p1.setName("Anna Harbour"); + assertNotEquals(p1, p2); + assertFalse(p1 == p2); + assertNotEquals(p1.hashCode(), p2.hashCode()); + p2.setName("Anna Harbour"); + assertEquals(p1, p2); + assertFalse(p1 == p2); + assertEquals(p1.hashCode(), p2.hashCode()); + + } + + @Test + public void toStringTest() { + Person person = new Person(); + assertEquals(null, person.toString()); + person.setIndex(1234); + assertEquals(null, person.toString()); + person.setName("John Stuart"); + assertEquals("John Stuart", person.toString()); + } + +} diff --git a/src/test/java/sk/gymy/seminar/domain/SeminarTest.java b/src/test/java/sk/gymy/seminar/domain/SeminarTest.java new file mode 100644 index 0000000..3f574dc --- /dev/null +++ b/src/test/java/sk/gymy/seminar/domain/SeminarTest.java @@ -0,0 +1,94 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.domain; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; + +public class SeminarTest { + + @Test + public void equalsAndHashCodeTest() { + Seminar s1 = new Seminar(); + Seminar s2 = new Seminar(); + assertEquals(s1, s2); + assertFalse(s1 == s2); + assertEquals(s1.hashCode(), s2.hashCode()); + + Teacher teacher = new Teacher(); + Group group = new Group(1); + s1 = new Seminar(1, "ANJ", true, teacher, null, group); + s2 = new Seminar(1, "ANJ", true, teacher, null, group); + assertEquals(s1, s2); + assertFalse(s1 == s2); + assertEquals(s1.hashCode(), s2.hashCode()); + + s1.setTeacher(new Teacher(1, "Joan King")); + s2.setTeacher(new Teacher(1, "Joan King")); + s1.setLocked(false); + s2.setLocked(false); + assertEquals(s1, s2); + assertFalse(s1 == s2); + assertEquals(s1.hashCode(), s2.hashCode()); + + List studentList1 = new ArrayList<>(); + studentList1.add(new Student(1, "Johan")); + studentList1.add(new Student(2, "John")); + studentList1.add(new Student()); + s1.setStudents(studentList1); + List studentList2 = new ArrayList<>(); + studentList2.add(new Student(1, "Johan")); + studentList2.add(new Student(2, "John")); + studentList2.add(new Student(3, "Jan")); + s2.setStudents(studentList2); + assertNotEquals(s1, s2); + assertFalse(s1 == s2); + assertNotEquals(s1.hashCode(), s2.hashCode()); + + s2.getStudents().remove(2); + s1.getStudents().remove(2); + assertEquals(s1, s2); + assertFalse(s1 == s2); + assertEquals(s1.hashCode(), s2.hashCode()); + + // Unequal groups produce equal seminars, because a seminar's group is a Planning Variable + s1.setGroup(new Group(2)); + assertNotEquals(s1.getGroup(), s2.getGroup()); + assertEquals(s1, s2); + assertFalse(s1 == s2); + assertEquals(s1.hashCode(), s2.hashCode()); + } + + @Test + public void toStringTest() { + Seminar seminar = new Seminar(); + assertEquals("null: null", seminar.toString()); + seminar.setIndex(1234); + assertEquals("null: null", seminar.toString()); + seminar.setName("ANJ"); + assertEquals("ANJ: null", seminar.toString()); + seminar.setGroup(new Group(12345)); + assertEquals("ANJ: G12345", seminar.toString()); + } + +} diff --git a/src/test/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactoryTest.java b/src/test/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactoryTest.java new file mode 100644 index 0000000..d2f5460 --- /dev/null +++ b/src/test/java/sk/gymy/seminar/domain/solver/GroupStrengthWeightFactoryTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.domain.solver; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.optaplanner.core.api.solver.Solver; +import org.optaplanner.core.api.solver.SolverFactory; +import sk.gymy.seminar.app.SeminarApp; +import sk.gymy.seminar.domain.Group; +import sk.gymy.seminar.domain.Groups; +import sk.gymy.seminar.persistence.SeminarImporter; + +import java.io.File; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class GroupStrengthWeightFactoryTest { + + private static Groups groups; + private static Groups solvedGroups; + + @BeforeClass + public static void setUpClass() { + groups = (Groups) new SeminarImporter().readSolution(new File("data/seminar/import/simple5.sem")); + assertNotNull(groups); + assertEquals("Seminar-simple-5", groups.getName()); + assertEquals(3, groups.getN()); + assertEquals(20, groups.getStudentList().size()); + assertEquals(3, groups.getTeacherList().size()); + assertEquals(5, groups.getSeminarList().size()); + assertNull(groups.getScore()); + + solvedGroups = groups; + SolverFactory solverFactory = SolverFactory.createFromXmlResource(SeminarApp.SOLVER_CONFIG); + Solver solver = solverFactory.buildSolver(); + solver.solve(solvedGroups); + solvedGroups = (Groups) solver.getBestSolution(); + assertNotEquals(solvedGroups, groups); // Asserts, that the groups stays uninitialized + assertEquals("Groups{name=Seminar-simple-5, score=-2hard/-20soft, seminarList=[s01: null, s02: null, s03: null, s04: null, s05: null]}", groups.toString()); + assertEquals("Groups{name=Seminar-simple-5, score=0hard/0soft, seminarList=[s01: G2, s02: G0, s03: G0, s04: G1, s05: G2]}", solvedGroups.toString()); + } + + @Test + public void testCreateSorterWeight() { + GroupStrengthWeightFactory groupStrengthWeightFactory = new GroupStrengthWeightFactory(); + assertNotNull(groupStrengthWeightFactory); + for (Group group : groups.getGroupList()) { + assertNotNull(group); + GroupStrengthWeightFactory.GroupStrengthWeight groupStrengthWeight = + (GroupStrengthWeightFactory.GroupStrengthWeight) + groupStrengthWeightFactory.createSorterWeight(groups, group); + assertNotNull(groupStrengthWeight); + assertEquals(group, groupStrengthWeight.getGroup()); + assertEquals(0, groupStrengthWeight.getSeminarCount()); // This is an uninitialized solution + } + } + + @Test + public void testNullGroup() { + GroupStrengthWeightFactory groupStrengthWeightFactory = new GroupStrengthWeightFactory(); + assertNotNull(groupStrengthWeightFactory); + GroupStrengthWeightFactory.GroupStrengthWeight groupStrengthWeight = + (GroupStrengthWeightFactory.GroupStrengthWeight) + groupStrengthWeightFactory.createSorterWeight(groups, null); + assertNotNull(groupStrengthWeight); + assertEquals(null, groupStrengthWeight.getGroup()); + assertEquals(0, groupStrengthWeight.getSeminarCount()); // This is an uninitialized solution + } + + @Test + public void testSolvedSolution() { + GroupStrengthWeightFactory groupStrengthWeightFactory = new GroupStrengthWeightFactory(); + assertNotNull(groupStrengthWeightFactory); + for (Group group : solvedGroups.getGroupList()) { + assertNotNull(group); + GroupStrengthWeightFactory.GroupStrengthWeight groupStrengthWeight = + (GroupStrengthWeightFactory.GroupStrengthWeight) + groupStrengthWeightFactory.createSorterWeight(solvedGroups, group); + assertNotNull(groupStrengthWeight); + assertEquals(group, groupStrengthWeight.getGroup()); + assertNotEquals(0, groupStrengthWeight.getSeminarCount()); // This is a solved solution + } + } + +} diff --git a/src/test/java/sk/gymy/seminar/persistence/SeminarExporterTest.java b/src/test/java/sk/gymy/seminar/persistence/SeminarExporterTest.java new file mode 100644 index 0000000..7a31c87 --- /dev/null +++ b/src/test/java/sk/gymy/seminar/persistence/SeminarExporterTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.persistence; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import sk.gymy.seminar.domain.Groups; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class SeminarExporterTest { + + private Path outputPath; + private Groups groups; + + @Before + public void setUp() throws IOException { + outputPath = Files.createTempFile("seminarExportTest", "." + new SeminarExporter().getOutputFileSuffix()); + + this.groups = (Groups) new SeminarImporter().readSolution(new File("data/seminar/import/simple5.sem")); + assertNotNull(groups); + assertEquals("Seminar-simple-5", groups.getName()); + assertEquals(3, groups.getN()); + assertEquals(20, groups.getStudentList().size()); + assertEquals(3, groups.getTeacherList().size()); + assertEquals(5, groups.getSeminarList().size()); + assertNull(groups.getScore()); + } + + @After + public void tearDown() throws IOException { + Files.delete(outputPath); + } + + @Test + public void testSeminarExporterMain() { + SeminarExporter.main(new String[0]); + } + + @Test + public void testWriteSolution() throws IOException { + SeminarExporter seminarExporter = new SeminarExporter(); + seminarExporter.writeSolution(groups, outputPath.toFile()); + final String expected = "Name: Seminar-simple-5\n" + + "Groups: 3\n" + + "\n" + + "Group 0: \n" + + "Group 1: \n" + + "Group 2: "; + List result = Files.readAllLines(outputPath, Charset.defaultCharset()); + String[] resultArr = new String[result.size()]; + assertArrayEquals(expected.split("\n"), result.toArray(resultArr)); + } + + @Test + public void testOutputBuilder() throws IOException { + SeminarExporter.SeminarOutputBuilder sob = new SeminarExporter.SeminarOutputBuilder(); + assertNotNull(sob); + sob.setSolution(groups); + StringWriter sw = new StringWriter(); + BufferedWriter bw = new BufferedWriter(sw); + sob.setBufferedWriter(bw); + sob.writeSolution(); + bw.close(); + assertNotEquals("Empty StringWriter", "", sw.toString()); + assertEquals(sw.getBuffer().substring(0), sw.toString()); + assertEquals("Name: Seminar-simple-5\nGroups: 3\n\nGroup 0: \nGroup 1: \nGroup 2: \n", sw.toString()); + } + +} diff --git a/src/test/java/sk/gymy/seminar/persistence/SeminarGeneratorTest.java b/src/test/java/sk/gymy/seminar/persistence/SeminarGeneratorTest.java new file mode 100644 index 0000000..55413f4 --- /dev/null +++ b/src/test/java/sk/gymy/seminar/persistence/SeminarGeneratorTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.persistence; + +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mockito; +import org.optaplanner.examples.common.persistence.SolutionDao; +import sk.gymy.seminar.domain.Groups; + +import java.io.File; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class SeminarGeneratorTest { + + /** + * Shouldn't actually write anything to the filesystem + */ + @Test + public void testGenerate() { + SolutionDao daoMock = Mockito.mock(SeminarDao.class); + Mockito.when(daoMock.getDataDir()).thenReturn(new File("/tmp/generateTestDir")); + SeminarGenerator generator = new SeminarGenerator(daoMock); + generator.generate(); + Mockito.verify(daoMock).writeSolution(Mockito.any(Groups.class), + Mockito.eq(new File("/tmp/generateTestDir/unsolved/G3St20Tea6Sem18-seminar.xml"))); + } + + @Test + public void testCreateGroups() { + SeminarGenerator generator = new SeminarGenerator(); + Groups groups = generator.createGroups(3, 20, 6, 18); + assertNotNull(groups); + assertEquals("G3St20Tea6Sem18", groups.getName()); + assertEquals(3, groups.getN()); + assertEquals(20, groups.getStudentList().size()); + assertEquals(6, groups.getTeacherList().size()); + assertEquals(18, groups.getSeminarList().size()); + assertNull(groups.getScore()); + } + + @Test + @Ignore("Test pollutes the data/seminar/unsolved directory") + public void testSeminarGeneratorMain() { + SeminarGenerator.main(new String[0]); + } + +} diff --git a/src/test/java/sk/gymy/seminar/persistence/SeminarImporterTest.java b/src/test/java/sk/gymy/seminar/persistence/SeminarImporterTest.java new file mode 100644 index 0000000..d14daca --- /dev/null +++ b/src/test/java/sk/gymy/seminar/persistence/SeminarImporterTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.persistence; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import sk.gymy.seminar.domain.Groups; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class SeminarImporterTest { + + private Path file; + private Path dir; + private Path fileEdited; + + @Before + public void setUp() throws IOException { + dir = Files.createTempDirectory("seminarImporterTest"); + file = Paths.get(dir.toString(), "simple5.sem"); + fileEdited = Paths.get(dir.toString(), "simple5_edit.sem"); + Files.copy(Paths.get("data/seminar/import/simple5.sem"), file); + } + + @After + public void tearDown() throws IOException { + Files.deleteIfExists(fileEdited); + Files.deleteIfExists(file); + Files.deleteIfExists(dir); + } + + @Test + public void testSeminarImporterMain() { + SeminarImporter.main(new String[0]); + } + + @Test + public void testReadSolution() { + SeminarImporter seminarImporter = new SeminarImporter(); + Groups groups = (Groups) seminarImporter.readSolution(new File("data/seminar/import/simple5.sem")); + assertNotNull(groups); + assertEquals("Seminar-simple-5", groups.getName()); + assertEquals(3, groups.getN()); + assertEquals(20, groups.getStudentList().size()); + assertEquals(3, groups.getTeacherList().size()); + assertEquals(5, groups.getSeminarList().size()); + assertNull(groups.getScore()); + } + + @Test(expected = IllegalStateException.class) + public void testInputBuilderNonExistingTeacher() throws IOException { + BufferedReader br = new BufferedReader(new FileReader(file.toFile())); + BufferedWriter bw = new BufferedWriter(new FileWriter(fileEdited.toFile())); + String buffer; + while ((buffer = br.readLine()) != null) { + if (buffer.contains("s05 t02")) { + assertEquals("s05 t04 2 5 7 8 12 15 16 19", buffer = buffer.replace("t02", "t04")); + } + bw.write(buffer); + bw.newLine(); + bw.flush(); + } + br.close(); + bw.close(); + SeminarImporter seminarImporter = new SeminarImporter(); + seminarImporter.readSolution(fileEdited.toFile()); // IllegalStateException should be thrown + } + + @Test(expected = IllegalStateException.class) + public void testInputBuilderNonExistingStudent() throws IOException { + BufferedReader br = new BufferedReader(new FileReader(file.toFile())); + BufferedWriter bw = new BufferedWriter(new FileWriter(fileEdited.toFile())); + String buffer; + while ((buffer = br.readLine()) != null) { + if (buffer.contains("s05 t02")) { + assertEquals("s05 t02 2 5 7 8 12 15 16 21", buffer = buffer.replace("19", "21")); + } + bw.write(buffer); + bw.newLine(); + bw.flush(); + } + br.close(); + bw.close(); + SeminarImporter seminarImporter = new SeminarImporter(); + seminarImporter.readSolution(fileEdited.toFile()); // IllegalStateException should be thrown + } + +} diff --git a/src/test/java/sk/gymy/seminar/swingui/SeminarPanelTest.java b/src/test/java/sk/gymy/seminar/swingui/SeminarPanelTest.java new file mode 100644 index 0000000..e6493f8 --- /dev/null +++ b/src/test/java/sk/gymy/seminar/swingui/SeminarPanelTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2014 Ondrej Skopek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sk.gymy.seminar.swingui; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.optaplanner.core.api.solver.Solver; +import org.optaplanner.core.api.solver.SolverFactory; +import sk.gymy.seminar.app.SeminarApp; +import sk.gymy.seminar.domain.Groups; +import sk.gymy.seminar.persistence.SeminarImporter; + +import javax.swing.*; +import java.awt.*; +import java.io.File; + +public class SeminarPanelTest { + + private SeminarPanel panel; + + private static Groups groups; + private static Groups solvedGroups; + + @BeforeClass + public static void setUpClass() { + groups = (Groups) new SeminarImporter().readSolution(new File("data/seminar/import/simple5.sem")); + assertNotNull(groups); + assertEquals("Seminar-simple-5", groups.getName()); + assertEquals(3, groups.getN()); + assertEquals(20, groups.getStudentList().size()); + assertEquals(3, groups.getTeacherList().size()); + assertEquals(5, groups.getSeminarList().size()); + assertNull(groups.getScore()); + + solvedGroups = groups; + SolverFactory solverFactory = SolverFactory.createFromXmlResource(SeminarApp.SOLVER_CONFIG); + Solver solver = solverFactory.buildSolver(); + solver.solve(solvedGroups); + solvedGroups = (Groups) solver.getBestSolution(); + assertNotEquals(solvedGroups, groups); // Asserts, that the groups stays uninitialized + assertEquals("Groups{name=Seminar-simple-5, score=-2hard/-20soft, seminarList=[s01: null, s02: null, s03: null, s04: null, s05: null]}", groups.toString()); + assertEquals("Groups{name=Seminar-simple-5, score=0hard/0soft, seminarList=[s01: G2, s02: G0, s03: G0, s04: G1, s05: G2]}", solvedGroups.toString()); + } + + @Before + public void setUp() { + panel = new SeminarPanel(); + assertNotNull(panel); + assertEquals(0, panel.getComponents().length); + } + + @Test + public void testPanelUninitialized() { + panel.resetPanel(groups); + assertEquals(3, panel.getComponents().length); // 3 group labels + 0 seminar buttons + } + + @Test + public void testPanelSolved() { + panel.resetPanel(solvedGroups); + assertEquals(8, panel.getComponents().length); // 3 group labels + 5 seminar buttons + } + + @Test + public void testLockIconDrawing() { + solvedGroups.getSeminarList().get(0).setLocked(true); + solvedGroups.getSeminarList().get(2).setLocked(true); + panel.resetPanel(solvedGroups); + assertEquals(8, panel.getComponents().length); // 3 group labels + 5 seminar buttons + int buttonsWithLockIcons = 0; + for (Component component : panel.getComponents()) { + assertNotNull(component); + JButton button; + try { + button = (JButton) component; + } catch (ClassCastException cce) { + continue; // if component isn't a button + } + if (button.getIcon() != null) { + buttonsWithLockIcons++; + } + } + assertEquals(2, buttonsWithLockIcons); // Two locked seminars + solvedGroups.getSeminarList().get(0).setLocked(false); + solvedGroups.getSeminarList().get(2).setLocked(false); + } + +}