def test_regex_replace_nb_source(): """Test regex replacing notebook source.""" notebook = create_notebook() notebook.cells.extend( [ prepare_cell( {"metadata": {}, "outputs": [], "source": ["print(1)\n", "print(2)"]} ), prepare_cell( {"metadata": {}, "outputs": [], "source": ["print(1)\n", "print(2)"]} ), ] ) new_notebook = regex_replace_nb( notebook, [("/cells/0/source", "p", "s"), ("/cells/1/source", "p", "t")] ) new_notebook.nbformat_minor = None assert mapping_to_dict(new_notebook) == { "cells": [ {"metadata": {}, "outputs": [], "source": "srint(1)\nsrint(2)"}, {"metadata": {}, "outputs": [], "source": "trint(1)\ntrint(2)"}, ], "metadata": {}, "nbformat": 4, "nbformat_minor": None, }
def test_gather_paths_filter_str(): """Test gathering paths in the notebook, filtering by only str objects.""" notebook = create_notebook() notebook.cells.extend( [ prepare_cell( { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ {"name": "stdout", "output_type": "stream", "text": ["hallo\n"]} ], "source": ["print('hallo')\n"], } ) ] ) paths = [] gather_json_paths(notebook, paths, types=(str,)) assert paths == [ ("cells", 0, "cell_type"), ("cells", 0, "outputs", 0, "name"), ("cells", 0, "outputs", 0, "output_type"), ("cells", 0, "outputs", 0, "text"), ("cells", 0, "source"), ]
def test_regex_replace_nb_output(): """Test regex replacing notebook output.""" notebook = create_notebook() notebook.cells.extend([ prepare_cell({ "metadata": {}, "outputs": [{ "name": "stdout", "output_type": "stream", "text": ["2019-08-11\n"], }], "source": ["from datetime import date\n", "print(date.today())"], }) ]) new_notebook = regex_replace_nb( notebook, [("/cells/0/outputs/0", r"\d{2,4}-\d{1,2}-\d{1,2}", "DATE-STAMP")]) output = mapping_to_dict(new_notebook) output.pop("nbformat_minor") assert output == { "cells": [{ "metadata": {}, "outputs": [{ "name": "stdout", "output_type": "stream", "text": ["DATE-STAMP\n"], }], "source": "from datetime import date\nprint(date.today())", }], "metadata": {}, "nbformat": 4, }
def test_config_from_metadata(): """Test extraction of configuration data from notebook metadata.""" notebook = create_notebook() notebook.metadata[META_KEY] = { "diff_ignore": ["/", "/cells/*/outputs"], "diff_replace": [ ["/cells/0/outputs/0", r"\d{2,4}-\d{1,2}-\d{1,2}", "DATE-STAMP"] ], } notebook.cells.extend( [ prepare_cell({"metadata": {}}), prepare_cell({"metadata": {META_KEY: {"diff_ignore": ["/", "/outputs"]}}}), prepare_cell( {"metadata": {META_KEY: {"diff_replace": [["/source", "s", "p"]]}}} ), ] ) config = config_from_metadata(notebook) assert config == MetadataConfig( diff_replace=( ("/cells/0/outputs/0", r"\d{2,4}-\d{1,2}-\d{1,2}", "DATE-STAMP"), ("/cells/2/source", "s", "p"), ), diff_ignore={"/", "/cells/*/outputs", "/cells/1/", "/cells/1/outputs"}, )
def test_gather_paths(): """Test gathering paths in the notebook.""" notebook = create_notebook() notebook.cells.extend( [ prepare_cell( { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ {"name": "stdout", "output_type": "stream", "text": ["hallo\n"]} ], "source": ["print('hallo')\n"], } ) ] ) paths = [] gather_json_paths(notebook, paths) assert paths == [ ("nbformat",), ("nbformat_minor",), ("cells", 0, "cell_type"), ("cells", 0, "execution_count"), ("cells", 0, "outputs", 0, "name"), ("cells", 0, "outputs", 0, "output_type"), ("cells", 0, "outputs", 0, "text"), ("cells", 0, "source"), ]
def test_regex_replace_nb_no_change(): """Test that, if no replacements are made, the notebook remains the same.""" notebook = create_notebook() notebook.cells.extend( [prepare_cell({"metadata": {}, "outputs": [], "source": ["print(1)\n"]})] ) new_notebook = regex_replace_nb(notebook, []) assert notebook == new_notebook
def test_beautifulsoup(data_regression): """Test applying beautifulsoup to html outputs.""" notebook = create_notebook() notebook.cells.extend([ prepare_cell({ "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{ "data": { "text/html": [ "\n", '<div class="section" id="submodules">\n', ' <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this headline">¶</a></h2>\n', # noqa: E501 "</div>", ], "text/plain": ["<IPython.core.display.HTML object>"], }, "execution_count": 1, "metadata": {}, "output_type": "execute_result", }], "source": [""], }), prepare_cell({ "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{ "data": { "image/svg+xml": [ '<svg height="100" width="100">\n', ' <circle cx="50" cy="50" fill="red" r="40" stroke="black" stroke-width="3"/></svg>\n', # noqa: E501 "", ], "text/plain": ["<IPython.core.display.SVG object>"], }, "execution_count": 2, "metadata": {}, "output_type": "execute_result", }], "source": [""], }), ]) new_notebook, resources = beautifulsoup(notebook, {}) assert resources["beautifulsoup"] == [ "/cells/0/outputs/0/text/html", "/cells/1/outputs/0/image/svg+xml", ] output = mapping_to_dict(new_notebook) output["nbformat_minor"] = 2 data_regression.check(output)
def test_coalesce_streams(): """Test coalesce_streams if streams require merging.""" notebook = create_notebook() notebook.cells.append( prepare_cell({ "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": ["hallo1\n"] }, { "name": "stdout", "output_type": "stream", "text": ["hallo2\n"] }, ], "source": "".join(["print('hallo1')\n", "print('hallo2')"]), })) expected = create_notebook() expected.cells.append( prepare_cell({ "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{ "name": "stdout", "output_type": "stream", "text": ["hallo1\nhallo2\n"], }], "source": "".join(["print('hallo1')\n", "print('hallo2')"]), })) new_notebook, _ = coalesce_streams(notebook, {}) assert new_notebook == expected
def test_execute_notebook_with_coverage(): """Test executing a notebook with coverage.""" notebook = create_notebook() notebook.cells = [ create_cell( dedent("""\ from pytest_notebook.notebook import create_notebook create_notebook() import nbformat """)) ] exec_results = execute_notebook(notebook, cwd=os.path.join(PATH, "raw_files"), with_coverage=True) if exec_results.exec_error: raise exec_results.exec_error assert isinstance(exec_results.notebook, nbformat.NotebookNode) assert "!coverage.py" in exec_results.resources[COVERAGE_KEY]
def test_blacken_code(data_regression): """Test blacken unformatted code.""" notebook = create_notebook() notebook.cells.append( prepare_cell({ "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": textwrap.dedent("""\ for i in range(5): x=i a ='123'# comment """), })) new_notebook, _ = blacken_code(notebook, {}) output = mapping_to_dict(new_notebook) output["nbformat_minor"] = 2 data_regression.check(output)
def test_regex_replace_nb_with_wildcard(): """Test regex replacing notebook values.""" notebook = create_notebook() notebook.cells.extend([ prepare_cell({ "metadata": {}, "outputs": [], "source": ["print(1)\n", "print(2)"] }), prepare_cell({ "metadata": {}, "outputs": [], "source": ["print(1)\n", "print(2)"] }), ]) new_notebook = regex_replace_nb(notebook, [("/cells/*/source", "p", "s"), ("/cells/0/source", "t", "y")]) output = mapping_to_dict(new_notebook) output.pop("nbformat_minor") assert output == { "cells": [ { "metadata": {}, "outputs": [], "source": "sriny(1)\nsriny(2)" }, { "metadata": {}, "outputs": [], "source": "srint(1)\nsrint(2)" }, ], "metadata": {}, "nbformat": 4, }
def test_config_from_metadata_none(): """Test that, if no notebook metadata, the returned MetadataConfig is empty.""" notebook = create_notebook() config = config_from_metadata(notebook) assert config == MetadataConfig()
def test_beautifulsoup_no_output(): """Test prettify if no outputs present.""" notebook = create_notebook() new_notebook, _ = beautifulsoup(notebook, {}) assert notebook == new_notebook
def test_blacken_no_code(): """Test blacken if no code cells present.""" notebook = create_notebook() new_notebook, _ = blacken_code(notebook, {}) assert notebook == new_notebook