@@ -59,24 +59,28 @@ def _cli_cache_file(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
5959
6060
6161def test_get_local_file (person_file : Path ):
62+ """`pyld get` prints a local JSON-LD file as JSON."""
6263 result = runner .invoke (cli .pyld , ['get' , str (person_file )])
6364 assert result .exit_code == 0 , result .output
6465 assert json .loads (result .stdout ) == PERSON
6566
6667
6768def test_get_from_stdin ():
69+ """`pyld get -` reads JSON-LD from standard input and prints it."""
6870 result = runner .invoke (cli .pyld , ['get' , '-' ], input = json .dumps (PERSON ))
6971 assert result .exit_code == 0 , result .output
7072 assert json .loads (result .stdout ) == PERSON
7173
7274
7375def test_get_requires_input ():
76+ """`pyld get` without an input argument exits as a usage error."""
7477 result = runner .invoke (cli .pyld , ['get' ])
7578 assert result .exit_code == 2
7679 assert 'Missing argument' in result .output
7780
7881
7982def test_get_missing_file_exits_without_traceback (tmp_path : Path , capsys ):
83+ """A missing get input exits with a traceback hint and no stack trace."""
8084 missing = tmp_path / 'missing.jsonld'
8185 with pytest .raises (SystemExit ) as exited :
8286 cli .main (['get' , str (missing )])
@@ -103,6 +107,7 @@ def test_traceback_hint_repeats_the_failed_invocation(tmp_path: Path, capsys):
103107
104108
105109def test_expand_local_file (person_file : Path ):
110+ """`pyld expand` expands a local JSON-LD file."""
106111 result = runner .invoke (cli .pyld , ['expand' , str (person_file )])
107112 assert result .exit_code == 0 , result .output
108113 assert json .loads (result .stdout ) == [
@@ -111,6 +116,7 @@ def test_expand_local_file(person_file: Path):
111116
112117
113118def test_expand_from_stdin ():
119+ """`pyld expand -` expands JSON-LD from standard input."""
114120 result = runner .invoke (cli .pyld , ['expand' , '-' ], input = json .dumps (PERSON ))
115121 assert result .exit_code == 0 , result .output
116122 assert json .loads (result .stdout ) == [
@@ -119,6 +125,7 @@ def test_expand_from_stdin():
119125
120126
121127def test_expand_with_base (tmp_path : Path ):
128+ """`--base` resolves relative IRIs during expansion."""
122129 input = {
123130 '@context' : {
124131 'knows' : {'@id' : 'http://schema.org/knows' , '@type' : '@id' },
@@ -141,6 +148,7 @@ def test_expand_with_base(tmp_path: Path):
141148
142149
143150def test_expand_with_context_from_stdin (tmp_path : Path ):
151+ """`--context -` expands using a context read from standard input."""
144152 input = {'name' : 'Ada Lovelace' }
145153 input_path = write_json (tmp_path , 'person.jsonld' , input )
146154 result = runner .invoke (
@@ -155,6 +163,7 @@ def test_expand_with_context_from_stdin(tmp_path: Path):
155163
156164
157165def test_expand_with_context_file (tmp_path : Path ):
166+ """`--context` expands using a context loaded from a local file."""
158167 context_path = write_json (
159168 tmp_path ,
160169 'context.jsonld' ,
@@ -172,6 +181,7 @@ def test_expand_with_context_file(tmp_path: Path):
172181
173182
174183def test_invalid_json_on_stdin_exits_without_traceback (monkeypatch , capsys ):
184+ """Invalid JSON on stdin exits with a traceback hint and no stack trace."""
175185 monkeypatch .setattr (sys , 'stdin' , io .StringIO ('{not-json' ))
176186 with pytest .raises (SystemExit ) as exited :
177187 cli .main (['expand' , '-' ])
@@ -199,12 +209,14 @@ def test_bare_pyld_prints_help():
199209
200210
201211def test_expand_requires_input ():
212+ """`pyld expand` without an input argument exits as a usage error."""
202213 result = runner .invoke (cli .pyld , ['expand' ])
203214 assert result .exit_code == 2
204215 assert 'Missing argument' in result .output
205216
206217
207218def test_cli_is_jsonld_11_only ():
219+ """The CLI does not expose `--processing-mode` and rejects `json-ld-1.0`."""
208220 help_result = runner .invoke (cli .pyld , ['expand' , '--help' ])
209221 assert help_result .exit_code == 0
210222 assert '--processing-mode' not in help_result .stdout
@@ -223,12 +235,14 @@ def test_cli_is_jsonld_11_only():
223235 ['compact' , 'flatten' , 'frame' , 'to-rdf' , 'from-rdf' ],
224236)
225237def test_new_commands_require_input (command : str ):
238+ """Transformation commands without an input argument exit as a usage error."""
226239 result = runner .invoke (cli .pyld , [command ])
227240 assert result .exit_code == 2
228241 assert 'Missing argument' in result .output
229242
230243
231244def test_compact_local_file_with_context_from_stdin (tmp_path : Path ):
245+ """`pyld compact` compacts a local file using a context from stdin."""
232246 input_path = write_json (tmp_path , 'person.jsonld' , PERSON )
233247 result = runner .invoke (
234248 cli .pyld ,
@@ -243,6 +257,7 @@ def test_compact_local_file_with_context_from_stdin(tmp_path: Path):
243257
244258
245259def test_compact_from_stdin_with_context_file (tmp_path : Path ):
260+ """`pyld compact` compacts stdin using a context from a local file."""
246261 context_path = write_json (tmp_path , 'context.jsonld' , {'@context' : CONTEXT })
247262 result = runner .invoke (
248263 cli .pyld ,
@@ -254,6 +269,7 @@ def test_compact_from_stdin_with_context_file(tmp_path: Path):
254269
255270
256271def test_flatten_local_file (person_file : Path ):
272+ """`pyld flatten` flattens a local JSON-LD file."""
257273 result = runner .invoke (cli .pyld , ['flatten' , str (person_file )])
258274 assert result .exit_code == 0 , result .output
259275 assert json .loads (result .stdout )[0 ]['http://schema.org/name' ] == [
@@ -262,6 +278,7 @@ def test_flatten_local_file(person_file: Path):
262278
263279
264280def test_flatten_with_context_from_stdin (tmp_path : Path ):
281+ """`pyld flatten --context -` flattens using a context from stdin."""
265282 input_path = write_json (tmp_path , 'person.jsonld' , PERSON )
266283 result = runner .invoke (
267284 cli .pyld ,
@@ -273,6 +290,7 @@ def test_flatten_with_context_from_stdin(tmp_path: Path):
273290
274291
275292def test_frame_local_file_with_frame_file (tmp_path : Path ):
293+ """`pyld frame` frames a local document with a local frame file."""
276294 input_path = write_json (tmp_path , 'person.jsonld' , IDENTIFIED_PERSON )
277295 frame_path = write_json (tmp_path , 'frame.jsonld' , FRAME )
278296 result = runner .invoke (
@@ -284,6 +302,7 @@ def test_frame_local_file_with_frame_file(tmp_path: Path):
284302
285303
286304def test_frame_with_frame_from_stdin (tmp_path : Path ):
305+ """`pyld frame` frames a local document with a frame from stdin."""
287306 input_path = write_json (tmp_path , 'person.jsonld' , IDENTIFIED_PERSON )
288307 result = runner .invoke (
289308 cli .pyld ,
@@ -307,6 +326,7 @@ def test_frame_with_frame_from_stdin(tmp_path: Path):
307326 ],
308327)
309328def test_multiple_operands_reject_stdin (command : str , secondary : str ):
329+ """Commands reject using standard input for more than one operand."""
310330 args = [command , '-' ]
311331 if command in ('compact' , 'frame' ) and not secondary .startswith ('--' ):
312332 args .append (secondary )
@@ -320,6 +340,7 @@ def test_multiple_operands_reject_stdin(command: str, secondary: str):
320340
321341
322342def test_to_rdf_local_file_writes_exact_nquads (tmp_path : Path ):
343+ """`pyld to-rdf` writes exact N-Quads for a local JSON-LD file."""
323344 input_path = write_json (tmp_path , 'person.jsonld' , IDENTIFIED_PERSON )
324345 result = runner .invoke (cli .pyld , ['to-rdf' , str (input_path )])
325346 assert result .exit_code == 0 , result .output
@@ -328,6 +349,7 @@ def test_to_rdf_local_file_writes_exact_nquads(tmp_path: Path):
328349
329350
330351def test_to_rdf_from_stdin_writes_exact_nquads ():
352+ """`pyld to-rdf -` writes exact N-Quads from standard input."""
331353 result = runner .invoke (
332354 cli .pyld ,
333355 ['to-rdf' , '-' ],
@@ -338,6 +360,7 @@ def test_to_rdf_from_stdin_writes_exact_nquads():
338360
339361
340362def test_from_rdf_local_file (tmp_path : Path ):
363+ """`pyld from-rdf` converts a local N-Quads file to JSON-LD."""
341364 input_path = write_text (tmp_path , 'person.nq' , NQUADS )
342365 result = runner .invoke (cli .pyld , ['from-rdf' , str (input_path )])
343366 assert result .exit_code == 0 , result .output
@@ -350,12 +373,14 @@ def test_from_rdf_local_file(tmp_path: Path):
350373
351374
352375def test_from_rdf_from_stdin ():
376+ """`pyld from-rdf -` converts N-Quads from standard input to JSON-LD."""
353377 result = runner .invoke (cli .pyld , ['from-rdf' , '-' ], input = NQUADS )
354378 assert result .exit_code == 0 , result .output
355379 assert json .loads (result .stdout )[0 ]['@id' ] == 'http://example.com/ada'
356380
357381
358382def test_from_rdf_rejects_remote_input ():
383+ """`pyld from-rdf` rejects remote URLs and requires a local path or `-`."""
359384 result = runner .invoke (
360385 cli .pyld ,
361386 ['from-rdf' , 'https://example.com/person.nq' ],
@@ -365,13 +390,15 @@ def test_from_rdf_rejects_remote_input():
365390
366391
367392def test_from_rdf_help_describes_only_local_input ():
393+ """`from-rdf --help` describes local path or stdin input only."""
368394 result = runner .invoke (cli .pyld , ['from-rdf' , '--help' ])
369395 assert result .exit_code == 0 , result .output
370396 assert 'Local path. Pass - to read from standard input.' in result .stdout
371397 assert 'Path or URL.' not in result .stdout
372398
373399
374400def test_print_nquads_preserves_empty_output (monkeypatch : pytest .MonkeyPatch ):
401+ """Empty N-Quads output is printed without adding a trailing newline."""
375402 monkeypatch .setattr (jsonld , 'to_rdf' , lambda * args , ** kwargs : '' )
376403 result = runner .invoke (cli .pyld , ['to-rdf' , '-' ], input = json .dumps (PERSON ))
377404 assert result .exit_code == 0 , result .output
@@ -500,6 +527,7 @@ def test_command_options_are_mapped_to_api_keys(
500527 function_name : str ,
501528 expected : dict ,
502529):
530+ """CLI flags are mapped to the corresponding JSON-LD API option keys."""
503531 captured = {}
504532
505533 def transform (* positional , options ):
@@ -537,6 +565,7 @@ def test_omitted_cli_options_do_not_override_api_defaults(
537565 function_name : str ,
538566 forced_keys : set [str ],
539567):
568+ """Omitted CLI flags leave API defaults unset except forced keys."""
540569 captured = {}
541570
542571 def transform (* positional , options ):
@@ -584,6 +613,7 @@ def test_jsonld_commands_preserve_remote_input_urls(
584613 args : list [str ],
585614 function_name : str ,
586615):
616+ """Remote input URLs are passed through to the JSON-LD API unchanged."""
587617 captured = {}
588618
589619 def transform (input_ , * positional , options ):
@@ -604,14 +634,17 @@ def transform(input_, *positional, options):
604634 ],
605635)
606636def test_document_value_preserves_remote_urls (value : str ):
637+ """`document_value` leaves remote URLs unchanged."""
607638 assert cli_input .document_value (value ) == value
608639
609640
610641def test_document_value_treats_inline_json_as_a_path ():
642+ """`document_value` treats inline JSON text as a local path."""
611643 assert cli_input .document_value ('{}' ) == Path ('{}' ).resolve ().as_uri ()
612644
613645
614646def test_missing_nquads_file_exits_without_traceback (tmp_path : Path , capsys ):
647+ """A missing from-rdf input exits with a traceback hint and no stack trace."""
615648 missing = tmp_path / 'missing.nq'
616649 with pytest .raises (SystemExit ) as exited :
617650 cli .main (['from-rdf' , str (missing )])
@@ -622,6 +655,7 @@ def test_missing_nquads_file_exits_without_traceback(tmp_path: Path, capsys):
622655
623656
624657def test_invalid_nquads_exits_without_traceback (monkeypatch , capsys ):
658+ """Invalid N-Quads on stdin exits with a traceback hint and no stack trace."""
625659 monkeypatch .setattr (sys , 'stdin' , io .StringIO ('not n-quads' ))
626660 with pytest .raises (SystemExit ) as exited :
627661 cli .main (['from-rdf' , '-' ])
@@ -632,6 +666,7 @@ def test_invalid_nquads_exits_without_traceback(monkeypatch, capsys):
632666
633667
634668def test_cache_clear (tmp_path : Path ):
669+ """`pyld cache clear` deletes the configured HTTP cache file."""
635670 cache_file = tmp_path / 'http_cache.sqlite'
636671 cache_file .write_text ('cache' , encoding = 'utf-8' )
637672 result = runner .invoke (cli .pyld , ['cache' , 'clear' ])
@@ -641,6 +676,7 @@ def test_cache_clear(tmp_path: Path):
641676
642677
643678def test_cache_clear_uses_env_var_cache_file (tmp_path : Path ):
679+ """`cache clear` deletes the cache file named by `PYLD_CACHE_FILE`."""
644680 cache_file = tmp_path / 'http_cache.sqlite'
645681 cache_file .write_text ('cache' , encoding = 'utf-8' )
646682 result = runner .invoke (cli .pyld , ['cache' , 'clear' ])
@@ -652,6 +688,7 @@ def test_cache_file_option_overrides_env_var(
652688 tmp_path : Path ,
653689 monkeypatch : pytest .MonkeyPatch ,
654690):
691+ """`--cache-file` overrides `PYLD_CACHE_FILE` for cache clear."""
655692 env_cache = tmp_path / 'from-env.sqlite'
656693 option_cache = tmp_path / 'from-option.sqlite'
657694 env_cache .write_text ('env' , encoding = 'utf-8' )
@@ -669,6 +706,7 @@ def test_cache_file_option_overrides_env_var(
669706def test_parse_location_treats_windows_drive_as_path (
670707 monkeypatch : pytest .MonkeyPatch ,
671708):
709+ """On Windows, drive-letter paths are treated as filesystem paths."""
672710 monkeypatch .setattr (cli_input .sys , 'platform' , 'win32' )
673711 for path in (
674712 r'C:\Users\ada\doc.jsonld' ,
@@ -682,29 +720,34 @@ def test_parse_location_treats_windows_drive_as_path(
682720def test_parse_location_preserves_single_letter_scheme_outside_windows (
683721 monkeypatch : pytest .MonkeyPatch ,
684722):
723+ """Outside Windows, a single-letter scheme is left as a URL."""
685724 monkeypatch .setattr (cli_input .sys , 'platform' , 'linux' )
686725 assert cli_input .parse_location ('x:document' ) == 'x:document'
687726
688727
689728def test_parse_location_preserves_http_urls ():
729+ """`parse_location` leaves HTTP(S) URLs unchanged."""
690730 assert cli_input .parse_location ('https://example.com/x.jsonld' ) == (
691731 'https://example.com/x.jsonld'
692732 )
693733
694734
695735def test_parse_location_resolves_local_path (tmp_path : Path ):
736+ """`parse_location` resolves a local path to an absolute Path."""
696737 path = write_json (tmp_path , 'person.jsonld' , {})
697738 result = cli_input .parse_location (str (path ))
698739 assert result == path .resolve ()
699740 assert isinstance (result , Path )
700741
701742
702743def test_document_url_converts_local_path_to_file_url (tmp_path : Path ):
744+ """`document_url` converts a local path to a file: URL."""
703745 path = write_json (tmp_path , 'person.jsonld' , {})
704746 assert cli_input .document_url (str (path )) == path .as_uri ()
705747
706748
707749def test_document_url_preserves_http_url ():
750+ """`document_url` leaves HTTP(S) URLs unchanged."""
708751 assert cli_input .document_url ('https://example.com/x.jsonld' ) == (
709752 'https://example.com/x.jsonld'
710753 )
@@ -714,6 +757,7 @@ def test_configured_cache_file_resolves_relative_path(
714757 tmp_path : Path ,
715758 monkeypatch : pytest .MonkeyPatch ,
716759):
760+ """`configured_cache_file` resolves a relative cache path against cwd."""
717761 monkeypatch .chdir (tmp_path )
718762 cli_state .current = State (cache_file = Path ('rel.sqlite' ))
719763 assert cli_input .configured_cache_file () == (tmp_path / 'rel.sqlite' ).resolve ()
@@ -734,6 +778,7 @@ def test_cli_entry_exits_when_cli_deps_missing(
734778 monkeypatch : pytest .MonkeyPatch ,
735779 capsys : pytest .CaptureFixture [str ],
736780):
781+ """Missing CLI dependencies exit with an install hint for `PyLD[cli]`."""
737782 from pyld .cli import entry
738783
739784 def fail ():
0 commit comments