From 343c3796272d4152b32dbbef42f0c46b58a6ee88 Mon Sep 17 00:00:00 2001 From: Vinit Kumar Date: Wed, 18 Dec 2024 11:19:01 +0530 Subject: [PATCH 1/2] fea: update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b97131e..06591d5 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,5 @@ dmypy.json .pyre/ .idea/ +.coverage +junit.xml From b4364209f547a08de18ccc19420518cc3ad33d25 Mon Sep 17 00:00:00 2001 From: Vinit Kumar Date: Wed, 18 Dec 2024 14:48:13 +0530 Subject: [PATCH 2/2] feat: add an intresting case for test failure --- .coverage | Bin 53248 -> 53248 bytes json2xml/dicttoxml.py | 2 +- junit.xml | 34 +++++++++++++++++++++++- tests/test_dict2xml.py | 2 +- tests/test_xml_escape.py | 56 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 tests/test_xml_escape.py diff --git a/.coverage b/.coverage index 672c021d25a5e0609e70b471239c8dfd0f5b4c61..a667c01f15e94008e521c565006d32d6cb5a0cde 100644 GIT binary patch delta 415 zcmZozz}&Eac>{}s2nW9@1OF@j^ZeWR=kPc4=kf>fn{E~qkmZk&=3r*9ElDjdDb@#( z@fEo_@u|hhi3O>81(lNQ%nX)Dl3B(1c}74LKq(P6W(Iv2U%#{@Gp86RD$dHxU{IB^h@CWmo0j-wfkCtJ!WkfO@#bypEW=mvAn3+I3*hQK3 z8DV_5&1@3PrU=o^6XS~&L^$~VF!2B6-^9O)-;3XdUyq-Q?+?)GCw!tj94w5SQXFEx zZ#@2fuUd&6$a7<#tlKXu!@~xWVbgm)=kk1pzdWoU9&6aly8SZI5uCLZw$1X{{~3eH~x?OZ}^|{KjOd3e*>uO Q06!};FvNK$-#xDk0C`}9Y5)KL delta 302 zcmZozz}&Eac>{}s5IcVm1OF@j^ZeWR=kPc3XYdDY78J1IXA)tbobNBH!N$yBnpK>i zXH=1!qYq=~6;w*HGBa3~q!yPH>x0Pn$rJsHfo26W@Negz%b&>~%>SDI0)G?GEL(m% zQD%Kcm|p$TlFXc9pb6{}%%%uYm^4s=O^Vr)5y|My6XS~&fM# str: Returns: str: The string of XML attributes. """ - attrstring = " ".join([f'{k}="{v}"' for k, v in attr.items()]) + attrstring = " ".join([f'{k}="{escape_xml(v)}"' for k, v in attr.items()]) return f'{" " if attrstring != "" else ""}{attrstring}' diff --git a/junit.xml b/junit.xml index fef39a8..0b3139e 100644 --- a/junit.xml +++ b/junit.xml @@ -1 +1,33 @@ - \ No newline at end of file +self = <tests.test_xml_escape.TestEscaping object at 0x1051b4aa0> + + def test_escapes_angle_brackets(self): + json_data = json.dumps({"root": {"@attrs": {"HelpText": "version <here>"}}}) + result = json2xml.Json2xml(json_data).to_xml() +> assert '"HelpText": "version &lt;here&gt;"' in result +E assert '"HelpText": "version &lt;here&gt;"' in '<?xml version="1.0" encoding="UTF-8"?>\n<all>\n\t<item type="str">{&quot;root&quot;: {&quot;@attrs&quot;: {&quot;HelpText&quot;: &quot;version &lt;here&gt;&quot;}}}</item>\n</all>\n' + +tests/test_xml_escape.py:39: AssertionErrorself = <tests.test_xml_escape.TestEscaping object at 0x1051b4740> + + def test_escapes_quotes(self): + json_data = json.dumps({"root": {"@attrs": {"Text": "\"quoted\""}}}) + result = json2xml.Json2xml(json_data).to_xml() +> assert '"Text": "\\"quoted\\""' in result +E assert '"Text": "\\"quoted\\""' in '<?xml version="1.0" encoding="UTF-8"?>\n<all>\n\t<item type="str">{&quot;root&quot;: {&quot;@attrs&quot;: {&quot;Text&quot;: &quot;\\&quot;quoted\\&quot;&quot;}}}</item>\n</all>\n' + +tests/test_xml_escape.py:44: AssertionErrorself = <tests.test_xml_escape.TestEscaping object at 0x1051b42f0> + + def test_escapes_ampersands(self): + json_data = json.dumps({"root": {"@attrs": {"Text": "this & that"}}}) + result = json2xml.Json2xml(json_data).to_xml() +> assert '"Text": "this &amp; that"' in result +E assert '"Text": "this &amp; that"' in '<?xml version="1.0" encoding="UTF-8"?>\n<all>\n\t<item type="str">{&quot;root&quot;: {&quot;@attrs&quot;: {&quot;Text&quot;: &quot;this &amp; that&quot;}}}</item>\n</all>\n' + +tests/test_xml_escape.py:49: AssertionErrorself = <tests.test_xml_escape.TestEscaping object at 0x1051b5730> + + def test_escapes_mixed_special_chars(self): + json_data = json.dumps({"root": {"@attrs": {"Text": "<tag> & \"quote\""}}}) + result = json2xml.Json2xml(json_data).to_xml() +> assert '"Text": "&lt;tag&gt; &amp; \\"quote\\""' in result +E assert '"Text": "&lt;tag&gt; &amp; \\"quote\\""' in '<?xml version="1.0" encoding="UTF-8"?>\n<all>\n\t<item type="str">{&quot;root&quot;: {&quot;@attrs&quot;: {&quot;Text&quot;: &quot;&lt;tag&gt; &amp; \\&quot;quote\\&quot;&quot;}}}</item>\n</all>\n' + +tests/test_xml_escape.py:54: AssertionError \ No newline at end of file diff --git a/tests/test_dict2xml.py b/tests/test_dict2xml.py index 7a54ab7..21d5bd5 100644 --- a/tests/test_dict2xml.py +++ b/tests/test_dict2xml.py @@ -3,7 +3,7 @@ import pytest -from json2xml import dicttoxml +from json2xml import dicttoxml, json2xml class TestDict2xml: diff --git a/tests/test_xml_escape.py b/tests/test_xml_escape.py new file mode 100644 index 0000000..8592641 --- /dev/null +++ b/tests/test_xml_escape.py @@ -0,0 +1,56 @@ +import pytest +import json + +from json2xml import dicttoxml, json2xml + + + +class TestEscaping: + def test_escaping(self): + # Test cases + test_cases = [ + { + "root": { + "@attrs": { + "Text": "this & that" + } + } + }, + { + "data": json.dumps({"key": "value & more"}) + }, + { + "mixed": { + "json_str": json.dumps({"a": "b & c"}), + "plain": "text & symbols" + } + } + ] + for i, data in enumerate(test_cases): + print(f"\nTest case {i + 1}:") + print("Input:", data) + xml = dicttoxml.dicttoxml(data, custom_root='all') + print("Output XML:") + print(xml.decode('utf-8')) + + def test_escapes_angle_brackets(self): + json_data = json.dumps({"root": {"@attrs": {"HelpText": "version "}}}) + result = json2xml.Json2xml(json_data).to_xml() + assert '"HelpText": "version <here>"' in result + + def test_escapes_quotes(self): + json_data = json.dumps({"root": {"@attrs": {"Text": "\"quoted\""}}}) + result = json2xml.Json2xml(json_data).to_xml() + assert '"Text": "\\"quoted\\""' in result + + def test_escapes_ampersands(self): + json_data = json.dumps({"root": {"@attrs": {"Text": "this & that"}}}) + result = json2xml.Json2xml(json_data).to_xml() + assert '"Text": "this & that"' in result + + def test_escapes_mixed_special_chars(self): + json_data = json.dumps({"root": {"@attrs": {"Text": " & \"quote\""}}}) + result = json2xml.Json2xml(json_data).to_xml() + assert '"Text": "<tag> & \\"quote\\""' in result + +