Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/attr escape #224

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Feat/attr escape #224

wants to merge 2 commits into from

Conversation

vinitkumar
Copy link
Owner

@vinitkumar vinitkumar commented Dec 18, 2024

Summary by Sourcery

Implement XML attribute escaping in the dicttoxml module to ensure special characters are properly handled, and add corresponding test cases to validate this functionality.

New Features:

  • Introduce XML attribute escaping in the dicttoxml module to handle special characters.

Tests:

  • Add new test cases in test_xml_escape.py to verify the correct escaping of special characters in XML attributes.

Copy link

sourcery-ai bot commented Dec 18, 2024

Reviewer's Guide by Sourcery

This PR implements XML attribute escaping functionality by modifying the attribute string generation process and adding corresponding test cases. The changes ensure that special characters in XML attributes are properly escaped to maintain valid XML structure.

Sequence diagram for XML attribute escaping process

sequenceDiagram
    participant Client
    participant DictToXml
    participant EscapeXml
    Client->>DictToXml: Call make_attrstring(attr)
    DictToXml->>EscapeXml: Call escape_xml(value)
    EscapeXml-->>DictToXml: Return escaped value
    DictToXml-->>Client: Return attribute string with escaped values
Loading

Class diagram for updated attribute string generation

classDiagram
    class DictToXml {
        +make_attrstring(attr: dict[str, Any]) str
    }
    class EscapeXml {
        +escape_xml(value: str) str
    }
    DictToXml --|> EscapeXml : uses
    note for DictToXml "Updated to use escape_xml for attribute values"
Loading

File-Level Changes

Change Details Files
Added XML attribute escaping in attribute string generation
  • Modified make_attrstring function to escape attribute values using escape_xml
  • Ensures special characters like &, <, >, and quotes are properly escaped in XML attributes
json2xml/dicttoxml.py
Added comprehensive test suite for XML escaping functionality
  • Created new test file for XML escaping scenarios
  • Added test cases for escaping angle brackets
  • Added test cases for escaping quotes
  • Added test cases for escaping ampersands
  • Added test cases for mixed special characters
tests/test_xml_escape.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @vinitkumar - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Good addition of XML attribute escaping, but please fix the failing test cases. The escaping needs to work consistently across both the json2xml and dicttoxml conversion paths.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +29 to +34
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'))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Avoid loops in tests. (no-loop-in-tests)

ExplanationAvoid complex code, like loops, in test functions.

Google's software engineering guidelines says:
"Clear tests are trivially correct upon inspection"
To reach that avoid complex code in tests:

  • loops
  • conditionals

Some ways to fix this:

  • Use parametrized tests to get rid of the loop.
  • Move the complex logic into helpers.
  • Move the complex part into pytest fixtures.

Complexity is most often introduced in the form of logic. Logic is defined via the imperative parts of programming languages such as operators, loops, and conditionals. When a piece of code contains logic, you need to do a bit of mental computation to determine its result instead of just reading it off of the screen. It doesn't take much logic to make a test more difficult to reason about.

Software Engineering at Google / Don't Put Logic in Tests

Copy link

codecov bot commented Dec 18, 2024

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
90 4 86 0
View the full list of 3 ❄️ flaky tests
tests.test_xml_escape.TestEscaping::test_escapes_mixed_special_chars

Flake rate in main: 84.39% (Passed 32 times, Failed 173 times)

Stack Traces | 0.009s run time
self = <tests.test_xml_escape.TestEscaping object at 0x0000018c68f8d718>

    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
tests.test_xml_escape.TestEscaping::test_escapes_ampersands

Flake rate in main: 84.39% (Passed 32 times, Failed 173 times)

Stack Traces | 0.01s run time
self = <tests.test_xml_escape.TestEscaping object at 0x0000018c68f8d868>

    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: AssertionError
tests.test_xml_escape.TestEscaping::test_escapes_angle_brackets

Flake rate in main: 84.39% (Passed 32 times, Failed 173 times)

Stack Traces | 0.01s run time
self = <tests.test_xml_escape.TestEscaping object at 0x0000018c68f8db08>

    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: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

@@ -3,7 +3,7 @@

import pytest

from json2xml import dicttoxml
from json2xml import dicttoxml, json2xml

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'json2xml' is not used.
@@ -0,0 +1,56 @@
import pytest

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'pytest' is not used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant