Skip to content

Commit

Permalink
Merge pull request #55 from ocefpaf/use_pytest
Browse files Browse the repository at this point in the history
Use pytest
  • Loading branch information
ocefpaf authored May 20, 2024
2 parents 92f6818 + 400b161 commit b4e0063
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 140 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ jobs:
run: |
python -m pip install -e . --no-deps --force-reinstall
- name: Install unstable dependencies
if: ${{ matrix.python-version == 3.9 }}
shell: bash -l {0}
run: |
micromamba install "netcdf4<1.6.5"
- name: Default Tests
shell: bash -l {0}
run: pytest -s -rxs -v cc_plugin_ncei
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ dist
**/.DS_Store
.tox/
.cache
cc_plugin_ncei/_version.py
123 changes: 63 additions & 60 deletions cc_plugin_ncei/tests/test_base.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,74 @@
"""Tests the base functionality of the checker that should remain the same
across all of the discrete sampling geometries
"""

import numpy as np
import pytest
from compliance_checker.base import BaseCheck
from compliance_checker.tests.helpers import MockNetCDF

from cc_plugin_ncei import ncei_base
from cc_plugin_ncei.tests.helpers import MockNetCDF
from cc_plugin_ncei.tests.ncei_test_case import NCEITestCase

# TestNCEIBase


@pytest.fixture()
def nc():
"""Create a simple timeseries like NetCDF object."""
nc = MockNetCDF()
nc.createDimension("time", None)
tvar = nc.createVariable("time", "f8", ("time",))
tvar.axis = "T"
tvar.standard_name = "time"
tvar.units = "seconds since 1970-01-01"
tvar.calendar = "gregorian"
tvar[:] = np.array([1, 2], dtype="f8")
pres = nc.createVariable("pressure", "f8", ("time",))
pres.standard_name = "air_pressure"
pres.units = "Pa"
pres[:] = np.array([101.325, 101.425], dtype=np.float64)
yield nc
nc.close()

class TestNCEIBase(NCEITestCase):
"""Tests the base functionality of the checker that should remain the same
across all of the discrete sampling geometries

def test_valid_range(nc):
"""Check for defined valid range with same dtype as source variable with
two elements in min to max order.
"""
base_check = ncei_base.BaseNCEICheck()

def setUp(self):
"""Create a simple timeseries like NetCDF object."""
self.ds = MockNetCDF()
self.ds.createDimension("time", None)
tvar = self.ds.createVariable("time", "f8", ("time",))
tvar.axis = "T"
tvar.standard_name = "time"
tvar.units = "seconds since 1970-01-01"
tvar.calendar = "gregorian"
tvar[:] = np.array([1, 2], dtype="f8")
pres = self.ds.createVariable("pressure", "f8", ("time",))
pres.standard_name = "air_pressure"
pres.units = "Pa"
pres[:] = np.array([101.325, 101.425], dtype=np.float64)
self.base_check = ncei_base.BaseNCEICheck()
var = nc.variables["pressure"]
tc1 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
var.valid_range = np.array([101.325, 101.425], dtype=np.float64)
base_check._check_min_max_range(var, tc1)
assert len(tc1.messages) == 0
# list-like types get automatically converted to numpy arrays if they
# aren't a base numpy type
var.valid_range = [100, 200, 300]
tc2 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
base_check._check_min_max_range(var, tc2)
assert (
"valid_range must be a two element vector of min followed by max with the same data type as pressure"
in tc2.messages
)

def tearDown(self):
"""Ensure the NetCDF object closes after each test or if an exception is
raised.
"""
self.ds.close()

def test_valid_range(self):
"""Check for defined valid range with same dtype as source variable with
two elements in min to max order.
"""
var = self.ds.variables["pressure"]
tc1 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
var.valid_range = np.array([101.325, 101.425], dtype=np.float64)
self.base_check._check_min_max_range(var, tc1)
self.assertEqual(len(tc1.messages), 0)
# list-like types get automatically converted to numpy arrays if they
# aren't a base numpy type
var.valid_range = [100, 200, 300]
tc2 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
self.base_check._check_min_max_range(var, tc2)
self.assertTrue(
"valid_range must be a two element vector of min followed by max with the same data type as pressure"
in tc2.messages,
)
def test_valid_min_max(nc):
"""When valid_range is not defined, check for the presence of both
attributes valid_min and valid_max which are the same data type as the
data in the variable.
"""
base_check = ncei_base.BaseNCEICheck()

def test_valid_min_max(self):
"""When valid_range is not defined, check for the presence of both
attributes valid_min and valid_max which are the same data type as the
data in the variable.
"""
var = self.ds.variables["pressure"]
var.valid_min, var.valid_max = 101.325, 101.425
tc1 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
self.base_check._check_min_max_range(var, tc1)
var.valid_min, var.valid_max = "101", "102"
tc2 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
self.base_check._check_min_max_range(var, tc2)
expected = [
f"{v} attribute should exist, have the same type as pressure, and not be empty or valid_range should be defined"
for v in ["valid_min", "valid_max"]
]
self.assertEqual(expected, tc2.messages)
var = nc.variables["pressure"]
var.valid_min, var.valid_max = 101.325, 101.425
tc1 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
base_check._check_min_max_range(var, tc1)
var.valid_min, var.valid_max = "101", "102"
tc2 = ncei_base.TestCtx(BaseCheck.MEDIUM, "Test context")
base_check._check_min_max_range(var, tc2)
expected = [
f"{v} attribute should exist, have the same type as pressure, and not be empty or valid_range should be defined"
for v in ["valid_min", "valid_max"]
]
assert expected == tc2.messages
106 changes: 106 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = [
"setuptools>=42",
"setuptools-scm",
"wheel",
]

[project]
name = "cc-plugin-ncei"
description = "Compliance Checker NCEI Templates Compliance plugin"
readme = "README.md"
license = { text = "Apache-2.0" }
maintainers = [
{ name = "Benjamin Adams" },
{ name = "Bob Fratantonio" },
{ name = "Filipe Fernandes" },
{ name = "Luke Campbell" },
]
requires-python = ">=3.8"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: Apache Software License",
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering",
]
dynamic = [
"dependencies",
"version",
]

urls.documentation = "https://ioos.github.io/cc-plugin-ncei"
urls.homepage = "https://compliance.ioos.us/index.html"
urls.repository = "https://github.com/ioos/cc-plugin-ncei"

entry-points."compliance_checker.suites"."ncei-grid-1.1" = "cc_plugin_ncei.ncei_grid:NCEIGrid1_1"
entry-points."compliance_checker.suites"."ncei-grid-2.0" = "cc_plugin_ncei.ncei_grid:NCEIGrid2_0"
entry-points."compliance_checker.suites"."ncei-point-1.1" = "cc_plugin_ncei.ncei_point:NCEIPoint1_1"
entry-points."compliance_checker.suites"."ncei-point-2.0" = "cc_plugin_ncei.ncei_point:NCEIPoint2_0"
entry-points."compliance_checker.suites"."ncei-profile-incomplete-1.1" = "cc_plugin_ncei.ncei_profile:NCEIProfileIncomplete1_1"
entry-points."compliance_checker.suites"."ncei-profile-incomplete-2.0" = "cc_plugin_ncei.ncei_profile:NCEIProfileIncomplete2_0"
entry-points."compliance_checker.suites"."ncei-profile-orthogonal-1.1" = "cc_plugin_ncei.ncei_profile:NCEIProfileOrthogonal1_1"
entry-points."compliance_checker.suites"."ncei-profile-orthogonal-2.0" = "cc_plugin_ncei.ncei_profile:NCEIProfileOrthogonal2_0"
entry-points."compliance_checker.suites"."ncei-timeseries-incomplete-1.1" = "cc_plugin_ncei.ncei_timeseries:NCEITimeSeriesIncomplete1_1"
entry-points."compliance_checker.suites"."ncei-timeseries-incomplete-2.0" = "cc_plugin_ncei.ncei_timeseries:NCEITimeSeriesIncomplete2_0"
entry-points."compliance_checker.suites"."ncei-timeseries-orthogonal-1.1" = "cc_plugin_ncei.ncei_timeseries:NCEITimeSeriesOrthogonal1_1"
entry-points."compliance_checker.suites"."ncei-timeseries-orthogonal-2.0" = "cc_plugin_ncei.ncei_timeseries:NCEITimeSeriesOrthogonal2_0"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-incomplete-1.1" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileIncomplete1_1"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-incomplete-2.0" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileIncomplete2_0"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-incompletetime-orthdepth-1.1" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileIncompleteTimeOrthDepth1_1"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-incompletetime-orthdepth-2.0" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileIncompleteTimeOrthDepth2_0"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-orthogonal-1.1" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileOrthogonal1_1"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-orthogonal-2.0" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileOrthogonal2_0"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-orthtime-incompletedepth-1.1" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileOrthTimeIncompleteDepth1_1"
entry-points."compliance_checker.suites"."ncei-timeseries-profile-orthtime-incompletedepth-2.0" = "cc_plugin_ncei.ncei_timeseries_profile:NCEITimeSeriesProfileOrthTimeIncompleteDepth2_0"
entry-points."compliance_checker.suites"."ncei-trajectory-1.1" = "cc_plugin_ncei.ncei_trajectory:NCEITrajectory1_1"
entry-points."compliance_checker.suites"."ncei-trajectory-2.0" = "cc_plugin_ncei.ncei_trajectory:NCEITrajectory2_0"
entry-points."compliance_checker.suites"."ncei-trajectory-profile-incomplete-1.1" = "cc_plugin_ncei.ncei_trajectory_profile:NCEITrajectoryProfileIncomplete1_1"
entry-points."compliance_checker.suites"."ncei-trajectory-profile-incomplete-2.0" = "cc_plugin_ncei.ncei_trajectory_profile:NCEITrajectoryProfileIncomplete2_0"

entry-points."compliance_checker.suites"."ncei-trajectory-profile-orthogonal-1.1" = "cc_plugin_ncei.ncei_trajectory_profile:NCEITrajectoryProfileOrthogonal1_1"
entry-points."compliance_checker.suites"."ncei-trajectory-profile-orthogonal-2.0" = "cc_plugin_ncei.ncei_trajectory_profile:NCEITrajectoryProfileOrthogonal2_0"

[tool.setuptools]
packages = [
"cc_plugin_ncei",
]
license-files = [
"LICENSE",
]
zip-safe = false
include-package-data = true

[tool.setuptools.package-data]
cc_plugin_ncei = [
"data/*.xml",
"data/*.json",
]

[tool.setuptools.dynamic]
dependencies = { file = [
"requirements.txt",
] }
readme = { file = "README.md", content-type = "text/markdown" }

[tool.setuptools_scm]
write_to = "cc_plugin_ncei/_version.py"
write_to_template = "__version__ = '{version}'"
tag_regex = "^(?P<prefix>v)?(?P<version>[^\\+]+)(?P<suffix>.*)?$"

[tool.pytest.ini_options]
filterwarnings = [
# We try to use strings instead od floats in puporse in the tests.
"ignore::UserWarning",
]
64 changes: 0 additions & 64 deletions setup.py

This file was deleted.

16 changes: 0 additions & 16 deletions tox.ini

This file was deleted.

0 comments on commit b4e0063

Please sign in to comment.