diff --git a/README.md b/README.md index 3c14d11..34fcb04 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,12 @@ Most tests have configurable rules. If a rule is not specified, it will use the Some tests are opt in only. These will be marked as such. +## Comment Linebreaks + +Identifier: `comment_linebreaks` + +Checks that comments for strings do not contain linebreaks. Comments which contain linebreaks can interfere with parsing in other tools such as [dotstrings](https://github.com/microsoft/dotstrings). + ## Comment Similarity Identifier: `comment_similarity` diff --git a/localizationkit/tests/__init__.py b/localizationkit/tests/__init__.py index 8887c07..141f1cc 100644 --- a/localizationkit/tests/__init__.py +++ b/localizationkit/tests/__init__.py @@ -1,5 +1,6 @@ """Toolkit for validation of localized strings.""" +import localizationkit.tests.comment_linebreaks import localizationkit.tests.comment_similarity import localizationkit.tests.duplicate_keys import localizationkit.tests.has_comments diff --git a/localizationkit/tests/comment_linebreaks.py b/localizationkit/tests/comment_linebreaks.py new file mode 100644 index 0000000..0bc4a57 --- /dev/null +++ b/localizationkit/tests/comment_linebreaks.py @@ -0,0 +1,30 @@ +"""Checks for comments.""" + +from typing import Any, Dict, List + +from localizationkit.tests.test_case import LocalizationTestCase + + +class CommentLinebreaks(LocalizationTestCase): + """Check that comments do not contain linebreaks.""" + + @classmethod + def name(cls) -> str: + return "comment_linebreaks" + + @classmethod + def default_settings(cls) -> Dict[str, Any]: + return {} + + def run_test(self) -> List[str]: + violations = [] + + for string in self.collection.strings_for_language(self.configuration.default_language()): + + if string.comment is None: + continue + + if "\n" in string.comment or "\r" in string.comment: + violations.append(f"Comment contains linebreaks: {string}") + + return violations diff --git a/tests/test_comment_linebreaks.py b/tests/test_comment_linebreaks.py new file mode 100644 index 0000000..7dc52ff --- /dev/null +++ b/tests/test_comment_linebreaks.py @@ -0,0 +1,60 @@ +"""Has comments tests.""" + +# pylint: disable=line-too-long + +import os +import sys +import unittest + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), "..", ".."))) +import localizationkit + + +class CommentLinebreaksTests(unittest.TestCase): + """Comment linebreaks tests.""" + + def setUp(self): + current_file_path = os.path.abspath(__file__) + current_folder_path = os.path.dirname(current_file_path) + self.config_path = os.path.abspath(os.path.join(current_folder_path, "config.toml")) + self.configuration = localizationkit.Configuration.from_file(self.config_path) + + def test_comment_linebreaks(self): + """Test that has comments works""" + bad_comments = [ + "\n", + "\r", + "\r\n", + "\n\r", + "Hello\nWorld", + "\nHello World", + "Hello World\n", + ] + good_comments = [ + None, + "", + "Hello World", + "This is a nice and long comment with lots of words that would " + + "normally induce a linebreak for automatic wrapping, but " + + "shouldn't here. This is a nice and long comment with lots of " + + "words that would normally induce a linebreak for automatic " + + "wrapping, but shouldn't here.", + ] + + for comment in bad_comments: + string = localizationkit.LocalizedString("Key", "Value", comment, "en") + collection = localizationkit.LocalizedCollection([string]) + comment_linebreak_test = localizationkit.tests.comment_linebreaks.CommentLinebreaks( + self.configuration, collection + ) + result = comment_linebreak_test.execute() + self.assertFalse(result.succeeded()) + + for comment in good_comments: + string = localizationkit.LocalizedString("Key", "Value", comment, "en") + collection = localizationkit.LocalizedCollection([string]) + comment_linebreak_test = localizationkit.tests.comment_linebreaks.CommentLinebreaks( + self.configuration, collection + ) + result = comment_linebreak_test.execute() + self.assertTrue(result.succeeded())