StringListPy/stringlist_tests/test_stringlist.py
2025-02-15 20:42:57 -07:00

833 lines
23 KiB
Python

import unittest
from os import path, remove, environ
from typing_extensions import List
from stringlist import *
class StringListTests(unittest.TestCase):
def setUp(self):
pass
def test_can_construct(self):
list = StringList()
self.assertIsNotNone(list)
self.assertIs(list.count(), 0)
def test_count_works(self):
list = StringList()
expected = 0
actual = list.count()
self.assertEqual(expected, actual)
list.values.extend([1, 2, 3])
expected = 3
actual = list.count()
self.assertEqual(expected, actual)
def test_clear_works(self):
list = StringList()
list.values.extend([1, 2, 3])
self.assertNotEqual(len(list.values), 0)
list.clear()
self.assertEqual(len(list.values), 0)
def test_add_works(self):
list: StringList = StringList()
expected: List[str] = ["abc", "123"]
list.add(expected[0])
list.add(expected[1])
actual: List[str] = ["abc", "123"]
self.assertIsNotNone(list.values)
self.assertListEqual(expected, actual)
def test_save_and_load_from_file(self):
userprofile_path = environ.get("userprofile")
if not path.exists(userprofile_path):
raise Exception(f"Cannot find path ({userprofile_path})")
filename: str = path.abspath(path.join(userprofile_path, "testfile.txt"))
if path.exists(filename):
raise Exception(f"Test file already exists: ({filename})")
expected_lines: str = ["There once", "was a man", "from Kantuckeh"]
list1: StringList = StringList().add_strings(expected_lines)
list1.save_to_file(filename)
try:
list2: StringList = StringList()
list2.load_from_file(filename)
finally:
remove(filename)
#self.assertListEqual(list1.values, list2.values)
self.assertEqual(list2.count(), len(expected_lines))
self.assertEqual(list2.count(), 3)
self.assertEqual(list2.values[0], expected_lines[0]+"\n")
self.assertEqual(list2.values[1], expected_lines[1]+"\n")
self.assertEqual(list2.values[2], expected_lines[2]+"\n")
def test_strip_line_endings_after_load_from_file(self):
userprofile_path = environ.get("userprofile")
if not path.exists(userprofile_path):
raise Exception(f"Cannot find path ({userprofile_path})")
filename: str = path.abspath(path.join(userprofile_path, "testfile.txt"))
if path.exists(filename):
raise Exception(f"Test file already exists: ({filename})")
expected_lines: str = ["There once", "was a man", "from Kantuckeh"]
list1: StringList = StringList().add_strings(expected_lines)
list1.save_to_file(filename)
try:
list2: StringList = StringList()
list2.load_from_file(filename)
finally:
remove(filename)
list2.strip_line_endings()
self.assertListEqual(list1.values, list2.values)
def test_remove_with_single_item(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(4)
expected = [0, 1, 2, 3, 5, 6, 7, 8, 9]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_first_item(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(0)
expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_last_item(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(9)
expected = [0, 1, 2, 3, 4, 5, 6, 7, 8]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_first_three_items(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(0, 3)
expected = [3, 4, 5, 6, 7, 8, 9]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_last_three_items(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(7, 3)
expected = [0, 1, 2, 3, 4, 5, 6]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_middle_three_items(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(4, 3)
expected = [0, 1, 2, 3, 7, 8, 9]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_before_first_item(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(-1, 3)
# This is what actually happens.
expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This is what I REALLY wanted to happen. :/
#expected = [2, 3, 4, 5, 6, 7, 8, 9]
actual = list1.values
self.assertEqual(expected, actual)
def test_remove_beyond_last_item(self):
before = list(range(0, 10))
list1: StringList = StringList() \
.add_strings(before) \
.remove(9, 3)
#expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
expected = [0, 1, 2, 3, 4, 5, 6, 7, 8]
actual = list1.values
self.assertEqual(expected, actual)
def test_parse_empty(self):
list1: StringList = StringList()
list1.parse("")
self.assertEqual(1, list1.count())
def test_parse_single_token(self):
list1: StringList = StringList()
input = "A monkey's your uncle."
expected = [input]
list1.parse(input, ",")
actual = list1.values
self.assertEqual(len(actual), 1)
self.assertEqual(expected, actual)
def test_parse_multiple_tokens(self):
list1: StringList = StringList()
input = "A monkey's your uncle."
expected = ["A", "monkey's", "your", "uncle."]
list1.parse(input, " ")
actual = list1.values
self.assertListEqual(expected, actual)
self.assertEqual(4, len(actual))
def test_text_empty(self):
list1: StringList = StringList()
list1.clear()
expected = ""
actual = list1.text()
self.assertEqual(expected, actual)
self.assertEqual(0, len(actual))
def test_text_single_value(self):
list1: StringList = StringList()
input = "A monkey's your uncle."
list1.add(input)
expected = input
actual = list1.text()
self.assertEqual(expected, actual)
def test_text_multiple_values(self):
list1: StringList = StringList()
input = ["A", "monkey's", "your", "uncle."]
list1.add_strings(input)
expected = "A monkey's your uncle."
actual = list1.text(" ")
self.assertEqual(expected, actual)
def test_value_of_missing_key_is_handled(self):
list1: StringList = StringList()
list1.add("key=value")
encountered_expected_exception: bool = False
try:
list1.value_of_key("missing_key")
except KeyNotFoundException as e:
encountered_expected_exception = True
self.assertTrue(encountered_expected_exception)
def test_contains_key_missing_on_list_size_of_1(self):
list1: StringList = StringList()
list1.add("key=value")
actual: bool = list1.contains_key("missing")
self.assertFalse(actual)
def test_contains_key_missing_on_list_size_of_10(self):
list1: StringList = StringList()
list1.add_strings([f"key{i}=value{i}" for i in range(0, 10)])
actual: bool = list1.contains_key("missing")
self.assertFalse(actual)
def test_contains_key_missing_on_empty_list(self):
list1: StringList = StringList()
actual: bool = list1.contains_key("missing")
self.assertFalse(actual)
def test_contains_key_present_on_list_size_of_1(self):
list1: StringList = StringList()
list1.add("key=value")
actual: bool = list1.contains_key("key")
self.assertTrue(actual)
def test_contains_key_present_on_list_size_of_10(self):
list1: StringList = StringList()
list1.add_strings([f"key{i}=value{i}" for i in range(0, 10)])
actual: bool = list1.contains_key("key1")
self.assertTrue(actual)
def test_value_of_key(self):
list1: StringList = StringList()
list1.add("key=value")
expected = "value"
actual = list1.value_of_key("key")
self.assertEqual(expected, actual)
def test_all_keys_empty(self):
list1: StringList = StringList()
expected = []
actual = list1.all_keys()
self.assertEqual(expected, actual)
def test_all_keys(self):
list1: StringList = StringList()
list1.add_strings([f"key{i}=value{i}" for i in range(0, 3)])
expected = ["key0", "key1", "key2"]
actual = list1.all_keys()
self.assertListEqual(expected, actual)
def test_all_values_of_key(self):
list1: StringList = StringList()
list1.add_strings([f"key{i%2}=value{i}" for i in range(0, 10)])
expected = ["value0", "value2", "value4", "value6", "value8"]
actual = list1.all_values_of_key("key0")
self.assertListEqual(expected, actual)
def test_assign(self):
list1: StringList = StringList().add_strings([f"string {i}" for i in range(0, 3)])
list2: StringList = StringList()
list2.assign(list1)
self.assertListEqual(list1.values, list2.values)
def test_assign_empty(self):
list1: StringList = StringList()
list2: StringList = StringList().add_strings([f"string {i}" for i in range(0, 3)])
expected = []
list2.assign(list1)
actual = list2.values
self.assertListEqual(expected, actual)
def test_add_strings(self):
list1: StringList = StringList().add_strings([f"string {i}" for i in range(0, 3)])
list2: StringList = StringList().add_strings(["a", "b", "c"])
expected = ["a", "b", "c", "string 0", "string 1", "string 2"]
list2.add_string_list(list1)
actual = list2.values
self.assertEqual(6, list2.count())
self.assertEqual(expected, actual)
def test_add_strings_empty(self):
list1: StringList = StringList()
list2: StringList = StringList().add_strings(["a", "b", "c"])
expected = ["a", "b", "c"]
list2.add_string_list(list1)
actual = list2.values
self.assertEqual(3, list2.count())
self.assertEqual(expected, actual)
def test_clone_empty(self):
expected = []
list1: StringList = StringList()
list2: StringList = list1.clone()
actual = list2.values
self.assertEqual(expected, actual)
self.assertEqual(0, list2.count())
def test_clone(self):
expected = ["a", "b", "c"]
list1: StringList = StringList().add_strings(expected)
list2: StringList = list1.clone()
actual = list2.values
self.assertEqual(expected, actual)
def test_push(self):
list1: StringList = StringList()
self.assertEqual([], list1.values)
list1.push("a")
self.assertEqual(["a"], list1.values)
list1.push("b")
self.assertEqual(["a", "b"], list1.values)
list1.push("c")
self.assertEqual(["a", "b", "c"], list1.values)
def test_pop(self):
list1: StringList = StringList() \
.push("a") \
.push("b") \
.push("c")
value1 = list1.pop()
value2 = list1.pop()
value3 = list1.pop()
self.assertEqual(0, list1.count())
self.assertEqual(["c", "b", "a"], [value1, value2, value3])
def test_enqueue(self):
list1: StringList = StringList()
self.assertEqual([], list1.values)
list1.enqueue("a")
self.assertEqual(["a"], list1.values)
list1.enqueue("b")
self.assertEqual(["b", "a"], list1.values)
list1.enqueue("c")
self.assertEqual(["c", "b", "a"], list1.values)
def test_dequeue(self):
list1: StringList = StringList() \
.push("c") \
.push("b") \
.push("a")
value1 = list1.dequeue()
value2 = list1.dequeue()
value3 = list1.dequeue()
self.assertEqual(0, list1.count())
self.assertEqual(["a", "b", "c"], [value1, value2, value3])
def test_keep_sorted_property(self):
list1: StringList = StringList()
self.assertEqual(False, list1.keep_sorted)
list1.keep_sorted = True
self.assertEqual(True, list1.keep_sorted)
def test_keep_sorted_property(self):
list1: StringList = StringList()
self.assertEqual(False, list1.keep_sorted)
list1.keep_sorted = True
self.assertEqual(True, list1.keep_sorted)
def test_insertion_sort(self):
list1: StringList = StringList()
list1.keep_sorted = False
list1.values = [0, 1, 2, 3, 4, 5]
self.assertTrue(list1.is_sorted())
list1.reverse()
self.assertFalse(list1.is_sorted())
list1._insertionsort()
self.assertTrue(list1.is_sorted())
def test_reverse(self):
list1: StringList = StringList().add_strings([f"{i}" for i in range(0, 3)])
expected = ["2", "1", "0"]
list1.reverse()
actual = list1.values
self.assertEqual(expected, actual)
def test_is_sorted(self):
list1: StringList = StringList()
list1.keep_sorted = False
sorted1: bool = list1.is_sorted(list1._sort_comparer)
list1.add_strings([f"{chr(i+65)}" for i in range(0, 25)])
sorted2: bool = list1.is_sorted()
list1.reverse()
sorted3: bool = list1.is_sorted()
self.assertEqual(True, sorted1)
self.assertEqual(True, sorted2)
self.assertEqual(False, sorted3)
def test_shuffle(self):
list1: StringList = StringList()
list1.keep_sorted = False
ordered_list: List[str] = [f"{chr(i+65)}" for i in range(0, 25)]
list1.add_strings(ordered_list)
not_expected = ordered_list
list1.shuffle()
actual = list1.values
self.assertNotEqual(not_expected, actual)
def test_sort(self):
list1: StringList = StringList()
list1.keep_sorted = False
list1.add_strings([f"{i}" for i in range(0, 10000)])
list1.shuffle()
list1._quicksort(0, list1.count() - 1)
self.assertTrue(list1.is_sorted())
def test_numeric_comparer(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 15)])
comparer: StringComparer = AnonymousStringComparer(lambda left, right: int(left) - int(right))
expected = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"]
list1.sort(comparer)
actual = list1.values
self.assertEqual(expected, actual)
def test_lexical_comparer(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 15)])
expected = ["0", "1", "10", "11", "12", "13", "14", "2", "3", "4", "5", "6", "7", "8", "9"]
list1.sort()
actual = list1.values
self.assertEqual(expected, actual)
def test_binary_search_present_0_to_99(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 100)])
list1.keep_sorted = True
for j in range(0, 100):
i: int = list1.index_of(str(f"{j:03}"))
self.assertEqual(j, i, f"{j}")
def test_binary_search_present_0_to_98(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 99)])
list1.keep_sorted = True
for j in range(0, 99):
i: int = list1.index_of(str(f"{j:03}"))
self.assertEqual(j, i, f"{j}")
def test_binary_search_present_0_to_2(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 2)])
list1.keep_sorted = True
for j in range(0, 2):
i: int = list1.index_of(str(f"{j:03}"))
self.assertEqual(j, i, f"{j}")
def test_binary_search_present_0_to_1(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 1)])
list1.keep_sorted = True
for j in range(0, 1):
i: int = list1.index_of(str(f"{j:03}"))
self.assertEqual(j, i, f"{j}")
def test_binary_search_present_single_element(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 0)])
list1.keep_sorted = True
for j in range(0, 0):
i: int = list1.index_of(str(f"{j:03}"))
self.assertEqual(j, i, f"{j}")
def test_binary_search_missing_empty(self):
list1 = StringList()
list1.keep_sorted = True
i: int = list1.index_of("missing")
self.assertEqual(-1, i)
def test_binary_search_missing_0_to_99(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 100)])
list1.keep_sorted = True
for j in range(0, 100):
i: int = list1.index_of(f"{j:03}5")
self.assertEqual(-1, i, f"{j}")
def test_binary_search_missing_0_to_98(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 99)])
list1.keep_sorted = True
for j in range(0, 99):
i: int = list1.index_of(f"{j:03}5")
self.assertEqual(-1, i, f"{j}")
def test_binary_search_missing_0_to_2(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 2)])
list1.keep_sorted = True
for j in range(0, 2):
i: int = list1.index_of(f"{j:03}5")
self.assertEqual(-1, i, f"{j}")
def test_binary_search_missing_0_to_1(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 1)])
list1.keep_sorted = True
for j in range(0, 1):
i: int = list1.index_of(f"{j:03}5")
self.assertEqual(-1, i, f"{j}")
def test_binary_search_missing_single_element(self):
list1 = StringList().add_strings([f"{i:03}" for i in range(0, 0)])
list1.keep_sorted = True
for j in range(0, 0):
i: int = list1.index_of(f"{j:03}5")
self.assertEqual(-1, i, f"{j}")
def test_linear_search_empty(self):
list1 = StringList()
self.assertEqual(-1, list1.index_of(""))
self.assertEqual(-1, list1.index_of("missing"))
def test_linear_search_one_element(self):
list1 = StringList().add("1")
self.assertEqual(-1, list1.index_of(""))
self.assertEqual(-1, list1.index_of("missing"))
self.assertEqual(0, list1.index_of("1"))
def test_linear_search_five_elements(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
self.assertEqual(-1, list1.index_of(""))
self.assertEqual(-1, list1.index_of("missing"))
for j in range(0, 5):
self.assertEqual(j, list1.index_of(str(j)), f"{j}")
def test_swap(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
list1.swap(1, 3)
expected = ["0", "3", "2", "1", "4"]
actual = list1.values
self.assertEqual(expected, actual)
def test_to_dictionary(self):
list1 = StringList().add_strings([f"{i+1}={chr(i + 65)}" for i in range(0, 5)])
table1 = list1.to_dictionary()
self.assertEqual(5, len(table1))
self.assertEqual(table1["1"], "A")
self.assertEqual(table1["2"], "B")
self.assertEqual(table1["3"], "C")
self.assertEqual(table1["4"], "D")
self.assertEqual(table1["5"], "E")
def test_to_indexed_dictionary(self):
list1 = StringList().add_strings([f"{i+1}={chr(i + 65)}" for i in range(0, 5)])
table1 = list1.to_indexed_dictionary()
self.assertEqual(5, len(table1))
self.assertEqual(table1["1"], (0, "A"))
self.assertEqual(table1["2"], (1, "B"))
self.assertEqual(table1["3"], (2, "C"))
self.assertEqual(table1["4"], (3, "D"))
self.assertEqual(table1["5"], (4, "E"))
def test_indexer_read(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
for j in range(0, 5):
expected = str(j)
actual = list1[j]
self.assertEqual(expected, actual)
def test_indexer_write(self):
values = [f"{i}" for i in range(0, 5)]
list1 = StringList().add_strings(["", "", "", "", ""])
for j in range(0, 5):
expected = str(values[j])
list1[j] = expected
actual = list1.values[j]
self.assertNotEqual("", actual)
self.assertEqual(expected, actual, f"{j}")
def test_maintain_sort_add(self):
list1 = StringList(keep_sorted=True)
self.assertTrue(list1.is_sorted())
list1.add("c")
self.assertTrue(list1.is_sorted())
list1.add("b")
self.assertTrue(list1.is_sorted())
list1.add("a")
self.assertTrue(list1.is_sorted())
def test_maintain_sort_add_range(self):
list1 = StringList(keep_sorted=True)
list1.add_strings(["x", "y", "z"])
self.assertTrue(list1.is_sorted())
list1.add_strings(["c", "b", "a"])
self.assertTrue(list1.is_sorted())
def test_maintain_sort_enqueue(self):
list1 = StringList(keep_sorted=True)
self.assertTrue(list1.is_sorted())
list1.enqueue("a")
self.assertTrue(list1.is_sorted())
list1.enqueue("b")
self.assertTrue(list1.is_sorted())
list1.enqueue("c")
self.assertTrue(list1.is_sorted())
def test_maintain_sort_push(self):
list1 = StringList(keep_sorted=True)
self.assertTrue(list1.is_sorted())
list1.push("c")
self.assertTrue(list1.is_sorted())
list1.push("b")
self.assertTrue(list1.is_sorted())
list1.push("a")
self.assertTrue(list1.is_sorted())
def test_stack(self):
list1 = StringList()
list1.push("1")
self.assertListEqual(["1"], list1.values)
list1.push("2")
self.assertListEqual(["1", "2"], list1.values)
actual = list1.pop()
self.assertEqual("2", actual)
self.assertListEqual(["1"], list1.values)
actual = list1.pop()
self.assertEqual("1", actual)
self.assertListEqual([], list1.values)
def test_bottom_stack(self):
list1 = StringList()
list1.push_bottom("1")
self.assertListEqual(["1"], list1.values)
list1.push_bottom("2")
self.assertListEqual(["2", "1"], list1.values)
actual = list1.pop_bottom()
self.assertEqual("2", actual)
self.assertListEqual(["1"], list1.values)
actual = list1.pop_bottom()
self.assertEqual("1", actual)
self.assertListEqual([], list1.values)
def test_where(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 10)])
list1.where(lambda index, line: index % 2 == 0)
self.assertListEqual(["0", "2", "4", "6", "8"], list1.values)
def test_select(self):
base_values = [f"{i}" for i in range(0, 5)]
list1 = StringList().add_strings(base_values)
list1.select(lambda index, line: str(int(line) + 1))
expected = [f"{i+1}" for i in range(0, 5)]
actual = list1.values
self.assertListEqual(expected, actual)
def test_distinct(self):
input = ["a", "b", "c", "d", "b", "c"]
expected = ["a", "b", "c", "d"]
list1 = StringList().add_strings(input)
list1.distinct()
actual = list1.values
self.assertListEqual(expected, actual)
def test_union(self):
list_a = ["a", "b", "c", ]
list_b = ["b", "c", "d", "e"]
list1 = StringList().add_strings(list_a)
list1.union(list_b)
expected = ["a", "b", "c", "d", "e"]
actual = list1.values
self.assertListEqual(expected, actual)
def test_exclude(self):
list_a = ["a", "b", "c"]
list_b = ["b", "c", "d", "e"]
list1 = StringList().add_strings(list_a)
list1.exclude(list_b)
expected = ["a"]
actual = list1.values
self.assertListEqual(expected, actual)
def test_zip(self):
list_a = ["a", "b", "c"]
list_b = ["1", "2", "3"]
list1 = StringList().add_strings(list_a)
list1.zip(list_b, lambda index, left, right: f"{index}:({left},{right})")
#print(list1.values)
expected = ["0:(a,1)", "1:(b,2)", "2:(c,3)"]
actual = list1.values
self.assertListEqual(expected, actual)
def test_first(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
actual = list1.first()
expected = "0"
self.assertEqual(expected, actual)
def test_first_empty(self):
list1 = StringList()
actual = list1.first("default")
expected = "default"
self.assertEqual(expected, actual)
def test_last(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
actual = list1.last()
expected = "4"
self.assertEqual(expected, actual)
def test_last_empty(self):
list1 = StringList()
actual = list1.last("default")
expected = "default"
self.assertEqual(expected, actual)
def test_skip(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
actual = list1.skip().values
expected = ["1", "2", "3", "4"]
self.assertListEqual(expected, actual)
def test_skip_2(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
actual = list1.skip(2).values
expected = ["2", "3", "4"]
self.assertListEqual(expected, actual)
def test_take(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
actual = list1.take().values
expected = ["0"]
self.assertListEqual(expected, actual)
def test_take_2(self):
list1 = StringList().add_strings([f"{i}" for i in range(0, 5)])
actual = list1.take(2).values
expected = ["0", "1"]
self.assertListEqual(expected, actual)