From dabf277942ea9b783305726dad7dfc081ec9dabd Mon Sep 17 00:00:00 2001
From: topsworld
Date: Thu, 19 Dec 2024 13:30:26 +0800
Subject: [PATCH 1/3] test: check lang_integrity
---
test/check_rule_format.py | 96 +++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/test/check_rule_format.py b/test/check_rule_format.py
index db2d8295..00ba86ac 100644
--- a/test/check_rule_format.py
+++ b/test/check_rule_format.py
@@ -4,6 +4,7 @@
from os import listdir, path
from typing import Optional
import pytest
+import yaml
SOURCE_DIR: str = path.dirname(path.abspath(__file__))
@@ -20,6 +21,18 @@ def load_json_file(file_path: str) -> Optional[dict]:
return None
+def load_yaml_file(file_path: str) -> Optional[dict]:
+ try:
+ with open(file_path, 'r', encoding='utf-8') as file:
+ return yaml.safe_load(file)
+ except FileNotFoundError:
+ print(file_path, 'is not found.')
+ return None
+ except yaml.YAMLError:
+ print(file_path, 'is not a valid YAML file.')
+ return None
+
+
def dict_str_str(d: dict) -> bool:
"""restricted format: dict[str, str]"""
if not isinstance(d, dict):
@@ -86,6 +99,30 @@ def bool_trans(d: dict) -> bool:
return True
+def compare_dict_structure(dict1: dict, dict2: dict) -> bool:
+ if not isinstance(dict1, dict) or not isinstance(dict2, dict):
+ print('invalid type')
+ return False
+ if dict1.keys() != dict2.keys():
+ print('inconsistent key values, ', dict1.keys(), dict2.keys())
+ return False
+ for key in dict1:
+ if isinstance(dict1[key], dict) and isinstance(dict2[key], dict):
+ if not compare_dict_structure(dict1[key], dict2[key]):
+ print('inconsistent key values, dict, ', key)
+ return False
+ elif isinstance(dict1[key], list) and isinstance(dict2[key], list):
+ if not all(
+ isinstance(i, type(j))
+ for i, j in zip(dict1[key], dict2[key])):
+ print('inconsistent key values, list, ', key)
+ return False
+ elif not isinstance(dict1[key], type(dict2[key])):
+ print('inconsistent key values, type, ', key)
+ return False
+ return True
+
+
@pytest.mark.github
def test_bool_trans():
data: dict = load_json_file(
@@ -125,3 +162,62 @@ def test_miot_i18n():
data: dict = load_json_file(file_path)
assert data
assert nested_3_dict_str_str(data)
+
+
+@pytest.mark.github
+def test_translations():
+ i18n_path: str = path.join(
+ SOURCE_DIR, '../custom_components/xiaomi_home/translations')
+ for file_name in listdir(i18n_path):
+ file_path: str = path.join(i18n_path, file_name)
+ data: dict = load_json_file(file_path)
+ assert data
+ assert dict_str_dict(data)
+
+
+@pytest.mark.github
+def test_miot_lang_integrity():
+ # pylint: disable=import-outside-toplevel
+ from miot.const import INTEGRATION_LANGUAGES
+ integration_lang_list: list[str] = [
+ f'{key}.json' for key in list(INTEGRATION_LANGUAGES.keys())]
+ translations_names: set[str] = set(listdir(
+ path.join(
+ SOURCE_DIR, '../custom_components/xiaomi_home/translations')))
+ assert len(translations_names) == len(integration_lang_list)
+ assert translations_names == set(integration_lang_list)
+ i18n_names: set[str] = set(listdir(
+ path.join(
+ SOURCE_DIR, '../custom_components/xiaomi_home/miot/i18n')))
+ assert len(i18n_names) == len(translations_names)
+ assert i18n_names == translations_names
+ # Check translation files structure
+ default_dict: dict = load_json_file(
+ path.join(
+ SOURCE_DIR,
+ '../custom_components/xiaomi_home/translations',
+ integration_lang_list[0]))
+ for name in list(integration_lang_list)[1:]:
+ compare_dict: dict = load_json_file(
+ path.join(
+ SOURCE_DIR,
+ '../custom_components/xiaomi_home/translations',
+ name))
+ if not compare_dict_structure(default_dict, compare_dict):
+ print('compare_dict_structure failed /translations, ', name)
+ assert False
+ # Check i18n files structure
+ default_dict = load_json_file(
+ path.join(
+ SOURCE_DIR,
+ '../custom_components/xiaomi_home/miot/i18n',
+ integration_lang_list[0]))
+ for name in list(integration_lang_list)[1:]:
+ compare_dict: dict = load_json_file(
+ path.join(
+ SOURCE_DIR,
+ '../custom_components/xiaomi_home/miot/i18n',
+ name))
+ if not compare_dict_structure(default_dict, compare_dict):
+ print('compare_dict_structure failed /miot/i18n, ', name)
+ assert False
From b93d8631b8c079c194f04e4bb0a727b5a37f803d Mon Sep 17 00:00:00 2001
From: topsworld
Date: Thu, 19 Dec 2024 13:31:17 +0800
Subject: [PATCH 2/3] fix: translations structure error
---
.../xiaomi_home/miot/i18n/zh-Hant.json | 12 +++++-------
custom_components/xiaomi_home/translations/ja.json | 4 +---
custom_components/xiaomi_home/translations/ru.json | 14 +++++++-------
3 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/custom_components/xiaomi_home/miot/i18n/zh-Hant.json b/custom_components/xiaomi_home/miot/i18n/zh-Hant.json
index bf381a3f..e62b4f96 100644
--- a/custom_components/xiaomi_home/miot/i18n/zh-Hant.json
+++ b/custom_components/xiaomi_home/miot/i18n/zh-Hant.json
@@ -43,20 +43,18 @@
},
"error": {
"common": {
- "-1": "未知錯誤",
"-10000": "未知錯誤",
"-10001": "æœå‹™ä¸å¯ç”¨",
- "-10002": "無效åƒæ•¸",
+ "-10002": "åƒæ•¸ç„¡æ•ˆ",
"-10003": "資æºä¸è¶³",
"-10004": "內部錯誤",
"-10005": "權é™ä¸è¶³",
"-10006": "執行超時",
"-10007": "è¨å‚™é›¢ç·šæˆ–者ä¸å˜åœ¨",
- "-10020": "無效的消æ¯æ ¼å¼"
- },
- "gw": {},
- "lan": {},
- "cloud": {
+ "-10020": "未授權(OAuth2)",
+ "-10030": "無效的token(HTTP)",
+ "-10040": "無效的消æ¯æ ¼å¼",
+ "-10050": "無效的è‰æ›¸",
"-704000000": "未知錯誤",
"-704010000": "未授權(è¨å‚™å¯èƒ½è¢«åˆªé™¤ï¼‰",
"-704014006": "沒找到è¨å‚™æè¿°",
diff --git a/custom_components/xiaomi_home/translations/ja.json b/custom_components/xiaomi_home/translations/ja.json
index 96d8029d..780378db 100644
--- a/custom_components/xiaomi_home/translations/ja.json
+++ b/custom_components/xiaomi_home/translations/ja.json
@@ -45,9 +45,7 @@
"get_cert_error": "ゲートウェイ証明書をå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚",
"no_family_selected": "家åºãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“。",
"no_devices": "é¸æŠžã•ã‚ŒãŸå®¶åºã«ãƒ‡ãƒã‚¤ã‚¹ãŒã‚ã‚Šã¾ã›ã‚“。デãƒã‚¤ã‚¹ãŒã‚る家åºã‚’é¸æŠžã—ã¦ç¶šè¡Œã—ã¦ãã ã•ã„。",
- "no_central_device": "ã€ä¸å¤®ã‚²ãƒ¼ãƒˆã‚¦ã‚§ã‚¤ãƒ¢ãƒ¼ãƒ‰ã€‘Home Assistant ãŒå˜åœ¨ã™ã‚‹ LAN 内ã«ä½¿ç”¨å¯èƒ½ãª Xiaomi ä¸å¤®ã‚²ãƒ¼ãƒˆã‚¦ã‚§ã‚¤ãŒã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚é¸æŠžã•ã‚ŒãŸå®¶åºãŒã“ã®è¦ä»¶ã‚’満ãŸã—ã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¦ãã ã•ã„。",
- "update_config_error": "è¨å®šæƒ…å ±ã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚",
- "not_confirm": "å¤‰æ›´é …ç›®ãŒç¢ºèªã•ã‚Œã¦ã„ã¾ã›ã‚“。確èªã‚’é¸æŠžã—ã¦ã‹ã‚‰é€ä¿¡ã—ã¦ãã ã•ã„。"
+ "no_central_device": "ã€ä¸å¤®ã‚²ãƒ¼ãƒˆã‚¦ã‚§ã‚¤ãƒ¢ãƒ¼ãƒ‰ã€‘Home Assistant ãŒå˜åœ¨ã™ã‚‹ LAN 内ã«ä½¿ç”¨å¯èƒ½ãª Xiaomi ä¸å¤®ã‚²ãƒ¼ãƒˆã‚¦ã‚§ã‚¤ãŒã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚é¸æŠžã•ã‚ŒãŸå®¶åºãŒã“ã®è¦ä»¶ã‚’満ãŸã—ã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¦ãã ã•ã„。"
},
"abort": {
"network_connect_error": "è¨å®šã«å¤±æ•—ã—ã¾ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã«ç•°å¸¸ãŒã‚ã‚Šã¾ã™ã€‚デãƒã‚¤ã‚¹ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨å®šã‚’確èªã—ã¦ãã ã•ã„。",
diff --git a/custom_components/xiaomi_home/translations/ru.json b/custom_components/xiaomi_home/translations/ru.json
index 06c49ca7..778206de 100644
--- a/custom_components/xiaomi_home/translations/ru.json
+++ b/custom_components/xiaomi_home/translations/ru.json
@@ -45,13 +45,13 @@
"get_cert_error": "Ðе удалоÑÑŒ получить Ñертификат центрального шлюза.",
"no_family_selected": "Ðе выбрана домашнÑÑ Ñеть.",
"no_devices": "Ð’ выбранной домашней Ñети нет уÑтройÑтв. ПожалуйÑта, выберите домашнюю Ñеть Ñ ÑƒÑтройÑтвами и продолжайте.",
- "no_central_device": "Ð”Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° центрального шлюза Xiaomi необходимо наличие доÑтупного центрального шлюза Xiaomi в локальной Ñети Home Assistant. Проверьте, ÑоответÑтвует ли Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð´Ð¾Ð¼Ð°ÑˆÐ½ÑÑ Ñеть Ñтому требованию.",
- "abort": {
- "network_connect_error": "Ошибка наÑтройки. Сетевое подключение недоÑтупно. Проверьте наÑтройки Ñети уÑтройÑтва.",
- "already_configured": "Ðтот пользователь уже наÑтроен. Перейдите на Ñтраницу интеграции и нажмите кнопку «ÐаÑтроить», чтобы изменить наÑтройки.",
- "invalid_auth_info": "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± авторизации иÑтекла. Перейдите на Ñтраницу интеграции и нажмите кнопку «ÐаÑтроить», чтобы переавторизоватьÑÑ.",
- "config_flow_error": "Ошибка наÑтройки интеграции: {error}"
- }
+ "no_central_device": "Ð”Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° центрального шлюза Xiaomi необходимо наличие доÑтупного центрального шлюза Xiaomi в локальной Ñети Home Assistant. Проверьте, ÑоответÑтвует ли Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð´Ð¾Ð¼Ð°ÑˆÐ½ÑÑ Ñеть Ñтому требованию."
+ },
+ "abort": {
+ "network_connect_error": "Ошибка наÑтройки. Сетевое подключение недоÑтупно. Проверьте наÑтройки Ñети уÑтройÑтва.",
+ "already_configured": "Ðтот пользователь уже наÑтроен. Перейдите на Ñтраницу интеграции и нажмите кнопку «ÐаÑтроить», чтобы изменить наÑтройки.",
+ "invalid_auth_info": "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± авторизации иÑтекла. Перейдите на Ñтраницу интеграции и нажмите кнопку «ÐаÑтроить», чтобы переавторизоватьÑÑ.",
+ "config_flow_error": "Ошибка наÑтройки интеграции: {error}"
}
},
"options": {
From 2d6387c30a86c3286a8b95306b551b701121f196 Mon Sep 17 00:00:00 2001
From: topsworld
Date: Thu, 19 Dec 2024 13:53:53 +0800
Subject: [PATCH 3/3] test: check_rule_format.py use constant
---
test/check_rule_format.py | 41 +++++++++++++--------------------------
1 file changed, 14 insertions(+), 27 deletions(-)
diff --git a/test/check_rule_format.py b/test/check_rule_format.py
index 00ba86ac..48d602ef 100644
--- a/test/check_rule_format.py
+++ b/test/check_rule_format.py
@@ -6,7 +6,9 @@
import pytest
import yaml
-SOURCE_DIR: str = path.dirname(path.abspath(__file__))
+SOURCE_PATH: str = path.dirname(path.abspath(__file__))
+TRANS_RELATIVE_PATH: str = '../custom_components/xiaomi_home/translations'
+MIOT_I18N_RELATIVE_PATH: str = '../custom_components/xiaomi_home/miot/i18n'
def load_json_file(file_path: str) -> Optional[dict]:
@@ -127,7 +129,7 @@ def compare_dict_structure(dict1: dict, dict2: dict) -> bool:
def test_bool_trans():
data: dict = load_json_file(
path.join(
- SOURCE_DIR,
+ SOURCE_PATH,
'../custom_components/xiaomi_home/miot/specs/bool_trans.json'))
assert data
assert bool_trans(data)
@@ -137,7 +139,7 @@ def test_bool_trans():
def test_spec_filter():
data: dict = load_json_file(
path.join(
- SOURCE_DIR,
+ SOURCE_PATH,
'../custom_components/xiaomi_home/miot/specs/spec_filter.json'))
assert data
assert spec_filter(data)
@@ -147,7 +149,7 @@ def test_spec_filter():
def test_multi_lang():
data: dict = load_json_file(
path.join(
- SOURCE_DIR,
+ SOURCE_PATH,
'../custom_components/xiaomi_home/miot/specs/multi_lang.json'))
assert data
assert nested_3_dict_str_str(data)
@@ -155,8 +157,7 @@ def test_multi_lang():
@pytest.mark.github
def test_miot_i18n():
- i18n_path: str = path.join(
- SOURCE_DIR, '../custom_components/xiaomi_home/miot/i18n')
+ i18n_path: str = path.join(SOURCE_PATH, MIOT_I18N_RELATIVE_PATH)
for file_name in listdir(i18n_path):
file_path: str = path.join(i18n_path, file_name)
data: dict = load_json_file(file_path)
@@ -166,8 +167,7 @@ def test_miot_i18n():
@pytest.mark.github
def test_translations():
- i18n_path: str = path.join(
- SOURCE_DIR, '../custom_components/xiaomi_home/translations')
+ i18n_path: str = path.join(SOURCE_PATH, TRANS_RELATIVE_PATH)
for file_name in listdir(i18n_path):
file_path: str = path.join(i18n_path, file_name)
data: dict = load_json_file(file_path)
@@ -182,42 +182,29 @@ def test_miot_lang_integrity():
integration_lang_list: list[str] = [
f'{key}.json' for key in list(INTEGRATION_LANGUAGES.keys())]
translations_names: set[str] = set(listdir(
- path.join(
- SOURCE_DIR, '../custom_components/xiaomi_home/translations')))
+ path.join(SOURCE_PATH, TRANS_RELATIVE_PATH)))
assert len(translations_names) == len(integration_lang_list)
assert translations_names == set(integration_lang_list)
i18n_names: set[str] = set(listdir(
- path.join(
- SOURCE_DIR, '../custom_components/xiaomi_home/miot/i18n')))
+ path.join(SOURCE_PATH, MIOT_I18N_RELATIVE_PATH)))
assert len(i18n_names) == len(translations_names)
assert i18n_names == translations_names
# Check translation files structure
default_dict: dict = load_json_file(
- path.join(
- SOURCE_DIR,
- '../custom_components/xiaomi_home/translations',
- integration_lang_list[0]))
+ path.join(SOURCE_PATH, TRANS_RELATIVE_PATH, integration_lang_list[0]))
for name in list(integration_lang_list)[1:]:
compare_dict: dict = load_json_file(
- path.join(
- SOURCE_DIR,
- '../custom_components/xiaomi_home/translations',
- name))
+ path.join(SOURCE_PATH, TRANS_RELATIVE_PATH, name))
if not compare_dict_structure(default_dict, compare_dict):
print('compare_dict_structure failed /translations, ', name)
assert False
# Check i18n files structure
default_dict = load_json_file(
path.join(
- SOURCE_DIR,
- '../custom_components/xiaomi_home/miot/i18n',
- integration_lang_list[0]))
+ SOURCE_PATH, MIOT_I18N_RELATIVE_PATH, integration_lang_list[0]))
for name in list(integration_lang_list)[1:]:
compare_dict: dict = load_json_file(
- path.join(
- SOURCE_DIR,
- '../custom_components/xiaomi_home/miot/i18n',
- name))
+ path.join(SOURCE_PATH, MIOT_I18N_RELATIVE_PATH, name))
if not compare_dict_structure(default_dict, compare_dict):
print('compare_dict_structure failed /miot/i18n, ', name)
assert False