Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions tests/test_cf_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
get_data_for_plotting,
run_contour_plot,
run_line_plot,
save_selected_field_data,
)

import numpy as np
Expand Down Expand Up @@ -172,21 +173,29 @@ class _FakeFigure:
def __init__(self) -> None:
self.text_calls: list[tuple[tuple[object, ...], dict[str, object]]] = []
self.suptitle_calls: list[tuple[tuple[object, ...], dict[str, object]]] = []
self.savefig_calls: list[str] = []

def text(self, *args: object, **kwargs: object) -> None:
self.text_calls.append((args, kwargs))

def suptitle(self, *args: object, **kwargs: object) -> None:
self.suptitle_calls.append((args, kwargs))

def savefig(self, filename: str) -> None:
self.savefig_calls.append(filename)


class _FakePlt:
def __init__(self) -> None:
self.figure = _FakeFigure()
self.close_calls = 0

def gcf(self) -> _FakeFigure:
return self.figure

def close(self, _fig: object) -> None:
self.close_calls += 1


def test_run_contour_plot_applies_levels_annotations_and_save(
monkeypatch: pytest.MonkeyPatch,
Expand All @@ -210,11 +219,13 @@ def test_run_contour_plot_applies_levels_annotations_and_save(
)

assert cfp.cscale_calls == [{"scale": "magma"}]
assert cfp.gopen_calls == [{"file": "/tmp/mock.png"}]
assert cfp.gopen_calls == [{"file": "cfplot.png", "user_plot": 1}]
assert cfp.levs_calls == [{"manual": [-1.0, 0.0, 1.0]}]
assert cfp.setvars_calls == [{"title_fontsize": 10.5, "viewer": None}]
assert cfp.con_calls
assert cfp.gclose_calls == 1
assert cfp.gclose_calls == 0
assert plt_obj.figure.savefig_calls == ["/tmp/mock.png"]
assert plt_obj.close_calls == 1
assert plt_obj.figure.text_calls
assert plt_obj.figure.text_calls[-1][1]["fontsize"] == 8.0

Expand Down Expand Up @@ -348,4 +359,18 @@ def render(self) -> None:
assert captured["pfld"] is field_eg
assert captured["options"] == {"filename": "/tmp/line.png", "title": "line"}
assert captured["rendered"] is True


def test_save_selected_field_data_uses_cf_write(monkeypatch: pytest.MonkeyPatch) -> None:
calls: list[tuple[object, str]] = []
monkeypatch.setattr(
cf_interface.cf,
"write",
lambda field, filename: calls.append((field, filename)),
)

field_obj = object()
save_selected_field_data(field_obj, "/tmp/out.nc")

assert calls == [(field_obj, "/tmp/out.nc")]

46 changes: 42 additions & 4 deletions tests/test_contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import numpy as np

from xconv2.cf_templates import contour_range_from_selection, plot_from_selection
from xconv2.cf_templates import contour_range_from_selection, plot_from_selection, save_data_from_selection
import xconv2.xconv_cf_interface as cf_interface
from xconv2.xconv_cf_interface import auto_contour_title, get_data_for_plotting, run_contour_plot
from xconv2.ui.contour_options_controller import ContourOptionsController
Expand Down Expand Up @@ -78,18 +78,26 @@ def gclose(self) -> None:
@dataclass
class _FakeFigure:
text_calls: list[tuple[tuple[object, ...], dict[str, object]]] = field(default_factory=list)
savefig_calls: list[str] = field(default_factory=list)

def text(self, *args: object, **kwargs: object) -> None:
self.text_calls.append((args, kwargs))

def savefig(self, filename: str) -> None:
self.savefig_calls.append(filename)


@dataclass
class _FakePlt:
figure: _FakeFigure = field(default_factory=_FakeFigure)
close_calls: int = 0

def gcf(self) -> _FakeFigure:
return self.figure

def close(self, _fig: object) -> None:
self.close_calls += 1



def _run_generated(
Expand All @@ -113,6 +121,7 @@ def _run_generated(
"cf": _FakeCF,
"np": np,
"get_data_for_plotting": get_data_for_plotting,
"save_selected_field_data": lambda _field, _path: None,
"run_contour_plot": run_contour_plot,
"auto_contour_title": auto_contour_title,
"send_to_gui": lambda prefix, payload=None: messages.append((prefix, payload)),
Expand Down Expand Up @@ -183,12 +192,15 @@ def test_plot_from_selection_contour_explicit_levels_and_save_file() -> None:

fld = _FakeField()
cfp = _FakeCFPlot()
messages = _run_generated(code, fld, cfp)
fake_plt = _FakePlt()
messages = _run_generated(code, fld, cfp, plt_obj=fake_plt)

assert cfp.gopen_calls == [{"file": output_file}]
assert cfp.gclose_calls == 1
assert cfp.gopen_calls == [{"file": "cfplot.png", "user_plot": 1}]
assert cfp.gclose_calls == 0
assert cfp.cscale_calls == [{}]
assert cfp.con_calls
assert fake_plt.figure.savefig_calls == [output_file]
assert fake_plt.close_calls == 1
assert ("STATUS:Saved plot to /tmp/mock-contour.png", None) in messages


Expand Down Expand Up @@ -249,6 +261,32 @@ def test_plot_from_selection_lineplot_generates_worker_call() -> None:
assert "lineplot_options" in code


def test_plot_from_selection_includes_data_save_when_requested() -> None:
code = plot_from_selection(
selections={"time": ("1", "2")},
collapse_by_coord={},
plot_kind="lineplot",
plot_options={"mode": "default"},
save_data_path="/tmp/selection.nc",
)

assert "save_selected_field_data(pfld, save_data_path)" in code
assert "save_data_path = '/tmp/selection.nc'" in code


def test_save_data_from_selection_builds_data_only_worker_code() -> None:
code = save_data_from_selection(
selections={"time": ("1", "2")},
collapse_by_coord={"time": "mean"},
save_data_path="/tmp/data-only.nc",
)

assert "pfld = get_data_for_plotting" in code
assert "save_selected_field_data(pfld, save_data_path)" in code
assert "run_line_plot(" not in code
assert "run_contour_plot(" not in code


def test_contour_property_text_normalization_compacts_linebreaks() -> None:
text = "alpha\r\n beta\n\ngamma\rdelta"
normalized = ContourOptionsController._normalize_property_cell_text(text)
Expand Down
Loading
Loading