update from last round
This commit is contained in:
@@ -145,7 +145,7 @@ class TestWorkerRequests:
|
||||
|
||||
Rota.add_grade_constraint_by_week([3], [1,2,3], ["a"])
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_avoid_grade_constraint_multiple_shifts(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -192,4 +192,4 @@ class TestWorkerRequests:
|
||||
|
||||
Rota.add_grade_constraint_by_week([1], [7,8,9], ["a"])
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
@@ -146,7 +146,7 @@ class TestWorkerRequests:
|
||||
|
||||
Rota.add_worker_name_constraint_by_week(["worker3"], [1,2,3], ["a"])
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_avoid_worker_constraint_multiple_shifts(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -193,4 +193,4 @@ class TestWorkerRequests:
|
||||
|
||||
Rota.add_worker_name_constraint_by_week(["worker1"], [7,8,9], ["a"])
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
@@ -75,7 +75,7 @@ class TestBalancing:
|
||||
name="a",
|
||||
length=12.5,
|
||||
days=days,
|
||||
balance_weighting=5,
|
||||
balance_weighting=10,
|
||||
workers_required=1,
|
||||
force_as_block=False,
|
||||
constraint=[{"name": "pre","options": "2"}, {"name": "post","options": "2"}],
|
||||
@@ -98,7 +98,7 @@ class TestBalancing:
|
||||
),
|
||||
)
|
||||
|
||||
Rota.build_and_solve(options={"ratio": 0.001})
|
||||
Rota.build_and_solve(options={"ratio": 0.0001})
|
||||
Rota.export_rota_to_html("basic_balancing_weighted_shifts")
|
||||
|
||||
shift_summary = Rota.get_shift_summary_dict()
|
||||
@@ -198,7 +198,7 @@ class TestBalancing:
|
||||
|
||||
worker = Rota.get_worker_by_name(worker_name)
|
||||
# assert worker_shifts["a"] in (46,47,48)
|
||||
assert worker_shifts["c"] in (7, 8)
|
||||
assert worker_shifts["c"] in (approx(7), approx(8))
|
||||
#assert worker_shifts["b"] in (53, 54)
|
||||
|
||||
def test_weighted_shift_balancing4(self):
|
||||
|
||||
@@ -146,7 +146,7 @@ class TestNightShifts:
|
||||
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_nights2(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -315,7 +315,7 @@ class TestNightShifts:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("night")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_nights_max_frequency3(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -352,7 +352,7 @@ class TestNightShifts:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("night")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_nights_max_frequency4(self):
|
||||
Rota = generate_basic_rota()
|
||||
|
||||
+5
-5
@@ -90,7 +90,7 @@ class TestDemoRota:
|
||||
|
||||
self.Rota.export_rota_to_html("nwd")
|
||||
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_nwd_partial_rota(self):
|
||||
# Set up rota
|
||||
@@ -188,7 +188,7 @@ class TestDemoRota:
|
||||
|
||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_nwd_force_as_block(self):
|
||||
# Set up rota
|
||||
@@ -273,21 +273,21 @@ class TestDemoRota:
|
||||
self.Rota.add_shifts(
|
||||
SingleShift(
|
||||
sites=("group1",), name="d", length= 12.5, days=days[:5],
|
||||
balance_offset=10,
|
||||
#balance_offset=50,
|
||||
workers_required=2,
|
||||
force_as_block_unless_nwd=True,
|
||||
assign_as_block=True,
|
||||
),
|
||||
SingleShift(
|
||||
sites=("group1",), name="w", length= 12.5, days=days[5:],
|
||||
balance_offset=10,
|
||||
#balance_offset=50,
|
||||
workers_required=4,
|
||||
force_as_block_unless_nwd=True,
|
||||
assign_as_block=True,
|
||||
),
|
||||
)
|
||||
|
||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
self.Rota.build_and_solve()
|
||||
self.Rota.export_rota_to_html("nwd_block_force_split")
|
||||
|
||||
assert self.Rota.results.solver.status == "ok"
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ class TestRemoteRotas:
|
||||
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_remote_pass_week(self):
|
||||
Rota = setup_basic_rota()
|
||||
|
||||
+27
-14
@@ -2,7 +2,8 @@ from copy import deepcopy
|
||||
from re import S
|
||||
from black import main
|
||||
import pytest
|
||||
from rota.shifts import NoWorkers, RotaBuilder, SingleShift, days
|
||||
from pytest import approx
|
||||
from rota.shifts import NoWorkers, RotaBuilder, SingleShift, WarningTermination, days
|
||||
|
||||
import datetime
|
||||
|
||||
@@ -285,14 +286,14 @@ class TestDemoRotaNights:
|
||||
worker = self.Rota.get_worker_by_name(worker_name)
|
||||
|
||||
if worker.fte == 40:
|
||||
assert worker_shifts["night_weekday"] in (0, 4)
|
||||
assert worker_shifts["night_weekend"] in (0, 3)
|
||||
assert worker_shifts["night_weekday"] in (approx(0), approx(4))
|
||||
assert worker_shifts["night_weekend"] in (approx(0), approx(3))
|
||||
elif worker.fte == 60:
|
||||
assert worker_shifts["night_weekday"] in (0, 4, 8)
|
||||
assert worker_shifts["night_weekend"] in (0, 3, 6)
|
||||
assert worker_shifts["night_weekday"] in (approx(0), approx(4), approx(8))
|
||||
assert worker_shifts["night_weekend"] in (approx(0), approx(3), approx(6))
|
||||
else:
|
||||
assert worker_shifts["night_weekday"] in (4, 8)
|
||||
assert worker_shifts["night_weekend"] in (3, 6)
|
||||
assert worker_shifts["night_weekday"] in (approx(4), approx(8))
|
||||
assert worker_shifts["night_weekend"] in (approx(3), approx(6))
|
||||
|
||||
|
||||
class TestDemoRotaClear:
|
||||
@@ -326,7 +327,7 @@ class TestDemoRotaClear:
|
||||
name="a",
|
||||
length=12.5,
|
||||
days=days[:5],
|
||||
balance_offset=40,
|
||||
#balance_offset=40,
|
||||
workers_required=2,
|
||||
constraint=[{"name": "pre", "options": 1}],
|
||||
),
|
||||
@@ -335,7 +336,7 @@ class TestDemoRotaClear:
|
||||
name="b",
|
||||
length=12.5,
|
||||
days=days[:5],
|
||||
balance_offset=40,
|
||||
#balance_offset=40,
|
||||
workers_required=2,
|
||||
),
|
||||
SingleShift(
|
||||
@@ -343,7 +344,7 @@ class TestDemoRotaClear:
|
||||
name="c",
|
||||
length=12.5,
|
||||
days=days[3],
|
||||
balance_offset=40,
|
||||
#balance_offset=40,
|
||||
workers_required=1,
|
||||
constraint=[{"name": "pre", "options": 1}, {"name": "post", "options": 1}],
|
||||
),
|
||||
@@ -481,7 +482,7 @@ class TestDemoRotaShiftConstraints:
|
||||
def test_max_shifts_fail(self):
|
||||
self.Rota.constraint_options["max_shifts_per_month"] = 13
|
||||
self.Rota.build_and_solve()
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
assert self.Rota.results.solver.termination_condition == "infeasible"
|
||||
|
||||
def test_max_shifts_extra_worker(self):
|
||||
@@ -495,7 +496,7 @@ class TestDemoRotaShiftConstraints:
|
||||
self.Rota.constraint_options["max_shifts_per_week"] = 3
|
||||
self.Rota.build_and_solve()
|
||||
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
assert self.Rota.results.solver.termination_condition == "infeasible"
|
||||
|
||||
def test_max_shifts_per_week_pass(self):
|
||||
@@ -550,7 +551,17 @@ class TestDemoRotaBalanceShiftSites:
|
||||
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||
self.Rota.constraint_options["balance_nights"] = False
|
||||
self.Rota.constraint_options["constrain_time_off_after_nights"] = False
|
||||
|
||||
# Worker 5 and 6 don't have any valid shifts so this should fail
|
||||
#with pytest.raises(WarningTermination):
|
||||
# self.Rota.build_and_solve(options={"ratio": 0.0})
|
||||
|
||||
# Unless we remove the warning
|
||||
self.Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||
self.Rota.build_and_solve(options={"ratio": 0.0})
|
||||
|
||||
assert len(self.Rota.get_warnings("Worker/no valid shifts")) == 2
|
||||
|
||||
self.Rota.export_rota_to_html("test5")
|
||||
|
||||
print(self.Rota.get_workers_by_group())
|
||||
@@ -586,6 +597,8 @@ class TestDemoRotaBalanceShiftSites:
|
||||
self.Rota.constraint_options["balance_nights_across_sites"] = False
|
||||
self.Rota.constraint_options["balance_nights"] = False
|
||||
self.Rota.constraint_options["constrain_time_off_after_nights"] = False
|
||||
|
||||
self.Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||
self.Rota.build_and_solve(options={"ratio": 0.1})
|
||||
|
||||
group_workers = self.Rota.get_workers_by_group()
|
||||
@@ -1151,7 +1164,7 @@ class TestNightUnavailable:
|
||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
self.Rota.export_rota_to_html("testnight_unavail")
|
||||
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
assert self.Rota.results.solver.termination_condition == "infeasible"
|
||||
|
||||
def test_assign_non_night_prior_to_unavailablity(self):
|
||||
@@ -1252,7 +1265,7 @@ class TestNightUnavailable:
|
||||
#
|
||||
# self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
#
|
||||
# assert self.Rota.results.solver.status == "warning"
|
||||
# assert self.Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
if __name__ == "__main__":
|
||||
t = TestLimitConstraints()
|
||||
|
||||
+5
-5
@@ -142,7 +142,7 @@ class TestShiftConstraints:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("max_shifts_per_week_block")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_max_shifts_per_week_block_shift_number(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -172,7 +172,7 @@ class TestShiftConstraints:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("max_shifts_per_week_block")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_pre_shift_constraint(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -226,7 +226,7 @@ class TestShiftConstraints:
|
||||
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_pre_shift_constraint2(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -269,7 +269,7 @@ class TestShiftConstraints:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("pre")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_post_shift_constraint(self):
|
||||
Rota = generate_basic_rota()
|
||||
@@ -311,4 +311,4 @@ class TestShiftConstraints:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("post")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
@@ -210,7 +210,7 @@ class TestDemoRota:
|
||||
|
||||
self.Rota.build_and_solve(options={"ratio": 0.00})
|
||||
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
def test_post_mon(self):
|
||||
# Set up rota
|
||||
@@ -343,4 +343,4 @@ class TestDemoRota:
|
||||
|
||||
self.Rota.export_rota_to_html("weekend_padding")
|
||||
|
||||
assert self.Rota.results.solver.status == "warning"
|
||||
assert self.Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import datetime
|
||||
import pytest
|
||||
from pytest import approx
|
||||
from rota.shifts import InvalidShift, NoWorkers, RotaBuilder, SingleShift, days
|
||||
|
||||
from rota.workers import Worker
|
||||
@@ -179,7 +180,7 @@ class TestWorkerRequests:
|
||||
|
||||
worker = Rota.get_worker_by_name(worker_name)
|
||||
|
||||
assert worker_shifts["a"] in (46, 47)
|
||||
assert worker_shifts["a"] in (approx(46), approx(47))
|
||||
|
||||
# shift_string = Rota.get_worker_shift_list_string(worker)
|
||||
|
||||
@@ -216,7 +217,7 @@ class TestWorkerRequests:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("unavailable_to_work2")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
assert Rota.results.solver.termination_condition == "infeasible"
|
||||
|
||||
def test_unavailable_to_work3(self):
|
||||
@@ -304,7 +305,7 @@ class TestWorkerRequests:
|
||||
Rota.build_and_solve(options={"ratio": 0.000})
|
||||
Rota.export_rota_to_html("unavailable_to_work4")
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
assert Rota.results.solver.termination_condition == "infeasible"
|
||||
|
||||
def test_work_requests(self):
|
||||
@@ -523,7 +524,7 @@ class TestWorkerRequests:
|
||||
worker = Rota.get_worker_by_name(worker_name)
|
||||
|
||||
assert worker_shifts["a"] in (26, 27)
|
||||
assert worker_shifts["b"] == 10
|
||||
assert worker_shifts["b"] == approx(10)
|
||||
|
||||
shift_string = Rota.get_worker_shift_list_string(worker)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import pytest
|
||||
from rota.shifts import NoWorkers, RotaBuilder, SingleShift, days
|
||||
from rota.shifts import NoWorkers, RotaBuilder, SingleShift, WarningTermination, days
|
||||
|
||||
import datetime
|
||||
from rota.workers import Worker
|
||||
@@ -64,7 +64,7 @@ class TestWorkers:
|
||||
),
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(WarningTermination):
|
||||
Rota.build_and_solve(solve=False)
|
||||
|
||||
def test_worker_ftes(self):
|
||||
@@ -143,6 +143,10 @@ class TestWorkers:
|
||||
),
|
||||
)
|
||||
|
||||
with pytest.raises(WarningTermination):
|
||||
Rota.build_and_solve()
|
||||
|
||||
Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||
Rota.build_and_solve()
|
||||
|
||||
# All workers should have an adjusted fte of 50 %
|
||||
@@ -298,6 +302,7 @@ class TestWorkers:
|
||||
),
|
||||
)
|
||||
|
||||
Rota.terminate_on_warning.remove("Worker/no valid shifts")
|
||||
Rota.build_and_solve()
|
||||
|
||||
# All workers should have an adjusted fte of 50 %
|
||||
@@ -353,7 +358,7 @@ class TestWorkers:
|
||||
Rota.build_and_solve()
|
||||
|
||||
# With two paired workers we shouldn't be able to solve
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
worker3 = Worker(name="worker3", site="group1", grade=1, fte=100)
|
||||
Rota.add_worker(worker3)
|
||||
@@ -374,7 +379,7 @@ class TestWorkers:
|
||||
|
||||
Rota.build_and_solve()
|
||||
|
||||
assert Rota.results.solver.status == "warning"
|
||||
assert Rota.results.solver.status in ("warning", "error")
|
||||
|
||||
worker3.pair = 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user