Skip to content

Commit 1776869

Browse files
authored
OIJ contest type (#237)
* Add OIJ contest type * Add tests
1 parent 1eecdff commit 1776869

File tree

4 files changed

+127
-65
lines changed

4 files changed

+127
-65
lines changed

src/sinol_make/contest_types/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from sinol_make.contest_types.default import DefaultContest
22
from sinol_make.contest_types.icpc import ICPCContest
33
from sinol_make.contest_types.oi import OIContest
4+
from sinol_make.contest_types.oij import OIJContest
45
from sinol_make.helpers.package_util import get_config
56
from sinol_make.interfaces.Errors import UnknownContestType
67

@@ -15,5 +16,7 @@ def get_contest_type():
1516
return OIContest()
1617
elif contest_type == "icpc":
1718
return ICPCContest()
19+
elif contest_type == "oij":
20+
return OIJContest()
1821
else:
1922
raise UnknownContestType(f'Unknown contest type "{contest_type}"')
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import argparse
2+
3+
from sinol_make import util
4+
from sinol_make.helpers import package_util
5+
from sinol_make.contest_types.default import DefaultContest
6+
7+
8+
class OIJContest(DefaultContest):
9+
"""
10+
Contest type for Polish Junior Olympiad in Informatics.
11+
"""
12+
13+
def get_type(self) -> str:
14+
return "oij"
15+
16+
def argument_overrides(self, args: argparse.Namespace) -> argparse.Namespace:
17+
"""
18+
Add arguments for features required by OIJ contest
19+
"""
20+
args.export_ocen = True
21+
return args
22+
23+
def verify_pre_gen(self):
24+
"""
25+
Verify if scores sum up to 100.
26+
"""
27+
config = package_util.get_config()
28+
if 'scores' not in config:
29+
util.exit_with_error("Scores are not defined in config.yml.")
30+
total_score = sum(config['scores'].values())
31+
if total_score != 100:
32+
util.exit_with_error(f"Total score in config is {total_score}, but should be 100.")

tests/commands/export/test_integration.py

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import yaml
22
import stat
33
import glob
4+
import shutil
45
import pytest
56
import tarfile
67
import zipfile
@@ -9,6 +10,7 @@
910
from sinol_make import configure_parsers
1011
from sinol_make import util as sinol_util
1112
from sinol_make.commands.doc import Command as DocCommand
13+
from sinol_make.helpers import paths
1214
from tests import util
1315
from tests.fixtures import create_package
1416
from .util import *
@@ -43,6 +45,17 @@ def _test_archive(package_path, out, tar):
4345
assert glob.glob(os.path.join(extracted, "out", "*")) == []
4446

4547

48+
def _set_contest_type(contest_type):
49+
config = package_util.get_config()
50+
config["sinol_contest_type"] = contest_type
51+
sinol_util.save_config(config)
52+
task_id = package_util.get_task_id()
53+
if os.path.exists(os.path.join(os.getcwd(), f'{task_id}.tgz')):
54+
os.remove(f'{task_id}.tgz')
55+
if os.path.exists(paths.get_cache_path()):
56+
shutil.rmtree(paths.get_cache_path())
57+
58+
4659
@pytest.mark.parametrize("create_package", [util.get_simple_package_path(), util.get_library_package_path(),
4760
util.get_library_string_args_package_path(),
4861
util.get_shell_ingen_pack_path(), util.get_handwritten_package_path()],
@@ -166,35 +179,37 @@ def test_ocen_archive(create_package):
166179
"""
167180
Test creation of ocen archive.
168181
"""
169-
parser = configure_parsers()
170-
args = parser.parse_args(["export", "--no-statement"])
171-
command = Command()
172-
command.run(args)
173-
task_id = package_util.get_task_id()
174-
in_handwritten = ["ocen0.in", "ocen0a.in", "ocen1a.in", "ocen1ocen.in"]
175-
out_handwritten = ["ocen0.out"]
176-
ocen_tests = ["ocen0", "ocen0a", "ocen0b", "ocen1ocen", "ocen2ocen"]
182+
for contest_type in ["oi", "oij"]:
183+
_set_contest_type(contest_type)
184+
parser = configure_parsers()
185+
args = parser.parse_args(["export", "--no-statement"])
186+
command = Command()
187+
command.run(args)
188+
task_id = package_util.get_task_id()
189+
in_handwritten = ["ocen0.in", "ocen0a.in", "ocen1a.in", "ocen1ocen.in"]
190+
out_handwritten = ["ocen0.out"]
191+
ocen_tests = ["ocen0", "ocen0a", "ocen0b", "ocen1ocen", "ocen2ocen"]
177192

178-
with tempfile.TemporaryDirectory() as tmpdir:
179-
package_path = os.path.join(tmpdir, task_id)
180-
os.mkdir(package_path)
181-
with tarfile.open(f'{task_id}.tgz', "r") as tar:
182-
sinol_util.extract_tar(tar, tmpdir)
193+
with tempfile.TemporaryDirectory() as tmpdir:
194+
package_path = os.path.join(tmpdir, task_id)
195+
os.mkdir(package_path)
196+
with tarfile.open(f'{task_id}.tgz', "r") as tar:
197+
sinol_util.extract_tar(tar, tmpdir)
183198

184-
for ext in ["in", "out"]:
185-
tests = [os.path.basename(f) for f in glob.glob(os.path.join(package_path, ext, f'*.{ext}'))]
186-
assert set(tests) == set(in_handwritten if ext == "in" else out_handwritten)
199+
for ext in ["in", "out"]:
200+
tests = [os.path.basename(f) for f in glob.glob(os.path.join(package_path, ext, f'*.{ext}'))]
201+
assert set(tests) == set(in_handwritten if ext == "in" else out_handwritten)
187202

188-
ocen_archive = os.path.join(package_path, "attachments", f"{task_id}ocen.zip")
189-
assert os.path.exists(ocen_archive)
190-
ocen_dir = os.path.join(package_path, "ocen_dir")
203+
ocen_archive = os.path.join(package_path, "attachments", f"{task_id}ocen.zip")
204+
assert os.path.exists(ocen_archive)
205+
ocen_dir = os.path.join(package_path, "ocen_dir")
191206

192-
with zipfile.ZipFile(ocen_archive, "r") as zip:
193-
zip.extractall(ocen_dir)
207+
with zipfile.ZipFile(ocen_archive, "r") as zip:
208+
zip.extractall(ocen_dir)
194209

195-
for ext in ["in", "out"]:
196-
tests = [os.path.basename(f) for f in glob.glob(os.path.join(ocen_dir, task_id, ext, f'*.{ext}'))]
197-
assert set(tests) == set([f'{test}.{ext}' for test in ocen_tests])
210+
for ext in ["in", "out"]:
211+
tests = [os.path.basename(f) for f in glob.glob(os.path.join(ocen_dir, task_id, ext, f'*.{ext}'))]
212+
assert set(tests) == set([f'{test}.{ext}' for test in ocen_tests])
198213

199214

200215
@pytest.mark.parametrize("create_package", [util.get_icpc_package_path()], indirect=True)
@@ -220,42 +235,46 @@ def test_no_ocen_and_dlazaw(create_package):
220235
Test if ocen archive is not created when there are no ocen tests.
221236
Also test if dlazaw archive is created.
222237
"""
223-
parser = configure_parsers()
224-
args = parser.parse_args(["export", "--no-statement"])
225-
command = Command()
226-
command.run(args)
227-
task_id = package_util.get_task_id()
238+
for contest_type in ["oi", "oij"]:
239+
_set_contest_type(contest_type)
240+
parser = configure_parsers()
241+
args = parser.parse_args(["export", "--no-statement"])
242+
command = Command()
243+
command.run(args)
244+
task_id = package_util.get_task_id()
228245

229-
with tempfile.TemporaryDirectory() as tmpdir:
230-
with tarfile.open(f'{task_id}.tgz', "r") as tar:
231-
sinol_util.extract_tar(tar, tmpdir)
246+
with tempfile.TemporaryDirectory() as tmpdir:
247+
with tarfile.open(f'{task_id}.tgz', "r") as tar:
248+
sinol_util.extract_tar(tar, tmpdir)
232249

233-
assert not os.path.exists(os.path.join(tmpdir, task_id, "attachments", f"{task_id}ocen.zip"))
234-
dlazaw_archive = os.path.join(tmpdir, task_id, "attachments", f"dlazaw.zip")
235-
assert os.path.exists(dlazaw_archive)
250+
assert not os.path.exists(os.path.join(tmpdir, task_id, "attachments", f"{task_id}ocen.zip"))
251+
dlazaw_archive = os.path.join(tmpdir, task_id, "attachments", f"dlazaw.zip")
252+
assert os.path.exists(dlazaw_archive)
236253

237-
with zipfile.ZipFile(dlazaw_archive, "r") as zip:
238-
zip.extractall(os.path.join(tmpdir))
254+
with zipfile.ZipFile(dlazaw_archive, "r") as zip:
255+
zip.extractall(os.path.join(tmpdir))
239256

240-
assert os.path.exists(os.path.join(tmpdir, "dlazaw"))
241-
assert os.path.exists(os.path.join(tmpdir, "dlazaw", "epic_file"))
257+
assert os.path.exists(os.path.join(tmpdir, "dlazaw"))
258+
assert os.path.exists(os.path.join(tmpdir, "dlazaw", "epic_file"))
242259

243260

244261
@pytest.mark.parametrize("create_package", [util.get_ocen_package_path()], indirect=True)
245262
def test_dlazaw_ocen(create_package):
246263
"""
247264
Test if ocen archive isn't created when dlazaw directory exists
248265
"""
249-
os.makedirs("dlazaw")
250-
parser = configure_parsers()
251-
args = parser.parse_args(["export", "--no-statement"])
252-
command = Command()
253-
command.run(args)
254-
task_id = package_util.get_task_id()
266+
for contest_type in ["oi", "oij"]:
267+
_set_contest_type(contest_type)
268+
os.makedirs("dlazaw", exist_ok=True)
269+
parser = configure_parsers()
270+
args = parser.parse_args(["export", "--no-statement"])
271+
command = Command()
272+
command.run(args)
273+
task_id = package_util.get_task_id()
255274

256-
with tempfile.TemporaryDirectory() as tmpdir:
257-
with tarfile.open(f'{task_id}.tgz', "r") as tar:
258-
sinol_util.extract_tar(tar, tmpdir)
275+
with tempfile.TemporaryDirectory() as tmpdir:
276+
with tarfile.open(f'{task_id}.tgz', "r") as tar:
277+
sinol_util.extract_tar(tar, tmpdir)
259278

260-
assert not os.path.exists(os.path.join(tmpdir, task_id, "attachments", f"{task_id}ocen.zip"))
261-
assert os.path.join(tmpdir, task_id, "attachments", f"dlazaw.zip")
279+
assert not os.path.exists(os.path.join(tmpdir, task_id, "attachments", f"{task_id}ocen.zip"))
280+
assert os.path.join(tmpdir, task_id, "attachments", f"dlazaw.zip")

tests/commands/verify/test_integration.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import os
2+
import shutil
23
import pytest
34

45
from sinol_make import configure_parsers
56
from sinol_make import util as sm_util
67
from sinol_make.commands.verify import Command
7-
from sinol_make.helpers import package_util
8+
from sinol_make.helpers import package_util, paths
89
from tests import util
910
from tests.fixtures import create_package
1011

@@ -103,24 +104,29 @@ def test_invalid_scores(capsys, create_package):
103104
@pytest.mark.parametrize("create_package", [util.get_simple_package_path()], indirect=True)
104105
def test_scores_not_100(capsys, create_package):
105106
"""
106-
Test if scores not adding up to 100 will cause the verify command to fail.
107+
Test if scores not adding up to 100 will cause the verify command to fail if contest type is OI or OIJ.
107108
"""
108109
config = package_util.get_config()
109-
config["sinol_contest_type"] = "oi"
110110
config["scores"][1] -= 1
111111
sm_util.save_config(config)
112-
with pytest.raises(SystemExit) as e:
113-
run()
114-
assert e.value.code == 1
115-
out = capsys.readouterr().out
116-
assert "Total score in config is 99, but should be 100." in out
112+
for contest_type in ["oi", "oij"]:
113+
if os.path.exists(paths.get_cache_path()):
114+
shutil.rmtree(paths.get_cache_path())
115+
config = package_util.get_config()
116+
config["sinol_contest_type"] = contest_type
117+
sm_util.save_config(config)
118+
with pytest.raises(SystemExit) as e:
119+
run()
120+
assert e.value.code == 1
121+
out = capsys.readouterr().out
122+
assert "Total score in config is 99, but should be 100." in out
117123

118124

119125
@pytest.mark.parametrize("create_package", [util.get_dlazaw_package()], indirect=True)
120126
def test_expected_contest_and_no_scores(capsys, create_package):
121127
"""
122128
Test if --expected-contest-type flag works,
123-
and if contest type is OI and there are no scores in config.yml, the verify command will fail.
129+
and if contest type is OI or OIJ and there are no scores in config.yml, the verify command will fail.
124130
"""
125131
config = package_util.get_config()
126132
with pytest.raises(SystemExit) as e:
@@ -130,9 +136,11 @@ def test_expected_contest_and_no_scores(capsys, create_package):
130136
assert "Invalid contest type 'oi'. Expected 'icpc'." in out
131137

132138
del config["scores"]
133-
sm_util.save_config(config)
134-
with pytest.raises(SystemExit) as e:
135-
run(["--expected-contest-type", "oi"])
136-
assert e.value.code == 1
137-
out = capsys.readouterr().out
138-
assert "Scores are not defined in config.yml." in out
139+
for contest_type in ["oi", "oij"]:
140+
config["sinol_contest_type"] = contest_type
141+
sm_util.save_config(config)
142+
with pytest.raises(SystemExit) as e:
143+
run(["--expected-contest-type", contest_type])
144+
assert e.value.code == 1
145+
out = capsys.readouterr().out
146+
assert "Scores are not defined in config.yml." in out

0 commit comments

Comments
 (0)