From 3e1266386701d84c67df29d9b2d4bddbdff1e232 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 15 Oct 2024 10:37:00 +0800 Subject: [PATCH] Split tests in test_clib.py into mutliple smaller test files --- pygmt/tests/test_clib.py | 343 +------------------ pygmt/tests/test_clib_call_module.py | 88 +++++ pygmt/tests/test_clib_create_data.py | 98 ++++++ pygmt/tests/test_clib_dataarray_to_matrix.py | 117 +++++++ pygmt/tests/test_clib_extract_region.py | 48 +++ pygmt/tests/test_clib_write_data.py | 29 ++ 6 files changed, 381 insertions(+), 342 deletions(-) create mode 100644 pygmt/tests/test_clib_call_module.py create mode 100644 pygmt/tests/test_clib_create_data.py create mode 100644 pygmt/tests/test_clib_dataarray_to_matrix.py create mode 100644 pygmt/tests/test_clib_extract_region.py create mode 100644 pygmt/tests/test_clib_write_data.py diff --git a/pygmt/tests/test_clib.py b/pygmt/tests/test_clib.py index 7747c1551bc..c5727e16692 100644 --- a/pygmt/tests/test_clib.py +++ b/pygmt/tests/test_clib.py @@ -3,16 +3,11 @@ """ from contextlib import contextmanager -from pathlib import Path -import numpy as np -import numpy.testing as npt import pytest -import xarray as xr from packaging.version import Version -from pygmt import Figure, clib +from pygmt import clib from pygmt.clib import required_gmt_version -from pygmt.clib.conversion import dataarray_to_matrix from pygmt.clib.session import FAMILIES, VIAS from pygmt.exceptions import ( GMTCLibError, @@ -20,9 +15,6 @@ GMTInvalidInput, GMTVersionError, ) -from pygmt.helpers import GMTTempFile - -POINTS_DATA = Path(__file__).parent / "data" / "points.txt" @contextmanager @@ -129,82 +121,6 @@ def test_destroy_session_fails(): ses.destroy() -@pytest.mark.benchmark -def test_call_module(): - """ - Call a GMT module by passing a list of arguments. - """ - with clib.Session() as lib: - with GMTTempFile() as out_fname: - lib.call_module("info", [str(POINTS_DATA), "-C", f"->{out_fname.name}"]) - assert Path(out_fname.name).stat().st_size > 0 - output = out_fname.read().strip() - assert output == "11.5309 61.7074 -2.9289 7.8648 0.1412 0.9338" - - -def test_call_module_argument_string(): - """ - Call a GMT module by passing a single argument string. - """ - with clib.Session() as lib: - with GMTTempFile() as out_fname: - lib.call_module("info", f"{POINTS_DATA} -C ->{out_fname.name}") - assert Path(out_fname.name).stat().st_size > 0 - output = out_fname.read().strip() - assert output == "11.5309 61.7074 -2.9289 7.8648 0.1412 0.9338" - - -def test_call_module_empty_argument(): - """ - call_module should work if an empty string or an empty list is passed as argument. - """ - Figure() - with clib.Session() as lib: - lib.call_module("logo", "") - with clib.Session() as lib: - lib.call_module("logo", []) - - -def test_call_module_invalid_argument_type(): - """ - call_module only accepts a string or a list of strings as module arguments. - """ - with clib.Session() as lib: - with pytest.raises(GMTInvalidInput): - lib.call_module("get", ("FONT_TITLE", "FONT_TAG")) - - -def test_call_module_invalid_arguments(): - """ - call_module should fail for invalid module arguments. - """ - with clib.Session() as lib: - with pytest.raises(GMTCLibError): - lib.call_module("info", ["bogus-data.bla"]) - - -def test_call_module_invalid_name(): - """ - call_module should fail when an invalid module name is given. - """ - with clib.Session() as lib: - with pytest.raises(GMTCLibError): - lib.call_module("meh", []) - - -def test_call_module_error_message(): - """ - Check if the GMT error message was captured when calling a module. - """ - with clib.Session() as lib: - with pytest.raises(GMTCLibError) as exc_info: - lib.call_module("info", ["bogus-data.bla"]) - assert "Module 'info' failed with status code" in exc_info.value.args[0] - assert ( - "gmtinfo [ERROR]: Cannot find file bogus-data.bla" in exc_info.value.args[0] - ) - - def test_method_no_session(): """ Fails when not in a session. @@ -268,263 +184,6 @@ def test_parse_constant_fails(): ) -def test_create_data_dataset(): - """ - Run the function to make sure it doesn't fail badly. - """ - with clib.Session() as lib: - # Dataset from vectors - data_vector = lib.create_data( - family="GMT_IS_DATASET|GMT_VIA_VECTOR", - geometry="GMT_IS_POINT", - mode="GMT_CONTAINER_ONLY", - dim=[10, 20, 1, 0], # columns, rows, layers, dtype - ) - # Dataset from matrices - data_matrix = lib.create_data( - family="GMT_IS_DATASET|GMT_VIA_MATRIX", - geometry="GMT_IS_POINT", - mode="GMT_CONTAINER_ONLY", - dim=[10, 20, 1, 0], - ) - assert data_vector != data_matrix - - -def test_create_data_grid_dim(): - """ - Create a grid ignoring range and inc. - """ - with clib.Session() as lib: - # Grids from matrices using dim - lib.create_data( - family="GMT_IS_GRID|GMT_VIA_MATRIX", - geometry="GMT_IS_SURFACE", - mode="GMT_CONTAINER_ONLY", - dim=[10, 20, 1, 0], - ) - - -def test_create_data_grid_range(): - """ - Create a grid specifying range and inc instead of dim. - """ - with clib.Session() as lib: - # Grids from matrices using range and int - lib.create_data( - family="GMT_IS_GRID|GMT_VIA_MATRIX", - geometry="GMT_IS_SURFACE", - mode="GMT_CONTAINER_ONLY", - ranges=[150.0, 250.0, -20.0, 20.0], - inc=[0.1, 0.2], - ) - - -def test_create_data_fails(): - """ - Check that create_data raises exceptions for invalid input and output. - """ - # Passing in invalid mode - with pytest.raises(GMTInvalidInput): - with clib.Session() as lib: - lib.create_data( - family="GMT_IS_DATASET", - geometry="GMT_IS_SURFACE", - mode="Not_a_valid_mode", - dim=[0, 0, 1, 0], - ranges=[150.0, 250.0, -20.0, 20.0], - inc=[0.1, 0.2], - ) - # Passing in invalid geometry - with pytest.raises(GMTInvalidInput): - with clib.Session() as lib: - lib.create_data( - family="GMT_IS_GRID", - geometry="Not_a_valid_geometry", - mode="GMT_CONTAINER_ONLY", - dim=[0, 0, 1, 0], - ranges=[150.0, 250.0, -20.0, 20.0], - inc=[0.1, 0.2], - ) - - # If the data pointer returned is None (NULL pointer) - with clib.Session() as lib: - with mock(lib, "GMT_Create_Data", returns=None): - with pytest.raises(GMTCLibError): - lib.create_data( - family="GMT_IS_DATASET", - geometry="GMT_IS_SURFACE", - mode="GMT_CONTAINER_ONLY", - dim=[11, 10, 2, 0], - ) - - -def test_extract_region_fails(): - """ - Check that extract region fails if nothing has been plotted. - """ - Figure() - with pytest.raises(GMTCLibError): - with clib.Session() as lib: - lib.extract_region() - - -def test_extract_region_two_figures(): - """ - Extract region should handle multiple figures existing at the same time. - """ - # Make two figures before calling extract_region to make sure that it's - # getting from the current figure, not the last figure. - fig1 = Figure() - region1 = np.array([0, 10, -20, -10]) - fig1.coast(region=region1, projection="M6i", frame=True, land="black") - - fig2 = Figure() - fig2.basemap(region="US.HI+r5", projection="M6i", frame=True) - - # Activate the first figure and extract the region from it - # Use in a different session to avoid any memory problems. - with clib.Session() as lib: - lib.call_module("figure", [fig1._name, "-"]) - with clib.Session() as lib: - wesn1 = lib.extract_region() - npt.assert_allclose(wesn1, region1) - - # Now try it with the second one - with clib.Session() as lib: - lib.call_module("figure", [fig2._name, "-"]) - with clib.Session() as lib: - wesn2 = lib.extract_region() - npt.assert_allclose(wesn2, np.array([-165.0, -150.0, 15.0, 25.0])) - - -def test_write_data_fails(): - """ - Check that write data raises an exception for non-zero return codes. - """ - # It's hard to make the C API function fail without causing a Segmentation - # Fault. Can't test this if by giving a bad file name because if - # output=='', GMT will just write to stdout and spaces are valid file - # names. Use a mock instead just to exercise this part of the code. - with clib.Session() as lib: - with mock(lib, "GMT_Write_Data", returns=1): - with pytest.raises(GMTCLibError): - lib.write_data( - "GMT_IS_VECTOR", - "GMT_IS_POINT", - "GMT_WRITE_SET", - [1] * 6, - "some-file-name", - None, - ) - - -@pytest.mark.benchmark -def test_dataarray_to_matrix_works(): - """ - Check that dataarray_to_matrix returns correct output. - """ - data = np.diag(v=np.arange(3)) - x = np.linspace(start=0, stop=4, num=3) - y = np.linspace(start=5, stop=9, num=3) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - - matrix, region, inc = dataarray_to_matrix(grid) - npt.assert_allclose(actual=matrix, desired=np.flipud(data)) - npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) - npt.assert_allclose(actual=inc, desired=[x[1] - x[0], y[1] - y[0]]) - - -def test_dataarray_to_matrix_negative_x_increment(): - """ - Check if dataarray_to_matrix returns correct output with flipped x. - """ - data = np.diag(v=np.arange(3)) - x = np.linspace(start=4, stop=0, num=3) - y = np.linspace(start=5, stop=9, num=3) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - - matrix, region, inc = dataarray_to_matrix(grid) - npt.assert_allclose(actual=matrix, desired=np.flip(data, axis=(0, 1))) - npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) - npt.assert_allclose(actual=inc, desired=[abs(x[1] - x[0]), abs(y[1] - y[0])]) - - -def test_dataarray_to_matrix_negative_y_increment(): - """ - Check that dataarray_to_matrix returns correct output with flipped y. - """ - data = np.diag(v=np.arange(3)) - x = np.linspace(start=0, stop=4, num=3) - y = np.linspace(start=9, stop=5, num=3) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - - matrix, region, inc = dataarray_to_matrix(grid) - npt.assert_allclose(actual=matrix, desired=data) - npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) - npt.assert_allclose(actual=inc, desired=[abs(x[1] - x[0]), abs(y[1] - y[0])]) - - -def test_dataarray_to_matrix_negative_x_and_y_increment(): - """ - Check that dataarray_to_matrix returns correct output with flipped x/y. - """ - data = np.diag(v=np.arange(3)) - x = np.linspace(start=4, stop=0, num=3) - y = np.linspace(start=9, stop=5, num=3) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - - matrix, region, inc = dataarray_to_matrix(grid) - npt.assert_allclose(actual=matrix, desired=np.fliplr(data)) - npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) - npt.assert_allclose(actual=inc, desired=[abs(x[1] - x[0]), abs(y[1] - y[0])]) - - -def test_dataarray_to_matrix_dims_fails(): - """ - Check that it fails for > 2 dims. - """ - # Make a 3-D regular grid - data = np.ones((10, 12, 11), dtype="float32") - x = np.arange(11) - y = np.arange(12) - z = np.arange(10) - grid = xr.DataArray(data, coords=[("z", z), ("y", y), ("x", x)]) - with pytest.raises(GMTInvalidInput): - dataarray_to_matrix(grid) - - -def test_dataarray_to_matrix_irregular_inc_warning(): - """ - Check that it warns for variable increments, see also - https://github.com/GenericMappingTools/pygmt/issues/1468. - """ - data = np.ones((4, 5), dtype="float64") - x = np.linspace(0, 1, 5) - y = np.logspace(2, 3, 4) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - with pytest.warns(expected_warning=RuntimeWarning) as record: - dataarray_to_matrix(grid) - assert len(record) == 1 - - -def test_dataarray_to_matrix_zero_inc_fails(): - """ - Check that dataarray_to_matrix fails for zero increments grid. - """ - data = np.ones((5, 5), dtype="float32") - x = np.linspace(0, 1, 5) - y = np.zeros_like(x) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - with pytest.raises(GMTInvalidInput): - dataarray_to_matrix(grid) - - y = np.linspace(0, 1, 5) - x = np.zeros_like(x) - grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) - with pytest.raises(GMTInvalidInput): - dataarray_to_matrix(grid) - - def test_get_default(): """ Make sure get_default works without crashing and gives reasonable results. diff --git a/pygmt/tests/test_clib_call_module.py b/pygmt/tests/test_clib_call_module.py new file mode 100644 index 00000000000..de881b7a1d8 --- /dev/null +++ b/pygmt/tests/test_clib_call_module.py @@ -0,0 +1,88 @@ +""" +Tests for the Session.call_module method. +""" + +from pathlib import Path + +import pytest +from pygmt import Figure, clib +from pygmt.exceptions import GMTCLibError, GMTInvalidInput +from pygmt.helpers import GMTTempFile + +POINTS_DATA = Path(__file__).parent / "data" / "points.txt" + + +@pytest.mark.benchmark +def test_call_module(): + """ + Call a GMT module by passing a list of arguments. + """ + with clib.Session() as lib: + with GMTTempFile() as out_fname: + lib.call_module("info", [str(POINTS_DATA), "-C", f"->{out_fname.name}"]) + assert Path(out_fname.name).stat().st_size > 0 + output = out_fname.read().strip() + assert output == "11.5309 61.7074 -2.9289 7.8648 0.1412 0.9338" + + +def test_call_module_argument_string(): + """ + Call a GMT module by passing a single argument string. + """ + with clib.Session() as lib: + with GMTTempFile() as out_fname: + lib.call_module("info", f"{POINTS_DATA} -C ->{out_fname.name}") + assert Path(out_fname.name).stat().st_size > 0 + output = out_fname.read().strip() + assert output == "11.5309 61.7074 -2.9289 7.8648 0.1412 0.9338" + + +def test_call_module_empty_argument(): + """ + call_module should work if an empty string or an empty list is passed as argument. + """ + Figure() + with clib.Session() as lib: + lib.call_module("logo", "") + with clib.Session() as lib: + lib.call_module("logo", []) + + +def test_call_module_invalid_argument_type(): + """ + call_module only accepts a string or a list of strings as module arguments. + """ + with clib.Session() as lib: + with pytest.raises(GMTInvalidInput): + lib.call_module("get", ("FONT_TITLE", "FONT_TAG")) + + +def test_call_module_invalid_arguments(): + """ + call_module should fail for invalid module arguments. + """ + with clib.Session() as lib: + with pytest.raises(GMTCLibError): + lib.call_module("info", ["bogus-data.bla"]) + + +def test_call_module_invalid_name(): + """ + call_module should fail when an invalid module name is given. + """ + with clib.Session() as lib: + with pytest.raises(GMTCLibError): + lib.call_module("meh", []) + + +def test_call_module_error_message(): + """ + Check if the GMT error message was captured when calling a module. + """ + with clib.Session() as lib: + with pytest.raises(GMTCLibError) as exc_info: + lib.call_module("info", ["bogus-data.bla"]) + assert "Module 'info' failed with status code" in exc_info.value.args[0] + assert ( + "gmtinfo [ERROR]: Cannot find file bogus-data.bla" in exc_info.value.args[0] + ) diff --git a/pygmt/tests/test_clib_create_data.py b/pygmt/tests/test_clib_create_data.py new file mode 100644 index 00000000000..bd76c9ec4fa --- /dev/null +++ b/pygmt/tests/test_clib_create_data.py @@ -0,0 +1,98 @@ +""" +Test the Session.create_data method. +""" + +import pytest +from pygmt import clib +from pygmt.exceptions import GMTCLibError, GMTInvalidInput +from pygmt.tests.test_clib import mock + + +def test_create_data_dataset(): + """ + Run the function to make sure it doesn't fail badly. + """ + with clib.Session() as lib: + # Dataset from vectors + data_vector = lib.create_data( + family="GMT_IS_DATASET|GMT_VIA_VECTOR", + geometry="GMT_IS_POINT", + mode="GMT_CONTAINER_ONLY", + dim=[10, 20, 1, 0], # columns, rows, layers, dtype + ) + # Dataset from matrices + data_matrix = lib.create_data( + family="GMT_IS_DATASET|GMT_VIA_MATRIX", + geometry="GMT_IS_POINT", + mode="GMT_CONTAINER_ONLY", + dim=[10, 20, 1, 0], + ) + assert data_vector != data_matrix + + +def test_create_data_grid_dim(): + """ + Create a grid ignoring range and inc. + """ + with clib.Session() as lib: + # Grids from matrices using dim + lib.create_data( + family="GMT_IS_GRID|GMT_VIA_MATRIX", + geometry="GMT_IS_SURFACE", + mode="GMT_CONTAINER_ONLY", + dim=[10, 20, 1, 0], + ) + + +def test_create_data_grid_range(): + """ + Create a grid specifying range and inc instead of dim. + """ + with clib.Session() as lib: + # Grids from matrices using range and int + lib.create_data( + family="GMT_IS_GRID|GMT_VIA_MATRIX", + geometry="GMT_IS_SURFACE", + mode="GMT_CONTAINER_ONLY", + ranges=[150.0, 250.0, -20.0, 20.0], + inc=[0.1, 0.2], + ) + + +def test_create_data_fails(): + """ + Check that create_data raises exceptions for invalid input and output. + """ + # Passing in invalid mode + with pytest.raises(GMTInvalidInput): + with clib.Session() as lib: + lib.create_data( + family="GMT_IS_DATASET", + geometry="GMT_IS_SURFACE", + mode="Not_a_valid_mode", + dim=[0, 0, 1, 0], + ranges=[150.0, 250.0, -20.0, 20.0], + inc=[0.1, 0.2], + ) + # Passing in invalid geometry + with pytest.raises(GMTInvalidInput): + with clib.Session() as lib: + lib.create_data( + family="GMT_IS_GRID", + geometry="Not_a_valid_geometry", + mode="GMT_CONTAINER_ONLY", + dim=[0, 0, 1, 0], + ranges=[150.0, 250.0, -20.0, 20.0], + inc=[0.1, 0.2], + ) + + # If the data pointer returned is None (NULL pointer) + with clib.Session() as lib: + with mock(lib, "GMT_Create_Data", returns=None): + with pytest.raises(GMTCLibError): + lib.create_data( + family="GMT_IS_DATASET", + geometry="GMT_IS_SURFACE", + mode="GMT_CONTAINER_ONLY", + dim=[11, 10, 2, 0], + ) diff --git a/pygmt/tests/test_clib_dataarray_to_matrix.py b/pygmt/tests/test_clib_dataarray_to_matrix.py new file mode 100644 index 00000000000..fdaf44ec06a --- /dev/null +++ b/pygmt/tests/test_clib_dataarray_to_matrix.py @@ -0,0 +1,117 @@ +""" +Test the dataarray_to_matrix function. +""" + +import numpy as np +import numpy.testing as npt +import pytest +import xarray as xr +from pygmt.clib.conversion import dataarray_to_matrix +from pygmt.exceptions import GMTInvalidInput + + +@pytest.mark.benchmark +def test_dataarray_to_matrix_works(): + """ + Check that dataarray_to_matrix returns correct output. + """ + data = np.diag(v=np.arange(3)) + x = np.linspace(start=0, stop=4, num=3) + y = np.linspace(start=5, stop=9, num=3) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + + matrix, region, inc = dataarray_to_matrix(grid) + npt.assert_allclose(actual=matrix, desired=np.flipud(data)) + npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) + npt.assert_allclose(actual=inc, desired=[x[1] - x[0], y[1] - y[0]]) + + +def test_dataarray_to_matrix_negative_x_increment(): + """ + Check if dataarray_to_matrix returns correct output with flipped x. + """ + data = np.diag(v=np.arange(3)) + x = np.linspace(start=4, stop=0, num=3) + y = np.linspace(start=5, stop=9, num=3) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + + matrix, region, inc = dataarray_to_matrix(grid) + npt.assert_allclose(actual=matrix, desired=np.flip(data, axis=(0, 1))) + npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) + npt.assert_allclose(actual=inc, desired=[abs(x[1] - x[0]), abs(y[1] - y[0])]) + + +def test_dataarray_to_matrix_negative_y_increment(): + """ + Check that dataarray_to_matrix returns correct output with flipped y. + """ + data = np.diag(v=np.arange(3)) + x = np.linspace(start=0, stop=4, num=3) + y = np.linspace(start=9, stop=5, num=3) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + + matrix, region, inc = dataarray_to_matrix(grid) + npt.assert_allclose(actual=matrix, desired=data) + npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) + npt.assert_allclose(actual=inc, desired=[abs(x[1] - x[0]), abs(y[1] - y[0])]) + + +def test_dataarray_to_matrix_negative_x_and_y_increment(): + """ + Check that dataarray_to_matrix returns correct output with flipped x/y. + """ + data = np.diag(v=np.arange(3)) + x = np.linspace(start=4, stop=0, num=3) + y = np.linspace(start=9, stop=5, num=3) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + + matrix, region, inc = dataarray_to_matrix(grid) + npt.assert_allclose(actual=matrix, desired=np.fliplr(data)) + npt.assert_allclose(actual=region, desired=[x.min(), x.max(), y.min(), y.max()]) + npt.assert_allclose(actual=inc, desired=[abs(x[1] - x[0]), abs(y[1] - y[0])]) + + +def test_dataarray_to_matrix_dims_fails(): + """ + Check that it fails for > 2 dims. + """ + # Make a 3-D regular grid + data = np.ones((10, 12, 11), dtype="float32") + x = np.arange(11) + y = np.arange(12) + z = np.arange(10) + grid = xr.DataArray(data, coords=[("z", z), ("y", y), ("x", x)]) + with pytest.raises(GMTInvalidInput): + dataarray_to_matrix(grid) + + +def test_dataarray_to_matrix_irregular_inc_warning(): + """ + Check that it warns for variable increments, see also + https://github.com/GenericMappingTools/pygmt/issues/1468. + """ + data = np.ones((4, 5), dtype="float64") + x = np.linspace(0, 1, 5) + y = np.logspace(2, 3, 4) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + with pytest.warns(expected_warning=RuntimeWarning) as record: + dataarray_to_matrix(grid) + assert len(record) == 1 + + +def test_dataarray_to_matrix_zero_inc_fails(): + """ + Check that dataarray_to_matrix fails for zero increments grid. + """ + data = np.ones((5, 5), dtype="float32") + x = np.linspace(0, 1, 5) + y = np.zeros_like(x) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + with pytest.raises(GMTInvalidInput): + dataarray_to_matrix(grid) + + y = np.linspace(0, 1, 5) + x = np.zeros_like(x) + grid = xr.DataArray(data, coords=[("y", y), ("x", x)]) + with pytest.raises(GMTInvalidInput): + dataarray_to_matrix(grid) diff --git a/pygmt/tests/test_clib_extract_region.py b/pygmt/tests/test_clib_extract_region.py new file mode 100644 index 00000000000..bb857ab5ae8 --- /dev/null +++ b/pygmt/tests/test_clib_extract_region.py @@ -0,0 +1,48 @@ +""" +Test the Session.extract_region function. +""" + +import numpy as np +import numpy.testing as npt +import pytest +from pygmt import Figure, clib +from pygmt.exceptions import GMTCLibError + + +def test_extract_region_fails(): + """ + Check that extract region fails if nothing has been plotted. + """ + Figure() + with pytest.raises(GMTCLibError): + with clib.Session() as lib: + lib.extract_region() + + +def test_extract_region_two_figures(): + """ + Extract region should handle multiple figures existing at the same time. + """ + # Make two figures before calling extract_region to make sure that it's + # getting from the current figure, not the last figure. + fig1 = Figure() + region1 = np.array([0, 10, -20, -10]) + fig1.coast(region=region1, projection="M6i", frame=True, land="black") + + fig2 = Figure() + fig2.basemap(region="US.HI+r5", projection="M6i", frame=True) + + # Activate the first figure and extract the region from it + # Use in a different session to avoid any memory problems. + with clib.Session() as lib: + lib.call_module("figure", [fig1._name, "-"]) + with clib.Session() as lib: + wesn1 = lib.extract_region() + npt.assert_allclose(wesn1, region1) + + # Now try it with the second one + with clib.Session() as lib: + lib.call_module("figure", [fig2._name, "-"]) + with clib.Session() as lib: + wesn2 = lib.extract_region() + npt.assert_allclose(wesn2, np.array([-165.0, -150.0, 15.0, 25.0])) diff --git a/pygmt/tests/test_clib_write_data.py b/pygmt/tests/test_clib_write_data.py new file mode 100644 index 00000000000..03dfe8d7760 --- /dev/null +++ b/pygmt/tests/test_clib_write_data.py @@ -0,0 +1,29 @@ +""" +Test the Session.write_data method. +""" + +import pytest +from pygmt import clib +from pygmt.exceptions import GMTCLibError +from pygmt.tests.test_clib import mock + + +def test_write_data_fails(): + """ + Check that write data raises an exception for non-zero return codes. + """ + # It's hard to make the C API function fail without causing a Segmentation + # Fault. Can't test this if by giving a bad file name because if + # output=='', GMT will just write to stdout and spaces are valid file + # names. Use a mock instead just to exercise this part of the code. + with clib.Session() as lib: + with mock(lib, "GMT_Write_Data", returns=1): + with pytest.raises(GMTCLibError): + lib.write_data( + "GMT_IS_VECTOR", + "GMT_IS_POINT", + "GMT_WRITE_SET", + [1] * 6, + "some-file-name", + None, + )