Repository: kmyk/online-judge-tools
Pull request #237 (2019-01-04 08:32:58)

#236


Patch:
diff --git a/onlinejudge/implementation/command/generate_output.py b/onlinejudge/implementation/command/generate_output.py
index b68c4e2..cdd0a73 100644
--- a/onlinejudge/implementation/command/generate_output.py
+++ b/onlinejudge/implementation/command/generate_output.py
@@ -2,7 +2,7 @@
 import onlinejudge
 import onlinejudge.implementation.utils as utils
 import onlinejudge.implementation.logging as log
-import onlinejudge.implementation.command.utils as cutils
+import onlinejudge.implementation.format_utils as cutils
 import time
 from typing import *
 if TYPE_CHECKING:
@@ -13,7 +13,7 @@ def generate_output(args: 'argparse.Namespace') -> None:
         args.test = cutils.glob_with_format(args.directory, args.format) # by default
     if args.ignore_backup:
         args.test = cutils.drop_backup_or_hidden_files(args.test)
-    tests = cutils.construct_relationship_of_files(args.test, args.format)
+    tests = cutils.construct_relationship_of_files(args.test, args.directory, args.format)
     for name, it in sorted(tests.items()):
         log.emit('')
         log.info('%s', name)
diff --git a/onlinejudge/implementation/command/utils.py b/onlinejudge/implementation/format_utils.py
similarity index 75%
rename from onlinejudge/implementation/command/utils.py
rename to onlinejudge/implementation/format_utils.py
index 82bec7c..062589b 100644
--- a/onlinejudge/implementation/command/utils.py
+++ b/onlinejudge/implementation/format_utils.py
@@ -19,21 +19,11 @@ def glob_with_format(directory: pathlib.Path, format: str) -> List[pathlib.Path]
         log.debug('testcase globbed: %s', path)
     return paths
 
-def counts_included_dirname(format: str) -> int:
-    count = 0  # type: int
-    for dirname in format.split('/'):
-        if dirname:
-            count += 1
-    return count
-
-def match_with_format(format: str, path: pathlib.Path) -> Optional[Match[str]]:
+def match_with_format(directory: pathlib.Path, format: str, path: pathlib.Path) -> Optional[Match[str]]:
     table = {}
     table['s'] = '(?P<name>.+)'
     table['e'] = '(?P<ext>in|out)'
-    format_root_path = path  # type: pathlib.Path
-    for i in range(counts_included_dirname(format)):
-        format_root_path = format_root_path.parent
-    pattern = re.compile('^' + str(format_root_path) + '/' + utils.parcentformat(format, table) + '$')
+    pattern = re.compile('^' + str(directory.resolve()) + '/' + utils.parcentformat(format, table) + '$')
     return pattern.match(str(path.resolve()))
 
 def path_from_format(directory: pathlib.Path, format: str, name: str, ext: str) -> pathlib.Path:
@@ -55,10 +45,10 @@ def drop_backup_or_hidden_files(paths: List[pathlib.Path]) -> List[pathlib.Path]
             result += [ path ]
     return result
 
-def construct_relationship_of_files(paths: List[pathlib.Path], format: str) -> Dict[str, Dict[str, pathlib.Path]]:
+def construct_relationship_of_files(paths: List[pathlib.Path], directory: pathlib.Path, format: str) -> Dict[str, Dict[str, pathlib.Path]]:
     tests = collections.defaultdict(dict)  # type: Dict[str, Dict[str, pathlib.Path]]
     for path in paths:
-        m = match_with_format(format, path.resolve())
+        m = match_with_format(directory, format, path.resolve())
         if not m:
             log.error('unrecognizable file found: %s', path)
             sys.exit(1)


Test patch:
diff --git a/onlinejudge/implementation/command/test.py b/onlinejudge/implementation/command/test.py
index f85d6d5..58a96cc 100644
--- a/onlinejudge/implementation/command/test.py
+++ b/onlinejudge/implementation/command/test.py
@@ -2,7 +2,7 @@
 import onlinejudge
 import onlinejudge.implementation.utils as utils
 import onlinejudge.implementation.logging as log
-import onlinejudge.implementation.command.utils as cutils
+import onlinejudge.implementation.format_utils as cutils
 import json
 import math
 import sys
@@ -39,7 +39,7 @@ def test(args: 'argparse.Namespace') -> None:
         args.test = cutils.glob_with_format(args.directory, args.format)  # by default
     if args.ignore_backup:
         args.test = cutils.drop_backup_or_hidden_files(args.test)
-    tests = cutils.construct_relationship_of_files(args.test, args.format)
+    tests = cutils.construct_relationship_of_files(args.test, args.directory, args.format)
     if args.error: # float mode
         match = lambda a, b: compare_as_floats(a, b, args.error)
     else:
diff --git a/tests/command_test.py b/tests/command_test.py
index a7cc3cb..b78d736 100644
--- a/tests/command_test.py
+++ b/tests/command_test.py
@@ -225,3 +225,33 @@ class TestTest(unittest.TestCase):
                 'exitcode': 0,
             } ],
         )
+
+    def test_call_test_format_hack(self):
+        self.snippet_call_test(
+            args=[ '-c', 'cat', '-d', 'a/b', '-f', 'c/test_%e/d/%s/e.case.txt' ],
+            files=[
+                { 'path': 'a/b/c/test_in/d/sample.case.1/e.case.txt', 'data': 'foo\n' },
+                { 'path': 'a/b/c/test_out/d/sample.case.1/e.case.txt', 'data': 'foo\n' },
+                { 'path': 'a/b/c/test_in/d/sample.case.2/e.case.txt', 'data': 'bar\n' },
+                { 'path': 'a/b/c/test_out/d/sample.case.2/e.case.txt', 'data': 'bar\n' },
+            ],
+            expected=[ {
+                'result': 'AC',
+                'testcase': {
+                    'name': 'sample.case.1',
+                    'input': '%s/a/b/c/test_in/d/sample.case.1/e.case.txt',
+                    'output': '%s/a/b/c/test_out/d/sample.case.1/e.case.txt',
+                },
+                'output': 'foo\n',
+                'exitcode': 0,
+            }, {
+                'result': 'AC',
+                'testcase': {
+                    'name': 'sample.case.2',
+                    'input': '%s/a/b/c/test_in/d/sample.case.2/e.case.txt',
+                    'output': '%s/a/b/c/test_out/d/sample.case.2/e.case.txt',
+                },
+                'output': 'bar\n',
+                'exitcode': 0,
+            } ],
+        )