diff --git a/.github/workflows/ci-i18n-with-apicall.yml b/.github/workflows/ci-i18n-with-apicall.yml new file mode 100644 index 000000000..bcbd25d54 --- /dev/null +++ b/.github/workflows/ci-i18n-with-apicall.yml @@ -0,0 +1,36 @@ +name: CI-i18n-with-apicall + +# workflow for translate script testing +# with apicall testing, so runs scheduled on main branch or triggered manually + +on: + schedule: + - cron: "0 0 1 * *" # every month on the 1st + branches: + - main + workflow_dispatch: + branches: + - main + +jobs: + auto-trans-tool-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install aiida-core-i18n + run: | + pip install -e .[dev] + + - name: Run tests + run: | + pytest -k "apicall" tests -v --cov + env: + DEEPL_TOKEN: ${{ secrets.DEEPL_TOKEN }} diff --git a/.github/workflows/ci-i18n.yml b/.github/workflows/ci-i18n.yml new file mode 100644 index 000000000..2fc86ce94 --- /dev/null +++ b/.github/workflows/ci-i18n.yml @@ -0,0 +1,44 @@ +name: CI-i18n + +# workflow for translate script testing + +on: + pull_request: + paths_ignore: + - "translations/**" + - "locale_sources/**" + - aiida-core + push: + paths_ignore: + - "translations/**" + - "locale_sources/**" + - aiida-core + branches: + - main + +jobs: + auto-trans-tool-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install aiida-core-i18n + run: | + pip install -e .[dev] + + - name: Run tests + run: | + pytest -k "not apicall" tests -v --cov + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + with: + name: aiida-core-i18n + fail_ci_if_error: false # don't fail job, if coverage upload fails diff --git a/README.md b/README.md index 91f1c4982..dc9c17f91 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # aiida-core i18n localization documentation +[![codecov](https://codecov.io/gh/unkcpz/aiida-core-i18n/graph/badge.svg?token=8K9WSJNWRP)](https://codecov.io/gh/unkcpz/aiida-core-i18n) + This is the repository serves for the localization of [aiida-core documentation](https://aiida.readthedocs.io/projects/aiida-core/en/latest/index.html). You can also translate online at and your changes will be reviewed as soon as possible. diff --git a/pyproject.toml b/pyproject.toml index 2459c0a14..ec99580aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] build-backend = "flit_core.buildapi" -requires = ["flit_core >=3.7.1,<4"] +requires = ["flit_core >=3.7,<4"] [project] name = "aiida-core-i18n" @@ -23,6 +23,16 @@ classifiers = [ dependencies = [ "deepl~=1.11", "requests~=2.28", +] + +[project.optional-dependencies] +dev = [ "pytest~=7.2", "pytest-regressions~=2.4", + "pytest-cov~=4.0", +] + +[tool.pytest.ini_options] +markers = [ + "apicall", ] \ No newline at end of file diff --git a/src/aiida_core_i18n/__init__.py b/src/aiida_core_i18n/__init__.py index 7d397074e..341c9dea9 100644 --- a/src/aiida_core_i18n/__init__.py +++ b/src/aiida_core_i18n/__init__.py @@ -5,7 +5,7 @@ DEEPL_TOKEN = os.environ.get("DEEPL_TOKEN") -def str_pp(raw_str): +def str_post_processing(raw_str: str) -> str: """deepl zh_CN has problem when translate the `` in CJK from English, this method will handle the process of it to render code snippet. """ @@ -24,7 +24,7 @@ def str_pp(raw_str): return res.strip() -def translate(inp_str: str, target_lang="ZH"): +def translate(inp_str: str, target_lang="ZH") -> str: """Call deepl API to tranlate and do post process""" translator = deepl.Translator(DEEPL_TOKEN) @@ -48,11 +48,11 @@ def translate(inp_str: str, target_lang="ZH"): tstr = translated.text tstr = tstr.replace('EDBS', '``') - res = str_pp(tstr) + res = str_post_processing(tstr) return res -def po_translate(lines: typing.List[str]): +def po_translate(lines: typing.List[str], override: bool = False) -> typing.List[str]: """Translate the po files line by line""" output_lines = [i for i in lines] for ln, line in enumerate(lines): @@ -63,11 +63,12 @@ def po_translate(lines: typing.List[str]): ln_end = ln_start + count break - # if translated, skip, otherwise will override the translated result - if lines[ln_end] != 'msgstr ""': + # if translated, skip, otherwise the result will be overwritten + if lines[ln_end] != 'msgstr ""' and not override: continue if ln_end - ln_start > 1: + # combine the string from multiple lines inp_str = "".join([i.strip('"') for i in lines[ln_start+1:ln_end]]) else: # get the string from double quotes diff --git a/tests/test_translate.py b/tests/test_translate.py index 368fb88bb..d1ff71a40 100644 --- a/tests/test_translate.py +++ b/tests/test_translate.py @@ -1,9 +1,12 @@ import pytest import pathlib -from aiida_core_i18n import str_pp, po_translate +from aiida_core_i18n import str_post_processing, po_translate -STATIC_PATH = pathlib.Path(__file__).parent.resolve() +@pytest.fixture(scope="function") +def static_path() -> pathlib.Path: + """The path of this file""" + return pathlib.Path(__file__).parent.resolve() @pytest.mark.parametrize( ('input', 'expected'), @@ -15,18 +18,37 @@ ("参见 :py:mod:`aiida.plugins`中的API文档。", "参见 :py:mod:`aiida.plugins`中的API文档。"), ] ) -def test_str_pp(input, expected): +def test_str_post_processing(input: str, expected: str): """test post process the string for code snippet""" - got = str_pp(input) + got = str_post_processing(input) assert got == expected -with open(STATIC_PATH / "statics" / "origin_text.txt", "r") as fh: - PO_STR = fh.read() -def test_po_translate(file_regression): - """The actuall process of po file""" - lines = PO_STR.splitlines() +@pytest.fixture(scope="function") +def pot_str(static_path: pathlib.Path) -> str: + """Read the po file from statics""" + with open(static_path / "statics" / "origin_text.txt", "r") as fh: + s = fh.read() + return s + +@pytest.mark.apicall +def test_po_translate_default(pot_str, file_regression): + """The actuall process of po file + This consumes ~ 500 characters of deepl API + """ + lines = pot_str.splitlines() translated_lines = po_translate(lines) file_regression.check('\n'.join(translated_lines)) - \ No newline at end of file + +@pytest.mark.parametrize("override", [True, False]) +def test_po_translate_override(pot_str, file_regression, monkeypatch, override: bool): + """Monkey patch the translate function to return the same string + In order to test the flow of po_translate + """ + monkeypatch.setattr("aiida_core_i18n.translate", lambda x: x) + + lines = pot_str.splitlines() + + translated_lines = po_translate(lines, override=override) + file_regression.check('\n'.join(translated_lines)) diff --git a/tests/test_translate/test_po_translate.txt b/tests/test_translate/test_po_translate_default.txt similarity index 92% rename from tests/test_translate/test_po_translate.txt rename to tests/test_translate/test_po_translate_default.txt index 0e690a2b0..7e19b7393 100644 --- a/tests/test_translate/test_po_translate.txt +++ b/tests/test_translate/test_po_translate_default.txt @@ -27,10 +27,10 @@ msgstr "发动机" #: ../../source/internals/engine.rst:38 msgid "The ``WorkflowNode`` example" -msgstr "``WorkflowNode``的例子" +msgstr "``WorkflowNode`` 示例" #: ../../source/internals/engine.rst:19 msgid "" "There are several methods which the internal classes of AiiDA use to control" " the caching mechanism:" -msgstr "AiiDA的内部类有几个方法用来控制缓存机制。" \ No newline at end of file +msgstr "AiiDA 的内部类使用几种方法来控制缓存机制:" \ No newline at end of file diff --git a/tests/test_translate/test_po_translate_override_False_.txt b/tests/test_translate/test_po_translate_override_False_.txt new file mode 100644 index 000000000..e4c183081 --- /dev/null +++ b/tests/test_translate/test_po_translate_override_False_.txt @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014-2020, ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (Theory and Simulation of Materials (THEOS) and National Centre for Computational Design and Discovery of Novel Materials (NCCR MARVEL)), Switzerland and ROBERT BOSCH LLC, USA. All rights reserved +# This file is distributed under the same license as the AiiDA package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: AiiDA 2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-03 14:17+0000\n" +"PO-Revision-Date: 2022-11-03 14:19+0000\n" +"Language-Team: Chinese (China) (https://www.transifex.com/aiidateam/teams/98967/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../source/internals/engine.rst:5 +msgid "Engine" +msgstr "引擎(已翻译)" + +#: ../../source/internals/engine.rst:5 +msgid "Engine" +msgstr "Engine" + +#: ../../source/internals/engine.rst:38 +msgid "The ``WorkflowNode`` example" +msgstr "The ``WorkflowNode`` example" + +#: ../../source/internals/engine.rst:19 +msgid "" +"There are several methods which the internal classes of AiiDA use to control" +" the caching mechanism:" +msgstr "There are several methods which the internal classes of AiiDA use to control the caching mechanism:" \ No newline at end of file diff --git a/tests/test_translate/test_po_translate_override_True_.txt b/tests/test_translate/test_po_translate_override_True_.txt new file mode 100644 index 000000000..70955c6a7 --- /dev/null +++ b/tests/test_translate/test_po_translate_override_True_.txt @@ -0,0 +1,36 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014-2020, ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (Theory and Simulation of Materials (THEOS) and National Centre for Computational Design and Discovery of Novel Materials (NCCR MARVEL)), Switzerland and ROBERT BOSCH LLC, USA. All rights reserved +# This file is distributed under the same license as the AiiDA package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: AiiDA 2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-03 14:17+0000\n" +"PO-Revision-Date: 2022-11-03 14:19+0000\n" +"Language-Team: Chinese (China) (https://www.transifex.com/aiidateam/teams/98967/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../source/internals/engine.rst:5 +msgid "Engine" +msgstr "Engine" + +#: ../../source/internals/engine.rst:5 +msgid "Engine" +msgstr "Engine" + +#: ../../source/internals/engine.rst:38 +msgid "The ``WorkflowNode`` example" +msgstr "The ``WorkflowNode`` example" + +#: ../../source/internals/engine.rst:19 +msgid "" +"There are several methods which the internal classes of AiiDA use to control" +" the caching mechanism:" +msgstr "There are several methods which the internal classes of AiiDA use to control the caching mechanism:" \ No newline at end of file