Skip to content

Commit

Permalink
Merge pull request #47 from MarcinOrlowski/dev
Browse files Browse the repository at this point in the history
Release 2.2.0
  • Loading branch information
MarcinOrlowski authored Aug 11, 2021
2 parents 9658710 + a519cdc commit bfba116
Show file tree
Hide file tree
Showing 29 changed files with 415 additions and 132 deletions.
10 changes: 7 additions & 3 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ ignore =
WPS336, # WPS336 Found explicit string concatenation
WPS338, # WPS338 Found incorrect order of methods in a class
WPS360, # WPS360 Found an unnecessary use of a raw string
WPS402, # WPS402 Found `noqa` comments overuse: 12
WPS420, # WPS420 Found wrong keyword: pass
WPS442, # WPS442 Found outer scope names shadowing:
WPS600, # WPS600 Found subclassing a builtin: list
Expand All @@ -82,6 +83,9 @@ per-file-ignores =
transtool/report/error.py: WPS420, WPS604,
transtool/report/warn.py: WPS420, WPS604,

# WPS437 Found protected attribute usage
transtool/report/group.py: WPS437,

# WPS230 Found too many public instance attributes
transtool/config/config.py: WPS230,

Expand Down Expand Up @@ -130,12 +134,12 @@ per-file-ignores =
# WPS214 Found too many methods
# WPS323 Found `%` string formatting
# WPS432 Found magic number
# WPS437 Found protected attribute usage
# WPS609 Found direct magic attribute usage: __abstractmethods__
tests/*: S311, WPS323, WPS214, WPS432, WPS609, WPS118,
tests/*: S311, WPS323, WPS214, WPS432, WPS609, WPS118, WPS437,

# WPS431 Found nested class: FakeArgs
# WPS437 Found protected attribute usage: _set_on_off_option
tests/report/test_config_builder.py: WPS431, WPS437,
tests/report/test_config_builder.py: WPS431,

# WPS430 Found nested function: log_abort_side_effect
# S311 Standard pseudo-random generators are not suitable for security/cryptographic purposes.
Expand Down
4 changes: 4 additions & 0 deletions docs/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

# Changelog #

* v2.2.0 (2021-08-11)
* Added ability to specify checks to run with `--checks` option.
* Added more unit tests.

* v2.1.0 (2021-08-06)
* Rebranded and renamed project to `trans-tool`.
* Fixed config loader not handling Checks' sections properly.
Expand Down
5 changes: 3 additions & 2 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* [« Documentation table of contents](README.md)
* **Configuration**
* [Config file](#config-file)
* [Syntax file](#syntax)
* [Syntax](#syntax)
* [Structure](#structure)
* [The [trans-tool] section](#trans-tool-section)

Expand All @@ -27,7 +27,7 @@ any text editor. Please see commented [config.ini](../config.ini) for example co

You should be using standard `UTF-8` encoding for your configuration file.

## Syntax ##
# Syntax #

Configuration file is separated into sections. Each section starts with section header put in separate line between square brackets,
followed by section related configuration items. Items are usually in `key = value` form. All keys are always lower-cased, and for
Expand Down Expand Up @@ -99,6 +99,7 @@ The following elements are supported in `[trans-tool]` section

| Key | CLI switch | Argument type | Default | Description |
|-----------|---------------|---------------|---------|-------------|
| checks | `--checks` | List of strings | `[ Brackets, ... ]` | List of Checks IDs to be used for content validation. |
| comment | `--comment` | String | `#` | TODO |
| separator | `--separator` | String | `=` | TODO |
| quiet | `--quiet` | Boolean | `false` | Quiet mode. If enabled, all but fatal errors are muted. |
Expand Down
6 changes: 6 additions & 0 deletions requirements3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
argparse
wemake-python-styleguide
pytest
wheel
setuptools
twine
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

with open('README.md', 'r') as fh:
readme = fh.read()
readme.replace('![trans-tool logo](artwork/trans-tool-logo.png)',
'https://raw.githubusercontent.com/MarcinOrlowski/trans-tool/master/artwork/trans-tool-logo.png', 1)

setup(
name = Const.APP_NAME,
Expand Down
2 changes: 1 addition & 1 deletion tests/checks/checks_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def check_skipping_of_dangling_keys(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
trans_keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
trans_keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

# have less keys for reference file
upper_bound = 10
Expand Down
4 changes: 2 additions & 2 deletions tests/checks/test_dangling_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_translation_no_faults(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]
ref_file = self.build_prepfile(keys)
trans_file = self.build_prepfile(keys)
self.check(trans_file, ref_file)
Expand All @@ -36,7 +36,7 @@ def test_translation_with_faults(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
trans_keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
trans_keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

# have less keys for reference file
upper_bound = 10
Expand Down
8 changes: 4 additions & 4 deletions tests/checks/test_empty_translations.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_no_faults(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]
ref_file = self.build_prepfile(keys)
trans_file = self.build_prepfile(keys)
self.check(trans_file, ref_file)
Expand All @@ -40,7 +40,7 @@ def test_if_both_are_empty(self) -> None:
cnt_min = 10
cnt_max = 20
key_cnt = random.randint(cnt_min, cnt_max)
keys = [self.get_random_string('key_') for _ in range(key_cnt)]
keys = [self.get_random_string('key') for _ in range(key_cnt)]
ref_file = self.build_prepfile(keys)
trans_file = self.build_prepfile(keys)

Expand Down Expand Up @@ -72,7 +72,7 @@ def test_translation_with_dangling_keys(self) -> None:
cnt_min = 10
cnt_max = 20
key_cnt = random.randint(cnt_min, cnt_max)
keys = [self.get_random_string('key_') for _ in range(key_cnt)]
keys = [self.get_random_string('key') for _ in range(key_cnt)]
ref_file = self.build_prepfile(keys)
trans_file = self.build_prepfile(keys)

Expand Down Expand Up @@ -100,7 +100,7 @@ def test_translation_with_faults(self) -> None:
cnt_min = 10
cnt_max = 20
key_cnt = random.randint(cnt_min, cnt_max)
keys = [self.get_random_string('key_') for _ in range(key_cnt)]
keys = [self.get_random_string('key') for _ in range(key_cnt)]

ref_file = self.build_prepfile(keys)
trans_file = self.build_prepfile(keys)
Expand Down
8 changes: 4 additions & 4 deletions tests/checks/test_missing_translations.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_no_faults(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]
ref_file = self.build_prepfile(keys)
trans_file = self.build_prepfile(keys)
self.check(trans_file, ref_file)
Expand All @@ -42,7 +42,7 @@ def test_translation_with_keys_in_comments(self) -> None:
# Generate some keys for reference file.
cnt_min = 10
cnt_max = 15
ref_keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
ref_keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

# have less keys for translation file
how_many_less = random.randint(1, cnt_min - 1)
Expand All @@ -58,7 +58,7 @@ def test_translation_with_keys_in_comments(self) -> None:
if random.randint(0, 1) == 0:
comment = Comment.get_commented_out_key_comment(self.config, key)
else:
val = self.get_random_string('translation_')
val = self.get_random_string('translation')
comment = Comment.get_commented_out_key_comment(self.config, key, val)
trans_file.append(comment)

Expand All @@ -74,7 +74,7 @@ def test_translation_with_faults(self) -> None:
# generate some keys for reference file
cnt_min = 20
cnt_max = 40
ref_keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
ref_keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

# have less keys for translation file
how_many_less = random.randint(1, cnt_min - 1)
Expand Down
4 changes: 2 additions & 2 deletions tests/checks/test_punctuation.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_no_faults(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

marks = self.checker.config['chars']
punct_idx = 0
Expand All @@ -48,7 +48,7 @@ def test_with_faults(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

marks = self.checker.config['chars']
punct_idx = 0
Expand Down
8 changes: 4 additions & 4 deletions tests/checks/test_starts_with_the_same_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_checker(self, config: Union[Dict, None] = None) -> Check:
def test_no_faults(self) -> None:
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

ref_file = PropFile(self.config)
trans_file = PropFile(self.config)
Expand All @@ -43,7 +43,7 @@ def test_no_faults(self) -> None:
def test_with_faults(self) -> None:
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

expected_faults = 0

Expand All @@ -68,7 +68,7 @@ def _do_scan_test(self, tests: List[Tuple[str, str]], exp_warnings = 0):
for ref_value, trans_value in tests:
ref_file = PropFile(self.config)
trans_file = PropFile(self.config)
key = self.get_random_string('key_')
key = self.get_random_string('key')
ref_file.append(Translation(key, ref_value))
trans_file.append(Translation(key, trans_value))
self.check(trans_file, ref_file, exp_warnings = exp_warnings)
Expand Down Expand Up @@ -144,7 +144,7 @@ def test_skipping_of_entry_items(self) -> None:
# generate some keys for translation file
cnt_min = 20
cnt_max = 40
keys = [self.get_random_string('key_') for _ in range(random.randint(cnt_min, cnt_max))]
keys = [self.get_random_string('key') for _ in range(random.randint(cnt_min, cnt_max))]

ref_file = self.build_prepfile(keys, lower = True)
trans_file = self.build_prepfile(keys, lower = True)
Expand Down
80 changes: 80 additions & 0 deletions tests/checks/test_substitutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
# trans-tool
# The translation files checker and syncing tool.
#
# Copyright ©2021 Marcin Orlowski <mail [@] MarcinOrlowski.com>
# https://github.com/MarcinOrlowski/trans-tool/
#
"""
from typing import Dict, Union, List

from transtool.checks.substitutions import Substitutions
from transtool.decorators.overrides import overrides
from transtool.prop.file import PropFile
from transtool.prop.items import Comment, Translation
from tests.checks.checks_test_case import ChecksTestCase


class SubstitutionsTests(ChecksTestCase):

@overrides(ChecksTestCase)
def get_checker(self, config: Union[Dict, None] = None) -> Substitutions:
return Substitutions(config)

# #################################################################################################

def _get_valid_strings(self) -> List[str]:
return [
'Foo. Bar. All is fin5e!',
'Foo!',
]

def _get_faulty_strings(self) -> List[str]:
return [
'Triple dots...',
'Ough!!!',
]

def test_translation_no_faults(self) -> None:
for test in self._get_valid_strings():
self.check_single_file(Translation('key', test))

def test_empty_translation(self) -> None:
self.check(PropFile(self.config))

# #################################################################################################

def test_comment_no_faults(self) -> None:
for test in self._get_valid_strings():
self.check_single_file(Comment(test))

def test_comment_with_faults(self) -> None:
faults = self._get_faulty_strings()

for fault in faults:
# We should see no issues if comment scanning is disabled.
self.checker.config['comments'] = False
self.check_single_file(Comment(fault))

# And some warnings when comment scanning in enabled.
self.checker.config['comments'] = True
self.check_single_file(Comment(fault), exp_warnings = 1)

# #################################################################################################

def test_fail_with_error_flag(self) -> None:
"""
Ensures FLAG_FAIL_WITH_ERROR flag aborts scanning and returns error while
FLAG_DEFAULT yields warning.
"""
cfg = {
'regexp': r'([\.]{3})',
'replace': '…',
}
self.checker.config['map'] = [cfg]

cfg['flag'] = Substitutions.FLAG_DEFAULT
self.check_single_file(Translation('key', 'Triple dots...'), exp_warnings = 1)

cfg['flag'] = Substitutions.FLAG_FAIL_WITH_ERROR
self.check_single_file(Translation('key', 'Triple dots...'), exp_errors = 1)
2 changes: 1 addition & 1 deletion tests/checks/test_white_chars_before_linefeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_translation_no_faults(self) -> None:
self.check_single_file(Translation('key', r'This is\nall\nOK'))

def test_translation_string_too_short(self) -> None:
# Checks behavior when the string is too short to fit space and litera,
# Checks behavior when the string is too short to fit space and literals,
self.check_single_file(Translation('key', r' X'))
self.check_single_file(Translation('key', r'\n'))

Expand Down
59 changes: 59 additions & 0 deletions tests/config/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
# trans-tool
# The translation files checker and syncing tool.
#
# Copyright ©2021 Marcin Orlowski <mail [@] MarcinOrlowski.com>
# https://github.com/MarcinOrlowski/trans-tool/
#
"""

import random

from tests.test_case import TestCase
from transtool.config.config import Config


class TestConfig(TestCase):

def test_set_checker_config(self) -> None:
config = Config()
checker_id = self.get_random_string('checker_id')
checker_config = {}
max_items = 10
for idx in range(random.randint(1, max_items)):
checker_config[self.get_random_string(f'key{idx}')] = self.get_random_string(f'val{idx}')
config.set_checker_config(checker_id, checker_config)

self.assertIn(checker_id, config.checks)
self.assertEqual(len(checker_config), len(config.checks[checker_id]))
for key, val in checker_config.items():
self.assertIn(key, config.checks[checker_id])
self.assertEqual(val, config.checks[checker_id][key])

def test_set_checker_config_invalid_type(self) -> None:
config = Config()
checker_id = self.get_random_string('checker_id')
with self.assertRaises(TypeError):
# noinspection PyTypeChecker
config.set_checker_config(checker_id, False) # noqa: WPS425

def test_get_checker_config(self) -> None:
config = Config()
checker_id = self.get_random_string('checker_id')
checker_config = {}
max_items = 10
for idx in range(random.randint(1, max_items)):
checker_config[self.get_random_string(f'key{idx}')] = self.get_random_string(f'val{idx}')
config.set_checker_config(checker_id, checker_config)

read_config = config.get_checker_config(checker_id)
self.assertEqual(len(checker_config), len(read_config))
for key, val in checker_config.items():
self.assertIn(key, read_config)
self.assertEqual(val, read_config[key])

def test_get_checker_config_no_entry(self) -> None:
config = Config()
checker_id = self.get_random_string('checker_id')
with self.assertRaises(KeyError):
config.get_checker_config(checker_id)
Loading

0 comments on commit bfba116

Please sign in to comment.