test_bad()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
c 0
b 0
f 0
dl 0
loc 16
rs 8
1
# Copyright (c) 2017 MetPy Developers.
2
# Distributed under the terms of the BSD 3-Clause License.
3
# SPDX-License-Identifier: BSD-3-Clause
4
r"""Tests the operation of MetPy's unit support code."""
5
6
import sys
7
8
import matplotlib.pyplot as plt
9
import pytest
10
11
from metpy.testing import set_agg_backend  # noqa: F401
12
from metpy.units import check_units, units
13
14
15
@pytest.mark.mpl_image_compare(tolerance=0, remove_text=True)
16
def test_axhline():
17
    r"""Ensure that passing a quantity to axhline does not error."""
18
    fig, ax = plt.subplots()
19
    ax.axhline(930 * units('mbar'))
20
    ax.set_ylim(900, 950)
21
    ax.set_ylabel('')
22
    return fig
23
24
25
@pytest.mark.mpl_image_compare(tolerance=0, remove_text=True)
26
def test_axvline():
27
    r"""Ensure that passing a quantity to axvline does not error."""
28
    fig, ax = plt.subplots()
29
    ax.axvline(0 * units('degC'))
30
    ax.set_xlim(-1, 1)
31
    ax.set_xlabel('')
32
    return fig
33
34
#
35
# Tests for unit-checking decorator
36
#
37
38
39
def unit_calc(temp, press, dens, mixing, unitless_const):
40
    r"""Stub calculation for testing unit checking."""
41
    pass
42
43
44
test_funcs = [
45
    check_units('[temperature]', '[pressure]', dens='[mass]/[volume]',
46
                mixing='[dimensionless]')(unit_calc),
47
    check_units(temp='[temperature]', press='[pressure]', dens='[mass]/[volume]',
48
                mixing='[dimensionless]')(unit_calc),
49
    check_units('[temperature]', '[pressure]', '[mass]/[volume]',
50
                '[dimensionless]')(unit_calc)]
51
52
53
@pytest.mark.parametrize('func', test_funcs, ids=['some kwargs', 'all kwargs', 'all pos'])
54
def test_good_units(func):
55
    r"""Test that unit checking passes good units regardless."""
56
    func(30 * units.degC, 1000 * units.mbar, 1.0 * units('kg/m^3'), 1, 5.)
57
58
59
test_params = [((30 * units.degC, 1000 * units.mb, 1 * units('kg/m^3'), 1, 5 * units('J/kg')),
60
                {}, [('press', '[pressure]', 'millibarn')]),
61
               ((30, 1000, 1.0, 1, 5.), {}, [('press', '[pressure]', 'none'),
62
                                             ('temp', '[temperature]', 'none'),
63
                                             ('dens', '[mass]/[volume]', 'none')]),
64
               ((30, 1000 * units.mbar),
65
                {'dens': 1.0 * units('kg / m'), 'mixing': 5 * units.m, 'unitless_const': 2},
66
                [('temp', '[temperature]', 'none'),
67
                 ('dens', '[mass]/[volume]', 'kilogram / meter'),
68
                 ('mixing', '[dimensionless]', 'meter')])]
69
70
71
@pytest.mark.skipif(sys.version_info < (3, 3), reason='Unit checking requires Python >= 3.3')
72
@pytest.mark.parametrize('func', test_funcs, ids=['some kwargs', 'all kwargs', 'all pos'])
73
@pytest.mark.parametrize('args,kwargs,bad_parts', test_params,
74
                         ids=['one bad arg', 'all args no units', 'mixed args'])
75
def test_bad(func, args, kwargs, bad_parts):
76
    r"""Test that unit checking flags appropriate arguments."""
77
    with pytest.raises(ValueError) as exc:
78
        func(*args, **kwargs)
79
80
    message = str(exc.value)
81
    assert func.__name__ in message
82
    for param in bad_parts:
83
        assert '`{}` requires "{}" but given "{}"'.format(*param) in message
84
85
        # Should never complain about the const argument
86
        assert 'unitless_const' not in message
87