Skip to content

Commit

Permalink
docs: correct documentation
Browse files Browse the repository at this point in the history
fixes #1202
  • Loading branch information
TomCools authored and triceo committed Nov 13, 2024
1 parent f95b1dd commit 57953a4
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,14 @@ To complete this guide, you need:
== The build file and the dependencies
Use https://code.quarkus.io/[code.quarkus.io] to generate an application
Use https://code.quarkus.io/?a=timefold-solver-quickstart&j=17&e=resteasy&e=resteasy-jackson&e=ai.timefold.solver%3Atimefold-solver-quarkus-jackson&e=ai.timefold.solver%3Atimefold-solver-quarkus[code.quarkus.io] to generate an application
with the following extensions, for Maven or Gradle:
[NOTE]
====
Clicking the link above will automatically select the dependencies for you on *code.quarkus.io*.
====
* RESTEasy JAX-RS (`quarkus-resteasy`)
* RESTEasy Jackson (`quarkus-resteasy-jackson`)
* Timefold Solver (`timefold-solver-quarkus`)
Expand Down Expand Up @@ -250,9 +255,9 @@ package org.acme.schooltimetabling.rest;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import jakarta.inject.Inject;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import org.acme.schooltimetabling.domain.Timetable;
import ai.timefold.solver.core.api.solver.SolverJob;
Expand Down Expand Up @@ -602,7 +607,7 @@ package org.acme.schooltimetabling.solver;
import java.time.DayOfWeek;
import java.time.LocalTime;
import javax.inject.Inject;
import jakarta.inject.Inject;
import io.quarkus.test.junit.QuarkusTest;
import org.acme.schooltimetabling.domain.Lesson;
Expand All @@ -615,7 +620,7 @@ import ai.timefold.solver.test.api.score.stream.ConstraintVerifier;
@QuarkusTest
class TimetableConstraintProviderTest {
private static final Room ROOM = new Room("Room1");
private static final Room ROOM1 = new Room("Room1");
private static final Timeslot TIMESLOT1 = new Timeslot(DayOfWeek.MONDAY, LocalTime.of(9,0), LocalTime.NOON);
private static final Timeslot TIMESLOT2 = new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(9,0), LocalTime.NOON);
Expand All @@ -624,14 +629,23 @@ class TimetableConstraintProviderTest {
@Test
void roomConflict() {
Lesson firstLesson = new Lesson("1", "Subject1", "Teacher1", "Group1", TIMESLOT1, ROOM1);
Lesson conflictingLesson = new Lesson("2", "Subject2", "Teacher2", "Group2", TIMESLOT1, ROOM1);
Lesson nonConflictingLesson = new Lesson("3", "Subject3", "Teacher3", "Group3", TIMESLOT2, ROOM1);
Lesson firstLesson = createTestLesson("1", "Subject1", "Teacher1", "Group1", TIMESLOT1, ROOM1);
Lesson conflictingLesson = createTestLesson("2", "Subject2", "Teacher2", "Group2", TIMESLOT1, ROOM1);
Lesson nonConflictingLesson = createTestLesson("3", "Subject3", "Teacher3", "Group3", TIMESLOT2, ROOM1);
constraintVerifier.verifyThat(TimetableConstraintProvider::roomConflict)
.given(firstLesson, conflictingLesson, nonConflictingLesson)
.penalizesBy(1);
}
// This methods avoids the need to create a constructor just for testing and uses the setter like the solver does.
Lesson createTestLesson(String id, String subject, String teacher, String studentGroup, Timeslot timeslot, Room room) {
Lesson lesson = new Lesson(id, subject, teacher, group);
lesson.setTimeslot(timeslot);
lesson.setRoom(room);
return lesson;
}
}
----
--
Expand Down Expand Up @@ -670,11 +684,20 @@ class TimetableConstraintProviderTest {
val firstLesson = Lesson("1", "Subject1", "Teacher1", "Group1", TIMESLOT1, ROOM1)
val conflictingLesson = Lesson("2", "Subject2", "Teacher2", "Group2", TIMESLOT1, ROOM1)
val nonConflictingLesson = Lesson("3", "Subject3", "Teacher3", "Group3", TIMESLOT2, ROOM1)
constraintVerifier.verifyThat(TimeTableConstraintProvider::roomConflict)
.given(firstLesson, conflictingLesson, nonConflictingLesson)
.penalizesBy(1)
}
// This methods avoids the need to create a constructor just for testing and uses the setter like the solver does.
fun createTestLesson(String id, String subject, String teacher, String studentGroup, Timeslot timeslot, Room room) : Lesson {
Lesson lesson = Lesson(id, subject, teacher, group);
lesson.setTimeslot(timeslot);
lesson.setRoom(room);
return lesson;
}
}
----
--
Expand Down Expand Up @@ -707,7 +730,6 @@ package org.acme.schooltimetabling.rest;
import static io.restassured.RestAssured.get;
import static io.restassured.RestAssured.given;
import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -738,32 +760,18 @@ class TimetableResourceTest {
@Test
void solveDemoDataUntilFeasible() {
Timetable testTimetable = given()
.when().get("/demo-data/SMALL")
.then()
.statusCode(200)
.extract()
.as(Timetable.class);
Timetable testTimetable = //setup your test data
String jobId = given()
Timetable solution = given()
.contentType(ContentType.JSON)
.body(testTimetable)
.expect().contentType(ContentType.TEXT)
.when().post("/timetables")
.then()
.statusCode(200)
.extract()
.asString();
await()
.atMost(Duration.ofMinutes(1))
.pollInterval(Duration.ofMillis(500L))
.until(() -> SolverStatus.NOT_SOLVING.name().equals(
get("/timetables/" + jobId + "/status")
.jsonPath().get("solverStatus")));
.as(Timetable.class);
Timetable solution = get("/timetables/" + jobId).then().extract().as(Timetable.class);
assertEquals(SolverStatus.NOT_SOLVING, solution.getSolverStatus());
assertNotNull(solution.getLessons());
assertNotNull(solution.getTimeslots());
assertNotNull(solution.getRooms());
Expand Down Expand Up @@ -792,7 +800,6 @@ import io.restassured.http.ContentType
import org.acme.schooltimetabling.domain.Room
import org.acme.schooltimetabling.domain.Timeslot
import org.acme.schooltimetabling.domain.Timetable
import org.awaitility.Awaitility.await
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Assertions.assertTrue
Expand All @@ -804,12 +811,7 @@ class TimetableResourceTest {
@Test
fun solveDemoDataUntilFeasible() {
val testTimetable: Timetable = given()
.`when`()["/demo-data/SMALL"]
.then()
.statusCode(200)
.extract()
.`as`(Timetable::class.java)
val testTimetable: Timetable = //setup your test data
val jobId: String = given()
.contentType(ContentType.JSON)
Expand All @@ -821,14 +823,6 @@ class TimetableResourceTest {
.extract()
.asString()
await()
.atMost(Duration.ofMinutes(1))
.pollInterval(Duration.ofMillis(500L))
.until {
SolverStatus.NOT_SOLVING.name ==
get("/timetables/$jobId/status")
.jsonPath().get("solverStatus")
}
val solution: Timetable =
get("/timetables/$jobId").then().extract().`as`<Timetable>(
Timetable::class.java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public class TimetableConstraintProvider implements ConstraintProvider {
};
}
private Constraint roomConflict(ConstraintFactory constraintFactory) {
Constraint roomConflict(ConstraintFactory constraintFactory) {
// A room can accommodate at most one lesson at the same time.
return constraintFactory
// Select each pair of 2 different lessons ...
Expand All @@ -184,7 +184,7 @@ public class TimetableConstraintProvider implements ConstraintProvider {
.asConstraint("Room conflict");
}
private Constraint teacherConflict(ConstraintFactory constraintFactory) {
Constraint teacherConflict(ConstraintFactory constraintFactory) {
// A teacher can teach at most one lesson at the same time.
return constraintFactory
.forEachUniquePair(Lesson.class,
Expand All @@ -194,7 +194,7 @@ public class TimetableConstraintProvider implements ConstraintProvider {
.asConstraint("Teacher conflict");
}
private Constraint studentGroupConflict(ConstraintFactory constraintFactory) {
Constraint studentGroupConflict(ConstraintFactory constraintFactory) {
// A student can attend at most one lesson at the same time.
return constraintFactory
.forEachUniquePair(Lesson.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ This does not apply to Timefold Solver for Python, since Python does not have pr
====
A planning value range is the set of possible planning values for a planning variable.
Planning value ranges need to be countable, meaning there needs to be a finite number of possible planning values.
Planning value ranges need to come from a finite collection.
[#planningValueRangeProvider]
Expand Down

0 comments on commit 57953a4

Please sign in to comment.