2017-03-18 08:41:59 -05:00
|
|
|
|
"""test module."""
|
|
|
|
|
from itertools import product
|
|
|
|
|
from unittest import mock
|
2018-08-01 04:38:43 -05:00
|
|
|
|
from urllib.parse import urlparse
|
2017-12-12 21:16:17 -06:00
|
|
|
|
import json
|
2017-03-18 09:09:09 -05:00
|
|
|
|
import os
|
|
|
|
|
import signal
|
2017-03-18 08:41:59 -05:00
|
|
|
|
import sys
|
2017-03-18 09:09:09 -05:00
|
|
|
|
import unittest
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
2017-08-14 16:07:01 -05:00
|
|
|
|
from buku import is_int, parse_tags, prep_tag_search
|
2017-03-18 09:09:09 -05:00
|
|
|
|
|
2017-07-12 11:53:38 -05:00
|
|
|
|
only_python_3_5 = pytest.mark.skipif(
|
|
|
|
|
sys.version_info < (3, 5), reason="requires Python 3.5 or later")
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'url, exp_res',
|
|
|
|
|
[
|
2017-03-30 11:52:47 -05:00
|
|
|
|
['http://example.com', False],
|
|
|
|
|
['ftp://ftp.somedomain.org', False],
|
|
|
|
|
['http://examplecom.', True],
|
|
|
|
|
['http://.example.com', True],
|
|
|
|
|
['http://example.com.', True],
|
2017-10-14 06:13:53 -05:00
|
|
|
|
['about:newtab', True],
|
|
|
|
|
['chrome://version/', True],
|
2017-03-18 08:41:59 -05:00
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_is_bad_url(url, exp_res):
|
|
|
|
|
"""test func."""
|
|
|
|
|
import buku
|
2017-03-30 11:52:47 -05:00
|
|
|
|
res = buku.is_bad_url(url)
|
|
|
|
|
assert res == exp_res
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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_gen_headers():
|
|
|
|
|
"""test func."""
|
|
|
|
|
import buku
|
|
|
|
|
exp_myheaders = {
|
|
|
|
|
'Accept-Encoding': 'gzip,deflate',
|
|
|
|
|
'User-Agent': buku.USER_AGENT,
|
|
|
|
|
'Accept': '*/*',
|
|
|
|
|
'Cookie': '',
|
|
|
|
|
'DNT': '1'
|
|
|
|
|
}
|
|
|
|
|
buku.gen_headers()
|
2018-12-30 20:49:38 -06:00
|
|
|
|
assert buku.MYPROXY is None
|
|
|
|
|
assert buku.MYHEADERS == exp_myheaders
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('m_myproxy', [None, mock.Mock()])
|
|
|
|
|
def test_get_PoolManager(m_myproxy):
|
|
|
|
|
"""test func."""
|
2018-08-06 02:51:36 -05:00
|
|
|
|
with mock.patch('buku.urllib3'):
|
2017-03-18 08:41:59 -05:00
|
|
|
|
import buku
|
|
|
|
|
buku.myproxy = m_myproxy
|
2018-08-06 02:51:36 -05:00
|
|
|
|
assert buku.get_PoolManager()
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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
|
|
|
|
|
|
|
|
|
|
|
2017-09-23 12:01:37 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'records, field_filter, exp_res',
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
1,
|
|
|
|
|
['1\thttp://url1.com', '2\thttp://url2.com']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
2,
|
|
|
|
|
['1\thttp://url1.com\ttag1', '2\thttp://url2.com\ttag1,tag2']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
3,
|
|
|
|
|
['1\ttitle1', '2\ttitle2']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
4,
|
|
|
|
|
['1\thttp://url1.com\ttitle1\ttag1', '2\thttp://url2.com\ttitle2\ttag1,tag2']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
10,
|
|
|
|
|
['http://url1.com', 'http://url2.com']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
20,
|
|
|
|
|
['http://url1.com\ttag1', 'http://url2.com\ttag1,tag2']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
30,
|
|
|
|
|
['title1', 'title2']
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[(1, 'http://url1.com', 'title1', ',tag1,'),
|
|
|
|
|
(2, 'http://url2.com', 'title2', ',tag1,tag2,')],
|
|
|
|
|
40,
|
|
|
|
|
['http://url1.com\ttitle1\ttag1', 'http://url2.com\ttitle2\ttag1,tag2']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_print_rec_with_filter(records, field_filter, exp_res):
|
|
|
|
|
"""test func."""
|
|
|
|
|
with mock.patch('buku.print', create=True) as m_print:
|
|
|
|
|
import buku
|
|
|
|
|
buku.print_rec_with_filter(records, field_filter)
|
|
|
|
|
for res in exp_res:
|
|
|
|
|
m_print.assert_any_call(res)
|
|
|
|
|
|
|
|
|
|
|
2017-08-14 16:07:01 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'taglist, exp_res',
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'tag1, tag2+3',
|
|
|
|
|
([',tag1,', ',tag2+3,'], 'OR', None)
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag1 + tag2-3 + tag4',
|
|
|
|
|
([',tag1,', ',tag2-3,', ',tag4,'], 'AND', None)
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag1, tag2-3 - tag4, tag5',
|
|
|
|
|
([',tag1,', ',tag2-3,'], 'OR', ',tag4,|,tag5,')
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_prep_tag_search(taglist, exp_res):
|
|
|
|
|
"""test prep_tag_search helper function"""
|
|
|
|
|
|
|
|
|
|
results = prep_tag_search(taglist)
|
|
|
|
|
assert results == exp_res
|
|
|
|
|
|
|
|
|
|
|
2017-03-18 08:41:59 -05:00
|
|
|
|
@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
|
2018-12-30 20:49:38 -06:00
|
|
|
|
if nav == 'w':
|
2017-03-18 08:41:59 -05:00
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'field_filter, single_record',
|
2017-05-18 20:40:43 -05:00
|
|
|
|
product(list(range(4)), [True, False])
|
2017-03-18 08:41:59 -05:00
|
|
|
|
)
|
|
|
|
|
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(
|
2017-04-12 10:36:11 -05:00
|
|
|
|
'url, opened_url, platform',
|
2017-03-18 08:41:59 -05:00
|
|
|
|
[
|
2017-04-12 10:36:11 -05:00
|
|
|
|
['http://example.com', 'http://example.com', 'linux'],
|
|
|
|
|
['example.com', 'http://example.com', 'linux'],
|
|
|
|
|
['http://example.com', 'http://example.com', 'win32'],
|
2017-03-18 08:41:59 -05:00
|
|
|
|
]
|
|
|
|
|
)
|
2017-04-12 10:36:11 -05:00
|
|
|
|
def test_browse(url, opened_url, platform):
|
2017-03-18 08:41:59 -05:00
|
|
|
|
"""test func."""
|
2017-04-12 10:36:11 -05:00
|
|
|
|
with mock.patch('buku.webbrowser') as m_webbrowser, \
|
2018-02-21 01:09:30 -06:00
|
|
|
|
mock.patch('buku.sys') as m_sys, \
|
|
|
|
|
mock.patch('buku.os'):
|
2017-04-12 10:36:11 -05:00
|
|
|
|
m_sys.platform = platform
|
2018-02-21 01:09:30 -06:00
|
|
|
|
get_func_retval = mock.Mock()
|
|
|
|
|
m_webbrowser.get.return_value = get_func_retval
|
2017-03-18 08:41:59 -05:00
|
|
|
|
import buku
|
2017-09-08 14:51:35 -05:00
|
|
|
|
buku.browse.suppress_browser_output = True
|
2018-02-18 11:44:00 -06:00
|
|
|
|
buku.browse.override_text_browser = False
|
2017-03-18 08:41:59 -05:00
|
|
|
|
buku.browse(url)
|
2018-02-21 01:09:30 -06:00
|
|
|
|
if platform == 'win32':
|
|
|
|
|
m_webbrowser.open.assert_called_once_with(opened_url, new=2)
|
|
|
|
|
else:
|
|
|
|
|
get_func_retval.open.assert_called_once_with(opened_url, new=2)
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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()
|
2017-12-12 21:16:17 -06:00
|
|
|
|
resp.status = status_code
|
|
|
|
|
m_manager = mock.Mock()
|
|
|
|
|
m_manager.request.return_value = resp
|
|
|
|
|
with mock.patch('buku.urllib3') as m_urllib3, \
|
2017-03-18 08:41:59 -05:00
|
|
|
|
mock.patch('buku.print') as m_print:
|
|
|
|
|
import buku
|
|
|
|
|
if latest_release:
|
|
|
|
|
latest_version = 'v{}'.format(buku.__version__)
|
|
|
|
|
else:
|
|
|
|
|
latest_version = 'v0'
|
2017-12-12 21:16:17 -06:00
|
|
|
|
m_urllib3.PoolManager.return_value = m_manager
|
|
|
|
|
resp.data.decode.return_value = json.dumps([{'tag_name': latest_version}])
|
2017-03-18 08:41:59 -05:00
|
|
|
|
buku.check_upstream_release()
|
|
|
|
|
if status_code != 200:
|
|
|
|
|
return
|
2017-12-12 21:16:17 -06:00
|
|
|
|
len(m_print.mock_calls) == 1
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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
|
|
|
|
|
|
|
|
|
|
|
2017-03-18 09:09:09 -05:00
|
|
|
|
def test_sigint_handler_with_mock():
|
2017-03-18 08:41:59 -05:00
|
|
|
|
"""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'],
|
2018-08-06 01:19:21 -05:00
|
|
|
|
[None, '', '-', 'tag1,tag2', ',tag1,tag2,', ',,,,,'],
|
|
|
|
|
[None, '', '-', 'description'],
|
2017-03-18 08:41:59 -05:00
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
def test_to_temp_file_content(url, title_in, tags_in, desc):
|
|
|
|
|
"""test func."""
|
|
|
|
|
import buku
|
2018-08-06 00:58:44 -05:00
|
|
|
|
if desc is None:
|
|
|
|
|
desc_text = '\n'
|
|
|
|
|
elif desc == '':
|
|
|
|
|
desc_text = '-'
|
|
|
|
|
else:
|
|
|
|
|
desc_text = desc
|
2017-03-18 08:41:59 -05:00
|
|
|
|
if title_in is None:
|
2018-08-06 01:19:21 -05:00
|
|
|
|
title_text = ''
|
2017-03-18 08:41:59 -05:00
|
|
|
|
elif title_in == '':
|
2018-08-06 01:19:21 -05:00
|
|
|
|
title_text = '-'
|
|
|
|
|
else:
|
|
|
|
|
title_text = title_in
|
|
|
|
|
if tags_in is None:
|
|
|
|
|
with pytest.raises(AttributeError):
|
|
|
|
|
res = buku.to_temp_file_content(url, title_in, tags_in, desc)
|
|
|
|
|
return
|
2018-08-06 00:58:44 -05:00
|
|
|
|
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). Leave blank to web fetch, "-" for no comments.{}""".format(
|
|
|
|
|
''.join(['\n', url]) if url is not None else '',
|
2018-08-06 01:19:21 -05:00
|
|
|
|
''.join(['\n', title_text]),
|
2018-08-06 00:58:44 -05:00
|
|
|
|
''.join(['\n', ','.join([x for x in tags_in.split(',') if x])]) if tags_in else '\n',
|
|
|
|
|
''.join(['\n', desc_text])
|
|
|
|
|
)
|
|
|
|
|
assert res == lines
|
2017-03-18 08:41:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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)
|
2017-03-18 09:09:09 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestHelpers(unittest.TestCase):
|
|
|
|
|
|
|
|
|
|
# @unittest.skip('skipping')
|
|
|
|
|
def test_parse_tags(self):
|
|
|
|
|
# call with None
|
|
|
|
|
parsed = parse_tags(None)
|
|
|
|
|
self.assertIsNone(parsed)
|
|
|
|
|
# call with empty list
|
|
|
|
|
parsed = parse_tags([])
|
|
|
|
|
self.assertEqual(parsed, ",")
|
|
|
|
|
# empty tags
|
|
|
|
|
parsed = parse_tags([",,,,,"])
|
|
|
|
|
self.assertEqual(parsed, ",")
|
|
|
|
|
# sorting tags
|
|
|
|
|
parsed = parse_tags(["z_tag,a_tag,n_tag"])
|
|
|
|
|
self.assertEqual(parsed, ",a_tag,n_tag,z_tag,")
|
|
|
|
|
# whitespaces
|
|
|
|
|
parsed = parse_tags([" a tag , , , ,\t,\n,\r,\x0b,\x0c"])
|
|
|
|
|
self.assertEqual(parsed, ",a tag,")
|
|
|
|
|
# duplicates, excessive spaces
|
|
|
|
|
parsed = parse_tags(["tag,tag, tag, tag,tag , tag "])
|
|
|
|
|
self.assertEqual(parsed, ",tag,")
|
|
|
|
|
# escaping quotes
|
|
|
|
|
parsed = parse_tags(["\"tag\",\'tag\',tag"])
|
|
|
|
|
self.assertEqual(parsed, ",\"tag\",\'tag\',tag,")
|
|
|
|
|
# combo
|
|
|
|
|
parsed = parse_tags([",,z_tag, a tag ,\t,,, ,n_tag ,n_tag, a_tag, \na tag ,\r, \"a_tag\""])
|
|
|
|
|
self.assertEqual(parsed, ",\"a_tag\",a tag,a_tag,n_tag,z_tag,")
|
|
|
|
|
|
|
|
|
|
# @unittest.skip('skipping')
|
|
|
|
|
def test_is_int(self):
|
|
|
|
|
self.assertTrue(is_int('0'))
|
|
|
|
|
self.assertTrue(is_int('1'))
|
|
|
|
|
self.assertTrue(is_int('-1'))
|
|
|
|
|
self.assertFalse(is_int(''))
|
|
|
|
|
self.assertFalse(is_int('one'))
|
|
|
|
|
|
|
|
|
|
# This test fails because we use os._exit() now
|
|
|
|
|
@unittest.skip('skipping')
|
|
|
|
|
def test_sigint_handler(capsys):
|
|
|
|
|
try:
|
|
|
|
|
# sending SIGINT to self
|
|
|
|
|
os.kill(os.getpid(), signal.SIGINT)
|
|
|
|
|
except SystemExit as error:
|
|
|
|
|
out, err = capsys.readouterr()
|
|
|
|
|
# assert exited with 1
|
|
|
|
|
assert error.args[0] == 1
|
|
|
|
|
# assert proper error message
|
|
|
|
|
assert out == ''
|
|
|
|
|
assert err == "\nInterrupted.\n"
|
2017-03-30 11:52:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'url, exp_res',
|
|
|
|
|
[
|
2018-08-06 02:42:46 -05:00
|
|
|
|
['http://example.com.', (None, None, None, 0, 1)],
|
|
|
|
|
['http://example.com', ('Example Domain', None, None, 0, 0)],
|
|
|
|
|
['http://example.com/page1.txt', (('', '', '', 1, 0))],
|
|
|
|
|
['about:new_page', ((None, None, None, 0, 1))],
|
|
|
|
|
['chrome://version/', ((None, None, None, 0, 1))],
|
|
|
|
|
['chrome://version/', ((None, None, None, 0, 1))],
|
2019-04-03 10:30:04 -05:00
|
|
|
|
# [
|
|
|
|
|
# 'http://4pda.ru/forum/index.php?showtopic=182463&st=1640#entry6044923',
|
|
|
|
|
# (
|
|
|
|
|
# 'Samsung GT-I5800 Galaxy 580 - Обсуждение - 4PDA',
|
|
|
|
|
# 'Samsung GT-I5800 Galaxy 580 - Обсуждение - 4PDA',
|
|
|
|
|
# None,
|
|
|
|
|
# 0, 0
|
|
|
|
|
# )
|
|
|
|
|
# ],
|
2018-08-01 04:30:46 -05:00
|
|
|
|
[
|
|
|
|
|
'https://www.google.ru/search?'
|
|
|
|
|
'newwindow=1&safe=off&q=xkbcomp+alt+gr&'
|
|
|
|
|
'oq=xkbcomp+alt+gr&'
|
|
|
|
|
'gs_l=serp.3..33i21.28976559.28977886.0.'
|
|
|
|
|
'28978017.6.6.0.0.0.0.167.668.0j5.5.0....0...1c.1.64.'
|
2018-08-01 04:38:43 -05:00
|
|
|
|
'serp..1.2.311.06cSKPTLo18',
|
2018-08-06 02:42:46 -05:00
|
|
|
|
('xkbcomp alt gr', None, None, 0, 0)
|
2018-08-01 04:30:46 -05:00
|
|
|
|
],
|
2018-08-01 05:36:06 -05:00
|
|
|
|
[
|
|
|
|
|
'http://www.vim.org/scripts/script.php?script_id=4641',
|
|
|
|
|
(
|
|
|
|
|
'mlessnau_case - "in-case" selection, deletion and substitution '
|
2018-08-06 02:42:46 -05:00
|
|
|
|
'for underscore, camel, mixed case : vim online',
|
|
|
|
|
None, None, 0, 0
|
2018-08-01 05:36:06 -05:00
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'http://www.kadrof.ru/cat_exchange.shtml',
|
2018-08-06 02:42:46 -05:00
|
|
|
|
(
|
2018-12-26 07:39:30 -06:00
|
|
|
|
'Все биржи фриланса и удаленной работы - больше 110 сайтов для фрилансеров | Kadrof.ru',
|
2018-08-06 02:42:46 -05:00
|
|
|
|
'Здесь собраны самые популярные биржи удаленной работы и фриланса для новичков и опытных специалистов. '
|
|
|
|
|
'Более 110 ресурсов по видам:',
|
2018-12-26 07:39:30 -06:00
|
|
|
|
'биржи удаленной работы,биржи фриланс', 0, 0
|
2018-08-06 02:42:46 -05:00
|
|
|
|
)
|
2018-08-01 05:36:06 -05:00
|
|
|
|
],
|
2017-03-30 11:52:47 -05:00
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_network_handler_with_url(url, exp_res):
|
|
|
|
|
"""test func."""
|
|
|
|
|
import buku
|
|
|
|
|
import urllib3
|
|
|
|
|
buku.urllib3 = urllib3
|
|
|
|
|
buku.myproxy = None
|
|
|
|
|
res = buku.network_handler(url)
|
2018-08-01 04:38:43 -05:00
|
|
|
|
if urlparse(url).netloc == 'www.google.ru':
|
2018-08-06 02:42:46 -05:00
|
|
|
|
temp_res = [res[0].split(" - ")[0], ]
|
|
|
|
|
temp_res.extend(res[1:])
|
|
|
|
|
res = tuple(temp_res)
|
2017-03-30 11:52:47 -05:00
|
|
|
|
assert res == exp_res
|
2017-07-18 09:35:08 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'url, exp_res',
|
|
|
|
|
[
|
|
|
|
|
('http://example.com', False),
|
|
|
|
|
('apt:package1,package2,package3', True),
|
|
|
|
|
('apt://firefox', True),
|
|
|
|
|
('file:///tmp/vim-markdown-preview.html', True),
|
|
|
|
|
('place:sort=8&maxResults=10', True),
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_is_nongeneric_url(url, exp_res):
|
|
|
|
|
import buku
|
|
|
|
|
res = buku.is_nongeneric_url(url)
|
|
|
|
|
assert res == exp_res
|
2017-07-21 22:31:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'newtag, exp_res',
|
|
|
|
|
[
|
|
|
|
|
(None, ('http://example.com', 'text1', None, None, 0, True)),
|
2018-12-30 20:49:38 -06:00
|
|
|
|
('tag1', ('http://example.com', 'text1', ',tag1,', None, 0, True)),
|
2017-07-21 22:31:29 -05:00
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_import_md(tmpdir, newtag, exp_res):
|
|
|
|
|
from buku import import_md
|
|
|
|
|
p = tmpdir.mkdir("importmd").join("test.md")
|
|
|
|
|
p.write("[text1](http://example.com)")
|
|
|
|
|
res = list(import_md(p.strpath, newtag))
|
|
|
|
|
assert res[0] == exp_res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'html_text, exp_res',
|
|
|
|
|
[
|
|
|
|
|
(
|
|
|
|
|
"""<DT><A HREF="https://github.com/j" ADD_DATE="1360951967" PRIVATE="1" TAGS="tag1,tag2">GitHub</A>
|
|
|
|
|
<DD>comment for the bookmark here
|
|
|
|
|
<a> </a>""",
|
|
|
|
|
((
|
|
|
|
|
'https://github.com/j', 'GitHub', ',tag1,tag2,',
|
2018-12-28 17:59:40 -06:00
|
|
|
|
'comment for the bookmark here', 0, True, False
|
2017-07-21 22:31:29 -05:00
|
|
|
|
),)
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
"""DT><A HREF="https://github.com/j" ADD_DATE="1360951967" PRIVATE="1" TAGS="tag1,tag2">GitHub</A>
|
|
|
|
|
<DD>comment for the bookmark here
|
|
|
|
|
<a>second line of the comment here</a>""",
|
|
|
|
|
((
|
|
|
|
|
'https://github.com/j', 'GitHub', ',tag1,tag2,',
|
2018-12-28 17:59:40 -06:00
|
|
|
|
'comment for the bookmark here', 0, True, False
|
2017-07-21 22:31:29 -05:00
|
|
|
|
),)
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
"""DT><A HREF="https://github.com/j" ADD_DATE="1360951967" PRIVATE="1" TAGS="tag1,tag2">GitHub</A>
|
|
|
|
|
<DD>comment for the bookmark here
|
|
|
|
|
second line of the comment here
|
|
|
|
|
third line of the comment here
|
|
|
|
|
<DT><A HREF="https://news.com/" ADD_DATE="1360951967" PRIVATE="1" TAGS="tag1,tag2,tag3">News</A>""",
|
|
|
|
|
(
|
|
|
|
|
(
|
|
|
|
|
'https://github.com/j', 'GitHub', ',tag1,tag2,',
|
|
|
|
|
'comment for the bookmark here\n '
|
|
|
|
|
'second line of the comment here\n '
|
2018-12-28 17:59:40 -06:00
|
|
|
|
'third line of the comment here',
|
2018-10-29 19:50:05 -05:00
|
|
|
|
0, True, False
|
2017-07-21 22:31:29 -05:00
|
|
|
|
),
|
2018-10-29 19:50:05 -05:00
|
|
|
|
('https://news.com/', 'News', ',tag1,tag2,tag3,', None, 0, True, False)
|
2017-07-21 22:31:29 -05:00
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
|
|
|
|
|
"""DT><A HREF="https://github.com/j" ADD_DATE="1360951967" PRIVATE="1" TAGS="tag1,tag2">GitHub</A>
|
|
|
|
|
<DD>comment for the bookmark here""",
|
|
|
|
|
((
|
|
|
|
|
'https://github.com/j', 'GitHub', ',tag1,tag2,',
|
2018-10-29 19:50:05 -05:00
|
|
|
|
'comment for the bookmark here', 0, True, False
|
2017-07-21 22:31:29 -05:00
|
|
|
|
),)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
def test_import_html(html_text, exp_res):
|
|
|
|
|
"""test method."""
|
|
|
|
|
from buku import import_html
|
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
html_soup = BeautifulSoup(html_text, 'html.parser')
|
|
|
|
|
res = list(import_html(html_soup, False, None))
|
|
|
|
|
for item, exp_item in zip(res, exp_res):
|
2018-10-29 19:50:05 -05:00
|
|
|
|
assert item == exp_item, 'Actual item:\n{}'.format(item)
|
2017-07-21 22:31:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_import_html_and_add_parent():
|
|
|
|
|
from buku import import_html
|
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
html_text = """<DT><H3>1s</H3>
|
|
|
|
|
<DL><p>
|
|
|
|
|
<DT><A HREF="http://example.com/"></A>"""
|
2018-10-29 19:50:05 -05:00
|
|
|
|
exp_res = ('http://example.com/', None, ',1s,', None, 0, True, False)
|
2017-07-21 22:31:29 -05:00
|
|
|
|
html_soup = BeautifulSoup(html_text, 'html.parser')
|
|
|
|
|
res = list(import_html(html_soup, True, None))
|
|
|
|
|
assert res[0] == exp_res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_import_html_and_new_tag():
|
|
|
|
|
from buku import import_html
|
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
html_text = """<DT><A HREF="https://github.com/j" TAGS="tag1,tag2">GitHub</A>
|
|
|
|
|
<DD>comment for the bookmark here"""
|
|
|
|
|
exp_res = (
|
|
|
|
|
'https://github.com/j', 'GitHub', ',tag1,tag2,tag3,',
|
2018-10-29 19:50:05 -05:00
|
|
|
|
'comment for the bookmark here', 0, True, False
|
2017-07-21 22:31:29 -05:00
|
|
|
|
)
|
|
|
|
|
html_soup = BeautifulSoup(html_text, 'html.parser')
|
|
|
|
|
res = list(import_html(html_soup, False, 'tag3'))
|
|
|
|
|
assert res[0] == exp_res
|
2018-02-11 09:57:33 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
'platform, params',
|
|
|
|
|
[
|
|
|
|
|
['linux', ['xsel', '-b', '-i']],
|
|
|
|
|
['freebsd', ['xsel', '-b', '-i']],
|
|
|
|
|
['openbsd', ['xsel', '-b', '-i']],
|
|
|
|
|
['darwin', ['pbcopy']],
|
|
|
|
|
['win32', ['clip']],
|
|
|
|
|
['random', None],
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
def test_copy_to_clipboard(platform, params):
|
|
|
|
|
# m_popen = mock.Mock()
|
|
|
|
|
content = mock.Mock()
|
|
|
|
|
m_popen_retval = mock.Mock()
|
|
|
|
|
platform_recognized = \
|
|
|
|
|
platform.startswith(('linux', 'freebsd', 'openbsd')) \
|
|
|
|
|
or platform in ('darwin', 'win32')
|
|
|
|
|
with mock.patch('buku.sys') as m_sys, \
|
|
|
|
|
mock.patch('buku.Popen', return_value=m_popen_retval) as m_popen, \
|
|
|
|
|
mock.patch('buku.shutil.which', return_value=True):
|
|
|
|
|
m_sys.platform = platform
|
|
|
|
|
from buku import copy_to_clipboard
|
|
|
|
|
import subprocess
|
|
|
|
|
copy_to_clipboard(content)
|
|
|
|
|
if platform_recognized:
|
|
|
|
|
m_popen.assert_called_once_with(
|
|
|
|
|
params, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
|
|
|
m_popen_retval.communicate.assert_called_once_with(content)
|
|
|
|
|
else:
|
|
|
|
|
m_popen.assert_not_called()
|
2019-04-28 01:00:46 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('export_type, exp_res', [
|
|
|
|
|
[
|
|
|
|
|
'html',
|
|
|
|
|
'<!DOCTYPE NETSCAPE-Bookmark-file-1>\n\n'
|
|
|
|
|
'<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">\n'
|
|
|
|
|
'<TITLE>Bookmarks</TITLE>\n<H1>Bookmarks</H1>\n\n<DL><p>\n'
|
|
|
|
|
' <DT><H3 ADD_DATE="1556430615" LAST_MODIFIED="1556430615" PERSONAL_TOOLBAR_FOLDER="true">Buku bookmarks</H3>\n'
|
|
|
|
|
' <DL><p>\n'
|
|
|
|
|
' <DT><A HREF="htttp://example.com" ADD_DATE="1556430615" LAST_MODIFIED="1556430615"></A>\n'
|
|
|
|
|
' <DT><A HREF="http://google.com" ADD_DATE="1556430615" LAST_MODIFIED="1556430615">Google</A>\n'
|
|
|
|
|
' </DL><p>\n</DL><p>'
|
|
|
|
|
],
|
|
|
|
|
['org', '- [Untitled](htttp://example.com)\n- [Google](http://google.com)\n'],
|
|
|
|
|
['markdown', '- [Untitled](htttp://example.com)\n- [Google](http://google.com)\n'],
|
|
|
|
|
['random', None],
|
|
|
|
|
])
|
|
|
|
|
def test_convert_bookmark_set(export_type, exp_res, monkeypatch):
|
|
|
|
|
from buku import convert_bookmark_set
|
|
|
|
|
import buku
|
|
|
|
|
bms = [
|
|
|
|
|
(1, 'htttp://example.com', '', ',', '', 0),
|
|
|
|
|
(2, 'http://google.com', 'Google', ',', '', 0)]
|
|
|
|
|
if export_type == 'random':
|
|
|
|
|
with pytest.raises(AssertionError):
|
|
|
|
|
convert_bookmark_set(bms, export_type=export_type)
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
def return_fixed_number():
|
|
|
|
|
return 1556430615
|
|
|
|
|
monkeypatch.setattr(buku.time, 'time', return_fixed_number)
|
|
|
|
|
res = convert_bookmark_set(bms, export_type=export_type)
|
|
|
|
|
assert res['count'] == 2
|
|
|
|
|
assert exp_res == res['data']
|