def setup(self): with open("tests/files/test.ipynb", "r") as fh: self.nb = read_nb(fh, "ipynb") self.cells = self.nb.worksheets[0].cells self.preprocessor = AssignmentPreprocessor()
class TestAssignmentPreprocessor(object): def setup(self): with open("tests/files/test.ipynb", "r") as fh: self.nb = read_nb(fh, "ipynb") self.cells = self.nb.worksheets[0].cells self.preprocessor = AssignmentPreprocessor() @staticmethod def _create_code_cell(): source = """# YOUR CODE HERE {% if solution %} print "hello" {% endif %} """ cell = new_code_cell(input=source, prompt_number=2, outputs=["foo"]) return cell @staticmethod def _create_text_cell(): source = """{% if solution %} this is the answer! {% else %} YOUR ANSWER HERE {% endif %} """ cell = new_text_cell("markdown", source=source) return cell def test_concatenate_nothing(self): """Are the cells the same if there is no header/footer?""" cells = self.preprocessor._concatenate_notebooks(self.cells) assert cells == self.cells def test_concatenate_header(self): """Is the header prepended correctly?""" self.preprocessor.header = "tests/files/test.ipynb" cells = self.preprocessor._concatenate_notebooks(self.cells[:-1]) assert cells == (self.cells + self.cells[:-1]) def test_concatenate_footer(self): """Is the footer appended correctly?""" self.preprocessor.footer = "tests/files/test.ipynb" cells = self.preprocessor._concatenate_notebooks(self.cells[:-1]) assert cells == (self.cells[:-1] + self.cells) def test_concatenate_header_and_footer(self): """Is the header and footer concatenated correctly?""" self.preprocessor.header = "tests/files/test.ipynb" self.preprocessor.footer = "tests/files/test.ipynb" cells = self.preprocessor._concatenate_notebooks(self.cells[:-1]) assert cells == (self.cells + self.cells[:-1] + self.cells) def test_filter_solution(self): """Are release and skip cells filtered out when solution=True?""" self.preprocessor.solution = True cells = self.preprocessor._filter_cells(self.cells) for cell in cells: cell_type = util.get_assignment_cell_type(cell) assert cell_type != "skip" assert cell_type != "release" def test_filter_release(self): """Are solution and skip cells filtered out when solution=False?""" self.preprocessor.solution = False cells = self.preprocessor._filter_cells(self.cells) for cell in cells: cell_type = util.get_assignment_cell_type(cell) assert cell_type != "skip" assert cell_type != "solution" def test_get_toc_no_heading_cells(self): """Is the ToC empty if there are no heading cells?""" toc = self.preprocessor._get_toc([]) assert toc == "" def test_get_toc(self): """Is the ToC correctly formatted?""" correct_toc = """* <a href="#foo-bar">foo bar</a> \t* <a href="#bar">bar</a> \t\t* <a href="#baz">baz</a> \t\t* <a href="#quux">quux</a> \t* <a href="#foo2">foo2</a>""" toc = self.preprocessor._get_toc(self.cells) assert toc == correct_toc def test_match_tests(self): """Are the tests matched to the correct problems?""" tests, rubric = self.preprocessor._match_tests(self.cells) assert tests == { "test1_for_problem1": { "weight": 0.3333333333333333, "points": 1, "problem": "problem1", "cell_type": "code", }, "test2_for_problem1": { "weight": 0.6666666666666666, "points": 2, "problem": "problem1", "cell_type": "markdown", }, } assert rubric == { "problem1": {"tests": ["test1_for_problem1", "test2_for_problem1"], "points": 3}, "problem2": {"tests": [], "points": 0}, } def test_match_tests_double_problem(self): """Is an error raised when a problem id is used twice?""" cell1 = new_code_cell() cell1.metadata = dict(assignment=dict(cell_type="grade", id="foo", points="")) cell2 = new_text_cell("markdown") cell2.metadata = dict(assignment=dict(cell_type="grade", id="foo", points="")) cells = [cell1, cell2] assert_raises(RuntimeError, self.preprocessor._match_tests, cells) def test_match_tests_no_match(self): """Is an error raised when an autograding cell cannot be matched?""" cell = new_code_cell() cell.metadata = dict(assignment=dict(cell_type="autograder")) cells = [cell] assert_raises(RuntimeError, self.preprocessor._match_tests, cells) def test_match_tests_double_test(self): """Is an error raised when a test id is used twice?""" cell1 = new_code_cell() cell1.metadata = dict(assignment=dict(cell_type="grade", id="foo", points="")) cell2 = new_code_cell() cell2.metadata = dict(assignment=dict(cell_type="autograder", id="foo_test")) cell3 = new_text_cell("markdown") cell3.metadata = dict(assignment=dict(cell_type="autograder", id="foo_test")) cells = [cell1, cell2, cell3] assert_raises(RuntimeError, self.preprocessor._match_tests, cells) def test_preprocess_nb_default_metadata(self): """Is the default metadata correctly set?""" nb, resources = self.preprocessor._preprocess_nb(self.nb, {}) assert "celltoolbar" not in nb.metadata assert nb.metadata["disable_assignment_toolbar"] assert nb.metadata["hide_autograder_cells"] def test_preprocess_nb_disable_toolbar(self): """Is the toolbar disabled?""" self.preprocessor.disable_toolbar = False nb, resources = self.preprocessor._preprocess_nb(self.nb, {}) assert "celltoolbar" not in nb.metadata assert not nb.metadata["disable_assignment_toolbar"] assert nb.metadata["hide_autograder_cells"] def test_preprocess_nb_hide_autograder_cells(self): """Are autograder cells hidden?""" self.preprocessor.hide_autograder_cells = False nb, resources = self.preprocessor._preprocess_nb(self.nb, {}) assert "celltoolbar" not in nb.metadata assert nb.metadata["disable_assignment_toolbar"] assert not nb.metadata["hide_autograder_cells"] def test_preprocess_code_cell_solution(self): """Is the solution version of a code cell correctly preprocessed?""" self.preprocessor.solution = True self.preprocessor.toc = "" cell = self._create_code_cell() self.preprocessor._create_client() cell, resources = self.preprocessor.preprocess_cell(cell, {}, 1) self.preprocessor._shutdown_client() output = NotebookNode() output.stream = "stdout" output.text = "hello\n" output.output_type = "stream" assert cell.input == """# YOUR CODE HERE\nprint "hello\"""" assert cell.outputs == [output] assert cell.prompt_number == 1 def test_preprocess_code_cell_release(self): """Is the release version of a code cell correctly preprocessed?""" self.preprocessor.solution = False self.preprocessor.toc = "" cell = self._create_code_cell() cell, resources = self.preprocessor.preprocess_cell(cell, {}, 1) assert cell.input == """# YOUR CODE HERE""" assert cell.outputs == [] assert "prompt_number" not in cell def test_preprocess_text_cell_solution(self): """Is the solution version of a text cell correctly preprocessed?""" self.preprocessor.solution = True self.preprocessor.toc = "" cell = self._create_text_cell() cell, resources = self.preprocessor.preprocess_cell(cell, {}, 1) assert cell.source == """this is the answer!""" def test_preprocess_text_cell_release(self): """Is the release version of a text cell correctly preprocessed?""" self.preprocessor.solution = False self.preprocessor.toc = "" cell = self._create_text_cell() cell, resources = self.preprocessor.preprocess_cell(cell, {}, 1) assert cell.source == """YOUR ANSWER HERE""" def test_preprocess_autograder_cells_hide(self): """Are autograder cells properly preprocessed and hidden?""" self.preprocessor.hide_autograder_cells = True self.preprocessor.solution = False cell1 = self._create_code_cell() cell1.metadata = dict(assignment=dict(cell_type="grade", id="foo", points=1)) cell2 = self._create_code_cell() cell2.input = "# hello" cell2.metadata = dict(assignment=dict(cell_type="autograder", id="foo")) cell3 = self._create_text_cell() cell3.source = "goodbye" cell3.metadata = dict(assignment=dict(cell_type="autograder", id="bar")) nb = new_notebook(worksheets=[NotebookNode()]) nb.worksheets[0].cells = [cell1, cell2, cell3] nb, resources = self.preprocessor.preprocess(nb, {}) cell1, cell2, cell3 = nb.worksheets[0].cells assert cell2.input == "" assert cell3.source == "" tests = resources["tests"] assert tests == { "foo": dict(weight=0.5, points=0.5, problem="foo", source="# hello", cell_type="code"), "bar": dict(weight=0.5, points=0.5, problem="foo", source="goodbye", cell_type="markdown"), } def test_preprocess_autograder_cells_show(self): """Are autograder cells properly preprocessed and shown?""" self.preprocessor.hide_autograder_cells = False self.preprocessor.solution = False cell1 = self._create_code_cell() cell1.metadata = dict(assignment=dict(cell_type="grade", id="foo", points=1)) cell2 = self._create_code_cell() cell2.input = "# hello" cell2.metadata = dict(assignment=dict(cell_type="autograder", id="foo")) cell3 = self._create_text_cell() cell3.source = "goodbye" cell3.metadata = dict(assignment=dict(cell_type="autograder", id="bar")) nb = new_notebook(worksheets=[NotebookNode()]) nb.worksheets[0].cells = [cell1, cell2, cell3] nb, resources = self.preprocessor.preprocess(nb, {}) cell1, cell2, cell3 = nb.worksheets[0].cells assert cell2.input == "# hello" assert cell3.source == "goodbye" tests = resources["tests"] assert tests == { "foo": dict(weight=0.5, points=0.5, problem="foo", source="# hello", cell_type="code"), "bar": dict(weight=0.5, points=0.5, problem="foo", source="goodbye", cell_type="markdown"), } def test_extract_outputs_release(self): """Are outputs excluded in release version?""" self.preprocessor.solution = False nb, resources = self.preprocessor._preprocess_nb(self.nb, {}) self.preprocessor._extract_outputs(resources) assert "outputs" not in resources def test_extract_outputs_solution(self): """Are outputs include in solution version?""" self.preprocessor.solution = True nb, resources = self.preprocessor._preprocess_nb(self.nb, {}) self.preprocessor._extract_outputs(resources) assert "outputs" in resources rubric = json.dumps(resources["rubric"], indent=1) tests = json.dumps(resources["tests"], indent=1) assert resources["outputs"]["rubric.json"] == rubric assert resources["outputs"]["autograder_tests.json"] == tests def test_preprocess_solution(self): """Does the solution preprocessor succeed?""" self.preprocessor.solution = True self.preprocessor.preprocess(self.nb, {}) def test_preprocess_release(self): """Does the release preprocessor succeed?""" self.preprocessor.solution = False self.preprocessor.preprocess(self.nb, {})