File size: 2,408 Bytes
a8784d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"""No-overlap / full-coverage invariant tests - the dataset's core guarantee."""
import numpy as np

from src.tearing import compute_adjacency, tear_page, verify_partition


def _page(h=400, w=300):
    rng = np.random.default_rng(0)
    return rng.integers(0, 255, size=(h, w, 3), dtype=np.uint8)


def test_partition_no_overlap_full_cover():
    torn = tear_page(_page(), n_pieces=12, seed=1,
                     noise_strength=20, noise_scale=60)
    rep = verify_partition(torn)
    assert rep["is_partition"], rep
    assert rep["max_overlap"] == 1
    assert rep["uncovered_pixels"] == 0


def test_piece_count_close_to_request():
    torn = tear_page(_page(), n_pieces=16, seed=2,
                     noise_strength=25, noise_scale=80)
    # Some seeds can lose their cell after warping; allow a small shortfall.
    assert 10 <= len(torn.pieces) <= 16


def test_per_page_randomness_changes():
    p = _page()
    a = tear_page(p, 12, seed=1, noise_strength=20, noise_scale=60).labels
    b = tear_page(p, 12, seed=2, noise_strength=20, noise_scale=60).labels
    assert not np.array_equal(a, b)


def test_reproducible_same_seed():
    p = _page()
    a = tear_page(p, 12, seed=5, noise_strength=20, noise_scale=60).labels
    b = tear_page(p, 12, seed=5, noise_strength=20, noise_scale=60).labels
    assert np.array_equal(a, b)


def test_adjacency_known_grid():
    # 3x3 label map: pieces 0,1,2 all mutually touch.
    labels = np.array([[0, 0, 1],
                       [0, 2, 1],
                       [2, 2, 1]], dtype=np.int32)
    adj = compute_adjacency(labels, {0: 0, 1: 1, 2: 2})
    assert adj == [(0, 1), (0, 2), (1, 2)]


def test_adjacency_invariants_on_real_page():
    torn = tear_page(_page(), n_pieces=16, seed=3,
                     noise_strength=25, noise_scale=80)
    n = len(torn.pieces)
    adj = torn.adjacency
    # undirected, deduped, sorted, in-range, no self-loops
    assert adj == sorted(set(adj))
    for i, j in adj:
        assert 0 <= i < j < n
    # partition over a connected page -> adjacency graph is connected
    seen = set()
    stack = [0]
    nbrs = {k: set() for k in range(n)}
    for i, j in adj:
        nbrs[i].add(j)
        nbrs[j].add(i)
    while stack:
        u = stack.pop()
        if u in seen:
            continue
        seen.add(u)
        stack.extend(nbrs[u] - seen)
    assert len(seen) == n          # every piece reachable