Skip to content

Don't escape backticks in Java, C# and Python values - #2006

Merged
diemol merged 2 commits into
trunkfrom
export-escape-per-language
Oct 30, 2026
Merged

diemol merged 2 commits into
trunkfrom
export-escape-per-language

Conversation

@diemol

@diemol diemol commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Description

  • New language option escapedQuotes: the quote characters to escape in command values. When it's not set, all quotes are escaped as before.
  • Java, C# (NUnit and xUnit) and Python set it to "', so backticks are left as they are.
  • stringEscape's second argument can list several quote characters.
  • Text and value checks (assertText, verifyNotText, assertNotSelectedValue...) escaped values a second time in every language, so a quote, backslash or line break in the expected text exported as a check for different text. They use the value as it is now.
  • xUnit verifyNotSelectedValue was missing the quotes around the value.
  • Tests: the escaper, a text check with quotes and backticks, and a type value with ' and backticks in Java, C# and Python.

Motivation and Context

The shared escaper put a backslash before backticks for every language. \` isn't a valid escape in Java or C#, so a value with a backtick (in type, store, or any other command) made the exported test fail to compile. Python accepted it with a warning. JavaScript and Ruby are unchanged.

Checked with javac: "it\'s ok" prints it's `ok` .

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the contributing document.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

🤖 Generated with Claude Code

The shared escaper put a backslash before every quote character, including
backticks. In Java and C# that's an invalid escape, so a value with a
backtick broke the build (Python only warned). A language can now set
escapedQuotes; Java, C# and Python escape only " and '.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@diemol

diemol commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Preserve backticks in Java, C# and Python command values

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Prevent invalid backtick escapes in exported Java and C# commands and warnings in Python.
• Let language exporters select which quotes to escape while preserving defaults for other
 languages.
• Add escaper and command-output tests for the affected languages.
Diagram

graph TD
  A["Language options"] --> B["Command emission"] --> C["Parameter preprocessing"] --> D["String escaper"] --> E["Exported commands"]
  F["Other languages"] --> B
Loading
High-Level Assessment

Keep the shared escaper with a per-language quote selection. Separate language-specific escapers would duplicate the existing handling of backslashes and line breaks, while changing the global default would affect JavaScript and Ruby.

Files changed (12) +43 / -6

Bug fix (8) +22 / -6
index.tsConfigure NUnit quote escaping +2/-0

Configure NUnit quote escaping

• Sets the language option to escape double and single quotes, leaving backticks unchanged.

packages/code-export-csharp-nunit/src/index.ts

index.tsConfigure xUnit quote escaping +2/-0

Configure xUnit quote escaping

• Sets the xUnit language option to escape double and single quotes instead of backticks.

packages/code-export-csharp-xunit/src/index.ts

index.tsConfigure Java quote escaping +2/-0

Configure Java quote escaping

• Limits quote escaping to double and single quotes so exported Java values retain backticks.

packages/code-export-java-junit/src/index.ts

index.tsConfigure Python quote escaping +2/-0

Configure Python quote escaping

• Limits quote escaping to double and single quotes, avoiding unnecessary backslash-backtick sequences.

packages/code-export-python-pytest/src/index.ts

emit.tsForward language escape options during command emission +2/-2

Forward language escape options during command emission

• Passes the configured quote characters when preprocessing both command targets and values.

packages/side-code-export/src/code-export/emit.ts

preprocessor.tsCarry quote selection through parameter preprocessing +6/-3

Carry quote selection through parameter preprocessing

• Adds an optional escape setting to preprocessor options and forwards it to the shared string escaper.

packages/side-code-export/src/code-export/preprocessor.ts

index.tsSupport multiple selected quote characters +4/-1

Support multiple selected quote characters

• Treats the escaper’s second argument as a set of quote characters. An omitted or empty argument still escapes all quotes.

packages/side-code-export/src/string-escape/index.ts

types.tsExpose an optional language escape setting +2/-0

Expose an optional language escape setting

• Adds 'escapedQuotes' to language emitter options so exporters can choose which quote characters to escape.

packages/side-code-export/src/types.ts

Tests (4) +21 / -0
command.spec.jsTest NUnit output containing backticks +6/-0

Test NUnit output containing backticks

• Adds a 'type' command assertion that retains backticks in the emitted value while escaping its apostrophe.

packages/code-export-csharp-nunit/test/src/command.spec.js

command.spec.jsTest Java output containing backticks +6/-0

Test Java output containing backticks

• Adds a 'type' command assertion that checks backticks remain unescaped in the generated Java value.

packages/code-export-java-junit/test/src/command.spec.js

command.spec.jsTest Python output containing backticks +6/-0

Test Python output containing backticks

• Adds a 'type' command assertion that checks backticks remain unescaped in the generated Python value.

packages/code-export-python-pytest/test/src/command.spec.js

index.spec.jsTest multi-character quote selection +3/-0

Test multi-character quote selection

• Verifies that selecting both quote characters escapes them while preserving a backtick.

packages/side-code-export/test/src/string-escape/index.spec.js

@qodo-code-review

qodo-code-review Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Backticks still break exported text checks ✓ Resolved
Description
escapedQuotes leaves backticks unchanged during preprocessing, but the text assertion emitters
then call exporter.emit.text without that setting, adding a backslash before each backtick. When a
Java or C# verifyText or assertText value contains a backtick, the generated quoted literal
contains an invalid escape and fails to compile; Python emits the same warned-about escape.
Code

packages/side-code-export/src/code-export/emit.ts[215]

+        { ignoreEscaping: false, escapedQuotes: context?.escapedQuotes }
Evidence
The changed value path passes the language quote setting, but exporter.emit.text is an alias for
stringEscape and its calls in text assertions omit the setting. Its default escapes backticks, so
those assertions still emit a backslash-backtick sequence.

packages/side-code-export/src/code-export/emit.ts[205-216]
packages/side-code-export/src/code-export/emit.ts[730-740]
packages/side-code-export/src/string-escape/index.ts[3-14]
packages/code-export-java-junit/src/command.ts[981-987]
packages/code-export-csharp-commons/src/command.ts[983-989]
packages/code-export-csharp-xunit/src/command.ts[248-255]
packages/code-export-python-pytest/src/command.ts[902-910]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Text assertion emitters escape values a second time with the default quote set, so the new language-specific setting does not remove invalid backtick escapes from those commands.

## Fix Focus Areas
- packages/side-code-export/src/code-export/emit.ts[209-215]
- packages/code-export-java-junit/src/command.ts[981-987]
- packages/code-export-csharp-commons/src/command.ts[983-989]
- packages/code-export-csharp-xunit/src/command.ts[248-255]
- packages/code-export-python-pytest/src/command.ts[902-910]

## Recommended Fix
Use the already-preprocessed assertion value rather than escaping it again in the affected emitters. Apply the same correction to their other calls to `exporter.emit.text`, and add regression tests for backticks in text assertions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: Auto: ⚖️ Balanced: Localized runtime escaping changes span multiple language-specific assertion paths.
✅ Fix-loop round: fix loop

Grey Divider

Tip of the day
💡 Did you know, you can route each severity your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit da3dca7

Results up to commit d1a0e43 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Backticks still break exported text checks ✓ Resolved
Description
escapedQuotes leaves backticks unchanged during preprocessing, but the text assertion emitters
then call exporter.emit.text without that setting, adding a backslash before each backtick. When a
Java or C# verifyText or assertText value contains a backtick, the generated quoted literal
contains an invalid escape and fails to compile; Python emits the same warned-about escape.
Code

packages/side-code-export/src/code-export/emit.ts[215]

+        { ignoreEscaping: false, escapedQuotes: context?.escapedQuotes }
Evidence
The changed value path passes the language quote setting, but exporter.emit.text is an alias for
stringEscape and its calls in text assertions omit the setting. Its default escapes backticks, so
those assertions still emit a backslash-backtick sequence.

packages/side-code-export/src/code-export/emit.ts[205-216]
packages/side-code-export/src/code-export/emit.ts[730-740]
packages/side-code-export/src/string-escape/index.ts[3-14]
packages/code-export-java-junit/src/command.ts[981-987]
packages/code-export-csharp-commons/src/command.ts[983-989]
packages/code-export-csharp-xunit/src/command.ts[248-255]
packages/code-export-python-pytest/src/command.ts[902-910]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Text assertion emitters escape values a second time with the default quote set, so the new language-specific setting does not remove invalid backtick escapes from those commands.

## Fix Focus Areas
- packages/side-code-export/src/code-export/emit.ts[209-215]
- packages/code-export-java-junit/src/command.ts[981-987]
- packages/code-export-csharp-commons/src/command.ts[983-989]
- packages/code-export-csharp-xunit/src/command.ts[248-255]
- packages/code-export-python-pytest/src/command.ts[902-910]

## Recommended Fix
Use the already-preprocessed assertion value rather than escaping it again in the affected emitters. Apply the same correction to their other calls to `exporter.emit.text`, and add regression tests for backticks in text assertions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

The text and value check emitters escaped values that were already
escaped, so a quote, backslash or line break in an expected text exported
as a check for different text (\\n instead of \n). Also add the missing
quotes in the xUnit verifyNotSelectedValue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@diemol

diemol commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit da3dca7

@diemol
diemol merged commit 3302014 into trunk Oct 30, 2026
5 checks passed
@diemol
diemol deleted the export-escape-per-language branch October 30, 2026 18:54
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