mirror of
https://github.com/yweber/lodel2.git
synced 2026-04-17 14:39:58 +02:00
Implementing mlstring + tests
This commit is contained in:
parent
9d4a85b5af
commit
7910374183
8 changed files with 229 additions and 0 deletions
0
lodel/utils/__init__.py
Normal file
0
lodel/utils/__init__.py
Normal file
98
lodel/utils/mlstring.py
Normal file
98
lodel/utils/mlstring.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
## @brief Stores multilangage string
|
||||
class MlString(object):
|
||||
|
||||
__default_lang = 'eng'
|
||||
|
||||
langs = [
|
||||
'fre',
|
||||
'eng',
|
||||
'ger',
|
||||
'esp',
|
||||
]
|
||||
|
||||
## @brief Create a new MlString instance
|
||||
# @param arg str | dict : Can be a json string, a string or a dict
|
||||
def __init__(self, arg):
|
||||
self.values = dict()
|
||||
if isinstance(arg, str):
|
||||
self.values[self.__default_lang] = arg
|
||||
elif isinstance(arg, dict):
|
||||
for lang, value in arg.items():
|
||||
if not self.lang_is_valid(lang):
|
||||
raise ValueError('Invalid lang found in argument : "%s"' % lang)
|
||||
self.values[lang] = value
|
||||
elif isinstance(arg, MlString):
|
||||
self.values = copy.copy(arg.values)
|
||||
else:
|
||||
raise ValueError('<class str>, <class dict> or <class MlString> expected, but %s found' % type(arg))
|
||||
|
||||
## @brief Return a translation given a lang
|
||||
# @param lang str
|
||||
def get(self, lang):
|
||||
if not self.lang_is_valid(lang):
|
||||
raise ValueError("Invalid lang : '%s'" % lang)
|
||||
elif lang in self.values:
|
||||
return self.values[lang]
|
||||
else:
|
||||
return str(self)
|
||||
|
||||
## @brief Set a translation
|
||||
# @param lang str : the lang
|
||||
# @param val str | None: the translation if None delete the translation
|
||||
def set(self, lang, val):
|
||||
if not self.lang_is_valid(lang):
|
||||
raise ValueError("Invalid lang : '%s'" % lang)
|
||||
if not isinstance(val, str) and val is not None:
|
||||
raise ValueError("Expected a <class str> as value but got %s" % type(val))
|
||||
if val is None:
|
||||
del(self.values[lang])
|
||||
else:
|
||||
self.values[lang] = val
|
||||
|
||||
## @brief Checks that given lang is valid
|
||||
# @param lang str : the lang
|
||||
@classmethod
|
||||
def lang_is_valid(cls, lang):
|
||||
if not isinstance(lang, str):
|
||||
raise ValueError('Invalid value for lang. Str expected but %s found' % type(lang))
|
||||
return lang in cls.langs
|
||||
|
||||
## @brief Get or set the default lang
|
||||
@classmethod
|
||||
def default_lang(cls, lang = None):
|
||||
if lang is None:
|
||||
return cls.__default_lang
|
||||
if not cls.lang_is_valid(lang):
|
||||
raise ValueError('lang "%s" is not valid"' % lang)
|
||||
cls.__default_lang = lang
|
||||
|
||||
## @brief Return a mlstring loaded from a json string
|
||||
# @param json_str str : Json string
|
||||
@classmethod
|
||||
def from_json(cls, json_str):
|
||||
return MlString(json.loads(json_str))
|
||||
|
||||
def __hash__(self):
|
||||
res = ''
|
||||
for lang in sorted(list(self.values.keys())):
|
||||
res = hash((res, lang, self.values[lang]))
|
||||
return res
|
||||
|
||||
def __eq__(self, a):
|
||||
return hash(self) == hash(a)
|
||||
|
||||
## @return The default langage translation or any available translation
|
||||
def __str__(self):
|
||||
if self.__default_lang in self.values:
|
||||
return self.values[self.__default_lang]
|
||||
else:
|
||||
return self.values[list(self.values.keys())[0]]
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.values)
|
||||
|
||||
49
runtest
Executable file
49
runtest
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Usage : ./runtest [OPTIONS] [test_module[.test_class][ test_module2[.test_class2]...]
|
||||
#########
|
||||
#
|
||||
# Options list :
|
||||
################
|
||||
#
|
||||
# -b, --buffer
|
||||
#
|
||||
# The standard output and standard error streams are buffered during the test run. Output during a passing test is discarded. Output is echoed normally on test fail or error and is added to the failure messages.
|
||||
#
|
||||
# -c, --catch
|
||||
#
|
||||
# Control-C during the test run waits for the current test to end and then reports all the results so far. A second control-C raises the normal KeyboardInterrupt exception.
|
||||
#
|
||||
#
|
||||
# -f, --failfast
|
||||
#
|
||||
# Stop the test run on the first error or failure.
|
||||
#
|
||||
# -h, --help
|
||||
#
|
||||
# Get some help
|
||||
#
|
||||
# -v, --verbose
|
||||
#
|
||||
# higher verbosity
|
||||
#
|
||||
# Examples :
|
||||
############
|
||||
#
|
||||
# Running all discoverables tests :
|
||||
# ./runtest
|
||||
#
|
||||
# Running only Em test about component object (only tests about the __init__ and modify_rank methods) with higher verbosity and failfast :
|
||||
# ./runtest -fv EditorialModel.test.test_component.TestInit EditorialModel.test.test_component.TestModifyRank
|
||||
#
|
||||
#
|
||||
# Running only Em tests
|
||||
# ./runtest discover EditorialModel
|
||||
#
|
||||
# More details :
|
||||
################
|
||||
#
|
||||
# https://docs.python.org/3.4/library/unittest.html
|
||||
#
|
||||
|
||||
python -W ignore -m unittest $@
|
||||
82
tests/test_mlstrings.py
Normal file
82
tests/test_mlstrings.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
import copy
|
||||
|
||||
from lodel.utils.mlstring import MlString
|
||||
|
||||
class MlStringTestCase(unittest.TestCase):
|
||||
|
||||
examples = {
|
||||
'eng': 'Hello world !',
|
||||
'fre': 'Bonjour monde !',
|
||||
'ger': 'Hallo welt !',
|
||||
}
|
||||
|
||||
def test_init_str(self):
|
||||
""" Test MlString instanciation with string as argument """
|
||||
testlangs = ['eng', 'fre']
|
||||
teststrs = ['hello', 'Hello world !', '{helloworld !!!]}']
|
||||
for lang in testlangs:
|
||||
for teststr in teststrs:
|
||||
MlString.default_lang(lang)
|
||||
mls_test = MlString(teststr)
|
||||
self.assertEqual(teststr, str(mls_test))
|
||||
self.assertEqual(teststr, mls_test.get(lang))
|
||||
|
||||
def test_init_dict(self):
|
||||
""" Test MlString instanciation with dict as argument """
|
||||
mls = MlString(self.examples)
|
||||
for lang, val in self.examples.items():
|
||||
self.assertEqual(mls.get(lang), val)
|
||||
|
||||
def test_init_json(self):
|
||||
""" Test MlString instanciation using a json string """
|
||||
testval = '{"eng":"Hello world !", "fre":"Bonjour monde !", "ger":"Hallo welt !"}'
|
||||
mls = MlString.from_json(testval)
|
||||
for lang in self.examples:
|
||||
self.assertEqual(mls.get(lang), self.examples[lang])
|
||||
|
||||
def test_get(self):
|
||||
""" Test MlString get method """
|
||||
mls = MlString(self.examples)
|
||||
for lang, val in self.examples.items():
|
||||
self.assertEqual(mls.get(lang), val)
|
||||
# A lang that is not set
|
||||
self.assertEqual(mls.get('esp'), str(mls))
|
||||
# A deleted lang
|
||||
mls.set('fre', None)
|
||||
self.assertEqual(mls.get('fre'), str(mls))
|
||||
|
||||
def test_eq(self):
|
||||
""" Test MlString comparison functions """
|
||||
for val in ['hello world', self.examples]:
|
||||
mls1 = MlString(val)
|
||||
mls2 = MlString(val)
|
||||
self.assertTrue(mls1 == mls2)
|
||||
self.assertEqual(hash(mls1), hash(mls2))
|
||||
|
||||
mls1 = MlString('Hello world !')
|
||||
mls2 = MlString('hello world !')
|
||||
self.assertTrue(mls1 != mls2)
|
||||
self.assertNotEqual(hash(mls1), hash(mls2))
|
||||
|
||||
modexamples = copy.copy(self.examples)
|
||||
modexamples['eng'] = 'hello world !'
|
||||
mls1 = MlString(modexamples)
|
||||
mls2 = MlString(self.examples)
|
||||
self.assertTrue(mls1 != mls2)
|
||||
self.assertNotEqual(hash(mls1), hash(mls2))
|
||||
|
||||
mls1 = MlString(self.examples)
|
||||
mls2 = MlString(self.examples)
|
||||
mls1.set('eng', None)
|
||||
self.assertTrue(mls1 != mls2)
|
||||
self.assertNotEqual(hash(mls1), hash(mls2))
|
||||
|
||||
mls1 = MlString(self.examples)
|
||||
mls2 = MlString(self.examples)
|
||||
mls1.set('eng', 'hello world !')
|
||||
self.assertTrue(mls1 != mls2)
|
||||
self.assertNotEqual(hash(mls1), hash(mls2))
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue