diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py index 5ff8f65..599b0a2 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py @@ -9,9 +9,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -25,6 +25,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +plt.style.use(all_styles["bg-style"]) # Config # 2: Give a file path to where your PDF (.gr) and # structure (.cif) files are located. @@ -33,7 +34,7 @@ # First we store the absolute directory of this script, # then two directories above this,with the directory # 'data' appended -PWD = Path(__file__).parent.absolute() +PWD = Path(__file__).parent.resolve() DPATH = PWD.parent.parent / "data" # 3: Give an identifying name for the refinement, similar @@ -264,13 +265,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py index 35f164d..f00afb4 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py @@ -13,9 +13,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -30,6 +30,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your PDF (.gr) and structure (.cif) files # are located. @@ -241,13 +242,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py b/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py index cd06828..3e12439 100644 --- a/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py +++ b/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py @@ -10,9 +10,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -26,6 +26,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your pdf (.gr) and (.cif) files are located. PWD = Path(__file__).parent.absolute() @@ -271,13 +272,6 @@ def plot_results(recipe, fig_name): ni_signal = ni_scale * recipe.crystal.G_Ni.profile.ycalc ni_signal += min(si_signal) - np.abs(max(ni_signal)) - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py b/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py index aa9feb8..75a5c9c 100644 --- a/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py +++ b/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py @@ -10,9 +10,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -27,12 +27,7 @@ from diffpy.structure.atom import Atom from diffpy.structure.parsers import getParser -try: - from bg_mpl_stylesheets.bg_mpl_stylesheet import bg_mpl_style - - plt.style.use(bg_mpl_style) -except ImportError: - pass +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your pdf (.gr) and (.cif) files are located. @@ -246,13 +241,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py b/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py index b7d03e5..654c50e 100644 --- a/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py +++ b/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py @@ -9,9 +9,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -25,12 +25,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser -try: - from bg_mpl_stylesheets.bg_mpl_stylesheet import bg_mpl_style - - plt.style.use(bg_mpl_style) -except ImportError: - pass +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your pdf (.gr) and (.cif) files are located. @@ -221,13 +216,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py b/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py index 2200179..bdacb52 100644 --- a/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py +++ b/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py @@ -10,7 +10,6 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np from scipy.optimize import least_squares @@ -445,13 +444,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py b/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py index 316948b..98fdae0 100644 --- a/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py +++ b/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py @@ -199,9 +199,6 @@ def plot_results(recipe, figname): diff = g - gcalc + diffzero mpl.rcParams.update(mpl.rcParamsDefault) - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) fig, ax1 = plt.subplots(1, 1) diff --git a/news/example-ci.rst b/news/example-ci.rst new file mode 100644 index 0000000..d0453da --- /dev/null +++ b/news/example-ci.rst @@ -0,0 +1,23 @@ +**Added:** + +* Add tests that run PDF example scripts + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/requirements/packs/plotting.txt b/requirements/packs/plotting.txt index 6b41443..6a968c8 100644 --- a/requirements/packs/plotting.txt +++ b/requirements/packs/plotting.txt @@ -1,4 +1,5 @@ ipywidgets matplotlib ipympl +bg-mpl-stylesheets py3dmol>=2.0.1 diff --git a/requirements/tests.txt b/requirements/tests.txt index fde0e31..a1092fb 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -8,3 +8,5 @@ pytest-env pytest-mock freezegun DeepDiff +psutil +bg-mpl-stylesheets diff --git a/tests/conftest.py b/tests/conftest.py index e3b6313..3eaae7d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,32 @@ import json +import shutil from pathlib import Path +import matplotlib import pytest +PROJECT_ROOT = Path(__file__).resolve().parents[1] +EXAMPLES_ROOT = PROJECT_ROOT / "docs" / "examples" + + +@pytest.fixture(scope="session") +def tmp_examples(tmp_path_factory): + """Copy the entire examples/ tree into a temp directory once per + test session. + + Returns the path to that copy. + """ + tmpdir = tmp_path_factory.mktemp("examples") + tmp_examples = tmpdir / "examples" + shutil.copytree(EXAMPLES_ROOT, tmp_examples) + yield tmp_examples + + +@pytest.fixture(scope="session", autouse=True) +def use_headless_matplotlib(): + """Force matplotlib to use a headless backend during tests.""" + matplotlib.use("Agg") + @pytest.fixture def user_filesystem(tmp_path): diff --git a/tests/test_examples.py b/tests/test_examples.py new file mode 100644 index 0000000..96cd573 --- /dev/null +++ b/tests/test_examples.py @@ -0,0 +1,13 @@ +import runpy + + +def test_all_examples(tmp_examples): + """Run all example scripts to ensure they execute without error.""" + scripts = list(tmp_examples.rglob("**/solutions/diffpy-cmi/*.py")) + # sort list so that fitBulkNi.py runs first + scripts.sort(key=lambda s: 0 if s.name == "fitBulkNi.py" else 1) + for script in scripts: + script_relative_path = script.relative_to(tmp_examples).as_posix() + print("hello", script_relative_path) + print(f"Testing {script_relative_path}") + runpy.run_path(str(script), run_name="__main__")