Skip to content

Commit 341d01e

Browse files
committed
Add end-to-end test case; more robust parsing
1 parent 55adef1 commit 341d01e

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

lchelper/crawler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,6 @@ def get_problems(contest_url: str, site: str, cookie_path: str) -> List[Problem]
171171
log(f"Parsed problem ({idx + 1}/{len(problem_paths)}): {problem_name}")
172172

173173
browser.quit()
174-
log("All problems successfully parsed", "success")
174+
log("All problems successfully crawled", "success")
175175

176176
return parsed_problems

lchelper/parser.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,24 @@ def parse_problem(problem: Problem, site: str = "leetcode") -> Union[ProblemSign
7171
r"""Parse the problem given the raw contents crawled from the web.
7272
"""
7373

74-
def find_example_section(s: str, cur_tag: str, next_tag: str, colon: str = ":") -> str:
74+
def find_example_section(s: str, cur_tag: str, next_tag: str, colon: str = ":", ignore_error: bool = False) -> str:
7575
r"""Find the part in the example that is between two tags. If ``next_tag`` does not exist, then find the part
7676
until the end.
7777
"""
7878
start_pos = s.find(cur_tag)
7979
if start_pos == -1:
80-
raise ValueError
81-
start_pos += len(cur_tag)
82-
if s[start_pos] == colon:
83-
start_pos += 1
80+
if not ignore_error:
81+
raise ValueError
82+
start_pos = 0
83+
else:
84+
start_pos += len(cur_tag)
85+
if s[start_pos] == colon:
86+
start_pos += 1
8487
end_pos = s.find(next_tag, start_pos)
8588
if end_pos == -1:
86-
return s[start_pos:].strip()
89+
if not ignore_error:
90+
raise ValueError
91+
end_pos = len(s)
8792
return s[start_pos:end_pos].strip()
8893

8994
# Parse function signature from code.
@@ -98,8 +103,8 @@ def find_example_section(s: str, cur_tag: str, next_tag: str, colon: str = ":")
98103
input_str = find_example_section(example, "输入", "输出", ":")
99104
output_str = find_example_section(example, "输出", "解释", ":")
100105
except ValueError:
101-
input_str = find_example_section(example, "Input", "Output")
102-
output_str = find_example_section(example, "Output", "Explanation")
106+
input_str = find_example_section(example, "Input", "Output", ignore_error=True)
107+
output_str = find_example_section(example, "Output", "Explanation", ignore_error=True)
103108

104109
functions, input_str = parse_value(input_str)
105110
arg_vals, input_str = parse_value(input_str)
@@ -130,8 +135,8 @@ def find_example_section(s: str, cur_tag: str, next_tag: str, colon: str = ":")
130135
input_str = find_example_section(example, "输入", "输出", ":")
131136
output_str = find_example_section(example, "输出", "解释", ":")
132137
except ValueError:
133-
input_str = find_example_section(example, "Input", "Output")
134-
output_str = find_example_section(example, "Output", "Explanation")
138+
input_str = find_example_section(example, "Input", "Output", ignore_error=True)
139+
output_str = find_example_section(example, "Output", "Explanation", ignore_error=True)
135140

136141
input_vals = {}
137142
for idx, (_, name) in enumerate(func_signature.arguments):

test.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,52 @@
11
import unittest
2-
from typing import Union
2+
from typing import Union, Dict, Optional, List
33

4-
from lchelper.parser import parse_problem
4+
import lchelper.codegen
55
from lchelper.common import FunctionSignature, Example, ProblemSignature, Interaction, \
66
InteractiveProblemSignature, Problem
77

88

9+
class EndToEndTest(unittest.TestCase):
10+
def _test_problem_set(self, url: str, site: str = "leetcode", ignore_problems: Optional[List[int]] = None):
11+
available_users = [user for user in lchelper.get_users() if user.site == site]
12+
assert len(available_users) > 0, f"User cookie from site \"{site}\" required for end-to-end tests"
13+
user = available_users[0]
14+
problems = lchelper.get_problems(url, site, lchelper.get_cookie_path(user.username, user.site))
15+
codegen: Dict[str, lchelper.codegen.CodeGen] = {
16+
lang: codegen_klass()
17+
for lang, codegen_klass in lchelper.LANGUAGES.items()
18+
}
19+
20+
ignore_problems = ignore_problems or []
21+
for idx, problem in enumerate(problems):
22+
if idx in ignore_problems:
23+
continue
24+
problem_signature = lchelper.parse_problem(problem, site)
25+
for lang, gen in codegen.items():
26+
_, _ = gen.generate_code(problem, problem_signature)
27+
28+
def test_contests(self):
29+
contests = [
30+
("weekly-contest-183", []),
31+
("weekly-contest-182", []),
32+
("weekly-contest-181", []),
33+
("weekly-contest-180", []),
34+
("weekly-contest-163", []),
35+
("biweekly-contest-14", []),
36+
]
37+
for contest, ignore_problems in contests:
38+
url = f"https://leetcode.com/contest/{contest}"
39+
self._test_problem_set(url, ignore_problems=ignore_problems)
40+
41+
942
class ParseTest(unittest.TestCase):
1043
def _function_equal(self, parsed_function: FunctionSignature, function: FunctionSignature):
1144
assert parsed_function.return_type == function.return_type
1245
assert parsed_function.name == function.name
1346
assert parsed_function.arguments == function.arguments
1447

1548
def _test_parse_problem(self, problem: Problem, signature: Union[ProblemSignature, InteractiveProblemSignature]):
16-
parsed_signature = parse_problem(problem)
49+
parsed_signature = lchelper.parse_problem(problem)
1750
assert type(parsed_signature) is type(signature)
1851
if isinstance(signature, InteractiveProblemSignature):
1952
assert parsed_signature.class_name == signature.class_name
@@ -141,7 +174,7 @@ def test_parse_problem_2(self):
141174
class_name="FindElements",
142175
functions=[
143176
FunctionSignature(
144-
return_type="", name="FindElements",
177+
return_type="FindElements", name="FindElements",
145178
arguments=[("TreeNode*", "root")]),
146179
FunctionSignature(
147180
return_type="bool", name="find",

0 commit comments

Comments
 (0)