Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ exclude = ["**/*.ipynb"]
xrlint = "xrlint.cli.main:main"

[project.optional-dependencies]
acdd = [
"isodate>=0.7.2",
Comment thread
abkfenris marked this conversation as resolved.
Outdated
]

[dependency-groups]
dev = [
# Development tools
"build",
Expand Down Expand Up @@ -93,3 +98,6 @@ Documentation = "https://bcdev.github.io/xrlint"
Repository = "https://github.com/bcdev/xrlint"
Changelog = "https://github.com/bcdev/xrlint/blob/main/CHANGES.md"
Issues = "https://github.com/bcdev/xrlint/issues"

[tool.uv.pip]
all-extras = true
34 changes: 34 additions & 0 deletions tests/plugins/acdd/rules/test_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import xarray as xr
from xrlint.testing import RuleTest, RuleTester

from xrlint.plugins.acdd.rules.attributes import (
Attributes_1_3_Highly_Reccomended,
)

valid_1_3_highly_rec_dataset = xr.Dataset(
attrs={
"title": "Tis only a test",
Comment thread
abkfenris marked this conversation as resolved.
Outdated
"summary": "This is only a test dataset.",
"keywords": "test, example, sample",
"conventions": "ACDD-1.3",
},
)
invalid_1_3_highly_rec_dataset = xr.Dataset()


Attributes_1_3_Highly_ReccomendedTest = RuleTester.define_test(
"1.3_attrs_highly_recommended",
Attributes_1_3_Highly_Reccomended,
valid=[RuleTest(dataset=valid_1_3_highly_rec_dataset)],
invalid=[
RuleTest(
dataset=invalid_1_3_highly_rec_dataset,
expected=[
"Missing highly recommended attribute 'title'",
"Missing highly recommended attribute 'keywords'",
"Missing highly recommended attribute 'summary'",
"Missing highly recommended attribute 'conventions'",
],
),
],
)
35 changes: 35 additions & 0 deletions tests/plugins/acdd/rules/test_conventions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import xarray as xr
from xrlint.testing import RuleTest, RuleTester

from xrlint.plugins.acdd.rules.conventions import Conventions

valid_dataset_0 = xr.Dataset(attrs={"Conventions": "ACDD-1.3"})

invalid_dataset_0 = xr.Dataset()
invalid_dataset_1 = xr.Dataset(attrs={"Conventions": "ACDD-1.2"})
invalid_dataset_2 = xr.Dataset(attrs={"Conventions": 1.3})


ConventionsTest = RuleTester.define_test(
"1.3_conventions",
Conventions,
valid=[
RuleTest(dataset=valid_dataset_0),
],
invalid=[
RuleTest(
dataset=invalid_dataset_0,
expected=["Missing attribute 'Conventions'."],
),
RuleTest(
dataset=invalid_dataset_1,
expected=[
"Attribute 'Conventions' needs to contain 'ACDD-1.3' in addition to the current: 'ACDD-1.2'",
],
),
RuleTest(
dataset=invalid_dataset_2,
expected=["Invalid attribute 'Conventions': 1.3"],
),
],
)
26 changes: 26 additions & 0 deletions tests/plugins/acdd/rules/test_id_blanks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import xarray as xr
from xrlint.testing import RuleTest, RuleTester

from xrlint.plugins.acdd.rules.no_id_blanks import NoBlanksInID

valid_dataset_0 = xr.Dataset(attrs={"id": "testind_dataset"})

invalid_dataset_0 = xr.Dataset()
invalid_dataset_1 = xr.Dataset(attrs={"id": "testing dataset"})


IdBlanksTest = RuleTester.define_test(
"1.3_no_blanks_in_id",
NoBlanksInID,
valid=[RuleTest(dataset=valid_dataset_0)],
invalid=[
RuleTest(
dataset=invalid_dataset_0,
expected=["Missing attribute 'id'"],
),
RuleTest(
dataset=invalid_dataset_1,
expected=["There should be no blanks in the id field"],
),
],
)
61 changes: 61 additions & 0 deletions tests/plugins/acdd/rules/test_iso_dates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import xarray as xr
from xrlint.testing import RuleTest, RuleTester

from xrlint.plugins.acdd.rules.iso_dates import IsoDates

valid_dataset_0 = xr.Dataset(attrs={"date_created": "2023-10-05T12:34:56Z"})
valid_dataset_1 = xr.Dataset(attrs={"date_modified": "2023-10-05"})
valid_dataset_2 = xr.Dataset(attrs={"date_issued": "2023-10-05T12:34:56+00:00"})
valid_dataset_3 = xr.Dataset(
attrs={"date_metadata_modified": "2023-10-05T12:34:56-05:00"},
)
valid_dataset_4 = xr.Dataset() # No date attributes


invalid_dataset_0 = xr.Dataset(attrs={"date_created": "10/05/2023"})
invalid_dataset_1 = xr.Dataset(attrs={"date_issued": "2023-13-05"})
invalid_dataset_2 = xr.Dataset(attrs={"date_modified": "2023-10-05 12:34:56"})
invalid_dataset_3 = xr.Dataset(attrs={"date_metadata_modified": "2023/10/05"})
invalid_dataset_4 = xr.Dataset(
attrs={"date_created": "2023-10-05T25:34:56Z"},
) # Invalid hour

IsoDatesTest = RuleTester.define_test(
"1.3_dates_iso_format",
IsoDates,
valid=[
RuleTest(dataset=valid_dataset_0),
RuleTest(dataset=valid_dataset_1),
RuleTest(dataset=valid_dataset_2),
RuleTest(dataset=valid_dataset_3),
RuleTest(dataset=valid_dataset_4),
],
invalid=[
RuleTest(
dataset=invalid_dataset_0,
expected=["Attribute 'date_created' is not in ISO format: '10/05/2023'"],
),
RuleTest(
dataset=invalid_dataset_1,
expected=["Attribute 'date_issued' is not in ISO format: '2023-13-05'"],
),
RuleTest(
dataset=invalid_dataset_2,
expected=[
"Attribute 'date_modified' is not in ISO format: '2023-10-05 12:34:56'",
],
),
RuleTest(
dataset=invalid_dataset_3,
expected=[
"Attribute 'date_metadata_modified' is not in ISO format: '2023/10/05'",
],
),
RuleTest(
dataset=invalid_dataset_4,
expected=[
"Attribute 'date_created' is not in ISO format: '2023-10-05T25:34:56Z'",
],
),
],
)
28 changes: 28 additions & 0 deletions tests/plugins/acdd/rules/test_metadata_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import xarray as xr
from xrlint.testing import RuleTest, RuleTester

from xrlint.plugins.acdd.rules.metadata_link import MetadataLink

valid_dataset_0 = xr.Dataset(attrs={"metadata_link": "http://example.com/metadata"})
valid_dataset_1 = xr.Dataset(attrs={"metadata_link": "https://example.com/metadata"})
valid_dataset_2 = xr.Dataset()

invalid_dataset_0 = xr.Dataset(attrs={"metadata_link": "example.com/metadata"})

Metadata_LinkTest = RuleTester.define_test(
"1.3_metadata_link",
MetadataLink,
valid=[
RuleTest(dataset=valid_dataset_0),
RuleTest(dataset=valid_dataset_1),
RuleTest(dataset=valid_dataset_2),
],
invalid=[
RuleTest(
dataset=invalid_dataset_0,
expected=[
"Metadata URL should include http:// or https://: 'example.com/metadata'",
],
),
],
)
38 changes: 38 additions & 0 deletions tests/plugins/acdd/test_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from unittest import TestCase

from xrlint.plugins.acdd import export_plugin


class TestACDDPlugin(TestCase):
def test_rules_complete(self):
plugin = export_plugin()
self.assertEqual(
{
"1.3_conventions",
"1.0_attrs_suggested",
"1.0_attrs_highly_recommended",
"1.0_attrs_recommended",
"1.3_attrs_recommended",
"1.3_attrs_suggested",
"1.3_attrs_highly_recommended",
"1.3_no_blanks_in_id",
"1.3_metadata_link",
"1.3_dates_iso_format",
},
set(plugin.rules.keys()),
)

def test_configs_complete(self):
plugin = export_plugin()
self.assertEqual(
{
"recommended",
"acdd_1.3",
"acdd_1.3_strict_reccomended",
"acdd_1.3_strict",
"acdd_1.3_warn",
"acdd_1.1",
"acdd_1.0",
},
set(plugin.configs.keys()),
)
89 changes: 89 additions & 0 deletions xrlint/plugins/acdd/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from xrlint.plugin import Plugin
from xrlint.util.importutil import import_submodules


def export_plugin() -> Plugin:
from .plugin import plugin

import_submodules("xrlint.plugins.acdd.rules")

common_configs = [
{
"plugins": {
"acdd": plugin,
}
}
]

rules_1_0 = {
"acdd/1.0-attrs-highly-recommended": "error",
"acdd/1.0-attrs-recommended": "warn",
"acdd/1.0-attrs-suggested": "warn",
}

rules_1_1 = {
"acdd/1.1-attrs-highly-recommended": "error",
"acdd/1.1-attrs-recommended": "warn",
"acdd/1.1-attrs-suggested": "warn",
}

rules_1_3 = {
"acdd/1.3-conventions": "error",
"acdd/1.3-attrs-highly-recommended": "error",
"acdd/1.3-attrs-recommended": "warn",
"acdd/1.3-attrs-suggested": "warn",
"acdd/1.3-no-blanks-in-id": "warn",
"acdd/1.3-metadata-link": "warn",
"acdd/1.3-dates-iso-format": "warn",
}

plugin.define_config(
"recommended", [*common_configs, {"name": "recommended", "rules": rules_1_3}]
)

plugin.define_config(
"acdd_1.3", [*common_configs, {"name": "ACDD 1.3", "rules": rules_1_3}]
)

plugin.define_config(
"acdd_1.3_strict_reccomended",
[
*common_configs,
{
"name": "ACDD 1.3 (strict recommended)",
"rules": {
**rules_1_3,
"1.3-attrs-recommended": "error",
},
},
],
)

plugin.define_config(
"acdd_1.3_strict",
[
*common_configs,
{"name": "ACDD 1.3 (strict)", "rules": dict.fromkeys(rules_1_3, "error")},
],
)

plugin.define_config(
"acdd_1.3_warn",
[
*common_configs,
{
"name": "ACDD 1.3 (as warnings)",
"rules": dict.fromkeys(rules_1_3, "warn"),
},
],
)

plugin.define_config(
"acdd_1.1", [*common_configs, {"name": "ACDD 1.1", "rules": rules_1_1}]
)

plugin.define_config(
"acdd_1.0", [*common_configs, {"name": "ACDD 1.0", "rules": rules_1_0}]
)

return plugin
7 changes: 7 additions & 0 deletions xrlint/plugins/acdd/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from xrlint.plugin import new_plugin

plugin = new_plugin(
"acdd",
"1.3",
docs_url="https://wiki.esipfed.org/Attribute_Convention_for_Data_Discovery_1-3",
)
Loading