Passed
Push — master ( 03a424...c63886 )
by Matěj
04:12 queued 13s
created

oval_graph.arf_xml_parser._test_info   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Test Coverage

Coverage 99.07%

Importance

Changes 0
Metric Value
eloc 133
dl 0
loc 163
ccs 106
cts 107
cp 0.9907
rs 8.8798
c 0
b 0
f 0
wmc 44

21 Methods

Rating   Name   Duplication   Size   Complexity  
A _TestInfo.get_info_about_test() 0 5 3
A _TestInfo._get_tests_info() 0 15 4
A _TestInfo._get_collected_objects_by_id() 0 4 1
A _TestInfo._get_collected_objects_info() 0 15 4
A _TestInfo._complete_message() 0 5 3
A _TestInfo._get_ref_var() 0 13 5
A _TestInfo._get_oval_system_characteristics() 0 4 1
A _TestInfo._get_item() 0 7 4
A _TestInfo._get_system_data_by_id() 0 4 1
A _TestInfo._find_item_ref() 0 4 1
A _TestInfo._get_data_by_id() 0 3 1
A _TestInfo._get_unique_key() 0 3 1
A _TestInfo._get_object_items() 0 9 4
A _TestInfo.__init__() 0 9 1
A _TestInfo._get_tests() 0 2 1
A _TestInfo._get_object_info() 0 15 2
A _TestInfo._get_unique_id_in_dict() 0 4 2
A _TestInfo._get_oval_definitions() 0 3 1
A _TestInfo._get_objects_by_id() 0 4 1
A _TestInfo._collected_object_is_not_none_and_contain_var_ref() 0 3 1
A _TestInfo._get_key_of_xml_element() 0 3 2

How to fix   Complexity   

Complexity

Complex classes like oval_graph.arf_xml_parser._test_info often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 1
import uuid
2
3 1
from .global_namespaces import namespaces
4
5 1
MAX_MESSAGE_LEN = 99
6
7
8 1
class _TestInfo:
9 1
    def __init__(self, report_data):
10 1
        self.report_data = report_data
11 1
        self.oval_definitions = self._get_oval_definitions()
12 1
        self.tests = self._get_tests()
13 1
        self.objects = self._get_objects_by_id()
14 1
        self.oval_system_characteristics = self._get_oval_system_characteristics()
15 1
        self.collected_objects = self._get_collected_objects_by_id()
16 1
        self.system_data = self._get_system_data_by_id()
17 1
        self.tests_info = self._get_tests_info()
18
19 1
    def _get_oval_system_characteristics(self):
20 1
        return self.report_data.find(
21
            ('.//XMLSchema:oval_results/XMLSchema:results/XMLSchema:system'
22
             '/oval-characteristics:oval_system_characteristics'), namespaces)
23
24 1
    @staticmethod
25
    def _get_data_by_id(data):
26 1
        return {item.attrib.get('id'): item for item in data}
27
28 1
    def _get_collected_objects_by_id(self):
29 1
        data = self.oval_system_characteristics.find(
30
            './/oval-characteristics:collected_objects', namespaces)
31 1
        return self._get_data_by_id(data)
32
33 1
    def _get_system_data_by_id(self):
34 1
        data = self.oval_system_characteristics.find(
35
            './/oval-characteristics:system_data', namespaces)
36 1
        return self._get_data_by_id(data)
37
38 1
    def _get_oval_definitions(self):
39 1
        return self.report_data.find(
40
            ('.//XMLSchema:oval_results/oval-definitions:oval_definitions'), namespaces)
41
42 1
    def _get_tests(self):
43 1
        return self.oval_definitions.find('.//oval-definitions:tests', namespaces)
44
45 1
    def _get_objects_by_id(self):
46 1
        data = self.oval_definitions.find(
47
            ('.//oval-definitions:objects'), namespaces)
48 1
        return self._get_data_by_id(data)
49
50 1
    @staticmethod
51
    def _get_key_of_xml_element(element):
52 1
        return element.tag.split('}')[1] if '}' in element.tag else element.tag
53
54 1
    @staticmethod
55
    def _find_item_ref(object_):
56 1
        list_of_item_ref = [item.get('item_ref') for item in object_]
57 1
        return list(filter(None, list_of_item_ref))
58
59 1
    @staticmethod
60
    def _get_unique_key(key):
61 1
        return key + '@' + str(uuid.uuid4())
62
63 1
    def _get_unique_id_in_dict(self, object_, dict_):
64 1
        if self._get_key_of_xml_element(object_) in dict_:
65 1
            return self._get_unique_key(self._get_key_of_xml_element(object_))
66 1
        return self._get_key_of_xml_element(object_)
67
68 1
    def _get_collected_objects_info(self, collected_object, object_):
69 1
        out = {}
70 1
        if len(collected_object) == 0:
71 1
            out[self._get_unique_id_in_dict(object_, out)
72
                ] = self._get_object_items(object_, collected_object)
73
        else:
74 1
            item_refs = self._find_item_ref(collected_object)
75 1
            if item_refs:
76 1
                for item_id in item_refs:
77 1
                    out[self._get_unique_id_in_dict(
78
                        object_, out)] = self._get_item(item_id)
79
            else:
80 1
                out[self._get_unique_id_in_dict(
81
                    object_, out)] = self._get_object_items(object_, collected_object)
82 1
        return out
83
84 1
    def _get_object_info(self, id_object):
85 1
        object_ = self.objects.get(id_object)
86 1
        collected_object = self.collected_objects.get(id_object)
87 1
        result = {}
88 1
        if collected_object is not None:
89 1
            result[
90
                collected_object.attrib.get('id')
91
            ] = collected_object.attrib.get('flag')
92 1
            result.update(
93
                self._get_collected_objects_info(collected_object, object_))
94
        else:
95 1
            result[object_.attrib.get('id')] = "does not exist"
96 1
            result[self._get_unique_id_in_dict(
97
                object_, result)] = self._get_object_items(object_, collected_object)
98 1
        return result
99
100 1
    def _get_object_items(self, object_, collected_object):
101 1
        out = {}
102 1
        for element in object_.iterchildren():
103 1
            if element.text and element.text.strip():
104 1
                out[self._get_unique_id_in_dict(element, out)] = element.text
105
            else:
106 1
                out[self._get_unique_id_in_dict(element, out)] = self._get_ref_var(
107
                    element, collected_object)
108 1
        return out
109
110 1
    def _get_ref_var(self, element, collected_object):
111 1
        variable_value = ''
112 1
        if self._collected_object_is_not_none_and_contain_var_ref(
113
                element, collected_object):
114 1
            var_id = element.attrib.get('var_ref')
115 1
            for item in collected_object:
116 1
                if var_id == item.attrib.get('variable_id'):
117 1
                    variable_value += item.text
118 1
                elif self._get_key_of_xml_element(item) == 'message':
119 1
                    variable_value += self._complete_message(item, var_id) + '<br>'
120
        else:
121 1
            variable_value = 'no value'
122 1
        return variable_value
123
124 1
    @staticmethod
125
    def _complete_message(item, var_id):
126 1
        if len(item.text) == MAX_MESSAGE_LEN and var_id[:item.text.find('(')] in var_id:
127 1
            return "{}{})".format(item.text[:item.text.find('(') + 1], var_id)
128 1
        return item.text
129
130 1
    @staticmethod
131
    def _collected_object_is_not_none_and_contain_var_ref(element, collected_object):
132 1
        return collected_object is not None and 'var_ref' in element.attrib
133
134 1
    def _get_item(self, item_ref):
135 1
        item = self.system_data.get(item_ref)
136 1
        out = {}
137 1
        for element in item.iterchildren():
138 1
            if element.text and element.text.strip():
139 1
                out[self._get_unique_id_in_dict(element, out)] = element.text
140 1
        return out
141
142 1
    def _get_tests_info(self):
143 1
        out = []
144 1
        for test in self.tests:
145 1
            objects = []
146 1
            for item in test:
147 1
                object_id = item.attrib.get('object_ref')
148 1
                if object_id:
149 1
                    objects.append(self._get_object_info(object_id))
150 1
            out.append(
151
                dict(
152
                    id=test.attrib.get('id'),
153
                    comment=test.attrib.get('comment'),
154
                    objects=objects,
155
                ))
156 1
        return out
157
158 1
    def get_info_about_test(self, id_of_test):
159 1
        for test in self.tests_info:
160 1
            if test['id'] == id_of_test:
161 1
                return test
162
        return None
163