test_color   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 152
Duplicated Lines 21.71 %

Importance

Changes 0
Metric Value
wmc 11
eloc 84
dl 33
loc 152
rs 10
c 0
b 0
f 0

9 Functions

Rating   Name   Duplication   Size   Complexity  
A test_color_hex() 0 7 1
A test_color_hex_error() 0 7 2
A test_node_color_mapping_no_node_types_in_graph() 0 13 1
A test_node_color_mapping_empty_graph() 0 9 1
A test_color_hex_compatibility_with_node_color_mapping_outputs() 0 17 2
A test_node_color_mapping_equivalence() 0 16 1
A test_node_color_mapping_filters_generic_node_type() 18 18 1
A test_node_color_mapping_multiple_types() 15 15 1
A test_node_color_mapping_with_only_generic_node_type() 0 14 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
import networkx as nx
2
import numpy as np
3
import pytest
4
5
from graphinate.color import color_hex, node_color_mapping
6
7
colors = [
8
    ([0, 0, 0], '#000000'),
9
    ([0.5, 0.5, 0.5], '#7f7f7f'),
10
    ([1, 1, 1], '#010101'),  # This is a list of ints, not floats
11
    ([2, 2, 2], '#020202'),
12
    ([50, 50, 50], '#323232'),
13
    ([100, 100, 100], '#646464'),
14
    ([128, 128, 128], '#808080'),
15
    ([255, 255, 255], '#ffffff'),
16
    ('Not a Sequence', 'Not a Sequence'),
17
]
18
19
20
@pytest.mark.parametrize(('color', 'expected_color_hex'), colors)
21
def test_color_hex(color, expected_color_hex):
22
    # Act
23
    actual_color_hex = color_hex(color)
24
25
    # Assert
26
    assert actual_color_hex == expected_color_hex
27
28
29
def test_color_hex_error():
30
    # Act & Assert
31
    with pytest.raises(
32
            ValueError,
33
            match='Input values should either be a float between 0 and 1 or an int between 0 and 255',
34
    ):
35
        _ = color_hex(['a', 'b', 'c'])
36
37
38
def test_node_color_mapping_empty_graph():
39
    # Arrange
40
    g = nx.Graph()
41
42
    # Act
43
    color_map = node_color_mapping(g)
44
45
    # Assert
46
    assert color_map == {}
47
48
49 View Code Duplication
def test_node_color_mapping_multiple_types():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
50
    # Arrange
51
    g = nx.Graph()
52
    g.graph['node_types'] = {'user': {}, 'post': {}}
53
    g.add_node('u1', type='user')
54
    g.add_node('u2', type='user')
55
    g.add_node('p1', type='post')
56
57
    # Act
58
    color_map = node_color_mapping(g)
59
60
    # Assert
61
    assert len(color_map) == 3
62
    assert np.array_equal(color_map['u1'], color_map['u2'])  # Same type, same color
63
    assert not np.array_equal(color_map['u1'], color_map['p1'])  # Different types, different colors
64
65
66 View Code Duplication
def test_node_color_mapping_filters_generic_node_type():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
67
    # Arrange
68
    g = nx.Graph()
69
    # The 'node' type should be ignored in color calculations if other types exist
70
    g.graph['node_types'] = {'user': {}, 'post': {}, 'node': {}}
71
    g.add_node('u1', type='user')
72
    g.add_node('p1', type='post')
73
    g.add_node('n1', type='node')  # This should get a default color
74
75
    # Act
76
    color_map = node_color_mapping(g)
77
78
    # Assert
79
    # 'user' and 'post' should have distinct colors
80
    assert not np.array_equal(color_map['u1'], color_map['p1'])
81
    # 'node' type should map to the first color in the sequence (same as 'user' in this case)
82
    # because 'user' will be at index 0 and 'post' at index 1 after filtering.
83
    assert np.array_equal(color_map['n1'], color_map['u1'])
84
85
86
def test_node_color_mapping_with_only_generic_node_type():
87
    # Arrange
88
    g = nx.Graph()
89
    # If 'node' is the only type, it should NOT be filtered
90
    g.graph['node_types'] = {'node': {}}
91
    g.add_node('n1', type='node')
92
    g.add_node('n2', type='node')
93
94
    # Act
95
    color_map = node_color_mapping(g)
96
97
    # Assert
98
    assert len(color_map) == 2
99
    assert np.array_equal(color_map['n1'], color_map['n2'])  # All nodes get the same color
100
101
102
def test_node_color_mapping_no_node_types_in_graph():
103
    # Arrange
104
    g = nx.Graph()
105
    g.add_node('u1', type='user')
106
    g.add_node('p1', type='post')
107
108
    # Act
109
    color_map = node_color_mapping(g)
110
111
    # Assert
112
    # Without `node_types`, all nodes get the default color (index 0)
113
    assert len(color_map) == 2
114
    assert np.array_equal(color_map['u1'], color_map['p1'])
115
116
117
def test_node_color_mapping_equivalence():
118
    # Arrange
119
    g = nx.Graph()
120
    g.graph['node_types'] = {'user': {}, 'post': {}, 'comment': {}}
121
    g.add_node('u1', type='user')
122
    g.add_node('u2', type='user')
123
    g.add_node('p1', type='post')
124
    g.add_node('c1', type='comment')
125
    g.add_node('n1')  # node with no type
126
127
    # Act
128
    color_map = node_color_mapping(g)
129
130
    # Assert
131
    assert set(color_map.keys()) == {'u2', 'u1', 'p1', 'n1', 'c1'}
132
    assert len({tuple(v) for v in color_map.values()}) == 3
133
134
135
def test_color_hex_compatibility_with_node_color_mapping_outputs():
136
    # Arrange
137
    g = nx.Graph()
138
    g.graph['node_types'] = {'user': {}, 'post': {}}
139
    g.add_node('u1', type='user')
140
    g.add_node('p1', type='post')
141
142
    # Act
143
    color_map = node_color_mapping(g)
144
145
    # Assert
146
    # Check that color_hex works for the new function's output
147
    for color in color_map.values():
148
        hex_color = color_hex(color)
149
        assert isinstance(hex_color, str)
150
        assert hex_color.startswith('#')
151
        assert len(hex_color) == 7
152