Feature/test (#130)
* new: test: test for BukuHTMLParser class * new: test: test for BukuCrypt class * chg: test: change getpass patch path * new: test: test for ExtendedArgumentParser class * new: test: test for functions. * chg: test: fix warning for caplog * chg: test: exclude some test for python3.5 only
This commit is contained in:
parent
fc5ee94b86
commit
8fc2775b48
35
tests/test_BukuCrypt.py
Normal file
35
tests/test_BukuCrypt.py
Normal file
@ -0,0 +1,35 @@
|
||||
"""test module."""
|
||||
from unittest import mock
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_get_filehash(tmpdir):
|
||||
"""test method."""
|
||||
exp_res = b'\x9f\x86\xd0\x81\x88L}e\x9a/\xea\xa0\xc5Z\xd0\x15\xa3\xbfO\x1b+\x0b\x82,\xd1]l\x15\xb0\xf0\n\x08' # NOQA
|
||||
test_file = os.path.join(tmpdir.strpath, 'my_test_file.txt')
|
||||
with open(test_file, 'w') as f:
|
||||
f.write('test')
|
||||
from buku import BukuCrypt
|
||||
res = BukuCrypt.get_filehash(test_file)
|
||||
assert res == exp_res
|
||||
|
||||
|
||||
def touch(fname):
|
||||
"""touch implementation for python."""
|
||||
if os.path.exists(fname):
|
||||
os.utime(fname, None)
|
||||
else:
|
||||
open(fname, 'a').close()
|
||||
|
||||
|
||||
def test_encrypt_decrypt(tmpdir):
|
||||
"""test method."""
|
||||
dbfile = os.path.join(tmpdir.strpath, 'test_encrypt_decrypt_dbfile')
|
||||
touch(dbfile)
|
||||
with mock.patch('getpass.getpass', return_value='password'):
|
||||
from buku import BukuCrypt
|
||||
with pytest.raises(SystemExit):
|
||||
BukuCrypt.encrypt_file(1, dbfile=dbfile)
|
||||
BukuCrypt.decrypt_file(1, dbfile=dbfile)
|
66
tests/test_BukuHTMLParser.py
Normal file
66
tests/test_BukuHTMLParser.py
Normal file
@ -0,0 +1,66 @@
|
||||
"""test module."""
|
||||
from itertools import product
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_init():
|
||||
"""test method."""
|
||||
from buku import BukuHTMLParser
|
||||
obj = BukuHTMLParser()
|
||||
assert not obj.in_title_tag
|
||||
assert not obj.data
|
||||
assert obj.prev_tag is None
|
||||
assert obj.parsed_title is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('tag', ['', 'title'])
|
||||
def test_handle_starttag(tag):
|
||||
"""test method."""
|
||||
attrs = mock.Mock()
|
||||
from buku import BukuHTMLParser
|
||||
obj = BukuHTMLParser()
|
||||
obj.handle_starttag(tag, attrs)
|
||||
if tag == 'title':
|
||||
assert obj.in_title_tag
|
||||
assert obj.prev_tag == tag
|
||||
else:
|
||||
assert not obj.in_title_tag
|
||||
|
||||
|
||||
@pytest.mark.parametrize('tag, data', product(['', 'title'], [None, 'data']))
|
||||
def test_handle_endtag(tag, data):
|
||||
"""test method."""
|
||||
from buku import BukuHTMLParser
|
||||
obj = BukuHTMLParser()
|
||||
obj.data = data
|
||||
obj.reset = mock.Mock()
|
||||
obj.handle_endtag(tag)
|
||||
# test
|
||||
if tag == 'title':
|
||||
assert not obj.in_title_tag
|
||||
if tag == 'title' and data != '':
|
||||
assert obj.parsed_title == data
|
||||
obj.reset.assert_called_once_with()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('prev_tag, in_title_tag', product(['', 'title'], [None, 'data']))
|
||||
def test_handle_data(prev_tag, in_title_tag):
|
||||
"""test method."""
|
||||
new_data = 'new_data'
|
||||
from buku import BukuHTMLParser
|
||||
obj = BukuHTMLParser()
|
||||
obj.prev_tag = prev_tag
|
||||
obj.data = ''
|
||||
obj.in_title_tag = in_title_tag
|
||||
obj.handle_data(new_data)
|
||||
if obj.prev_tag == 'title' and in_title_tag:
|
||||
assert obj.data == new_data
|
||||
|
||||
|
||||
def test_error():
|
||||
"""test method."""
|
||||
from buku import BukuHTMLParser
|
||||
obj = BukuHTMLParser()
|
||||
obj.error(message=mock.Mock())
|
64
tests/test_ExtendedArgumentParser.py
Normal file
64
tests/test_ExtendedArgumentParser.py
Normal file
@ -0,0 +1,64 @@
|
||||
"""test module."""
|
||||
from itertools import product
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform, file", product(['win32', 'linux'], [None, mock.Mock()]))
|
||||
def test_program_info(platform, file):
|
||||
"""test method."""
|
||||
with mock.patch('buku.sys') as m_sys:
|
||||
import buku
|
||||
prog_info_text = '''
|
||||
SYMBOLS:
|
||||
> title
|
||||
+ comment
|
||||
# tags
|
||||
|
||||
Version {}
|
||||
Copyright © 2015-2017 {}
|
||||
License: {}
|
||||
Webpage: https://github.com/jarun/Buku
|
||||
'''.format(buku.__version__, buku.__author__, buku.__license__)
|
||||
file = mock.Mock()
|
||||
if file is None:
|
||||
buku.ExtendedArgumentParser.program_info()
|
||||
else:
|
||||
buku.ExtendedArgumentParser.program_info(file)
|
||||
if platform == 'win32' and file == m_sys.stdout:
|
||||
m_sys.stderr.write.assert_called_once_with(prog_info_text)
|
||||
else:
|
||||
file.write.assert_called_once_with(prog_info_text)
|
||||
|
||||
|
||||
def test_prompt_help():
|
||||
"""test method."""
|
||||
file = mock.Mock()
|
||||
import buku
|
||||
buku.ExtendedArgumentParser.prompt_help(file)
|
||||
file.write.assert_called_once_with('''
|
||||
keys:
|
||||
1-N browse search result indices and/or ranges
|
||||
a open all results in browser
|
||||
s keyword [...] search for records with ANY keyword
|
||||
S keyword [...] search for records with ALL keywords
|
||||
d match substrings ('pen' matches 'opened')
|
||||
r expression run a regex search
|
||||
t [...] search bookmarks by a tag or show tag list
|
||||
w [editor|index] edit and add or update a bookmark
|
||||
(tag list index fetches bookmarks by tag)
|
||||
? show this help
|
||||
q, ^D, double Enter exit buku
|
||||
|
||||
''')
|
||||
|
||||
|
||||
def test_print_help():
|
||||
"""test method."""
|
||||
file = mock.Mock()
|
||||
import buku
|
||||
obj = buku.ExtendedArgumentParser()
|
||||
obj.program_info = mock.Mock()
|
||||
obj.print_help(file)
|
||||
obj.program_info.assert_called_once_with(file)
|
424
tests/test_buku.py
Normal file
424
tests/test_buku.py
Normal file
@ -0,0 +1,424 @@
|
||||
"""test module."""
|
||||
from itertools import product
|
||||
from unittest import mock
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
only_python_3_5 = pytest.mark.skipif(sys.version_info < (3, 5), reason="requires python3.5")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url, exp_res',
|
||||
[
|
||||
('http://example.com', False),
|
||||
]
|
||||
)
|
||||
def test_is_bad_url(url, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
assert exp_res == buku.is_bad_url(url)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url, exp_res',
|
||||
[
|
||||
('http://example.com/file.pdf', True),
|
||||
('http://example.com/file.txt', True),
|
||||
('http://example.com/file.jpg', False),
|
||||
]
|
||||
)
|
||||
def test_is_ignored_mime(url, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
assert exp_res == buku.is_ignored_mime(url)
|
||||
|
||||
|
||||
def test_get_page_title():
|
||||
"""test func."""
|
||||
resp = mock.Mock()
|
||||
parser = mock.Mock()
|
||||
with mock.patch('buku.BukuHTMLParser', return_value=parser):
|
||||
import buku
|
||||
res = buku.get_page_title(resp)
|
||||
assert res == parser.parsed_title
|
||||
|
||||
|
||||
def test_gen_headers():
|
||||
"""test func."""
|
||||
import buku
|
||||
exp_myheaders = {
|
||||
'Accept-Encoding': 'gzip,deflate',
|
||||
'User-Agent': buku.USER_AGENT,
|
||||
'Accept': '*/*',
|
||||
'Cookie': '',
|
||||
'DNT': '1'
|
||||
}
|
||||
buku.gen_headers()
|
||||
assert buku.myproxy is None
|
||||
assert buku.myheaders == exp_myheaders
|
||||
|
||||
|
||||
@pytest.mark.parametrize('m_myproxy', [None, mock.Mock()])
|
||||
def test_get_PoolManager(m_myproxy):
|
||||
"""test func."""
|
||||
with mock.patch('buku.urllib3') as m_ul3:
|
||||
import buku
|
||||
buku.myproxy = m_myproxy
|
||||
res = buku.get_PoolManager()
|
||||
if m_myproxy:
|
||||
m_ul3.ProxyManager.assert_called_once_with(
|
||||
m_myproxy, num_pools=1, headers=buku.myheaders)
|
||||
assert res == m_ul3.ProxyManager.return_value
|
||||
else:
|
||||
m_ul3.PoolManager.assert_called_once_with(
|
||||
num_pools=1, headers=buku.myheaders)
|
||||
assert res == m_ul3.PoolManager.return_value
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'keywords, exp_res',
|
||||
[
|
||||
(None, None),
|
||||
([], None),
|
||||
(['tag1', 'tag2'], ',tag1 tag2,'),
|
||||
(['tag1,tag2', 'tag3'], ',tag1,tag2 tag3,'),
|
||||
]
|
||||
)
|
||||
def test_parse_tags(keywords, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
if keywords is None:
|
||||
pass
|
||||
elif not keywords:
|
||||
exp_res = buku.DELIM
|
||||
res = buku.parse_tags(keywords)
|
||||
assert res == exp_res
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'nav, is_editor_valid_retval, edit_rec_retval',
|
||||
product(
|
||||
['w', [None, None, 1], [None, None, 'string']],
|
||||
[True, False],
|
||||
[[mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock()], None]
|
||||
)
|
||||
)
|
||||
def test_edit_at_prompt(nav, is_editor_valid_retval, edit_rec_retval):
|
||||
"""test func."""
|
||||
obj = mock.Mock()
|
||||
editor = mock.Mock()
|
||||
with mock.patch('buku.get_system_editor', return_value=editor), \
|
||||
mock.patch('buku.is_editor_valid', return_value=is_editor_valid_retval), \
|
||||
mock.patch('buku.edit_rec', return_value=edit_rec_retval) as m_edit_rec:
|
||||
import buku
|
||||
buku.edit_at_prompt(obj, nav)
|
||||
# test
|
||||
if nav == 'w' and not is_editor_valid_retval:
|
||||
return
|
||||
elif nav == 'w':
|
||||
m_edit_rec.assert_called_once_with(editor, '', None, buku.DELIM, None)
|
||||
elif buku.is_int(nav[2:]):
|
||||
obj.edit_update_rec.assert_called_once_with(int(nav[2:]))
|
||||
return
|
||||
else:
|
||||
editor = nav[2:]
|
||||
m_edit_rec.assert_called_once_with(editor, '', None, buku.DELIM, None)
|
||||
if edit_rec_retval is not None:
|
||||
obj.add_rec(*edit_rec_retval)
|
||||
|
||||
|
||||
@only_python_3_5
|
||||
@pytest.mark.parametrize(
|
||||
'idx, row0, row1, row2, row3, row4, row5',
|
||||
product(
|
||||
[0, 1],
|
||||
[0],
|
||||
['', 'row1'],
|
||||
['', 'row2'],
|
||||
[',', 'row3'],
|
||||
['', 'row4'],
|
||||
[0, 1],
|
||||
)
|
||||
)
|
||||
def test_print_record(idx, row0, row1, row2, row3, row4, row5):
|
||||
"""test func."""
|
||||
row = [row0, row1, row2, row3, row4, row5]
|
||||
pr = None
|
||||
with mock.patch('buku.print') as m_print:
|
||||
import buku
|
||||
buku.print_record(row, idx)
|
||||
|
||||
if idx != 0:
|
||||
pr = buku.ID_str % (idx, row1, row0)
|
||||
else:
|
||||
pr = buku.ID_DB_str % (row0, row1)
|
||||
if row5 & 1:
|
||||
pr = buku.MUTE_str % (pr)
|
||||
else:
|
||||
pr += '\n'
|
||||
|
||||
if row2 != '':
|
||||
pr = buku.TITLE_str % (pr, row2)
|
||||
if row4 != '':
|
||||
pr = buku.DESC_str % (pr, row4)
|
||||
if row3 != buku.DELIM:
|
||||
pr = buku.TAG_str % (pr, row3[1:-1])
|
||||
|
||||
m_print.assert_called_once_with(pr)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'field_filter, single_record',
|
||||
product(range(4), [True, False])
|
||||
)
|
||||
def test_format_json(field_filter, single_record):
|
||||
"""test func."""
|
||||
resultset = [['row{}'.format(x) for x in range(5)]]
|
||||
if field_filter == 1:
|
||||
marks = {'uri': 'row1'}
|
||||
elif field_filter == 2:
|
||||
marks = {'uri': 'row1', 'tags': 'row3'[1:-1]}
|
||||
elif field_filter == 3:
|
||||
marks = {'title': 'row2'}
|
||||
else:
|
||||
marks = {
|
||||
'index': 'row0',
|
||||
'uri': 'row1',
|
||||
'title': 'row2',
|
||||
'description': 'row4',
|
||||
'tags': 'row3'[1:-1]
|
||||
}
|
||||
if not single_record:
|
||||
marks = [marks]
|
||||
|
||||
with mock.patch('buku.json') as m_json:
|
||||
import buku
|
||||
res = buku.format_json(resultset, single_record, field_filter)
|
||||
m_json.dumps.assert_called_once_with(marks, sort_keys=True, indent=4)
|
||||
assert res == m_json.dumps.return_value
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'string, exp_res',
|
||||
[
|
||||
('string', False),
|
||||
('12', True),
|
||||
('12.1', False),
|
||||
]
|
||||
)
|
||||
def test_is_int(string, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
assert exp_res == buku.is_int(string)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url, opened_url',
|
||||
[
|
||||
['http://example.com', 'http://example.com', ],
|
||||
['example.com', 'http://example.com', ],
|
||||
]
|
||||
)
|
||||
def test_browse(url, opened_url):
|
||||
"""test func."""
|
||||
with mock.patch('buku.webbrowser') as m_webbrowser:
|
||||
import buku
|
||||
buku.browse(url)
|
||||
m_webbrowser.open.assert_called_once_with(opened_url)
|
||||
|
||||
|
||||
@only_python_3_5
|
||||
@pytest.mark.parametrize(
|
||||
'status_code, latest_release',
|
||||
product([200, 404], [True, False])
|
||||
)
|
||||
def test_check_upstream_release(status_code, latest_release):
|
||||
"""test func."""
|
||||
resp = mock.Mock()
|
||||
resp.status_code = status_code
|
||||
with mock.patch('buku.requests') as m_requests, \
|
||||
mock.patch('buku.print') as m_print:
|
||||
import buku
|
||||
if latest_release:
|
||||
latest_version = 'v{}'.format(buku.__version__)
|
||||
else:
|
||||
latest_version = 'v0'
|
||||
resp.json.return_value = [{'tag_name': latest_version}]
|
||||
m_requests.get.return_value = resp
|
||||
buku.check_upstream_release()
|
||||
if status_code != 200:
|
||||
return
|
||||
if latest_release:
|
||||
print_text = 'This is the latest release'
|
||||
else:
|
||||
print_text = 'Latest upstream release is %s' % latest_version
|
||||
m_print.assert_called_once_with(print_text)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'exp, item, exp_res',
|
||||
[
|
||||
('cat.y', 'catty', True),
|
||||
('cat.y', 'caty', False),
|
||||
]
|
||||
)
|
||||
def test_regexp(exp, item, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
res = buku.regexp(exp, item)
|
||||
assert res == exp_res
|
||||
|
||||
|
||||
@pytest.mark.parametrize('token, exp_res', [('text', ',text,')])
|
||||
def test_delim_wrap(token, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
res = buku.delim_wrap(token)
|
||||
assert res == exp_res
|
||||
|
||||
|
||||
@only_python_3_5
|
||||
def test_read_in():
|
||||
"""test func."""
|
||||
message = mock.Mock()
|
||||
with mock.patch('buku.disable_sigint_handler'), \
|
||||
mock.patch('buku.enable_sigint_handler'), \
|
||||
mock.patch('buku.input', return_value=message):
|
||||
import buku
|
||||
res = buku.read_in(msg=mock.Mock())
|
||||
assert res == message
|
||||
|
||||
|
||||
def test_sigint_handler():
|
||||
"""test func."""
|
||||
with mock.patch('buku.os') as m_os:
|
||||
import buku
|
||||
buku.sigint_handler(mock.Mock(), mock.Mock())
|
||||
m_os._exit.assert_called_once_with(1)
|
||||
|
||||
|
||||
def test_get_system_editor():
|
||||
"""test func."""
|
||||
with mock.patch('buku.os') as m_os:
|
||||
import buku
|
||||
res = buku.get_system_editor()
|
||||
assert res == m_os.environ.get.return_value
|
||||
m_os.environ.get.assert_called_once_with('EDITOR', 'none')
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'editor, exp_res',
|
||||
[
|
||||
('none', False),
|
||||
('0', False),
|
||||
('random_editor', True),
|
||||
]
|
||||
)
|
||||
def test_is_editor_valid(editor, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
assert buku.is_editor_valid(editor) == exp_res
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url, title_in, tags_in, desc',
|
||||
product(
|
||||
[None, 'example.com'],
|
||||
[None, '', 'title'],
|
||||
['', 'tag1,tag2', ',tag1,tag2,'],
|
||||
[None, '', 'description'],
|
||||
)
|
||||
)
|
||||
def test_to_temp_file_content(url, title_in, tags_in, desc):
|
||||
"""test func."""
|
||||
import buku
|
||||
res = buku.to_temp_file_content(url, title_in, tags_in, desc)
|
||||
lines = [
|
||||
'# Lines beginning with "#" will be stripped.',
|
||||
'# Add URL in next line (single line).',
|
||||
'# Add TITLE in next line (single line). Leave blank to web fetch, "-" for no title.',
|
||||
'# Add comma-separated TAGS in next line (single line).',
|
||||
'# Add COMMENTS in next line(s).',
|
||||
]
|
||||
idx_offset = 0
|
||||
# url
|
||||
if url is not None:
|
||||
lines.insert(2, url)
|
||||
idx_offset += 1
|
||||
if title_in is None:
|
||||
title_in = ''
|
||||
elif title_in == '':
|
||||
title_in = '-'
|
||||
else:
|
||||
pass
|
||||
|
||||
# title
|
||||
lines.insert(idx_offset + 3, title_in)
|
||||
idx_offset += 1
|
||||
|
||||
# tags
|
||||
lines.insert(idx_offset + 4, tags_in.strip(buku.DELIM))
|
||||
idx_offset += 1
|
||||
|
||||
# description
|
||||
if desc is not None and desc != '':
|
||||
pass
|
||||
else:
|
||||
desc = ''
|
||||
lines.insert(idx_offset + 5, desc)
|
||||
|
||||
for idx, res_line in enumerate(res.splitlines()):
|
||||
assert lines[idx] == res_line
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'content, exp_res',
|
||||
[
|
||||
('', None),
|
||||
('#line1\n#line2', None),
|
||||
(
|
||||
'\n'.join([
|
||||
'example.com',
|
||||
'title',
|
||||
'tags',
|
||||
'desc',
|
||||
]),
|
||||
('example.com', 'title', ',tags,', 'desc')
|
||||
)
|
||||
]
|
||||
)
|
||||
def test_parse_temp_file_content(content, exp_res):
|
||||
"""test func."""
|
||||
import buku
|
||||
res = buku.parse_temp_file_content(content)
|
||||
assert res == exp_res
|
||||
|
||||
|
||||
@only_python_3_5
|
||||
@pytest.mark.skip(reason="can't patch subprocess")
|
||||
def test_edit_rec():
|
||||
"""test func."""
|
||||
editor = 'nanoe'
|
||||
args = ('url', 'title_in', 'tags_in', 'desc')
|
||||
with mock.patch('buku.to_temp_file_content'), \
|
||||
mock.patch('buku.os'), \
|
||||
mock.patch('buku.open'), \
|
||||
mock.patch('buku.parse_temp_file_content') as m_ptfc:
|
||||
import buku
|
||||
res = buku.edit_rec(editor, *args)
|
||||
assert res == m_ptfc.return_value
|
||||
|
||||
|
||||
@pytest.mark.parametrize('argv, pipeargs, isatty', product(['argv'], [None, []], [True, False]))
|
||||
def test_piped_input(argv, pipeargs, isatty):
|
||||
"""test func."""
|
||||
with mock.patch('buku.sys') as m_sys:
|
||||
m_sys.stdin.isatty.return_value = isatty
|
||||
m_sys.stdin.readlines.return_value = 'arg1\narg2'
|
||||
import buku
|
||||
if pipeargs is None and not isatty:
|
||||
with pytest.raises(TypeError):
|
||||
buku.piped_input(argv, pipeargs)
|
||||
return
|
||||
buku.piped_input(argv, pipeargs)
|
@ -424,7 +424,7 @@ def test_print_rec(capsys, caplog, setup):
|
||||
bdb.print_rec(1)
|
||||
out, err = capsys.readouterr()
|
||||
|
||||
for record in caplog.records():
|
||||
for record in caplog.records:
|
||||
assert record.levelname == "ERROR"
|
||||
assert record.getMessage() == "No matching index 1"
|
||||
assert (out, err) == ('', '')
|
||||
|
Loading…
Reference in New Issue
Block a user