diff --git a/soitool/database.py b/soitool/database.py index 89ef947761d7a666a75937d60eb67150433f218f..c72c09b11f9d5735952fb25a1491babc99d5adfd 100644 --- a/soitool/database.py +++ b/soitool/database.py @@ -67,7 +67,7 @@ class Database: def fill_codebook(self): """Read data from codebook.json and fills DB-table CodeBook.""" - file_path = os.path.join(CURDIR, "testdata/codebook.json") + file_path = os.path.join(CURDIR, "testdata/long_codebook.json") # Load json as dict with open(file_path, "r") as file: entries = json.load(file) @@ -196,7 +196,7 @@ class Database: print("Code in CodeBook updated") - def add_code(self, word, mode="ascii"): + def add_code_to(self, word, mode="ascii"): """ Add a code to the new word. @@ -209,24 +209,29 @@ class Database: 'ascii' for letters (default), 'digits' for digits and 'combo' for combination of letters and digits. """ - # Get length of codes + # Get length of codes and calculate needed length of codes stmt = "SELECT COUNT(*) FROM CodeBook" number_of_entries = self.conn.execute(stmt).fetchall()[0][0] - # TODO ordet ligger alt inne så her er det feil - code_len = soitool.coder.get_code_length(number_of_entries) - # If adding a word makes the code longer, update whole CodeBook in db - if code_len < soitool.coder.get_code_length(number_of_entries + 1): + stmt = "SELECT Code FROM CodeBook" + # Incase db is approximate empty, min code lenght is 2 + if number_of_entries < 2: + actual_code_len = len(self.conn.execute(stmt).fetchall()[1][0]) + else: + actual_code_len = soitool.coder.get_code_length(0) + + needed_code_len = soitool.coder.get_code_length(number_of_entries) + + if actual_code_len < needed_code_len: self.update_codebook() else: - # Get all the used codes - stmt = "SELECT Code FROM CodeBook" - codes_li = self.conn.execute(stmt).fetchall() - codes_set = set([i[:][0] for i in codes_li]) - # Get new unique code - code = soitool.coder.get_code(code_len, mode) - while code in codes_set: - code = soitool.coder.get_code(code_len, mode) - # Update db with new code + # Get all codes and convert to set + codes = self.conn.execute(stmt).fetchall() + codes = set([i[:][0] for i in codes]) + # Get new unique code fro param word + code = soitool.coder.get_code(needed_code_len, mode) + while code in codes: + code = soitool.coder.get_code(needed_code_len, mode) + # Insert code to the param word in db stmt = "UPDATE CodeBook SET Code = ? WHERE Word = ?" self.conn.execute(stmt, (code, word)) diff --git a/test/test_database.py b/test/test_database.py index 1a5525e6c62506df1d16f747e82e86f7586d9c4f..dbd64c52e8ac2a07688f86663448165a09b10e35 100644 --- a/test/test_database.py +++ b/test/test_database.py @@ -83,7 +83,7 @@ class DatabaseTest(unittest.TestCase): def test_codebook(self): """Assert function get_codebook works as expected.""" # Get test-data from json - file_path = os.path.join(TESTDATA_PATH, "codebook.json") + file_path = os.path.join(TESTDATA_PATH, "long_codebook.json") with open(file_path, "r") as file: expected = json.load(file) file.close() @@ -129,20 +129,16 @@ class DatabaseTest(unittest.TestCase): def test_get_codebook(self): """Assert function get_codebook returns full codebook.""" # Load full codebook - file_path = os.path.join(TESTDATA_PATH, "codebook.json") + file_path = os.path.join(TESTDATA_PATH, "long_codebook.json") with open(file_path, "r") as file: expected = json.load(file) file.close() - # Get full codebook from db actual = self.database.get_codebook() - # Compare lenth self.assertEqual(len(expected), len(actual)) - # Get expected length of codes code_len = get_code_length(len(expected)) - # Compare contents for i, entry in enumerate(expected): self.assertEqual(entry["word"], actual[i]["word"]) @@ -153,26 +149,21 @@ class DatabaseTest(unittest.TestCase): def test_get_codebook_small(self): """Assert function get_codebook only return the small codebook.""" # Load full codebook - file_path = os.path.join(TESTDATA_PATH, "codebook.json") + file_path = os.path.join(TESTDATA_PATH, "long_codebook.json") with open(file_path, "r") as file: data = json.load(file) file.close() - # Fill expected with only small codebook entries expected = [] for entry in data: if entry["type"] == 1: expected.append(entry) - # Get small codebook from db actual = self.database.get_codebook(small=True) - # Compare lenght self.assertEqual(len(expected), len(actual)) - # Get expected length of codes code_len = get_code_length(len(expected)) - # Compare contents for i, entry in enumerate(expected): self.assertEqual(entry["word"], actual[i]["word"]) @@ -198,21 +189,52 @@ class DatabaseTest(unittest.TestCase): # Test that at least some of the test are new self.assertTrue(pairs < number_of_entries) + def test_code_length_extended_on_update(self): + """Test code length gets extended when number of entries makes it.""" + three_letter_len = 26 ** 2 + stmt_count = "SELECT COUNT(*) FROM CodeBook" + numb_of_entries = self.database.conn.execute(stmt_count).fetchall()[0][ + 0 + ] + # Codes only gets extended when number of entries pass 26**x + if numb_of_entries == (three_letter_len): + # Get length of current codes + stmt_code = "SELECT Code FROM CodeBook" + code_len = len( + self.database.conn.execute(stmt_code).fetchall()[0][0] + ) + self.assertEqual(2, code_len) + # Insert a entry to pass 26**2 entries + stmt = "INSERT INTO CodeBook (Word, Category, Code) VALUES (?,?,?)" + self.database.conn.execute(stmt, ("676", "676", None)) + self.database.update_codebook() + # Check that entry got inserted + numb_of_entries = self.database.conn.execute( + stmt_count + ).fetchall()[0][0] + self.assertEqual(numb_of_entries, three_letter_len + 1) + # Test that codes got extended length + code_len = len( + self.database.conn.execute(stmt_code).fetchall()[0][0] + ) + self.assertEqual(code_len, get_code_length(numb_of_entries)) + + else: + print("ERROR: Database is not 675 entries long, cant run test") + self.assertTrue(False) # pylint: disable=W1503 + def test_add_code(self): - """Test add a single code to CodeBook""" - testdata = ("testword", "testcategory") + """Test add a single code to CodeBook.""" + testdata = ("Testword", "Testcategory") stmt = "INSERT INTO CodeBook (Word, Category) VALUES (?,?)" self.database.conn.execute(stmt, (testdata[0], testdata[1])) - self.database.add_code(testdata[0]) + self.database.add_code_to(testdata[0]) stmt = "SELECT Code FROM CodeBook WHERE Word = ?" code = self.database.conn.execute(stmt, (testdata[0],)).fetchall()[0][ 0 ] self.assertRegex(code, "[A-Z0-9]") - def test_add_code_extending_code_length(self): - """Test all codes get updated when code lenght i changed.""" - if __name__ == "__main__": unittest.main()