commit mwic for openSUSE:Factory

Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mwic for openSUSE:Factory checked in at 2024-01-03 12:23:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mwic (Old) and /work/SRC/openSUSE:Factory/.mwic.new.28375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "mwic" Wed Jan 3 12:23:26 2024 rev:8 rq:1135580 version:0.7.10 Changes: -------- --- /work/SRC/openSUSE:Factory/mwic/mwic.changes 2023-01-20 17:39:12.676697470 +0100 +++ /work/SRC/openSUSE:Factory/.mwic.new.28375/mwic.changes 2024-01-03 12:23:28.348154578 +0100 @@ -1,0 +2,15 @@ +Thu Dec 28 20:31:54 UTC 2023 - Dirk Müller <dmueller@suse.com> + +- update to 0.7.10: + * Fix --max-context-width. + * When trimming strings, take grapheme clusters into account. + * Add new multi-word misspellings to the dictionary. + * Improve pager support: + + Don't reset encoding error handler to “strict”. + + Improve handling errors. + * Improve the test suite. + * Use “pytest” in “make test”. + * Enlarge screenshot. +- mwic.keyring: update with 2023 key from https://jwilk.net/openpgp/ + +------------------------------------------------------------------- Old: ---- mwic-0.7.9.tar.gz mwic-0.7.9.tar.gz.asc New: ---- mwic-0.7.10.tar.gz mwic-0.7.10.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mwic.spec ++++++ --- /var/tmp/diff_new_pack.IlAVLv/_old 2024-01-03 12:23:29.264188056 +0100 +++ /var/tmp/diff_new_pack.IlAVLv/_new 2024-01-03 12:23:29.264188056 +0100 @@ -18,7 +18,7 @@ %{!?license: %global license %doc} Name: mwic -Version: 0.7.9 +Version: 0.7.10 Release: 0 Summary: A spellchecker with grouping support License: MIT ++++++ mwic-0.7.9.tar.gz -> mwic-0.7.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/Makefile new/mwic-0.7.10/Makefile --- old/mwic-0.7.9/Makefile 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/Makefile 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright © 2012-2019 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2012-2022 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -59,12 +59,13 @@ .PHONY: test test: - $(PYTHON) tests/run-tests --verbose + $(PYTHON) -bb -m pytest -v .PHONY: clean clean: find . -type f -name '*.py[co]' -delete find . -type d -name '__pycache__' -delete + rm -rf .pytest_cache rm -f .coverage rm -f *.tmp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/dict/en new/mwic-0.7.10/dict/en --- old/mwic-0.7.9/dict/en 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/dict/en 2023-02-23 16:00:36.000000000 +0100 @@ -184,7 +184,9 @@ do(es)?n’t user # ISO 8895 (etc.) → ISO 8859 +# ISO 8061 (etc.) → ISO 8601 iso( |[_-])?(8858|8895|8559|5589) +iso( |[_-])?(8061|8610) # lot's of → lots of lot’s of @@ -198,6 +200,9 @@ # more that → more than (more|less|larger|bigger|smaller|faster|slower) that(?! way) +# no enough → not enough +no enough + # an → a an Unicode an unary diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/doc/LICENSE new/mwic-0.7.10/doc/LICENSE --- old/mwic-0.7.9/doc/LICENSE 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/doc/LICENSE 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright © 2012-2022 Jakub Wilk <jwilk@jwilk.net> +Copyright © 2012-2023 Jakub Wilk <jwilk@jwilk.net> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/doc/changelog new/mwic-0.7.10/doc/changelog --- old/mwic-0.7.9/doc/changelog 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/doc/changelog 2023-02-23 16:00:36.000000000 +0100 @@ -1,3 +1,17 @@ +mwic (0.7.10) unstable; urgency=low + + * Fix --max-context-width. + * When trimming strings, take grapheme clusters into account. + * Add new multi-word misspellings to the dictionary. + * Improve pager support: + + Don't reset encoding error handler to “strict”. + + Improve handling errors. + * Improve the test suite. + * Use “pytest” in “make test”. + * Enlarge screenshot. + + -- Jakub Wilk <jwilk@jwilk.net> Thu, 23 Feb 2023 16:00:04 +0100 + mwic (0.7.9) unstable; urgency=low * Add new multi-word misspellings to the dictionary. @@ -7,7 +21,7 @@ + Use uppercase for CLI metavar. * Drop support for Python < 3.6. * Update Docutils homepage URL. - * Make it possible use pytest as the test harness. + * Make it possible to use pytest as the test harness. -- Jakub Wilk <jwilk@jwilk.net> Mon, 25 Apr 2022 14:33:05 +0200 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/doc/manpage.rst new/mwic-0.7.10/doc/manpage.rst --- old/mwic-0.7.9/doc/manpage.rst 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/doc/manpage.rst 2023-02-23 16:00:36.000000000 +0100 @@ -7,8 +7,8 @@ --------------------------- :manual section: 1 -:version: mwic 0.7.9 -:date: 2022-04-25 +:version: mwic 0.7.10 +:date: 2023-02-23 Synopsis -------- @@ -90,8 +90,8 @@ LESS If this variable is unset, mwic sets it - to ``FX``, - or to ``FXR`` if the output is in color. + to ``-FX``, + or to ``-FXR`` if the output is in color. LV If this variable in unset, and the output is in color, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/doc/mwic.1 new/mwic-0.7.10/doc/mwic.1 --- old/mwic-0.7.9/doc/mwic.1 2022-04-25 14:33:19.000000000 +0200 +++ new/mwic-0.7.10/doc/mwic.1 2023-02-23 16:00:40.000000000 +0100 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH MWIC 1 "2022-04-25" "mwic 0.7.9" "" +.TH MWIC 1 "2023-02-23" "mwic 0.7.10" "" .SH NAME mwic \- Misspelled Words In Context . @@ -107,8 +107,8 @@ .TP .B LESS If this variable is unset, mwic sets it -to \fBFX\fP, -or to \fBFXR\fP if the output is in color. +to \fB\-FX\fP, +or to \fB\-FXR\fP if the output is in color. .TP .B LV If this variable in unset, and the output is in color, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/doc/screenshot.svg new/mwic-0.7.10/doc/screenshot.svg --- old/mwic-0.7.9/doc/screenshot.svg 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/doc/screenshot.svg 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -<svg xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" viewBox="0 0 804 762" width="80.4ex" height="76.2ex"> +<svg xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" viewBox="0 0 804 762" width="48em" height="45.4em"> <g font-family="monospace" font-size="16"> <rect width="804" height="764"></rect><rect width="10" height="20" x="2" y="2"></rect><g fill="#fff" font-weight="bold"><text x="2" y="17">$</text> </g><rect width="740" height="20" x="12" y="2"></rect><g fill="#eee"><text x="22" y="17">m</text><text x="32" y="17">w</text><text x="42" y="17">i</text><text x="52" y="17">c</text> <text x="72" y="17">-</text><text x="82" y="17">-</text><text x="92" y="17">b</text><text x="102" y="17">l</text><text x="112" y="17">a</text><text x="122" y="17">c</text><text x="132" y="17">k</text><text x="142" y="17">l</text><text x="152" y="17">i</text><text x="162" y="17">s</text><text x="172" y="17">t</text> <text x="192" y="17">/</text><text x="202" y="17">u</text><text x="212" y="17">s</text><text x="222" y="17">r</text><text x="232" y="17">/</text><text x="242" y="17">s</text><text x="252" y="17">h</text><text x="262" y="17">a</text><text x="272" y="17">r</text><text x="282" y="17">e</text><text x="292" y="17">/</text><text x="302" y="17">l</text><t ext x="312" y="17">i</text><text x="322" y="17">n</text><text x="332" y="17">t</text><text x="342" y="17">i</text><text x="352" y="17">a</text><text x="362" y="17">n</text><text x="372" y="17">/</text><text x="382" y="17">d</text><text x="392" y="17">a</text><text x="402" y="17">t</text><text x="412" y="17">a</text><text x="422" y="17">/</text><text x="432" y="17">s</text><text x="442" y="17">p</text><text x="452" y="17">e</text><text x="462" y="17">l</text><text x="472" y="17">l</text><text x="482" y="17">i</text><text x="492" y="17">n</text><text x="502" y="17">g</text><text x="512" y="17">/</text><text x="522" y="17">c</text><text x="532" y="17">o</text><text x="542" y="17">r</text><text x="552" y="17">r</text><text x="562" y="17">e</text><text x="572" y="17">c</text><text x="582" y="17">t</text><text x="592" y="17">i</text><text x="602" y="17">o</text><text x="612" y="17">n</text><text x="622" y="17">s</text> <text x="642" y="17">r</text><text x="652" y="17">f</text><text x="662 " y="17">c</text><text x="672" y="17">1</text><text x="682" y="17">9</text><text x="692" y="17">2</text><text x="702" y="17">7</text><text x="712" y="17">.</text><text x="722" y="17">t</text><text x="732" y="17">x</text><text x="742" y="17">t</text></g> <rect width="50" height="20" x="752" y="2"></rect><rect width="130" height="20" x="2" y="22"></rect><g fill="#eee"><text x="2" y="37">h</text><text x="12" y="37">e</text><text x="22" y="37">i</text><text x="32" y="37">r</text><text x="42" y="37">a</text><text x="52" y="37">r</text><text x="62" y="37">c</text><text x="72" y="37">h</text><text x="82" y="37">i</text><text x="92" y="37">c</text><text x="102" y="37">a</text><text x="112" y="37">l</text><text x="122" y="37">:</text></g> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/lib/cli.py new/mwic-0.7.10/lib/cli.py --- old/mwic-0.7.9/lib/cli.py 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/lib/cli.py 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright © 2013-2022 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2013-2023 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -25,6 +25,7 @@ import argparse import functools import io +import re import signal import sys import types @@ -41,7 +42,7 @@ from . import text # pylint: enable=import-outside-toplevel -__version__ = '0.7.9' +__version__ = '0.7.10' class VersionAction(argparse.Action): @@ -99,7 +100,7 @@ help='omit blank lines in output') ap.add_argument('--limit', metavar='N', type=int, default=1e999, help='skip words that have >N instances') - ap.add_argument('--max-context-width', metavar='N', default=30, + ap.add_argument('--max-context-width', type=int, metavar='N', default=30, help='limit context width to N chars') ap.add_argument('--suggest', metavar='N', type=int, default=0, help='suggest up to N corrections') @@ -173,8 +174,15 @@ if not misspellings: sys.exit(rc) raw_cc = options.output_format == 'color' - with lib.pager.autopager(raw_control_chars=raw_cc): - print_misspellings(ctxt) + try: + with lib.pager.autopager(raw_control_chars=raw_cc): + print_misspellings(ctxt) + except lib.pager.Error: + if options.traceback: + raise + msg = f'{ap.prog}: pager failed' + print(msg, file=sys.stderr) + rc = 1 sys.exit(rc) def spellcheck_file(ctxt, file): @@ -185,7 +193,7 @@ for line in file: if force_ucs2: # https://github.com/rfk/pyenchant/issues/58 - line = ''.join(c if c <= '\uFFFF' else '\uFFFD' for c in line) + line = re.sub(r'[^\0-\uFFFF]', '\uFFFD', line) line = line.strip() line = line.expandtabs() taken = bytearray(len(line)) @@ -289,7 +297,7 @@ underline[x : x + len(word)] = underline_char * len(word) if not header: continue - print(', '.join(header) + ':') + print(str.join(', ', header) + ':') underline = underline.decode() lwidth = len(underline) - len(underline.lstrip()) rwidth = len(underline) - len(underline.rstrip()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/lib/intdict.py new/mwic-0.7.10/lib/intdict.py --- old/mwic-0.7.9/lib/intdict.py 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/lib/intdict.py 2023-02-23 16:00:36.000000000 +0100 @@ -67,7 +67,7 @@ for i, (name, definition) in enumerate(self._defs.items()): substs += [definition] regex += [f'(?P<mwic{i}>{re.escape(name)})'] - regex = '|'.join(regex) + regex = str.join('|', regex) regex = re.compile(regex) self._regex = regex self._substs = substs @@ -129,7 +129,7 @@ else: raise error('malformed @-command') # no coverage else: - regex = r'\s+'.join(line) + regex = str.join(r'\s+', line) regex = macros.expand(regex) try: re.compile(regex) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/lib/pager.py new/mwic-0.7.10/lib/pager.py --- old/mwic-0.7.9/lib/pager.py 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/lib/pager.py 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright © 2015-2021 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2015-2022 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -35,13 +35,16 @@ def get_default_pager(): # Use "pager" if it exist: - # https://www.debian.org/doc/debian-policy/#document-ch-customized-programs + # https://www.debian.org/doc/debian-policy/ch-customized-programs.html#editors... # Fall back to "more", which is in POSIX. return ( _find_command('pager') or 'more' ) +class Error(RuntimeError): + pass + @contextlib.contextmanager def autopager(*, raw_control_chars=False): if not sys.stdout.isatty(): @@ -53,7 +56,7 @@ return env = None if 'LESS' not in os.environ: - lessopt = 'FX' + lessopt = '-FX' if raw_control_chars: lessopt += 'R' env = dict(env or os.environ, LESS=lessopt) @@ -64,6 +67,7 @@ with ipc.Popen(cmdline, shell=True, stdin=ipc.PIPE, env=env) as pager: sys.stdout = io.TextIOWrapper(pager.stdin, encoding=orig_stdout.encoding, + errors=orig_stdout.errors, ) try: yield @@ -71,8 +75,11 @@ sys.stdout.close() finally: sys.stdout = orig_stdout + if pager.returncode: + raise Error __all__ = [ + 'Error', 'autopager', ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/lib/text.py new/mwic-0.7.10/lib/text.py --- old/mwic-0.7.9/lib/text.py 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/lib/text.py 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright © 2013-2018 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2013-2023 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -23,21 +23,29 @@ ''' import functools -import re +import regex as re def ltrim(s, n, *, char='…'): - if len(s) <= n: + if n <= 0: + return s and char + pat = re.compile(r'\X\X(\X{#})\Z'.replace('#', str(n - 1))) + match = pat.search(s) + if match is None: return s if n <= 1: return char - return char + s[-n+1:] + return char + match.group(1) def rtrim(s, n, *, char='…'): - if len(s) <= n: + if n <= 0: + return s and char + pat = re.compile(r'\A(\X{#})\X\X'.replace('#', str(n - 1))) + match = pat.match(s) + if match is None: return s if n <= 1: return char - return s[:n-1] + char + return match.group(1) + char _camel_case_split = re.compile('([A-Z][^A-Z]*)').split diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/private/check-rst new/mwic-0.7.10/private/check-rst --- old/mwic-0.7.9/private/check-rst 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/private/check-rst 2023-02-23 16:00:36.000000000 +0100 @@ -37,6 +37,6 @@ else printf '%s\n' "$@" fi | -xargs -t -I{} "$rst2xml" $options {} /dev/null +xargs -t -I{} "$rst2xml" $options {} > /dev/null # vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/private/update-branch-coverage new/mwic-0.7.10/private/update-branch-coverage --- old/mwic-0.7.9/private/update-branch-coverage 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/private/update-branch-coverage 2023-02-23 16:00:36.000000000 +0100 @@ -1,6 +1,6 @@ -#!/usr/bin/env python3 +#!/bin/sh -# Copyright © 2014 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2022 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -20,51 +20,17 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import io -import os -import sys - -import nose -import nose.plugins.cover - -class Coverage(nose.plugins.cover.Coverage): - - stream = None - - def report(self, stream): - return super().report(self.stream) - -basedir = os.path.join( - os.path.dirname(__file__), - os.pardir, -) - -def main(): - argv = [ - sys.argv[0], - '--with-coverage', - '--cover-package=lib', - '--cover-erase', - ] - path = os.path.join( - 'tests', - 'coverage' - ) - plugin = Coverage() - report_stream = plugin.stream = io.StringIO() - print('Generated automatically by private/update-branch-coverage. ' - 'Do not edit.\n', file=report_stream) - ok = nose.run(argv=argv, plugins=[plugin]) - if not ok: - sys.exit(1) - report_stream.seek(0) - with open(path + '.tmp', 'wt', encoding='ASCII') as file: - for line in report_stream: - line = line.rstrip() - print(line, file=file) - os.rename(path + '.tmp', path) - -if __name__ == '__main__': - main() +set -e -u +here=${0%/*} +cd "$here/.." +python3 -m pytest --cov=lib --cov-branch --cov-report= -q +true > tests/coverage.tmp +printf 'Generated automatically by private/update-branch-coverage. ' >> tests/coverage.tmp +printf 'Do not edit.\n\n' >> tests/coverage.tmp +python3 -m coverage report >> tests/coverage.tmp || { + printf '"python3 -m coverage" failed\n' >&2 + exit 1 +} +mv tests/coverage.tmp tests/coverage # vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/coverage new/mwic-0.7.10/tests/coverage --- old/mwic-0.7.9/tests/coverage 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/tests/coverage 2023-02-23 16:00:36.000000000 +0100 @@ -2,13 +2,13 @@ Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------- -lib/__init__.py 1 0 2 1 67% 5->exit -lib/cli.py 219 41 102 20 76% 62-63, 114, 125-131, 151, 163-169, 173, 187, 194, 221-222, 233, 236-238, 254-257, 278, 282, 285-287, 292, 308-316, 325-327, 65->67, 113->114, 124->125, 137->139, 150->151, 172->173, 185->187, 193->194, 220->221, 232->233, 235->236, 253->254, 265->267, 267->229, 277->278, 281->282, 284->285, 291->292, 307->308, 320->273 -lib/colors.py 36 5 12 3 83% 38, 45, 52-53, 62, 44->45, 51->52, 61->62 -lib/data.py 56 3 14 2 90% 38-39, 86, 35->38, 85->86 -lib/extdict.py 61 0 32 2 98% 84->88, 98->101 -lib/intdict.py 93 0 24 0 100% -lib/pager.py 40 25 12 1 31% 33-34, 40, 50-76, 47->50 -lib/text.py 28 0 16 0 100% +lib/__init__.py 1 0 0 0 100% +lib/cli.py 229 49 106 19 75% 64-65, 68, 116, 127-133, 139->141, 165-171, 175, 180-185, 196, 203, 230-231, 242, 245-248, 264-267, 271->273, 273->238, 284, 288, 291-294, 299, 315-323, 327->279, 332-334 +lib/colors.py 36 5 12 3 83% 38, 45, 52-53, 62 +lib/data.py 57 3 18 2 91% 38-39, 86 +lib/extdict.py 61 0 34 2 98% 84->88, 98->101 +lib/intdict.py 95 0 26 0 100% +lib/pager.py 42 25 18 1 33% 33-34, 40, 53-79 +lib/text.py 37 0 22 0 100% ------------------------------------------------------------- -TOTAL 534 74 214 29 82% +TOTAL 558 82 236 27 82% diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/multiword-iso.exp new/mwic-0.7.10/tests/multiword-iso.exp --- old/mwic-0.7.9/tests/multiword-iso.exp 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/tests/multiword-iso.exp 2023-02-23 16:00:36.000000000 +0100 @@ -2,10 +2,18 @@ | ISO-5589-1 ^^^^^^^^ +ISO-8061: +| ISO-8061 + ^^^^^^^^ + ISO-8559: | ISO-8559-1 ^^^^^^^^ +ISO-8610: +| ISO-8610 + ^^^^^^^^ + ISO-8858: | ISO-8858-1 ^^^^^^^^ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/multiword-iso.txt new/mwic-0.7.10/tests/multiword-iso.txt --- old/mwic-0.7.9/tests/multiword-iso.txt 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/tests/multiword-iso.txt 2023-02-23 16:00:36.000000000 +0100 @@ -4,3 +4,8 @@ ISO-5589-1 ISO-8859-1 + +ISO-8061 +ISO-8610 + +ISO-8601 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/multiword-no-enough.exp new/mwic-0.7.10/tests/multiword-no-enough.exp --- old/mwic-0.7.9/tests/multiword-no-enough.exp 1970-01-01 01:00:00.000000000 +0100 +++ new/mwic-0.7.10/tests/multiword-no-enough.exp 2023-02-23 16:00:36.000000000 +0100 @@ -0,0 +1,4 @@ +no enough: +| no enough memory + ^^^^^^^^^ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/multiword-no-enough.txt new/mwic-0.7.10/tests/multiword-no-enough.txt --- old/mwic-0.7.9/tests/multiword-no-enough.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/mwic-0.7.10/tests/multiword-no-enough.txt 2023-02-23 16:00:36.000000000 +0100 @@ -0,0 +1 @@ +no enough memory diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/run-nose new/mwic-0.7.10/tests/run-nose --- old/mwic-0.7.9/tests/run-nose 1970-01-01 01:00:00.000000000 +0100 +++ new/mwic-0.7.10/tests/run-nose 2023-02-23 16:00:36.000000000 +0100 @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +# Copyright © 2016-2023 Jakub Wilk <jwilk@jwilk.net> +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the “Software”), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import pathlib +import sys + +import nose + +sys.path[:0] = [str(pathlib.Path(__file__).parent.parent)] + +from tests import test_blackbox # pylint: disable=wrong-import-position + +if __name__ == '__main__': + nose.main(addplugins=[test_blackbox.nose_plugin()]) + +# vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/run-tests new/mwic-0.7.10/tests/run-tests --- old/mwic-0.7.9/tests/run-tests 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/tests/run-tests 1970-01-01 01:00:00.000000000 +0100 @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright © 2016-2022 Jakub Wilk <jwilk@jwilk.net> -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the “Software”), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import sys - -import nose - -sys.path[0] += '/..' - -from tests import test_blackbox - -if __name__ == '__main__': - nose.main(addplugins=[test_blackbox.nose_plugin()]) - -# vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/test_blackbox.py new/mwic-0.7.10/tests/test_blackbox.py --- old/mwic-0.7.9/tests/test_blackbox.py 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/tests/test_blackbox.py 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright © 2014-2022 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2014-2023 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -21,34 +21,54 @@ import glob import io import os +import random +import signal +import string import sys import unittest.mock import lib.cli as M from .tools import ( + assert_in, assert_multi_line_equal, ) here = os.path.dirname(__file__) here = os.path.relpath(here) -def _get_output(path, language): - argv = ['mwic', '--language', language, path] +def _get_output(*args, stdin=''): + argv = ['mwic', *args] + binstdin = io.BytesIO(stdin.encode('UTF-8')) + textstdin = io.TextIOWrapper(binstdin, encoding='UTF-8') binstdout = io.BytesIO() textstdout = io.TextIOWrapper(binstdout, encoding='UTF-8') - with unittest.mock.patch.multiple(sys, argv=argv, stdout=textstdout): + sys_patch = unittest.mock.patch.multiple(sys, argv=argv, stdin=textstdin, stdout=textstdout) + signal_patch = unittest.mock.patch('signal.signal') + with sys_patch, signal_patch: try: try: M.main() except SystemExit as exc: if exc.code != 0: raise + signal.signal.assert_called_once() sys.stdout.flush() return binstdout.getvalue().decode('UTF-8') finally: textstdout.close() +def random_word(): + return str.join('', [ + random.choice(string.ascii_lowercase) + for x in range(32) + ]) + +def test_max_context_width(): + bad_word = random_word() + text = _get_output('--language', 'en', '--max-context-width=2', stdin=f'yes {bad_word} yes') + assert_in(f'… {bad_word} …', text) + def _test_text(xpath): assert xpath.endswith('.exp') if '@' in xpath: @@ -57,7 +77,7 @@ language = 'en-US' ipath = xpath[:-4] ipath += '.txt' - text = _get_output(ipath, language) + text = _get_output('--language', language, ipath) with open(xpath, 'rt', encoding='UTF-8') as file: expected = file.read() if expected != text: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mwic-0.7.9/tests/test_trim.py new/mwic-0.7.10/tests/test_trim.py --- old/mwic-0.7.9/tests/test_trim.py 2022-04-25 14:33:14.000000000 +0200 +++ new/mwic-0.7.10/tests/test_trim.py 2023-02-23 16:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright © 2014-2022 Jakub Wilk <jwilk@jwilk.net> +# Copyright © 2014-2023 Jakub Wilk <jwilk@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -18,6 +18,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import re +import sys + +import regex + import lib.text as M from .tools import ( @@ -25,14 +30,29 @@ assert_greater_equal, ) +if sys.version_info >= (3, 7): + isascii = str.isascii # pylint: disable=no-member +else: + def isascii(s): + return re.fullmatch(r'[\0-\x7F]*', s) is not None + +def xlen(s): + n = sum(1 if c else 0 for c in regex.split(r'(\X)', s)) + if isascii(s): + assert n == len(s) + else: + assert n <= len(s) + return n + def test_ltrim(): def t(s, n, expected): result = M.ltrim(s, n) + assert_equal(result, expected) assert_greater_equal( max(1, n), - len(result) + xlen(result) ) - assert_equal(result, expected) + t('', 0, '') truncations = [ '…', '…', @@ -43,11 +63,22 @@ ] for n, s in enumerate(truncations): t(truncations[-1], n, s) + truncations = [ + s.replace('g', 'g\N{COMBINING GRAVE ACCENT}') + for s in truncations + ] + for n, s in enumerate(truncations): + t(truncations[-1], n, s) def test_rtrim(): def t(s, n, expected): result = M.rtrim(s, n) assert_equal(result, expected) + assert_greater_equal( + max(1, n), + xlen(result) + ) + t('', 0, '') truncations = [ '…', '…', @@ -58,5 +89,11 @@ ] for n, s in enumerate(truncations): t(truncations[-1], n, s) + truncations = [ + s.replace('g', 'g\N{COMBINING ACUTE ACCENT}') + for s in truncations + ] + for n, s in enumerate(truncations): + t(truncations[-1], n, s) # vim:ts=4 sts=4 sw=4 et ++++++ mwic.keyring ++++++ --- /var/tmp/diff_new_pack.IlAVLv/_old 2024-01-03 12:23:29.380192296 +0100 +++ /var/tmp/diff_new_pack.IlAVLv/_new 2024-01-03 12:23:29.384192442 +0100 @@ -1,85 +1,14 @@ -pub rsa4096/0x2D4EB3A6015475F5 2009-10-23 [SC] [expires: 2018-01-01] - CDB5A1243ACDB63009AD07212D4EB3A6015475F5 -uid [ unknown] Jakub Wilk <jwilk@jwilk.net> -uid [ unknown] Jakub Wilk <jwilk@debian.org> -uid [ unknown] Jakub Wilk <ubanus@users.sf.net> -sub rsa4096/0x49A526BFE5874F63 2009-10-23 [E] - -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -i0i3KQXs09FW/+n9DTw= -=R8Zy +mDMEYzeDABYJKwYBBAHaRw8BAQdAKDC8FwZXK9zK/RIePpJ+OIpCpZnUjnmfrVBy +7V3kIsi0HEpha3ViIFdpbGsgPGp3aWxrQGp3aWxrLm5ldD6IlAQTFggAPAIbAwUL +CQgHAwMVCAsFFgMCAQACHgECF4AWIQR/XQ6dMyP4A9iIwx7hq8h3aW7HTgUCZRi2 +gAUJBD0CgAAKCRDhq8h3aW7HTlarAQDrifQgY1Pt9pIi/fjzNQeNl4XAJsjNzX71 +GCotzYRE7wD/ex7PtITHm4z9qGcKhkCPavaR0Axoa1tm5MpyPTsDQQ64OARjN4MA +EgorBgEEAZdVAQUBAQdAGTvkypRjUwt2khbbjNlLIzYjKnhA96X7e5sWYsJGK2kD +AQgHiH4EGBYIACYCGwwWIQR/XQ6dMyP4A9iIwx7hq8h3aW7HTgUCZRi2gAUJBD0C +gAAKCRDhq8h3aW7HTvZ1AQDk6yxntgBX3DcrTipBvbmDB3+6BrNyOYpB9wlocokO +1QD9EyiKFDs28KzUa36YwZYA240/2fnGMbbCNn1cOt0tqgg= +=Es8D -----END PGP PUBLIC KEY BLOCK-----
participants (1)
-
Source-Sync