Skip to content

Commit 200ce2f

Browse files
authored
Merge pull request #49 from bcdev/forman-improved_jl_support
Improved jupyter support
2 parents 214542c + 872fd89 commit 200ce2f

File tree

22 files changed

+748
-288
lines changed

22 files changed

+748
-288
lines changed

CHANGES.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
## Version 0.5.0 (in development)
44

5-
### Changes
5+
### Adjustments and Enhancements
6+
7+
- Added HTML styling for both CLI output (`--format html`) and rendering
8+
of `Result` objects in Jupyter notebooks.
69

710
- Rule `no-empty-chunks` has taken off the `"recommended"` settings
811
as there is no easy/efficient way to tell whether a dataset has
@@ -41,6 +44,7 @@
4144
### Other changes
4245

4346
- Added more tests so we finally reached 100% coverage.
47+
- New `PluginMeta.docs_url` property.
4448

4549
## Version 0.4.1 (from 2025-01-31)
4650

docs/todo.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,30 @@
22

33
## Required
44

5-
- populate `core` plugin by more rules, see CF site and `cf-check` tool
6-
- populate `xcube` plugin by more rules
5+
- support zarr >= 3 which we do not only because test
6+
`tests/plugins/xcube/processors/test_mldataset.py` fails
7+
(see code TODO)
8+
- validate `RuleConfig.args/kwargs` against `RuleMeta.schema`
9+
(see code TODO)
710
- enhance docs
811
- complete configuration page
912
- provide guide page
1013
- use mkdocstrings ref syntax in docstrings
1114
- provide configuration examples (use as tests?)
1215
- add `docs_url` to all existing rules
16+
- rule ref should cover rule parameters
1317

1418
## Desired
1519

1620
- project logo
21+
- add `core` rule checks recommended use of fill value
22+
- add `xcube` rule that helps to identify chunking issues
1723
- apply rule op args/kwargs validation schema
18-
- provide core rule that checks for configurable list of std attributes
1924
- measure time it takes to open a dataset and pass time into rule context
2025
so we can write a configurable rule that checks the opening time
2126
- allow outputting suggestions, if any, that are emitted by some rules
22-
- enhance styling of `Result` representation in Jupyter notebooks
23-
(check if we can expand/collapse messages with suggestions)
27+
- add CLI option
28+
- expand/collapse messages with suggestions in Jupyter notebooks
2429

2530
## Nice to have
2631

@@ -69,4 +74,3 @@ types that can read the data from a file path.
6974
- call the root element `accept(validator)` that validates the
7075
root element `validate.root()` and starts traversal of
7176
child elements.
72-

notebooks/xrlint-cli.ipynb

Lines changed: 225 additions & 89 deletions
Large diffs are not rendered by default.

notebooks/xrlint-linter.ipynb

Lines changed: 293 additions & 89 deletions
Large diffs are not rendered by default.

tests/cli/test_main.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,24 @@ def test_files_but_config_file_missing(self):
194194
self.assertIn("Error: file not found: pippo.py", result.output)
195195
self.assertEqual(1, result.exit_code)
196196

197-
def test_files_with_format_option(self):
197+
def test_files_with_format_json(self):
198198
with text_file(DEFAULT_CONFIG_FILE_YAML, self.ok_config_yaml):
199199
result = self.xrlint("-f", "json", *self.files)
200200
self.assertIn('"results": [\n', result.output)
201201
self.assertEqual(0, result.exit_code)
202202

203+
def test_files_with_format_html(self):
204+
with text_file(DEFAULT_CONFIG_FILE_YAML, self.ok_config_yaml):
205+
result = self.xrlint("-f", "html", *self.files)
206+
self.assertIn("<h3>Results</h3>", result.output)
207+
self.assertEqual(0, result.exit_code)
208+
203209
def test_file_does_not_match(self):
204210
with text_file(DEFAULT_CONFIG_FILE_YAML, no_match_config_yaml):
205211
result = self.xrlint("test.zarr")
206-
# TODO: make this assertion work
207-
# self.assertIn("No configuration matches this file.", result.output)
212+
self.assertIn(
213+
"No configuration given or matches 'test.zarr'.", result.output
214+
)
208215
self.assertEqual(1, result.exit_code)
209216

210217
def test_print_config_option(self):

tests/formatters/helpers.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,18 @@ class Rule2(RuleOp):
4545
config_object=config_obj,
4646
file_path="test.nc",
4747
messages=[
48-
Message(message="message-1", rule_id="test/rule-1", severity=2),
49-
Message(message="message-2", rule_id="test/rule-2", severity=1),
48+
Message(
49+
message="message-1",
50+
rule_id="test/rule-1",
51+
severity=2,
52+
node_path="dataset",
53+
),
54+
Message(
55+
message="message-2",
56+
rule_id="test/rule-2",
57+
severity=1,
58+
node_path="dataset",
59+
),
5060
Message(message="message-3", fatal=True),
5161
],
5262
),

tests/formatters/test_html.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from unittest import TestCase
22

3-
from xrlint.formatters.html import Html
3+
from xrlint.formatters.html import Html, HtmlText
44

55
from .helpers import get_context, get_test_results
66

@@ -13,7 +13,8 @@ def test_html(self):
1313
context=get_context(),
1414
results=results,
1515
)
16-
self.assertIsInstance(text, str)
16+
self.assertIsInstance(text, HtmlText)
17+
self.assertIs(text, text._repr_html_())
1718
self.assertIn("</p>", text)
1819

1920
def test_html_with_meta(self):
@@ -23,5 +24,6 @@ def test_html_with_meta(self):
2324
context=get_context(),
2425
results=results,
2526
)
26-
self.assertIsInstance(text, str)
27+
self.assertIsInstance(text, HtmlText)
28+
self.assertIs(text, text._repr_html_())
2729
self.assertIn("</p>", text)

tests/test_linter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from xrlint.config import Config, ConfigObject
77
from xrlint.constants import CORE_PLUGIN_NAME, NODE_ROOT_NAME
88
from xrlint.linter import Linter, new_linter
9-
from xrlint.node import AttrNode, AttrsNode, VariableNode, DatasetNode
9+
from xrlint.node import AttrNode, AttrsNode, DatasetNode, VariableNode
1010
from xrlint.plugin import new_plugin
1111
from xrlint.processor import ProcessorOp
1212
from xrlint.result import Message, Result

tests/test_result.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ def test_repr_html(self):
6969
)
7070
html = result._repr_html_()
7171
self.assertIsInstance(html, str)
72-
self.assertEqual('<p role="file">test.zarr - ok</p>\n', html)
72+
self.assertIn("ok", html)
73+
self.assertIn("<div", html)
7374

7475
result = Result.new(
7576
config_object=ConfigObject(),

xrlint/_linter/apply.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from xrlint.node import AttrNode, AttrsNode, VariableNode, DatasetNode
1+
from xrlint.node import AttrNode, AttrsNode, DatasetNode, VariableNode
22
from xrlint.rule import RuleConfig, RuleExit, RuleOp
33

44
from ..constants import NODE_ROOT_NAME

0 commit comments

Comments
 (0)