1
0
mirror of https://github.com/wting/autojump synced 2024-10-27 20:34:07 +00:00

Fix #123, new installations were not initializing database properly.

Also added unit test coverage to check database initialization, saving, and
loading.  Unit tests also revealed that migration code was not working properly
(starts database from scratch instead of copying existing entries over).
This commit is contained in:
William Ting 2012-05-28 09:21:31 -10:00
parent b3c3253e89
commit b00e0e85e1
2 changed files with 98 additions and 22 deletions

View File

@ -81,6 +81,7 @@ class Database:
else:
import math
self.data[path] = math.sqrt((self.data[path]**2)+(increment**2))
self.save()
def decay(self):
"""
@ -102,34 +103,34 @@ class Database:
"""
Try to open the database file, recovering from backup if needed.
"""
try:
with open(self.filename, 'r') as aj_file:
for line in aj_file.readlines():
if os.path.exists(self.filename):
with open(self.filename, 'r') as f:
for line in f.readlines():
weight, path = line[:-1].split("\t", 1)
path = decode(path, 'utf-8')
self.data[path] = float(weight)
except (IOError, EOFError):
if not error_recovery and os.path.exists(self.filename + ".bak"):
elif os.path.exists(self.filename + '.bak'):
if not error_recovery:
print('Problem with autojump database,\
trying to recover from backup...', file=sys.stderr)
shutil.copy(self.filename + '.bak', self.filename)
return self.load(True)
else:
# TODO: migration code, will be removed in v22+
# autojump_py last used in v17
# migration code, autojump_py last used in v17
self.filename = get_db_file('autojump_py')
if os.path.exists(self.filename):
try: # fix to get optimised pickle in python < 3
import cPickle as pickle
except ImportError:
import pickle
try:
with open(self.filename, 'rb') as aj_file:
with open(self.filename, 'rb') as f:
# encoding is only specified for Python 2 compatibility
if sys.version_info[0] > 2:
self.data = pickle.load(aj_file, encoding="utf-8")
self.data = pickle.load(f, encoding="utf-8")
else:
self.data = pickle.load(aj_file)
self.data = pickle.load(f)
unicode_dict = {}
for k, v in self.data.items():
print(k)
@ -163,7 +164,8 @@ class Database:
def save(self):
"""
Save database atomically and preserve backup.
Save database atomically and preserve backup, creating new database if
needed.
"""
# check file existence and permissions
if ((not os.path.exists(self.filename)) or
@ -247,7 +249,6 @@ def options():
if(ARGS.add != os.path.expanduser("~")):
db = Database(DB_FILE)
db.add(decode(ARGS.add))
db.save()
return True
if (ARGS.purge):

View File

@ -6,10 +6,23 @@
from __future__ import division
import autojump
import contextlib
import random
import os
import shutil
import sys
import tempfile
import unittest
@contextlib.contextmanager
def no_stderr():
savestderr = sys.stderr
class DevNull(object):
def write(self, _): pass
sys.stderr = DevNull()
yield
sys.stderr = savestderr
# test suite
class TestAutojump(unittest.TestCase):
@ -18,6 +31,8 @@ class TestAutojump(unittest.TestCase):
self.fd, self.fname = tempfile.mkstemp()
self.db = autojump.Database(self.fname)
random.seed()
def tearDown(self):
os.remove(self.fname)
if os.path.isfile(self.fname + ".bak"):
@ -42,26 +57,86 @@ class TestAutojump(unittest.TestCase):
self.db.decay()
self.assertTrue(self.db.get_weight('/1') < 10)
def test_db_load_empty(self):
pass
def test_db_load_backup(self):
pass
def test_db_load_migrate(self):
pass
def test_db_load_existing(self):
self.db = autojump.Database('tests/database.txt')
self.assertTrue(len(self.db) > 0)
def test_db_load_empty(self):
# setup
_, fname = tempfile.mkstemp()
db = autojump.Database(fname)
try:
# test
self.assertEquals(len(self.db), 0)
finally:
# teardown
os.remove(fname)
def test_db_load_backup(self):
# setup
fname = '/tmp/autojump_test_db_load_backup_' + str(random.randint(0,32678))
db = autojump.Database(fname)
db.add('/1')
os.rename(fname, fname + '.bak')
try:
# test
with no_stderr():
db = autojump.Database(fname)
self.assertTrue(len(db.data) > 0)
self.assertTrue(os.path.isfile(fname))
finally:
# teardown
os.remove(fname)
os.remove(fname + '.bak')
def test_db_load_migrate(self):
ORIG_CONFIG_DIR = autojump.CONFIG_DIR
try:
# setup
CONFIG_DIR = '/tmp/autojump_test_db_load_migrate_' + str(random.randint(0,32678))
os.mkdir(CONFIG_DIR)
autojump.CONFIG_DIR = CONFIG_DIR
fname = CONFIG_DIR + '/autojump_py'
db = autojump.Database(fname)
db.add('/1')
shutil.copy(fname, fname + '.bak')
db.add('/2')
# test
missing_fname = '/tmp/autojump_test_db_load_missing_' + str(random.randint(0,32678)) + '.txt'
db = autojump.Database(missing_fname)
db.add('/3')
self.assertEquals(len(db.data), 3)
finally:
# teardown
shutil.rmtree(CONFIG_DIR)
os.remove(missing_fname)
os.remove(missing_fname + '.bak')
autojump.CONFIG_DIR = ORIG_CONFIG_DIR
def test_db_purge(self):
self.db.add('/1')
self.db.purge()
self.assertEquals(len(self.db), 0)
def test_db_save(self):
pass
# setup
fname = '/tmp/autojump_test_db_save_' + str(random.randint(0,32678)) + '.txt'
db = autojump.Database(fname)
try:
# test
db.save()
self.assertTrue(os.path.isfile(fname))
finally:
# teardown
os.remove(fname)
os.remove(fname + '.bak')
def test_db_trim(self):
self.db.add('/1')