Passed
Pull Request — master (#203)
by Jan
03:51
created

oval_graph.arf_xml_parser._test_info   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Test Coverage

Coverage 98.15%

Importance

Changes 0
Metric Value
wmc 45
eloc 134
dl 0
loc 164
ccs 106
cts 108
cp 0.9815
rs 8.8
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A _TestInfo._get_key_for_element() 0 3 2
A _TestInfo._get_system_data() 0 4 1
A _TestInfo._get_oval_system_characteristics() 0 4 1
A _TestInfo.__init__() 0 9 1
A _TestInfo._get_tests() 0 2 1
A _TestInfo._get_oval_definitions() 0 3 1
A _TestInfo._get_collected_objects() 0 4 1
A _TestInfo._get_objects() 0 4 1
A _TestInfo._get_dict_of_data() 0 3 1
A _TestInfo._xml_element_to_dict() 0 13 2
A _TestInfo._get_collected_objects_info() 0 15 4
A _TestInfo._get_ref_var() 0 13 5
A _TestInfo._get_item() 0 7 4
A _TestInfo._find_item_ref() 0 4 1
A _TestInfo._get_unique_key() 0 3 1
A _TestInfo._get_object_items() 0 9 4
A _TestInfo.get_info_about_test() 0 5 3
A _TestInfo._get_object_info() 0 4 1
A _TestInfo._get_tests_info() 0 15 4
A _TestInfo._get_unique_id_in_dict() 0 4 2
A _TestInfo._collected_object_is_not_none_and_contain_var_ref() 0 3 1
A _TestInfo._fix_message() 0 5 3

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