#!/usr/bin/env python3
"""Test pwb.py."""
#
# (C) Pywikibot team, 2007-2023
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
import io
import sys
import unittest
from tests import create_path_func, join_tests_path
from tests.aspects import PwbTestCase
from tests.utils import execute, execute_pwb
join_pwb_tests_path = create_path_func(join_tests_path, 'pwb')
[docs]
class TestPwb(PwbTestCase):
"""Test pwb.py functionality.
This is registered as a Site test because it will not run without a
user config file.
.. note::
``site`` must be explicitly set for pwb tests. This test does not
require network access, because tests/pwb/print_locals.py does
not use handle_args, etc. so version.py doesn't talk on the
network.
"""
site = False
net = False
def _do_check(self, name):
package_name = 'tests.pwb.' + name
script_path = join_pwb_tests_path(name + '.py')
direct = execute([sys.executable, '-m', package_name])
vpwb = execute_pwb([script_path])
self.maxDiff = None
self.assertEqual(direct['stdout'], vpwb['stdout'])
return (direct, vpwb)
[docs]
def test_env(self):
"""
Test external environment of pywikibot.
Make sure the environment is not contaminated, and is the same as
the environment we get when directly running a script.
"""
self._do_check('print_env')
[docs]
def test_locals(self):
"""
Test internal environment of pywikibot.
Make sure the environment is not contaminated, and is the same as
the environment we get when directly running a script.
"""
self._do_check('print_locals')
[docs]
def test_unicode(self):
"""Test printing unicode in pywikibot."""
(direct, vpwb) = self._do_check('print_unicode')
self.assertEqual('Häuser', direct['stdout'].strip())
self.assertEqual('Häuser', direct['stderr'].strip())
self.assertEqual('Häuser', vpwb['stdout'].strip())
self.assertEqual('Häuser', vpwb['stderr'].strip())
[docs]
def test_argv(self):
"""Test argv of pywikibot.
Make sure that argv passed to the script is not contaminated by
global options given to pwb.py wrapper.
"""
script_name = 'print_argv'
script_path = join_pwb_tests_path(script_name + '.py')
script_opts = ['-help']
command = [script_path] + script_opts
without_global_args = execute_pwb(command)
with_no_global_args = execute_pwb(['-maxlag:5'] + command)
self.assertEqual(without_global_args['stdout'],
with_no_global_args['stdout'])
self.assertEqual(without_global_args['stdout'].rstrip(),
str([script_name] + script_opts))
[docs]
def test_script_found(self):
"""Test pwb.py script call which is found."""
stdout = io.StringIO(execute_pwb(['pwb'])['stdout'])
self.assertEqual(stdout.readline().strip(),
'Wrapper script to invoke pywikibot-based scripts.')
[docs]
def test_script_not_found(self):
"""Test pwbot.py script call which is not found."""
stderr = io.StringIO(execute_pwb(['pywikibot'])['stderr'])
self.assertEqual(stderr.readline().strip(),
'ERROR: pywikibot.py not found! Misspelling?')
[docs]
def test_one_similar_script(self):
"""Test shell.py script call which gives one similar result."""
result = [
'ERROR: hello.py not found! Misspelling?',
'NOTE: Starting the most similar script shell.py',
'in 5.0 seconds; type CTRL-C to stop.',
]
stream = execute_pwb(['hello'], data_in=chr(3), timeout=10)
stderr = io.StringIO(stream['stderr'])
with self.subTest(line=0):
self.assertEqual(stderr.readline().strip(), result[0])
with self.subTest(line=1):
text = stderr.readline().strip()
self.assertTrue(
text.startswith(result[1]),
msg=f'"{text}" does not start with "{result[1]}"')
with self.subTest(line=2):
self.assertEqual(stderr.readline().strip(), result[2])
[docs]
def test_similar_scripts_found(self):
"""Test script call which gives multiple similar results."""
result = [
'ERROR: inter_wikidata.py not found! Misspelling?',
'',
'The most similar scripts are:',
'1 - interwikidata',
'2 - interwiki',
'3 - illustrate_wikidata',
]
stderr = io.StringIO(
execute_pwb(['inter_wikidata'], data_in='q')['stderr'])
for line in result:
with self.subTest(line=line):
self.assertEqual(stderr.readline().strip(), line)
remaining = stderr.readlines()
self.assertLength(remaining, 3) # always 3 lines remaining after list
if __name__ == '__main__': # pragma: no cover
unittest.main(verbosity=10)