Skip to content

feat: add json support#31

Merged
konradmichalik merged 3 commits intomainfrom
json-support
Jul 14, 2025
Merged

feat: add json support#31
konradmichalik merged 3 commits intomainfrom
json-support

Conversation

@konradmichalik
Copy link
Copy Markdown
Contributor

@konradmichalik konradmichalik commented Jul 13, 2025

Summary by CodeRabbit

  • New Features

    • Added support for JSON translation files throughout the application, including detection, parsing, and validation.
    • Validators now handle JSON files in addition to existing formats (XLIFF, YAML).
  • Documentation

    • Updated documentation and command help text to reflect JSON translation file support with relevant examples.
  • Tests

    • Introduced comprehensive tests for JSON translation file handling and validation.
    • Added JSON translation file fixtures for both success and failure scenarios.
    • Updated existing tests to cover JSON support in validators and file detection.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 13, 2025

Walkthrough

JSON translation file support was added throughout the codebase. This includes the introduction of a JsonParser, updates to file detection, parser registry, and multiple validators to recognize and process JSON files. Documentation, help texts, and tests were updated to reflect and verify the new JSON compatibility.

Changes

Files/Paths Change Summary
README.md, src/Command/ValidateTranslationCommand.php Documentation and help text updated to mention JSON translation file support.
src/FileDetector/SuffixFileDetector.php Regex updated to detect .json translation files for grouping logic.
src/Parser/JsonParser.php New JsonParser class added for parsing and extracting keys/values from JSON translation files.
src/Parser/ParserRegistry.php JsonParser added to the list of available parsers.
src/Validator/DuplicateValuesValidator.php
src/Validator/EmptyValuesValidator.php
src/Validator/MismatchValidator.php
src/Validator/PlaceholderConsistencyValidator.php
Each validator updated to support JsonParser in their supportsParser() method.
tests/src/FileDetector/CollectorTest.php Debug log count increased by one to account for new parser.
tests/src/Fixtures/translations/json/fail/messages.de.json
tests/src/Fixtures/translations/json/fail/messages.en.json
tests/src/Fixtures/translations/json/success/messages.de.json
tests/src/Fixtures/translations/json/success/messages.en.json
New JSON translation files added as test fixtures for success and failure cases.
tests/src/Parser/JsonParserTest.php New test class for JsonParser covering error handling and key/value extraction.
tests/src/Parser/ParserRegistryTest.php Tests updated to include JsonParser in available parsers and extension resolution.
tests/src/Validator/EmptyValuesValidatorTest.php
tests/src/Validator/MismatchValidatorTest.php
tests/src/Validator/PlaceholderConsistencyValidatorTest.php
Tests updated to expect JsonParser in supported parsers.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CommandLine
    participant FileDetector
    participant ParserRegistry
    participant JsonParser
    participant Validator

    User->>CommandLine: Run validate-translations
    CommandLine->>FileDetector: Collect translation files (.xlf, .yaml, .yml, .json)
    FileDetector->>ParserRegistry: Resolve parser for each file
    ParserRegistry->>JsonParser: Use for .json files
    JsonParser->>Validator: Provide extracted keys/values
    Validator->>CommandLine: Report validation results
Loading

Possibly related PRs

Poem

In the garden of code where translations grow,
JSON joins the party, with keys in tow.
Parsers and validators now play as one,
Testing and docs say, "Look what we've done!"
From YAML to XLIFF, and now JSON too,
The rabbit hops forward—new languages in view! 🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ae17ec and 4627f44.

📒 Files selected for processing (2)
  • src/Parser/JsonParser.php (1 hunks)
  • src/Parser/YamlParser.php (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/Parser/YamlParser.php
🧰 Additional context used
🪛 PHPMD (2.15.0)
src/Parser/JsonParser.php

63-63: Avoid unused parameters such as '$attribute'. (Unused Code Rules)

(UnusedFormalParameter)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Report test coverage
🔇 Additional comments (3)
src/Parser/JsonParser.php (3)

12-31: Excellent constructor implementation with robust error handling.

The constructor properly validates the JSON structure and provides clear error messages. The validation logic correctly ensures the JSON contains an object (not an array or scalar) by checking both !is_array($decoded) and array_is_list($decoded).


36-61: Well-implemented recursive key extraction.

The recursive closure properly traverses nested JSON structures and builds dot-notated keys for leaf values only. The logic correctly handles the prefix concatenation and recursive traversal.


1-101: Solid JsonParser implementation ready for integration.

This is a well-architected class that properly integrates JSON translation file support. The implementation demonstrates good practices including:

  • Comprehensive error handling with descriptive messages
  • Type safety with proper declarations and validation
  • Consistent interface compliance
  • Appropriate handling of edge cases

Previous review concerns have been addressed, and the code is ready for production use.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/src/Fixtures/translations/json/success/messages.de.json (1)

1-15: Consider using consistent indentation format.

The JSON fixture content and structure are appropriate for testing. However, the file uses tab characters for indentation, which may not align with project standards.

Consider using spaces for indentation for consistency:

 {
-  "greeting": "Hallo!",
-  "farewell": "Auf Wiedersehen!",
-  "user": {
-	"created": "Benutzer wurde erfolgreich erstellt.",
-	"deleted": "Benutzer wurde gelöscht."
-  },
-  "form": {
-	"submit": "Absenden",
-	"cancel": "Abbrechen"
-  },
-  "error": {
-	"not_found": "Die angeforderte Ressource wurde nicht gefunden."
-  }
+  "greeting": "Hallo!",
+  "farewell": "Auf Wiedersehen!",
+  "user": {
+    "created": "Benutzer wurde erfolgreich erstellt.",
+    "deleted": "Benutzer wurde gelöscht."
+  },
+  "form": {
+    "submit": "Absenden",
+    "cancel": "Abbrechen"
+  },
+  "error": {
+    "not_found": "Die angeforderte Ressource wurde nicht gefunden."
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87154bc and 5ae17ec.

📒 Files selected for processing (19)
  • README.md (2 hunks)
  • src/Command/ValidateTranslationCommand.php (1 hunks)
  • src/FileDetector/SuffixFileDetector.php (1 hunks)
  • src/Parser/JsonParser.php (1 hunks)
  • src/Parser/ParserRegistry.php (1 hunks)
  • src/Validator/DuplicateValuesValidator.php (2 hunks)
  • src/Validator/EmptyValuesValidator.php (2 hunks)
  • src/Validator/MismatchValidator.php (2 hunks)
  • src/Validator/PlaceholderConsistencyValidator.php (2 hunks)
  • tests/src/FileDetector/CollectorTest.php (2 hunks)
  • tests/src/Fixtures/translations/json/fail/messages.de.json (1 hunks)
  • tests/src/Fixtures/translations/json/fail/messages.en.json (1 hunks)
  • tests/src/Fixtures/translations/json/success/messages.de.json (1 hunks)
  • tests/src/Fixtures/translations/json/success/messages.en.json (1 hunks)
  • tests/src/Parser/JsonParserTest.php (1 hunks)
  • tests/src/Parser/ParserRegistryTest.php (3 hunks)
  • tests/src/Validator/EmptyValuesValidatorTest.php (2 hunks)
  • tests/src/Validator/MismatchValidatorTest.php (1 hunks)
  • tests/src/Validator/PlaceholderConsistencyValidatorTest.php (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (10)
src/Parser/ParserRegistry.php (1)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
tests/src/Validator/MismatchValidatorTest.php (1)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Validator/EmptyValuesValidator.php (1)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Validator/PlaceholderConsistencyValidator.php (3)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Parser/XliffParser.php (1)
  • XliffParser (7-81)
src/Parser/YamlParser.php (1)
  • YamlParser (9-91)
tests/src/Validator/PlaceholderConsistencyValidatorTest.php (1)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Validator/MismatchValidator.php (1)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Validator/DuplicateValuesValidator.php (3)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Parser/XliffParser.php (1)
  • XliffParser (7-81)
src/Parser/YamlParser.php (1)
  • YamlParser (9-91)
tests/src/Parser/ParserRegistryTest.php (2)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Parser/ParserRegistry.php (2)
  • ParserRegistry (9-50)
  • resolveParserClass (26-49)
tests/src/Validator/EmptyValuesValidatorTest.php (1)
src/Parser/JsonParser.php (1)
  • JsonParser (7-99)
src/Parser/JsonParser.php (1)
src/Parser/AbstractParser.php (1)
  • AbstractParser (7-51)
🪛 PHPMD (2.15.0)
src/Parser/JsonParser.php

63-63: Avoid unused parameters such as '$attribute'. (Unused Code Rules)

(UnusedFormalParameter)

🔇 Additional comments (30)
tests/src/Validator/EmptyValuesValidatorTest.php (2)

7-7: Import statement correctly added for JSON support.

The JsonParser import is necessary for the updated test that verifies JSON parser support.


126-126: Test properly updated to include JsonParser support.

The test correctly verifies that EmptyValuesValidator supports JsonParser alongside the existing XliffParser and YamlParser, ensuring the validator's JSON compatibility is properly tested.

src/Command/ValidateTranslationCommand.php (1)

89-89: Help text appropriately updated to reflect JSON support.

The command description now correctly documents support for JSON translation files alongside XLIFF and YAML formats.

src/Parser/ParserRegistry.php (1)

19-19: JsonParser correctly added to parser registry.

The integration of JsonParser into the available parsers list enables the system to recognize and handle JSON translation files alongside existing formats.

src/FileDetector/SuffixFileDetector.php (1)

20-20: File detection properly extended for JSON support.

The regex pattern correctly includes .json extension, enabling the file detector to recognize and group JSON translation files alongside existing YAML and XLIFF formats.

tests/src/Validator/MismatchValidatorTest.php (1)

192-192: LGTM! Correct addition of JSON parser support to test.

The test correctly includes JsonParser::class in the expected supported parsers array, aligning with the new JSON translation file support added to the MismatchValidator.

tests/src/FileDetector/CollectorTest.php (2)

97-97: LGTM! Updated debug call expectation for JSON parser support.

The increase from 2 to 3 expected debug calls correctly reflects the addition of JsonParser to the system. When no files are found, the collector now logs debug messages for all three parser classes (XliffParser, YamlParser, and JsonParser).


115-115: LGTM! Consistent debug call expectation update.

This change correctly mirrors the update in testCollectFilesWithNoMatchingFiles, maintaining consistency across test methods that verify debug logging when no matching files are found.

tests/src/Fixtures/translations/json/success/messages.en.json (1)

1-16: LGTM! Well-structured JSON translation fixture.

The fixture provides excellent test coverage with:

  • Proper JSON syntax and nested structure
  • Realistic translation keys covering common UI scenarios
  • Correct file naming convention (messages.en.json) for language detection
  • Nested keys that test the JsonParser's dot notation handling capability

This fixture will effectively validate the JSON translation parsing functionality.

tests/src/Fixtures/translations/json/fail/messages.en.json (1)

1-17: LGTM! Appropriate JSON fixture for validation testing.

The fixture effectively supports validation testing by:

  • Including an extra_key that exists only in the English translation
  • Maintaining the same base structure as the success fixture for consistency
  • Providing a realistic scenario for testing the MismatchValidator's key comparison logic
  • Using proper JSON syntax and structure

This fixture will help verify that validators correctly identify key mismatches across JSON translation files.

tests/src/Validator/PlaceholderConsistencyValidatorTest.php (2)

8-8: LGTM! Required import for JSON parser support.

The import statement is necessary to reference JsonParser::class in the test, supporting the extension of JSON translation file validation to the PlaceholderConsistencyValidator.


232-232: LGTM! Correct addition of JSON parser to expected supported parsers.

The test correctly verifies that PlaceholderConsistencyValidator now supports JsonParser alongside XliffParser and YamlParser, maintaining consistency with the JSON translation file support implementation across all validators.

tests/src/Fixtures/translations/json/fail/messages.de.json (1)

1-16: Well-structured JSON test fixture for validation testing.

The JSON structure is properly organized with logical grouping of translation keys. The inclusion of the missing_from_english key effectively provides test coverage for mismatch validation scenarios.

src/Validator/MismatchValidator.php (2)

8-8: Import correctly added for JSON parser support.

The JsonParser import is properly placed and follows the existing import organization.


218-218: JSON parser support correctly implemented.

The addition of JsonParser::class to the supported parsers array follows the established pattern and properly extends the validator's capabilities to JSON translation files.

tests/src/Parser/ParserRegistryTest.php (3)

7-7: Import correctly added for comprehensive test coverage.

The JsonParser import enables proper testing of the new JSON parser functionality.


22-24: Test assertions properly updated for JSON parser support.

The addition of the JsonParser assertion and the count update from 2 to 3 correctly reflect the expanded parser registry. The test coverage ensures the JsonParser is properly registered.


43-44: Comprehensive test coverage for JSON file extension resolution.

The new test case properly verifies that .json files resolve to the JsonParser::class, ensuring the file extension mapping works correctly.

README.md (2)

70-70: Comprehensive documentation for JSON format support.

The addition clearly documents JSON support with appropriate framework references and examples, providing users with clear guidance on the new format capability.


81-86: Accurate validator documentation updates.

The validator table correctly reflects which validators support JSON format, ensuring users understand the scope of JSON validation capabilities across different validator types.

src/Validator/EmptyValuesValidator.php (2)

7-7: Import correctly added for JSON parser support.

The JsonParser import follows the established import organization pattern.


68-68: Consistent JSON parser support implementation.

The addition of JsonParser::class to the supported parsers array maintains consistency with the implementation pattern used across other validators, properly extending JSON validation capabilities.

src/Validator/DuplicateValuesValidator.php (1)

7-7: LGTM: Clean integration of JSON parser support.

The addition of JsonParser import and its inclusion in the supportsParser() method follows the established pattern used for other parsers. This change correctly extends the validator to support JSON translation files.

Also applies to: 87-87

src/Validator/PlaceholderConsistencyValidator.php (1)

8-8: LGTM: Consistent JSON parser integration.

The addition of JsonParser support follows the exact same pattern as other validators, ensuring consistency across the codebase. The import and supportsParser() method updates are correctly implemented.

Also applies to: 287-287

tests/src/Parser/JsonParserTest.php (4)

19-66: Excellent test setup and cleanup implementation.

The setup and teardown methods properly manage temporary files and directories, ensuring test isolation. The removeDirectory() helper correctly handles recursive directory cleanup.


68-118: Comprehensive constructor error handling tests.

The test cases cover all major error scenarios:

  • Non-existent files
  • Unreadable files
  • Invalid file extensions
  • Invalid JSON syntax
  • Non-object JSON content
  • Empty files

This thorough coverage ensures robust error handling in the JsonParser constructor.


174-195: Thorough language detection testing.

The test validates various filename patterns including language codes with and without region variants (en, en_US, de_DE). This comprehensive coverage ensures the regex pattern works correctly across different naming conventions.


197-242: Excellent complex nesting validation.

The tests for deep JSON structures verify that the parser correctly handles multi-level nesting and generates proper dot-notation keys. The sorting of expected vs actual keys ensures reliable comparison regardless of iteration order.

src/Parser/JsonParser.php (2)

16-30: Robust JSON parsing with proper validation.

The constructor correctly:

  • Reads file content with error handling
  • Uses JSON_THROW_ON_ERROR for reliable error detection
  • Validates that JSON contains an object (not array) which is appropriate for translation files
  • Provides clear error messages with file context

36-61: Well-implemented recursive key extraction.

The extractKeys() method correctly:

  • Uses a recursive closure to traverse nested objects
  • Builds dot-notation keys (parent.child.grandchild)
  • Handles both leaf values and nested structures
  • Returns a flat array of all available keys

This implementation aligns well with the YAML parser's approach shown in the relevant code snippets.

@konradmichalik konradmichalik merged commit e6a438b into main Jul 14, 2025
28 checks passed
@konradmichalik konradmichalik deleted the json-support branch July 28, 2025 17:14
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