ads2_2022/code/python/tests/test_graphs/test_tarjan.py

99 lines
3.0 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from contextlib import nullcontext as does_not_raise
from collections import Counter;
from pytest import mark;
from pytest import fixture;
from pytest import lazy_fixture;
from unittest import TestCase;
from src.local.typing import *;
from src.graphs.graph import *;
from src.graphs.tarjan import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# FIXTURES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@fixture(scope='module')
def graph1() -> Graph:
return Graph(
nodes=[1,2,3,4],
edges=[(1,2), (2,4), (4,2)],
);
@fixture(scope='module')
def graph2() -> Graph:
return Graph(
nodes=[1,2,3,4,5,6,7],
edges=[(1,2), (1,3), (2,3), (3,4), (4,5), (5,2), (5,6), (5,7), (6,7)],
);
@fixture(scope='module')
def graph3() -> Graph:
return Graph(
nodes=[1,2,3,4,5,6,7,8],
edges=[
(1,2),
(1,3),
(2,4),
(2,5),
(3,5),
(3,6),
(3,8),
(4,5),
(4,7),
(5,1),
(5,8),
(6,8),
(7,8),
(8,6),
],
);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test Tarjan-Algorithm
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@mark.parametrize(
('G', 'expected'),
[
(lazy_fixture('graph1'), [[1], [3], [2,4]]),
(lazy_fixture('graph2'), [[1], [6], [7], [2,3,4,5]]),
(lazy_fixture('graph3'), [[1,2,3,4,5], [7], [6,8]]),
],
)
@mark.usefixtures('test')
def test_tarjan(test, G, expected):
components = tarjan_algorithm(G, False);
assert_components_eq(test, components, expected);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AUXILIARY METHODS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def assert_components_eq(test: TestCase, components1: list[list[Any]], components2: list[list[Any]]):
result = check_components_eq(test, components1, components2);
test.assertTrue(result);
def check_components_eq(test: TestCase, components1: list[list[Any]], components2: list[list[Any]]) -> bool:
if len(components1) != len(components2):
return False;
for component1 in components1:
found = False;
for component2 in components2:
try:
test.assertCountEqual(component1, component2);
found = True;
break;
except:
continue;
if not found:
return False;
return True;