1# Copyright (c) 2018 MetPy Developers.
2# Distributed under the terms of the BSD 3-Clause License.
3# SPDX-License-Identifier: BSD-3-Clause
4"""Test the cartopy utilities."""
5import matplotlib
6import matplotlib.pyplot as plt
7import pytest
8
9import metpy.plots as mpplots
10
11MPL_VERSION = matplotlib.__version__[:3]
12
13
14@pytest.mark.mpl_image_compare(tolerance={'3.0': 0.161}.get(MPL_VERSION, 0.053),
15                               remove_text=True)
16def test_us_county_defaults(ccrs):
17    """Test the default US county plotting."""
18    proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0)
19
20    fig = plt.figure(figsize=(12, 9))
21    ax = fig.add_subplot(1, 1, 1, projection=proj)
22    ax.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic())
23    ax.add_feature(mpplots.USCOUNTIES)
24    return fig
25
26
27@pytest.mark.mpl_image_compare(tolerance={'3.0': 0.1994}.get(MPL_VERSION, 0.092),
28                               remove_text=True)
29def test_us_county_scales(ccrs):
30    """Test US county plotting with all scales."""
31    proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0)
32
33    fig = plt.figure(figsize=(12, 9))
34    ax1 = fig.add_subplot(1, 3, 1, projection=proj)
35    ax2 = fig.add_subplot(1, 3, 2, projection=proj)
36    ax3 = fig.add_subplot(1, 3, 3, projection=proj)
37
38    for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]):
39        axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic())
40        axis.add_feature(mpplots.USCOUNTIES.with_scale(scale))
41    return fig
42
43
44@pytest.mark.mpl_image_compare(tolerance=0.053, remove_text=True)
45def test_us_states_defaults(ccrs):
46    """Test the default US States plotting."""
47    proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0)
48
49    fig = plt.figure(figsize=(12, 9))
50    ax = fig.add_subplot(1, 1, 1, projection=proj)
51    ax.set_extent([270, 280, 28, 39], ccrs.Geodetic())
52    ax.add_feature(mpplots.USSTATES)
53    return fig
54
55
56@pytest.mark.mpl_image_compare(tolerance={'3.0': 0.991}.get(MPL_VERSION, 0.092),
57                               remove_text=True)
58def test_us_states_scales(ccrs):
59    """Test the default US States plotting with all scales."""
60    proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0)
61
62    fig = plt.figure(figsize=(12, 9))
63    ax1 = fig.add_subplot(1, 3, 1, projection=proj)
64    ax2 = fig.add_subplot(1, 3, 2, projection=proj)
65    ax3 = fig.add_subplot(1, 3, 3, projection=proj)
66
67    for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]):
68        axis.set_extent([270, 280, 28, 39], ccrs.Geodetic())
69        axis.add_feature(mpplots.USSTATES.with_scale(scale))
70    return fig
71
72
73def test_cartopy_stub(monkeypatch):
74    """Test that the CartoPy stub will issue an error if CartoPy is not present."""
75    import sys
76
77    # This makes sure that cartopy is not found
78    monkeypatch.setitem(sys.modules, 'cartopy.crs', None)
79
80    ccrs = mpplots.cartopy_utils.import_cartopy()
81    with pytest.raises(AttributeError, match='without Cartopy'):
82        ccrs.PlateCarree()
83
84
85def test_plots_getattr(monkeypatch):
86    """Ensure the module-level getattr works."""
87    # Make sure the feature is missing
88    monkeypatch.delattr(mpplots.cartopy_utils, 'USSTATES', raising=False)
89    with pytest.raises(AttributeError, match='Cannot use USSTATES without Cartopy'):
90        assert not mpplots.USSTATES  # Should fail on attribute lookup before assert
91
92
93def test_plots_dir():
94    """Ensure dir() on metpy.plots works."""
95    assert 'USSTATES' in dir(mpplots)
96