Skip to content

Commit 09716d1

Browse files
committed
Add tests for find_assignments and find_notebooks
1 parent f4a4ea3 commit 09716d1

File tree

2 files changed

+87
-7
lines changed

2 files changed

+87
-7
lines changed

nbgrader/coursedir.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ def find_assignments(self,
361361
# Locate all matching directories using a glob
362362
dirs = list(
363363
filter(
364-
lambda p: p.is_dir() and not is_ignored(p.name, self.ignore),
364+
lambda p: p.is_dir() and not is_ignored(p.relative_to(self.root), self.ignore),
365365
Path(self.root).glob(self.directory_structure.format(**kwargs))
366366
)
367367
)
@@ -385,7 +385,7 @@ def find_assignments(self,
385385
for dir in dirs:
386386
match = re.match(pattern, str(dir.relative_to(self.root)))
387387
if match:
388-
results.append({ **kwargs, **match.groupdict() })
388+
results.append({ **kwargs, **match.groupdict(), 'path': dir })
389389

390390
return results
391391

@@ -436,7 +436,7 @@ def find_notebooks(
436436
}
437437

438438
# Convert to a Path and back to a string to remove any instances of `/.`
439-
pattern = str(Path(pattern.format(**pattern_args)))
439+
pattern = str(Path(pattern.replace(".", r"\.").format(**pattern_args)))
440440

441441
if sys.platform == 'win32':
442442
# Escape backslashes on Windows
@@ -445,7 +445,7 @@ def find_notebooks(
445445
for file in files:
446446
match = re.match(pattern, str(file.relative_to(self.root)))
447447
if match:
448-
results.append({ **kwargs, **match.groupdict(), "path": file})
448+
results.append({ **kwargs, **match.groupdict(), "path": file })
449449

450450
return results
451451

nbgrader/tests/test_coursedir.py

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@
77

88
from nbgrader.coursedir import CourseDirectory
99

10+
def pluck(key, collection):
11+
return sorted([x[key] for x in collection], key=lambda x: x)
12+
13+
def touch(path):
14+
path.parent.mkdir(parents=True, exist_ok=True)
15+
path.touch()
16+
1017
@pytest.mark.parametrize("root", [
1118
None, # Keep the course_dir fixture
1219
os.path.sep + "[special]~root",
1320
"C:\\Users\\Student",
1421
])
1522
def test_coursedir_format_path(course_dir, root):
16-
conf = Config()
23+
config = Config()
1724
if root is None:
1825
root = course_dir
19-
conf.CourseDirectory.root = root
20-
coursedir = CourseDirectory(config=conf)
26+
config.CourseDirectory.root = root
27+
coursedir = CourseDirectory(config=config)
2128

2229
# The default includes the un-escaped root
2330
path = os.path.join(coursedir.root, "step", "student_id", "assignment1")
@@ -37,3 +44,76 @@ def test_coursedir_format_path(course_dir, root):
3744
match = re.match(actual, path)
3845
assert match is not None
3946
assert match.group("assignment_id") == "assignment1"
47+
48+
def test_find_assignments(course_dir):
49+
config = Config({"CourseDirectory": {"root": course_dir}})
50+
coursedir = CourseDirectory(config=config)
51+
52+
root = Path(coursedir.root)
53+
54+
root.joinpath("source", ".", "assn").mkdir(parents=True)
55+
root.joinpath("release", ".", "assn").mkdir(parents=True)
56+
root.joinpath("submitted", "student1", "assn").mkdir(parents=True)
57+
root.joinpath("submitted", "student2", "assn").mkdir(parents=True)
58+
root.joinpath("autograded", "student1", "assn").mkdir(parents=True)
59+
root.joinpath("autograded", "student2", "assn").mkdir(parents=True)
60+
root.joinpath("feedback", "student1", "assn").mkdir(parents=True)
61+
root.joinpath("feedback", "student2", "assn").mkdir(parents=True)
62+
63+
64+
assert pluck("assignment_id", coursedir.find_assignments("source", ".")) == [
65+
"assn",
66+
]
67+
68+
assert pluck("student_id", coursedir.find_assignments("submitted")) == [
69+
"student1", "student2",
70+
]
71+
72+
assert pluck("nbgrader_step", coursedir.find_assignments(student_id="student1")) == [
73+
"autograded", "feedback", "submitted",
74+
]
75+
76+
# Finding by assignment has the shortcoming of not being able to find across
77+
# student_id="." and student_id="*" at the same time.
78+
assn = coursedir.find_assignments(assignment_id="assn", student_id=".")
79+
assert pluck("nbgrader_step", assn) == ["release", "source"]
80+
81+
assn = coursedir.find_assignments(assignment_id="assn")
82+
assert pluck("nbgrader_step", assn) == [
83+
"autograded", "autograded", "feedback", "feedback", "submitted", "submitted",
84+
]
85+
86+
def test_find_notebooks(course_dir):
87+
config = Config({"CourseDirectory": {"root": course_dir}})
88+
coursedir = CourseDirectory(config=config)
89+
90+
root = Path(coursedir.root)
91+
92+
touch(root.joinpath("source", ".", "assn", "assn.ipynb"))
93+
touch(root.joinpath("release", ".", "assn", "assn.ipynb"))
94+
touch(root.joinpath("submitted", "student1", "assn", "assn.ipynb"))
95+
touch(root.joinpath("submitted", "student2", "assn", "assn.ipynb"))
96+
touch(root.joinpath("autograded", "student1", "assn", "assn.ipynb"))
97+
touch(root.joinpath("autograded", "student2", "assn", "assn.ipynb"))
98+
touch(root.joinpath("feedback", "student1", "assn", "assn.html"))
99+
touch(root.joinpath("feedback", "student2", "assn", "assn.html"))
100+
101+
assert pluck("ext", coursedir.find_notebooks(assignment_id="assn", ext="*")) == [
102+
"html",
103+
"html",
104+
"ipynb",
105+
"ipynb",
106+
"ipynb",
107+
"ipynb",
108+
]
109+
110+
111+
# By default, we only look for .ipynb files
112+
assert pluck("nbgrader_step", coursedir.find_notebooks(student_id="student1")) == [
113+
"autograded", "submitted",
114+
]
115+
116+
assert pluck("nbgrader_step", coursedir.find_notebooks(student_id="student1", ext="*")) == [
117+
"autograded", "feedback", "submitted",
118+
]
119+

0 commit comments

Comments
 (0)