Skip to content

Commit e34ce55

Browse files
thomasyzy7dawangk
andauthored
Ty/scrum 52 timetable generation (#74)
Co-authored-by: dawangk <[email protected]>
1 parent e71811e commit e34ce55

File tree

6 files changed

+744
-2
lines changed

6 files changed

+744
-2
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { describe, expect, it, test } from "@jest/globals";
2+
3+
import {
4+
canInsert,
5+
createOffering,
6+
Offering,
7+
} from "../src/controllers/generatorController";
8+
9+
describe("canInsert function", () => {
10+
const offering1: Offering = createOffering({
11+
id: 1,
12+
course_id: 101,
13+
day: "MO",
14+
start: "09:00:00",
15+
end: "10:00:00",
16+
});
17+
const offering2: Offering = createOffering({
18+
id: 2,
19+
course_id: 102,
20+
day: "MO",
21+
start: "10:00:00",
22+
end: "11:00:00",
23+
});
24+
const offering3: Offering = createOffering({
25+
id: 3,
26+
course_id: 103,
27+
day: "MO",
28+
start: "11:00:00",
29+
end: "12:00:00",
30+
});
31+
32+
it("should return true if there is no overlap with existing offerings", async () => {
33+
const toInsert: Offering = createOffering({
34+
id: 4,
35+
course_id: 104,
36+
day: "MO",
37+
start: "12:00:00",
38+
end: "13:00:00",
39+
});
40+
const curList: Offering[] = [offering1, offering2, offering3];
41+
42+
const result = await canInsert(toInsert, curList);
43+
44+
expect(result).toBe(true); // No overlap, should return true
45+
});
46+
47+
it("should return false if there is an overlap with an existing offering", async () => {
48+
const toInsert: Offering = createOffering({
49+
id: 4,
50+
course_id: 104,
51+
day: "MO",
52+
start: "09:30:00",
53+
end: "10:30:00",
54+
});
55+
const curList: Offering[] = [offering1, offering2, offering3];
56+
57+
const result = await canInsert(toInsert, curList);
58+
59+
expect(result).toBe(false); // There is an overlap with offering1, should return false
60+
});
61+
62+
it("should return true if the new offering starts after the last one ends", async () => {
63+
const toInsert: Offering = createOffering({
64+
id: 4,
65+
course_id: 104,
66+
day: "MO",
67+
start: "13:00:00",
68+
end: "14:00:00",
69+
});
70+
const curList: Offering[] = [offering1, offering2, offering3];
71+
72+
const result = await canInsert(toInsert, curList);
73+
74+
expect(result).toBe(true); // No overlap, should return true
75+
});
76+
77+
it("should return true if the new offering ends before the first one starts", async () => {
78+
const toInsert: Offering = createOffering({
79+
id: 4,
80+
course_id: 104,
81+
day: "MO",
82+
start: "07:00:00",
83+
end: "08:00:00",
84+
});
85+
const curList: Offering[] = [offering1, offering2, offering3];
86+
87+
const result = await canInsert(toInsert, curList);
88+
89+
expect(result).toBe(true); // No overlap, should return true
90+
});
91+
92+
it("should return false if the new offering is completely inside an existing one", async () => {
93+
const toInsert: Offering = createOffering({
94+
id: 4,
95+
course_id: 104,
96+
day: "MO",
97+
start: "09:30:00",
98+
end: "09:45:00",
99+
});
100+
const curList: Offering[] = [offering1, offering2, offering3];
101+
102+
const result = await canInsert(toInsert, curList);
103+
104+
expect(result).toBe(false); // Overlaps with offering1, should return false
105+
});
106+
107+
it("should return true if the day is different (no overlap)", async () => {
108+
const toInsert: Offering = createOffering({
109+
id: 4,
110+
course_id: 104,
111+
day: "TU",
112+
start: "09:00:00",
113+
end: "10:00:00",
114+
});
115+
const curList: Offering[] = [offering1, offering2, offering3];
116+
117+
const result = await canInsert(toInsert, curList);
118+
119+
expect(result).toBe(true); // Different day, no overlap
120+
});
121+
});
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { describe, expect, it, test } from "@jest/globals";
2+
3+
import {
4+
createOffering,
5+
Offering,
6+
getFrequencyTable,
7+
} from "../src/controllers/generatorController";
8+
9+
describe("getFrequencyTable", () => {
10+
test("should return a frequency map of days", () => {
11+
const offering1: Offering = createOffering({
12+
id: 1,
13+
course_id: 101,
14+
day: "MO",
15+
start: "09:00:00",
16+
end: "10:00:00",
17+
});
18+
const offering2: Offering = createOffering({
19+
id: 2,
20+
course_id: 102,
21+
day: "TU",
22+
start: "10:00:00",
23+
end: "11:00:00",
24+
});
25+
const offering3: Offering = createOffering({
26+
id: 3,
27+
course_id: 103,
28+
day: "TU",
29+
start: "11:00:00",
30+
end: "12:00:00",
31+
});
32+
const offering4: Offering = createOffering({
33+
id: 4,
34+
course_id: 104,
35+
day: "MO",
36+
start: "11:00:00",
37+
end: "12:00:00",
38+
});
39+
const offering5: Offering = createOffering({
40+
id: 5,
41+
course_id: 105,
42+
day: "WE",
43+
start: "11:00:00",
44+
end: "12:00:00",
45+
});
46+
const offering6: Offering = createOffering({
47+
id: 6,
48+
course_id: 106,
49+
day: "WE",
50+
start: "11:00:00",
51+
end: "12:00:00",
52+
});
53+
const offering7: Offering = createOffering({
54+
id: 7,
55+
course_id: 107,
56+
day: "WE",
57+
start: "11:00:00",
58+
end: "12:00:00",
59+
});
60+
61+
const result = getFrequencyTable([
62+
offering1,
63+
offering2,
64+
offering3,
65+
offering4,
66+
offering5,
67+
offering6,
68+
offering7,
69+
]);
70+
71+
expect(result.get("MO")).toBe(2);
72+
expect(result.get("TU")).toBe(2);
73+
expect(result.get("WE")).toBe(3);
74+
expect(result.get("TH")).toBeUndefined(); // Day not in data
75+
expect(result.get("FR")).toBeUndefined(); // Day not in data
76+
expect(result.size).toBe(3);
77+
});
78+
79+
test("should return an empty map for an empty array", () => {
80+
const result = getFrequencyTable([]);
81+
expect(result.size).toBe(0);
82+
});
83+
});
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { describe, expect, it, test } from "@jest/globals";
2+
3+
import {
4+
createOffering,
5+
isValidOffering,
6+
Offering,
7+
Restriction,
8+
RestrictionType,
9+
} from "../src/controllers/generatorController";
10+
11+
describe("isValidOffering", () => {
12+
const sampleOffering: Offering = createOffering({
13+
id: 1,
14+
course_id: 101,
15+
day: "MO",
16+
start: "10:00:00",
17+
end: "11:00:00",
18+
});
19+
20+
test("should allow offering if there are no restrictions", () => {
21+
expect(isValidOffering(sampleOffering, [])).toBe(true);
22+
});
23+
24+
test("should allow offering if all restrictions are disabled", () => {
25+
const restrictions: Restriction[] = [
26+
{
27+
type: RestrictionType.RestrictBefore,
28+
days: ["MO"],
29+
startTime: "",
30+
endTime: "09:00:00",
31+
disabled: true,
32+
numDays: 0,
33+
},
34+
];
35+
expect(isValidOffering(sampleOffering, restrictions)).toBe(true);
36+
});
37+
38+
test("should reject offering if it starts before restriction start time", () => {
39+
const restrictions: Restriction[] = [
40+
{
41+
type: RestrictionType.RestrictBefore,
42+
days: ["MO"],
43+
startTime: "",
44+
endTime: "11:00:00",
45+
disabled: false,
46+
numDays: 0,
47+
},
48+
];
49+
expect(isValidOffering(sampleOffering, restrictions)).toBe(false);
50+
});
51+
52+
test("should reject offering if it ends after restriction end time", () => {
53+
const restrictions: Restriction[] = [
54+
{
55+
type: RestrictionType.RestrictAfter,
56+
days: ["MO"],
57+
startTime: "10:30:00",
58+
endTime: "",
59+
disabled: false,
60+
numDays: 0,
61+
},
62+
];
63+
expect(isValidOffering(sampleOffering, restrictions)).toBe(false);
64+
});
65+
66+
test("should reject offering if it is within restricted time range", () => {
67+
const restrictions: Restriction[] = [
68+
{
69+
type: RestrictionType.RestrictBetween,
70+
days: ["MO"],
71+
startTime: "09:00:00",
72+
endTime: "12:00:00",
73+
disabled: false,
74+
numDays: 0,
75+
},
76+
];
77+
expect(isValidOffering(sampleOffering, restrictions)).toBe(false);
78+
});
79+
80+
test("should reject offering if the day is restricted", () => {
81+
const restrictions: Restriction[] = [
82+
{
83+
type: RestrictionType.RestrictDay,
84+
days: ["MO"],
85+
startTime: "",
86+
endTime: "",
87+
disabled: false,
88+
numDays: 0,
89+
},
90+
];
91+
expect(isValidOffering(sampleOffering, restrictions)).toBe(false);
92+
});
93+
94+
test("should allow offering if the day is not restricted", () => {
95+
const restrictions: Restriction[] = [
96+
{
97+
type: RestrictionType.RestrictDay,
98+
days: ["TU"],
99+
startTime: "",
100+
endTime: "",
101+
disabled: false,
102+
numDays: 0,
103+
},
104+
];
105+
expect(isValidOffering(sampleOffering, restrictions)).toBe(true);
106+
});
107+
});

0 commit comments

Comments
 (0)