diff --git a/.ci/environment-ci.yml b/.ci/environment-ci.yml index 5243e0b6b..1582dcf5e 100644 --- a/.ci/environment-ci.yml +++ b/.ci/environment-ci.yml @@ -10,23 +10,6 @@ channels: - defaults - conda-forge dependencies: - - ipykernel - - nbconvert + - jupyterlab - nbformat>=5.1.2 - - pyyaml - - toml - - markdown-it-py - - mdit-py-plugins - - pip - - pytest - - pytest-randomly - - pytest-cov - - coverage - - flake8 - - autopep8 - - black - - isort - pandoc==2.16.2 - - sphinx-gallery<0.8 - - pre-commit - - gitpython diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 000000000..8e3dfbb9e --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,34 @@ +codecov: + notify: + after_n_builds: 15 + +comment: + after_n_builds: 15 + +coverage: + status: + project: + source: + paths: + - "src/jupytext/" + target: 97% + threshold: 0.002 + tests: + paths: + - "tests/" + target: 100% + unit-tests: + flags: + - unit + functional-tests: + flags: + - functional + integration-tests: + flags: + - integration + external-tests: + flags: + - external + patch: + default: + target: 80% # new contributions should have a coverage at least equal to target diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0dbbcbc98..bc508b0b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,10 @@ jobs: needs: [codeql] uses: ./.github/workflows/step_tests-pip.yml + test-unit-functional-integration: + needs: [codeql] + uses: ./.github/workflows/step_test_unit_functional.yml + test-conda: needs: [codeql] uses: ./.github/workflows/step_tests-conda.yml @@ -56,7 +60,7 @@ jobs: upload: ${{ inputs.upload-build-artifacts || false }} pass: - needs: [pre-commit, codeql, test-pip, test-conda, test-ui, build] + needs: [pre-commit, codeql, test-unit-functional-integration, test-pip, test-conda, test-ui, build] runs-on: ubuntu-latest steps: - name: Check jobs diff --git a/.github/workflows/step_build.yml b/.github/workflows/step_build.yml index abb0e9613..d5cb47807 100644 --- a/.github/workflows/step_build.yml +++ b/.github/workflows/step_build.yml @@ -29,7 +29,7 @@ jobs: python -m pip install build wheel # NOTE: These builds and verifications of the builds can be done more - # robustily with jupyter-releaser. + # robustly with jupyter-releaser. # # Removed the check on size of package as we are distributing tests/ with # sdist now and they are around 8MB. Seems like original check was to make diff --git a/.github/workflows/step_test_unit_functional.yml b/.github/workflows/step_test_unit_functional.yml new file mode 100644 index 000000000..1bf3c9ce6 --- /dev/null +++ b/.github/workflows/step_test_unit_functional.yml @@ -0,0 +1,45 @@ +name: test-categories +run-name: Run Unit/Functional/Integration and External tests using Pip + +on: + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-test_classification + cancel-in-progress: true + +jobs: + test-pip: + continue-on-error: ${{ matrix.experimental || false }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + python-version: [ "3.11" ] + coverage: [unit, functional, integration, external] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Base Setup + uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + with: + python_version: ${{ matrix.python-version }} + + - name: Install from source + run: HATCH_BUILD_HOOKS_ENABLE=false python -m pip install -e '.[test-cov,test-${{ matrix.coverage }}]' markdown-it-py~=3.0 + + - name: Install a Jupyter Kernel + run: python -m ipykernel install --name python_kernel --user + + - name: Run the tests + run: pytest tests/${{ matrix.coverage }} --cov + + - name: Upload the coverage + uses: codecov/codecov-action@v3 + with: + flags: ${{ matrix.coverage }} + fail_ci_if_error: true + verbose: true diff --git a/.github/workflows/step_tests-conda.yml b/.github/workflows/step_tests-conda.yml index a8577da6c..ce105fc6e 100644 --- a/.github/workflows/step_tests-conda.yml +++ b/.github/workflows/step_tests-conda.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ] - python-version: [ 3.9 ] + python-version: [ 3.11 ] runs-on: ${{ matrix.os }} steps: @@ -38,9 +38,8 @@ jobs: use-only-tar-bz2: true - name: Install from source - # This is required for the pre-commit tests shell: pwsh - run: python -m pip install -e '.[test-cov]' + run: python -m pip install -e '.[test-external,test-cov]' - name: Create kernel shell: pwsh @@ -61,8 +60,7 @@ jobs: - name: Test with pytest shell: pwsh - run: pytest --cov=src/jupytext --cov-report=xml + run: pytest --cov - name: Upload coverage uses: codecov/codecov-action@v3 - if: ${{ matrix.os != 'windows-latest' }} diff --git a/.github/workflows/step_tests-pip.yml b/.github/workflows/step_tests-pip.yml index ce18690af..2c95cec62 100644 --- a/.github/workflows/step_tests-pip.yml +++ b/.github/workflows/step_tests-pip.yml @@ -18,7 +18,6 @@ jobs: matrix: python-version: [ "3.8", "3.9", "3.10", "3.11" ] markdown-it-py-version: ["~=2.0"] - kernel: [true] include: - python-version: "3.12-dev" experimental: true @@ -28,14 +27,13 @@ jobs: markdown-it-py-version: "" - python-version: "3.x" markdown-it-py-version: "~=3.0" - - python-version: "3.11" + - python-version: "3.x" markdown-it-py-version: "~=4.0" experimental: true - python-version: "3.x" - kernel: false + no_kernel: true - python-version: "3.x" quarto: true - kernel: true steps: - name: Checkout @@ -46,11 +44,11 @@ jobs: with: python_version: ${{ matrix.python-version }} - - name: Install from source (required for the pre-commit tests) - run: python -m pip install -e '.[test-cov]' ${{ matrix.markdown-it-py-version && format('markdown-it-py{0}', matrix.markdown-it-py-version) }} + - name: Install from source + run: python -m pip install -e '.[test-cov,test-external]' ${{ matrix.markdown-it-py-version && format('markdown-it-py{0}', matrix.markdown-it-py-version) }} - name: Install a Jupyter Kernel - if: ${{ matrix.kernel }} + if: ${{ !matrix.no_kernel }} run: python -m ipykernel install --name python_kernel --user - name: Install Quarto @@ -66,12 +64,13 @@ jobs: - name: Test lab extension run: | # Check extension + pip install jupyterlab jupyter labextension list jupyter labextension list 2>&1 | grep -ie "jupyterlab-jupytext.*OK" python -m jupyterlab.browser_check - name: Test with pytest - run: pytest --cov=src/jupytext --cov-report=xml + run: pytest --cov - name: Upload coverage uses: codecov/codecov-action@v3 diff --git a/.github/workflows/step_tests-ui.yml b/.github/workflows/step_tests-ui.yml index 5cbb050c1..0579887c4 100644 --- a/.github/workflows/step_tests-ui.yml +++ b/.github/workflows/step_tests-ui.yml @@ -20,14 +20,16 @@ jobs: - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - - name: Install from source (required for the pre-commit tests) - run: python -m pip install -e '.[test-cov]' + - name: Install from source + run: python -m pip install -e . - name: Install galata working-directory: jupyterlab/packages/jupyterlab-jupytext-extension/ui-tests env: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - run: jlpm install + run: | + pip install jupyterlab + jlpm install - name: Install browser working-directory: jupyterlab/packages/jupyterlab-jupytext-extension/ui-tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e66eccbfe..998ed165b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ exclude: > (?x)^( demo/.*| - tests/notebooks/.*| + tests/data/notebooks/.*| )$ repos: diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 0d1814fed..000000000 --- a/codecov.yml +++ /dev/null @@ -1,23 +0,0 @@ -codecov: - notify: - after_n_builds: 11 - -comment: - after_n_builds: 11 - -coverage: - status: - project: - default: false # disable the default status that measures entire project - tests: - paths: - - "tests/" - target: 100% - source: - paths: - - "jupytext/" - target: 97% - threshold: 0.002 - patch: - default: - target: 80% # new contributions should have a coverage at least equal to target diff --git a/docs/contributing.md b/docs/contributing.md index f8ea09834..198821d01 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -20,5 +20,5 @@ You want to submit an enhancement on Jupytext? Unless this is a small change, we A pull request for which you do not need to contact us in advance is the addition of a new language to Jupytext. In principle that should be easy - you would only have to: - document the language extension and comment by adding one line to `_SCRIPT_EXTENSIONS` in `jupytext/languages.py`. - add the language to `docs/languages.md` -- contribute a sample notebook in `tests/notebooks/ipynb_[language]`. -- run the tests suite (create a [development environment](developing.md), then execute `pytest` locally). The tests will generate various text representations corresponding to your notebook under `tests/notebooks/mirror/`. Please verify that these files are valid scripts, and include them in your PR. +- contribute a sample notebook in `tests/data/notebooks/inputs/ipynb_[language]`. +- run the tests suite (create a [development environment](developing.md), then execute `pytest` locally). The tests will generate various text representations corresponding to your notebook under `tests/data/notebooks/outputs/`. Please verify that these files are valid scripts, and include them in your PR. diff --git a/docs/using-pre-commit.md b/docs/using-pre-commit.md index db999ec2a..408f78877 100644 --- a/docs/using-pre-commit.md +++ b/docs/using-pre-commit.md @@ -62,5 +62,5 @@ repos: language_version: python3 ``` -Tested examples of how to use the pre-commit hook are available in our [tests](https://github.com/mwouts/jupytext/tree/main/tests) - -see for instance [test_pre_commit_1_sync_with_config.py](https://github.com/mwouts/jupytext/blob/main/tests/test_pre_commit_1_sync_with_config.py). +Tested examples of how to use the pre-commit hook are available in our [tests](https://github.com/mwouts/jupytext/tree/main/tests/functional/pre-commit) - +see for instance [test_pre_commit_1_sync_with_config.py](https://github.com/mwouts/jupytext/blob/main/tests/functional/pre-commit/test_pre_commit_1_sync_with_config.py). diff --git a/environment.yml b/environment.yml index 87959902c..3e4df5174 100644 --- a/environment.yml +++ b/environment.yml @@ -6,23 +6,6 @@ dependencies: - python>=3.8 - jupyterlab>=4.0.0 - nbformat>=5.1.2 - - pyyaml - - toml - - markdown-it-py>=1.0.0,<3.0.0 - - mdit-py-plugins - - nbconvert - - ipykernel - - pytest - - pytest-xdist - - pytest-randomly - - pytest-cov - pre-commit - - gitpython - - pylint - - flake8 - - black==23.11.0 - - isort==5.12.0 - - autopep8 - - sphinx-gallery<0.8 - - pandoc==2.16.2 - nodejs>=20 + - pandoc==2.16.2 diff --git a/pyproject.toml b/pyproject.toml index a60b0f94f..e9bc8d8bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,10 +32,11 @@ classifiers = [ ] dependencies = [ "nbformat", - "pyyaml", - "toml", "mdit_py_plugins", "markdown-it-py>=1.0.0", + "packaging", + "pyyaml", + "toml", ] dynamic = ["version"] @@ -46,31 +47,44 @@ Documentation = "https://jupytext.readthedocs.io" [project.optional-dependencies] # Test related dependencies -# TODO: Split them into unit, integration and functional tests groups test = [ - "autopep8", - "black", - "isort", - "ruff", - "flake8", - "pytest", - "pytest-randomly", - "gitpython", - "jupyterlab", - "notebook", - "nbconvert", - # jupyter-fs==0.4.0 is async, which is not supported by Jupytext ATM - "jupyter-fs<0.4.0", - "ipykernel", - "pre-commit", + "pytest", + "pytest-randomly" +] +test-functional = [ + "jupytext[test]", +] +test-integration = [ + "jupytext[test-functional]", + "jupyter-server", + # jupytext --execute + "nbconvert", + "ipykernel", +] +test-external = [ + "jupytext[test-integration]", + # jupytext --pipe and --check + "autopep8", + "black", + "isort", + "flake8", + # Sphinx gallery + "sphinx-gallery<0.8", + # Pre-commit tests + "gitpython", + "pre-commit", + # Interaction with other contents managers + # jupyter-fs==0.4.0 is async, which is not supported by Jupytext ATM + "jupyter-fs<0.4.0" ] # Coverage requirements test-cov = [ - "jupytext[test]", + "jupytext[test-integration]", "pytest-cov>=2.6.1", ] dev = [ "jupytext[test]", + "pre-commit" ] # Documentation dependencies docs = [ @@ -103,9 +117,7 @@ path = "src/jupytext/version.py" # Following config is related to JupyterLab extension [tool.hatch.build.targets.sdist] artifacts = ["jupyterlab/jupyterlab_jupytext/labextension"] -# Exclude tests (contains Notebooks that have a total size of ~8MB) to reduce sdist -# tarball. (See #1142) -exclude = ["tests", "demo", "**/.yarn", "**/node_modules"] +exclude = ["demo", "**/.yarn", "**/node_modules"] [tool.hatch.build.targets.wheel] packages = ["src/jupytext", "src/jupytext_config", "jupyterlab/jupyterlab_jupytext"] @@ -163,7 +175,7 @@ ignore = ["W002"] [tool.ruff] line-length = 127 exclude = [ - "tests/notebooks/*", + "tests/data/notebooks/*", ] # Seems like W503 is not implemented in ruff # ref: https://github.com/astral-sh/ruff/issues/4125 @@ -172,9 +184,40 @@ ignore = [ ] [tool.pytest.ini_options] +markers = [ + "requires_black", + "requires_isort", + "requires_flake8", + "requires_autopep8", + "requires_nbconvert", + "requires_myst", + "requires_no_myst", + "requires_quarto", + "requires_pandoc", + "requires_no_pandoc", + "requires_sphinx_gallery", + "requires_user_kernel_python3", + "requires_ir_kernel", + "skip_on_windows", + "pre_commit", +] filterwarnings = [ # Uncomment this "error" to turn all unfiltered warnings into errors # "error", + # Our cwd_tmpdir fixture + "ignore:pathlib.Path.__enter__\\(\\) is deprecated and scheduled for removal in Python 3.13:DeprecationWarning", + # Pre-commit + "ignore:read_text is deprecated. Use files\\(\\) instead:DeprecationWarning", + "ignore:open_text is deprecated. Use files\\(\\) instead:DeprecationWarning", + # Jupyter + "ignore:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning", + # Jupyter notebook + "ignore:Support for bleach <5 will be removed in a future version of nbconvert:DeprecationWarning", + # jupyterfs + "ignore:run_pre_save_hook is deprecated, use run_pre_save_hooks instead:DeprecationWarning", + "ignore:run_post_save_hook is deprecated, use run_post_save_hooks instead:DeprecationWarning", + "ignore:Deprecated call to `pkg_resources.declare_namespace:DeprecationWarning", + "ignore:pkg_resources is deprecated as an API:DeprecationWarning", # use single quote to denote raw strings in toml # (10 warnings) 'ignore:Passing unrecognized arguments to super\(KernelSpec\).__init__:DeprecationWarning', diff --git a/src/jupytext/cell_reader.py b/src/jupytext/cell_reader.py index 74aa45230..e4ea21c13 100644 --- a/src/jupytext/cell_reader.py +++ b/src/jupytext/cell_reader.py @@ -5,16 +5,16 @@ from copy import copy from nbformat.v4.nbbase import new_code_cell, new_markdown_cell, new_raw_cell +from packaging.version import parse from .doxygen import doxygen_to_markdown from .languages import _SCRIPT_EXTENSIONS -from .parse_version import parse_version # Sphinx Gallery is an optional dependency. And we intercept the SyntaxError for #301 try: from sphinx_gallery import __version__ as sg_version - if parse_version(sg_version) <= parse_version("0.7.0"): + if parse(sg_version) <= parse("0.7.0"): from sphinx_gallery.notebook import rst2md else: warnings.warn( diff --git a/src/jupytext/cli.py b/src/jupytext/cli.py index dcb1b9630..6ce98a033 100644 --- a/src/jupytext/cli.py +++ b/src/jupytext/cli.py @@ -50,6 +50,15 @@ def system(*args, **kwargs): return out.decode("utf-8") +def tool_version(tool): + try: + args = tool.split(" ") + args.append("--version") + return system(*args) + except (OSError, SystemExit): # pragma: no cover + return None + + def str2bool(value): """Parse Yes/No/Default string https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse""" diff --git a/src/jupytext/compare.py b/src/jupytext/compare.py index df3ea4739..5b3347c7e 100644 --- a/src/jupytext/compare.py +++ b/src/jupytext/compare.py @@ -2,13 +2,16 @@ import difflib import json +import os import re +from jupytext.paired_paths import full_path + from .cell_metadata import _IGNORE_CELL_METADATA from .combine import combine_inputs_with_outputs -from .formats import long_form_one_format +from .formats import check_auto_ext, long_form_one_format from .header import _DEFAULT_NOTEBOOK_METADATA -from .jupytext import reads, writes +from .jupytext import read, reads, write, writes from .metadata_filter import filter_metadata _BLANK_LINE = re.compile(r"^\s*$") @@ -388,3 +391,75 @@ def test_round_trip_conversion( allow_expected_differences, raise_on_first_difference=stop_on_first_error, ) + + +# The functions below are used in the Jupytext text collection +def create_mirror_file_if_missing(mirror_file, notebook, fmt): + if not os.path.isfile(mirror_file): + write(notebook, mirror_file, fmt=fmt) + + +def assert_conversion_same_as_mirror(nb_file, fmt, mirror_name, compare_notebook=False): + """This function is used in the tests""" + dirname, basename = os.path.split(nb_file) + file_name, org_ext = os.path.splitext(basename) + fmt = long_form_one_format(fmt) + notebook = read(nb_file, fmt=fmt) + fmt = check_auto_ext(fmt, notebook.metadata, "") + ext = fmt["extension"] + mirror_file = os.path.join( + dirname, "..", "..", "outputs", mirror_name, full_path(file_name, fmt) + ) + + # it's better not to have Jupytext metadata in test notebooks: + if fmt == "ipynb" and "jupytext" in notebook.metadata: # pragma: no cover + notebook.metadata.pop("jupytext") + write(nb_file, fmt=fmt) + + create_mirror_file_if_missing(mirror_file, notebook, fmt) + + # Compare the text representation of the two notebooks + if compare_notebook: + # Read and convert the mirror file to the latest nbformat version if necessary + nb_mirror = read(mirror_file, as_version=notebook.nbformat) + nb_mirror.nbformat_minor = notebook.nbformat_minor + compare_notebooks(nb_mirror, notebook) + return + elif ext == ".ipynb": + notebook = read(mirror_file) + fmt.update({"extension": org_ext}) + actual = writes(notebook, fmt) + with open(nb_file, encoding="utf-8") as fp: + expected = fp.read() + else: + actual = writes(notebook, fmt) + with open(mirror_file, encoding="utf-8") as fp: + expected = fp.read() + + if not actual.endswith("\n"): + actual = actual + "\n" + compare(actual, expected) + + # Compare the two notebooks + if ext != ".ipynb": + notebook = read(nb_file) + nb_mirror = read(mirror_file, fmt=fmt) + + if fmt.get("format_name") == "sphinx": + nb_mirror.cells = nb_mirror.cells[1:] + for cell in notebook.cells: + cell.metadata = {} + for cell in nb_mirror.cells: + cell.metadata = {} + + compare_notebooks(nb_mirror, notebook, fmt) + + nb_mirror = combine_inputs_with_outputs(nb_mirror, notebook) + compare_notebooks(nb_mirror, notebook, fmt, compare_outputs=True) + + +def notebook_model(nb): + """Return a notebook model, with content a + dictionary rather than a notebook object. + To be used in tests only.""" + return dict(type="notebook", content=json.loads(json.dumps(nb))) diff --git a/src/jupytext/formats.py b/src/jupytext/formats.py index d9a481768..efed28cd4 100644 --- a/src/jupytext/formats.py +++ b/src/jupytext/formats.py @@ -40,7 +40,7 @@ myst_extensions, myst_version, ) -from .pandoc import pandoc_version +from .pandoc import is_pandoc_available, pandoc_version from .stringparser import StringParser from .version import __version__ @@ -825,3 +825,13 @@ def check_auto_ext(fmt, metadata, option): option, short_form_one_format(fmt) ) ) + + +def formats_with_support_for_cell_metadata(): + for fmt in JUPYTEXT_FORMATS: + if fmt.format_name == "myst" and not is_myst_available(): + continue + if fmt.format_name == "pandoc" and not is_pandoc_available(): + continue + if fmt.format_name not in ["sphinx", "nomarker", "spin", "quarto"]: + yield f"{fmt.extension[1:]}:{fmt.format_name}" diff --git a/src/jupytext/pandoc.py b/src/jupytext/pandoc.py index 11b9b6e1b..41afce087 100644 --- a/src/jupytext/pandoc.py +++ b/src/jupytext/pandoc.py @@ -3,13 +3,11 @@ import os import subprocess import tempfile -from functools import partial # Copy nbformat reads and writes to avoid them being patched in the contents manager!! from nbformat import reads as ipynb_reads from nbformat import writes as ipynb_writes - -from .parse_version import parse_version as parse +from packaging.version import parse class PandocError(OSError): @@ -58,14 +56,13 @@ def raise_if_pandoc_is_not_available(min_version="2.7.2", max_version=None): "but pandoc was not found" ) - parse_version = partial(parse, custom_error=PandocError) - if parse_version(version) < parse_version(min_version): + if parse(version) < parse(min_version): raise PandocError( f"The Pandoc Markdown format requires 'pandoc>={min_version}', " f"but pandoc version {version} was found" ) - if max_version and parse_version(version) > parse_version(max_version): + if max_version and parse(version) > parse(max_version): raise PandocError( f"The Pandoc Markdown format requires 'pandoc<={max_version}', " f"but pandoc version {version} was found" @@ -89,8 +86,7 @@ def md_to_notebook(text): tmp_file.write(text.encode("utf-8")) tmp_file.close() - parse_version = partial(parse, custom_error=PandocError) - if parse_version(pandoc_version()) < parse_version("2.11.2"): + if parse(pandoc_version()) < parse("2.11.2"): pandoc_args = "--from markdown --to ipynb -s --atx-headers --wrap=preserve --preserve-tabs" else: pandoc_args = "--from markdown --to ipynb -s --markdown-headings=atx --wrap=preserve --preserve-tabs" @@ -114,8 +110,7 @@ def notebook_to_md(notebook): tmp_file.write(ipynb_writes(notebook).encode("utf-8")) tmp_file.close() - parse_version = partial(parse, custom_error=PandocError) - if parse_version(pandoc_version()) < parse_version("2.11.2"): + if parse(pandoc_version()) < parse("2.11.2"): pandoc_args = "--from ipynb --to markdown -s --atx-headers --wrap=preserve --preserve-tabs" else: pandoc_args = "--from ipynb --to markdown -s --markdown-headings=atx --wrap=preserve --preserve-tabs" diff --git a/src/jupytext/parse_version.py b/src/jupytext/parse_version.py deleted file mode 100644 index 86fbde04a..000000000 --- a/src/jupytext/parse_version.py +++ /dev/null @@ -1,11 +0,0 @@ -def parse_version(version, custom_error=ImportError): - try: - from pkg_resources import parse_version as parse - except ImportError: - try: - from packaging.version import parse - except ImportError: - raise custom_error("Please install either pkg_resources or packaging") - - print(version) - return parse(version) diff --git a/src/jupytext/quarto.py b/src/jupytext/quarto.py index e704b7682..0eec6b2dc 100644 --- a/src/jupytext/quarto.py +++ b/src/jupytext/quarto.py @@ -3,13 +3,11 @@ import os import subprocess import tempfile -from functools import partial # Copy nbformat reads and writes to avoid them being patched in the contents manager!! from nbformat import reads as ipynb_reads from nbformat import writes as ipynb_writes - -from .parse_version import parse_version as parse +from packaging.version import parse QUARTO_MIN_VERSION = "0.2.134" @@ -53,8 +51,7 @@ def raise_if_quarto_is_not_available(min_version=QUARTO_MIN_VERSION): "but quarto was not found" ) - parse_version = partial(parse, custom_error=QuartoError) - if parse_version(version) < parse_version(min_version): + if parse(version) < parse(min_version): raise QuartoError( f"The Quarto Markdown format requires 'quarto>={min_version}', " f"but quarto version {version} was not found" diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/conftest.py b/tests/conftest.py index 53f8ac53e..8fd89c621 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,12 @@ +import itertools +import os.path +import re +import sys import unittest.mock as mock from pathlib import Path import pytest -from git import Repo +from jupyter_client.kernelspec import find_kernel_specs, get_kernel_spec from nbformat.v4 import nbbase from nbformat.v4.nbbase import ( new_code_cell, @@ -12,14 +16,20 @@ ) import jupytext -from jupytext.cli import system +from jupytext.cell_reader import rst2md +from jupytext.cli import system, tool_version +from jupytext.formats import formats_with_support_for_cell_metadata +from jupytext.myst import is_myst_available +from jupytext.pandoc import is_pandoc_available +from jupytext.quarto import is_quarto_available -from .utils import formats_with_support_for_cell_metadata - -# Pytest's tmpdir is in /tmp (at least for me), so this helps avoiding interferences between +# Pytest's tmpdir is in /tmp (at least for me), so this helps to avoid interferences between # global configuration on HOME and the test collection jupytext.config.JUPYTEXT_CEILING_DIRECTORIES = ["/tmp/"] +SAMPLE_NOTEBOOK_PATH = Path(__file__).parent / "data" / "notebooks" / "inputs" +ROOT_PATH = Path(__file__).parent.parent + @pytest.fixture def no_jupytext_version_number(): @@ -27,12 +37,6 @@ def no_jupytext_version_number(): yield -@pytest.fixture -def tmp_repo(tmpdir): - repo = Repo.init(str(tmpdir)) - return repo - - @pytest.fixture def cwd_tmpdir(tmpdir): # Run the whole test from inside tmpdir @@ -71,7 +75,16 @@ def python_notebook(): "display_name": "Python 3", "language": "python", "name": "python_kernel", - } + }, + "language_info": { + "codemirror_mode": {"name": "ipython", "version": 3}, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4", + }, }, ) @@ -107,6 +120,296 @@ def fmt_with_cell_metadata(request): return request.param +def list_notebooks(path="ipynb", skip=""): + """All notebooks in the directory notebooks/path, + or in the package itself""" + if path == "ipynb": + return ( + list_notebooks("ipynb_julia", skip=skip) + + list_notebooks("ipynb_py", skip=skip) + + list_notebooks("ipynb_R", skip=skip) + ) + + nb_path = SAMPLE_NOTEBOOK_PATH + + if path == "ipynb_all": + return itertools.chain( + *( + list_notebooks(folder.name, skip=skip) + for folder in nb_path.iterdir() + if folder.name.startswith("ipynb_") + ) + ) + + if path == "all": + return itertools.chain( + *(list_notebooks(folder.name, skip=skip) for folder in nb_path.iterdir()) + ) + + if path.startswith("."): + nb_path = Path(__file__).parent / ".." / path + else: + nb_path = nb_path / path + + if skip: + skip_re = re.compile(".*" + skip + ".*") + return [ + str(nb_file) + for nb_file in nb_path.iterdir() + if nb_file.is_file() and not skip_re.match(nb_file.name) + ] + + return [str(nb_file) for nb_file in nb_path.iterdir() if nb_file.is_file()] + + +def notebook_id_func(nb_file): + nb_file = Path(nb_file) + if SAMPLE_NOTEBOOK_PATH in nb_file.parents: + return str(nb_file.relative_to(SAMPLE_NOTEBOOK_PATH)) + return str(nb_file.relative_to(ROOT_PATH)) + + +@pytest.fixture(params=list_notebooks("ipynb_all"), ids=notebook_id_func) +def ipynb_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("all"), ids=notebook_id_func) +def any_nb_file(request): + return request.param + + +@pytest.fixture +def ipynb_py_R_jl_files(): + return list_notebooks() + + +@pytest.fixture(params=list_notebooks(), ids=notebook_id_func) +def ipynb_py_R_jl_file(request): + return request.param + + +@pytest.fixture +def ipynb_py_R_jl_ext(ipynb_py_R_jl_file): + for language in "py", "R", "julia": + if f"{os.path.sep}ipynb_{language}{os.path.sep}" in ipynb_py_R_jl_file: + return ".jl" if language == "julia" else "." + language + + raise RuntimeError(f"language not found for {ipynb_py_R_jl_file}") + + +@pytest.fixture( + params=list_notebooks("ipynb") + list_notebooks("Rmd"), ids=notebook_id_func +) +def ipynb_or_rmd_file(request): + return request.param + + +@pytest.fixture( + params=list_notebooks("ipynb_py") + list_notebooks("ipynb_R"), ids=notebook_id_func +) +def ipynb_py_R_file(request): + return request.param + + +@pytest.fixture +def ipynb_py_files(): + return list_notebooks("ipynb_py") + + +@pytest.fixture(params=list_notebooks("ipynb_py"), ids=notebook_id_func) +def ipynb_py_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("ipynb_R"), ids=notebook_id_func) +def ipynb_R_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("ipynb_julia"), ids=notebook_id_func) +def ipynb_julia_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("ipynb_scheme"), ids=notebook_id_func) +def ipynb_scheme_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("ipynb_cpp"), ids=notebook_id_func) +def ipynb_cpp_file(request): + return request.param + + +@pytest.fixture( + params=list_notebooks("ipynb_all", skip="many hash"), ids=notebook_id_func +) +def ipynb_to_light(request): + return request.param + + +@pytest.fixture(params=list_notebooks("ipynb_all"), ids=notebook_id_func) +def ipynb_to_myst(request): + return request.param + + +@pytest.fixture( + params=[ + py_file + for py_file in list_notebooks("./src/jupytext") + if py_file.endswith(".py") and "folding_markers" not in py_file + ], + ids=notebook_id_func, +) +def py_file(request): + return request.param + + +@pytest.fixture( + params=list_notebooks("julia") + + list_notebooks("python") + + list_notebooks("R") + + list_notebooks("ps1"), + ids=notebook_id_func, +) +def script_to_ipynb(request): + return request.param + + +@pytest.fixture(params=list_notebooks("python"), ids=notebook_id_func) +def python_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("percent"), ids=notebook_id_func) +def percent_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("hydrogen"), ids=notebook_id_func) +def hydrogen_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("R"), ids=notebook_id_func) +def r_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("R_spin"), ids=notebook_id_func) +def r_spin_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("md"), ids=notebook_id_func) +def md_file(request): + return request.param + + +@pytest.fixture( + params=list_notebooks( + "ipynb", skip="(functional|Notebook with|flavors|invalid|305)" + ), + ids=notebook_id_func, +) +def ipynb_to_pandoc(request): + return request.param + + +@pytest.fixture( + params=list_notebooks( + "ipynb", + skip="(functional|Notebook with|plotly_graphs|flavors|complex_metadata|" + "update83|raw_cell|_66|nteract|LaTeX|invalid|305|text_outputs|ir_notebook|jupyter|with_R_magic)", + ), + ids=notebook_id_func, +) +def ipynb_to_quarto(request): + return request.param + + +@pytest.fixture( + params=list_notebooks("ipynb_py", skip="(raw|hash|frozen|magic|html|164|long)"), + ids=notebook_id_func, +) +def ipynb_to_sphinx(request): + return request.param + + +@pytest.fixture(params=list_notebooks("Rmd"), ids=notebook_id_func) +def rmd_file(request): + return request.param + + +@pytest.fixture(params=list_notebooks("sphinx"), ids=notebook_id_func) +def sphinx_file(request): + return request.param + + +def pytest_runtest_setup(item): + for mark in item.iter_markers(): + for tool in [ + "jupytext", + "black", + "isort", + "flake8", + "autopep8", + "jupyter nbconvert", + ]: + if mark.name == f"requires_{tool.replace(' ', '_')}": + if not tool_version(tool): + pytest.skip(f"{tool} is not installed") + if mark.name == "requires_sphinx_gallery": + if not rst2md: + pytest.skip("sphinx_gallery is not available") + if mark.name == "requires_pandoc": + # The mirror files changed slightly when Pandoc 2.11 was introduced + # https://github.com/mwouts/jupytext/commit/c07d919702999056ce47f92b74f63a15c8361c5d + # The mirror files changed again when Pandoc 2.16 was introduced + # https://github.com/mwouts/jupytext/pull/919/commits/1fa1451ecdaa6ad8d803bcb6fb0c0cf09e5371bf + if not is_pandoc_available(min_version="2.16.2", max_version="2.16.2"): + pytest.skip("pandoc==2.16.2 is not available") + if mark.name == "requires_quarto": + if not is_quarto_available(min_version="0.2.0"): + pytest.skip("quarto>=0.2 is not available") + if mark.name == "requires_no_pandoc": + if is_pandoc_available(): + pytest.skip("Pandoc is installed") + if mark.name == "requires_ir_kernel": + if not any( + get_kernel_spec(name).language == "R" for name in find_kernel_specs() + ): + pytest.skip("irkernel is not installed") + if mark.name == "requires_user_kernel_python3": + if "python_kernel" not in find_kernel_specs(): + pytest.skip( + "Please run 'python -m ipykernel install --name python_kernel --user'" + ) + if mark.name == "requires_myst": + if not is_myst_available(): + pytest.skip("myst_parser not found") + if mark.name == "requires_no_myst": + if is_myst_available(): + pytest.skip("myst is available") + if mark.name == "skip_on_windows": + if sys.platform.startswith("win"): + pytest.skip("Issue 489") + if mark.name == "pre_commit": + if sys.platform.startswith("win"): + pytest.skip( + "OSError: [WinError 193] %1 is not a valid Win32 application" + ) + if not (Path(__file__).parent.parent / ".git").is_dir(): + pytest.skip("Jupytext folder is not a git repository #814") + + +def pytest_collection_modifyitems(config, items): + for item in items: + if (config.rootdir / "tests" / "external" / "pre_commit") in item.path.parents: + item.add_marker(pytest.mark.pre_commit) + + """To make sure that cell ids are distinct we use a global counter. This solves https://github.com/mwouts/jupytext/issues/747""" global_cell_count = 0 diff --git a/tests/notebooks/R/simple_r_script.R b/tests/data/notebooks/inputs/R/simple_r_script.R similarity index 100% rename from tests/notebooks/R/simple_r_script.R rename to tests/data/notebooks/inputs/R/simple_r_script.R diff --git a/tests/notebooks/R_spin/knitr-spin.R b/tests/data/notebooks/inputs/R_spin/knitr-spin.R similarity index 100% rename from tests/notebooks/R_spin/knitr-spin.R rename to tests/data/notebooks/inputs/R_spin/knitr-spin.R diff --git a/tests/notebooks/Rmd/R_sample.Rmd b/tests/data/notebooks/inputs/Rmd/R_sample.Rmd similarity index 100% rename from tests/notebooks/Rmd/R_sample.Rmd rename to tests/data/notebooks/inputs/Rmd/R_sample.Rmd diff --git a/tests/notebooks/Rmd/chunk_options.Rmd b/tests/data/notebooks/inputs/Rmd/chunk_options.Rmd similarity index 100% rename from tests/notebooks/Rmd/chunk_options.Rmd rename to tests/data/notebooks/inputs/Rmd/chunk_options.Rmd diff --git a/tests/notebooks/Rmd/ioslides.Rmd b/tests/data/notebooks/inputs/Rmd/ioslides.Rmd similarity index 100% rename from tests/notebooks/Rmd/ioslides.Rmd rename to tests/data/notebooks/inputs/Rmd/ioslides.Rmd diff --git a/tests/notebooks/Rmd/knitr-spin.Rmd b/tests/data/notebooks/inputs/Rmd/knitr-spin.Rmd similarity index 100% rename from tests/notebooks/Rmd/knitr-spin.Rmd rename to tests/data/notebooks/inputs/Rmd/knitr-spin.Rmd diff --git a/tests/notebooks/Rmd/markdown.Rmd b/tests/data/notebooks/inputs/Rmd/markdown.Rmd similarity index 100% rename from tests/notebooks/Rmd/markdown.Rmd rename to tests/data/notebooks/inputs/Rmd/markdown.Rmd diff --git a/tests/notebooks/hydrogen/hydrogen_latex_html_R_magics.py b/tests/data/notebooks/inputs/hydrogen/hydrogen_latex_html_R_magics.py similarity index 100% rename from tests/notebooks/hydrogen/hydrogen_latex_html_R_magics.py rename to tests/data/notebooks/inputs/hydrogen/hydrogen_latex_html_R_magics.py diff --git a/tests/notebooks/ipynb_R/R notebook with invalid cell keys.ipynb b/tests/data/notebooks/inputs/ipynb_R/R notebook with invalid cell keys.ipynb similarity index 100% rename from tests/notebooks/ipynb_R/R notebook with invalid cell keys.ipynb rename to tests/data/notebooks/inputs/ipynb_R/R notebook with invalid cell keys.ipynb diff --git a/tests/notebooks/ipynb_R/ir_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_R/ir_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_R/ir_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_R/ir_notebook.ipynb diff --git a/tests/notebooks/ipynb_bash/sample_bash_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_bash/sample_bash_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_bash/sample_bash_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_bash/sample_bash_notebook.ipynb diff --git a/tests/notebooks/ipynb_clojure/html-demo.ipynb b/tests/data/notebooks/inputs/ipynb_clojure/html-demo.ipynb similarity index 100% rename from tests/notebooks/ipynb_clojure/html-demo.ipynb rename to tests/data/notebooks/inputs/ipynb_clojure/html-demo.ipynb diff --git a/tests/notebooks/ipynb_coconut/coconut_homepage_demo.ipynb b/tests/data/notebooks/inputs/ipynb_coconut/coconut_homepage_demo.ipynb similarity index 100% rename from tests/notebooks/ipynb_coconut/coconut_homepage_demo.ipynb rename to tests/data/notebooks/inputs/ipynb_coconut/coconut_homepage_demo.ipynb diff --git a/tests/notebooks/ipynb_cpp/xcpp_by_quantstack.ipynb b/tests/data/notebooks/inputs/ipynb_cpp/xcpp_by_quantstack.ipynb similarity index 100% rename from tests/notebooks/ipynb_cpp/xcpp_by_quantstack.ipynb rename to tests/data/notebooks/inputs/ipynb_cpp/xcpp_by_quantstack.ipynb diff --git a/tests/notebooks/ipynb_cs/csharp.ipynb b/tests/data/notebooks/inputs/ipynb_cs/csharp.ipynb similarity index 100% rename from tests/notebooks/ipynb_cs/csharp.ipynb rename to tests/data/notebooks/inputs/ipynb_cs/csharp.ipynb diff --git a/tests/notebooks/ipynb_fs/fsharp.ipynb b/tests/data/notebooks/inputs/ipynb_fs/fsharp.ipynb similarity index 100% rename from tests/notebooks/ipynb_fs/fsharp.ipynb rename to tests/data/notebooks/inputs/ipynb_fs/fsharp.ipynb diff --git a/tests/notebooks/ipynb_gnuplot/gnuplot_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_gnuplot/gnuplot_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_gnuplot/gnuplot_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_gnuplot/gnuplot_notebook.ipynb diff --git a/tests/notebooks/ipynb_groovy/tailrecursive-factorial.ipynb b/tests/data/notebooks/inputs/ipynb_groovy/tailrecursive-factorial.ipynb similarity index 100% rename from tests/notebooks/ipynb_groovy/tailrecursive-factorial.ipynb rename to tests/data/notebooks/inputs/ipynb_groovy/tailrecursive-factorial.ipynb diff --git a/tests/notebooks/ipynb_haskell/haskell_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_haskell/haskell_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_haskell/haskell_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_haskell/haskell_notebook.ipynb diff --git a/tests/notebooks/ipynb_idl/demo_gdl_fbp.ipynb b/tests/data/notebooks/inputs/ipynb_idl/demo_gdl_fbp.ipynb similarity index 100% rename from tests/notebooks/ipynb_idl/demo_gdl_fbp.ipynb rename to tests/data/notebooks/inputs/ipynb_idl/demo_gdl_fbp.ipynb diff --git a/tests/notebooks/ipynb_java/simple-helloworld.ipynb b/tests/data/notebooks/inputs/ipynb_java/simple-helloworld.ipynb similarity index 100% rename from tests/notebooks/ipynb_java/simple-helloworld.ipynb rename to tests/data/notebooks/inputs/ipynb_java/simple-helloworld.ipynb diff --git a/tests/notebooks/ipynb_js/ijavascript.ipynb b/tests/data/notebooks/inputs/ipynb_js/ijavascript.ipynb similarity index 100% rename from tests/notebooks/ipynb_js/ijavascript.ipynb rename to tests/data/notebooks/inputs/ipynb_js/ijavascript.ipynb diff --git a/tests/notebooks/ipynb_julia/julia_benchmark_plotly_barchart.ipynb b/tests/data/notebooks/inputs/ipynb_julia/julia_benchmark_plotly_barchart.ipynb similarity index 100% rename from tests/notebooks/ipynb_julia/julia_benchmark_plotly_barchart.ipynb rename to tests/data/notebooks/inputs/ipynb_julia/julia_benchmark_plotly_barchart.ipynb diff --git a/tests/notebooks/ipynb_julia/julia_functional_geometry.ipynb b/tests/data/notebooks/inputs/ipynb_julia/julia_functional_geometry.ipynb similarity index 100% rename from tests/notebooks/ipynb_julia/julia_functional_geometry.ipynb rename to tests/data/notebooks/inputs/ipynb_julia/julia_functional_geometry.ipynb diff --git a/tests/notebooks/ipynb_m/octave_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_m/octave_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_m/octave_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_m/octave_notebook.ipynb diff --git a/tests/notebooks/ipynb_maxima/maxima_example.ipynb b/tests/data/notebooks/inputs/ipynb_maxima/maxima_example.ipynb similarity index 100% rename from tests/notebooks/ipynb_maxima/maxima_example.ipynb rename to tests/data/notebooks/inputs/ipynb_maxima/maxima_example.ipynb diff --git a/tests/notebooks/ipynb_ocaml/ocaml_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_ocaml/ocaml_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_ocaml/ocaml_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_ocaml/ocaml_notebook.ipynb diff --git a/tests/notebooks/ipynb_ps1/powershell.ipynb b/tests/data/notebooks/inputs/ipynb_ps1/powershell.ipynb similarity index 100% rename from tests/notebooks/ipynb_ps1/powershell.ipynb rename to tests/data/notebooks/inputs/ipynb_ps1/powershell.ipynb diff --git a/tests/notebooks/ipynb_py/Line_breaks_in_LateX_305.ipynb b/tests/data/notebooks/inputs/ipynb_py/Line_breaks_in_LateX_305.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Line_breaks_in_LateX_305.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Line_breaks_in_LateX_305.ipynb diff --git a/tests/notebooks/ipynb_py/Notebook with function and cell metadata 164.ipynb b/tests/data/notebooks/inputs/ipynb_py/Notebook with function and cell metadata 164.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Notebook with function and cell metadata 164.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Notebook with function and cell metadata 164.ipynb diff --git a/tests/notebooks/ipynb_py/Notebook with html and latex cells.ipynb b/tests/data/notebooks/inputs/ipynb_py/Notebook with html and latex cells.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Notebook with html and latex cells.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Notebook with html and latex cells.ipynb diff --git a/tests/notebooks/ipynb_py/Notebook with many hash signs.ipynb b/tests/data/notebooks/inputs/ipynb_py/Notebook with many hash signs.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Notebook with many hash signs.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Notebook with many hash signs.ipynb diff --git a/tests/notebooks/ipynb_py/Notebook with metadata and long cells.ipynb b/tests/data/notebooks/inputs/ipynb_py/Notebook with metadata and long cells.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Notebook with metadata and long cells.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Notebook with metadata and long cells.ipynb diff --git a/tests/notebooks/ipynb_py/Notebook_with_R_magic.ipynb b/tests/data/notebooks/inputs/ipynb_py/Notebook_with_R_magic.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Notebook_with_R_magic.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Notebook_with_R_magic.ipynb diff --git a/tests/notebooks/ipynb_py/Notebook_with_more_R_magic_111.ipynb b/tests/data/notebooks/inputs/ipynb_py/Notebook_with_more_R_magic_111.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/Notebook_with_more_R_magic_111.ipynb rename to tests/data/notebooks/inputs/ipynb_py/Notebook_with_more_R_magic_111.ipynb diff --git a/tests/notebooks/ipynb_py/The flavors of raw cells.ipynb b/tests/data/notebooks/inputs/ipynb_py/The flavors of raw cells.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/The flavors of raw cells.ipynb rename to tests/data/notebooks/inputs/ipynb_py/The flavors of raw cells.ipynb diff --git a/tests/notebooks/ipynb_py/cat_variable.ipynb b/tests/data/notebooks/inputs/ipynb_py/cat_variable.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/cat_variable.ipynb rename to tests/data/notebooks/inputs/ipynb_py/cat_variable.ipynb diff --git a/tests/notebooks/ipynb_py/convert_to_py_then_test_with_update83.ipynb b/tests/data/notebooks/inputs/ipynb_py/convert_to_py_then_test_with_update83.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/convert_to_py_then_test_with_update83.ipynb rename to tests/data/notebooks/inputs/ipynb_py/convert_to_py_then_test_with_update83.ipynb diff --git a/tests/notebooks/ipynb_py/frozen_cell.ipynb b/tests/data/notebooks/inputs/ipynb_py/frozen_cell.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/frozen_cell.ipynb rename to tests/data/notebooks/inputs/ipynb_py/frozen_cell.ipynb diff --git a/tests/notebooks/ipynb_py/jupyter.ipynb b/tests/data/notebooks/inputs/ipynb_py/jupyter.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/jupyter.ipynb rename to tests/data/notebooks/inputs/ipynb_py/jupyter.ipynb diff --git a/tests/notebooks/ipynb_py/jupyter_again.ipynb b/tests/data/notebooks/inputs/ipynb_py/jupyter_again.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/jupyter_again.ipynb rename to tests/data/notebooks/inputs/ipynb_py/jupyter_again.ipynb diff --git a/tests/notebooks/ipynb_py/jupyter_with_raw_cell_in_body.ipynb b/tests/data/notebooks/inputs/ipynb_py/jupyter_with_raw_cell_in_body.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/jupyter_with_raw_cell_in_body.ipynb rename to tests/data/notebooks/inputs/ipynb_py/jupyter_with_raw_cell_in_body.ipynb diff --git a/tests/notebooks/ipynb_py/jupyter_with_raw_cell_on_top.ipynb b/tests/data/notebooks/inputs/ipynb_py/jupyter_with_raw_cell_on_top.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/jupyter_with_raw_cell_on_top.ipynb rename to tests/data/notebooks/inputs/ipynb_py/jupyter_with_raw_cell_on_top.ipynb diff --git a/tests/notebooks/ipynb_py/notebook_with_complex_metadata.ipynb b/tests/data/notebooks/inputs/ipynb_py/notebook_with_complex_metadata.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/notebook_with_complex_metadata.ipynb rename to tests/data/notebooks/inputs/ipynb_py/notebook_with_complex_metadata.ipynb diff --git a/tests/notebooks/ipynb_py/nteract_with_parameter.ipynb b/tests/data/notebooks/inputs/ipynb_py/nteract_with_parameter.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/nteract_with_parameter.ipynb rename to tests/data/notebooks/inputs/ipynb_py/nteract_with_parameter.ipynb diff --git a/tests/notebooks/ipynb_py/plotly_graphs.ipynb b/tests/data/notebooks/inputs/ipynb_py/plotly_graphs.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/plotly_graphs.ipynb rename to tests/data/notebooks/inputs/ipynb_py/plotly_graphs.ipynb diff --git a/tests/notebooks/ipynb_py/sample_rise_notebook_66.ipynb b/tests/data/notebooks/inputs/ipynb_py/sample_rise_notebook_66.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/sample_rise_notebook_66.ipynb rename to tests/data/notebooks/inputs/ipynb_py/sample_rise_notebook_66.ipynb diff --git a/tests/notebooks/ipynb_py/text_outputs_and_images.ipynb b/tests/data/notebooks/inputs/ipynb_py/text_outputs_and_images.ipynb similarity index 100% rename from tests/notebooks/ipynb_py/text_outputs_and_images.ipynb rename to tests/data/notebooks/inputs/ipynb_py/text_outputs_and_images.ipynb diff --git a/tests/notebooks/ipynb_q/kalman_filter_and_visualization.ipynb b/tests/data/notebooks/inputs/ipynb_q/kalman_filter_and_visualization.ipynb similarity index 100% rename from tests/notebooks/ipynb_q/kalman_filter_and_visualization.ipynb rename to tests/data/notebooks/inputs/ipynb_q/kalman_filter_and_visualization.ipynb diff --git a/tests/notebooks/ipynb_robot/simple_robot_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_robot/simple_robot_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_robot/simple_robot_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_robot/simple_robot_notebook.ipynb diff --git a/tests/notebooks/ipynb_rust/evcxr_jupyter_tour.ipynb b/tests/data/notebooks/inputs/ipynb_rust/evcxr_jupyter_tour.ipynb similarity index 100% rename from tests/notebooks/ipynb_rust/evcxr_jupyter_tour.ipynb rename to tests/data/notebooks/inputs/ipynb_rust/evcxr_jupyter_tour.ipynb diff --git a/tests/notebooks/ipynb_sage/sage_print_hello.ipynb b/tests/data/notebooks/inputs/ipynb_sage/sage_print_hello.ipynb similarity index 100% rename from tests/notebooks/ipynb_sage/sage_print_hello.ipynb rename to tests/data/notebooks/inputs/ipynb_sage/sage_print_hello.ipynb diff --git a/tests/notebooks/ipynb_sas/sas.ipynb b/tests/data/notebooks/inputs/ipynb_sas/sas.ipynb similarity index 100% rename from tests/notebooks/ipynb_sas/sas.ipynb rename to tests/data/notebooks/inputs/ipynb_sas/sas.ipynb diff --git a/tests/notebooks/ipynb_scala/simple_scala_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_scala/simple_scala_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_scala/simple_scala_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_scala/simple_scala_notebook.ipynb diff --git a/tests/notebooks/ipynb_scheme/Reference Guide for Calysto Scheme.ipynb b/tests/data/notebooks/inputs/ipynb_scheme/Reference Guide for Calysto Scheme.ipynb similarity index 100% rename from tests/notebooks/ipynb_scheme/Reference Guide for Calysto Scheme.ipynb rename to tests/data/notebooks/inputs/ipynb_scheme/Reference Guide for Calysto Scheme.ipynb diff --git a/tests/notebooks/ipynb_sos/jupytext_replication.ipynb b/tests/data/notebooks/inputs/ipynb_sos/jupytext_replication.ipynb similarity index 100% rename from tests/notebooks/ipynb_sos/jupytext_replication.ipynb rename to tests/data/notebooks/inputs/ipynb_sos/jupytext_replication.ipynb diff --git a/tests/notebooks/ipynb_stata/stata_notebook.ipynb b/tests/data/notebooks/inputs/ipynb_stata/stata_notebook.ipynb similarity index 100% rename from tests/notebooks/ipynb_stata/stata_notebook.ipynb rename to tests/data/notebooks/inputs/ipynb_stata/stata_notebook.ipynb diff --git a/tests/notebooks/ipynb_tcl/tcl_test.ipynb b/tests/data/notebooks/inputs/ipynb_tcl/tcl_test.ipynb similarity index 100% rename from tests/notebooks/ipynb_tcl/tcl_test.ipynb rename to tests/data/notebooks/inputs/ipynb_tcl/tcl_test.ipynb diff --git a/tests/notebooks/ipynb_ts/itypescript.ipynb b/tests/data/notebooks/inputs/ipynb_ts/itypescript.ipynb similarity index 100% rename from tests/notebooks/ipynb_ts/itypescript.ipynb rename to tests/data/notebooks/inputs/ipynb_ts/itypescript.ipynb diff --git a/tests/notebooks/ipynb_wolfram/wolfram.ipynb b/tests/data/notebooks/inputs/ipynb_wolfram/wolfram.ipynb similarity index 100% rename from tests/notebooks/ipynb_wolfram/wolfram.ipynb rename to tests/data/notebooks/inputs/ipynb_wolfram/wolfram.ipynb diff --git a/tests/notebooks/julia/julia_sample_script.jl b/tests/data/notebooks/inputs/julia/julia_sample_script.jl similarity index 100% rename from tests/notebooks/julia/julia_sample_script.jl rename to tests/data/notebooks/inputs/julia/julia_sample_script.jl diff --git a/tests/notebooks/md/jupytext_markdown.md b/tests/data/notebooks/inputs/md/jupytext_markdown.md similarity index 100% rename from tests/notebooks/md/jupytext_markdown.md rename to tests/data/notebooks/inputs/md/jupytext_markdown.md diff --git a/tests/notebooks/md/plain_markdown.md b/tests/data/notebooks/inputs/md/plain_markdown.md similarity index 100% rename from tests/notebooks/md/plain_markdown.md rename to tests/data/notebooks/inputs/md/plain_markdown.md diff --git a/tests/notebooks/percent/hydrogen.py b/tests/data/notebooks/inputs/percent/hydrogen.py similarity index 100% rename from tests/notebooks/percent/hydrogen.py rename to tests/data/notebooks/inputs/percent/hydrogen.py diff --git a/tests/notebooks/ps1/build.ps1 b/tests/data/notebooks/inputs/ps1/build.ps1 similarity index 100% rename from tests/notebooks/ps1/build.ps1 rename to tests/data/notebooks/inputs/ps1/build.ps1 diff --git a/tests/notebooks/python/light_sample.py b/tests/data/notebooks/inputs/python/light_sample.py similarity index 100% rename from tests/notebooks/python/light_sample.py rename to tests/data/notebooks/inputs/python/light_sample.py diff --git a/tests/notebooks/python/python_notebook_sample.py b/tests/data/notebooks/inputs/python/python_notebook_sample.py similarity index 100% rename from tests/notebooks/python/python_notebook_sample.py rename to tests/data/notebooks/inputs/python/python_notebook_sample.py diff --git a/tests/notebooks/sphinx/plot_notebook.py b/tests/data/notebooks/inputs/sphinx/plot_notebook.py similarity index 100% rename from tests/notebooks/sphinx/plot_notebook.py rename to tests/data/notebooks/inputs/sphinx/plot_notebook.py diff --git a/tests/notebooks/mirror/Rmd_to_ipynb/R_sample.ipynb b/tests/data/notebooks/outputs/Rmd_to_ipynb/R_sample.ipynb similarity index 100% rename from tests/notebooks/mirror/Rmd_to_ipynb/R_sample.ipynb rename to tests/data/notebooks/outputs/Rmd_to_ipynb/R_sample.ipynb diff --git a/tests/notebooks/mirror/Rmd_to_ipynb/chunk_options.ipynb b/tests/data/notebooks/outputs/Rmd_to_ipynb/chunk_options.ipynb similarity index 100% rename from tests/notebooks/mirror/Rmd_to_ipynb/chunk_options.ipynb rename to tests/data/notebooks/outputs/Rmd_to_ipynb/chunk_options.ipynb diff --git a/tests/notebooks/mirror/Rmd_to_ipynb/ioslides.ipynb b/tests/data/notebooks/outputs/Rmd_to_ipynb/ioslides.ipynb similarity index 100% rename from tests/notebooks/mirror/Rmd_to_ipynb/ioslides.ipynb rename to tests/data/notebooks/outputs/Rmd_to_ipynb/ioslides.ipynb diff --git a/tests/notebooks/mirror/Rmd_to_ipynb/knitr-spin.ipynb b/tests/data/notebooks/outputs/Rmd_to_ipynb/knitr-spin.ipynb similarity index 100% rename from tests/notebooks/mirror/Rmd_to_ipynb/knitr-spin.ipynb rename to tests/data/notebooks/outputs/Rmd_to_ipynb/knitr-spin.ipynb diff --git a/tests/notebooks/mirror/Rmd_to_ipynb/markdown.ipynb b/tests/data/notebooks/outputs/Rmd_to_ipynb/markdown.ipynb similarity index 100% rename from tests/notebooks/mirror/Rmd_to_ipynb/markdown.ipynb rename to tests/data/notebooks/outputs/Rmd_to_ipynb/markdown.ipynb diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Line_breaks_in_LateX_305.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Line_breaks_in_LateX_305.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Line_breaks_in_LateX_305.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Line_breaks_in_LateX_305.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Notebook with function and cell metadata 164.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with function and cell metadata 164.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Notebook with function and cell metadata 164.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with function and cell metadata 164.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Notebook with html and latex cells.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with html and latex cells.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Notebook with html and latex cells.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with html and latex cells.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Notebook with many hash signs.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with many hash signs.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Notebook with many hash signs.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with many hash signs.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Notebook with metadata and long cells.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with metadata and long cells.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Notebook with metadata and long cells.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook with metadata and long cells.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Notebook_with_R_magic.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook_with_R_magic.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Notebook_with_R_magic.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook_with_R_magic.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Notebook_with_more_R_magic_111.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook_with_more_R_magic_111.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Notebook_with_more_R_magic_111.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Notebook_with_more_R_magic_111.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/R notebook with invalid cell keys.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/R notebook with invalid cell keys.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/R notebook with invalid cell keys.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/R notebook with invalid cell keys.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/Reference Guide for Calysto Scheme.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/Reference Guide for Calysto Scheme.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/Reference Guide for Calysto Scheme.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/Reference Guide for Calysto Scheme.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/The flavors of raw cells.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/The flavors of raw cells.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/The flavors of raw cells.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/The flavors of raw cells.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/cat_variable.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/cat_variable.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/cat_variable.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/cat_variable.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/coconut_homepage_demo.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/coconut_homepage_demo.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/coconut_homepage_demo.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/coconut_homepage_demo.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/convert_to_py_then_test_with_update83.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/convert_to_py_then_test_with_update83.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/convert_to_py_then_test_with_update83.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/convert_to_py_then_test_with_update83.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/csharp.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/csharp.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/csharp.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/csharp.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/demo_gdl_fbp.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/demo_gdl_fbp.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/demo_gdl_fbp.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/demo_gdl_fbp.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/evcxr_jupyter_tour.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/evcxr_jupyter_tour.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/evcxr_jupyter_tour.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/evcxr_jupyter_tour.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/frozen_cell.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/frozen_cell.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/frozen_cell.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/frozen_cell.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/fsharp.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/fsharp.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/fsharp.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/fsharp.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/gnuplot_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/gnuplot_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/gnuplot_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/gnuplot_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/haskell_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/haskell_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/haskell_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/haskell_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/html-demo.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/html-demo.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/html-demo.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/html-demo.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/ijavascript.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/ijavascript.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/ijavascript.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/ijavascript.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/ir_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/ir_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/ir_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/ir_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/itypescript.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/itypescript.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/itypescript.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/itypescript.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/julia_benchmark_plotly_barchart.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/julia_benchmark_plotly_barchart.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/julia_benchmark_plotly_barchart.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/julia_benchmark_plotly_barchart.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/julia_functional_geometry.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/julia_functional_geometry.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/julia_functional_geometry.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/julia_functional_geometry.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/jupyter.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/jupyter.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/jupyter_again.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter_again.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/jupyter_again.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter_again.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/jupyter_with_raw_cell_in_body.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter_with_raw_cell_in_body.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/jupyter_with_raw_cell_in_body.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter_with_raw_cell_in_body.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/jupyter_with_raw_cell_on_top.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter_with_raw_cell_on_top.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/jupyter_with_raw_cell_on_top.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/jupyter_with_raw_cell_on_top.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/jupytext_replication.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/jupytext_replication.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/jupytext_replication.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/jupytext_replication.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/kalman_filter_and_visualization.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/kalman_filter_and_visualization.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/kalman_filter_and_visualization.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/kalman_filter_and_visualization.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/maxima_example.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/maxima_example.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/maxima_example.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/maxima_example.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/notebook_with_complex_metadata.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/notebook_with_complex_metadata.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/notebook_with_complex_metadata.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/notebook_with_complex_metadata.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/nteract_with_parameter.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/nteract_with_parameter.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/nteract_with_parameter.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/nteract_with_parameter.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/ocaml_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/ocaml_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/ocaml_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/ocaml_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/octave_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/octave_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/octave_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/octave_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/plotly_graphs.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/plotly_graphs.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/plotly_graphs.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/plotly_graphs.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/powershell.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/powershell.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/powershell.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/powershell.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/sage_print_hello.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/sage_print_hello.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/sage_print_hello.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/sage_print_hello.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/sample_bash_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/sample_bash_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/sample_bash_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/sample_bash_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/sample_rise_notebook_66.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/sample_rise_notebook_66.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/sample_rise_notebook_66.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/sample_rise_notebook_66.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/sas.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/sas.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/sas.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/sas.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/simple-helloworld.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/simple-helloworld.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/simple-helloworld.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/simple-helloworld.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/simple_robot_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/simple_robot_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/simple_robot_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/simple_robot_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/simple_scala_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/simple_scala_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/simple_scala_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/simple_scala_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/stata_notebook.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/stata_notebook.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/stata_notebook.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/stata_notebook.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/tailrecursive-factorial.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/tailrecursive-factorial.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/tailrecursive-factorial.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/tailrecursive-factorial.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/tcl_test.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/tcl_test.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/tcl_test.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/tcl_test.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/text_outputs_and_images.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/text_outputs_and_images.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/text_outputs_and_images.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/text_outputs_and_images.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/wolfram.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/wolfram.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/wolfram.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/wolfram.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_Rmd/xcpp_by_quantstack.Rmd b/tests/data/notebooks/outputs/ipynb_to_Rmd/xcpp_by_quantstack.Rmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_Rmd/xcpp_by_quantstack.Rmd rename to tests/data/notebooks/outputs/ipynb_to_Rmd/xcpp_by_quantstack.Rmd diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Line_breaks_in_LateX_305.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Line_breaks_in_LateX_305.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Line_breaks_in_LateX_305.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Line_breaks_in_LateX_305.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with function and cell metadata 164.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with function and cell metadata 164.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with function and cell metadata 164.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with function and cell metadata 164.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with html and latex cells.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with html and latex cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with html and latex cells.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with html and latex cells.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with many hash signs.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with many hash signs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with many hash signs.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with many hash signs.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with metadata and long cells.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with metadata and long cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Notebook with metadata and long cells.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook with metadata and long cells.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Notebook_with_R_magic.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook_with_R_magic.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Notebook_with_R_magic.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook_with_R_magic.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Notebook_with_more_R_magic_111.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook_with_more_R_magic_111.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Notebook_with_more_R_magic_111.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Notebook_with_more_R_magic_111.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/R notebook with invalid cell keys.R b/tests/data/notebooks/outputs/ipynb_to_hydrogen/R notebook with invalid cell keys.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/R notebook with invalid cell keys.R rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/R notebook with invalid cell keys.R diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/Reference Guide for Calysto Scheme.ss b/tests/data/notebooks/outputs/ipynb_to_hydrogen/Reference Guide for Calysto Scheme.ss similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/Reference Guide for Calysto Scheme.ss rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/Reference Guide for Calysto Scheme.ss diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/The flavors of raw cells.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/The flavors of raw cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/The flavors of raw cells.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/The flavors of raw cells.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/cat_variable.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/cat_variable.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/cat_variable.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/cat_variable.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/coconut_homepage_demo.coco b/tests/data/notebooks/outputs/ipynb_to_hydrogen/coconut_homepage_demo.coco similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/coconut_homepage_demo.coco rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/coconut_homepage_demo.coco diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/convert_to_py_then_test_with_update83.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/convert_to_py_then_test_with_update83.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/convert_to_py_then_test_with_update83.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/convert_to_py_then_test_with_update83.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/csharp.cs b/tests/data/notebooks/outputs/ipynb_to_hydrogen/csharp.cs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/csharp.cs rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/csharp.cs diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/demo_gdl_fbp.pro b/tests/data/notebooks/outputs/ipynb_to_hydrogen/demo_gdl_fbp.pro similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/demo_gdl_fbp.pro rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/demo_gdl_fbp.pro diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/evcxr_jupyter_tour.rs b/tests/data/notebooks/outputs/ipynb_to_hydrogen/evcxr_jupyter_tour.rs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/evcxr_jupyter_tour.rs rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/evcxr_jupyter_tour.rs diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/frozen_cell.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/frozen_cell.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/frozen_cell.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/frozen_cell.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/fsharp.fsx b/tests/data/notebooks/outputs/ipynb_to_hydrogen/fsharp.fsx similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/fsharp.fsx rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/fsharp.fsx diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/gnuplot_notebook.gp b/tests/data/notebooks/outputs/ipynb_to_hydrogen/gnuplot_notebook.gp similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/gnuplot_notebook.gp rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/gnuplot_notebook.gp diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/haskell_notebook.hs b/tests/data/notebooks/outputs/ipynb_to_hydrogen/haskell_notebook.hs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/haskell_notebook.hs rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/haskell_notebook.hs diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/html-demo.clj b/tests/data/notebooks/outputs/ipynb_to_hydrogen/html-demo.clj similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/html-demo.clj rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/html-demo.clj diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/ijavascript.js b/tests/data/notebooks/outputs/ipynb_to_hydrogen/ijavascript.js similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/ijavascript.js rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/ijavascript.js diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/ir_notebook.R b/tests/data/notebooks/outputs/ipynb_to_hydrogen/ir_notebook.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/ir_notebook.R rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/ir_notebook.R diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/itypescript.ts b/tests/data/notebooks/outputs/ipynb_to_hydrogen/itypescript.ts similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/itypescript.ts rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/itypescript.ts diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/julia_benchmark_plotly_barchart.jl b/tests/data/notebooks/outputs/ipynb_to_hydrogen/julia_benchmark_plotly_barchart.jl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/julia_benchmark_plotly_barchart.jl rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/julia_benchmark_plotly_barchart.jl diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/julia_functional_geometry.jl b/tests/data/notebooks/outputs/ipynb_to_hydrogen/julia_functional_geometry.jl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/julia_functional_geometry.jl rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/julia_functional_geometry.jl diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/jupyter.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/jupyter.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/jupyter_again.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter_again.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/jupyter_again.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter_again.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/jupyter_with_raw_cell_in_body.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter_with_raw_cell_in_body.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/jupyter_with_raw_cell_in_body.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter_with_raw_cell_in_body.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/jupyter_with_raw_cell_on_top.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter_with_raw_cell_on_top.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/jupyter_with_raw_cell_on_top.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/jupyter_with_raw_cell_on_top.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/jupytext_replication.sos b/tests/data/notebooks/outputs/ipynb_to_hydrogen/jupytext_replication.sos similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/jupytext_replication.sos rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/jupytext_replication.sos diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/kalman_filter_and_visualization.q b/tests/data/notebooks/outputs/ipynb_to_hydrogen/kalman_filter_and_visualization.q similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/kalman_filter_and_visualization.q rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/kalman_filter_and_visualization.q diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/maxima_example.mac b/tests/data/notebooks/outputs/ipynb_to_hydrogen/maxima_example.mac similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/maxima_example.mac rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/maxima_example.mac diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/notebook_with_complex_metadata.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/notebook_with_complex_metadata.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/notebook_with_complex_metadata.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/notebook_with_complex_metadata.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/nteract_with_parameter.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/nteract_with_parameter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/nteract_with_parameter.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/nteract_with_parameter.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/ocaml_notebook.ml b/tests/data/notebooks/outputs/ipynb_to_hydrogen/ocaml_notebook.ml similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/ocaml_notebook.ml rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/ocaml_notebook.ml diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/octave_notebook.m b/tests/data/notebooks/outputs/ipynb_to_hydrogen/octave_notebook.m similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/octave_notebook.m rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/octave_notebook.m diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/plotly_graphs.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/plotly_graphs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/plotly_graphs.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/plotly_graphs.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/powershell.ps1 b/tests/data/notebooks/outputs/ipynb_to_hydrogen/powershell.ps1 similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/powershell.ps1 rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/powershell.ps1 diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/sage_print_hello.sage b/tests/data/notebooks/outputs/ipynb_to_hydrogen/sage_print_hello.sage similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/sage_print_hello.sage rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/sage_print_hello.sage diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/sample_bash_notebook.sh b/tests/data/notebooks/outputs/ipynb_to_hydrogen/sample_bash_notebook.sh similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/sample_bash_notebook.sh rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/sample_bash_notebook.sh diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/sample_rise_notebook_66.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/sample_rise_notebook_66.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/sample_rise_notebook_66.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/sample_rise_notebook_66.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/sas.sas b/tests/data/notebooks/outputs/ipynb_to_hydrogen/sas.sas similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/sas.sas rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/sas.sas diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/simple-helloworld.java b/tests/data/notebooks/outputs/ipynb_to_hydrogen/simple-helloworld.java similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/simple-helloworld.java rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/simple-helloworld.java diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/simple_robot_notebook.robot b/tests/data/notebooks/outputs/ipynb_to_hydrogen/simple_robot_notebook.robot similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/simple_robot_notebook.robot rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/simple_robot_notebook.robot diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/simple_scala_notebook.scala b/tests/data/notebooks/outputs/ipynb_to_hydrogen/simple_scala_notebook.scala similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/simple_scala_notebook.scala rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/simple_scala_notebook.scala diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/stata_notebook.do b/tests/data/notebooks/outputs/ipynb_to_hydrogen/stata_notebook.do similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/stata_notebook.do rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/stata_notebook.do diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/tailrecursive-factorial.groovy b/tests/data/notebooks/outputs/ipynb_to_hydrogen/tailrecursive-factorial.groovy similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/tailrecursive-factorial.groovy rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/tailrecursive-factorial.groovy diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/tcl_test.tcl b/tests/data/notebooks/outputs/ipynb_to_hydrogen/tcl_test.tcl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/tcl_test.tcl rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/tcl_test.tcl diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/text_outputs_and_images.py b/tests/data/notebooks/outputs/ipynb_to_hydrogen/text_outputs_and_images.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/text_outputs_and_images.py rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/text_outputs_and_images.py diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/wolfram.wolfram b/tests/data/notebooks/outputs/ipynb_to_hydrogen/wolfram.wolfram similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/wolfram.wolfram rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/wolfram.wolfram diff --git a/tests/notebooks/mirror/ipynb_to_hydrogen/xcpp_by_quantstack.cpp b/tests/data/notebooks/outputs/ipynb_to_hydrogen/xcpp_by_quantstack.cpp similarity index 100% rename from tests/notebooks/mirror/ipynb_to_hydrogen/xcpp_by_quantstack.cpp rename to tests/data/notebooks/outputs/ipynb_to_hydrogen/xcpp_by_quantstack.cpp diff --git a/tests/notebooks/mirror/ipynb_to_md/Line_breaks_in_LateX_305.md b/tests/data/notebooks/outputs/ipynb_to_md/Line_breaks_in_LateX_305.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Line_breaks_in_LateX_305.md rename to tests/data/notebooks/outputs/ipynb_to_md/Line_breaks_in_LateX_305.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Notebook with function and cell metadata 164.md b/tests/data/notebooks/outputs/ipynb_to_md/Notebook with function and cell metadata 164.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Notebook with function and cell metadata 164.md rename to tests/data/notebooks/outputs/ipynb_to_md/Notebook with function and cell metadata 164.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Notebook with html and latex cells.md b/tests/data/notebooks/outputs/ipynb_to_md/Notebook with html and latex cells.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Notebook with html and latex cells.md rename to tests/data/notebooks/outputs/ipynb_to_md/Notebook with html and latex cells.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Notebook with many hash signs.md b/tests/data/notebooks/outputs/ipynb_to_md/Notebook with many hash signs.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Notebook with many hash signs.md rename to tests/data/notebooks/outputs/ipynb_to_md/Notebook with many hash signs.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Notebook with metadata and long cells.md b/tests/data/notebooks/outputs/ipynb_to_md/Notebook with metadata and long cells.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Notebook with metadata and long cells.md rename to tests/data/notebooks/outputs/ipynb_to_md/Notebook with metadata and long cells.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Notebook_with_R_magic.md b/tests/data/notebooks/outputs/ipynb_to_md/Notebook_with_R_magic.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Notebook_with_R_magic.md rename to tests/data/notebooks/outputs/ipynb_to_md/Notebook_with_R_magic.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Notebook_with_more_R_magic_111.md b/tests/data/notebooks/outputs/ipynb_to_md/Notebook_with_more_R_magic_111.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Notebook_with_more_R_magic_111.md rename to tests/data/notebooks/outputs/ipynb_to_md/Notebook_with_more_R_magic_111.md diff --git a/tests/notebooks/mirror/ipynb_to_md/R notebook with invalid cell keys.md b/tests/data/notebooks/outputs/ipynb_to_md/R notebook with invalid cell keys.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/R notebook with invalid cell keys.md rename to tests/data/notebooks/outputs/ipynb_to_md/R notebook with invalid cell keys.md diff --git a/tests/notebooks/mirror/ipynb_to_md/Reference Guide for Calysto Scheme.md b/tests/data/notebooks/outputs/ipynb_to_md/Reference Guide for Calysto Scheme.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/Reference Guide for Calysto Scheme.md rename to tests/data/notebooks/outputs/ipynb_to_md/Reference Guide for Calysto Scheme.md diff --git a/tests/notebooks/mirror/ipynb_to_md/The flavors of raw cells.md b/tests/data/notebooks/outputs/ipynb_to_md/The flavors of raw cells.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/The flavors of raw cells.md rename to tests/data/notebooks/outputs/ipynb_to_md/The flavors of raw cells.md diff --git a/tests/notebooks/mirror/ipynb_to_md/cat_variable.md b/tests/data/notebooks/outputs/ipynb_to_md/cat_variable.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/cat_variable.md rename to tests/data/notebooks/outputs/ipynb_to_md/cat_variable.md diff --git a/tests/notebooks/mirror/ipynb_to_md/coconut_homepage_demo.md b/tests/data/notebooks/outputs/ipynb_to_md/coconut_homepage_demo.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/coconut_homepage_demo.md rename to tests/data/notebooks/outputs/ipynb_to_md/coconut_homepage_demo.md diff --git a/tests/notebooks/mirror/ipynb_to_md/convert_to_py_then_test_with_update83.md b/tests/data/notebooks/outputs/ipynb_to_md/convert_to_py_then_test_with_update83.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/convert_to_py_then_test_with_update83.md rename to tests/data/notebooks/outputs/ipynb_to_md/convert_to_py_then_test_with_update83.md diff --git a/tests/notebooks/mirror/ipynb_to_md/csharp.md b/tests/data/notebooks/outputs/ipynb_to_md/csharp.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/csharp.md rename to tests/data/notebooks/outputs/ipynb_to_md/csharp.md diff --git a/tests/notebooks/mirror/ipynb_to_md/demo_gdl_fbp.md b/tests/data/notebooks/outputs/ipynb_to_md/demo_gdl_fbp.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/demo_gdl_fbp.md rename to tests/data/notebooks/outputs/ipynb_to_md/demo_gdl_fbp.md diff --git a/tests/notebooks/mirror/ipynb_to_md/evcxr_jupyter_tour.md b/tests/data/notebooks/outputs/ipynb_to_md/evcxr_jupyter_tour.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/evcxr_jupyter_tour.md rename to tests/data/notebooks/outputs/ipynb_to_md/evcxr_jupyter_tour.md diff --git a/tests/notebooks/mirror/ipynb_to_md/frozen_cell.md b/tests/data/notebooks/outputs/ipynb_to_md/frozen_cell.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/frozen_cell.md rename to tests/data/notebooks/outputs/ipynb_to_md/frozen_cell.md diff --git a/tests/notebooks/mirror/ipynb_to_md/fsharp.md b/tests/data/notebooks/outputs/ipynb_to_md/fsharp.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/fsharp.md rename to tests/data/notebooks/outputs/ipynb_to_md/fsharp.md diff --git a/tests/notebooks/mirror/ipynb_to_md/gnuplot_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/gnuplot_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/gnuplot_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/gnuplot_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/haskell_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/haskell_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/haskell_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/haskell_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/html-demo.md b/tests/data/notebooks/outputs/ipynb_to_md/html-demo.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/html-demo.md rename to tests/data/notebooks/outputs/ipynb_to_md/html-demo.md diff --git a/tests/notebooks/mirror/ipynb_to_md/ijavascript.md b/tests/data/notebooks/outputs/ipynb_to_md/ijavascript.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/ijavascript.md rename to tests/data/notebooks/outputs/ipynb_to_md/ijavascript.md diff --git a/tests/notebooks/mirror/ipynb_to_md/ir_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/ir_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/ir_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/ir_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/itypescript.md b/tests/data/notebooks/outputs/ipynb_to_md/itypescript.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/itypescript.md rename to tests/data/notebooks/outputs/ipynb_to_md/itypescript.md diff --git a/tests/notebooks/mirror/ipynb_to_md/julia_benchmark_plotly_barchart.md b/tests/data/notebooks/outputs/ipynb_to_md/julia_benchmark_plotly_barchart.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/julia_benchmark_plotly_barchart.md rename to tests/data/notebooks/outputs/ipynb_to_md/julia_benchmark_plotly_barchart.md diff --git a/tests/notebooks/mirror/ipynb_to_md/julia_functional_geometry.md b/tests/data/notebooks/outputs/ipynb_to_md/julia_functional_geometry.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/julia_functional_geometry.md rename to tests/data/notebooks/outputs/ipynb_to_md/julia_functional_geometry.md diff --git a/tests/notebooks/mirror/ipynb_to_md/jupyter.md b/tests/data/notebooks/outputs/ipynb_to_md/jupyter.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/jupyter.md rename to tests/data/notebooks/outputs/ipynb_to_md/jupyter.md diff --git a/tests/notebooks/mirror/ipynb_to_md/jupyter_again.md b/tests/data/notebooks/outputs/ipynb_to_md/jupyter_again.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/jupyter_again.md rename to tests/data/notebooks/outputs/ipynb_to_md/jupyter_again.md diff --git a/tests/notebooks/mirror/ipynb_to_md/jupyter_with_raw_cell_in_body.md b/tests/data/notebooks/outputs/ipynb_to_md/jupyter_with_raw_cell_in_body.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/jupyter_with_raw_cell_in_body.md rename to tests/data/notebooks/outputs/ipynb_to_md/jupyter_with_raw_cell_in_body.md diff --git a/tests/notebooks/mirror/ipynb_to_md/jupyter_with_raw_cell_on_top.md b/tests/data/notebooks/outputs/ipynb_to_md/jupyter_with_raw_cell_on_top.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/jupyter_with_raw_cell_on_top.md rename to tests/data/notebooks/outputs/ipynb_to_md/jupyter_with_raw_cell_on_top.md diff --git a/tests/notebooks/mirror/ipynb_to_md/jupytext_replication.md b/tests/data/notebooks/outputs/ipynb_to_md/jupytext_replication.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/jupytext_replication.md rename to tests/data/notebooks/outputs/ipynb_to_md/jupytext_replication.md diff --git a/tests/notebooks/mirror/ipynb_to_md/kalman_filter_and_visualization.md b/tests/data/notebooks/outputs/ipynb_to_md/kalman_filter_and_visualization.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/kalman_filter_and_visualization.md rename to tests/data/notebooks/outputs/ipynb_to_md/kalman_filter_and_visualization.md diff --git a/tests/notebooks/mirror/ipynb_to_md/maxima_example.md b/tests/data/notebooks/outputs/ipynb_to_md/maxima_example.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/maxima_example.md rename to tests/data/notebooks/outputs/ipynb_to_md/maxima_example.md diff --git a/tests/notebooks/mirror/ipynb_to_md/notebook_with_complex_metadata.md b/tests/data/notebooks/outputs/ipynb_to_md/notebook_with_complex_metadata.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/notebook_with_complex_metadata.md rename to tests/data/notebooks/outputs/ipynb_to_md/notebook_with_complex_metadata.md diff --git a/tests/notebooks/mirror/ipynb_to_md/nteract_with_parameter.md b/tests/data/notebooks/outputs/ipynb_to_md/nteract_with_parameter.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/nteract_with_parameter.md rename to tests/data/notebooks/outputs/ipynb_to_md/nteract_with_parameter.md diff --git a/tests/notebooks/mirror/ipynb_to_md/ocaml_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/ocaml_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/ocaml_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/ocaml_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/octave_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/octave_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/octave_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/octave_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/plotly_graphs.md b/tests/data/notebooks/outputs/ipynb_to_md/plotly_graphs.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/plotly_graphs.md rename to tests/data/notebooks/outputs/ipynb_to_md/plotly_graphs.md diff --git a/tests/notebooks/mirror/ipynb_to_md/powershell.md b/tests/data/notebooks/outputs/ipynb_to_md/powershell.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/powershell.md rename to tests/data/notebooks/outputs/ipynb_to_md/powershell.md diff --git a/tests/notebooks/mirror/ipynb_to_md/sage_print_hello.md b/tests/data/notebooks/outputs/ipynb_to_md/sage_print_hello.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/sage_print_hello.md rename to tests/data/notebooks/outputs/ipynb_to_md/sage_print_hello.md diff --git a/tests/notebooks/mirror/ipynb_to_md/sample_bash_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/sample_bash_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/sample_bash_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/sample_bash_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/sample_rise_notebook_66.md b/tests/data/notebooks/outputs/ipynb_to_md/sample_rise_notebook_66.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/sample_rise_notebook_66.md rename to tests/data/notebooks/outputs/ipynb_to_md/sample_rise_notebook_66.md diff --git a/tests/notebooks/mirror/ipynb_to_md/sas.md b/tests/data/notebooks/outputs/ipynb_to_md/sas.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/sas.md rename to tests/data/notebooks/outputs/ipynb_to_md/sas.md diff --git a/tests/notebooks/mirror/ipynb_to_md/simple-helloworld.md b/tests/data/notebooks/outputs/ipynb_to_md/simple-helloworld.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/simple-helloworld.md rename to tests/data/notebooks/outputs/ipynb_to_md/simple-helloworld.md diff --git a/tests/notebooks/mirror/ipynb_to_md/simple_robot_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/simple_robot_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/simple_robot_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/simple_robot_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/simple_scala_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/simple_scala_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/simple_scala_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/simple_scala_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/stata_notebook.md b/tests/data/notebooks/outputs/ipynb_to_md/stata_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/stata_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_md/stata_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_md/tailrecursive-factorial.md b/tests/data/notebooks/outputs/ipynb_to_md/tailrecursive-factorial.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/tailrecursive-factorial.md rename to tests/data/notebooks/outputs/ipynb_to_md/tailrecursive-factorial.md diff --git a/tests/notebooks/mirror/ipynb_to_md/tcl_test.md b/tests/data/notebooks/outputs/ipynb_to_md/tcl_test.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/tcl_test.md rename to tests/data/notebooks/outputs/ipynb_to_md/tcl_test.md diff --git a/tests/notebooks/mirror/ipynb_to_md/text_outputs_and_images.md b/tests/data/notebooks/outputs/ipynb_to_md/text_outputs_and_images.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/text_outputs_and_images.md rename to tests/data/notebooks/outputs/ipynb_to_md/text_outputs_and_images.md diff --git a/tests/notebooks/mirror/ipynb_to_md/wolfram.md b/tests/data/notebooks/outputs/ipynb_to_md/wolfram.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/wolfram.md rename to tests/data/notebooks/outputs/ipynb_to_md/wolfram.md diff --git a/tests/notebooks/mirror/ipynb_to_md/xcpp_by_quantstack.md b/tests/data/notebooks/outputs/ipynb_to_md/xcpp_by_quantstack.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_md/xcpp_by_quantstack.md rename to tests/data/notebooks/outputs/ipynb_to_md/xcpp_by_quantstack.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Line_breaks_in_LateX_305.md b/tests/data/notebooks/outputs/ipynb_to_myst/Line_breaks_in_LateX_305.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Line_breaks_in_LateX_305.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Line_breaks_in_LateX_305.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Notebook with function and cell metadata 164.md b/tests/data/notebooks/outputs/ipynb_to_myst/Notebook with function and cell metadata 164.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Notebook with function and cell metadata 164.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Notebook with function and cell metadata 164.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Notebook with html and latex cells.md b/tests/data/notebooks/outputs/ipynb_to_myst/Notebook with html and latex cells.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Notebook with html and latex cells.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Notebook with html and latex cells.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Notebook with many hash signs.md b/tests/data/notebooks/outputs/ipynb_to_myst/Notebook with many hash signs.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Notebook with many hash signs.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Notebook with many hash signs.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Notebook with metadata and long cells.md b/tests/data/notebooks/outputs/ipynb_to_myst/Notebook with metadata and long cells.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Notebook with metadata and long cells.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Notebook with metadata and long cells.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Notebook_with_R_magic.md b/tests/data/notebooks/outputs/ipynb_to_myst/Notebook_with_R_magic.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Notebook_with_R_magic.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Notebook_with_R_magic.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Notebook_with_more_R_magic_111.md b/tests/data/notebooks/outputs/ipynb_to_myst/Notebook_with_more_R_magic_111.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Notebook_with_more_R_magic_111.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Notebook_with_more_R_magic_111.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/R notebook with invalid cell keys.md b/tests/data/notebooks/outputs/ipynb_to_myst/R notebook with invalid cell keys.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/R notebook with invalid cell keys.md rename to tests/data/notebooks/outputs/ipynb_to_myst/R notebook with invalid cell keys.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/Reference Guide for Calysto Scheme.md b/tests/data/notebooks/outputs/ipynb_to_myst/Reference Guide for Calysto Scheme.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/Reference Guide for Calysto Scheme.md rename to tests/data/notebooks/outputs/ipynb_to_myst/Reference Guide for Calysto Scheme.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/The flavors of raw cells.md b/tests/data/notebooks/outputs/ipynb_to_myst/The flavors of raw cells.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/The flavors of raw cells.md rename to tests/data/notebooks/outputs/ipynb_to_myst/The flavors of raw cells.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/cat_variable.md b/tests/data/notebooks/outputs/ipynb_to_myst/cat_variable.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/cat_variable.md rename to tests/data/notebooks/outputs/ipynb_to_myst/cat_variable.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/coconut_homepage_demo.md b/tests/data/notebooks/outputs/ipynb_to_myst/coconut_homepage_demo.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/coconut_homepage_demo.md rename to tests/data/notebooks/outputs/ipynb_to_myst/coconut_homepage_demo.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/convert_to_py_then_test_with_update83.md b/tests/data/notebooks/outputs/ipynb_to_myst/convert_to_py_then_test_with_update83.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/convert_to_py_then_test_with_update83.md rename to tests/data/notebooks/outputs/ipynb_to_myst/convert_to_py_then_test_with_update83.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/csharp.md b/tests/data/notebooks/outputs/ipynb_to_myst/csharp.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/csharp.md rename to tests/data/notebooks/outputs/ipynb_to_myst/csharp.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/demo_gdl_fbp.md b/tests/data/notebooks/outputs/ipynb_to_myst/demo_gdl_fbp.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/demo_gdl_fbp.md rename to tests/data/notebooks/outputs/ipynb_to_myst/demo_gdl_fbp.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/evcxr_jupyter_tour.md b/tests/data/notebooks/outputs/ipynb_to_myst/evcxr_jupyter_tour.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/evcxr_jupyter_tour.md rename to tests/data/notebooks/outputs/ipynb_to_myst/evcxr_jupyter_tour.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/frozen_cell.md b/tests/data/notebooks/outputs/ipynb_to_myst/frozen_cell.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/frozen_cell.md rename to tests/data/notebooks/outputs/ipynb_to_myst/frozen_cell.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/fsharp.md b/tests/data/notebooks/outputs/ipynb_to_myst/fsharp.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/fsharp.md rename to tests/data/notebooks/outputs/ipynb_to_myst/fsharp.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/gnuplot_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/gnuplot_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/gnuplot_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/gnuplot_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/haskell_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/haskell_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/haskell_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/haskell_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/ijavascript.md b/tests/data/notebooks/outputs/ipynb_to_myst/ijavascript.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/ijavascript.md rename to tests/data/notebooks/outputs/ipynb_to_myst/ijavascript.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/ir_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/ir_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/ir_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/ir_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/itypescript.md b/tests/data/notebooks/outputs/ipynb_to_myst/itypescript.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/itypescript.md rename to tests/data/notebooks/outputs/ipynb_to_myst/itypescript.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/julia_benchmark_plotly_barchart.md b/tests/data/notebooks/outputs/ipynb_to_myst/julia_benchmark_plotly_barchart.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/julia_benchmark_plotly_barchart.md rename to tests/data/notebooks/outputs/ipynb_to_myst/julia_benchmark_plotly_barchart.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/jupyter.md b/tests/data/notebooks/outputs/ipynb_to_myst/jupyter.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/jupyter.md rename to tests/data/notebooks/outputs/ipynb_to_myst/jupyter.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/jupyter_again.md b/tests/data/notebooks/outputs/ipynb_to_myst/jupyter_again.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/jupyter_again.md rename to tests/data/notebooks/outputs/ipynb_to_myst/jupyter_again.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/jupyter_with_raw_cell_in_body.md b/tests/data/notebooks/outputs/ipynb_to_myst/jupyter_with_raw_cell_in_body.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/jupyter_with_raw_cell_in_body.md rename to tests/data/notebooks/outputs/ipynb_to_myst/jupyter_with_raw_cell_in_body.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/jupyter_with_raw_cell_on_top.md b/tests/data/notebooks/outputs/ipynb_to_myst/jupyter_with_raw_cell_on_top.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/jupyter_with_raw_cell_on_top.md rename to tests/data/notebooks/outputs/ipynb_to_myst/jupyter_with_raw_cell_on_top.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/jupytext_replication.md b/tests/data/notebooks/outputs/ipynb_to_myst/jupytext_replication.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/jupytext_replication.md rename to tests/data/notebooks/outputs/ipynb_to_myst/jupytext_replication.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/kalman_filter_and_visualization.md b/tests/data/notebooks/outputs/ipynb_to_myst/kalman_filter_and_visualization.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/kalman_filter_and_visualization.md rename to tests/data/notebooks/outputs/ipynb_to_myst/kalman_filter_and_visualization.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/maxima_example.md b/tests/data/notebooks/outputs/ipynb_to_myst/maxima_example.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/maxima_example.md rename to tests/data/notebooks/outputs/ipynb_to_myst/maxima_example.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/notebook_with_complex_metadata.md b/tests/data/notebooks/outputs/ipynb_to_myst/notebook_with_complex_metadata.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/notebook_with_complex_metadata.md rename to tests/data/notebooks/outputs/ipynb_to_myst/notebook_with_complex_metadata.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/nteract_with_parameter.md b/tests/data/notebooks/outputs/ipynb_to_myst/nteract_with_parameter.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/nteract_with_parameter.md rename to tests/data/notebooks/outputs/ipynb_to_myst/nteract_with_parameter.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/ocaml_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/ocaml_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/ocaml_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/ocaml_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/octave_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/octave_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/octave_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/octave_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/plotly_graphs.md b/tests/data/notebooks/outputs/ipynb_to_myst/plotly_graphs.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/plotly_graphs.md rename to tests/data/notebooks/outputs/ipynb_to_myst/plotly_graphs.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/powershell.md b/tests/data/notebooks/outputs/ipynb_to_myst/powershell.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/powershell.md rename to tests/data/notebooks/outputs/ipynb_to_myst/powershell.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/sage_print_hello.md b/tests/data/notebooks/outputs/ipynb_to_myst/sage_print_hello.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/sage_print_hello.md rename to tests/data/notebooks/outputs/ipynb_to_myst/sage_print_hello.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/sample_bash_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/sample_bash_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/sample_bash_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/sample_bash_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/sample_rise_notebook_66.md b/tests/data/notebooks/outputs/ipynb_to_myst/sample_rise_notebook_66.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/sample_rise_notebook_66.md rename to tests/data/notebooks/outputs/ipynb_to_myst/sample_rise_notebook_66.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/sas.md b/tests/data/notebooks/outputs/ipynb_to_myst/sas.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/sas.md rename to tests/data/notebooks/outputs/ipynb_to_myst/sas.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/simple-helloworld.md b/tests/data/notebooks/outputs/ipynb_to_myst/simple-helloworld.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/simple-helloworld.md rename to tests/data/notebooks/outputs/ipynb_to_myst/simple-helloworld.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/simple_robot_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/simple_robot_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/simple_robot_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/simple_robot_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/simple_scala_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/simple_scala_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/simple_scala_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/simple_scala_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/stata_notebook.md b/tests/data/notebooks/outputs/ipynb_to_myst/stata_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/stata_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_myst/stata_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/tailrecursive-factorial.md b/tests/data/notebooks/outputs/ipynb_to_myst/tailrecursive-factorial.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/tailrecursive-factorial.md rename to tests/data/notebooks/outputs/ipynb_to_myst/tailrecursive-factorial.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/tcl_test.md b/tests/data/notebooks/outputs/ipynb_to_myst/tcl_test.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/tcl_test.md rename to tests/data/notebooks/outputs/ipynb_to_myst/tcl_test.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/text_outputs_and_images.md b/tests/data/notebooks/outputs/ipynb_to_myst/text_outputs_and_images.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/text_outputs_and_images.md rename to tests/data/notebooks/outputs/ipynb_to_myst/text_outputs_and_images.md diff --git a/tests/notebooks/mirror/ipynb_to_myst/wolfram.md b/tests/data/notebooks/outputs/ipynb_to_myst/wolfram.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_myst/wolfram.md rename to tests/data/notebooks/outputs/ipynb_to_myst/wolfram.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/Notebook_with_R_magic.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/Notebook_with_R_magic.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/Notebook_with_R_magic.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/Notebook_with_R_magic.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/Notebook_with_more_R_magic_111.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/Notebook_with_more_R_magic_111.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/Notebook_with_more_R_magic_111.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/Notebook_with_more_R_magic_111.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/cat_variable.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/cat_variable.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/cat_variable.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/cat_variable.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/convert_to_py_then_test_with_update83.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/convert_to_py_then_test_with_update83.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/convert_to_py_then_test_with_update83.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/convert_to_py_then_test_with_update83.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/frozen_cell.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/frozen_cell.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/frozen_cell.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/frozen_cell.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/ir_notebook.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/ir_notebook.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/ir_notebook.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/ir_notebook.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/julia_benchmark_plotly_barchart.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/julia_benchmark_plotly_barchart.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/julia_benchmark_plotly_barchart.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/julia_benchmark_plotly_barchart.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/jupyter.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/jupyter.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/jupyter_again.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter_again.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/jupyter_again.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter_again.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/jupyter_with_raw_cell_in_body.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter_with_raw_cell_in_body.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/jupyter_with_raw_cell_in_body.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter_with_raw_cell_in_body.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/jupyter_with_raw_cell_on_top.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter_with_raw_cell_on_top.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/jupyter_with_raw_cell_on_top.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/jupyter_with_raw_cell_on_top.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/notebook_with_complex_metadata.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/notebook_with_complex_metadata.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/notebook_with_complex_metadata.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/notebook_with_complex_metadata.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/nteract_with_parameter.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/nteract_with_parameter.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/nteract_with_parameter.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/nteract_with_parameter.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/plotly_graphs.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/plotly_graphs.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/plotly_graphs.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/plotly_graphs.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/sample_rise_notebook_66.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/sample_rise_notebook_66.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/sample_rise_notebook_66.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/sample_rise_notebook_66.md diff --git a/tests/notebooks/mirror/ipynb_to_pandoc/text_outputs_and_images.md b/tests/data/notebooks/outputs/ipynb_to_pandoc/text_outputs_and_images.md similarity index 100% rename from tests/notebooks/mirror/ipynb_to_pandoc/text_outputs_and_images.md rename to tests/data/notebooks/outputs/ipynb_to_pandoc/text_outputs_and_images.md diff --git a/tests/notebooks/mirror/ipynb_to_percent/Line_breaks_in_LateX_305.py b/tests/data/notebooks/outputs/ipynb_to_percent/Line_breaks_in_LateX_305.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Line_breaks_in_LateX_305.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Line_breaks_in_LateX_305.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/Notebook with function and cell metadata 164.py b/tests/data/notebooks/outputs/ipynb_to_percent/Notebook with function and cell metadata 164.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Notebook with function and cell metadata 164.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Notebook with function and cell metadata 164.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/Notebook with html and latex cells.py b/tests/data/notebooks/outputs/ipynb_to_percent/Notebook with html and latex cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Notebook with html and latex cells.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Notebook with html and latex cells.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/Notebook with many hash signs.py b/tests/data/notebooks/outputs/ipynb_to_percent/Notebook with many hash signs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Notebook with many hash signs.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Notebook with many hash signs.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/Notebook with metadata and long cells.py b/tests/data/notebooks/outputs/ipynb_to_percent/Notebook with metadata and long cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Notebook with metadata and long cells.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Notebook with metadata and long cells.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/Notebook_with_R_magic.py b/tests/data/notebooks/outputs/ipynb_to_percent/Notebook_with_R_magic.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Notebook_with_R_magic.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Notebook_with_R_magic.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/Notebook_with_more_R_magic_111.py b/tests/data/notebooks/outputs/ipynb_to_percent/Notebook_with_more_R_magic_111.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Notebook_with_more_R_magic_111.py rename to tests/data/notebooks/outputs/ipynb_to_percent/Notebook_with_more_R_magic_111.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/R notebook with invalid cell keys.R b/tests/data/notebooks/outputs/ipynb_to_percent/R notebook with invalid cell keys.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/R notebook with invalid cell keys.R rename to tests/data/notebooks/outputs/ipynb_to_percent/R notebook with invalid cell keys.R diff --git a/tests/notebooks/mirror/ipynb_to_percent/R notebook with invalid cell keys.low.r b/tests/data/notebooks/outputs/ipynb_to_percent/R notebook with invalid cell keys.low.r similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/R notebook with invalid cell keys.low.r rename to tests/data/notebooks/outputs/ipynb_to_percent/R notebook with invalid cell keys.low.r diff --git a/tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.scm b/tests/data/notebooks/outputs/ipynb_to_percent/Reference Guide for Calysto Scheme.scm similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.scm rename to tests/data/notebooks/outputs/ipynb_to_percent/Reference Guide for Calysto Scheme.scm diff --git a/tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.ss b/tests/data/notebooks/outputs/ipynb_to_percent/Reference Guide for Calysto Scheme.ss similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/Reference Guide for Calysto Scheme.ss rename to tests/data/notebooks/outputs/ipynb_to_percent/Reference Guide for Calysto Scheme.ss diff --git a/tests/notebooks/mirror/ipynb_to_percent/The flavors of raw cells.py b/tests/data/notebooks/outputs/ipynb_to_percent/The flavors of raw cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/The flavors of raw cells.py rename to tests/data/notebooks/outputs/ipynb_to_percent/The flavors of raw cells.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/cat_variable.py b/tests/data/notebooks/outputs/ipynb_to_percent/cat_variable.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/cat_variable.py rename to tests/data/notebooks/outputs/ipynb_to_percent/cat_variable.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/coconut_homepage_demo.coco b/tests/data/notebooks/outputs/ipynb_to_percent/coconut_homepage_demo.coco similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/coconut_homepage_demo.coco rename to tests/data/notebooks/outputs/ipynb_to_percent/coconut_homepage_demo.coco diff --git a/tests/notebooks/mirror/ipynb_to_percent/convert_to_py_then_test_with_update83.py b/tests/data/notebooks/outputs/ipynb_to_percent/convert_to_py_then_test_with_update83.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/convert_to_py_then_test_with_update83.py rename to tests/data/notebooks/outputs/ipynb_to_percent/convert_to_py_then_test_with_update83.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/csharp.cs b/tests/data/notebooks/outputs/ipynb_to_percent/csharp.cs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/csharp.cs rename to tests/data/notebooks/outputs/ipynb_to_percent/csharp.cs diff --git a/tests/notebooks/mirror/ipynb_to_percent/demo_gdl_fbp.pro b/tests/data/notebooks/outputs/ipynb_to_percent/demo_gdl_fbp.pro similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/demo_gdl_fbp.pro rename to tests/data/notebooks/outputs/ipynb_to_percent/demo_gdl_fbp.pro diff --git a/tests/notebooks/mirror/ipynb_to_percent/evcxr_jupyter_tour.rs b/tests/data/notebooks/outputs/ipynb_to_percent/evcxr_jupyter_tour.rs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/evcxr_jupyter_tour.rs rename to tests/data/notebooks/outputs/ipynb_to_percent/evcxr_jupyter_tour.rs diff --git a/tests/notebooks/mirror/ipynb_to_percent/frozen_cell.py b/tests/data/notebooks/outputs/ipynb_to_percent/frozen_cell.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/frozen_cell.py rename to tests/data/notebooks/outputs/ipynb_to_percent/frozen_cell.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/fsharp.fsx b/tests/data/notebooks/outputs/ipynb_to_percent/fsharp.fsx similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/fsharp.fsx rename to tests/data/notebooks/outputs/ipynb_to_percent/fsharp.fsx diff --git a/tests/notebooks/mirror/ipynb_to_percent/gnuplot_notebook.gp b/tests/data/notebooks/outputs/ipynb_to_percent/gnuplot_notebook.gp similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/gnuplot_notebook.gp rename to tests/data/notebooks/outputs/ipynb_to_percent/gnuplot_notebook.gp diff --git a/tests/notebooks/mirror/ipynb_to_percent/haskell_notebook.hs b/tests/data/notebooks/outputs/ipynb_to_percent/haskell_notebook.hs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/haskell_notebook.hs rename to tests/data/notebooks/outputs/ipynb_to_percent/haskell_notebook.hs diff --git a/tests/notebooks/mirror/ipynb_to_percent/html-demo.clj b/tests/data/notebooks/outputs/ipynb_to_percent/html-demo.clj similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/html-demo.clj rename to tests/data/notebooks/outputs/ipynb_to_percent/html-demo.clj diff --git a/tests/notebooks/mirror/ipynb_to_percent/ijavascript.js b/tests/data/notebooks/outputs/ipynb_to_percent/ijavascript.js similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/ijavascript.js rename to tests/data/notebooks/outputs/ipynb_to_percent/ijavascript.js diff --git a/tests/notebooks/mirror/ipynb_to_percent/ir_notebook.R b/tests/data/notebooks/outputs/ipynb_to_percent/ir_notebook.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/ir_notebook.R rename to tests/data/notebooks/outputs/ipynb_to_percent/ir_notebook.R diff --git a/tests/notebooks/mirror/ipynb_to_percent/ir_notebook.low.r b/tests/data/notebooks/outputs/ipynb_to_percent/ir_notebook.low.r similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/ir_notebook.low.r rename to tests/data/notebooks/outputs/ipynb_to_percent/ir_notebook.low.r diff --git a/tests/notebooks/mirror/ipynb_to_percent/itypescript.ts b/tests/data/notebooks/outputs/ipynb_to_percent/itypescript.ts similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/itypescript.ts rename to tests/data/notebooks/outputs/ipynb_to_percent/itypescript.ts diff --git a/tests/notebooks/mirror/ipynb_to_percent/julia_benchmark_plotly_barchart.jl b/tests/data/notebooks/outputs/ipynb_to_percent/julia_benchmark_plotly_barchart.jl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/julia_benchmark_plotly_barchart.jl rename to tests/data/notebooks/outputs/ipynb_to_percent/julia_benchmark_plotly_barchart.jl diff --git a/tests/notebooks/mirror/ipynb_to_percent/julia_functional_geometry.jl b/tests/data/notebooks/outputs/ipynb_to_percent/julia_functional_geometry.jl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/julia_functional_geometry.jl rename to tests/data/notebooks/outputs/ipynb_to_percent/julia_functional_geometry.jl diff --git a/tests/notebooks/mirror/ipynb_to_percent/jupyter.py b/tests/data/notebooks/outputs/ipynb_to_percent/jupyter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/jupyter.py rename to tests/data/notebooks/outputs/ipynb_to_percent/jupyter.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/jupyter_again.py b/tests/data/notebooks/outputs/ipynb_to_percent/jupyter_again.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/jupyter_again.py rename to tests/data/notebooks/outputs/ipynb_to_percent/jupyter_again.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/jupyter_with_raw_cell_in_body.py b/tests/data/notebooks/outputs/ipynb_to_percent/jupyter_with_raw_cell_in_body.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/jupyter_with_raw_cell_in_body.py rename to tests/data/notebooks/outputs/ipynb_to_percent/jupyter_with_raw_cell_in_body.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/jupyter_with_raw_cell_on_top.py b/tests/data/notebooks/outputs/ipynb_to_percent/jupyter_with_raw_cell_on_top.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/jupyter_with_raw_cell_on_top.py rename to tests/data/notebooks/outputs/ipynb_to_percent/jupyter_with_raw_cell_on_top.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/jupytext_replication.sos b/tests/data/notebooks/outputs/ipynb_to_percent/jupytext_replication.sos similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/jupytext_replication.sos rename to tests/data/notebooks/outputs/ipynb_to_percent/jupytext_replication.sos diff --git a/tests/notebooks/mirror/ipynb_to_percent/kalman_filter_and_visualization.q b/tests/data/notebooks/outputs/ipynb_to_percent/kalman_filter_and_visualization.q similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/kalman_filter_and_visualization.q rename to tests/data/notebooks/outputs/ipynb_to_percent/kalman_filter_and_visualization.q diff --git a/tests/notebooks/mirror/ipynb_to_percent/maxima_example.mac b/tests/data/notebooks/outputs/ipynb_to_percent/maxima_example.mac similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/maxima_example.mac rename to tests/data/notebooks/outputs/ipynb_to_percent/maxima_example.mac diff --git a/tests/notebooks/mirror/ipynb_to_percent/notebook_with_complex_metadata.py b/tests/data/notebooks/outputs/ipynb_to_percent/notebook_with_complex_metadata.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/notebook_with_complex_metadata.py rename to tests/data/notebooks/outputs/ipynb_to_percent/notebook_with_complex_metadata.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/nteract_with_parameter.py b/tests/data/notebooks/outputs/ipynb_to_percent/nteract_with_parameter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/nteract_with_parameter.py rename to tests/data/notebooks/outputs/ipynb_to_percent/nteract_with_parameter.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/ocaml_notebook.ml b/tests/data/notebooks/outputs/ipynb_to_percent/ocaml_notebook.ml similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/ocaml_notebook.ml rename to tests/data/notebooks/outputs/ipynb_to_percent/ocaml_notebook.ml diff --git a/tests/notebooks/mirror/ipynb_to_percent/octave_notebook.m b/tests/data/notebooks/outputs/ipynb_to_percent/octave_notebook.m similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/octave_notebook.m rename to tests/data/notebooks/outputs/ipynb_to_percent/octave_notebook.m diff --git a/tests/notebooks/mirror/ipynb_to_percent/plotly_graphs.py b/tests/data/notebooks/outputs/ipynb_to_percent/plotly_graphs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/plotly_graphs.py rename to tests/data/notebooks/outputs/ipynb_to_percent/plotly_graphs.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/powershell.ps1 b/tests/data/notebooks/outputs/ipynb_to_percent/powershell.ps1 similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/powershell.ps1 rename to tests/data/notebooks/outputs/ipynb_to_percent/powershell.ps1 diff --git a/tests/notebooks/mirror/ipynb_to_percent/sage_print_hello.sage b/tests/data/notebooks/outputs/ipynb_to_percent/sage_print_hello.sage similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/sage_print_hello.sage rename to tests/data/notebooks/outputs/ipynb_to_percent/sage_print_hello.sage diff --git a/tests/notebooks/mirror/ipynb_to_percent/sample_bash_notebook.sh b/tests/data/notebooks/outputs/ipynb_to_percent/sample_bash_notebook.sh similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/sample_bash_notebook.sh rename to tests/data/notebooks/outputs/ipynb_to_percent/sample_bash_notebook.sh diff --git a/tests/notebooks/mirror/ipynb_to_percent/sample_rise_notebook_66.py b/tests/data/notebooks/outputs/ipynb_to_percent/sample_rise_notebook_66.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/sample_rise_notebook_66.py rename to tests/data/notebooks/outputs/ipynb_to_percent/sample_rise_notebook_66.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/sas.sas b/tests/data/notebooks/outputs/ipynb_to_percent/sas.sas similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/sas.sas rename to tests/data/notebooks/outputs/ipynb_to_percent/sas.sas diff --git a/tests/notebooks/mirror/ipynb_to_percent/simple-helloworld.java b/tests/data/notebooks/outputs/ipynb_to_percent/simple-helloworld.java similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/simple-helloworld.java rename to tests/data/notebooks/outputs/ipynb_to_percent/simple-helloworld.java diff --git a/tests/notebooks/mirror/ipynb_to_percent/simple_robot_notebook.robot b/tests/data/notebooks/outputs/ipynb_to_percent/simple_robot_notebook.robot similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/simple_robot_notebook.robot rename to tests/data/notebooks/outputs/ipynb_to_percent/simple_robot_notebook.robot diff --git a/tests/notebooks/mirror/ipynb_to_percent/simple_scala_notebook.scala b/tests/data/notebooks/outputs/ipynb_to_percent/simple_scala_notebook.scala similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/simple_scala_notebook.scala rename to tests/data/notebooks/outputs/ipynb_to_percent/simple_scala_notebook.scala diff --git a/tests/notebooks/mirror/ipynb_to_percent/stata_notebook.do b/tests/data/notebooks/outputs/ipynb_to_percent/stata_notebook.do similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/stata_notebook.do rename to tests/data/notebooks/outputs/ipynb_to_percent/stata_notebook.do diff --git a/tests/notebooks/mirror/ipynb_to_percent/tailrecursive-factorial.groovy b/tests/data/notebooks/outputs/ipynb_to_percent/tailrecursive-factorial.groovy similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/tailrecursive-factorial.groovy rename to tests/data/notebooks/outputs/ipynb_to_percent/tailrecursive-factorial.groovy diff --git a/tests/notebooks/mirror/ipynb_to_percent/tcl_test.tcl b/tests/data/notebooks/outputs/ipynb_to_percent/tcl_test.tcl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/tcl_test.tcl rename to tests/data/notebooks/outputs/ipynb_to_percent/tcl_test.tcl diff --git a/tests/notebooks/mirror/ipynb_to_percent/text_outputs_and_images.py b/tests/data/notebooks/outputs/ipynb_to_percent/text_outputs_and_images.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/text_outputs_and_images.py rename to tests/data/notebooks/outputs/ipynb_to_percent/text_outputs_and_images.py diff --git a/tests/notebooks/mirror/ipynb_to_percent/wolfram.wolfram b/tests/data/notebooks/outputs/ipynb_to_percent/wolfram.wolfram similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/wolfram.wolfram rename to tests/data/notebooks/outputs/ipynb_to_percent/wolfram.wolfram diff --git a/tests/notebooks/mirror/ipynb_to_percent/xcpp_by_quantstack.cpp b/tests/data/notebooks/outputs/ipynb_to_percent/xcpp_by_quantstack.cpp similarity index 100% rename from tests/notebooks/mirror/ipynb_to_percent/xcpp_by_quantstack.cpp rename to tests/data/notebooks/outputs/ipynb_to_percent/xcpp_by_quantstack.cpp diff --git a/tests/notebooks/mirror/ipynb_to_quarto/Notebook_with_more_R_magic_111.qmd b/tests/data/notebooks/outputs/ipynb_to_quarto/Notebook_with_more_R_magic_111.qmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_quarto/Notebook_with_more_R_magic_111.qmd rename to tests/data/notebooks/outputs/ipynb_to_quarto/Notebook_with_more_R_magic_111.qmd diff --git a/tests/notebooks/mirror/ipynb_to_quarto/cat_variable.qmd b/tests/data/notebooks/outputs/ipynb_to_quarto/cat_variable.qmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_quarto/cat_variable.qmd rename to tests/data/notebooks/outputs/ipynb_to_quarto/cat_variable.qmd diff --git a/tests/notebooks/mirror/ipynb_to_quarto/frozen_cell.qmd b/tests/data/notebooks/outputs/ipynb_to_quarto/frozen_cell.qmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_quarto/frozen_cell.qmd rename to tests/data/notebooks/outputs/ipynb_to_quarto/frozen_cell.qmd diff --git a/tests/notebooks/mirror/ipynb_to_quarto/julia_benchmark_plotly_barchart.qmd b/tests/data/notebooks/outputs/ipynb_to_quarto/julia_benchmark_plotly_barchart.qmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_quarto/julia_benchmark_plotly_barchart.qmd rename to tests/data/notebooks/outputs/ipynb_to_quarto/julia_benchmark_plotly_barchart.qmd diff --git a/tests/notebooks/mirror/ipynb_to_quarto/jupyter_again.qmd b/tests/data/notebooks/outputs/ipynb_to_quarto/jupyter_again.qmd similarity index 100% rename from tests/notebooks/mirror/ipynb_to_quarto/jupyter_again.qmd rename to tests/data/notebooks/outputs/ipynb_to_quarto/jupyter_again.qmd diff --git a/tests/notebooks/mirror/ipynb_to_script/Line_breaks_in_LateX_305.py b/tests/data/notebooks/outputs/ipynb_to_script/Line_breaks_in_LateX_305.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Line_breaks_in_LateX_305.py rename to tests/data/notebooks/outputs/ipynb_to_script/Line_breaks_in_LateX_305.py diff --git a/tests/notebooks/mirror/ipynb_to_script/Notebook with function and cell metadata 164.py b/tests/data/notebooks/outputs/ipynb_to_script/Notebook with function and cell metadata 164.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Notebook with function and cell metadata 164.py rename to tests/data/notebooks/outputs/ipynb_to_script/Notebook with function and cell metadata 164.py diff --git a/tests/notebooks/mirror/ipynb_to_script/Notebook with html and latex cells.py b/tests/data/notebooks/outputs/ipynb_to_script/Notebook with html and latex cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Notebook with html and latex cells.py rename to tests/data/notebooks/outputs/ipynb_to_script/Notebook with html and latex cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script/Notebook with metadata and long cells.py b/tests/data/notebooks/outputs/ipynb_to_script/Notebook with metadata and long cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Notebook with metadata and long cells.py rename to tests/data/notebooks/outputs/ipynb_to_script/Notebook with metadata and long cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script/Notebook_with_R_magic.py b/tests/data/notebooks/outputs/ipynb_to_script/Notebook_with_R_magic.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Notebook_with_R_magic.py rename to tests/data/notebooks/outputs/ipynb_to_script/Notebook_with_R_magic.py diff --git a/tests/notebooks/mirror/ipynb_to_script/Notebook_with_more_R_magic_111.py b/tests/data/notebooks/outputs/ipynb_to_script/Notebook_with_more_R_magic_111.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Notebook_with_more_R_magic_111.py rename to tests/data/notebooks/outputs/ipynb_to_script/Notebook_with_more_R_magic_111.py diff --git a/tests/notebooks/mirror/ipynb_to_script/R notebook with invalid cell keys.R b/tests/data/notebooks/outputs/ipynb_to_script/R notebook with invalid cell keys.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/R notebook with invalid cell keys.R rename to tests/data/notebooks/outputs/ipynb_to_script/R notebook with invalid cell keys.R diff --git a/tests/notebooks/mirror/ipynb_to_script/R notebook with invalid cell keys.low.r b/tests/data/notebooks/outputs/ipynb_to_script/R notebook with invalid cell keys.low.r similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/R notebook with invalid cell keys.low.r rename to tests/data/notebooks/outputs/ipynb_to_script/R notebook with invalid cell keys.low.r diff --git a/tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.scm b/tests/data/notebooks/outputs/ipynb_to_script/Reference Guide for Calysto Scheme.scm similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.scm rename to tests/data/notebooks/outputs/ipynb_to_script/Reference Guide for Calysto Scheme.scm diff --git a/tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.ss b/tests/data/notebooks/outputs/ipynb_to_script/Reference Guide for Calysto Scheme.ss similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/Reference Guide for Calysto Scheme.ss rename to tests/data/notebooks/outputs/ipynb_to_script/Reference Guide for Calysto Scheme.ss diff --git a/tests/notebooks/mirror/ipynb_to_script/The flavors of raw cells.py b/tests/data/notebooks/outputs/ipynb_to_script/The flavors of raw cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/The flavors of raw cells.py rename to tests/data/notebooks/outputs/ipynb_to_script/The flavors of raw cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script/cat_variable.py b/tests/data/notebooks/outputs/ipynb_to_script/cat_variable.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/cat_variable.py rename to tests/data/notebooks/outputs/ipynb_to_script/cat_variable.py diff --git a/tests/notebooks/mirror/ipynb_to_script/coconut_homepage_demo.coco b/tests/data/notebooks/outputs/ipynb_to_script/coconut_homepage_demo.coco similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/coconut_homepage_demo.coco rename to tests/data/notebooks/outputs/ipynb_to_script/coconut_homepage_demo.coco diff --git a/tests/notebooks/mirror/ipynb_to_script/convert_to_py_then_test_with_update83.py b/tests/data/notebooks/outputs/ipynb_to_script/convert_to_py_then_test_with_update83.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/convert_to_py_then_test_with_update83.py rename to tests/data/notebooks/outputs/ipynb_to_script/convert_to_py_then_test_with_update83.py diff --git a/tests/notebooks/mirror/ipynb_to_script/csharp.cs b/tests/data/notebooks/outputs/ipynb_to_script/csharp.cs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/csharp.cs rename to tests/data/notebooks/outputs/ipynb_to_script/csharp.cs diff --git a/tests/notebooks/mirror/ipynb_to_script/demo_gdl_fbp.pro b/tests/data/notebooks/outputs/ipynb_to_script/demo_gdl_fbp.pro similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/demo_gdl_fbp.pro rename to tests/data/notebooks/outputs/ipynb_to_script/demo_gdl_fbp.pro diff --git a/tests/notebooks/mirror/ipynb_to_script/evcxr_jupyter_tour.rs b/tests/data/notebooks/outputs/ipynb_to_script/evcxr_jupyter_tour.rs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/evcxr_jupyter_tour.rs rename to tests/data/notebooks/outputs/ipynb_to_script/evcxr_jupyter_tour.rs diff --git a/tests/notebooks/mirror/ipynb_to_script/frozen_cell.py b/tests/data/notebooks/outputs/ipynb_to_script/frozen_cell.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/frozen_cell.py rename to tests/data/notebooks/outputs/ipynb_to_script/frozen_cell.py diff --git a/tests/notebooks/mirror/ipynb_to_script/fsharp.fsx b/tests/data/notebooks/outputs/ipynb_to_script/fsharp.fsx similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/fsharp.fsx rename to tests/data/notebooks/outputs/ipynb_to_script/fsharp.fsx diff --git a/tests/notebooks/mirror/ipynb_to_script/gnuplot_notebook.gp b/tests/data/notebooks/outputs/ipynb_to_script/gnuplot_notebook.gp similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/gnuplot_notebook.gp rename to tests/data/notebooks/outputs/ipynb_to_script/gnuplot_notebook.gp diff --git a/tests/notebooks/mirror/ipynb_to_script/haskell_notebook.hs b/tests/data/notebooks/outputs/ipynb_to_script/haskell_notebook.hs similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/haskell_notebook.hs rename to tests/data/notebooks/outputs/ipynb_to_script/haskell_notebook.hs diff --git a/tests/notebooks/mirror/ipynb_to_script/html-demo.clj b/tests/data/notebooks/outputs/ipynb_to_script/html-demo.clj similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/html-demo.clj rename to tests/data/notebooks/outputs/ipynb_to_script/html-demo.clj diff --git a/tests/notebooks/mirror/ipynb_to_script/ijavascript.js b/tests/data/notebooks/outputs/ipynb_to_script/ijavascript.js similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/ijavascript.js rename to tests/data/notebooks/outputs/ipynb_to_script/ijavascript.js diff --git a/tests/notebooks/mirror/ipynb_to_script/ir_notebook.R b/tests/data/notebooks/outputs/ipynb_to_script/ir_notebook.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/ir_notebook.R rename to tests/data/notebooks/outputs/ipynb_to_script/ir_notebook.R diff --git a/tests/notebooks/mirror/ipynb_to_script/ir_notebook.low.r b/tests/data/notebooks/outputs/ipynb_to_script/ir_notebook.low.r similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/ir_notebook.low.r rename to tests/data/notebooks/outputs/ipynb_to_script/ir_notebook.low.r diff --git a/tests/notebooks/mirror/ipynb_to_script/itypescript.ts b/tests/data/notebooks/outputs/ipynb_to_script/itypescript.ts similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/itypescript.ts rename to tests/data/notebooks/outputs/ipynb_to_script/itypescript.ts diff --git a/tests/notebooks/mirror/ipynb_to_script/julia_benchmark_plotly_barchart.jl b/tests/data/notebooks/outputs/ipynb_to_script/julia_benchmark_plotly_barchart.jl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/julia_benchmark_plotly_barchart.jl rename to tests/data/notebooks/outputs/ipynb_to_script/julia_benchmark_plotly_barchart.jl diff --git a/tests/notebooks/mirror/ipynb_to_script/julia_functional_geometry.jl b/tests/data/notebooks/outputs/ipynb_to_script/julia_functional_geometry.jl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/julia_functional_geometry.jl rename to tests/data/notebooks/outputs/ipynb_to_script/julia_functional_geometry.jl diff --git a/tests/notebooks/mirror/ipynb_to_script/jupyter.py b/tests/data/notebooks/outputs/ipynb_to_script/jupyter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/jupyter.py rename to tests/data/notebooks/outputs/ipynb_to_script/jupyter.py diff --git a/tests/notebooks/mirror/ipynb_to_script/jupyter_again.py b/tests/data/notebooks/outputs/ipynb_to_script/jupyter_again.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/jupyter_again.py rename to tests/data/notebooks/outputs/ipynb_to_script/jupyter_again.py diff --git a/tests/notebooks/mirror/ipynb_to_script/jupyter_with_raw_cell_in_body.py b/tests/data/notebooks/outputs/ipynb_to_script/jupyter_with_raw_cell_in_body.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/jupyter_with_raw_cell_in_body.py rename to tests/data/notebooks/outputs/ipynb_to_script/jupyter_with_raw_cell_in_body.py diff --git a/tests/notebooks/mirror/ipynb_to_script/jupyter_with_raw_cell_on_top.py b/tests/data/notebooks/outputs/ipynb_to_script/jupyter_with_raw_cell_on_top.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/jupyter_with_raw_cell_on_top.py rename to tests/data/notebooks/outputs/ipynb_to_script/jupyter_with_raw_cell_on_top.py diff --git a/tests/notebooks/mirror/ipynb_to_script/jupytext_replication.sos b/tests/data/notebooks/outputs/ipynb_to_script/jupytext_replication.sos similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/jupytext_replication.sos rename to tests/data/notebooks/outputs/ipynb_to_script/jupytext_replication.sos diff --git a/tests/notebooks/mirror/ipynb_to_script/kalman_filter_and_visualization.q b/tests/data/notebooks/outputs/ipynb_to_script/kalman_filter_and_visualization.q similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/kalman_filter_and_visualization.q rename to tests/data/notebooks/outputs/ipynb_to_script/kalman_filter_and_visualization.q diff --git a/tests/notebooks/mirror/ipynb_to_script/maxima_example.mac b/tests/data/notebooks/outputs/ipynb_to_script/maxima_example.mac similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/maxima_example.mac rename to tests/data/notebooks/outputs/ipynb_to_script/maxima_example.mac diff --git a/tests/notebooks/mirror/ipynb_to_script/notebook_with_complex_metadata.py b/tests/data/notebooks/outputs/ipynb_to_script/notebook_with_complex_metadata.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/notebook_with_complex_metadata.py rename to tests/data/notebooks/outputs/ipynb_to_script/notebook_with_complex_metadata.py diff --git a/tests/notebooks/mirror/ipynb_to_script/nteract_with_parameter.py b/tests/data/notebooks/outputs/ipynb_to_script/nteract_with_parameter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/nteract_with_parameter.py rename to tests/data/notebooks/outputs/ipynb_to_script/nteract_with_parameter.py diff --git a/tests/notebooks/mirror/ipynb_to_script/ocaml_notebook.ml b/tests/data/notebooks/outputs/ipynb_to_script/ocaml_notebook.ml similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/ocaml_notebook.ml rename to tests/data/notebooks/outputs/ipynb_to_script/ocaml_notebook.ml diff --git a/tests/notebooks/mirror/ipynb_to_script/octave_notebook.m b/tests/data/notebooks/outputs/ipynb_to_script/octave_notebook.m similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/octave_notebook.m rename to tests/data/notebooks/outputs/ipynb_to_script/octave_notebook.m diff --git a/tests/notebooks/mirror/ipynb_to_script/plotly_graphs.py b/tests/data/notebooks/outputs/ipynb_to_script/plotly_graphs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/plotly_graphs.py rename to tests/data/notebooks/outputs/ipynb_to_script/plotly_graphs.py diff --git a/tests/notebooks/mirror/ipynb_to_script/powershell.ps1 b/tests/data/notebooks/outputs/ipynb_to_script/powershell.ps1 similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/powershell.ps1 rename to tests/data/notebooks/outputs/ipynb_to_script/powershell.ps1 diff --git a/tests/notebooks/mirror/ipynb_to_script/sage_print_hello.sage b/tests/data/notebooks/outputs/ipynb_to_script/sage_print_hello.sage similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/sage_print_hello.sage rename to tests/data/notebooks/outputs/ipynb_to_script/sage_print_hello.sage diff --git a/tests/notebooks/mirror/ipynb_to_script/sample_bash_notebook.sh b/tests/data/notebooks/outputs/ipynb_to_script/sample_bash_notebook.sh similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/sample_bash_notebook.sh rename to tests/data/notebooks/outputs/ipynb_to_script/sample_bash_notebook.sh diff --git a/tests/notebooks/mirror/ipynb_to_script/sample_rise_notebook_66.py b/tests/data/notebooks/outputs/ipynb_to_script/sample_rise_notebook_66.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/sample_rise_notebook_66.py rename to tests/data/notebooks/outputs/ipynb_to_script/sample_rise_notebook_66.py diff --git a/tests/notebooks/mirror/ipynb_to_script/sas.sas b/tests/data/notebooks/outputs/ipynb_to_script/sas.sas similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/sas.sas rename to tests/data/notebooks/outputs/ipynb_to_script/sas.sas diff --git a/tests/notebooks/mirror/ipynb_to_script/simple-helloworld.java b/tests/data/notebooks/outputs/ipynb_to_script/simple-helloworld.java similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/simple-helloworld.java rename to tests/data/notebooks/outputs/ipynb_to_script/simple-helloworld.java diff --git a/tests/notebooks/mirror/ipynb_to_script/simple_robot_notebook.robot b/tests/data/notebooks/outputs/ipynb_to_script/simple_robot_notebook.robot similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/simple_robot_notebook.robot rename to tests/data/notebooks/outputs/ipynb_to_script/simple_robot_notebook.robot diff --git a/tests/notebooks/mirror/ipynb_to_script/simple_scala_notebook.scala b/tests/data/notebooks/outputs/ipynb_to_script/simple_scala_notebook.scala similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/simple_scala_notebook.scala rename to tests/data/notebooks/outputs/ipynb_to_script/simple_scala_notebook.scala diff --git a/tests/notebooks/mirror/ipynb_to_script/stata_notebook.do b/tests/data/notebooks/outputs/ipynb_to_script/stata_notebook.do similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/stata_notebook.do rename to tests/data/notebooks/outputs/ipynb_to_script/stata_notebook.do diff --git a/tests/notebooks/mirror/ipynb_to_script/tailrecursive-factorial.groovy b/tests/data/notebooks/outputs/ipynb_to_script/tailrecursive-factorial.groovy similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/tailrecursive-factorial.groovy rename to tests/data/notebooks/outputs/ipynb_to_script/tailrecursive-factorial.groovy diff --git a/tests/notebooks/mirror/ipynb_to_script/tcl_test.tcl b/tests/data/notebooks/outputs/ipynb_to_script/tcl_test.tcl similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/tcl_test.tcl rename to tests/data/notebooks/outputs/ipynb_to_script/tcl_test.tcl diff --git a/tests/notebooks/mirror/ipynb_to_script/text_outputs_and_images.py b/tests/data/notebooks/outputs/ipynb_to_script/text_outputs_and_images.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/text_outputs_and_images.py rename to tests/data/notebooks/outputs/ipynb_to_script/text_outputs_and_images.py diff --git a/tests/notebooks/mirror/ipynb_to_script/wolfram.wolfram b/tests/data/notebooks/outputs/ipynb_to_script/wolfram.wolfram similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/wolfram.wolfram rename to tests/data/notebooks/outputs/ipynb_to_script/wolfram.wolfram diff --git a/tests/notebooks/mirror/ipynb_to_script/xcpp_by_quantstack.cpp b/tests/data/notebooks/outputs/ipynb_to_script/xcpp_by_quantstack.cpp similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script/xcpp_by_quantstack.cpp rename to tests/data/notebooks/outputs/ipynb_to_script/xcpp_by_quantstack.cpp diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Line_breaks_in_LateX_305.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Line_breaks_in_LateX_305.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Line_breaks_in_LateX_305.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Line_breaks_in_LateX_305.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with function and cell metadata 164.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with function and cell metadata 164.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with function and cell metadata 164.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with function and cell metadata 164.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with html and latex cells.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with html and latex cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with html and latex cells.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with html and latex cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with many hash signs.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with many hash signs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with many hash signs.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with many hash signs.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with metadata and long cells.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with metadata and long cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook with metadata and long cells.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook with metadata and long cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook_with_R_magic.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook_with_R_magic.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook_with_R_magic.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook_with_R_magic.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook_with_more_R_magic_111.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook_with_more_R_magic_111.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/Notebook_with_more_R_magic_111.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/Notebook_with_more_R_magic_111.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/The flavors of raw cells.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/The flavors of raw cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/The flavors of raw cells.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/The flavors of raw cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/cat_variable.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/cat_variable.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/cat_variable.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/cat_variable.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/convert_to_py_then_test_with_update83.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/convert_to_py_then_test_with_update83.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/convert_to_py_then_test_with_update83.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/convert_to_py_then_test_with_update83.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/frozen_cell.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/frozen_cell.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/frozen_cell.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/frozen_cell.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter_again.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter_again.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter_again.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter_again.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_in_body.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_in_body.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_in_body.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_in_body.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_on_top.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_on_top.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_on_top.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/jupyter_with_raw_cell_on_top.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/notebook_with_complex_metadata.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/notebook_with_complex_metadata.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/notebook_with_complex_metadata.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/notebook_with_complex_metadata.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/nteract_with_parameter.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/nteract_with_parameter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/nteract_with_parameter.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/nteract_with_parameter.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/plotly_graphs.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/plotly_graphs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/plotly_graphs.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/plotly_graphs.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/sample_rise_notebook_66.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/sample_rise_notebook_66.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/sample_rise_notebook_66.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/sample_rise_notebook_66.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/text_outputs_and_images.py b/tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/text_outputs_and_images.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vim_folding_markers/text_outputs_and_images.py rename to tests/data/notebooks/outputs/ipynb_to_script_vim_folding_markers/text_outputs_and_images.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Line_breaks_in_LateX_305.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Line_breaks_in_LateX_305.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Line_breaks_in_LateX_305.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Line_breaks_in_LateX_305.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with function and cell metadata 164.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with function and cell metadata 164.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with function and cell metadata 164.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with function and cell metadata 164.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with html and latex cells.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with html and latex cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with html and latex cells.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with html and latex cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with many hash signs.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with many hash signs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with many hash signs.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with many hash signs.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with metadata and long cells.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with metadata and long cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook with metadata and long cells.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook with metadata and long cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook_with_R_magic.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook_with_R_magic.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook_with_R_magic.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook_with_R_magic.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook_with_more_R_magic_111.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook_with_more_R_magic_111.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/Notebook_with_more_R_magic_111.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/Notebook_with_more_R_magic_111.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/The flavors of raw cells.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/The flavors of raw cells.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/The flavors of raw cells.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/The flavors of raw cells.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/cat_variable.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/cat_variable.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/cat_variable.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/cat_variable.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/convert_to_py_then_test_with_update83.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/convert_to_py_then_test_with_update83.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/convert_to_py_then_test_with_update83.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/convert_to_py_then_test_with_update83.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/frozen_cell.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/frozen_cell.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/frozen_cell.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/frozen_cell.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter_again.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter_again.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter_again.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter_again.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_in_body.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_in_body.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_in_body.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_in_body.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_on_top.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_on_top.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_on_top.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/jupyter_with_raw_cell_on_top.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/notebook_with_complex_metadata.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/notebook_with_complex_metadata.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/notebook_with_complex_metadata.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/notebook_with_complex_metadata.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/nteract_with_parameter.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/nteract_with_parameter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/nteract_with_parameter.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/nteract_with_parameter.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/plotly_graphs.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/plotly_graphs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/plotly_graphs.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/plotly_graphs.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/sample_rise_notebook_66.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/sample_rise_notebook_66.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/sample_rise_notebook_66.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/sample_rise_notebook_66.py diff --git a/tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/text_outputs_and_images.py b/tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/text_outputs_and_images.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_script_vscode_folding_markers/text_outputs_and_images.py rename to tests/data/notebooks/outputs/ipynb_to_script_vscode_folding_markers/text_outputs_and_images.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/Line_breaks_in_LateX_305.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/Line_breaks_in_LateX_305.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/Line_breaks_in_LateX_305.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/Line_breaks_in_LateX_305.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/cat_variable.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/cat_variable.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/cat_variable.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/cat_variable.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/convert_to_py_then_test_with_update83.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/convert_to_py_then_test_with_update83.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/convert_to_py_then_test_with_update83.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/convert_to_py_then_test_with_update83.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/jupyter.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/jupyter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/jupyter.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/jupyter.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/jupyter_again.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/jupyter_again.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/jupyter_again.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/jupyter_again.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/notebook_with_complex_metadata.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/notebook_with_complex_metadata.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/notebook_with_complex_metadata.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/notebook_with_complex_metadata.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/nteract_with_parameter.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/nteract_with_parameter.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/nteract_with_parameter.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/nteract_with_parameter.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/plotly_graphs.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/plotly_graphs.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/plotly_graphs.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/plotly_graphs.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/sample_rise_notebook_66.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/sample_rise_notebook_66.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/sample_rise_notebook_66.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/sample_rise_notebook_66.py diff --git a/tests/notebooks/mirror/ipynb_to_sphinx/text_outputs_and_images.py b/tests/data/notebooks/outputs/ipynb_to_sphinx/text_outputs_and_images.py similarity index 100% rename from tests/notebooks/mirror/ipynb_to_sphinx/text_outputs_and_images.py rename to tests/data/notebooks/outputs/ipynb_to_sphinx/text_outputs_and_images.py diff --git a/tests/notebooks/mirror/ipynb_to_spin/R notebook with invalid cell keys.R b/tests/data/notebooks/outputs/ipynb_to_spin/R notebook with invalid cell keys.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_spin/R notebook with invalid cell keys.R rename to tests/data/notebooks/outputs/ipynb_to_spin/R notebook with invalid cell keys.R diff --git a/tests/notebooks/mirror/ipynb_to_spin/R notebook with invalid cell keys.low.r b/tests/data/notebooks/outputs/ipynb_to_spin/R notebook with invalid cell keys.low.r similarity index 100% rename from tests/notebooks/mirror/ipynb_to_spin/R notebook with invalid cell keys.low.r rename to tests/data/notebooks/outputs/ipynb_to_spin/R notebook with invalid cell keys.low.r diff --git a/tests/notebooks/mirror/ipynb_to_spin/ir_notebook.R b/tests/data/notebooks/outputs/ipynb_to_spin/ir_notebook.R similarity index 100% rename from tests/notebooks/mirror/ipynb_to_spin/ir_notebook.R rename to tests/data/notebooks/outputs/ipynb_to_spin/ir_notebook.R diff --git a/tests/notebooks/mirror/ipynb_to_spin/ir_notebook.low.r b/tests/data/notebooks/outputs/ipynb_to_spin/ir_notebook.low.r similarity index 100% rename from tests/notebooks/mirror/ipynb_to_spin/ir_notebook.low.r rename to tests/data/notebooks/outputs/ipynb_to_spin/ir_notebook.low.r diff --git a/tests/notebooks/mirror/md_to_ipynb/jupytext_markdown.ipynb b/tests/data/notebooks/outputs/md_to_ipynb/jupytext_markdown.ipynb similarity index 100% rename from tests/notebooks/mirror/md_to_ipynb/jupytext_markdown.ipynb rename to tests/data/notebooks/outputs/md_to_ipynb/jupytext_markdown.ipynb diff --git a/tests/notebooks/mirror/md_to_ipynb/plain_markdown.ipynb b/tests/data/notebooks/outputs/md_to_ipynb/plain_markdown.ipynb similarity index 100% rename from tests/notebooks/mirror/md_to_ipynb/plain_markdown.ipynb rename to tests/data/notebooks/outputs/md_to_ipynb/plain_markdown.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/build.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/build.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/build.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/build.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/hydrogen.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/hydrogen.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/hydrogen.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/hydrogen.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/hydrogen_latex_html_R_magics.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/hydrogen_latex_html_R_magics.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/hydrogen_latex_html_R_magics.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/hydrogen_latex_html_R_magics.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/julia_sample_script.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/julia_sample_script.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/julia_sample_script.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/julia_sample_script.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/knitr-spin.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/knitr-spin.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/knitr-spin.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/knitr-spin.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/light_sample.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/light_sample.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/light_sample.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/light_sample.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/python_notebook_sample.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/python_notebook_sample.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/python_notebook_sample.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/python_notebook_sample.ipynb diff --git a/tests/notebooks/mirror/script_to_ipynb/simple_r_script.ipynb b/tests/data/notebooks/outputs/script_to_ipynb/simple_r_script.ipynb similarity index 100% rename from tests/notebooks/mirror/script_to_ipynb/simple_r_script.ipynb rename to tests/data/notebooks/outputs/script_to_ipynb/simple_r_script.ipynb diff --git a/tests/notebooks/mirror/sphinx-rst2md_to_ipynb/plot_notebook.ipynb b/tests/data/notebooks/outputs/sphinx-rst2md_to_ipynb/plot_notebook.ipynb similarity index 100% rename from tests/notebooks/mirror/sphinx-rst2md_to_ipynb/plot_notebook.ipynb rename to tests/data/notebooks/outputs/sphinx-rst2md_to_ipynb/plot_notebook.ipynb diff --git a/tests/notebooks/mirror/sphinx_to_ipynb/plot_notebook.ipynb b/tests/data/notebooks/outputs/sphinx_to_ipynb/plot_notebook.ipynb similarity index 100% rename from tests/notebooks/mirror/sphinx_to_ipynb/plot_notebook.ipynb rename to tests/data/notebooks/outputs/sphinx_to_ipynb/plot_notebook.ipynb diff --git a/tests/test_black.py b/tests/external/cli/test_black.py similarity index 91% rename from tests/test_black.py rename to tests/external/cli/test_black.py index 396e737b8..1f5f79f20 100644 --- a/tests/test_black.py +++ b/tests/external/cli/test_black.py @@ -11,19 +11,18 @@ from jupytext.compare import compare, compare_cells, compare_notebooks from jupytext.header import _DEFAULT_NOTEBOOK_METADATA -from .utils import list_notebooks, requires_autopep8, requires_black, requires_flake8 - -@requires_black -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_apply_black_on_python_notebooks(tmpdir, cwd_tmpdir, nb_file): - copyfile(nb_file, "notebook.ipynb") +@pytest.mark.requires_black +def test_apply_black_on_python_notebooks(tmpdir, cwd_tmpdir, ipynb_py_file): + if "cell metadata" in ipynb_py_file: + pytest.skip() + copyfile(ipynb_py_file, "notebook.ipynb") jupytext(args=["notebook.ipynb", "--to", "py:percent"]) system("black", "notebook.py") jupytext(args=["notebook.py", "--to", "ipynb", "--update"]) - nb1 = read(nb_file) + nb1 = read(ipynb_py_file) nb2 = read("notebook.ipynb") nb3 = read("notebook.py") @@ -54,7 +53,7 @@ def test_black_invariant(): assert black_invariant(text_org) == black_invariant(text_black) -@requires_black +@pytest.mark.requires_black def test_pipe_into_black(): nb_org = new_notebook(cells=[new_code_cell("1 +1", id="cell-id")]) nb_dest = new_notebook(cells=[new_code_cell("1 + 1", id="cell-id")]) @@ -65,7 +64,7 @@ def test_pipe_into_black(): ) -@requires_autopep8 +@pytest.mark.requires_autopep8 def test_pipe_into_autopep8(): nb_org = new_notebook(cells=[new_code_cell("1 +1", id="cell-id")]) nb_dest = new_notebook(cells=[new_code_cell("1 + 1", id="cell-id")]) @@ -76,7 +75,7 @@ def test_pipe_into_autopep8(): ) -@requires_flake8 +@pytest.mark.requires_flake8 def test_pipe_into_flake8(): # Notebook OK nb = new_notebook(cells=[new_code_cell("# correct code\n1 + 1")]) @@ -88,12 +87,11 @@ def test_pipe_into_flake8(): pipe_notebook(nb, "flake8", update=False) -@requires_black -@requires_flake8 -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_apply_black_through_jupytext(tmpdir, nb_file): +@pytest.mark.requires_black +@pytest.mark.requires_flake8 +def test_apply_black_through_jupytext(tmpdir, python_notebook): # Load real notebook metadata to get the 'auto' extension in --pipe-fmt to work - metadata = read(nb_file).metadata + metadata = python_notebook.metadata nb_org = new_notebook( cells=[new_code_cell("1 +1", id="cell-id")], metadata=metadata @@ -141,11 +139,10 @@ def test_apply_black_through_jupytext(tmpdir, nb_file): compare_notebooks(nb_now, nb_black) -@requires_black -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_apply_black_and_sync_on_paired_notebook(tmpdir, cwd_tmpdir, nb_file): +@pytest.mark.requires_black +def test_apply_black_and_sync_on_paired_notebook(tmpdir, cwd_tmpdir, python_notebook): # Load real notebook metadata to get the 'auto' extension in --pipe-fmt to work - metadata = read(nb_file).metadata + metadata = python_notebook.metadata metadata["jupytext"] = {"formats": "ipynb,py"} assert "language_info" in metadata @@ -174,7 +171,7 @@ def test_apply_black_and_sync_on_paired_notebook(tmpdir, cwd_tmpdir, nb_file): compare_notebooks(nb_now, nb_black) -@requires_black +@pytest.mark.requires_black def test_apply_black_on_markdown_notebook(tmpdir): text = """--- jupyter: @@ -210,7 +207,7 @@ def test_apply_black_on_markdown_notebook(tmpdir): compare_cells(nb.cells, [new_code_cell("1 + 2 + 3 + 4")], compare_ids=False) -@requires_black +@pytest.mark.requires_black def test_black_through_tempfile( tmpdir, text="""```python @@ -231,7 +228,7 @@ def test_black_through_tempfile( compare(fp.read(), black) -@requires_black +@pytest.mark.requires_black def test_pipe_black_removes_lines_to_next_cell_metadata( tmpdir, cwd_tmpdir, @@ -255,7 +252,7 @@ def func(): assert "\n\n# %%\nfunc()" in new_text -@requires_black +@pytest.mark.requires_black @pytest.mark.parametrize( "code,black_should_fail", [("myvar = %dont_format_me", False), ("incomplete_instruction = (...", True)], @@ -288,7 +285,7 @@ def test_pipe_black_uses_warn_only_781( compare_notebooks(actual, nb) -@requires_black +@pytest.mark.requires_black def test_pipe_black_preserve_outputs(notebook_with_outputs, tmpdir, cwd_tmpdir, capsys): write(notebook_with_outputs, "test.ipynb") jupytext(["--pipe", "black", "test.ipynb"]) diff --git a/tests/test_cli_check.py b/tests/external/cli/test_cli_check.py similarity index 93% rename from tests/test_cli_check.py rename to tests/external/cli/test_cli_check.py index cbc469441..6056e3b5e 100644 --- a/tests/test_cli_check.py +++ b/tests/external/cli/test_cli_check.py @@ -4,15 +4,13 @@ from jupytext import write from jupytext.cli import jupytext -from .utils import requires_black - @pytest.fixture def non_black_notebook(python_notebook): return new_notebook(metadata=python_notebook.metadata, cells=[new_code_cell("1+1")]) -@requires_black +@pytest.mark.requires_black def test_check_notebooks_left_or_right_black(python_notebook, tmpdir, cwd_tmpdir): write(python_notebook, str(tmpdir / "nb1.ipynb")) write(python_notebook, str(tmpdir / "nb2.ipynb")) @@ -21,7 +19,7 @@ def test_check_notebooks_left_or_right_black(python_notebook, tmpdir, cwd_tmpdir jupytext(["--check", "black --check {}", "*.ipynb"]) -@requires_black +@pytest.mark.requires_black def test_check_notebooks_left_or_right_not_black( non_black_notebook, tmpdir, cwd_tmpdir ): diff --git a/tests/test_isort.py b/tests/external/cli/test_isort.py similarity index 93% rename from tests/test_isort.py rename to tests/external/cli/test_isort.py index 0c03ca17e..1df015533 100644 --- a/tests/test_isort.py +++ b/tests/external/cli/test_isort.py @@ -1,11 +1,11 @@ +import pytest + from jupytext import reads, writes from jupytext.cli import pipe_notebook from jupytext.compare import compare -from .utils import requires_isort - -@requires_isort +@pytest.mark.requires_isort def test_pipe_into_isort(): text_org = """# %% import numpy as np diff --git a/tests/external/conftest.py b/tests/external/conftest.py new file mode 100644 index 000000000..9f9cd86ba --- /dev/null +++ b/tests/external/conftest.py @@ -0,0 +1,8 @@ +import pytest +from git import Repo + + +@pytest.fixture +def tmp_repo(tmpdir): + repo = Repo.init(str(tmpdir)) + return repo diff --git a/tests/external/contents_manager/test_contentsmanager_external.py b/tests/external/contents_manager/test_contentsmanager_external.py new file mode 100644 index 000000000..06effd1e2 --- /dev/null +++ b/tests/external/contents_manager/test_contentsmanager_external.py @@ -0,0 +1,54 @@ +import re + +import pytest + +import jupytext +from jupytext.compare import compare_notebooks, notebook_model + + +@pytest.mark.requires_pandoc +def test_save_load_paired_md_pandoc_notebook(ipynb_py_R_jl_file, tmpdir): + if re.match( + r".*(functional|Notebook with|flavors|invalid|305).*", ipynb_py_R_jl_file + ): + pytest.skip() + tmp_ipynb = "notebook.ipynb" + tmp_md = "notebook.md" + + cm = jupytext.TextFileContentsManager() + cm.root_dir = str(tmpdir) + + # open ipynb, save with cm, reopen + nb = jupytext.read(ipynb_py_R_jl_file) + nb.metadata["jupytext"] = {"formats": "ipynb,md:pandoc"} + + cm.save(model=notebook_model(nb), path=tmp_ipynb) + nb_md = cm.get(tmp_md) + + compare_notebooks(nb_md["content"], nb, "md:pandoc") + assert nb_md["content"].metadata["jupytext"]["formats"] == "ipynb,md:pandoc" + + +@pytest.mark.requires_quarto +def test_save_load_paired_qmd_notebook(ipynb_py_R_jl_file, tmpdir): + if re.match( + r".*(functional|Notebook with|plotly_graphs|flavors|complex_metadata|" + "update83|raw_cell|_66|nteract|LaTeX|invalid|305|text_outputs|ir_notebook|jupyter|with_R_magic).*", + ipynb_py_R_jl_file, + ): + pytest.skip() + tmp_ipynb = "notebook.ipynb" + tmp_qmd = "notebook.qmd" + + cm = jupytext.TextFileContentsManager() + cm.root_dir = str(tmpdir) + + # open ipynb, save with cm, reopen + nb = jupytext.read(ipynb_py_R_jl_file) + nb.metadata["jupytext"] = {"formats": "ipynb,qmd"} + + cm.save(model=notebook_model(nb), path=tmp_ipynb) + nb_md = cm.get(tmp_qmd) + + compare_notebooks(nb_md["content"], nb, "qmd") + assert nb_md["content"].metadata["jupytext"]["formats"] == "ipynb,qmd" diff --git a/tests/test_using_cli.py b/tests/external/docs/test_using_cli.py similarity index 88% rename from tests/test_using_cli.py rename to tests/external/docs/test_using_cli.py index a0e54d86d..275b4313e 100644 --- a/tests/test_using_cli.py +++ b/tests/external/docs/test_using_cli.py @@ -7,14 +7,12 @@ import jupytext from jupytext.cli import jupytext as jupytext_cli -from .utils import requires_black, requires_myst, requires_user_kernel_python3 +doc_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "docs") -doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "docs") - -@requires_user_kernel_python3 -@requires_black -@requires_myst +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_black +@pytest.mark.requires_myst @pytest.mark.skipif( not os.path.isdir(doc_path), reason="Documentation folder is missing" ) diff --git a/tests/external/jupyter_fs/test_jupyter_fs.py b/tests/external/jupyter_fs/test_jupyter_fs.py new file mode 100644 index 000000000..0b703e542 --- /dev/null +++ b/tests/external/jupyter_fs/test_jupyter_fs.py @@ -0,0 +1,98 @@ +import logging + +import pytest +from nbformat.v4.nbbase import new_code_cell, new_markdown_cell, new_notebook + +import jupytext +from jupytext.compare import compare_cells, notebook_model + + +def fs_meta_manager(tmpdir): + try: + from jupyterfs.metamanager import MetaManager + except ImportError: + pytest.skip("jupyterfs is not available") + + cm_class = jupytext.build_jupytext_contents_manager_class(MetaManager) + logger = logging.getLogger("jupyter-fs") + cm = cm_class(parent=None, log=logger) + cm.initResource( + { + "url": f"osfs://{tmpdir}", + } + ) + return cm + + +def test_jupytext_jupyter_fs_metamanager(tmpdir): + """Test the basic get/save functions of Jupytext with a fs manager + https://github.com/mwouts/jupytext/issues/618""" + cm = fs_meta_manager(tmpdir) + # the hash that corresponds to the osfs + osfs = [h for h in cm._managers if h != ""][0] + + # save a few files + text = "some text\n" + cm.save(dict(type="file", content=text, format="text"), path=osfs + ":text.md") + nb = new_notebook( + cells=[new_markdown_cell("A markdown cell"), new_code_cell("1 + 1")] + ) + cm.save(notebook_model(nb), osfs + ":notebook.ipynb") + cm.save(notebook_model(nb), osfs + ":text_notebook.md") + + # list the directory + directory = cm.get(osfs + ":/") + assert {file["name"] for file in directory["content"]} == { + "text.md", + "text_notebook.md", + "notebook.ipynb", + } + + # get the files + model = cm.get(osfs + ":/text.md", type="file") + assert model["type"] == "file" + assert model["content"] == text + + model = cm.get(osfs + ":text.md", type="notebook") + assert model["type"] == "notebook" + # We only compare the cells, as kernelspecs are added to the notebook metadata + compare_cells( + model["content"].cells, [new_markdown_cell(text.strip())], compare_ids=False + ) + + for nb_file in ["notebook.ipynb", "text_notebook.md"]: + model = cm.get(osfs + ":" + nb_file) + assert model["type"] == "notebook" + actual_cells = model["content"].cells + + # saving adds 'trusted=True' to the code cell metadata + for cell in actual_cells: + cell.metadata = {} + compare_cells(actual_cells, nb.cells, compare_ids=False) + + +def test_config_jupytext_jupyter_fs_meta_manager(tmpdir): + """Test the configuration of Jupytext with a fs manager""" + tmpdir.join("jupytext.toml").write('formats = "ipynb,py"') + cm = fs_meta_manager(tmpdir) + # the hash that corresponds to the osfs + osfs = [h for h in cm._managers if h != ""][0] + + # save a few files + nb = new_notebook() + cm.save(dict(type="file", content="text", format="text"), path=osfs + ":text.md") + cm.save(notebook_model(nb), osfs + ":script.py") + cm.save(notebook_model(nb), osfs + ":text_notebook.md") + cm.save(notebook_model(nb), osfs + ":notebook.ipynb") + + # list the directory + directory = cm.get(osfs + ":/") + assert {file["name"] for file in directory["content"]} == { + "jupytext.toml", + "text.md", + "text_notebook.md", + "notebook.ipynb", + "notebook.py", + "script.py", + "script.ipynb", + } diff --git a/tests/test_pre_commit_0_ipynb_to_py.py b/tests/external/pre_commit/test_pre_commit_0_ipynb_to_py.py similarity index 91% rename from tests/test_pre_commit_0_ipynb_to_py.py rename to tests/external/pre_commit/test_pre_commit_0_ipynb_to_py.py index 87c284160..2b3af5a8f 100644 --- a/tests/test_pre_commit_0_ipynb_to_py.py +++ b/tests/external/pre_commit/test_pre_commit_0_ipynb_to_py.py @@ -7,14 +7,7 @@ from jupytext.cli import jupytext from jupytext.compare import compare_cells -from .utils import ( - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo def test_pre_commit_hook_ipynb_to_py( tmpdir, cwd_tmpdir, tmp_repo, jupytext_repo_root, jupytext_repo_rev ): diff --git a/tests/test_pre_commit_1_sync.py b/tests/external/pre_commit/test_pre_commit_1_sync.py similarity index 93% rename from tests/test_pre_commit_1_sync.py rename to tests/external/pre_commit/test_pre_commit_1_sync.py index 256e72fcd..6b9854040 100644 --- a/tests/test_pre_commit_1_sync.py +++ b/tests/external/pre_commit/test_pre_commit_1_sync.py @@ -8,14 +8,7 @@ from jupytext import read, write from jupytext.cli import jupytext -from .utils import ( - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo def test_pre_commit_hook_sync( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_1_sync_with_config.py b/tests/external/pre_commit/test_pre_commit_1_sync_with_config.py similarity index 92% rename from tests/test_pre_commit_1_sync_with_config.py rename to tests/external/pre_commit/test_pre_commit_1_sync_with_config.py index 1bb3adaec..1ef521cff 100644 --- a/tests/test_pre_commit_1_sync_with_config.py +++ b/tests/external/pre_commit/test_pre_commit_1_sync_with_config.py @@ -5,14 +5,7 @@ from jupytext import TextFileContentsManager, read -from .utils import ( - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo def test_pre_commit_hook_sync_with_config( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_1_sync_with_no_config.py b/tests/external/pre_commit/test_pre_commit_1_sync_with_no_config.py similarity index 91% rename from tests/test_pre_commit_1_sync_with_no_config.py rename to tests/external/pre_commit/test_pre_commit_1_sync_with_no_config.py index 0ba56b052..4222cc91f 100644 --- a/tests/test_pre_commit_1_sync_with_no_config.py +++ b/tests/external/pre_commit/test_pre_commit_1_sync_with_no_config.py @@ -9,14 +9,7 @@ from jupytext import TextFileContentsManager from jupytext.compare import compare_notebooks -from .utils import ( - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo def test_pre_commit_hook_sync_with_no_config( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_2_sync_nbstripout.py b/tests/external/pre_commit/test_pre_commit_2_sync_nbstripout.py similarity index 88% rename from tests/test_pre_commit_2_sync_nbstripout.py rename to tests/external/pre_commit/test_pre_commit_2_sync_nbstripout.py index 14dc9b9e1..304a84f5b 100644 --- a/tests/test_pre_commit_2_sync_nbstripout.py +++ b/tests/external/pre_commit/test_pre_commit_2_sync_nbstripout.py @@ -5,14 +5,7 @@ from jupytext import read, write from jupytext.cli import jupytext -from .utils import ( - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo def test_pre_commit_hook_sync_nbstripout( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_3_sync_black_nbstripout.py b/tests/external/pre_commit/test_pre_commit_3_sync_black_nbstripout.py similarity index 89% rename from tests/test_pre_commit_3_sync_black_nbstripout.py rename to tests/external/pre_commit/test_pre_commit_3_sync_black_nbstripout.py index db04796b9..01a549fec 100644 --- a/tests/test_pre_commit_3_sync_black_nbstripout.py +++ b/tests/external/pre_commit/test_pre_commit_3_sync_black_nbstripout.py @@ -4,14 +4,7 @@ from jupytext import read, write -from .utils import ( - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo def test_pre_commit_hook_sync_black_nbstripout( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_4_sync_execute.py b/tests/external/pre_commit/test_pre_commit_4_sync_execute.py similarity index 86% rename from tests/test_pre_commit_4_sync_execute.py rename to tests/external/pre_commit/test_pre_commit_4_sync_execute.py index 0fc232b5a..92694b29b 100644 --- a/tests/test_pre_commit_4_sync_execute.py +++ b/tests/external/pre_commit/test_pre_commit_4_sync_execute.py @@ -5,16 +5,8 @@ from jupytext import read, write -from .utils import ( - requires_user_kernel_python3, - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@requires_user_kernel_python3 -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo +@pytest.mark.requires_user_kernel_python3 def test_pre_commit_hook_sync_execute( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_5_reformat_markdown.py b/tests/external/pre_commit/test_pre_commit_5_reformat_markdown.py similarity index 93% rename from tests/test_pre_commit_5_reformat_markdown.py rename to tests/external/pre_commit/test_pre_commit_5_reformat_markdown.py index 86c04e1ee..e55654dbc 100644 --- a/tests/test_pre_commit_5_reformat_markdown.py +++ b/tests/external/pre_commit/test_pre_commit_5_reformat_markdown.py @@ -5,16 +5,8 @@ from jupytext import read, write -from .utils import ( - requires_pandoc, - skip_pre_commit_tests_on_windows, - skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo, -) - -@requires_pandoc -@skip_pre_commit_tests_on_windows -@skip_pre_commit_tests_when_jupytext_folder_is_not_a_git_repo +@pytest.mark.requires_pandoc def test_pre_commit_hook_sync_reformat_code_and_markdown( tmpdir, cwd_tmpdir, diff --git a/tests/test_pre_commit_mode.py b/tests/external/pre_commit/test_pre_commit_mode.py similarity index 92% rename from tests/test_pre_commit_mode.py rename to tests/external/pre_commit/test_pre_commit_mode.py index ec35f08dc..125775f9b 100644 --- a/tests/test_pre_commit_mode.py +++ b/tests/external/pre_commit/test_pre_commit_mode.py @@ -254,3 +254,23 @@ def test_sync_pre_commit_mode_respects_commit_order_780( for file in commit_order: nb = read(file) assert nb.cells[0].source == "2 + 2", file + + +@pytest.mark.requires_user_kernel_python3 +def test_skip_execution(tmpdir, cwd_tmpdir, tmp_repo, python_notebook, capsys): + write( + new_notebook(cells=[new_code_cell("1 + 1")], metadata=python_notebook.metadata), + "test.ipynb", + ) + tmp_repo.index.add("test.ipynb") + + jupytext(["--execute", "--pre-commit-mode", "test.ipynb"]) + captured = capsys.readouterr() + assert "Executing notebook" in captured.out + + nb = read("test.ipynb") + assert nb.cells[0].execution_count == 1 + + jupytext(["--execute", "--pre-commit-mode", "test.ipynb"]) + captured = capsys.readouterr() + assert "skipped" in captured.out diff --git a/tests/test_pre_commit_scripts.py b/tests/external/pre_commit/test_pre_commit_scripts.py similarity index 95% rename from tests/test_pre_commit_scripts.py rename to tests/external/pre_commit/test_pre_commit_scripts.py index ae0116355..885986db9 100644 --- a/tests/test_pre_commit_scripts.py +++ b/tests/external/pre_commit/test_pre_commit_scripts.py @@ -9,14 +9,6 @@ from jupytext.cli import jupytext, system from jupytext.compare import compare_cells, compare_notebooks -from .utils import ( - list_notebooks, - requires_black, - requires_flake8, - requires_jupytext_installed, - requires_pandoc, -) - def git_in_tmpdir(tmpdir): """Return a function that will execute git instruction in the desired directory""" @@ -43,7 +35,6 @@ def system_(*args): return system_ -@requires_jupytext_installed def test_pre_commit_hook(tmpdir): tmp_ipynb = str(tmpdir.join("nb with spaces.ipynb")) tmp_py = str(tmpdir.join("nb with spaces.py")) @@ -70,7 +61,6 @@ def test_pre_commit_hook(tmpdir): assert os.path.isfile(tmp_py) -@requires_jupytext_installed def test_sync_with_pre_commit_hook(tmpdir): # Init git and create a pre-commit hook git = git_in_tmpdir(tmpdir) @@ -149,7 +139,6 @@ def test_sync_with_pre_commit_hook(tmpdir): git("commit", "-m", "added image") -@requires_jupytext_installed def test_pre_commit_hook_in_subfolder(tmpdir): tmp_ipynb = str(tmpdir.join("nb with spaces.ipynb")) tmp_py = str(tmpdir.join("python", "nb with spaces.py")) @@ -178,7 +167,6 @@ def test_pre_commit_hook_in_subfolder(tmpdir): assert os.path.isfile(tmp_py) -@requires_jupytext_installed def test_pre_commit_hook_py_to_ipynb_and_md(tmpdir): tmp_ipynb = str(tmpdir.join("nb with spaces.ipynb")) tmp_py = str(tmpdir.join("nb with spaces.py")) @@ -214,13 +202,11 @@ def test_pre_commit_hook_py_to_ipynb_and_md(tmpdir): assert os.path.isfile(tmp_md) -@requires_black -@requires_flake8 -@requires_jupytext_installed -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_pre_commit_hook_sync_black_flake8(tmpdir, nb_file): +@pytest.mark.requires_black +@pytest.mark.requires_flake8 +def test_pre_commit_hook_sync_black_flake8(tmpdir, python_notebook): # Load real notebook metadata to get the 'auto' extension in --pipe-fmt to work - metadata = read(nb_file).metadata + metadata = python_notebook.metadata git = git_in_tmpdir(tmpdir) hook = str(tmpdir.join(".git/hooks/pre-commit")) @@ -287,7 +273,6 @@ def hook(): assert os.path.isfile(tmp_py) -@requires_jupytext_installed def test_pre_commit_hook_with_subfolders_issue_506(tmpdir): """I have the following directory structure, where the nb/test.ipynb is paired with the py/test.py. @@ -331,8 +316,7 @@ def test_pre_commit_hook_with_subfolders_issue_506(tmpdir): assert read(str(nb_file)).cells[0].source == "A Markdown cell" -@requires_pandoc -@requires_jupytext_installed +@pytest.mark.requires_pandoc def test_wrap_markdown_cell(tmpdir): """Use a pre-commit hook to sync a notebook to a script paired in a tree, and reformat the markdown cells using pandoc""" diff --git a/tests/external/round_trip/test_mirror_external.py b/tests/external/round_trip/test_mirror_external.py new file mode 100644 index 000000000..70467a197 --- /dev/null +++ b/tests/external/round_trip/test_mirror_external.py @@ -0,0 +1,53 @@ +import pytest + +from jupytext.compare import assert_conversion_same_as_mirror + +"""--------------------------------------------------------------------------------- + +Part I: ipynb -> fmt -> ipynb + +---------------------------------------------------------------------------------""" + + +@pytest.mark.requires_pandoc +def test_ipynb_to_pandoc(ipynb_to_pandoc, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_to_pandoc, "md:pandoc", "ipynb_to_pandoc") + + +@pytest.mark.requires_quarto +def test_ipynb_to_quarto( + ipynb_to_quarto, + no_jupytext_version_number, +): + assert_conversion_same_as_mirror(ipynb_to_quarto, "qmd", "ipynb_to_quarto") + + +@pytest.mark.requires_sphinx_gallery +def test_ipynb_to_python_sphinx(ipynb_to_sphinx, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_to_sphinx, "py:sphinx", "ipynb_to_sphinx") + + +"""--------------------------------------------------------------------------------- + +Part II: text -> ipynb -> text + +---------------------------------------------------------------------------------""" + + +def test_Rmd_to_ipynb(rmd_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(rmd_file, "ipynb", "Rmd_to_ipynb") + + +@pytest.mark.requires_sphinx_gallery +def test_sphinx_to_ipynb(sphinx_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(sphinx_file, "ipynb:sphinx", "sphinx_to_ipynb") + + +@pytest.mark.requires_sphinx_gallery +def test_sphinx_md_to_ipynb(sphinx_file, no_jupytext_version_number): + assert_conversion_same_as_mirror( + sphinx_file, + {"extension": ".ipynb", "format_name": "sphinx", "rst2md": True}, + "sphinx-rst2md_to_ipynb", + compare_notebook=True, + ) diff --git a/tests/external/rst2md/test_rst2md.py b/tests/external/rst2md/test_rst2md.py new file mode 100644 index 000000000..d89c6337f --- /dev/null +++ b/tests/external/rst2md/test_rst2md.py @@ -0,0 +1,69 @@ +import os + +import pytest +from nbformat.v4.nbbase import new_markdown_cell, new_notebook + +from jupytext import TextFileContentsManager, read, write +from jupytext.cli import jupytext + + +@pytest.mark.requires_sphinx_gallery +def test_rst2md(tmpdir, cwd_tmpdir): + tmp_py = "notebook.py" + tmp_ipynb = "notebook.ipynb" + + # Write notebook in sphinx format + nb = new_notebook( + cells=[ + new_markdown_cell("A short sphinx notebook"), + new_markdown_cell(":math:`1+1`"), + ] + ) + write(nb, tmp_py, fmt="py:sphinx") + + jupytext( + [ + tmp_py, + "--from", + "py:sphinx", + "--to", + "ipynb", + "--opt", + "rst2md=True", + "--opt", + "cell_metadata_filter=-all", + ] + ) + + assert os.path.isfile(tmp_ipynb) + nb = read(tmp_ipynb) + + assert nb.metadata["jupytext"]["cell_metadata_filter"] == "-all" + assert nb.metadata["jupytext"]["rst2md"] is False + + # Was rst to md conversion effective? + assert nb.cells[2].source == "$1+1$" + + +@pytest.mark.requires_sphinx_gallery +def test_rst2md_option(tmpdir): + tmp_py = str(tmpdir.join("notebook.py")) + + # Write notebook in sphinx format + nb = new_notebook( + cells=[ + new_markdown_cell("A short sphinx notebook"), + new_markdown_cell(":math:`1+1`"), + ] + ) + write(nb, tmp_py, fmt="py:sphinx") + + cm = TextFileContentsManager() + cm.sphinx_convert_rst2md = True + cm.root_dir = str(tmpdir) + + nb2 = cm.get("notebook.py")["content"] + + # Was rst to md conversion effective? + assert nb2.cells[2].source == "$1+1$" + assert nb2.metadata["jupytext"]["rst2md"] is False diff --git a/tests/test_read_simple_pandoc.py b/tests/external/simple_external_notebooks/test_read_simple_pandoc.py similarity index 93% rename from tests/test_read_simple_pandoc.py rename to tests/external/simple_external_notebooks/test_read_simple_pandoc.py index c0c24d461..406a254b7 100644 --- a/tests/test_read_simple_pandoc.py +++ b/tests/external/simple_external_notebooks/test_read_simple_pandoc.py @@ -6,10 +6,8 @@ from jupytext.compare import compare, compare_notebooks from jupytext.pandoc import PandocError -from .utils import requires_no_pandoc, requires_pandoc - -@requires_pandoc +@pytest.mark.requires_pandoc def test_pandoc_implicit( markdown="""# Lorem ipsum @@ -31,7 +29,7 @@ def test_pandoc_implicit( compare(markdown3, markdown2) -@requires_pandoc +@pytest.mark.requires_pandoc def test_pandoc_explicit( markdown="""::: {.cell .markdown} # Lorem @@ -46,7 +44,7 @@ def test_pandoc_explicit( compare("\n".join(markdown2.splitlines()[12:]), markdown) -@requires_pandoc +@pytest.mark.requires_pandoc def test_pandoc_utf8_in_md( markdown="""::: {.cell .markdown} # Utf-8 support @@ -60,7 +58,7 @@ def test_pandoc_utf8_in_md( compare("\n".join(markdown2.splitlines()[12:]), markdown) -@requires_pandoc +@pytest.mark.requires_pandoc def test_pandoc_utf8_in_nb( nb=new_notebook( cells=[ @@ -78,7 +76,7 @@ def test_pandoc_utf8_in_nb( compare_notebooks(nb, nb2, "md:pandoc") -@requires_no_pandoc +@pytest.mark.requires_no_pandoc def test_meaningfull_error_when_pandoc_is_missing(tmpdir): nb_file = tmpdir.join("notebook.ipynb") jupytext.write(new_notebook(), str(nb_file)) diff --git a/tests/test_read_simple_quarto.py b/tests/external/simple_external_notebooks/test_read_simple_quarto.py similarity index 94% rename from tests/test_read_simple_quarto.py rename to tests/external/simple_external_notebooks/test_read_simple_quarto.py index 1e50c2394..ed9aff054 100644 --- a/tests/test_read_simple_quarto.py +++ b/tests/external/simple_external_notebooks/test_read_simple_quarto.py @@ -1,12 +1,11 @@ +import pytest from nbformat.v4.nbbase import new_code_cell, new_markdown_cell, new_notebook import jupytext from jupytext.compare import compare, compare_notebooks -from .utils import requires_quarto - -@requires_quarto +@pytest.mark.requires_quarto def test_qmd_to_ipynb( qmd="""Some text diff --git a/tests/test_cli.py b/tests/functional/cli/test_cli.py similarity index 83% rename from tests/test_cli.py rename to tests/functional/cli/test_cli.py index 1b613b175..a3d229083 100644 --- a/tests/test_cli.py +++ b/tests/functional/cli/test_cli.py @@ -17,17 +17,9 @@ from jupytext.cli import jupytext, parse_jupytext_args, str2bool, system from jupytext.compare import compare, compare_notebooks from jupytext.formats import JupytextFormatError, long_form_one_format +from jupytext.myst import is_myst_available from jupytext.paired_paths import InconsistentPath, paired_paths - -from .utils import ( - list_notebooks, - requires_jupytext_installed, - requires_myst, - requires_pandoc, - requires_sphinx_gallery, - requires_user_kernel_python3, - skip_on_windows, -) +from jupytext.pandoc import is_pandoc_available def test_str2bool(): @@ -38,20 +30,22 @@ def test_str2bool(): str2bool("UNEXPECTED") -@pytest.mark.parametrize("nb_file", list_notebooks()) -def test_cli_single_file(nb_file): - assert parse_jupytext_args([nb_file] + ["--to", "py"]).notebooks == [nb_file] +def test_cli_single_file(ipynb_py_R_jl_file): + assert parse_jupytext_args([ipynb_py_R_jl_file] + ["--to", "py"]).notebooks == [ + ipynb_py_R_jl_file + ] -@pytest.mark.parametrize("nb_files", [list_notebooks()]) -def test_cli_multiple_files(nb_files): - assert parse_jupytext_args(nb_files + ["--to", "py"]).notebooks == nb_files +def test_cli_multiple_files(ipynb_py_R_jl_files): + assert ( + parse_jupytext_args(ipynb_py_R_jl_files + ["--to", "py"]).notebooks + == ipynb_py_R_jl_files + ) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_convert_single_file_in_place(nb_file, tmpdir): - nb_org = str(tmpdir.join(os.path.basename(nb_file))) - copyfile(nb_file, nb_org) +def test_convert_single_file_in_place(ipynb_py_file, tmpdir): + nb_org = str(tmpdir.join(os.path.basename(ipynb_py_file))) + copyfile(ipynb_py_file, nb_org) base, ext = os.path.splitext(nb_org) nb_other = base + ".py" @@ -64,11 +58,9 @@ def test_convert_single_file_in_place(nb_file, tmpdir): compare_notebooks(nb2, nb1) -@requires_jupytext_installed -def test_convert_single_file_in_place_m(tmpdir): - nb_file = list_notebooks("ipynb_py")[0] - nb_org = str(tmpdir.join(os.path.basename(nb_file))) - copyfile(nb_file, nb_org) +def test_convert_single_file_in_place_m(ipynb_py_file, tmpdir): + nb_org = str(tmpdir.join(os.path.basename(ipynb_py_file))) + copyfile(ipynb_py_file, nb_org) base, ext = os.path.splitext(nb_org) @@ -83,12 +75,11 @@ def test_convert_single_file_in_place_m(tmpdir): compare_notebooks(nb2, nb1) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb") + list_notebooks("Rmd")) -def test_convert_single_file(nb_file, tmpdir, capsys): - nb_org = str(tmpdir.join(os.path.basename(nb_file))) - copyfile(nb_file, nb_org) +def test_convert_single_file(ipynb_or_rmd_file, tmpdir, capsys): + nb_org = str(tmpdir.join(os.path.basename(ipynb_or_rmd_file))) + copyfile(ipynb_or_rmd_file, nb_org) - nb1 = read(nb_file) + nb1 = read(ipynb_or_rmd_file) pynb = writes(nb1, "py") jupytext([nb_org, "--to", "py", "-o", "-"]) @@ -125,10 +116,9 @@ def test_wildcard(tmpdir): jupytext(["nb3.ipynb", "--to", "py"]) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_cpp")) -def test_to_cpluplus(nb_file, tmpdir, capsys): - nb_org = str(tmpdir.join(os.path.basename(nb_file))) - copyfile(nb_file, nb_org) +def test_to_cpluplus(ipynb_cpp_file, tmpdir, capsys): + nb_org = str(tmpdir.join(os.path.basename(ipynb_cpp_file))) + copyfile(ipynb_cpp_file, nb_org) nb1 = read(nb_org) text_cpp = writes(nb1, "cpp") @@ -139,12 +129,11 @@ def test_to_cpluplus(nb_file, tmpdir, capsys): compare(out, text_cpp) -@pytest.mark.parametrize("nb_files", [list_notebooks("ipynb_py")]) -def test_convert_multiple_file(nb_files, tmpdir): +def test_convert_multiple_file(ipynb_py_files, tmpdir): nb_orgs = [] nb_others = [] - for nb_file in nb_files: + for nb_file in ipynb_py_files: nb_org = str(tmpdir.join(os.path.basename(nb_file))) base, ext = os.path.splitext(nb_org) nb_other = base + ".py" @@ -309,13 +298,12 @@ def test_combine_lower_version_raises(tmpdir): jupytext([tmp_nbpy, "--to", "ipynb", "--update"]) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_ipynb_to_py_then_update_test(nb_file, tmpdir): +def test_ipynb_to_py_then_update_test(ipynb_py_file, tmpdir): """Reproduce https://github.com/mwouts/jupytext/issues/83""" tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_nbpy = str(tmpdir.join("notebook.py")) - copyfile(nb_file, tmp_ipynb) + copyfile(ipynb_py_file, tmp_ipynb) jupytext(["--to", "py", tmp_ipynb]) jupytext(["--test", "--update", "--to", "ipynb", tmp_nbpy]) @@ -350,12 +338,11 @@ def test_test_to_ipynb_ignore_version_number_414( assert jupytext(["--test", "--to", "ipynb", tmp_py]) == 0 -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_convert_to_percent_format(nb_file, tmpdir): +def test_convert_to_percent_format(ipynb_py_file, tmpdir): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_nbpy = str(tmpdir.join("notebook.py")) - copyfile(nb_file, tmp_ipynb) + copyfile(ipynb_py_file, tmp_ipynb) jupytext(["--to", "py:percent", tmp_ipynb]) @@ -369,12 +356,11 @@ def test_convert_to_percent_format(nb_file, tmpdir): compare_notebooks(nb2, nb1) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_convert_to_percent_format_and_keep_magics(nb_file, tmpdir): +def test_convert_to_percent_format_and_keep_magics(ipynb_py_file, tmpdir): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_nbpy = str(tmpdir.join("notebook.py")) - copyfile(nb_file, tmp_ipynb) + copyfile(ipynb_py_file, tmp_ipynb) jupytext(["--to", "py:percent", "--opt", "comment_magics=False", tmp_ipynb]) @@ -390,24 +376,22 @@ def test_convert_to_percent_format_and_keep_magics(nb_file, tmpdir): compare_notebooks(nb2, nb1) -@pytest.mark.parametrize("py_file", list_notebooks("python")) -def test_set_formats(py_file, tmpdir): +def test_set_formats(python_file, tmpdir): tmp_py = str(tmpdir.join("notebook.py")) tmp_ipynb = str(tmpdir.join("notebook.ipynb")) - copyfile(py_file, tmp_py) + copyfile(python_file, tmp_py) jupytext([tmp_py, "--set-formats", "ipynb,py:light"]) nb = read(tmp_ipynb) assert nb.metadata["jupytext"]["formats"] == "ipynb,py:light" -@pytest.mark.parametrize("py_file", list_notebooks("python")) -def test_update_metadata(py_file, tmpdir, capsys): +def test_update_metadata(python_file, tmpdir, capsys): tmp_py = str(tmpdir.join("notebook.py")) tmp_ipynb = str(tmpdir.join("notebook.ipynb")) - copyfile(py_file, tmp_py) + copyfile(python_file, tmp_py) jupytext( [ @@ -436,12 +420,11 @@ def test_update_metadata(py_file, tmpdir, capsys): assert "invalid" in err -@requires_user_kernel_python3 -@pytest.mark.parametrize("py_file", list_notebooks("python")) -def test_set_kernel_inplace(py_file, tmpdir): +@pytest.mark.requires_user_kernel_python3 +def test_set_kernel_inplace(python_file, tmpdir): tmp_py = str(tmpdir.join("notebook.py")) - copyfile(py_file, tmp_py) + copyfile(python_file, tmp_py) jupytext([tmp_py, "--set-kernel", "-"]) @@ -451,13 +434,12 @@ def test_set_kernel_inplace(py_file, tmpdir): assert cmd == "python" or os.path.samefile(cmd, sys.executable) -@requires_user_kernel_python3 -@pytest.mark.parametrize("py_file", list_notebooks("python")) -def test_set_kernel_auto(py_file, tmpdir): +@pytest.mark.requires_user_kernel_python3 +def test_set_kernel_auto(python_file, tmpdir): tmp_py = str(tmpdir.join("notebook.py")) tmp_ipynb = str(tmpdir.join("notebook.ipynb")) - copyfile(py_file, tmp_py) + copyfile(python_file, tmp_py) jupytext(["--to", "ipynb", tmp_py, "--set-kernel", "-"]) @@ -467,13 +449,12 @@ def test_set_kernel_auto(py_file, tmpdir): assert cmd == "python" or os.path.samefile(cmd, sys.executable) -@requires_user_kernel_python3 -@pytest.mark.parametrize("py_file", list_notebooks("python")) -def test_set_kernel_with_name(py_file, tmpdir): +@pytest.mark.requires_user_kernel_python3 +def test_set_kernel_with_name(python_file, tmpdir): tmp_py = str(tmpdir.join("notebook.py")) tmp_ipynb = str(tmpdir.join("notebook.ipynb")) - copyfile(py_file, tmp_py) + copyfile(python_file, tmp_py) for kernel in find_kernel_specs(): jupytext(["--to", "ipynb", tmp_py, "--set-kernel", kernel]) @@ -485,10 +466,9 @@ def test_set_kernel_with_name(py_file, tmpdir): jupytext(["--to", "ipynb", tmp_py, "--set-kernel", "non_existing_env"]) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_paired_paths(nb_file, tmpdir, capsys): +def test_paired_paths(ipynb_py_file, tmpdir, capsys): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) - nb = read(nb_file) + nb = read(ipynb_py_file) nb.metadata.setdefault("jupytext", {})[ "formats" ] = "ipynb,_light.py,_percent.py:percent" @@ -505,12 +485,11 @@ def test_paired_paths(nb_file, tmpdir, capsys): } -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_sync(nb_file, tmpdir, cwd_tmpdir, capsys): +def test_sync(ipynb_py_file, tmpdir, cwd_tmpdir, capsys): tmp_ipynb = "notebook.ipynb" tmp_py = "notebook.py" tmp_rmd = "notebook.Rmd" - nb = read(nb_file) + nb = read(ipynb_py_file) write(nb, tmp_ipynb) # Test that sync issues a warning when the notebook is not paired @@ -556,14 +535,11 @@ def test_sync(nb_file, tmpdir, cwd_tmpdir, capsys): assert os.path.getmtime(tmp_ipynb) <= os.path.getmtime(tmp_py) -@requires_pandoc -@pytest.mark.parametrize( - "nb_file", list_notebooks("ipynb_py", skip="(Notebook with|flavors|305)") -) -def test_sync_pandoc(nb_file, tmpdir, cwd_tmpdir, capsys): +@pytest.mark.requires_pandoc +def test_sync_pandoc(ipynb_to_pandoc, tmpdir, cwd_tmpdir, capsys): tmp_ipynb = "notebook.ipynb" tmp_md = "notebook.md" - nb = read(nb_file) + nb = read(ipynb_to_pandoc) write(nb, tmp_ipynb) # Test that sync issues a warning when the notebook is not paired @@ -585,16 +561,12 @@ def test_sync_pandoc(nb_file, tmpdir, cwd_tmpdir, capsys): assert "pandoc" in fp.read() -@pytest.mark.parametrize( - "nb_file,ext", - [(nb_file, ".py") for nb_file in list_notebooks("ipynb_py")] - + [(nb_file, ".R") for nb_file in list_notebooks("ipynb_R")] - + [(nb_file, ".jl") for nb_file in list_notebooks("ipynb_julia")], -) -def test_cli_can_infer_jupytext_format(nb_file, ext, tmpdir, cwd_tmpdir): +def test_cli_can_infer_jupytext_format( + ipynb_py_R_jl_file, ipynb_py_R_jl_ext, tmpdir, cwd_tmpdir +): tmp_ipynb = "notebook.ipynb" - tmp_text = "notebook" + ext - nb = read(nb_file) + tmp_text = "notebook" + ipynb_py_R_jl_ext + nb = read(ipynb_py_R_jl_file) # Light format to Jupyter notebook write(nb, tmp_text) @@ -603,21 +575,16 @@ def test_cli_can_infer_jupytext_format(nb_file, ext, tmpdir, cwd_tmpdir): compare_notebooks(nb2, nb) # Percent format to Jupyter notebook - write(nb, tmp_text, fmt=ext + ":percent") + write(nb, tmp_text, fmt=ipynb_py_R_jl_ext + ":percent") jupytext(["--to", "notebook", tmp_text]) nb2 = read(tmp_ipynb) compare_notebooks(nb2, nb) -@pytest.mark.parametrize( - "nb_file,ext", - [(nb_file, ".py") for nb_file in list_notebooks("ipynb_py")] - + [(nb_file, ".R") for nb_file in list_notebooks("ipynb_R")], -) -def test_cli_to_script(nb_file, ext, tmpdir, cwd_tmpdir): +def test_cli_to_script(ipynb_py_R_jl_file, ipynb_py_R_jl_ext, tmpdir, cwd_tmpdir): tmp_ipynb = "notebook.ipynb" - tmp_text = "notebook" + ext - nb = read(nb_file) + tmp_text = "notebook" + ipynb_py_R_jl_ext + nb = read(ipynb_py_R_jl_file) write(nb, tmp_ipynb) jupytext(["--to", "script", tmp_ipynb]) @@ -625,15 +592,10 @@ def test_cli_to_script(nb_file, ext, tmpdir, cwd_tmpdir): compare_notebooks(nb2, nb) -@pytest.mark.parametrize( - "nb_file,ext", - [(nb_file, ".py") for nb_file in list_notebooks("ipynb_py")] - + [(nb_file, ".R") for nb_file in list_notebooks("ipynb_R")], -) -def test_cli_to_auto(nb_file, ext, tmpdir, cwd_tmpdir): +def test_cli_to_auto(ipynb_py_R_jl_file, ipynb_py_R_jl_ext, tmpdir, cwd_tmpdir): tmp_ipynb = "notebook.ipynb" - tmp_text = "notebook" + ext - nb = read(nb_file) + tmp_text = "notebook" + ipynb_py_R_jl_ext + nb = read(ipynb_py_R_jl_file) write(nb, tmp_ipynb) jupytext(["--to", "auto", tmp_ipynb]) @@ -641,15 +603,14 @@ def test_cli_to_auto(nb_file, ext, tmpdir, cwd_tmpdir): compare_notebooks(nb2, nb) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_cli_can_infer_jupytext_format_from_stdin(nb_file, tmpdir, cwd_tmpdir): +def test_cli_can_infer_jupytext_format_from_stdin(ipynb_py_file, tmpdir, cwd_tmpdir): tmp_ipynb = "notebook.ipynb" tmp_py = "notebook.py" tmp_rmd = "notebook.Rmd" - nb = read(nb_file) + nb = read(ipynb_py_file) # read ipynb notebook on stdin, write to python - with open(nb_file) as fp, mock.patch("sys.stdin", fp): + with open(ipynb_py_file) as fp, mock.patch("sys.stdin", fp): jupytext(["--to", "py:percent", "-o", tmp_py]) nb2 = read(tmp_py) compare_notebooks(nb2, nb) @@ -661,7 +622,7 @@ def test_cli_can_infer_jupytext_format_from_stdin(nb_file, tmpdir, cwd_tmpdir): compare_notebooks(nb2, nb) # read ipynb notebook on stdin, write to R markdown - with open(nb_file) as fp, mock.patch("sys.stdin", fp): + with open(ipynb_py_file) as fp, mock.patch("sys.stdin", fp): jupytext(["-o", tmp_rmd]) nb2 = read(tmp_rmd) compare_notebooks(nb2, nb, "Rmd") @@ -673,7 +634,7 @@ def test_cli_can_infer_jupytext_format_from_stdin(nb_file, tmpdir, cwd_tmpdir): compare_notebooks(nb2, nb, "Rmd") -@requires_user_kernel_python3 +@pytest.mark.requires_user_kernel_python3 def test_set_kernel_works_with_pipes_326(capsys): md = """```python 1 + 1 @@ -688,25 +649,6 @@ def test_set_kernel_works_with_pipes_326(capsys): assert "kernelspec" in nb.metadata -@requires_user_kernel_python3 -@skip_on_windows -@pytest.mark.filterwarnings("ignore") -def test_utf8_out_331(capsys, caplog): - py = "from IPython.core.display import HTML; HTML(u'\xd7')" - - with mock.patch("sys.stdin", StringIO(py)): - jupytext(["--to", "ipynb", "--execute", "-"]) - - out, err = capsys.readouterr() - - assert err == "" - nb = reads(out, "ipynb") - assert len(nb.cells) == 1 - print(nb.cells[0].outputs) - assert nb.cells[0].outputs[0]["data"]["text/html"] == "\xd7" - - -@requires_jupytext_installed @pytest.mark.filterwarnings("ignore:The --pre-commit argument is deprecated") def test_cli_expect_errors(tmp_ipynb): with pytest.raises(ValueError): @@ -838,44 +780,6 @@ def test_cli_sync_file_with_prefix_974(tmp_path, python_notebook): assert (tmp_path / "examples/folder1/example_paired.py").exists(), "Paired" -@requires_sphinx_gallery -def test_rst2md(tmpdir, cwd_tmpdir): - tmp_py = "notebook.py" - tmp_ipynb = "notebook.ipynb" - - # Write notebook in sphinx format - nb = new_notebook( - cells=[ - new_markdown_cell("A short sphinx notebook"), - new_markdown_cell(":math:`1+1`"), - ] - ) - write(nb, tmp_py, fmt="py:sphinx") - - jupytext( - [ - tmp_py, - "--from", - "py:sphinx", - "--to", - "ipynb", - "--opt", - "rst2md=True", - "--opt", - "cell_metadata_filter=-all", - ] - ) - - assert os.path.isfile(tmp_ipynb) - nb = read(tmp_ipynb) - - assert nb.metadata["jupytext"]["cell_metadata_filter"] == "-all" - assert nb.metadata["jupytext"]["rst2md"] is False - - # Was rst to md conversion effective? - assert nb.cells[2].source == "$1+1$" - - def test_remove_jupytext_metadata(tmpdir, cwd_tmpdir): tmp_ipynb = "notebook.ipynb" nb = new_notebook( @@ -907,26 +811,25 @@ def test_remove_jupytext_metadata(tmpdir, cwd_tmpdir): } -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) @pytest.mark.parametrize("fmt", ["py:light", "py:percent", "md"]) -def test_convert_and_update_preserves_notebook(nb_file, fmt, tmpdir, cwd_tmpdir): +def test_convert_and_update_preserves_notebook(ipynb_py_file, fmt, tmpdir, cwd_tmpdir): # cannot encode magic parameters in markdown yet - if ("magic" in nb_file or "LateX" in nb_file) and fmt == "md": + if ("magic" in ipynb_py_file or "LateX" in ipynb_py_file) and fmt == "md": return tmp_ipynb = "notebook.ipynb" - copyfile(nb_file, tmp_ipynb) + copyfile(ipynb_py_file, tmp_ipynb) ext = long_form_one_format(fmt)["extension"] tmp_text = "notebook" + ext jupytext(["--to", fmt, tmp_ipynb]) jupytext(["--to", "ipynb", "--update", tmp_text]) - nb_org = read(nb_file) + nb_org = read(ipynb_py_file) nb_now = read(tmp_ipynb) # The cell marker changes from """ to r""" on the LateX notebook #836 - if "LateX" in nb_file and fmt == "py:percent": + if "LateX" in ipynb_py_file and fmt == "py:percent": last_cell = nb_now.cells[-1] last_cell.metadata["cell_marker"] = last_cell.metadata["cell_marker"][1:] @@ -1040,15 +943,10 @@ def test_set_format_with_subfolder(tmpdir, cwd_tmpdir): def skip_if_format_missing(format_name): """Check whether MyST or Pandoc are available and skip if not""" - if format_name == "md:myst": - mark = requires_myst() - elif format_name == "md:pandoc": - mark = requires_pandoc() - else: - return - - if mark.args[0]: - pytest.skip(**mark.kwargs) + if format_name == "md:myst" and not is_myst_available(): + pytest.skip("MyST markdown is not available") + elif format_name == "md:pandoc" and not is_pandoc_available(): + pytest.skip("Pandoc is not available") @pytest.mark.parametrize("format_name", ["md", "md:myst", "md:pandoc"]) @@ -1065,7 +963,7 @@ def test_create_header_with_set_formats(format_name, cwd_tmpdir, tmpdir): assert nb["metadata"]["jupytext"]["formats"] == format_name -@requires_user_kernel_python3 +@pytest.mark.requires_user_kernel_python3 @pytest.mark.parametrize( "format_name", ["md", "md:myst", "md:pandoc", "py:light", "py:percent"] ) @@ -1136,7 +1034,7 @@ def test_pair_in_tree_and_parent(tmpdir): assert "A markdown cell" in py_file.read() -@requires_pandoc +@pytest.mark.requires_pandoc def test_sync_pipe_config(tmpdir): """Sync a notebook to a script paired in a tree, and reformat the markdown cells using pandoc""" @@ -1256,26 +1154,6 @@ def test_show_changes(tmpdir, cwd_tmpdir, capsys): assert "-2 + 2\n+1 + 1" in captured.out -@requires_user_kernel_python3 -def test_skip_execution(tmpdir, cwd_tmpdir, tmp_repo, python_notebook, capsys): - write( - new_notebook(cells=[new_code_cell("1 + 1")], metadata=python_notebook.metadata), - "test.ipynb", - ) - tmp_repo.index.add("test.ipynb") - - jupytext(["--execute", "--pre-commit-mode", "test.ipynb"]) - captured = capsys.readouterr() - assert "Executing notebook" in captured.out - - nb = read("test.ipynb") - assert nb.cells[0].execution_count == 1 - - jupytext(["--execute", "--pre-commit-mode", "test.ipynb"]) - captured = capsys.readouterr() - assert "skipped" in captured.out - - def test_glob_recursive(tmpdir, cwd_tmpdir): tmpdir.mkdir("subfolder").join("test.py").write("1 + 1\n") tmpdir.join("test.py").write("2 + 2\n") diff --git a/tests/test_cli_config.py b/tests/functional/cli/test_cli_config.py similarity index 100% rename from tests/test_cli_config.py rename to tests/functional/cli/test_cli_config.py diff --git a/tests/test_config.py b/tests/functional/config/test_config.py similarity index 100% rename from tests/test_config.py rename to tests/functional/config/test_config.py diff --git a/tests/test_changelog.py b/tests/functional/docs/test_changelog.py similarity index 92% rename from tests/test_changelog.py rename to tests/functional/docs/test_changelog.py index 787a560e9..fd6a31af7 100644 --- a/tests/test_changelog.py +++ b/tests/functional/docs/test_changelog.py @@ -34,7 +34,7 @@ def test_replace_issue_numbers_with_links(input, output): sys.version_info < (3, 5), reason="'PosixPath' object has no attribute 'read_text'" ) def test_update_changelog(): - changelog_file = Path(__file__).parent.parent / "CHANGELOG.md" + changelog_file = Path(__file__).parent.parent.parent.parent / "CHANGELOG.md" cur_text = changelog_file.read_text() new_text = replace_issue_number_with_links(cur_text) if cur_text != new_text: diff --git a/tests/test_doc_files_are_notebooks.py b/tests/functional/docs/test_doc_files_are_notebooks.py similarity index 88% rename from tests/test_doc_files_are_notebooks.py rename to tests/functional/docs/test_doc_files_are_notebooks.py index bc2ed2492..12d436554 100644 --- a/tests/test_doc_files_are_notebooks.py +++ b/tests/functional/docs/test_doc_files_are_notebooks.py @@ -6,7 +6,7 @@ def documentation_files(): - for path in (Path(__file__).parent.parent / "docs").iterdir(): + for path in (Path(__file__).parent / "../../../docs").iterdir(): if path.suffix == ".md": yield path diff --git a/tests/test_metadata_filter.py b/tests/functional/metadata/test_metadata_filter.py similarity index 99% rename from tests/test_metadata_filter.py rename to tests/functional/metadata/test_metadata_filter.py index 05004df45..3438ee061 100644 --- a/tests/test_metadata_filter.py +++ b/tests/functional/metadata/test_metadata_filter.py @@ -8,8 +8,6 @@ from jupytext.compare import compare, compare_notebooks from jupytext.metadata_filter import filter_metadata, metadata_filter_as_dict -from .utils import requires_myst - def to_dict(keys): return {key: None for key in keys} @@ -175,7 +173,7 @@ def test_default_config_has_priority_over_current_metadata( ) -@requires_myst +@pytest.mark.requires_myst def test_metadata_filter_in_notebook_757(): md = """--- jupytext: diff --git a/tests/test_metadata_filters_from_config.py b/tests/functional/metadata/test_metadata_filters_from_config.py similarity index 100% rename from tests/test_metadata_filters_from_config.py rename to tests/functional/metadata/test_metadata_filters_from_config.py diff --git a/tests/invalid_file_896.md b/tests/functional/others/invalid_file_896.md similarity index 100% rename from tests/invalid_file_896.md rename to tests/functional/others/invalid_file_896.md diff --git a/tests/test_active_cells.py b/tests/functional/others/test_active_cells.py similarity index 100% rename from tests/test_active_cells.py rename to tests/functional/others/test_active_cells.py diff --git a/tests/test_auto_ext.py b/tests/functional/others/test_auto_ext.py similarity index 78% rename from tests/test_auto_ext.py rename to tests/functional/others/test_auto_ext.py index ef0debc7f..e427ce273 100644 --- a/tests/test_auto_ext.py +++ b/tests/functional/others/test_auto_ext.py @@ -3,14 +3,9 @@ from jupytext import read, reads, writes from jupytext.formats import JupytextFormatError, auto_ext_from_metadata -from .utils import list_notebooks - -@pytest.mark.parametrize( - "nb_file", list_notebooks("ipynb_R") + list_notebooks("ipynb_py") -) -def test_auto_in_fmt(nb_file): - nb = read(nb_file) +def test_auto_in_fmt(ipynb_py_R_file): + nb = read(ipynb_py_R_file) auto_ext = auto_ext_from_metadata(nb.metadata) fmt = auto_ext[1:] + ":percent" text = writes(nb, "auto:percent") @@ -27,9 +22,8 @@ def test_auto_in_fmt(nb_file): writes(nb, "auto:percent") -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_all")) -def test_auto_from_kernelspecs_works(nb_file): - nb = read(nb_file) +def test_auto_from_kernelspecs_works(ipynb_file): + nb = read(ipynb_file) language_info = nb.metadata.pop("language_info") expected_ext = language_info.get("file_extension") if not expected_ext: @@ -46,12 +40,10 @@ def test_auto_from_kernelspecs_works(nb_file): assert auto_ext == expected_ext -@pytest.mark.parametrize( - "nb_file", - list_notebooks("ipynb_R") + list_notebooks("ipynb_py", skip="(World|plotly)"), -) -def test_auto_in_formats(nb_file): - nb = read(nb_file) +def test_auto_in_formats(ipynb_py_R_jl_file): + if any(pattern in ipynb_py_R_jl_file for pattern in ["plotly", "julia"]): + pytest.skip() + nb = read(ipynb_py_R_jl_file) nb.metadata["jupytext"] = {"formats": "ipynb,auto:percent"} fmt = auto_ext_from_metadata(nb.metadata)[1:] + ":percent" expected_formats = "ipynb," + fmt diff --git a/tests/test_cell_markers.py b/tests/functional/others/test_cell_markers.py similarity index 100% rename from tests/test_cell_markers.py rename to tests/functional/others/test_cell_markers.py diff --git a/tests/test_cell_metadata.py b/tests/functional/others/test_cell_metadata.py similarity index 100% rename from tests/test_cell_metadata.py rename to tests/functional/others/test_cell_metadata.py diff --git a/tests/test_cell_tags_are_preserved.py b/tests/functional/others/test_cell_tags_are_preserved.py similarity index 91% rename from tests/test_cell_tags_are_preserved.py rename to tests/functional/others/test_cell_tags_are_preserved.py index 1c20e5b30..2069e40cf 100644 --- a/tests/test_cell_tags_are_preserved.py +++ b/tests/functional/others/test_cell_tags_are_preserved.py @@ -2,8 +2,7 @@ from nbformat.v4.nbbase import new_code_cell, new_markdown_cell from jupytext import reads, writes - -from .utils import formats_with_support_for_cell_metadata, is_myst_available +from jupytext.formats import formats_with_support_for_cell_metadata, is_myst_available @pytest.fixture() diff --git a/tests/test_cells.py b/tests/functional/others/test_cells.py similarity index 100% rename from tests/test_cells.py rename to tests/functional/others/test_cells.py diff --git a/tests/test_combine.py b/tests/functional/others/test_combine.py similarity index 96% rename from tests/test_combine.py rename to tests/functional/others/test_combine.py index bb658ac09..c801f8fba 100644 --- a/tests/test_combine.py +++ b/tests/functional/others/test_combine.py @@ -1,14 +1,11 @@ from copy import deepcopy -import pytest from nbformat.v4.nbbase import new_code_cell, new_markdown_cell, new_notebook import jupytext from jupytext.combine import combine_inputs_with_outputs from jupytext.compare import compare, compare_notebooks -from .utils import list_notebooks - def test_combine(): nb_source = new_notebook( @@ -133,9 +130,8 @@ def test_read_text_and_combine_with_outputs(tmpdir): assert len(nb.cells) == 3 -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_all")) -def test_combine_stable(nb_file): - nb_org = jupytext.read(nb_file) +def test_combine_stable(ipynb_file): + nb_org = jupytext.read(ipynb_file) nb_source = deepcopy(nb_org) nb_outputs = deepcopy(nb_org) diff --git a/tests/test_custom_cell_magics.py b/tests/functional/others/test_custom_cell_magics.py similarity index 100% rename from tests/test_custom_cell_magics.py rename to tests/functional/others/test_custom_cell_magics.py diff --git a/tests/test_doxygen.py b/tests/functional/others/test_doxygen.py similarity index 100% rename from tests/test_doxygen.py rename to tests/functional/others/test_doxygen.py diff --git a/tests/test_hide_remove_input_outputs_rmarkdown.py b/tests/functional/others/test_hide_remove_input_outputs_rmarkdown.py similarity index 100% rename from tests/test_hide_remove_input_outputs_rmarkdown.py rename to tests/functional/others/test_hide_remove_input_outputs_rmarkdown.py diff --git a/tests/test_invalid_file.py b/tests/functional/others/test_invalid_file.py similarity index 94% rename from tests/test_invalid_file.py rename to tests/functional/others/test_invalid_file.py index ba7cf8ec1..f40767291 100644 --- a/tests/test_invalid_file.py +++ b/tests/functional/others/test_invalid_file.py @@ -8,15 +8,13 @@ from jupytext import TextFileContentsManager, read from jupytext.cli import jupytext as jupytext_cli -from .utils import skip_on_windows - @pytest.fixture def invalid_md_file(): return Path(__file__).parent / "invalid_file_896.md" -@skip_on_windows +@pytest.mark.skip_on_windows def test_read_invalid_md_file_fails(invalid_md_file): with open(invalid_md_file) as fp: with pytest.raises(UnicodeDecodeError): diff --git a/tests/test_jupytext_errors.py b/tests/functional/others/test_jupytext_errors.py similarity index 100% rename from tests/test_jupytext_errors.py rename to tests/functional/others/test_jupytext_errors.py diff --git a/tests/test_jupytext_read.py b/tests/functional/others/test_jupytext_read.py similarity index 100% rename from tests/test_jupytext_read.py rename to tests/functional/others/test_jupytext_read.py diff --git a/tests/test_nbformat_version.py b/tests/functional/others/test_nbformat_version.py similarity index 100% rename from tests/test_nbformat_version.py rename to tests/functional/others/test_nbformat_version.py diff --git a/tests/test_preserve_empty_cells.py b/tests/functional/others/test_preserve_empty_cells.py similarity index 100% rename from tests/test_preserve_empty_cells.py rename to tests/functional/others/test_preserve_empty_cells.py diff --git a/tests/test_pytest.py b/tests/functional/others/test_pytest.py similarity index 100% rename from tests/test_pytest.py rename to tests/functional/others/test_pytest.py diff --git a/tests/test_raw_strings.py b/tests/functional/others/test_raw_strings.py similarity index 100% rename from tests/test_raw_strings.py rename to tests/functional/others/test_raw_strings.py diff --git a/tests/test_read_write_functions.py b/tests/functional/others/test_read_write_functions.py similarity index 100% rename from tests/test_read_write_functions.py rename to tests/functional/others/test_read_write_functions.py diff --git a/tests/test_remove_encoding.py b/tests/functional/others/test_remove_encoding.py similarity index 100% rename from tests/test_remove_encoding.py rename to tests/functional/others/test_remove_encoding.py diff --git a/tests/test_sample_notebooks_are_normalized.py b/tests/functional/others/test_sample_notebooks_are_normalized.py similarity index 61% rename from tests/test_sample_notebooks_are_normalized.py rename to tests/functional/others/test_sample_notebooks_are_normalized.py index 54c65fc40..573fe5d68 100644 --- a/tests/test_sample_notebooks_are_normalized.py +++ b/tests/functional/others/test_sample_notebooks_are_normalized.py @@ -3,19 +3,16 @@ import jupytext -from .utils import list_notebooks - @pytest.mark.skipif(nbformat.__version__ <= "5.7", reason="normalize is not available") -@pytest.mark.parametrize("nb_file", list_notebooks("all", skip="(invalid|pyc)")) -def test_sample_notebooks_are_normalized(nb_file): - nb = jupytext.read(nb_file) +def test_sample_notebooks_are_normalized(any_nb_file): + nb = jupytext.read(any_nb_file) changes, normalized_nb = nbformat.validator.normalize(nb) nbformat.validate(normalized_nb) if changes: # pragma: no cover - with open(nb_file, "w") as fp: + with open(any_nb_file, "w") as fp: jupytext.write(normalized_nb, fp) assert not changes diff --git a/tests/test_save_multiple.py b/tests/functional/others/test_save_multiple.py similarity index 85% rename from tests/test_save_multiple.py rename to tests/functional/others/test_save_multiple.py index 0a7fb62c0..0e23c79c3 100644 --- a/tests/test_save_multiple.py +++ b/tests/functional/others/test_save_multiple.py @@ -6,15 +6,12 @@ from tornado.web import HTTPError import jupytext -from jupytext.compare import compare_notebooks +from jupytext.compare import compare_notebooks, notebook_model from jupytext.contentsmanager import TextFileContentsManager -from .utils import list_notebooks, notebook_model - -@pytest.mark.parametrize("nb_file", list_notebooks(skip="66")) -def test_rmd_is_ok(nb_file, tmpdir): - nb = jupytext.read(nb_file) +def test_rmd_is_ok(ipynb_file, tmpdir): + nb = jupytext.read(ipynb_file) tmp_ipynb = "notebook.ipynb" tmp_rmd = "notebook.Rmd" @@ -30,9 +27,8 @@ def test_rmd_is_ok(nb_file, tmpdir): compare_notebooks(nb2, nb, "Rmd") -@pytest.mark.parametrize("nb_file", list_notebooks("Rmd")) -def test_ipynb_is_ok(nb_file, tmpdir): - nb = jupytext.read(nb_file) +def test_ipynb_is_ok(rmd_file, tmpdir): + nb = jupytext.read(rmd_file) tmp_ipynb = "notebook.ipynb" tmp_rmd = "notebook.Rmd" @@ -46,9 +42,8 @@ def test_ipynb_is_ok(nb_file, tmpdir): compare_notebooks(nb2, nb) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py", skip="66")) -def test_all_files_created(nb_file, tmpdir): - nb = jupytext.read(nb_file) +def test_all_files_created(ipynb_py_file, tmpdir): + nb = jupytext.read(ipynb_py_file) tmp_ipynb = "notebook.ipynb" tmp_rmd = "notebook.Rmd" tmp_py = "notebook.py" diff --git a/tests/test_trust_notebook.py b/tests/functional/others/test_trust_notebook.py similarity index 82% rename from tests/test_trust_notebook.py rename to tests/functional/others/test_trust_notebook.py index 1a2b7c13b..05c4b24a8 100644 --- a/tests/test_trust_notebook.py +++ b/tests/functional/others/test_trust_notebook.py @@ -7,37 +7,36 @@ from jupytext.compare import compare_notebooks from jupytext.contentsmanager import TextFileContentsManager -from .utils import list_notebooks, requires_myst - -@pytest.mark.parametrize("nb_file", list_notebooks("python")) -def test_py_notebooks_are_trusted(nb_file): +def test_py_notebooks_are_trusted(python_file): cm = TextFileContentsManager() - root, file = os.path.split(nb_file) + root, file = os.path.split(python_file) cm.root_dir = root nb = cm.get(file) for cell in nb["content"].cells: assert cell.metadata.get("trusted", True) -@pytest.mark.parametrize("nb_file", list_notebooks("Rmd")) -def test_rmd_notebooks_are_trusted(nb_file): +def test_rmd_notebooks_are_trusted(rmd_file): cm = TextFileContentsManager() - root, file = os.path.split(nb_file) + root, file = os.path.split(rmd_file) cm.root_dir = root nb = cm.get(file) for cell in nb["content"].cells: assert cell.metadata.get("trusted", True) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py", skip="hash sign")) -def test_ipynb_notebooks_can_be_trusted(nb_file, tmpdir, no_jupytext_version_number): +def test_ipynb_notebooks_can_be_trusted( + ipynb_py_file, tmpdir, no_jupytext_version_number +): + if "hash sign" in ipynb_py_file: + pytest.skip() cm = TextFileContentsManager() - root, file = os.path.split(nb_file) + root, file = os.path.split(ipynb_py_file) tmp_ipynb = str(tmpdir.join(file)) py_file = file.replace(".ipynb", ".py") tmp_py = str(tmpdir.join(py_file)) - shutil.copy(nb_file, tmp_ipynb) + shutil.copy(ipynb_py_file, tmp_ipynb) cm.formats = "ipynb,py" cm.root_dir = str(tmpdir) @@ -78,16 +77,17 @@ def test_ipynb_notebooks_can_be_trusted(nb_file, tmpdir, no_jupytext_version_num cm.trust_notebook(file) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py", skip="hash sign")) def test_ipynb_notebooks_can_be_trusted_even_with_metadata_filter( - nb_file, tmpdir, no_jupytext_version_number + ipynb_py_file, tmpdir, no_jupytext_version_number ): + if "hash sign" in ipynb_py_file: + pytest.skip() cm = TextFileContentsManager() - root, file = os.path.split(nb_file) + root, file = os.path.split(ipynb_py_file) tmp_ipynb = str(tmpdir.join(file)) py_file = file.replace(".ipynb", ".py") tmp_py = str(tmpdir.join(py_file)) - shutil.copy(nb_file, tmp_ipynb) + shutil.copy(ipynb_py_file, tmp_ipynb) cm.formats = "ipynb,py" cm.notebook_metadata_filter = "all" @@ -119,12 +119,13 @@ def test_ipynb_notebooks_can_be_trusted_even_with_metadata_filter( compare_notebooks(nb2["content"], model["content"]) -@pytest.mark.parametrize("nb_file", list_notebooks("percent", skip="hash sign")) -def test_text_notebooks_can_be_trusted(nb_file, tmpdir, no_jupytext_version_number): +def test_text_notebooks_can_be_trusted( + percent_file, tmpdir, no_jupytext_version_number +): cm = TextFileContentsManager() - root, file = os.path.split(nb_file) + root, file = os.path.split(percent_file) py_file = str(tmpdir.join(file)) - shutil.copy(nb_file, py_file) + shutil.copy(percent_file, py_file) cm.root_dir = str(tmpdir) model = cm.get(file) @@ -166,7 +167,7 @@ def test_simple_notebook_is_trusted(tmpdir, python_notebook): assert cm.notary.check_signature(nb) -@requires_myst +@pytest.mark.requires_myst def test_myst_notebook_is_trusted_941( tmp_path, myst="""--- @@ -204,7 +205,7 @@ def test_myst_notebook_is_trusted_941( assert cm.notary.check_cells(nb) -@requires_myst +@pytest.mark.requires_myst def test_paired_notebook_with_outputs_is_not_trusted_941(tmp_path, python_notebook): cm = TextFileContentsManager() cm.root_dir = str(tmp_path) diff --git a/tests/test_unicode.py b/tests/functional/others/test_unicode.py similarity index 91% rename from tests/test_unicode.py rename to tests/functional/others/test_unicode.py index 81ef043e1..0dbc632a0 100644 --- a/tests/test_unicode.py +++ b/tests/functional/others/test_unicode.py @@ -1,15 +1,18 @@ -import pytest from nbformat.v4.nbbase import new_markdown_cell, new_notebook import jupytext from jupytext.compare import compare -from .utils import list_notebooks +def test_notebook_contents_is_unicode(ipynb_file): + nb = jupytext.read(ipynb_file) -@pytest.mark.parametrize("nb_file", list_notebooks() + list_notebooks("Rmd")) -def test_notebook_contents_is_unicode(nb_file): - nb = jupytext.read(nb_file) + for cell in nb.cells: + assert isinstance(cell.source, str) + + +def test_rmd_notebook_contents_is_unicode(rmd_file): + nb = jupytext.read(rmd_file) for cell in nb.cells: assert isinstance(cell.source, str) diff --git a/tests/test_write_does_not_modify_notebook.py b/tests/functional/others/test_write_does_not_modify_notebook.py similarity index 59% rename from tests/test_write_does_not_modify_notebook.py rename to tests/functional/others/test_write_does_not_modify_notebook.py index 3e1873a57..76948a81a 100644 --- a/tests/test_write_does_not_modify_notebook.py +++ b/tests/functional/others/test_write_does_not_modify_notebook.py @@ -1,5 +1,4 @@ from copy import deepcopy -from itertools import product import pytest @@ -7,18 +6,13 @@ from jupytext.compare import compare from jupytext.formats import long_form_one_format -from .utils import list_notebooks - @pytest.mark.parametrize( - "nb_file,fmt", - product( - list_notebooks("ipynb_py") + list_notebooks("ipynb_R"), - ["auto:light", "auto:percent", "md", ".Rmd", ".ipynb"], - ), + "fmt", + ["auto:light", "auto:percent", "md", ".Rmd", ".ipynb"], ) -def test_write_notebook_does_not_change_it(nb_file, fmt, tmpdir): - nb_org = read(nb_file) +def test_write_notebook_does_not_change_it(ipynb_py_R_jl_file, fmt, tmpdir): + nb_org = read(ipynb_py_R_jl_file) nb_org_copied = deepcopy(nb_org) ext = long_form_one_format(fmt, nb_org.metadata)["extension"] diff --git a/tests/test_jupytext_nbconvert_round_trip.py b/tests/functional/round_trip/test_jupytext_nbconvert_round_trip.py similarity index 89% rename from tests/test_jupytext_nbconvert_round_trip.py rename to tests/functional/round_trip/test_jupytext_nbconvert_round_trip.py index 4bd6022d6..e259df7a0 100644 --- a/tests/test_jupytext_nbconvert_round_trip.py +++ b/tests/functional/round_trip/test_jupytext_nbconvert_round_trip.py @@ -3,14 +3,13 @@ import jupytext from jupytext.header import header_to_metadata_and_cell -from .utils import list_notebooks, requires_nbconvert - -@requires_nbconvert -@pytest.mark.parametrize("md_file", list_notebooks("md", skip="jupytext")) +@pytest.mark.requires_nbconvert def test_markdown_jupytext_nbconvert_is_identity(md_file): """Test that a Markdown file, converted to a notebook, then exported back to Markdown with nbconvert, yields the original file""" + if "jupytext" in md_file: + pytest.skip() with open(md_file) as fp: md_org = fp.read() @@ -39,12 +38,13 @@ def test_markdown_jupytext_nbconvert_is_identity(md_file): jupytext.compare.compare(md_nbconvert, md_expected) -@requires_nbconvert -@pytest.mark.parametrize("nb_file", list_notebooks(skip="(html|magic)")) -def test_jupytext_markdown_similar_to_nbconvert(nb_file): +@pytest.mark.requires_nbconvert +def test_jupytext_markdown_similar_to_nbconvert(ipynb_py_R_jl_file): """Test that the nbconvert export for a notebook matches Jupytext's one""" + if "magic" in ipynb_py_R_jl_file or "html" in ipynb_py_R_jl_file: + pytest.skip() - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) # Remove cell outputs and metadata for cell in nb.cells: diff --git a/tests/functional/round_trip/test_mirror.py b/tests/functional/round_trip/test_mirror.py new file mode 100644 index 000000000..8a04f75be --- /dev/null +++ b/tests/functional/round_trip/test_mirror.py @@ -0,0 +1,159 @@ +"""Here we generate mirror representation of py, Rmd and ipynb files +as py or ipynb, and make sure that these representations minimally +change on new releases. +""" + +import os +import re + +import pytest +from nbformat.v4.nbbase import new_notebook + +import jupytext +from jupytext.compare import ( + assert_conversion_same_as_mirror, + compare_notebooks, + create_mirror_file_if_missing, +) +from jupytext.formats import auto_ext_from_metadata +from jupytext.languages import _SCRIPT_EXTENSIONS + + +def test_create_mirror_file_if_missing(tmpdir, no_jupytext_version_number): + py_file = str(tmpdir.join("notebook.py")) + assert not os.path.isfile(py_file) + create_mirror_file_if_missing(py_file, new_notebook(), "py") + assert os.path.isfile(py_file) + + +"""--------------------------------------------------------------------------------- + +Part I: ipynb -> fmt -> ipynb + +---------------------------------------------------------------------------------""" + + +def test_ipynb_to_percent(ipynb_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_file, "auto:percent", "ipynb_to_percent") + + +def test_ipynb_to_hydrogen(ipynb_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_file, "auto:hydrogen", "ipynb_to_hydrogen") + + +def test_ipynb_to_light(ipynb_to_light, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_to_light, "auto", "ipynb_to_script") + + +def test_ipynb_to_md(ipynb_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_file, "md", "ipynb_to_md") + + +def test_ipynb_to_Rmd(ipynb_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_file, "Rmd", "ipynb_to_Rmd") + + +@pytest.mark.requires_myst +def test_ipynb_to_myst(ipynb_file, no_jupytext_version_number): + if re.match( + r".*(html-demo|julia_functional_geometry|xcpp_by_quantstack).*", ipynb_file + ): + pytest.skip() + assert_conversion_same_as_mirror(ipynb_file, "md:myst", "ipynb_to_myst") + + +"""--------------------------------------------------------------------------------- + +Part II: text -> ipynb -> text + +---------------------------------------------------------------------------------""" + + +def test_script_to_ipynb(script_to_ipynb, no_jupytext_version_number): + assert_conversion_same_as_mirror(script_to_ipynb, "ipynb", "script_to_ipynb") + + +def test_percent_to_ipynb(percent_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(percent_file, "ipynb:percent", "script_to_ipynb") + + +def test_hydrogen_to_ipynb(hydrogen_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(hydrogen_file, "ipynb:hydrogen", "script_to_ipynb") + + +def test_spin_to_ipynb(r_spin_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(r_spin_file, "ipynb:spin", "script_to_ipynb") + + +def test_md_to_ipynb(md_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(md_file, "ipynb", "md_to_ipynb") + + +"""--------------------------------------------------------------------------------- + +Part III: More specific round trip tests + +---------------------------------------------------------------------------------""" + + +def test_ipynb_to_percent_to_light(ipynb_file): + nb = jupytext.read(ipynb_file) + pct = jupytext.writes(nb, "auto:percent") + auto_ext = auto_ext_from_metadata(nb.metadata) + comment = _SCRIPT_EXTENSIONS[auto_ext]["comment"] + lgt = ( + pct.replace(comment + " %%\n", comment + " +\n") + .replace(comment + " %% ", comment + " + ") + .replace( + comment + " format_name: percent", + comment + " format_name: light", + ) + ) + nb2 = jupytext.reads(lgt, auto_ext) + compare_notebooks(nb2, nb) + + +def test_ipynb_to_python_vim(ipynb_py_file, no_jupytext_version_number): + assert_conversion_same_as_mirror( + ipynb_py_file, + {"extension": ".py", "cell_markers": "{{{,}}}"}, + "ipynb_to_script_vim_folding_markers", + ) + + +def test_ipynb_to_python_vscode(ipynb_py_file, no_jupytext_version_number): + assert_conversion_same_as_mirror( + ipynb_py_file, + {"extension": ".py", "cell_markers": "region,endregion"}, + "ipynb_to_script_vscode_folding_markers", + ) + + +def test_ipynb_to_r(ipynb_R_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_R_file, ".low.r", "ipynb_to_script") + + +def test_ipynb_to_r_percent(ipynb_R_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_R_file, ".low.r:percent", "ipynb_to_percent") + + +def test_ipynb_to_R_spin(ipynb_R_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_R_file, "R", "ipynb_to_spin") + + +def test_ipynb_to_r_spin(ipynb_R_file, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_R_file, ".low.r", "ipynb_to_spin") + + +@pytest.mark.parametrize("extension", ("ss", "scm")) +def test_ipynb_to_scheme(ipynb_scheme_file, extension, no_jupytext_version_number): + assert_conversion_same_as_mirror(ipynb_scheme_file, extension, "ipynb_to_script") + + +@pytest.mark.parametrize("extension", ("ss", "scm")) +def test_ipynb_to_scheme_percent( + ipynb_scheme_file, extension, no_jupytext_version_number +): + assert_conversion_same_as_mirror( + ipynb_scheme_file, f"{extension}:percent", "ipynb_to_percent" + ) diff --git a/tests/functional/round_trip/test_read_all_py.py b/tests/functional/round_trip/test_read_all_py.py new file mode 100644 index 000000000..c7e564f78 --- /dev/null +++ b/tests/functional/round_trip/test_read_all_py.py @@ -0,0 +1,12 @@ +import jupytext +from jupytext.compare import compare + + +def test_identity_source_write_read(py_file): + with open(py_file) as fp: + py = fp.read() + + nb = jupytext.reads(py, "py") + py2 = jupytext.writes(nb, "py") + + compare(py2, py) diff --git a/tests/test_rmd_to_ipynb.py b/tests/functional/round_trip/test_rmd_to_ipynb.py similarity index 75% rename from tests/test_rmd_to_ipynb.py rename to tests/functional/round_trip/test_rmd_to_ipynb.py index 8a8d237cc..2167f8e99 100644 --- a/tests/test_rmd_to_ipynb.py +++ b/tests/functional/round_trip/test_rmd_to_ipynb.py @@ -1,16 +1,11 @@ -import pytest - import jupytext from jupytext.compare import compare -from .utils import list_notebooks - -@pytest.mark.parametrize("nb_file", list_notebooks("Rmd")) -def test_identity_write_read(nb_file, no_jupytext_version_number): +def test_identity_write_read(rmd_file, no_jupytext_version_number): """Test that writing the notebook with ipynb, and read again, yields identity""" - with open(nb_file) as fp: + with open(rmd_file) as fp: rmd = fp.read() nb = jupytext.reads(rmd, "Rmd") diff --git a/tests/test_ipynb_to_R.py b/tests/functional/simple_notebooks/test_ipynb_to_R.py similarity index 59% rename from tests/test_ipynb_to_R.py rename to tests/functional/simple_notebooks/test_ipynb_to_R.py index b7be46ed6..b14451606 100644 --- a/tests/test_ipynb_to_R.py +++ b/tests/functional/simple_notebooks/test_ipynb_to_R.py @@ -1,24 +1,18 @@ -import itertools - import nbformat import pytest import jupytext from jupytext.compare import compare_notebooks -from .utils import list_notebooks - -@pytest.mark.parametrize( - "nb_file,ext", itertools.product(list_notebooks("ipynb_R"), [".r", ".R"]) -) -def test_identity_source_write_read(nb_file, ext): +@pytest.mark.parametrize("ext", [".r", ".R"]) +def test_identity_source_write_read(ipynb_R_file, ext): """ Test that writing the notebook with R, and read again, is the same as removing outputs """ - with open(nb_file) as fp: + with open(ipynb_R_file) as fp: nb1 = nbformat.read(fp, as_version=4) R = jupytext.writes(nb1, ext) diff --git a/tests/test_ipynb_to_myst.py b/tests/functional/simple_notebooks/test_ipynb_to_myst.py similarity index 96% rename from tests/test_ipynb_to_myst.py rename to tests/functional/simple_notebooks/test_ipynb_to_myst.py index 8786a1aeb..0a8551445 100644 --- a/tests/test_ipynb_to_myst.py +++ b/tests/functional/simple_notebooks/test_ipynb_to_myst.py @@ -22,10 +22,8 @@ myst_to_notebook, ) -from .utils import requires_myst, requires_no_myst - -@requires_myst +@pytest.mark.requires_myst def test_bad_notebook_metadata(): """Test exception raised if notebook metadata cannot be parsed.""" with pytest.raises(MystMetadataParsingError): @@ -40,7 +38,7 @@ def test_bad_notebook_metadata(): ) -@requires_myst +@pytest.mark.requires_myst def test_bad_code_metadata(): """Test exception raised if cell metadata cannot be parsed.""" with pytest.raises(MystMetadataParsingError): @@ -57,7 +55,7 @@ def test_bad_code_metadata(): ) -@requires_myst +@pytest.mark.requires_myst def test_bad_markdown_metadata(): """Test exception raised if markdown metadata cannot be parsed.""" with pytest.raises(MystMetadataParsingError): @@ -70,7 +68,7 @@ def test_bad_markdown_metadata(): ) -@requires_myst +@pytest.mark.requires_myst def test_bad_markdown_metadata2(): """Test exception raised if markdown metadata is not a dict.""" with pytest.raises(MystMetadataParsingError): @@ -83,7 +81,7 @@ def test_bad_markdown_metadata2(): ) -@requires_myst +@pytest.mark.requires_myst def test_matches_mystnb(): assert matches_mystnb("") is False assert matches_mystnb("```{code-cell}\n```") is False @@ -131,7 +129,7 @@ def test_not_installed(): get_format_implementation(".myst") -@requires_myst +@pytest.mark.requires_myst def test_add_source_map(): notebook = myst_to_notebook( dedent( @@ -159,7 +157,7 @@ def test_add_source_map(): PLEASE_INSTALL_MYST = "The MyST Markdown format requires .*" -@requires_no_myst +@pytest.mark.requires_no_myst def test_meaningfull_error_write_myst_missing(tmpdir): nb_file = tmpdir.join("notebook.ipynb") jupytext.write(new_notebook(), str(nb_file)) @@ -168,7 +166,7 @@ def test_meaningfull_error_write_myst_missing(tmpdir): jupytext_cli([str(nb_file), "--to", "md:myst"]) -@requires_no_myst +@pytest.mark.requires_no_myst def test_meaningfull_error_open_myst_missing(tmpdir): md_file = tmpdir.join("notebook.md") md_file.write( @@ -197,7 +195,7 @@ def test_meaningfull_error_open_myst_missing(tmpdir): cm.get("notebook.md") -@requires_myst +@pytest.mark.requires_myst @pytest.mark.parametrize("language_info", ["none", "std", "no_pygments_lexer"]) def test_myst_representation_same_cli_or_contents_manager( tmpdir, cwd_tmpdir, notebook_with_outputs, language_info diff --git a/tests/test_ipynb_to_py.py b/tests/functional/simple_notebooks/test_ipynb_to_py.py similarity index 64% rename from tests/test_ipynb_to_py.py rename to tests/functional/simple_notebooks/test_ipynb_to_py.py index 7a0915d7f..b46800189 100644 --- a/tests/test_ipynb_to_py.py +++ b/tests/functional/simple_notebooks/test_ipynb_to_py.py @@ -1,18 +1,14 @@ import nbformat -import pytest import jupytext from jupytext.compare import compare_notebooks -from .utils import list_notebooks - -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_identity_source_write_read(nb_file): +def test_identity_source_write_read(ipynb_py_file): """Test that writing the notebook with jupytext, and read again, is the same as removing outputs""" - with open(nb_file) as fp: + with open(ipynb_py_file) as fp: nb1 = nbformat.read(fp, as_version=4) py = jupytext.writes(nb1, "py") diff --git a/tests/test_ipynb_to_rmd.py b/tests/functional/simple_notebooks/test_ipynb_to_rmd.py similarity index 64% rename from tests/test_ipynb_to_rmd.py rename to tests/functional/simple_notebooks/test_ipynb_to_rmd.py index 5d61a6a61..e8e7bf5bf 100644 --- a/tests/test_ipynb_to_rmd.py +++ b/tests/functional/simple_notebooks/test_ipynb_to_rmd.py @@ -1,18 +1,14 @@ import nbformat -import pytest import jupytext from jupytext.compare import compare_notebooks -from .utils import list_notebooks - -@pytest.mark.parametrize("nb_file", list_notebooks(skip="66")) -def test_identity_source_write_read(nb_file): +def test_identity_source_write_read(ipynb_py_R_jl_file): """Test that writing the notebook with rmd, and read again, is the same as removing outputs""" - with open(nb_file) as fp: + with open(ipynb_py_R_jl_file) as fp: nb1 = nbformat.read(fp, as_version=4) rmd = jupytext.writes(nb1, "Rmd") diff --git a/tests/functional/simple_notebooks/test_knitr_spin.py b/tests/functional/simple_notebooks/test_knitr_spin.py new file mode 100644 index 000000000..579a67055 --- /dev/null +++ b/tests/functional/simple_notebooks/test_knitr_spin.py @@ -0,0 +1,14 @@ +import jupytext + + +def test_jupytext_same_as_knitr_spin(r_spin_file, tmpdir): + nb = jupytext.read(r_spin_file) + rmd_jupytext = jupytext.writes(nb, "Rmd") + + # Rmd file generated with spin(hair='R/spin.R', knit=FALSE) + rmd_file = r_spin_file.replace("R_spin", "Rmd").replace(".R", ".Rmd") + + with open(rmd_file) as fp: + rmd_spin = fp.read() + + assert rmd_spin == rmd_jupytext diff --git a/tests/test_read_dotnet_try_markdown.py b/tests/functional/simple_notebooks/test_read_dotnet_try_markdown.py similarity index 100% rename from tests/test_read_dotnet_try_markdown.py rename to tests/functional/simple_notebooks/test_read_dotnet_try_markdown.py diff --git a/tests/test_read_empty_text_notebook.py b/tests/functional/simple_notebooks/test_read_empty_text_notebook.py similarity index 85% rename from tests/test_read_empty_text_notebook.py rename to tests/functional/simple_notebooks/test_read_empty_text_notebook.py index e931dfa00..e134e1c97 100644 --- a/tests/test_read_empty_text_notebook.py +++ b/tests/functional/simple_notebooks/test_read_empty_text_notebook.py @@ -3,9 +3,8 @@ import jupytext from jupytext.formats import NOTEBOOK_EXTENSIONS -from jupytext.myst import myst_extensions - -from .utils import is_myst_available, is_quarto_available +from jupytext.myst import is_myst_available, myst_extensions +from jupytext.quarto import is_quarto_available @pytest.mark.parametrize("ext", sorted(set(NOTEBOOK_EXTENSIONS) - {".ipynb"})) diff --git a/tests/test_read_folding_markers.py b/tests/functional/simple_notebooks/test_read_folding_markers.py similarity index 100% rename from tests/test_read_folding_markers.py rename to tests/functional/simple_notebooks/test_read_folding_markers.py diff --git a/tests/test_read_incomplete_rmd.py b/tests/functional/simple_notebooks/test_read_incomplete_rmd.py similarity index 100% rename from tests/test_read_incomplete_rmd.py rename to tests/functional/simple_notebooks/test_read_incomplete_rmd.py diff --git a/tests/test_read_simple_R.py b/tests/functional/simple_notebooks/test_read_simple_R.py similarity index 100% rename from tests/test_read_simple_R.py rename to tests/functional/simple_notebooks/test_read_simple_R.py diff --git a/tests/test_read_simple_clojure.py b/tests/functional/simple_notebooks/test_read_simple_clojure.py similarity index 100% rename from tests/test_read_simple_clojure.py rename to tests/functional/simple_notebooks/test_read_simple_clojure.py diff --git a/tests/test_read_simple_csharp.py b/tests/functional/simple_notebooks/test_read_simple_csharp.py similarity index 100% rename from tests/test_read_simple_csharp.py rename to tests/functional/simple_notebooks/test_read_simple_csharp.py diff --git a/tests/test_read_simple_groovy.py b/tests/functional/simple_notebooks/test_read_simple_groovy.py similarity index 100% rename from tests/test_read_simple_groovy.py rename to tests/functional/simple_notebooks/test_read_simple_groovy.py diff --git a/tests/test_read_simple_hydrogen.py b/tests/functional/simple_notebooks/test_read_simple_hydrogen.py similarity index 100% rename from tests/test_read_simple_hydrogen.py rename to tests/functional/simple_notebooks/test_read_simple_hydrogen.py diff --git a/tests/test_read_simple_ipynb.py b/tests/functional/simple_notebooks/test_read_simple_ipynb.py similarity index 100% rename from tests/test_read_simple_ipynb.py rename to tests/functional/simple_notebooks/test_read_simple_ipynb.py diff --git a/tests/test_read_simple_java.py b/tests/functional/simple_notebooks/test_read_simple_java.py similarity index 100% rename from tests/test_read_simple_java.py rename to tests/functional/simple_notebooks/test_read_simple_java.py diff --git a/tests/test_read_simple_julia.py b/tests/functional/simple_notebooks/test_read_simple_julia.py similarity index 100% rename from tests/test_read_simple_julia.py rename to tests/functional/simple_notebooks/test_read_simple_julia.py diff --git a/tests/test_read_simple_markdown.py b/tests/functional/simple_notebooks/test_read_simple_markdown.py similarity index 100% rename from tests/test_read_simple_markdown.py rename to tests/functional/simple_notebooks/test_read_simple_markdown.py diff --git a/tests/test_read_simple_matlab.py b/tests/functional/simple_notebooks/test_read_simple_matlab.py similarity index 100% rename from tests/test_read_simple_matlab.py rename to tests/functional/simple_notebooks/test_read_simple_matlab.py diff --git a/tests/test_read_simple_nomarker.py b/tests/functional/simple_notebooks/test_read_simple_nomarker.py similarity index 100% rename from tests/test_read_simple_nomarker.py rename to tests/functional/simple_notebooks/test_read_simple_nomarker.py diff --git a/tests/test_read_simple_ocaml.py b/tests/functional/simple_notebooks/test_read_simple_ocaml.py similarity index 100% rename from tests/test_read_simple_ocaml.py rename to tests/functional/simple_notebooks/test_read_simple_ocaml.py diff --git a/tests/test_read_simple_percent.py b/tests/functional/simple_notebooks/test_read_simple_percent.py similarity index 99% rename from tests/test_read_simple_percent.py rename to tests/functional/simple_notebooks/test_read_simple_percent.py index 357a443ba..eea25a5cd 100644 --- a/tests/test_read_simple_percent.py +++ b/tests/functional/simple_notebooks/test_read_simple_percent.py @@ -9,9 +9,7 @@ ) import jupytext -from jupytext.compare import compare, compare_notebooks - -from .utils import notebook_model +from jupytext.compare import compare, compare_notebooks, notebook_model def test_read_simple_file( diff --git a/tests/test_read_simple_python.py b/tests/functional/simple_notebooks/test_read_simple_python.py similarity index 100% rename from tests/test_read_simple_python.py rename to tests/functional/simple_notebooks/test_read_simple_python.py diff --git a/tests/test_read_simple_rmd.py b/tests/functional/simple_notebooks/test_read_simple_rmd.py similarity index 100% rename from tests/test_read_simple_rmd.py rename to tests/functional/simple_notebooks/test_read_simple_rmd.py diff --git a/tests/test_read_simple_rust.py b/tests/functional/simple_notebooks/test_read_simple_rust.py similarity index 100% rename from tests/test_read_simple_rust.py rename to tests/functional/simple_notebooks/test_read_simple_rust.py diff --git a/tests/test_read_simple_scheme.py b/tests/functional/simple_notebooks/test_read_simple_scheme.py similarity index 100% rename from tests/test_read_simple_scheme.py rename to tests/functional/simple_notebooks/test_read_simple_scheme.py diff --git a/tests/test_read_simple_sphinx.py b/tests/functional/simple_notebooks/test_read_simple_sphinx.py similarity index 100% rename from tests/test_read_simple_sphinx.py rename to tests/functional/simple_notebooks/test_read_simple_sphinx.py diff --git a/tests/test_execute.py b/tests/integration/cli/test_execute.py similarity index 81% rename from tests/test_execute.py rename to tests/integration/cli/test_execute.py index b1c65fb53..3b53e3185 100644 --- a/tests/test_execute.py +++ b/tests/integration/cli/test_execute.py @@ -1,23 +1,17 @@ import shutil +from io import StringIO from unittest import mock import pytest -from jupytext import read +from jupytext import read, reads from jupytext.cli import jupytext from jupytext.version import __version__ -from .utils import ( - requires_ir_kernel, - requires_nbconvert, - requires_user_kernel_python3, - skip_on_windows, -) - -@requires_user_kernel_python3 -@requires_nbconvert -@skip_on_windows +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert +@pytest.mark.skip_on_windows def test_pipe_nbconvert_execute(tmpdir): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_py = str(tmpdir.join("notebook.py")) @@ -45,9 +39,9 @@ def test_pipe_nbconvert_execute(tmpdir): assert nb.cells[0].outputs[0]["data"] == {"text/plain": "3"} -@requires_user_kernel_python3 -@requires_nbconvert -@skip_on_windows +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert +@pytest.mark.skip_on_windows def test_pipe_nbconvert_execute_sync(tmpdir): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_py = str(tmpdir.join("notebook.py")) @@ -76,9 +70,9 @@ def test_pipe_nbconvert_execute_sync(tmpdir): assert nb.cells[0].outputs[0]["data"] == {"text/plain": "3"} -@requires_user_kernel_python3 -@requires_nbconvert -@skip_on_windows +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert +@pytest.mark.skip_on_windows def test_execute(tmpdir, caplog, capsys): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_py = str(tmpdir.join("notebook.py")) @@ -96,8 +90,8 @@ def test_execute(tmpdir, caplog, capsys): assert nb.cells[0].outputs[0]["data"] == {"text/plain": "3"} -@requires_user_kernel_python3 -@requires_nbconvert +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert def test_execute_readme_ok(tmpdir): tmp_md = str(tmpdir.join("notebook.md")) @@ -115,9 +109,9 @@ def test_execute_readme_ok(tmpdir): jupytext(args=[tmp_md, "--execute"]) -@requires_user_kernel_python3 -@requires_nbconvert -@skip_on_windows +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert +@pytest.mark.skip_on_windows def test_execute_readme_not_ok(tmpdir): tmp_md = str(tmpdir.join("notebook.md")) @@ -140,9 +134,9 @@ def test_execute_readme_not_ok(tmpdir): jupytext(args=[tmp_md, "--execute"]) -@requires_user_kernel_python3 -@requires_nbconvert -@skip_on_windows +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert +@pytest.mark.skip_on_windows def test_execute_sync(tmpdir, caplog, capsys): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_py = str(tmpdir.join("notebook.py")) @@ -160,9 +154,9 @@ def test_execute_sync(tmpdir, caplog, capsys): assert nb.cells[0].outputs[0]["data"] == {"text/plain": "3"} -@requires_nbconvert -@requires_ir_kernel -@skip_on_windows +@pytest.mark.requires_nbconvert +@pytest.mark.requires_ir_kernel +@pytest.mark.skip_on_windows def test_execute_r(tmpdir, caplog, capsys): # pragma: no cover tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_md = str(tmpdir.join("notebook.md")) @@ -182,9 +176,9 @@ def test_execute_r(tmpdir, caplog, capsys): # pragma: no cover assert nb.cells[0].outputs[0]["data"]["text/markdown"] == "6" -@requires_user_kernel_python3 -@requires_nbconvert -@skip_on_windows +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.requires_nbconvert +@pytest.mark.skip_on_windows def test_execute_in_subfolder(tmpdir, caplog, capsys): subfolder = tmpdir.mkdir("subfolder") @@ -263,7 +257,7 @@ def sample_md_notebook(): """ -@requires_user_kernel_python3 +@pytest.mark.requires_user_kernel_python3 def test_execute_text_file_does_update_the_metadata(sample_md_notebook, tmp_path): md_file = tmp_path / "nb.md" md_file.write_text(sample_md_notebook) @@ -275,7 +269,7 @@ def test_execute_text_file_does_update_the_metadata(sample_md_notebook, tmp_path assert "kernelspec" in new_md_text -@requires_user_kernel_python3 +@pytest.mark.requires_user_kernel_python3 def test_cat_execute_does_not_update_the_metadata(sample_md_notebook, tmp_path): md_file = tmp_path / "nb.md" md_file.write_text(sample_md_notebook) @@ -288,3 +282,21 @@ def test_cat_execute_does_not_update_the_metadata(sample_md_notebook, tmp_path): new_md_text = md_file.read_text() assert __version__ not in new_md_text assert "kernelspec" not in new_md_text + + +@pytest.mark.requires_user_kernel_python3 +@pytest.mark.skip_on_windows +@pytest.mark.filterwarnings("ignore") +def test_utf8_out_331(capsys, caplog): + py = "from IPython.core.display import HTML; HTML(u'\xd7')" + + with mock.patch("sys.stdin", StringIO(py)): + jupytext(["--to", "ipynb", "--execute", "-"]) + + out, err = capsys.readouterr() + + assert err == "" + nb = reads(out, "ipynb") + assert len(nb.cells) == 1 + print(nb.cells[0].outputs) + assert nb.cells[0].outputs[0]["data"]["text/html"] == "\xd7" diff --git a/tests/test_cm_config.py b/tests/integration/contents_manager/test_cm_config.py similarity index 99% rename from tests/test_cm_config.py rename to tests/integration/contents_manager/test_cm_config.py index 2e0d6c744..28215f247 100644 --- a/tests/test_cm_config.py +++ b/tests/integration/contents_manager/test_cm_config.py @@ -10,9 +10,7 @@ import jupytext from jupytext import TextFileContentsManager -from jupytext.compare import compare_cells - -from .utils import notebook_model +from jupytext.compare import compare_cells, notebook_model SAMPLE_NOTEBOOK = new_notebook( cells=[new_markdown_cell("A Markdown cell"), new_code_cell("# A code cell\n1 + 1")] diff --git a/tests/test_contentsmanager.py b/tests/integration/contents_manager/test_contentsmanager.py similarity index 83% rename from tests/test_contentsmanager.py rename to tests/integration/contents_manager/test_contentsmanager.py index 19556a671..731bda423 100644 --- a/tests/test_contentsmanager.py +++ b/tests/integration/contents_manager/test_contentsmanager.py @@ -1,5 +1,3 @@ -import itertools -import logging import os import re import shutil @@ -11,21 +9,12 @@ import jupytext from jupytext.cli import jupytext as jupytext_cli -from jupytext.compare import compare, compare_cells, compare_notebooks +from jupytext.compare import compare, compare_notebooks, notebook_model from jupytext.formats import auto_ext_from_metadata, read_format_from_metadata from jupytext.header import header_to_metadata_and_cell from jupytext.jupytext import read, write, writes from jupytext.kernels import kernelspec_from_language -from .utils import ( - list_notebooks, - notebook_model, - requires_pandoc, - requires_quarto, - requires_sphinx_gallery, - requires_user_kernel_python3, -) - def test_create_contentsmanager(): jupytext.TextFileContentsManager() @@ -115,8 +104,7 @@ def test_pair_unpair_notebook(tmpdir): assert len(nb2.cells[0]["outputs"]) == 0 -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb", skip="66")) -def test_load_save_rename(nb_file, tmpdir): +def test_load_save_rename(ipynb_py_R_jl_file, tmpdir): tmp_ipynb = "notebook.ipynb" tmp_rmd = "notebook.Rmd" @@ -125,7 +113,7 @@ def test_load_save_rename(nb_file, tmpdir): cm.root_dir = str(tmpdir) # open ipynb, save Rmd, reopen - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) cm.save(model=notebook_model(nb), path=tmp_rmd) nb_rmd = cm.get(tmp_rmd) compare_notebooks(nb_rmd["content"], nb, "Rmd") @@ -158,8 +146,7 @@ def test_load_save_rename(nb_file, tmpdir): assert not os.path.isfile(str(tmpdir.join("new.Rmd"))) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb", skip="magic")) -def test_save_load_paired_md_notebook(nb_file, tmpdir): +def test_save_load_paired_md_notebook(ipynb_py_R_jl_file, tmpdir): tmp_ipynb = "notebook.ipynb" tmp_md = "notebook.md" @@ -167,7 +154,7 @@ def test_save_load_paired_md_notebook(nb_file, tmpdir): cm.root_dir = str(tmpdir) # open ipynb, save with cm, reopen - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) nb.metadata["jupytext"] = {"formats": "ipynb,md"} cm.save(model=notebook_model(nb), path=tmp_ipynb) @@ -177,58 +164,7 @@ def test_save_load_paired_md_notebook(nb_file, tmpdir): assert nb_md["content"].metadata["jupytext"]["formats"] == "ipynb,md" -@requires_pandoc -@pytest.mark.parametrize( - "nb_file", - list_notebooks("ipynb", skip="(functional|Notebook with|flavors|invalid|305)"), -) -def test_save_load_paired_md_pandoc_notebook(nb_file, tmpdir): - tmp_ipynb = "notebook.ipynb" - tmp_md = "notebook.md" - - cm = jupytext.TextFileContentsManager() - cm.root_dir = str(tmpdir) - - # open ipynb, save with cm, reopen - nb = jupytext.read(nb_file) - nb.metadata["jupytext"] = {"formats": "ipynb,md:pandoc"} - - cm.save(model=notebook_model(nb), path=tmp_ipynb) - nb_md = cm.get(tmp_md) - - compare_notebooks(nb_md["content"], nb, "md:pandoc") - assert nb_md["content"].metadata["jupytext"]["formats"] == "ipynb,md:pandoc" - - -@requires_quarto -@pytest.mark.parametrize( - "nb_file", - list_notebooks( - "ipynb", - skip="(World|functional|Notebook with|plotly_graphs|flavors|complex_metadata|" - "update83|raw_cell|_66|nteract|LaTeX|invalid|305|text_outputs|ir_notebook|jupyter|with_R_magic)", - ), -) -def test_save_load_paired_qmd_notebook(nb_file, tmpdir): - tmp_ipynb = "notebook.ipynb" - tmp_qmd = "notebook.qmd" - - cm = jupytext.TextFileContentsManager() - cm.root_dir = str(tmpdir) - - # open ipynb, save with cm, reopen - nb = jupytext.read(nb_file) - nb.metadata["jupytext"] = {"formats": "ipynb,qmd"} - - cm.save(model=notebook_model(nb), path=tmp_ipynb) - nb_md = cm.get(tmp_qmd) - - compare_notebooks(nb_md["content"], nb, "qmd") - assert nb_md["content"].metadata["jupytext"]["formats"] == "ipynb,qmd" - - -@pytest.mark.parametrize("py_file", list_notebooks("percent")) -def test_pair_plain_script(py_file, tmpdir, caplog): +def test_pair_plain_script(percent_file, tmpdir, caplog): tmp_py = "notebook.py" tmp_ipynb = "notebook.ipynb" @@ -236,7 +172,7 @@ def test_pair_plain_script(py_file, tmpdir, caplog): cm.root_dir = str(tmpdir) # open py file, pair, save with cm - nb = jupytext.read(py_file) + nb = jupytext.read(percent_file) nb.metadata["jupytext"]["formats"] = "ipynb,py:hydrogen" cm.save(model=notebook_model(nb), path=tmp_py) @@ -246,7 +182,7 @@ def test_pair_plain_script(py_file, tmpdir, caplog): assert os.path.isfile(str(tmpdir.join(tmp_ipynb))) # Make sure we've not changed the script - with open(py_file) as fp: + with open(percent_file) as fp: script = fp.read() with open(str(tmpdir.join(tmp_py))) as fp: @@ -269,8 +205,7 @@ def test_pair_plain_script(py_file, tmpdir, caplog): assert "formats" not in nb2.metadata["jupytext"] -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_load_save_rename_nbpy(nb_file, tmpdir): +def test_load_save_rename_nbpy(ipynb_py_file, tmpdir): tmp_ipynb = "notebook.ipynb" tmp_nbpy = "notebook.nb.py" @@ -279,7 +214,7 @@ def test_load_save_rename_nbpy(nb_file, tmpdir): cm.root_dir = str(tmpdir) # open ipynb, save nb.py, reopen - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) cm.save(model=notebook_model(nb), path=tmp_nbpy) nbpy = cm.get(tmp_nbpy) compare_notebooks(nbpy["content"], nb) @@ -300,15 +235,17 @@ def test_load_save_rename_nbpy(nb_file, tmpdir): cm.rename_file(tmp_nbpy, "suffix_missing.py") -@pytest.mark.parametrize("script", list_notebooks("python", skip="light")) -def test_load_save_py_freeze_metadata(script, tmpdir): +def test_load_save_py_freeze_metadata(python_file, tmpdir): + if "light" in python_file: + pytest.skip() + tmp_nbpy = "notebook.py" cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmpdir) # read original file - with open(script) as fp: + with open(python_file) as fp: text_py = fp.read() # write to tmp_nbpy @@ -351,8 +288,7 @@ def test_load_text_notebook(tmpdir): assert nb_model[key] == py_model[key], key -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_load_save_rename_notebook_with_dot(nb_file, tmpdir): +def test_load_save_rename_notebook_with_dot(ipynb_py_file, tmpdir): tmp_ipynb = "1.notebook.ipynb" tmp_nbpy = "1.notebook.py" @@ -361,7 +297,7 @@ def test_load_save_rename_notebook_with_dot(nb_file, tmpdir): cm.root_dir = str(tmpdir) # open ipynb, save nb.py, reopen - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) cm.save(model=notebook_model(nb), path=tmp_nbpy) nbpy = cm.get(tmp_nbpy) compare_notebooks(nbpy["content"], nb) @@ -378,8 +314,7 @@ def test_load_save_rename_notebook_with_dot(nb_file, tmpdir): assert os.path.isfile(str(tmpdir.join("2.new_notebook.py"))) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_load_save_rename_nbpy_default_config(nb_file, tmpdir): +def test_load_save_rename_nbpy_default_config(ipynb_py_file, tmpdir): tmp_ipynb = "notebook.ipynb" tmp_nbpy = "notebook.nb.py" @@ -388,7 +323,7 @@ def test_load_save_rename_nbpy_default_config(nb_file, tmpdir): cm.root_dir = str(tmpdir) # open ipynb, save nb.py, reopen - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) cm.save(model=notebook_model(nb), path=tmp_nbpy) nbpy = cm.get(tmp_nbpy) @@ -418,8 +353,7 @@ def test_load_save_rename_nbpy_default_config(nb_file, tmpdir): assert not os.path.isfile(str(tmpdir.join("new.nb.py"))) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_load_save_rename_non_ascii_path(nb_file, tmpdir): +def test_load_save_rename_non_ascii_path(ipynb_py_file, tmpdir): tmp_ipynb = "notebôk.ipynb" tmp_nbpy = "notebôk.nb.py" @@ -429,7 +363,7 @@ def test_load_save_rename_non_ascii_path(nb_file, tmpdir): cm.root_dir = tmpdir # open ipynb, save nb.py, reopen - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) cm.save(model=notebook_model(nb), path=tmp_nbpy) nbpy = cm.get(tmp_nbpy) @@ -459,8 +393,7 @@ def test_load_save_rename_non_ascii_path(nb_file, tmpdir): assert not os.path.isfile(os.path.join(tmpdir, "nêw.nb.py")) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_outdated_text_notebook(nb_file, tmpdir): +def test_outdated_text_notebook(python_notebook, tmpdir): # 1. write py ipynb cm = jupytext.TextFileContentsManager() cm.formats = "py,ipynb" @@ -468,7 +401,7 @@ def test_outdated_text_notebook(nb_file, tmpdir): cm.root_dir = str(tmpdir) # open ipynb, save py, reopen - nb = jupytext.read(nb_file) + nb = python_notebook cm.save(model=notebook_model(nb), path="notebook.py") model_py = cm.get("notebook.py", load_alternative_format=False) model_ipynb = cm.get("notebook.ipynb", load_alternative_format=False) @@ -573,8 +506,7 @@ def test_outdated_text_notebook_diff_is_shown(tmpdir, python_notebook): ) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_reload_notebook_after_jupytext_cli(nb_file, tmpdir): +def test_reload_notebook_after_jupytext_cli(python_notebook, tmpdir): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_nbpy = str(tmpdir.join("notebook.py")) @@ -583,7 +515,7 @@ def test_reload_notebook_after_jupytext_cli(nb_file, tmpdir): cm.root_dir = str(tmpdir) # write the paired notebook - nb = jupytext.read(nb_file) + nb = python_notebook nb.metadata.setdefault("jupytext", {})["formats"] = "py,ipynb" cm.save(model=notebook_model(nb), path="notebook.py") @@ -601,10 +533,9 @@ def test_reload_notebook_after_jupytext_cli(nb_file, tmpdir): compare_notebooks(nb, nb2) -@pytest.mark.parametrize("nb_file", list_notebooks("percent")) -def test_load_save_percent_format(nb_file, tmpdir): +def test_load_save_percent_format(percent_file, tmpdir): tmp_py = "notebook.py" - with open(nb_file) as stream: + with open(percent_file) as stream: text_py = stream.read() with open(str(tmpdir.join(tmp_py)), "w") as stream: stream.write(text_py) @@ -631,8 +562,7 @@ def test_load_save_percent_format(nb_file, tmpdir): compare(text_py2, text_py) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_julia")) -def test_save_to_percent_format(nb_file, tmpdir): +def test_save_to_percent_format(ipynb_julia_file, tmpdir): tmp_ipynb = "notebook.ipynb" tmp_jl = "notebook.jl" @@ -640,7 +570,7 @@ def test_save_to_percent_format(nb_file, tmpdir): cm.root_dir = str(tmpdir) cm.preferred_jupytext_formats_save = "jl:percent" - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_julia_file) nb["metadata"]["jupytext"] = {"formats": "ipynb,jl"} # save to ipynb and jl @@ -655,9 +585,8 @@ def test_save_to_percent_format(nb_file, tmpdir): assert metadata["jupytext"]["formats"] == "ipynb,jl:percent" -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_save_using_preferred_and_default_format_170(nb_file, tmpdir): - nb = read(nb_file) +def test_save_using_preferred_and_default_format_170(ipynb_py_file, tmpdir): + nb = read(ipynb_py_file) # Way 0: preferred_jupytext_formats_save, no prefix + formats tmp_py = str(tmpdir.join("python/notebook.py")) @@ -704,13 +633,12 @@ def test_save_using_preferred_and_default_format_170(nb_file, tmpdir): assert nb_py.metadata["jupytext"]["text_representation"]["format_name"] == "percent" -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_open_using_preferred_and_default_format_174(nb_file, tmpdir): +def test_open_using_preferred_and_default_format_174(ipynb_py_file, tmpdir): tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_py = str(tmpdir.join("python/notebook.py")) tmp_py2 = str(tmpdir.join("other/notebook.py")) os.makedirs(str(tmpdir.join("other"))) - shutil.copyfile(nb_file, tmp_ipynb) + shutil.copyfile(ipynb_py_file, tmp_ipynb) cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmpdir) @@ -740,11 +668,12 @@ def test_open_using_preferred_and_default_format_174(nb_file, tmpdir): assert not os.path.isfile(str(tmpdir.join("other/notebook.ipynb"))) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py", skip="many hash")) -def test_kernelspec_are_preserved(nb_file, tmpdir): +def test_kernelspec_are_preserved(ipynb_py_file, tmpdir): + if "many hash" in ipynb_py_file: + pytest.skip() tmp_ipynb = str(tmpdir.join("notebook.ipynb")) tmp_py = str(tmpdir.join("notebook.py")) - shutil.copyfile(nb_file, tmp_ipynb) + shutil.copyfile(ipynb_py_file, tmp_ipynb) cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmpdir) @@ -768,8 +697,7 @@ def test_kernelspec_are_preserved(nb_file, tmpdir): compare_notebooks(model2["content"], model["content"]) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_save_to_light_percent_sphinx_format(nb_file, tmpdir): +def test_save_to_light_percent_sphinx_format(ipynb_py_file, tmpdir): tmp_ipynb = "notebook.ipynb" tmp_lgt_py = "notebook.lgt.py" tmp_pct_py = "notebook.pct.py" @@ -778,7 +706,7 @@ def test_save_to_light_percent_sphinx_format(nb_file, tmpdir): cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmpdir) - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) nb["metadata"]["jupytext"] = { "formats": "ipynb,.pct.py:percent,.lgt.py:light,.spx.py:sphinx" } @@ -809,8 +737,7 @@ def test_save_to_light_percent_sphinx_format(nb_file, tmpdir): compare_notebooks(model["content"], nb) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_pair_notebook_with_dot(nb_file, tmpdir): +def test_pair_notebook_with_dot(ipynb_py_file, tmpdir): # Reproduce issue #138 tmp_py = "file.5.1.py" tmp_ipynb = "file.5.1.ipynb" @@ -818,7 +745,7 @@ def test_pair_notebook_with_dot(nb_file, tmpdir): cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmpdir) - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) nb["metadata"]["jupytext"] = {"formats": "ipynb,py:percent"} # save to ipynb and three python flavors @@ -839,8 +766,7 @@ def test_pair_notebook_with_dot(nb_file, tmpdir): compare_notebooks(model["content"], nb) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_preferred_format_allows_to_read_others_format(nb_file, tmpdir): +def test_preferred_format_allows_to_read_others_format(python_notebook, tmpdir): # 1. write py ipynb tmp_ipynb = "notebook.ipynb" tmp_nbpy = "notebook.py" @@ -850,7 +776,7 @@ def test_preferred_format_allows_to_read_others_format(nb_file, tmpdir): cm.root_dir = str(tmpdir) # load notebook and save it using the cm - nb = jupytext.read(nb_file) + nb = python_notebook nb["metadata"]["jupytext"] = {"formats": "ipynb,py"} cm.save(model=notebook_model(nb), path=tmp_ipynb) @@ -908,10 +834,9 @@ def test_preferred_formats_read_auto(tmpdir): ) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb")) -def test_save_in_auto_extension_global(nb_file, tmpdir): +def test_save_in_auto_extension_global(ipynb_py_R_jl_file, tmpdir): # load notebook - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) auto_ext = auto_ext_from_metadata(nb.metadata) tmp_ipynb = "notebook.ipynb" @@ -992,10 +917,9 @@ def test_global_auto_pairing_works_with_empty_notebook(tmpdir): assert nb2.cells[0].source == "2+2" -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb")) -def test_save_in_auto_extension_global_with_format(nb_file, tmpdir): +def test_save_in_auto_extension_global_with_format(ipynb_py_R_jl_file, tmpdir): # load notebook - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) auto_ext = auto_ext_from_metadata(nb.metadata) tmp_ipynb = "notebook.ipynb" @@ -1022,10 +946,9 @@ def test_save_in_auto_extension_global_with_format(nb_file, tmpdir): compare_notebooks(model["content"], nb) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb")) -def test_save_in_auto_extension_local(nb_file, tmpdir): +def test_save_in_auto_extension_local(ipynb_py_R_jl_file, tmpdir): # load notebook - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) nb.metadata.setdefault("jupytext", {})["formats"] = "ipynb,auto:percent" auto_ext = auto_ext_from_metadata(nb.metadata) @@ -1049,10 +972,9 @@ def test_save_in_auto_extension_local(nb_file, tmpdir): compare_notebooks(model["content"], nb) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb")) -def test_save_in_pct_and_lgt_auto_extensions(nb_file, tmpdir): +def test_save_in_pct_and_lgt_auto_extensions(ipynb_py_R_jl_file, tmpdir): # load notebook - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_R_jl_file) auto_ext = auto_ext_from_metadata(nb.metadata) tmp_ipynb = "notebook.ipynb" @@ -1077,9 +999,10 @@ def test_save_in_pct_and_lgt_auto_extensions(nb_file, tmpdir): assert read_format_from_metadata(stream.read(), auto_ext) == "light" -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb", skip="(magic|305)")) -def test_metadata_filter_is_effective(nb_file, tmpdir): - nb = jupytext.read(nb_file) +def test_metadata_filter_is_effective(ipynb_py_R_jl_file, tmpdir): + if re.match(r".*(magic|305).*", ipynb_py_R_jl_file): + pytest.skip() + nb = jupytext.read(ipynb_py_R_jl_file) tmp_ipynb = "notebook.ipynb" tmp_script = "notebook.py" @@ -1163,12 +1086,10 @@ def test_no_metadata_added_to_scripts_139(tmpdir): compare(fp.read(), text) -@pytest.mark.parametrize( - "nb_file,ext", itertools.product(list_notebooks("ipynb_py"), [".py", ".ipynb"]) -) -def test_local_format_can_deactivate_pairing(nb_file, ext, tmpdir): +@pytest.mark.parametrize("ext", [".py", ".ipynb"]) +def test_local_format_can_deactivate_pairing(ipynb_py_file, ext, tmpdir): """This is a test for #157: local format can be used to deactivate the global pairing""" - nb = jupytext.read(nb_file) + nb = jupytext.read(ipynb_py_file) nb.metadata["jupytext_formats"] = ext[1:] # py or ipynb # create contents manager with default pairing @@ -1194,10 +1115,9 @@ def test_local_format_can_deactivate_pairing(nb_file, ext, tmpdir): compare_notebooks(nb3, nb) -@pytest.mark.parametrize("nb_file", list_notebooks("Rmd")) -def test_global_pairing_allows_to_save_other_file_types(nb_file, tmpdir): +def test_global_pairing_allows_to_save_other_file_types(rmd_file, tmpdir): """This is a another test for #157: local format can be used to deactivate the global pairing""" - nb = jupytext.read(nb_file) + nb = jupytext.read(rmd_file) # create contents manager with default pairing cm = jupytext.TextFileContentsManager() @@ -1216,12 +1136,11 @@ def test_global_pairing_allows_to_save_other_file_types(nb_file, tmpdir): compare_notebooks(nb2, nb) -@requires_user_kernel_python3 -@pytest.mark.parametrize("nb_file", list_notebooks("R")) -def test_python_kernel_preserves_R_files(nb_file, tmpdir): +@pytest.mark.requires_user_kernel_python3 +def test_python_kernel_preserves_R_files(r_file, tmpdir): """Opening a R file with a Jupyter server that has no R kernel should not modify the file""" tmp_r_file = str(tmpdir.join("script.R")) - with open(nb_file) as fp: + with open(r_file) as fp: script = fp.read() with open(tmp_r_file, "w") as fp: fp.write(script) @@ -1287,30 +1206,6 @@ def test_pair_notebook_in_dotdot_folder(tmpdir): cm.get("scripts/notebook_name.py") -@requires_sphinx_gallery -def test_rst2md_option(tmpdir): - tmp_py = str(tmpdir.join("notebook.py")) - - # Write notebook in sphinx format - nb = new_notebook( - cells=[ - new_markdown_cell("A short sphinx notebook"), - new_markdown_cell(":math:`1+1`"), - ] - ) - write(nb, tmp_py, fmt="py:sphinx") - - cm = jupytext.TextFileContentsManager() - cm.sphinx_convert_rst2md = True - cm.root_dir = str(tmpdir) - - nb2 = cm.get("notebook.py")["content"] - - # Was rst to md conversion effective? - assert nb2.cells[2].source == "$1+1$" - assert nb2.metadata["jupytext"]["rst2md"] is False - - def test_split_at_heading_option(tmpdir): text = """Markdown text @@ -1395,12 +1290,11 @@ def test_set_then_change_formats(tmpdir): assert not os.path.isfile(tmp_py) -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")[:1]) -def test_set_then_change_auto_formats(tmpdir, nb_file): +def test_set_then_change_auto_formats(tmpdir, python_notebook): tmp_ipynb = str(tmpdir.join("nb.ipynb")) tmp_py = str(tmpdir.join("nb.py")) tmp_rmd = str(tmpdir.join("nb.Rmd")) - nb = new_notebook(metadata=read(nb_file).metadata) + nb = new_notebook(metadata=python_notebook.metadata) cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmpdir) @@ -1434,8 +1328,7 @@ def test_set_then_change_auto_formats(tmpdir, nb_file): cm.get("nb.ipynb") -@pytest.mark.parametrize("nb_file", list_notebooks("ipynb_py")) -def test_share_py_recreate_ipynb(tmpdir, nb_file): +def test_share_py_recreate_ipynb(tmpdir, ipynb_py_R_jl_file): tmp_ipynb = str(tmpdir.join("nb.ipynb")) tmp_py = str(tmpdir.join("nb.py")) @@ -1452,7 +1345,7 @@ def test_share_py_recreate_ipynb(tmpdir, nb_file): cm.notebook_metadata_filter = "-all" cm.cell_metadata_filter = "-all" - nb = read(nb_file) + nb = read(ipynb_py_R_jl_file) model_ipynb = cm.save(model=notebook_model(nb), path="nb.ipynb") assert os.path.isfile(tmp_ipynb) @@ -1889,97 +1782,6 @@ def test_nested_prefix(tmpdir): assert tmpdir.join("nested").join("prefix").join("notebook.py").isfile() -def fs_meta_manager(tmpdir): - try: - from jupyterfs.metamanager import MetaManager - except ImportError: - pytest.skip("jupyterfs is not available") - - cm_class = jupytext.build_jupytext_contents_manager_class(MetaManager) - logger = logging.getLogger("jupyter-fs") - cm = cm_class(parent=None, log=logger) - cm.initResource( - { - "url": f"osfs://{tmpdir}", - } - ) - return cm - - -def test_jupytext_jupyter_fs_metamanager(tmpdir): - """Test the basic get/save functions of Jupytext with a fs manager - https://github.com/mwouts/jupytext/issues/618""" - cm = fs_meta_manager(tmpdir) - # the hash that corresponds to the osfs - osfs = [h for h in cm._managers if h != ""][0] - - # save a few files - text = "some text\n" - cm.save(dict(type="file", content=text, format="text"), path=osfs + ":text.md") - nb = new_notebook( - cells=[new_markdown_cell("A markdown cell"), new_code_cell("1 + 1")] - ) - cm.save(notebook_model(nb), osfs + ":notebook.ipynb") - cm.save(notebook_model(nb), osfs + ":text_notebook.md") - - # list the directory - directory = cm.get(osfs + ":/") - assert {file["name"] for file in directory["content"]} == { - "text.md", - "text_notebook.md", - "notebook.ipynb", - } - - # get the files - model = cm.get(osfs + ":/text.md", type="file") - assert model["type"] == "file" - assert model["content"] == text - - model = cm.get(osfs + ":text.md", type="notebook") - assert model["type"] == "notebook" - # We only compare the cells, as kernelspecs are added to the notebook metadata - compare_cells( - model["content"].cells, [new_markdown_cell(text.strip())], compare_ids=False - ) - - for nb_file in ["notebook.ipynb", "text_notebook.md"]: - model = cm.get(osfs + ":" + nb_file) - assert model["type"] == "notebook" - actual_cells = model["content"].cells - - # saving adds 'trusted=True' to the code cell metadata - for cell in actual_cells: - cell.metadata = {} - compare_cells(actual_cells, nb.cells, compare_ids=False) - - -def test_config_jupytext_jupyter_fs_meta_manager(tmpdir): - """Test the configuration of Jupytext with a fs manager""" - tmpdir.join("jupytext.toml").write('formats = "ipynb,py"') - cm = fs_meta_manager(tmpdir) - # the hash that corresponds to the osfs - osfs = [h for h in cm._managers if h != ""][0] - - # save a few files - nb = new_notebook() - cm.save(dict(type="file", content="text", format="text"), path=osfs + ":text.md") - cm.save(notebook_model(nb), osfs + ":script.py") - cm.save(notebook_model(nb), osfs + ":text_notebook.md") - cm.save(notebook_model(nb), osfs + ":notebook.ipynb") - - # list the directory - directory = cm.get(osfs + ":/") - assert {file["name"] for file in directory["content"]} == { - "jupytext.toml", - "text.md", - "text_notebook.md", - "notebook.ipynb", - "notebook.py", - "script.py", - "script.ipynb", - } - - def test_timestamp_is_correct_after_reload_978(tmp_path, python_notebook): """Here we reproduce the conditions in Issue #978 and make sure no warning is generated""" @@ -1989,12 +1791,12 @@ def test_timestamp_is_correct_after_reload_978(tmp_path, python_notebook): cm = jupytext.TextFileContentsManager() cm.root_dir = str(tmp_path) - ipynb_file = tmp_path / "nb.ipynb" + ipynb_py_R_jl_file = tmp_path / "nb.ipynb" py_file = tmp_path / "nb.py" # 1. Save the paired notebook cm.save(notebook_model(nb), path="nb.ipynb") - assert ipynb_file.exists() + assert ipynb_py_R_jl_file.exists() assert py_file.exists() # and reload to get the original timestamp diff --git a/tests/test_load_multiple.py b/tests/integration/contents_manager/test_load_multiple.py similarity index 100% rename from tests/test_load_multiple.py rename to tests/integration/contents_manager/test_load_multiple.py diff --git a/tests/notebooks/ipynb_py/World population.ipynb b/tests/notebooks/ipynb_py/World population.ipynb deleted file mode 100644 index a8bae7d5a..000000000 --- a/tests/notebooks/ipynb_py/World population.ipynb +++ /dev/null @@ -1,1475 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# A quick insight at world population\n", - "\n", - "## Collecting population data\n", - "\n", - "In the below we retrieve population data from the\n", - "[World Bank](http://www.worldbank.org/)\n", - "using the [wbdata](https://github.com/OliverSherouse/wbdata) python package" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import wbdata as wb\n", - "\n", - "pd.options.display.max_rows = 6\n", - "pd.options.display.max_columns = 20" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Corresponding indicator is found using search method - or, directly,\n", - "the World Bank site." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "SP.POP.TOTL\tPopulation, total\n" - ] - } - ], - "source": [ - "wb.search_indicators('Population, total') # SP.POP.TOTL\n", - "# wb.search_indicators('area')\n", - "# => https://data.worldbank.org/indicator is easier to use" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we download the population data" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " | \n", - " | Population, total | \n", - "Surface area (sq. km) | \n", - "Land area (sq. km) | \n", - "Arable land (% of land area) | \n", - "
---|---|---|---|---|---|
country | \n", - "date | \n", - "\n", - " | \n", - " | \n", - " | \n", - " |
Afghanistan | \n", - "1960-01-01 | \n", - "8996351.0 | \n", - "NaN | \n", - "NaN | \n", - "NaN | \n", - "
1961-01-01 | \n", - "9166764.0 | \n", - "652860.0 | \n", - "652860.0 | \n", - "11.717673 | \n", - "|
1962-01-01 | \n", - "9345868.0 | \n", - "652860.0 | \n", - "652860.0 | \n", - "11.794259 | \n", - "|
... | \n", - "... | \n", - "... | \n", - "... | \n", - "... | \n", - "... | \n", - "
Zimbabwe | \n", - "2015-01-01 | \n", - "15777451.0 | \n", - "390760.0 | \n", - "386850.0 | \n", - "10.339925 | \n", - "
2016-01-01 | \n", - "16150362.0 | \n", - "390760.0 | \n", - "386850.0 | \n", - "NaN | \n", - "|
2017-01-01 | \n", - "16529904.0 | \n", - "390760.0 | \n", - "386850.0 | \n", - "NaN | \n", - "
15312 rows × 4 columns
\n", - "\n", - " | Population, total | \n", - "Surface area (sq. km) | \n", - "Land area (sq. km) | \n", - "Arable land (% of land area) | \n", - "
---|---|---|---|---|
date | \n", - "\n", - " | \n", - " | \n", - " | \n", - " |
1960-01-01 | \n", - "3.032160e+09 | \n", - "NaN | \n", - "NaN | \n", - "NaN | \n", - "
1961-01-01 | \n", - "3.073369e+09 | \n", - "134043190.4 | \n", - "129721455.4 | \n", - "9.693086 | \n", - "
1962-01-01 | \n", - "3.126510e+09 | \n", - "134043190.4 | \n", - "129721435.4 | \n", - "9.726105 | \n", - "
... | \n", - "... | \n", - "... | \n", - "... | \n", - "... | \n", - "
2015-01-01 | \n", - "7.357559e+09 | \n", - "134325130.2 | \n", - "129732901.8 | \n", - "10.991288 | \n", - "
2016-01-01 | \n", - "7.444157e+09 | \n", - "134325130.2 | \n", - "129733172.7 | \n", - "NaN | \n", - "
2017-01-01 | \n", - "7.530360e+09 | \n", - "134325130.2 | \n", - "129733172.7 | \n", - "NaN | \n", - "
58 rows × 4 columns
\n", - "