#!/usr/local/cpython-3.6/bin/python3 """Unit tests for portions of equivs3e.""" import sys import copy import functools import unittest.mock import equivs3e @functools.total_ordering class ComparableInt(object): # pylint: disable=too-few-public-methods """An int with a compare method.""" def __init__(self, value): """Initialize.""" self.value = value def compare(self, other): """Like 2.x's cmp.""" if self.value < other.value: return -1 elif self.value > other.value: return 1 else: return 0 def __eq__(self, other): """Return True iff self.value equals other.value.""" return self.value == other.value def __lt__(self, other): """Return True iff self.value is less than other.value.""" return self.value < other.value def __repr__(self): """Return a repr.""" return 'CI({})'.format(self.value) CI = ComparableInt def test_double_merge_sort(): """Test double_merge_sort.""" all_good = True unordered_list = [ CI(1), CI(2), CI(3), CI(4), CI(3), CI(5), CI(3), CI(2), CI(6), ] expected_result = [ [CI(1)], [CI(2), CI(2)], [CI(3), CI(3), CI(3)], [CI(4)], [CI(5)], [CI(6)] ] actual_result = equivs3e.double_merge_sort(verbosity=0, lst=unordered_list) if actual_result != expected_result: sys.stderr.write('{}: test_double_merge_sort: actual_result {} != expected_result {}\n'.format( sys.argv[0], actual_result, expected_result, )) all_good = False return all_good def test_merge_case_mosn(): """Test merge_or_start_new under normal conditions: merge case.""" all_good = True initial_result = [ [CI(1)], [CI(2), CI(2)], [CI(3)], ] actual_result = copy.deepcopy(initial_result) bucket = [CI(3)] equivs3e.merge_or_start_new(actual_result, bucket) expected_result = copy.deepcopy(initial_result) expected_result[-1].extend(bucket) if actual_result != expected_result: sys.stderr.write('{}: test_merge_case_mosn: actual_result {} != expected_result {}\n'.format( sys.argv[0], actual_result, expected_result, )) all_good = False return all_good def test_append_case_mosn(): """Test merge_or_start_new under normal conditions: append case.""" all_good = True initial_result = [ [CI(1)], [CI(2), CI(2)], [CI(3)], ] actual_result = copy.deepcopy(initial_result) bucket = [CI(4)] equivs3e.merge_or_start_new(actual_result, bucket) expected_result = copy.deepcopy(initial_result) expected_result.append(bucket) if actual_result != expected_result: sys.stderr.write('{}: test_append_case_mosn: actual_result {} != expected_result {}\n'.format( sys.argv[0], actual_result, expected_result, )) all_good = False return all_good def test_mosn_left_exc(): """ Test merge_or_start_new with a LeftException. We only test the merge case, because it's the only part that should be able to raise LeftException or RightException. """ all_good = True initial_result = [ [CI(1)], [CI(2), CI(2)], [CI(3)], ] actual_result = copy.deepcopy(initial_result) # We'll pretend that the first element of this list has an error during # comparison. The other 2 elements, we won't touch, even if they're "no # longer good". bucket = [CI(3), CI(3), CI(3)] expected_result = copy.deepcopy(actual_result) # expected_result[-1].append(CI(3)) # expected_result[-1].append(CI(3)) with unittest.mock.patch.object(ComparableInt, '__eq__', side_effect=equivs3e.LeftException): # This actually should leave bucket unchanged, and actual_result should # be extended by 2 CI(3)'s. equivs3e.merge_or_start_new(actual_result, bucket) if actual_result != expected_result: sys.stderr.write('{}: test_mosn_left_exc: actual_result {} != expected_result {}\n'.format( sys.argv[0], actual_result, expected_result, )) all_good = False return all_good def test_mosn_right_exc_w2(): """ Test merge_or_start_new with a RightException with 2 elements in result[-1]. We only test the merge case, because it's the only part that should be able to raise LeftException or RightException. """ all_good = True initial_result = [ [CI(1)], [CI(2), CI(2)], [CI(3), CI(3)], ] actual_result = copy.deepcopy(initial_result) bucket = [CI(3)] with unittest.mock.patch.object(ComparableInt, '__eq__', side_effect=equivs3e.RightException): # This should delete the leftmost CI(3), and add the new one, giving us # the same output as input. equivs3e.merge_or_start_new(actual_result, bucket) if initial_result != actual_result: sys.stderr.write('{}: test_mosn_right_exc_w2: initial_result {} != actual_result {}\n'.format( sys.argv[0], initial_result, actual_result, )) all_good = False return all_good def test_mosn_right_exc_w1(): """ Test merge_or_start_new with a RightException with 1 elements in result[-1]. We only test the merge case, because it's the only part that should be able to raise LeftException or RightException. """ all_good = True initial_result = [ [CI(1)], [CI(2), CI(2)], [CI(3)], ] actual_result = copy.deepcopy(initial_result) bucket = [CI(3)] with unittest.mock.patch.object(ComparableInt, '__eq__', side_effect=equivs3e.RightException): # This should delete the leftmost CI(3), and add the new one, giving us # the same output as input. equivs3e.merge_or_start_new(actual_result, bucket) if initial_result != actual_result: sys.stderr.write('{}: test_mosn_right_exc_w1: initial_result {} != actual_result {}\n'.format( sys.argv[0], initial_result, actual_result, )) all_good = False return all_good def main(): """Main function.""" all_good = True all_good &= test_double_merge_sort() all_good &= test_merge_case_mosn() all_good &= test_append_case_mosn() all_good &= test_mosn_left_exc() all_good &= test_mosn_right_exc_w1() all_good &= test_mosn_right_exc_w2() if all_good: sys.stderr.write('{}: All tests passed\n'.format(sys.argv[0])) sys.exit(0) else: sys.stderr.write('{}: One or more tests failed\n'.format(sys.argv[0])) sys.exit(1) main()