json2xml 7.0.0__tar.gz → 7.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {json2xml-7.0.0 → json2xml-7.0.1}/HISTORY.rst +6 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/PKG-INFO +1 -1
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/__init__.py +1 -1
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/cli.py +9 -3
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml.egg-info/PKG-INFO +1 -1
- {json2xml-7.0.0 → json2xml-7.0.1}/pyproject.toml +1 -1
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_cli.py +54 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/AUTHORS.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/CONTRIBUTING.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/LICENSE +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/MANIFEST.in +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/README.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/Makefile +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/authors.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/benchmarks.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/conf.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/contributing.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/history.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/index.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/installation.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/json2xml.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/make.bat +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/modules.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/readme.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/rust_memory_benchmark.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/docs/usage.rst +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/backend_selector.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/dicttoxml.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/dicttoxml_fast.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/json2xml.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/types.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml/utils.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml.egg-info/SOURCES.txt +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml.egg-info/dependency_links.txt +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml.egg-info/entry_points.txt +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml.egg-info/requires.txt +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/json2xml.egg-info/top_level.txt +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/setup.cfg +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/setup.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/__init__.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/conftest.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_backend_selector.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_benchmark_multi_python.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_benchmark_security_hardening.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_dict2xml.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_dicttoxml_fast_fallback.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_dicttoxml_unit.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_json2xml.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_missing_coverage.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_rust_dicttoxml.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_rust_python_parity.py +0 -0
- {json2xml-7.0.0 → json2xml-7.0.1}/tests/test_utils.py +0 -0
|
@@ -109,13 +109,14 @@ class CLIApplication:
|
|
|
109
109
|
"""Thin command adapter around input resolution, conversion, and output."""
|
|
110
110
|
|
|
111
111
|
def read_input(self, options: CLIConversionOptions) -> JSONValue:
|
|
112
|
-
|
|
112
|
+
# None means omitted; explicit empty values still require source validation.
|
|
113
|
+
if options.url is not None:
|
|
113
114
|
try:
|
|
114
115
|
return readfromurl(options.url)
|
|
115
116
|
except URLReadError as error:
|
|
116
117
|
exit_with_error(f"Error reading from URL: {error}")
|
|
117
118
|
|
|
118
|
-
if options.string:
|
|
119
|
+
if options.string is not None:
|
|
119
120
|
try:
|
|
120
121
|
return readfromstring(options.string)
|
|
121
122
|
except StringReadError as error:
|
|
@@ -125,9 +126,14 @@ class CLIApplication:
|
|
|
125
126
|
f"({error})"
|
|
126
127
|
)
|
|
127
128
|
|
|
128
|
-
if options.input_file:
|
|
129
|
+
if options.input_file is not None:
|
|
129
130
|
if options.input_file == "-":
|
|
130
131
|
return read_from_stdin()
|
|
132
|
+
if not options.input_file:
|
|
133
|
+
exit_with_error(
|
|
134
|
+
"Error: Empty JSON file path. "
|
|
135
|
+
"Pass a JSON file, use - for stdin, or provide --string/--url."
|
|
136
|
+
)
|
|
131
137
|
if not Path(options.input_file).is_file():
|
|
132
138
|
exit_with_error(
|
|
133
139
|
f"Error: JSON file not found: {options.input_file}. "
|
|
@@ -218,6 +218,45 @@ class TestCLI:
|
|
|
218
218
|
assert result.returncode == 1
|
|
219
219
|
assert "Invalid JSON in --string input" in result.stderr
|
|
220
220
|
|
|
221
|
+
# @lat: [[tests#CLI input resolution#Explicit empty string rejects piped stdin]]
|
|
222
|
+
def test_empty_string_does_not_fall_back_to_stdin(self) -> None:
|
|
223
|
+
"""Test an explicit empty string remains the selected input source."""
|
|
224
|
+
result = subprocess.run(
|
|
225
|
+
[sys.executable, "-m", "json2xml.cli", "-s", ""],
|
|
226
|
+
input='{"stdin": "unexpected"}',
|
|
227
|
+
capture_output=True,
|
|
228
|
+
text=True,
|
|
229
|
+
)
|
|
230
|
+
assert result.returncode == 1
|
|
231
|
+
assert "Invalid JSON in --string input" in result.stderr
|
|
232
|
+
assert result.stdout == ""
|
|
233
|
+
|
|
234
|
+
# @lat: [[tests#CLI input resolution#Explicit empty URL rejects piped stdin]]
|
|
235
|
+
def test_empty_url_does_not_fall_back_to_stdin(self) -> None:
|
|
236
|
+
"""Test an explicit empty URL remains the selected input source."""
|
|
237
|
+
result = subprocess.run(
|
|
238
|
+
[sys.executable, "-m", "json2xml.cli", "-u", ""],
|
|
239
|
+
input='{"stdin": "unexpected"}',
|
|
240
|
+
capture_output=True,
|
|
241
|
+
text=True,
|
|
242
|
+
)
|
|
243
|
+
assert result.returncode == 1
|
|
244
|
+
assert "Error reading from URL" in result.stderr
|
|
245
|
+
assert result.stdout == ""
|
|
246
|
+
|
|
247
|
+
# @lat: [[tests#CLI input resolution#Explicit empty file path rejects piped stdin]]
|
|
248
|
+
def test_empty_file_path_does_not_fall_back_to_stdin(self) -> None:
|
|
249
|
+
"""Test an explicit empty file path remains the selected input source."""
|
|
250
|
+
result = subprocess.run(
|
|
251
|
+
[sys.executable, "-m", "json2xml.cli", ""],
|
|
252
|
+
input='{"stdin": "unexpected"}',
|
|
253
|
+
capture_output=True,
|
|
254
|
+
text=True,
|
|
255
|
+
)
|
|
256
|
+
assert result.returncode == 1
|
|
257
|
+
assert "Empty JSON file path" in result.stderr
|
|
258
|
+
assert result.stdout == ""
|
|
259
|
+
|
|
221
260
|
def test_no_input_error(self) -> None:
|
|
222
261
|
"""Test error when no input is provided."""
|
|
223
262
|
# Force isatty to return True by using a pty-like environment
|
|
@@ -607,6 +646,21 @@ class TestCLIUnitTests:
|
|
|
607
646
|
captured = capsys.readouterr()
|
|
608
647
|
assert "Error reading from URL" in captured.err
|
|
609
648
|
|
|
649
|
+
# @lat: [[tests#CLI failure messages#Empty file path names the empty source]]
|
|
650
|
+
def test_read_input_empty_file_path(self, capsys: CaptureFixture[str]) -> None:
|
|
651
|
+
"""Test read_input rejects an explicitly empty file path."""
|
|
652
|
+
args = MagicMock()
|
|
653
|
+
args.url = None
|
|
654
|
+
args.string = None
|
|
655
|
+
args.input_file = ""
|
|
656
|
+
|
|
657
|
+
with pytest.raises(SystemExit) as exc_info:
|
|
658
|
+
read_input(args)
|
|
659
|
+
|
|
660
|
+
assert exc_info.value.code == 1
|
|
661
|
+
captured = capsys.readouterr()
|
|
662
|
+
assert "Empty JSON file path" in captured.err
|
|
663
|
+
|
|
610
664
|
def test_read_input_json_file_error(self, capsys: CaptureFixture[str]) -> None:
|
|
611
665
|
"""Test read_input handles JSON file read errors."""
|
|
612
666
|
from json2xml.utils import JSONReadError
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|