Merge pull request #1341 from Exiv2/fix_1278_nls_test_0.27

Fix 1278 nls test 0.27
main
Robin Mills 5 years ago committed by GitHub
commit 55bdaafebf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -40,10 +40,6 @@ add_library( exiv2lib_int OBJECT
unused.h unused.h
) )
if (COMPILER_IS_GCC OR COMPILER_IS_CLANG)
set_source_files_properties(http.cpp PROPERTIES COMPILE_FLAGS -fno-sanitize=address,undefined)
endif()
add_library( exiv2lib add_library( exiv2lib
../include/exiv2/config.h ../include/exiv2/config.h
../include/exiv2/exiv2.hpp ../include/exiv2/exiv2.hpp

@ -83,6 +83,7 @@ TESTS = addmoddel.sh \
iotest.sh \ iotest.sh \
iptctest.sh \ iptctest.sh \
iso65k-test.sh \ iso65k-test.sh \
nls-test.sh \
modify-test.sh \ modify-test.sh \
path-test.sh \ path-test.sh \
png-test.sh \ png-test.sh \
@ -112,6 +113,7 @@ exiv2-test \
imagetest \ imagetest \
iotest \ iotest \
iptctest \ iptctest \
nls-test \
preview-test \ preview-test \
tiff-test \ tiff-test \
write-test \ write-test \

@ -0,0 +1,10 @@
exiv2: Une action doit être spécifié
exiv2: Au moins un fichier est nécessaire
Utilisation : exiv2 [ options ] [ action ] fichier ...
Manipulation des métadonnées EXIF issues des images.
exiv2: Se debe especificar una acción
exiv2: Se requiere un archivo al menos
Uso: exiv2 [ opciones ] [ acción ] archivo ...
manipular los metadatos Exif de las imágenes.

@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Test driver for exiv2.exe nls support
source ./functions.source
( cd "$testdir"
nls=$(runTest exiv2 -vVg nls|tail -1)
platform=$(${bin}exiv2${exe} -vVg platform|tail -1)
if [ "$nls" != "enable_nls=1" ]; then
echo "exiv2 not bulid with nls"
exit 0
fi
if [ "$platform" == "platform=windows" ]; then
echo "nls_test cannot be run msvc builds" >2
exit 0
fi
if [ "$platform" == "platform=linux" ]; then
LANG=LANGUAGE
else
LANG=LANG
fi
##
# if necessary ditto /usr/local/share/locale -> build/share/locale
share=${bin}../share
if [ ! -e $share ]; then
mkdir -p $share
fi
usr=/usr/local/share/locale
if [ -e "$usr" -a -e "$share" ]; then
cp -r "$usr" "$share"
else
echo "localisation files are not installed in $usr"
exit 0
fi
##
# test a couple of languages
for l in fr_FR es_ES; do (
export LC_ALL=$l
export $LANG=$l
runTest exiv2
) done
) 3>&1 > $results 2>&1
reportTest
# That's all Folks!
##

@ -861,6 +861,40 @@ set Exif.Photo.DateTimeDigitized 2020:05:26 07:31:42
BT.reportTest('modify-test', out) BT.reportTest('modify-test', out)
def nls_test(self):
# Test driver for exiv2.exe nls support
nls = BT.Executer('exiv2 -vVg nls').stdout.split('\n')[1]
platform = BT.Executer('exiv2 -vVg platform').stdout.split('\n')[1]
if nls != 'enable_nls=1':
print('Skipped. Because exiv2 is not built with nls.')
return
if platform == 'platform=windows':
print('Skipped. Because nls_test cannot be run msvc builds.')
return
if platform == 'platform=linux':
LANG = 'LANGUAGE'
else:
LANG = 'LANG'
share_dir = os.path.normpath(os.path.join(BT.Config.bin_dir, '..', 'share2'))
os.makedirs(share_dir, exist_ok=True)
locale_dir = '/usr/local/share/locale'
if os.path.isdir(locale_dir) and os.path.isdir(share_dir):
BT.cp(locale_dir, share_dir)
else:
print('Skipped. Because localisation files are not installed in {}.'.format(locale_dir))
# The above part is checking the environment, and the following part is executing the actual test
out = BT.Output()
for language in ['fr_FR', 'es_ES']:
out += BT.Executer('exiv2', extra_env={'LC_ALL': language, LANG: language}, assert_returncode=[1])
BT.reportTest('nls-test', out)
def path_test(self): def path_test(self):
# Mini test-driver for path utility functions # Mini test-driver for path utility functions
BT.copyTestFile('path-test.txt') BT.copyTestFile('path-test.txt')
@ -956,7 +990,7 @@ set Exif.Photo.DateTimeDigitized 2020:05:26 07:31:42
e = BT.Executer('exiv2 -pp {filename}', vars(), assert_returncode=None, redirect_stderr_to_stdout=False) e = BT.Executer('exiv2 -pp {filename}', vars(), assert_returncode=None, redirect_stderr_to_stdout=False)
out += e.stdout out += e.stdout
out += 'Exit code: {}'.format(e.returncode) out += 'Exit code: {}'.format(e.returncode)
BT.rm(*BT.find(image + '-preview*')) BT.rm(*BT.find(pattern=image + '-preview*'))
out += '\nCommand: exiv2 -f -ep ' + filename out += '\nCommand: exiv2 -f -ep ' + filename
e = BT.Executer('exiv2 -f -ep {filename}', vars(), assert_returncode=None, redirect_stderr_to_stdout=False) e = BT.Executer('exiv2 -f -ep {filename}', vars(), assert_returncode=None, redirect_stderr_to_stdout=False)
@ -966,7 +1000,7 @@ set Exif.Photo.DateTimeDigitized 2020:05:26 07:31:42
# Check the difference # Check the difference
e = BT.Executer('exiv2 -pp {filename}', vars(), assert_returncode=None, redirect_stderr_to_stdout=False) e = BT.Executer('exiv2 -pp {filename}', vars(), assert_returncode=None, redirect_stderr_to_stdout=False)
preview_num = e.stdout[:e.stdout.find(':')].lstrip('Preview ') preview_num = e.stdout[:e.stdout.find(':')].lstrip('Preview ')
for test_file in BT.find('{image}-preview{preview_num}.*'.format(**vars())): for test_file in BT.find(pattern='{image}-preview{preview_num}.*'.format(**vars())):
reference_file = os.path.join(preview_dir, test_file) reference_file = os.path.join(preview_dir, test_file)
if BT.diffCheck(reference_file, test_file, in_bytes=True): if BT.diffCheck(reference_file, test_file, in_bytes=True):
pass_count += 1 pass_count += 1
@ -987,8 +1021,7 @@ set Exif.Photo.DateTimeDigitized 2020:05:26 07:31:42
try: try:
import lxml import lxml
except ModuleNotFoundError: except ModuleNotFoundError:
print('ignored') print('Skipped. Because it misses module lxml. Please install: `pip install lxml`')
print('Missing module lxml, please install: `pip install lxml`')
return return
out = BT.Output() out = BT.Output()

@ -44,36 +44,17 @@ Part 2:
Here are some common functions that are poorly coupled with test cases. Here are some common functions that are poorly coupled with test cases.
""" """
def cp(src, dest):
""" It is used to copy one file, cannot handle directories """
shutil.copy(src, dest)
def find(directory='.', pattern=None, re_pattern=None, depth=-1, onerror=print) -> list:
def mv(src, dest):
""" It is used to move one file, cannot handle directories """
shutil.move(src, dest)
def rm(*files):
""" It is used to remove files, cannot handle directories """
for i in files:
try:
os.remove(i)
except FileNotFoundError:
continue
def find(pattern=None, re_pattern=None, directory='.', depth=-1, onerror=print) -> list:
""" """
Find files that match the pattern in the specified directory and return their paths. Find files and directories that match the pattern in the specified directory and return their paths.
Work in recursive mode. If there are thousands of files, the runtime may be several seconds.
- `directory` : Find files in this directory and its subdirectories
- `pattern` : Filter filename based on shell-style wildcards. - `pattern` : Filter filename based on shell-style wildcards.
- `re_pattern` : Filter filename based on regular expressions. - `re_pattern` : Filter filename based on regular expressions.
- `directory` : Find files in this directory and its subdirectories
- `depth` : Depth of subdirectories. If its value is negative, the depth is infinite. - `depth` : Depth of subdirectories. If its value is negative, the depth is infinite.
- `onerror` : A callable parameter. it will be called if an exception occurs. - `onerror` : A callable parameter. it will be called if an exception occurs.
Work in recursive mode. If there are thousands of files, the runtime may be several seconds.
Sample: Sample:
>>> find(pattern='*.py') >>> find(pattern='*.py')
>>> find(re_pattern='.*.py') >>> find(re_pattern='.*.py')
@ -85,25 +66,72 @@ def find(pattern=None, re_pattern=None, directory='.', depth=-1, onerror=print)
file_list = os.listdir(directory) file_list = os.listdir(directory)
except PermissionError as e: # Sometimes it does not have access to the directory except PermissionError as e: # Sometimes it does not have access to the directory
onerror("PermissionError: {}".format(e)) onerror("PermissionError: {}".format(e))
return -1 return []
def match(name, pattern=None, re_pattern=None):
if pattern and not fnmatch.fnmatch(name, pattern):
return False
if re_pattern and not re.findall(re_pattern, name):
return False
return True
path_list = [] path_list = []
for filename in file_list: if match(os.path.basename(directory), pattern, re_pattern):
path = os.path.join(directory, filename) path_list.append(directory)
if depth != 0 and os.path.isdir(path): if depth != 0:
sub_list = find(path, depth-1, pattern, re_pattern, onerror) for filename in file_list:
if sub_list != -1: path = os.path.join(directory, filename)
path_list.extend(sub_list) if os.path.isdir(path):
continue path_list.extend(find(path, pattern, re_pattern, depth-1, onerror))
if pattern and not fnmatch.fnmatch(filename, pattern): continue
continue if match(filename, pattern, re_pattern):
if re_pattern and not re.findall(re_pattern, filename): path_list.append(path)
continue
path_list.append(path)
return path_list return path_list
def cp(src, dst):
""" Copy one or more files or directories. It simulates `cp -rf src dst`. """
if os.path.isfile(src):
shutil.copy(src, dst)
elif os.path.isdir(src):
if os.path.isdir(dst):
dst_dir = os.path.join(dst, os.path.basename(src))
else:
dst_dir = dst
for src_path in find(src):
relpath = os.path.relpath(src_path, src)
dst_path = os.path.join(dst_dir, relpath)
if os.path.isdir(src_path):
os.makedirs(dst_path, exist_ok=True)
else:
shutil.copy(src_path, dst_path)
else:
raise ValueError('src is not a valid path to a file or directory.')
def rm(*paths):
""" Remove one or more files or directories. It simulates `rm -rf paths`. """
for path in paths:
if os.path.isfile(path):
os.remove(path)
elif os.path.isdir(path):
for sub_path in find(path, depth=1)[1:]:
if os.path.isdir(sub_path):
rm(sub_path)
else:
os.remove(sub_path)
os.rmdir(path) # Remove the directory only when it is empty
else:
continue
def mv(src, dst):
""" Move one or more files or directories. """
cp(src, dst)
rm(src)
def cat(*files, encoding=None, return_bytes=False): def cat(*files, encoding=None, return_bytes=False):
if return_bytes: if return_bytes:
result = b'' result = b''
@ -319,12 +347,12 @@ Part 3:
Here are some functions that are highly coupled to test cases. Here are some functions that are highly coupled to test cases.
""" """
def copyTestFile(src, dest=''): def copyTestFile(src, dst=''):
""" Copy one test file from data_dir to tmp_dir """ """ Copy one test file from data_dir to tmp_dir """
if not dest: if not dst:
dest = src dst = src
shutil.copy(os.path.join(Config.data_dir, src), shutil.copy(os.path.join(Config.data_dir, src),
os.path.join(Config.tmp_dir, dest)) os.path.join(Config.tmp_dir, dst))
def diffCheck(file1, file2, in_bytes=False, encoding=None): def diffCheck(file1, file2, in_bytes=False, encoding=None):
@ -382,6 +410,7 @@ class Executer:
def __init__(self, cmd: str, def __init__(self, cmd: str,
vars_dict=dict(), vars_dict=dict(),
cwd=None, cwd=None,
extra_env=dict(),
encoding=None, encoding=None,
stdin: (str, bytes) = None, stdin: (str, bytes) = None,
redirect_stderr_to_stdout=True, redirect_stderr_to_stdout=True,
@ -390,6 +419,12 @@ class Executer:
decode_output=True): decode_output=True):
self.cmd = cmd.format(**vars_dict) self.cmd = cmd.format(**vars_dict)
self.cwd = cwd or Config.tmp_dir self.cwd = cwd or Config.tmp_dir
# set environment variables
self.env = os.environ.copy()
self.env.update({'TZ': 'GMT-8'})
self.env.update(extra_env)
self.encoding = encoding or Config.encoding self.encoding = encoding or Config.encoding
self.stdin = stdin self.stdin = stdin
# self.stdout = None # self.stdout = None
@ -410,7 +445,7 @@ class Executer:
else: else:
self.args = shlex.split(args, posix=os.name == 'posix') self.args = shlex.split(args, posix=os.name == 'posix')
# check stdin # Check stdin
if self.stdin: if self.stdin:
if not isinstance(stdin, bytes): if not isinstance(stdin, bytes):
self.stdin = str(stdin).encode(self.encoding) self.stdin = str(stdin).encode(self.encoding)
@ -426,9 +461,9 @@ class Executer:
# Execute the command in subprocess # Execute the command in subprocess
try: try:
my_env = os.environ.copy() with subprocess.Popen(self.args, cwd=self.cwd, env=self.env,
my_env['TZ'] = 'GMT-8' stdin=subprocess.PIPE, stdout=subprocess.PIPE,
with subprocess.Popen(self.args,env=my_env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=stderr, cwd=self.cwd) as self.subprocess: stderr=stderr) as self.subprocess:
try: try:
output = self.subprocess.communicate(self.stdin, timeout=10) # Assign (stdout, stderr) to output output = self.subprocess.communicate(self.stdin, timeout=10) # Assign (stdout, stderr) to output
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
@ -447,7 +482,7 @@ class Executer:
output = [i.decode(self.encoding) for i in output] output = [i.decode(self.encoding) for i in output]
self.stdout, self.stderr = [i or None for i in output] self.stdout, self.stderr = [i or None for i in output]
# check return code # Check return code
self.returncode = self.subprocess.returncode self.returncode = self.subprocess.returncode
if self.assert_returncode and self.returncode not in self.assert_returncode: if self.assert_returncode and self.returncode not in self.assert_returncode:
log.error('Failed to execute: {}'.format(self.args)) log.error('Failed to execute: {}'.format(self.args))

Loading…
Cancel
Save