From 038d64b9018678c2d72661fabbdae033751ecb0a Mon Sep 17 00:00:00 2001 From: lufte Date: Mon, 28 Jun 2021 22:58:15 -0300 Subject: Update test_sql unit tests --- tests/unit/misc/test_sql.py | 152 ++++++++++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 62 deletions(-) (limited to 'tests') diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index f6fa68869..b287d6a29 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -28,7 +28,7 @@ from PyQt5.QtSql import QSqlError from qutebrowser.misc import sql -pytestmark = pytest.mark.usefixtures('init_sql') +pytestmark = pytest.mark.usefixtures('data_tmpdir') class TestUserVersion: @@ -120,23 +120,26 @@ class TestSqlError: assert err.text() == "db text" -def test_init(): - sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_init_table(data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_init_table.db')) + db.table('Foo', ['name', 'val', 'lucky']) # should not error if table already exists - sql.SqlTable('Foo', ['name', 'val', 'lucky']) + db.table('Foo', ['name', 'val', 'lucky']) -def test_insert(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_insert(qtbot, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_insert.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}) with qtbot.wait_signal(table.changed): table.insert({'name': 'wan', 'val': 1, 'lucky': False}) -def test_insert_replace(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky'], - constraints={'name': 'PRIMARY KEY'}) +def test_insert_replace(qtbot, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_insert_replace.db')) + table = db.table('Foo', ['name', 'val', 'lucky'], + constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}, replace=True) with qtbot.wait_signal(table.changed): @@ -147,8 +150,9 @@ def test_insert_replace(qtbot): table.insert({'name': 'one', 'val': 11, 'lucky': True}, replace=False) -def test_insert_batch(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_insert_batch(qtbot, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_insert_batch.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert_batch({'name': ['one', 'nine', 'thirteen'], @@ -160,9 +164,10 @@ def test_insert_batch(qtbot): ('thirteen', 13, True)] -def test_insert_batch_replace(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky'], - constraints={'name': 'PRIMARY KEY'}) +def test_insert_batch_replace(qtbot, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_insert_batch_replace.db')) + table = db.table('Foo', ['name', 'val', 'lucky'], + constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): table.insert_batch({'name': ['one', 'nine', 'thirteen'], @@ -185,8 +190,9 @@ def test_insert_batch_replace(qtbot): 'lucky': [True, True]}) -def test_iter(): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_iter(data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_iter.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -205,15 +211,17 @@ def test_iter(): ([{"a": 2, "b": 5}, {"a": 1, "b": 6}, {"a": 3, "b": 4}], 'a', 'asc', -1, [(1, 6), (2, 5), (3, 4)]), ]) -def test_select(rows, sort_by, sort_order, limit, result): - table = sql.SqlTable('Foo', ['a', 'b']) +def test_select(rows, sort_by, sort_order, limit, result, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_select.db')) + table = db.table('Foo', ['a', 'b']) for row in rows: table.insert(row) assert list(table.select(sort_by, sort_order, limit)) == result -def test_delete(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_delete(qtbot, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_delete.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -227,8 +235,9 @@ def test_delete(qtbot): assert not list(table) -def test_len(): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_len(data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_len.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) assert len(table) == 0 table.insert({'name': 'one', 'val': 1, 'lucky': False}) assert len(table) == 1 @@ -238,15 +247,17 @@ def test_len(): assert len(table) == 3 -def test_bool(): - table = sql.SqlTable('Foo', ['name']) +def test_bool(data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_bool.db')) + table = db.table('Foo', ['name']) assert not table table.insert({'name': 'one'}) assert table -def test_bool_benchmark(benchmark): - table = sql.SqlTable('Foo', ['number']) +def test_bool_benchmark(benchmark, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_bool_benchmark.db')) + table = db.table('Foo', ['number']) # Simulate a history table table.create_index('NumberIndex', 'number') @@ -258,8 +269,9 @@ def test_bool_benchmark(benchmark): benchmark(run) -def test_contains(): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_contains(data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_contains.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -279,8 +291,9 @@ def test_contains(): assert not val_query.run(val=10).value() -def test_delete_all(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_delete_all(qtbot, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_delete_all.db')) + table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -290,95 +303,110 @@ def test_delete_all(qtbot): def test_version(): - assert isinstance(sql.version(), str) + assert isinstance(sql.Database.version(), str) class TestSqlQuery: - def test_prepare_error(self): + def test_prepare_error(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_prepare_error')) with pytest.raises(sql.BugError) as excinfo: - sql.Query('invalid') + db.query('invalid') expected = ('Failed to prepare query "invalid": "near "invalid": ' 'syntax error Unable to execute statement"') assert str(excinfo.value) == expected @pytest.mark.parametrize('forward_only', [True, False]) - def test_forward_only(self, forward_only): - q = sql.Query('SELECT 0 WHERE 0', forward_only=forward_only) + def test_forward_only(self, forward_only, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_forward_only.db')) + q = db.query('SELECT 0 WHERE 0', forward_only=forward_only) assert q.query.isForwardOnly() == forward_only - def test_iter_inactive(self): - q = sql.Query('SELECT 0') + def test_iter_inactive(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_iter_inactive.db')) + q = db.query('SELECT 0') with pytest.raises(sql.BugError, match='Cannot iterate inactive query'): next(iter(q)) - def test_iter_empty(self): - q = sql.Query('SELECT 0 AS col WHERE 0') + def test_iter_empty(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_iter_empty.db')) + q = db.query('SELECT 0 AS col WHERE 0') q.run() with pytest.raises(StopIteration): next(iter(q)) - def test_iter(self): - q = sql.Query('SELECT 0 AS col') + def test_iter(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_iter.db')) + q = db.query('SELECT 0 AS col') q.run() result = next(iter(q)) assert result.col == 0 - def test_iter_multiple(self): - q = sql.Query('VALUES (1), (2), (3);') + def test_iter_multiple(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_iter_multiple.db')) + q = db.query('VALUES (1), (2), (3);') res = list(q.run()) assert len(res) == 3 assert res[0].column1 == 1 - def test_run_binding(self): - q = sql.Query('SELECT :answer') + def test_run_binding(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_run_binding.db')) + q = db.query('SELECT :answer') q.run(answer=42) assert q.value() == 42 - def test_run_missing_binding(self): - q = sql.Query('SELECT :answer') + def test_run_missing_binding(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_run_missing_binding.db')) + q = db.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run() - def test_run_batch(self): - q = sql.Query('SELECT :answer') + def test_run_batch(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_run_batch.db')) + q = db.query('SELECT :answer') q.run_batch(values={'answer': [42]}) assert q.value() == 42 - def test_run_batch_missing_binding(self): - q = sql.Query('SELECT :answer') + def test_run_batch_missing_binding(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_run_batch_missing_binding.db')) + q = db.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run_batch(values={}) - def test_value_missing(self): - q = sql.Query('SELECT 0 WHERE 0') + def test_value_missing(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_value_missing.db')) + q = db.query('SELECT 0 WHERE 0') q.run() with pytest.raises(sql.BugError, match='No result for single-result query'): q.value() - def test_num_rows_affected_not_active(self): + def test_num_rows_affected_not_active(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_num_rows_affected_not_active.db')) with pytest.raises(AssertionError): - q = sql.Query('SELECT 0') + q = db.query('SELECT 0') q.rows_affected() - def test_num_rows_affected_select(self): + def test_num_rows_affected_select(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_num_rows_affected_select.db')) with pytest.raises(AssertionError): - q = sql.Query('SELECT 0') + q = db.query('SELECT 0') q.run() q.rows_affected() @pytest.mark.parametrize('condition', [0, 1]) - def test_num_rows_affected(self, condition): - table = sql.SqlTable('Foo', ['name']) + def test_num_rows_affected(self, condition, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_num_rows_affected.db')) + table = db.table('Foo', ['name']) table.insert({'name': 'helloworld'}) - q = sql.Query(f'DELETE FROM Foo WHERE {condition}') + q = db.query(f'DELETE FROM Foo WHERE {condition}') q.run() assert q.rows_affected() == condition - def test_bound_values(self): - q = sql.Query('SELECT :answer') + def test_bound_values(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_bound_values.db')) + q = db.query('SELECT :answer') q.run(answer=42) assert q.bound_values() == {':answer': 42} -- cgit v1.2.3-54-g00ecf From 3b87db9059ff0d25cadff00dfb179d99486c9219 Mon Sep 17 00:00:00 2001 From: lufte Date: Wed, 30 Jun 2021 00:16:07 -0300 Subject: Make version() a plain function --- qutebrowser/misc/sql.py | 22 +++++++++++----------- qutebrowser/utils/version.py | 2 +- tests/unit/misc/test_sql.py | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/qutebrowser/misc/sql.py b/qutebrowser/misc/sql.py index 123e3bb0f..d254f50a9 100644 --- a/qutebrowser/misc/sql.py +++ b/qutebrowser/misc/sql.py @@ -309,17 +309,6 @@ class Database: """Return a Transaction object linked to this Database.""" return Transaction(self) - @classmethod - def version(cls) -> str: - """Return the sqlite version string.""" - try: - in_memory_db = cls(':memory:') - version = in_memory_db.query("select sqlite_version()").run().value() - in_memory_db.close() - return version - except KnownError as e: - return f'UNAVAILABLE ({e})' - class Transaction(contextlib.AbstractContextManager): # type: ignore[type-arg] @@ -614,3 +603,14 @@ class SqlTable(QObject): ) q.run(limit=limit) return q + + +def version() -> str: + """Return the sqlite version string.""" + try: + in_memory_db = Database(':memory:') + version = in_memory_db.query("select sqlite_version()").run().value() + in_memory_db.close() + return version + except KnownError as e: + return f'UNAVAILABLE ({e})' diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index f9bbb4cd2..8cd244fca 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -822,7 +822,7 @@ def version_info() -> str: lines += [ 'pdf.js: {}'.format(_pdfjs_version()), - 'sqlite: {}'.format(sql.Database.version()), + 'sqlite: {}'.format(sql.version()), 'QtNetwork SSL: {}\n'.format(QSslSocket.sslLibraryVersionString() if QSslSocket.supportsSsl() else 'no'), ] diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index b287d6a29..6843bd182 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -303,7 +303,7 @@ def test_delete_all(qtbot, data_tmpdir): def test_version(): - assert isinstance(sql.Database.version(), str) + assert isinstance(sql.version(), str) class TestSqlQuery: -- cgit v1.2.3-54-g00ecf From 748c686bf002822c6031565780e46ee8a378cc8e Mon Sep 17 00:00:00 2001 From: lufte Date: Wed, 30 Jun 2021 21:00:43 -0300 Subject: Fix history unit tests --- tests/helpers/fixtures.py | 14 +++---------- tests/unit/browser/test_history.py | 41 ++++++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 28 deletions(-) (limited to 'tests') diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py index 7106698be..3426e18b2 100644 --- a/tests/helpers/fixtures.py +++ b/tests/helpers/fixtures.py @@ -639,15 +639,6 @@ def short_tmpdir(): yield py.path.local(tdir) # pylint: disable=no-member -@pytest.fixture -def init_sql(data_tmpdir): - """Initialize the SQL module, and shut it down after the test.""" - path = str(data_tmpdir / 'test.db') - sql.init(path) - yield - sql.close() - - class ModelValidator: """Validates completion models.""" @@ -682,12 +673,13 @@ def download_stub(win_registry, tmpdir, stubs): @pytest.fixture -def web_history(fake_save_manager, tmpdir, init_sql, config_stub, stubs, +def web_history(fake_save_manager, tmpdir, data_tmpdir, config_stub, stubs, monkeypatch): """Create a WebHistory object.""" config_stub.val.completion.timestamp_format = '%Y-%m-%d' config_stub.val.completion.web_history.max_items = -1 - web_history = history.WebHistory(stubs.FakeHistoryProgress()) + db = sql.Database(str(data_tmpdir / 'history.db')) + web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) monkeypatch.setattr(history, 'web_history', web_history) return web_history diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py index 1a46c5be0..904a86a5f 100644 --- a/tests/unit/browser/test_history.py +++ b/tests/unit/browser/test_history.py @@ -31,7 +31,7 @@ from qutebrowser.misc import sql, objects @pytest.fixture(autouse=True) -def prerequisites(config_stub, fake_save_manager, init_sql, fake_args): +def prerequisites(config_stub, fake_save_manager, fake_args): """Make sure everything is ready to initialize a WebHistory.""" config_stub.data = {'general': {'private-browsing': False}} @@ -311,14 +311,14 @@ class TestInit: @pytest.mark.parametrize('backend', [usertypes.Backend.QtWebEngine, usertypes.Backend.QtWebKit]) - def test_init(self, backend, qapp, tmpdir, monkeypatch, cleanup_init): + def test_init(self, backend, qapp, tmpdir, data_tmpdir, monkeypatch, cleanup_init): if backend == usertypes.Backend.QtWebKit: pytest.importorskip('PyQt5.QtWebKitWidgets') else: assert backend == usertypes.Backend.QtWebEngine monkeypatch.setattr(history.objects, 'backend', backend) - history.init(qapp) + history.init(data_tmpdir / f'test_init_{backend}', qapp) assert history.web_history.parent() is qapp try: @@ -385,9 +385,10 @@ class TestRebuild: # hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) # assert list(hist2.completion) == [('example.com/1', '', 1)] - monkeypatch.setattr(sql, 'user_version_changed', lambda: True) + monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) - hist3 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist3 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist3.completion) == [ ('example.com/1', '', 1), ('example.com/2', '', 2), @@ -400,12 +401,14 @@ class TestRebuild: web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') - hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) # User version always changes, so this won't work # assert list(hist2.completion) == [('example.com/1', '', 1)] hist2.metainfo['force_rebuild'] = True - hist3 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist3 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist3.completion) == [ ('example.com/1', '', 1), ('example.com/2', '', 2), @@ -424,7 +427,8 @@ class TestRebuild: web_history.add_url(QUrl('http://example.org'), redirect=False, atime=2) - hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist2.completion) == [('http://example.com', '', 1)] def test_pattern_change_rebuild(self, config_stub, web_history, stubs): @@ -436,14 +440,16 @@ class TestRebuild: web_history.add_url(QUrl('http://example.org'), redirect=False, atime=2) - hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist2.completion) == [ ('http://example.com', '', 1), ] config_stub.val.completion.web_history.exclude = [] - hist3 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist3 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist3.completion) == [ ('http://example.com', '', 1), ('http://example.org', '', 2) @@ -454,10 +460,10 @@ class TestRebuild: web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) # Trigger a completion rebuild - monkeypatch.setattr(sql, 'user_version_changed', lambda: True) + monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) progress = stubs.FakeHistoryProgress() - history.WebHistory(progress=progress) + history.WebHistory(web_history.database, progress=progress) assert progress._value == 2 assert progress._started assert progress._finished @@ -468,10 +474,10 @@ class TestRebuild: progress = stubs.FakeHistoryProgress(raise_on_tick=True) # Trigger a completion rebuild - monkeypatch.setattr(sql, 'user_version_changed', lambda: True) + monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) with pytest.raises(Exception, match='tick-tock'): - history.WebHistory(progress=progress) + history.WebHistory(web_history.database, progress=progress) assert web_history.metainfo['force_rebuild'] @@ -483,8 +489,9 @@ class TestRebuild: class TestCompletionMetaInfo: @pytest.fixture - def metainfo(self): - return history.CompletionMetaInfo() + def metainfo(self, data_tmpdir): + db = sql.Database(str(data_tmpdir / 'TestCompletionMetaInfo.db')) + return history.CompletionMetaInfo(db) def test_contains_keyerror(self, metainfo): with pytest.raises(KeyError): @@ -521,7 +528,7 @@ class TestCompletionMetaInfo: assert not metainfo['force_rebuild'] def test_recovery_no_table(self, metainfo): - sql.Query("DROP TABLE CompletionMetaInfo").run() + metainfo._database.query("DROP TABLE CompletionMetaInfo").run() with pytest.raises(sql.BugError, match='no such table: CompletionMetaInfo'): metainfo['force_rebuild'] -- cgit v1.2.3-54-g00ecf From b75d23e0b1ad305a681847107bdaff5b870e1fef Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 2 Jul 2021 21:48:34 -0300 Subject: Fix histcategory unit tests --- tests/unit/completion/test_histcategory.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/unit/completion/test_histcategory.py b/tests/unit/completion/test_histcategory.py index e0a12943b..4e3b657e2 100644 --- a/tests/unit/completion/test_histcategory.py +++ b/tests/unit/completion/test_histcategory.py @@ -32,10 +32,11 @@ from qutebrowser.utils import usertypes @pytest.fixture -def hist(init_sql, config_stub): +def hist(data_tmpdir, config_stub): + db = sql.Database(str(data_tmpdir / 'test_histcategory.db')) config_stub.val.completion.timestamp_format = '%Y-%m-%d' config_stub.val.completion.web_history.max_items = -1 - return sql.SqlTable('CompletionHistory', ['url', 'title', 'last_atime']) + return sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime']) @pytest.mark.parametrize('pattern, before, after', [ @@ -99,7 +100,7 @@ def test_set_pattern(pattern, before, after, model_validator, hist): """Validate the filtering and sorting results of set_pattern.""" for row in before: hist.insert({'url': row[0], 'title': row[1], 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) model_validator.set_model(cat) cat.set_pattern(pattern) model_validator.validate(after) @@ -110,7 +111,7 @@ def test_set_pattern_repeated(model_validator, hist): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) hist.insert({'url': 'example.com/bar', 'title': 'title2', 'last_atime': 1}) hist.insert({'url': 'example.com/baz', 'title': 'title3', 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) model_validator.set_model(cat) cat.set_pattern('b') @@ -143,7 +144,7 @@ def test_set_pattern_repeated(model_validator, hist): ], ids=['numbers', 'characters']) def test_set_pattern_long(hist, message_mock, caplog, pattern): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) with caplog.at_level(logging.ERROR): cat.set_pattern(pattern) msg = message_mock.getmsg(usertypes.MessageLevel.error) @@ -153,7 +154,7 @@ def test_set_pattern_long(hist, message_mock, caplog, pattern): @hypothesis.given(pat=strategies.text()) def test_set_pattern_hypothesis(hist, pat, caplog): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) with caplog.at_level(logging.ERROR): cat.set_pattern(pat) @@ -202,7 +203,7 @@ def test_sorting(max_items, before, after, model_validator, hist, config_stub): for url, title, atime in before: timestamp = datetime.datetime.strptime(atime, '%Y-%m-%d').timestamp() hist.insert({'url': url, 'title': title, 'last_atime': timestamp}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) model_validator.set_model(cat) cat.set_pattern('') model_validator.validate(after) @@ -211,7 +212,7 @@ def test_sorting(max_items, before, after, model_validator, hist, config_stub): def test_remove_rows(hist, model_validator): hist.insert({'url': 'foo', 'title': 'Foo', 'last_atime': 0}) hist.insert({'url': 'bar', 'title': 'Bar', 'last_atime': 0}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) model_validator.set_model(cat) cat.set_pattern('') hist.delete('url', 'foo') @@ -227,7 +228,7 @@ def test_remove_rows_fetch(hist): 'title': [str(i) for i in range(300)], 'last_atime': [0] * 300, }) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) cat.set_pattern('') # sanity check that we didn't fetch everything up front @@ -245,20 +246,21 @@ def test_remove_rows_fetch(hist): ('%m/%d/%Y %H:%M', '02/27/2018 08:30'), ('', ''), ]) -def test_timestamp_fmt(fmt, expected, model_validator, config_stub, init_sql): +def test_timestamp_fmt(fmt, expected, model_validator, config_stub, data_tmpdir): """Validate the filtering and sorting results of set_pattern.""" config_stub.val.completion.timestamp_format = fmt - hist = sql.SqlTable('CompletionHistory', ['url', 'title', 'last_atime']) + db = sql.Database(str(data_tmpdir / 'test_timestamp_fmt.db')) + hist = sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime']) atime = datetime.datetime(2018, 2, 27, 8, 30) hist.insert({'url': 'foo', 'title': '', 'last_atime': atime.timestamp()}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) model_validator.set_model(cat) cat.set_pattern('') model_validator.validate([('foo', '', expected)]) def test_skip_duplicate_set(message_mock, caplog, hist): - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist._database) cat.set_pattern('foo') cat.set_pattern('foobarbaz') msg = caplog.messages[-1] -- cgit v1.2.3-54-g00ecf From 03b8a266455b2cfd0484e1d16ba7e6370ae49655 Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 2 Jul 2021 22:18:12 -0300 Subject: The database of a table shouldn't be private --- qutebrowser/browser/history.py | 41 +++++++++++++++--------------- qutebrowser/misc/sql.py | 28 ++++++++++---------- tests/unit/browser/test_history.py | 2 +- tests/unit/completion/test_histcategory.py | 18 ++++++------- 4 files changed, 45 insertions(+), 44 deletions(-) (limited to 'tests') diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py index ada8bf0a6..4163f1957 100644 --- a/qutebrowser/browser/history.py +++ b/qutebrowser/browser/history.py @@ -126,8 +126,8 @@ class CompletionMetaInfo(sql.SqlTable): def __getitem__(self, key): self._check_key(key) - query = self._database.query('SELECT value FROM CompletionMetaInfo ' - 'WHERE key = :key') + query = self.database.query('SELECT value FROM CompletionMetaInfo ' + 'WHERE key = :key') return query.run(key=key).value() def __setitem__(self, key, value): @@ -172,7 +172,6 @@ class WebHistory(sql.SqlTable): 'atime': 'NOT NULL', 'redirect': 'NOT NULL'}, parent=parent) - self.database = database self._progress = progress # Store the last saved url to avoid duplicate immediate saves. self._last_url = None @@ -188,8 +187,8 @@ class WebHistory(sql.SqlTable): self.metainfo.try_recover() rebuild_completion = self.metainfo['force_rebuild'] - if self._database.user_version_changed(): - with self._database.transaction(): + if self.database.user_version_changed(): + with self.database.transaction(): # If the DB user version changed, run a full cleanup and rebuild the # completion history. # @@ -199,7 +198,7 @@ class WebHistory(sql.SqlTable): # VACUUM to make things smaller. self._cleanup_history() rebuild_completion = True - self._database.upgrade_user_version() + self.database.upgrade_user_version() # Get a string of all patterns patterns = config.instance.get_str('completion.web_history.exclude') @@ -217,19 +216,19 @@ class WebHistory(sql.SqlTable): self.create_index('HistoryIndex', 'url') self.create_index('HistoryAtimeIndex', 'atime') self._contains_query = self.contains_query('url') - self._between_query = self._database.query('SELECT * FROM History ' - 'where not redirect ' - 'and not url like "qute://%" ' - 'and atime > :earliest ' - 'and atime <= :latest ' - 'ORDER BY atime desc') - - self._before_query = self._database.query('SELECT * FROM History ' + self._between_query = self.database.query('SELECT * FROM History ' 'where not redirect ' 'and not url like "qute://%" ' + 'and atime > :earliest ' 'and atime <= :latest ' - 'ORDER BY atime desc ' - 'limit :limit offset :offset') + 'ORDER BY atime desc') + + self._before_query = self.database.query('SELECT * FROM History ' + 'where not redirect ' + 'and not url like "qute://%" ' + 'and atime <= :latest ' + 'ORDER BY atime desc ' + 'limit :limit offset :offset') def __repr__(self): return utils.get_repr(self, length=len(self)) @@ -277,7 +276,7 @@ class WebHistory(sql.SqlTable): 'qute://pdfjs%', ] where_clause = ' OR '.join(f"url LIKE '{term}'" for term in terms) - q = self._database.query(f'DELETE FROM History WHERE {where_clause}') + q = self.database.query(f'DELETE FROM History WHERE {where_clause}') entries = q.run() log.sql.debug(f"Cleanup removed {entries.rows_affected()} items") @@ -303,9 +302,9 @@ class WebHistory(sql.SqlTable): QApplication.processEvents() # Select the latest entry for each url - q = self._database.query('SELECT url, title, max(atime) AS atime FROM History ' - 'WHERE NOT redirect ' - 'GROUP BY url ORDER BY atime asc') + q = self.database.query('SELECT url, title, max(atime) AS atime FROM History ' + 'WHERE NOT redirect ' + 'GROUP BY url ORDER BY atime asc') result = q.run() QApplication.processEvents() entries = list(result) @@ -325,7 +324,7 @@ class WebHistory(sql.SqlTable): self._progress.set_maximum(0) # We might have caused fragmentation - let's clean up. - self._database.query('VACUUM').run() + self.database.query('VACUUM').run() QApplication.processEvents() self.completion.insert_batch(data, replace=True) diff --git a/qutebrowser/misc/sql.py b/qutebrowser/misc/sql.py index d8755f0b4..460d88ce9 100644 --- a/qutebrowser/misc/sql.py +++ b/qutebrowser/misc/sql.py @@ -387,12 +387,14 @@ class SqlTable(QObject): Attributes: _name: Name of the SQL table this wraps. + database: The Database to which this table belongs. Signals: changed: Emitted when the table is modified. """ changed = pyqtSignal() + database: Database def __init__(self, database: Database, name: str, fields: List[str], constraints: Optional[Dict[str, str]] = None, @@ -407,7 +409,7 @@ class SqlTable(QObject): """ super().__init__(parent) self._name = name - self._database = database + self.database = database self._create_table(fields, constraints) def _create_table(self, fields: List[str], constraints: Optional[Dict[str, str]], @@ -417,13 +419,13 @@ class SqlTable(QObject): If the table already exists, this does nothing (except with force=True), so it can e.g. be called on every user_version change. """ - if not self._database.user_version_changed() and not force: + if not self.database.user_version_changed() and not force: return constraints = constraints or {} column_defs = [f'{field} {constraints.get(field, "")}' for field in fields] - q = self._database.query( + q = self.database.query( f"CREATE TABLE IF NOT EXISTS {self._name} ({', '.join(column_defs)})" ) q.run() @@ -435,17 +437,17 @@ class SqlTable(QObject): name: Name of the index, should be unique. field: Name of the field to index. """ - if not self._database.user_version_changed(): + if not self.database.user_version_changed(): return - q = self._database.query( + q = self.database.query( f"CREATE INDEX IF NOT EXISTS {name} ON {self._name} ({field})" ) q.run() def __iter__(self) -> Iterator[Any]: """Iterate rows in the table.""" - q = self._database.query(f"SELECT * FROM {self._name}") + q = self.database.query(f"SELECT * FROM {self._name}") q.run() return iter(q) @@ -455,19 +457,19 @@ class SqlTable(QObject): Args: field: Field to match. """ - return self._database.query( + return self.database.query( f"SELECT EXISTS(SELECT * FROM {self._name} WHERE {field} = :val)" ) def __len__(self) -> int: """Return the count of rows in the table.""" - q = self._database.query(f"SELECT count(*) FROM {self._name}") + q = self.database.query(f"SELECT count(*) FROM {self._name}") q.run() return q.value() def __bool__(self) -> bool: """Check whether there's any data in the table.""" - q = self._database.query(f"SELECT 1 FROM {self._name} LIMIT 1") + q = self.database.query(f"SELECT 1 FROM {self._name} LIMIT 1") q.run() return q.query.next() @@ -481,7 +483,7 @@ class SqlTable(QObject): Return: The number of rows deleted. """ - q = self._database.query(f"DELETE FROM {self._name} where {field} = :val") + q = self.database.query(f"DELETE FROM {self._name} where {field} = :val") q.run(val=value) if not q.rows_affected(): raise KeyError('No row with {field} = "{value}"') @@ -491,7 +493,7 @@ class SqlTable(QObject): params = ', '.join(f':{key}' for key in values) columns = ', '.join(values) verb = "REPLACE" if replace else "INSERT" - return self._database.query( + return self.database.query( f"{verb} INTO {self._name} ({columns}) values({params})" ) @@ -520,7 +522,7 @@ class SqlTable(QObject): def delete_all(self) -> None: """Remove all rows from the table.""" - self._database.query(f"DELETE FROM {self._name}").run() + self.database.query(f"DELETE FROM {self._name}").run() self.changed.emit() def select(self, sort_by: str, sort_order: str, limit: int = -1) -> Query: @@ -533,7 +535,7 @@ class SqlTable(QObject): Return: A prepared and executed select query. """ - q = self._database.query( + q = self.database.query( f"SELECT * FROM {self._name} ORDER BY {sort_by} {sort_order} LIMIT :limit" ) q.run(limit=limit) diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py index 904a86a5f..0454fb722 100644 --- a/tests/unit/browser/test_history.py +++ b/tests/unit/browser/test_history.py @@ -528,7 +528,7 @@ class TestCompletionMetaInfo: assert not metainfo['force_rebuild'] def test_recovery_no_table(self, metainfo): - metainfo._database.query("DROP TABLE CompletionMetaInfo").run() + metainfo.database.query("DROP TABLE CompletionMetaInfo").run() with pytest.raises(sql.BugError, match='no such table: CompletionMetaInfo'): metainfo['force_rebuild'] diff --git a/tests/unit/completion/test_histcategory.py b/tests/unit/completion/test_histcategory.py index 4e3b657e2..cb37fb784 100644 --- a/tests/unit/completion/test_histcategory.py +++ b/tests/unit/completion/test_histcategory.py @@ -100,7 +100,7 @@ def test_set_pattern(pattern, before, after, model_validator, hist): """Validate the filtering and sorting results of set_pattern.""" for row in before: hist.insert({'url': row[0], 'title': row[1], 'last_atime': 1}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern(pattern) model_validator.validate(after) @@ -111,7 +111,7 @@ def test_set_pattern_repeated(model_validator, hist): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) hist.insert({'url': 'example.com/bar', 'title': 'title2', 'last_atime': 1}) hist.insert({'url': 'example.com/baz', 'title': 'title3', 'last_atime': 1}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('b') @@ -144,7 +144,7 @@ def test_set_pattern_repeated(model_validator, hist): ], ids=['numbers', 'characters']) def test_set_pattern_long(hist, message_mock, caplog, pattern): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) with caplog.at_level(logging.ERROR): cat.set_pattern(pattern) msg = message_mock.getmsg(usertypes.MessageLevel.error) @@ -154,7 +154,7 @@ def test_set_pattern_long(hist, message_mock, caplog, pattern): @hypothesis.given(pat=strategies.text()) def test_set_pattern_hypothesis(hist, pat, caplog): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) with caplog.at_level(logging.ERROR): cat.set_pattern(pat) @@ -203,7 +203,7 @@ def test_sorting(max_items, before, after, model_validator, hist, config_stub): for url, title, atime in before: timestamp = datetime.datetime.strptime(atime, '%Y-%m-%d').timestamp() hist.insert({'url': url, 'title': title, 'last_atime': timestamp}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('') model_validator.validate(after) @@ -212,7 +212,7 @@ def test_sorting(max_items, before, after, model_validator, hist, config_stub): def test_remove_rows(hist, model_validator): hist.insert({'url': 'foo', 'title': 'Foo', 'last_atime': 0}) hist.insert({'url': 'bar', 'title': 'Bar', 'last_atime': 0}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('') hist.delete('url', 'foo') @@ -228,7 +228,7 @@ def test_remove_rows_fetch(hist): 'title': [str(i) for i in range(300)], 'last_atime': [0] * 300, }) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) cat.set_pattern('') # sanity check that we didn't fetch everything up front @@ -253,14 +253,14 @@ def test_timestamp_fmt(fmt, expected, model_validator, config_stub, data_tmpdir) hist = sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime']) atime = datetime.datetime(2018, 2, 27, 8, 30) hist.insert({'url': 'foo', 'title': '', 'last_atime': atime.timestamp()}) - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('') model_validator.validate([('foo', '', expected)]) def test_skip_duplicate_set(message_mock, caplog, hist): - cat = histcategory.HistoryCategory(database=hist._database) + cat = histcategory.HistoryCategory(database=hist.database) cat.set_pattern('foo') cat.set_pattern('foobarbaz') msg = caplog.messages[-1] -- cgit v1.2.3-54-g00ecf From 082916b45d1507ffbe28dd04eff7aa717a308d62 Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 2 Jul 2021 23:25:59 -0300 Subject: Add unit tests for the Transaction class --- tests/unit/misc/test_sql.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index 6843bd182..068298e3c 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -23,7 +23,7 @@ import pytest import hypothesis from hypothesis import strategies -from PyQt5.QtSql import QSqlError +from PyQt5.QtSql import QSqlDatabase, QSqlError, QSqlQuery from qutebrowser.misc import sql @@ -379,8 +379,7 @@ class TestSqlQuery: db = sql.Database(str(data_tmpdir / 'test_value_missing.db')) q = db.query('SELECT 0 WHERE 0') q.run() - with pytest.raises(sql.BugError, - match='No result for single-result query'): + with pytest.raises(sql.BugError, match='No result for single-result query'): q.value() def test_num_rows_affected_not_active(self, data_tmpdir): @@ -410,3 +409,36 @@ class TestSqlQuery: q = db.query('SELECT :answer') q.run(answer=42) assert q.bound_values() == {':answer': 42} + + +class TestTransaction: + + def test_successful_transaction(self, data_tmpdir): + path = str(data_tmpdir / 'test_successful_transaction') + db = sql.Database(path) + my_table = db.table('my_table', ['column']) + with db.transaction(): + my_table.insert({'column': 1}) + my_table.insert({'column': 2}) + + db2 = QSqlDatabase.addDatabase('QSQLITE', 'db2') + db2.setDatabaseName(path) + db2.open() + query = QSqlQuery(db2) + query.exec('select count(*) from my_table') + query.next() + assert query.record().value(0) == 0 + assert db.query('select count(*) from my_table').run().value() == 2 + + def test_failed_transaction(self, data_tmpdir): + path = str(data_tmpdir / 'test_failed_transaction') + db = sql.Database(path) + my_table = db.table('my_table', ['column']) + try: + with db.transaction(): + my_table.insert({'column': 1}) + my_table.insert({'column': 2}) + raise Exception('something went horribly wrong') + except Exception: + pass + assert db.query('select count(*) from my_table').run().value() == 0 -- cgit v1.2.3-54-g00ecf From 9949b4c5d6e81c3a7b4755262ab75a3ad21e5240 Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 2 Jul 2021 23:35:20 -0300 Subject: No need to create new databases each time --- tests/unit/misc/test_sql.py | 100 ++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 63 deletions(-) (limited to 'tests') diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index 068298e3c..33af9d7c1 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -31,6 +31,12 @@ from qutebrowser.misc import sql pytestmark = pytest.mark.usefixtures('data_tmpdir') +@pytest.fixture +def db(data_tmpdir): + database = sql.Database(str(data_tmpdir / 'test_sql.db')) + return database + + class TestUserVersion: @pytest.mark.parametrize('val, major, minor', [ @@ -120,15 +126,13 @@ class TestSqlError: assert err.text() == "db text" -def test_init_table(data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_init_table.db')) +def test_init_table(db): db.table('Foo', ['name', 'val', 'lucky']) # should not error if table already exists db.table('Foo', ['name', 'val', 'lucky']) -def test_insert(qtbot, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_insert.db')) +def test_insert(qtbot, db): table = db.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}) @@ -136,8 +140,7 @@ def test_insert(qtbot, data_tmpdir): table.insert({'name': 'wan', 'val': 1, 'lucky': False}) -def test_insert_replace(qtbot, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_insert_replace.db')) +def test_insert_replace(qtbot, db): table = db.table('Foo', ['name', 'val', 'lucky'], constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): @@ -150,8 +153,7 @@ def test_insert_replace(qtbot, data_tmpdir): table.insert({'name': 'one', 'val': 11, 'lucky': True}, replace=False) -def test_insert_batch(qtbot, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_insert_batch.db')) +def test_insert_batch(qtbot, db): table = db.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): @@ -164,8 +166,7 @@ def test_insert_batch(qtbot, data_tmpdir): ('thirteen', 13, True)] -def test_insert_batch_replace(qtbot, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_insert_batch_replace.db')) +def test_insert_batch_replace(qtbot, db): table = db.table('Foo', ['name', 'val', 'lucky'], constraints={'name': 'PRIMARY KEY'}) @@ -190,8 +191,7 @@ def test_insert_batch_replace(qtbot, data_tmpdir): 'lucky': [True, True]}) -def test_iter(data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_iter.db')) +def test_iter(db): table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) @@ -211,16 +211,14 @@ def test_iter(data_tmpdir): ([{"a": 2, "b": 5}, {"a": 1, "b": 6}, {"a": 3, "b": 4}], 'a', 'asc', -1, [(1, 6), (2, 5), (3, 4)]), ]) -def test_select(rows, sort_by, sort_order, limit, result, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_select.db')) +def test_select(rows, sort_by, sort_order, limit, result, db): table = db.table('Foo', ['a', 'b']) for row in rows: table.insert(row) assert list(table.select(sort_by, sort_order, limit)) == result -def test_delete(qtbot, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_delete.db')) +def test_delete(qtbot, db): table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) @@ -235,8 +233,7 @@ def test_delete(qtbot, data_tmpdir): assert not list(table) -def test_len(data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_len.db')) +def test_len(db): table = db.table('Foo', ['name', 'val', 'lucky']) assert len(table) == 0 table.insert({'name': 'one', 'val': 1, 'lucky': False}) @@ -247,16 +244,14 @@ def test_len(data_tmpdir): assert len(table) == 3 -def test_bool(data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_bool.db')) +def test_bool(db): table = db.table('Foo', ['name']) assert not table table.insert({'name': 'one'}) assert table -def test_bool_benchmark(benchmark, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_bool_benchmark.db')) +def test_bool_benchmark(benchmark, db): table = db.table('Foo', ['number']) # Simulate a history table @@ -269,8 +264,7 @@ def test_bool_benchmark(benchmark, data_tmpdir): benchmark(run) -def test_contains(data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_contains.db')) +def test_contains(db): table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) @@ -291,8 +285,7 @@ def test_contains(data_tmpdir): assert not val_query.run(val=10).value() -def test_delete_all(qtbot, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_delete_all.db')) +def test_delete_all(qtbot, db): table = db.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) @@ -308,8 +301,7 @@ def test_version(): class TestSqlQuery: - def test_prepare_error(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_prepare_error')) + def test_prepare_error(self, db): with pytest.raises(sql.BugError) as excinfo: db.query('invalid') @@ -318,94 +310,80 @@ class TestSqlQuery: assert str(excinfo.value) == expected @pytest.mark.parametrize('forward_only', [True, False]) - def test_forward_only(self, forward_only, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_forward_only.db')) + def test_forward_only(self, forward_only, db): q = db.query('SELECT 0 WHERE 0', forward_only=forward_only) assert q.query.isForwardOnly() == forward_only - def test_iter_inactive(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_iter_inactive.db')) + def test_iter_inactive(self, db): q = db.query('SELECT 0') with pytest.raises(sql.BugError, match='Cannot iterate inactive query'): next(iter(q)) - def test_iter_empty(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_iter_empty.db')) + def test_iter_empty(self, db): q = db.query('SELECT 0 AS col WHERE 0') q.run() with pytest.raises(StopIteration): next(iter(q)) - def test_iter(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_iter.db')) + def test_iter(self, db): q = db.query('SELECT 0 AS col') q.run() result = next(iter(q)) assert result.col == 0 - def test_iter_multiple(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_iter_multiple.db')) + def test_iter_multiple(self, db): q = db.query('VALUES (1), (2), (3);') res = list(q.run()) assert len(res) == 3 assert res[0].column1 == 1 - def test_run_binding(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_run_binding.db')) + def test_run_binding(self, db): q = db.query('SELECT :answer') q.run(answer=42) assert q.value() == 42 - def test_run_missing_binding(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_run_missing_binding.db')) + def test_run_missing_binding(self, db): q = db.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run() - def test_run_batch(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_run_batch.db')) + def test_run_batch(self, db): q = db.query('SELECT :answer') q.run_batch(values={'answer': [42]}) assert q.value() == 42 - def test_run_batch_missing_binding(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_run_batch_missing_binding.db')) + def test_run_batch_missing_binding(self, db): q = db.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run_batch(values={}) - def test_value_missing(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_value_missing.db')) + def test_value_missing(self, db): q = db.query('SELECT 0 WHERE 0') q.run() with pytest.raises(sql.BugError, match='No result for single-result query'): q.value() - def test_num_rows_affected_not_active(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_num_rows_affected_not_active.db')) + def test_num_rows_affected_not_active(self, db): with pytest.raises(AssertionError): q = db.query('SELECT 0') q.rows_affected() - def test_num_rows_affected_select(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_num_rows_affected_select.db')) + def test_num_rows_affected_select(self, db): with pytest.raises(AssertionError): q = db.query('SELECT 0') q.run() q.rows_affected() @pytest.mark.parametrize('condition', [0, 1]) - def test_num_rows_affected(self, condition, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_num_rows_affected.db')) + def test_num_rows_affected(self, condition, db): table = db.table('Foo', ['name']) table.insert({'name': 'helloworld'}) q = db.query(f'DELETE FROM Foo WHERE {condition}') q.run() assert q.rows_affected() == condition - def test_bound_values(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_bound_values.db')) + def test_bound_values(self, db): q = db.query('SELECT :answer') q.run(answer=42) assert q.bound_values() == {':answer': 42} @@ -413,16 +391,14 @@ class TestSqlQuery: class TestTransaction: - def test_successful_transaction(self, data_tmpdir): - path = str(data_tmpdir / 'test_successful_transaction') - db = sql.Database(path) + def test_successful_transaction(self, db): my_table = db.table('my_table', ['column']) with db.transaction(): my_table.insert({'column': 1}) my_table.insert({'column': 2}) db2 = QSqlDatabase.addDatabase('QSQLITE', 'db2') - db2.setDatabaseName(path) + db2.setDatabaseName(db.qt_database().databaseName()) db2.open() query = QSqlQuery(db2) query.exec('select count(*) from my_table') @@ -430,9 +406,7 @@ class TestTransaction: assert query.record().value(0) == 0 assert db.query('select count(*) from my_table').run().value() == 2 - def test_failed_transaction(self, data_tmpdir): - path = str(data_tmpdir / 'test_failed_transaction') - db = sql.Database(path) + def test_failed_transaction(self, db): my_table = db.table('my_table', ['column']) try: with db.transaction(): -- cgit v1.2.3-54-g00ecf From fae662a3c929efe18b20a58a8bfb078b123a1d66 Mon Sep 17 00:00:00 2001 From: lufte Date: Sat, 3 Jul 2021 00:51:20 -0300 Subject: Refactor tests that needed the Database class --- tests/unit/browser/test_history.py | 64 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'tests') diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py index 0454fb722..4f1032254 100644 --- a/tests/unit/browser/test_history.py +++ b/tests/unit/browser/test_history.py @@ -368,22 +368,16 @@ class TestDump: class TestRebuild: - # FIXME: Some of those tests might be a bit misleading, as creating a new - # history.WebHistory will regenerate the completion either way with the SQL changes - # in v2.0.0 (because the user version changed from 0 -> 3). - # - # They should be revisited once we can actually create two independent sqlite - # databases and copy the data over, for a "real" test. - - def test_user_version(self, web_history, stubs, monkeypatch): + def test_user_version(self, data_tmpdir, stubs, monkeypatch): """Ensure that completion is regenerated if user_version changes.""" + db = sql.Database(str(data_tmpdir / 'test_user_version.db')) + web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') - # User version always changes, so this won't work - # hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) - # assert list(hist2.completion) == [('example.com/1', '', 1)] + hist2 = history.WebHistory(db, progress=stubs.FakeHistoryProgress()) + assert list(hist2.completion) == [('example.com/1', '', 1)] monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) @@ -395,16 +389,17 @@ class TestRebuild: ] assert not hist3.metainfo['force_rebuild'] - def test_force_rebuild(self, web_history, stubs): + def test_force_rebuild(self, data_tmpdir, stubs): """Ensure that completion is regenerated if we force a rebuild.""" + db = sql.Database(str(data_tmpdir / 'test_user_version.db')) + web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') hist2 = history.WebHistory(web_history.database, progress=stubs.FakeHistoryProgress()) - # User version always changes, so this won't work - # assert list(hist2.completion) == [('example.com/1', '', 1)] + assert list(hist2.completion) == [('example.com/1', '', 1)] hist2.metainfo['force_rebuild'] = True hist3 = history.WebHistory(web_history.database, @@ -468,9 +463,12 @@ class TestRebuild: assert progress._started assert progress._finished - def test_interrupted(self, stubs, web_history, monkeypatch): + def test_interrupted(self, stubs, data_tmpdir, monkeypatch): """If we interrupt the rebuilding process, force_rebuild should still be set.""" + db = sql.Database(str(data_tmpdir / 'test_user_version.db')) + web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) + web_history.completion.delete('url', 'example.com/1') progress = stubs.FakeHistoryProgress(raise_on_tick=True) # Trigger a completion rebuild @@ -481,9 +479,9 @@ class TestRebuild: assert web_history.metainfo['force_rebuild'] - # If we now try again, we should get another rebuild. But due to user_version - # always changing, we can't test this at the moment (see the FIXME in the - # docstring for details) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) + assert list(hist2.completion) == [('example.com/1', '', 1)] class TestCompletionMetaInfo: @@ -514,27 +512,29 @@ class TestCompletionMetaInfo: metainfo['excluded_patterns'] = value assert metainfo['excluded_patterns'] == value - # FIXME: It'd be good to test those two things via WebHistory (and not just - # CompletionMetaInfo in isolation), but we can't do that right now - see the - # docstring of TestRebuild for details. - - def test_recovery_no_key(self, metainfo): - metainfo.delete('key', 'force_rebuild') + def test_recovery_no_key(self, caplog, data_tmpdir, stubs): + db = sql.Database(str(data_tmpdir / 'test_recovery_no_key.db')) + web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history.metainfo.delete('key', 'force_rebuild') with pytest.raises(sql.BugError, match='No result for single-result query'): - metainfo['force_rebuild'] + web_history.metainfo['force_rebuild'] - metainfo.try_recover() - assert not metainfo['force_rebuild'] + with caplog.at_level(logging.WARNING): + web_history2 = history.WebHistory(db, stubs.FakeHistoryProgress()) + assert not web_history2.metainfo['force_rebuild'] - def test_recovery_no_table(self, metainfo): - metainfo.database.query("DROP TABLE CompletionMetaInfo").run() + def test_recovery_no_table(self, caplog, data_tmpdir, stubs): + db = sql.Database(str(data_tmpdir / 'test_recovery_no_table.db')) + web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history.metainfo.database.query("DROP TABLE CompletionMetaInfo").run() with pytest.raises(sql.BugError, match='no such table: CompletionMetaInfo'): - metainfo['force_rebuild'] + web_history.metainfo['force_rebuild'] - metainfo.try_recover() - assert not metainfo['force_rebuild'] + with caplog.at_level(logging.WARNING): + web_history2 = history.WebHistory(db, stubs.FakeHistoryProgress()) + assert not web_history2.metainfo['force_rebuild'] class TestHistoryProgress: -- cgit v1.2.3-54-g00ecf From 484ac43cf1b090953ff4efde617f0a2fc07177cd Mon Sep 17 00:00:00 2001 From: lufte Date: Sat, 3 Jul 2021 01:00:32 -0300 Subject: Fix function name too short --- tests/unit/misc/test_sql.py | 140 ++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 70 deletions(-) (limited to 'tests') diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index 33af9d7c1..1262f0c3f 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -32,9 +32,9 @@ pytestmark = pytest.mark.usefixtures('data_tmpdir') @pytest.fixture -def db(data_tmpdir): - database = sql.Database(str(data_tmpdir / 'test_sql.db')) - return database +def database(data_tmpdir): + db = sql.Database(str(data_tmpdir / 'test_sql.db')) + return db class TestUserVersion: @@ -126,22 +126,22 @@ class TestSqlError: assert err.text() == "db text" -def test_init_table(db): - db.table('Foo', ['name', 'val', 'lucky']) +def test_init_table(database): + database.table('Foo', ['name', 'val', 'lucky']) # should not error if table already exists - db.table('Foo', ['name', 'val', 'lucky']) + database.table('Foo', ['name', 'val', 'lucky']) -def test_insert(qtbot, db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_insert(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}) with qtbot.wait_signal(table.changed): table.insert({'name': 'wan', 'val': 1, 'lucky': False}) -def test_insert_replace(qtbot, db): - table = db.table('Foo', ['name', 'val', 'lucky'], +def test_insert_replace(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky'], constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}, replace=True) @@ -153,8 +153,8 @@ def test_insert_replace(qtbot, db): table.insert({'name': 'one', 'val': 11, 'lucky': True}, replace=False) -def test_insert_batch(qtbot, db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_insert_batch(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert_batch({'name': ['one', 'nine', 'thirteen'], @@ -166,8 +166,8 @@ def test_insert_batch(qtbot, db): ('thirteen', 13, True)] -def test_insert_batch_replace(qtbot, db): - table = db.table('Foo', ['name', 'val', 'lucky'], +def test_insert_batch_replace(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky'], constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): @@ -191,8 +191,8 @@ def test_insert_batch_replace(qtbot, db): 'lucky': [True, True]}) -def test_iter(db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_iter(database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -211,15 +211,15 @@ def test_iter(db): ([{"a": 2, "b": 5}, {"a": 1, "b": 6}, {"a": 3, "b": 4}], 'a', 'asc', -1, [(1, 6), (2, 5), (3, 4)]), ]) -def test_select(rows, sort_by, sort_order, limit, result, db): - table = db.table('Foo', ['a', 'b']) +def test_select(rows, sort_by, sort_order, limit, result, database): + table = database.table('Foo', ['a', 'b']) for row in rows: table.insert(row) assert list(table.select(sort_by, sort_order, limit)) == result -def test_delete(qtbot, db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_delete(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -233,8 +233,8 @@ def test_delete(qtbot, db): assert not list(table) -def test_len(db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_len(database): + table = database.table('Foo', ['name', 'val', 'lucky']) assert len(table) == 0 table.insert({'name': 'one', 'val': 1, 'lucky': False}) assert len(table) == 1 @@ -244,15 +244,15 @@ def test_len(db): assert len(table) == 3 -def test_bool(db): - table = db.table('Foo', ['name']) +def test_bool(database): + table = database.table('Foo', ['name']) assert not table table.insert({'name': 'one'}) assert table -def test_bool_benchmark(benchmark, db): - table = db.table('Foo', ['number']) +def test_bool_benchmark(benchmark, database): + table = database.table('Foo', ['number']) # Simulate a history table table.create_index('NumberIndex', 'number') @@ -264,8 +264,8 @@ def test_bool_benchmark(benchmark, db): benchmark(run) -def test_contains(db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_contains(database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -285,8 +285,8 @@ def test_contains(db): assert not val_query.run(val=10).value() -def test_delete_all(qtbot, db): - table = db.table('Foo', ['name', 'val', 'lucky']) +def test_delete_all(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -301,118 +301,118 @@ def test_version(): class TestSqlQuery: - def test_prepare_error(self, db): + def test_prepare_error(self, database): with pytest.raises(sql.BugError) as excinfo: - db.query('invalid') + database.query('invalid') expected = ('Failed to prepare query "invalid": "near "invalid": ' 'syntax error Unable to execute statement"') assert str(excinfo.value) == expected @pytest.mark.parametrize('forward_only', [True, False]) - def test_forward_only(self, forward_only, db): - q = db.query('SELECT 0 WHERE 0', forward_only=forward_only) + def test_forward_only(self, forward_only, database): + q = database.query('SELECT 0 WHERE 0', forward_only=forward_only) assert q.query.isForwardOnly() == forward_only - def test_iter_inactive(self, db): - q = db.query('SELECT 0') + def test_iter_inactive(self, database): + q = database.query('SELECT 0') with pytest.raises(sql.BugError, match='Cannot iterate inactive query'): next(iter(q)) - def test_iter_empty(self, db): - q = db.query('SELECT 0 AS col WHERE 0') + def test_iter_empty(self, database): + q = database.query('SELECT 0 AS col WHERE 0') q.run() with pytest.raises(StopIteration): next(iter(q)) - def test_iter(self, db): - q = db.query('SELECT 0 AS col') + def test_iter(self, database): + q = database.query('SELECT 0 AS col') q.run() result = next(iter(q)) assert result.col == 0 - def test_iter_multiple(self, db): - q = db.query('VALUES (1), (2), (3);') + def test_iter_multiple(self, database): + q = database.query('VALUES (1), (2), (3);') res = list(q.run()) assert len(res) == 3 assert res[0].column1 == 1 - def test_run_binding(self, db): - q = db.query('SELECT :answer') + def test_run_binding(self, database): + q = database.query('SELECT :answer') q.run(answer=42) assert q.value() == 42 - def test_run_missing_binding(self, db): - q = db.query('SELECT :answer') + def test_run_missing_binding(self, database): + q = database.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run() - def test_run_batch(self, db): - q = db.query('SELECT :answer') + def test_run_batch(self, database): + q = database.query('SELECT :answer') q.run_batch(values={'answer': [42]}) assert q.value() == 42 - def test_run_batch_missing_binding(self, db): - q = db.query('SELECT :answer') + def test_run_batch_missing_binding(self, database): + q = database.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run_batch(values={}) - def test_value_missing(self, db): - q = db.query('SELECT 0 WHERE 0') + def test_value_missing(self, database): + q = database.query('SELECT 0 WHERE 0') q.run() with pytest.raises(sql.BugError, match='No result for single-result query'): q.value() - def test_num_rows_affected_not_active(self, db): + def test_num_rows_affected_not_active(self, database): with pytest.raises(AssertionError): - q = db.query('SELECT 0') + q = database.query('SELECT 0') q.rows_affected() - def test_num_rows_affected_select(self, db): + def test_num_rows_affected_select(self, database): with pytest.raises(AssertionError): - q = db.query('SELECT 0') + q = database.query('SELECT 0') q.run() q.rows_affected() @pytest.mark.parametrize('condition', [0, 1]) - def test_num_rows_affected(self, condition, db): - table = db.table('Foo', ['name']) + def test_num_rows_affected(self, condition, database): + table = database.table('Foo', ['name']) table.insert({'name': 'helloworld'}) - q = db.query(f'DELETE FROM Foo WHERE {condition}') + q = database.query(f'DELETE FROM Foo WHERE {condition}') q.run() assert q.rows_affected() == condition - def test_bound_values(self, db): - q = db.query('SELECT :answer') + def test_bound_values(self, database): + q = database.query('SELECT :answer') q.run(answer=42) assert q.bound_values() == {':answer': 42} class TestTransaction: - def test_successful_transaction(self, db): - my_table = db.table('my_table', ['column']) - with db.transaction(): + def test_successful_transaction(self, database): + my_table = database.table('my_table', ['column']) + with database.transaction(): my_table.insert({'column': 1}) my_table.insert({'column': 2}) db2 = QSqlDatabase.addDatabase('QSQLITE', 'db2') - db2.setDatabaseName(db.qt_database().databaseName()) + db2.setDatabaseName(database.qt_database().databaseName()) db2.open() query = QSqlQuery(db2) query.exec('select count(*) from my_table') query.next() assert query.record().value(0) == 0 - assert db.query('select count(*) from my_table').run().value() == 2 + assert database.query('select count(*) from my_table').run().value() == 2 - def test_failed_transaction(self, db): - my_table = db.table('my_table', ['column']) + def test_failed_transaction(self, database): + my_table = database.table('my_table', ['column']) try: - with db.transaction(): + with database.transaction(): my_table.insert({'column': 1}) my_table.insert({'column': 2}) raise Exception('something went horribly wrong') except Exception: pass - assert db.query('select count(*) from my_table').run().value() == 0 + assert database.query('select count(*) from my_table').run().value() == 0 -- cgit v1.2.3-54-g00ecf From 0c7b746a4ebfda0c8446558a56514b349aabdf41 Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 9 Jul 2021 01:10:36 -0300 Subject: Restore the sql fixture to close DBs after testing --- tests/helpers/fixtures.py | 14 +++++++++++--- tests/unit/browser/test_history.py | 36 +++++++++++++++--------------------- tests/unit/misc/test_sql.py | 6 ------ 3 files changed, 26 insertions(+), 30 deletions(-) (limited to 'tests') diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py index 3426e18b2..c09fbdc2c 100644 --- a/tests/helpers/fixtures.py +++ b/tests/helpers/fixtures.py @@ -673,13 +673,21 @@ def download_stub(win_registry, tmpdir, stubs): @pytest.fixture -def web_history(fake_save_manager, tmpdir, data_tmpdir, config_stub, stubs, +def database(data_tmpdir, request): + """Create a Database object.""" + name = request.node.get_closest_marker("db_name") or "history.db" + db = sql.Database(str(data_tmpdir / name)) + yield db + db.close() + + +@pytest.fixture +def web_history(fake_save_manager, tmpdir, database, config_stub, stubs, monkeypatch): """Create a WebHistory object.""" config_stub.val.completion.timestamp_format = '%Y-%m-%d' config_stub.val.completion.web_history.max_items = -1 - db = sql.Database(str(data_tmpdir / 'history.db')) - web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) monkeypatch.setattr(history, 'web_history', web_history) return web_history diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py index 4f1032254..7906d385c 100644 --- a/tests/unit/browser/test_history.py +++ b/tests/unit/browser/test_history.py @@ -368,15 +368,14 @@ class TestDump: class TestRebuild: - def test_user_version(self, data_tmpdir, stubs, monkeypatch): + def test_user_version(self, database, stubs, monkeypatch): """Ensure that completion is regenerated if user_version changes.""" - db = sql.Database(str(data_tmpdir / 'test_user_version.db')) - web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') - hist2 = history.WebHistory(db, progress=stubs.FakeHistoryProgress()) + hist2 = history.WebHistory(database, progress=stubs.FakeHistoryProgress()) assert list(hist2.completion) == [('example.com/1', '', 1)] monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) @@ -389,10 +388,9 @@ class TestRebuild: ] assert not hist3.metainfo['force_rebuild'] - def test_force_rebuild(self, data_tmpdir, stubs): + def test_force_rebuild(self, database, stubs): """Ensure that completion is regenerated if we force a rebuild.""" - db = sql.Database(str(data_tmpdir / 'test_user_version.db')) - web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') @@ -463,10 +461,9 @@ class TestRebuild: assert progress._started assert progress._finished - def test_interrupted(self, stubs, data_tmpdir, monkeypatch): + def test_interrupted(self, stubs, database, monkeypatch): """If we interrupt the rebuilding process, force_rebuild should still be set.""" - db = sql.Database(str(data_tmpdir / 'test_user_version.db')) - web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.completion.delete('url', 'example.com/1') progress = stubs.FakeHistoryProgress(raise_on_tick=True) @@ -487,9 +484,8 @@ class TestRebuild: class TestCompletionMetaInfo: @pytest.fixture - def metainfo(self, data_tmpdir): - db = sql.Database(str(data_tmpdir / 'TestCompletionMetaInfo.db')) - return history.CompletionMetaInfo(db) + def metainfo(self, database): + return history.CompletionMetaInfo(database) def test_contains_keyerror(self, metainfo): with pytest.raises(KeyError): @@ -512,28 +508,26 @@ class TestCompletionMetaInfo: metainfo['excluded_patterns'] = value assert metainfo['excluded_patterns'] == value - def test_recovery_no_key(self, caplog, data_tmpdir, stubs): - db = sql.Database(str(data_tmpdir / 'test_recovery_no_key.db')) - web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + def test_recovery_no_key(self, caplog, database, stubs): + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.metainfo.delete('key', 'force_rebuild') with pytest.raises(sql.BugError, match='No result for single-result query'): web_history.metainfo['force_rebuild'] with caplog.at_level(logging.WARNING): - web_history2 = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history2 = history.WebHistory(database, stubs.FakeHistoryProgress()) assert not web_history2.metainfo['force_rebuild'] - def test_recovery_no_table(self, caplog, data_tmpdir, stubs): - db = sql.Database(str(data_tmpdir / 'test_recovery_no_table.db')) - web_history = history.WebHistory(db, stubs.FakeHistoryProgress()) + def test_recovery_no_table(self, caplog, database, stubs): + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.metainfo.database.query("DROP TABLE CompletionMetaInfo").run() with pytest.raises(sql.BugError, match='no such table: CompletionMetaInfo'): web_history.metainfo['force_rebuild'] with caplog.at_level(logging.WARNING): - web_history2 = history.WebHistory(db, stubs.FakeHistoryProgress()) + web_history2 = history.WebHistory(database, stubs.FakeHistoryProgress()) assert not web_history2.metainfo['force_rebuild'] diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index 1262f0c3f..80ab7513c 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -31,12 +31,6 @@ from qutebrowser.misc import sql pytestmark = pytest.mark.usefixtures('data_tmpdir') -@pytest.fixture -def database(data_tmpdir): - db = sql.Database(str(data_tmpdir / 'test_sql.db')) - return db - - class TestUserVersion: @pytest.mark.parametrize('val, major, minor', [ -- cgit v1.2.3-54-g00ecf From 71a7674a706b73dfaac5958e9c3bca414c4e8665 Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 9 Jul 2021 10:06:24 -0300 Subject: Remove unused parameter and rename db --- tests/helpers/fixtures.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py index c09fbdc2c..cd3778b8a 100644 --- a/tests/helpers/fixtures.py +++ b/tests/helpers/fixtures.py @@ -673,10 +673,9 @@ def download_stub(win_registry, tmpdir, stubs): @pytest.fixture -def database(data_tmpdir, request): +def database(data_tmpdir): """Create a Database object.""" - name = request.node.get_closest_marker("db_name") or "history.db" - db = sql.Database(str(data_tmpdir / name)) + db = sql.Database(str(data_tmpdir / 'test.db')) yield db db.close() -- cgit v1.2.3-54-g00ecf