Repository: OpenSCAP/oval-graph (language: python)

Issue:
Improve storing the result of the OVAL tree
It will be a good idea to store the tree result in a different structure than the dictionary. Rename the items in the new structure to make them easier to understand. For example, `cnt_true` to `number_of_true`.


Discussion / hints:

Fix patch:
diff --git a/oval_graph/oval_tree/evaluate.py b/oval_graph/oval_tree/evaluate.py
deleted file mode 100644
index 2298d49e..00000000
--- a/oval_graph/oval_tree/evaluate.py
+++ /dev/null
@@ -1,314 +0,0 @@
-"""
-    Function for evaluate OVAL operators.
-"""
-
-
-def oval_operator_and(result):
-    """The AND operator produces a true result if every argument is true. If one or more arguments
-       are false, the result of the AND is false. If one or more of the arguments are unknown, and
-       if none of the arguments are false, then the AND operator produces a result of unknown.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            str. return values::
-
-                true
-                false
-                error
-                unknown
-                noteval
-    """
-    out_result = None
-    eval_eq_zero = eq_zero(result, 'false_cnt')
-    eval_greater_zero = greater_zero(result, 'true_cnt')
-    if eval_eq_zero and eval_greater_zero and error_unknown_noteval_eq_zero(result):
-        out_result = 'true'
-    elif greater_zero(result, 'false_cnt'):
-        out_result = 'false'
-    else:
-        out_result = error_unknown_noteval_for_operators_and_or(result, 'and')
-    return out_result
-
-
-def oval_operator_one(result):
-    """The ONE operator produces a true result if one and only one argument is true. If there are
-       more than argument is true (or if there are no true arguments), the result of the ONE
-       is false. If one or more of the arguments are unknown, then the ONE operator produces
-       a result of unknown.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            str. return values::
-
-                true
-                false
-                error
-                unknown
-                noteval
-    """
-    out_result = None
-    if one_is_true(result):
-        out_result = 'true'
-    elif one_is_false(result):
-        out_result = 'false'
-    elif one_is_error(result):
-        out_result = 'error'
-    elif one_is_unknown(result):
-        out_result = 'unknown'
-    elif one_is_noteval(result):
-        out_result = 'noteval'
-    return out_result
-
-
-def oval_operator_or(result):
-    """The OR operator produces a true result if one or more arguments is true. If every argument
-       is false, the result of the OR is false. If one or more of the arguments are unknown and
-       if none of arguments are true, then the OR operator produces a result of unknown.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            str. return values::
-
-                true
-                false
-                error
-                unknown
-                noteval
-    """
-    out_result = None
-    eval_eq_zero = eq_zero(result, 'true_cnt')
-    eval_greater_zero = greater_zero(result, 'false_cnt')
-    if greater_zero(result, 'true_cnt'):
-        out_result = 'true'
-    elif eval_eq_zero and eval_greater_zero and error_unknown_noteval_eq_zero(result):
-        out_result = 'false'
-    else:
-        out_result = error_unknown_noteval_for_operators_and_or(result, 'or')
-    return out_result
-
-
-def oval_operator_xor(result):
-    """XOR is defined to be true if an odd number of its arguments are true, and false otherwise.
-       If any of the arguments are unknown, then the XOR operator produces a result of unknown.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            str. return values::
-
-                true
-                false
-                error
-                unknown
-                noteval
-    """
-    out_result = None
-    eval_error_cnt = eq_zero(result, 'error_cnt')
-    eval_unknown_cnt = eq_zero(result, 'unknown_cnt')
-    if (result['true_cnt'] % 2) == 1 and eq_zero_unknown_noteval_notappl(result):
-        out_result = 'true'
-    elif (result['true_cnt'] % 2) == 0 and eq_zero_unknown_noteval_notappl(result):
-        out_result = 'false'
-    elif greater_zero(result, 'error_cnt'):
-        out_result = 'error'
-    elif eq_zero(result, 'error_cnt') and greater_zero(result, 'unknown_cnt'):
-        out_result = 'unknown'
-    elif eval_error_cnt and eval_unknown_cnt and greater_zero(result, 'noteval_cnt'):
-        out_result = 'noteval'
-    return out_result
-
-
-def error_unknown_noteval_for_operators_and_or(result, operator):
-    """Evaluates if the result match the values for error, unknown, noteval.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-            operator (str): Specifies for which operator is used
-
-    Returns:
-            str or None. return values::
-
-                error
-                unknown
-                notappl
-    """
-    out_result = None
-    value_for_check = 'false_cnt' if operator == 'and' else 'true_cnt'
-    if eq_zero(result, value_for_check) and greater_zero(result, 'error_cnt'):
-        out_result = 'error'
-    elif eq_zero(result, value_for_check) and error_unknown_eq_zero(result):
-        out_result = 'unknown'
-    elif eq_zero(result, value_for_check) and error_unknown_eq_noteval_greater_zero(result):
-        out_result = 'noteval'
-    return out_result
-
-
-def eq_zero(result, cnt):
-    return result[cnt] == 0
-
-
-def eq_zero_duo(result, cnt0, cnt1):
-    return result[cnt0] == 0 and result[cnt1] == 0
-
-
-def greater_zero(result, cnt):
-    return result[cnt] > 0
-
-
-def eq_or_greater_zero(result, cnt):
-    return result[cnt] >= 0
-
-
-def eq_or_greater_zero_duo(result, cnt0, cnt1):
-    return result[cnt0] >= 0 and result[cnt1] >= 0
-
-
-def smaller_than_two(result, cnt):
-    return result[cnt] < 2
-
-
-def one_is_noteval(result):
-    """Evaluates if the result match noteval for one operator.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            bool.
-    """
-    true_cnt = smaller_than_two(result, 'true_cnt')
-    false_cnt_notappl_cnt = eq_or_greater_zero_duo(result, 'false_cnt', 'notappl_cnt')
-    error_cnt_unknown_cnt = eq_zero_duo(result, 'error_cnt', 'unknown_cnt')
-    noteval_cnt = greater_zero(result, 'noteval_cnt')
-    return true_cnt and false_cnt_notappl_cnt and error_cnt_unknown_cnt and noteval_cnt
-
-
-def one_is_unknown(result):
-    """Evaluates if the result match unknown for one operator.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            bool.
-    """
-    true_cnt = smaller_than_two(result, 'true_cnt')
-    false_cnt = eq_or_greater_zero(result, 'false_cnt')
-    error_cnt = eq_zero(result, 'error_cnt')
-    unknown_cnt = result['unknown_cnt'] >= 1
-    noteval_cnt_notappl_cnt = eq_or_greater_zero_duo(result, 'noteval_cnt', 'notappl_cnt')
-    return true_cnt and false_cnt and error_cnt and unknown_cnt and noteval_cnt_notappl_cnt
-
-
-def one_is_error(result):
-    """Evaluates if the result match unknown for one operator.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            bool.
-    """
-    true_cnt = smaller_than_two(result, 'true_cnt')
-    false_cnt = eq_or_greater_zero(result, 'false_cnt')
-    error_cnt = greater_zero(result, 'error_cnt')
-    unknown_noteval_notappl = eq_or_greater_zero_unknown_noteval_notappl(result)
-    return true_cnt and false_cnt and error_cnt and unknown_noteval_notappl
-
-
-def one_is_false(result):
-    """Evaluates if the result match false for one operator.
-       Operator ONE has two cases of false state.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            bool.
-    """
-    # The first case for false
-    true_cnt = eq_zero(result, 'true_cnt')
-    false_cnt = eq_or_greater_zero(result, 'false_cnt')
-    unknown_noteval_cnt = error_unknown_noteval_eq_zero(result)
-    notappl_cnt = result['notappl_cnt'] >= 0
-
-    first_case = true_cnt and false_cnt and unknown_noteval_cnt and notappl_cnt
-
-    # The second case for false
-    true_cnt = result['true_cnt'] >= 2
-    false_error_cnt = eq_or_greater_zero_duo(result, 'false_cnt', 'error_cnt')
-    unknown_noteval_notappl = eq_or_greater_zero_unknown_noteval_notappl(result)
-    second_case = true_cnt and false_error_cnt and unknown_noteval_notappl
-
-    return first_case or second_case
-
-
-def one_is_true(result):
-    """Evaluates if the result match true for one operator.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            bool.
-    """
-    true_cnt = result['true_cnt'] == 1
-    false_notappl_cnt = eq_or_greater_zero_duo(result, 'false_cnt', 'notappl_cnt')
-    unknown_noteval_cnt = error_unknown_noteval_eq_zero(result)
-    return true_cnt and false_notappl_cnt and unknown_noteval_cnt
-
-
-def eq_or_greater_zero_unknown_noteval_notappl(result):
-    unknown_cnt = eq_or_greater_zero(result, 'unknown_cnt')
-    noteval_cnt = eq_or_greater_zero(result, 'noteval_cnt')
-    notappl_cnt = eq_or_greater_zero(result, 'notappl_cnt')
-    return unknown_cnt and notappl_cnt and noteval_cnt
-
-
-def eq_zero_unknown_noteval_notappl(result):
-    error_cnt = eq_zero(result, 'error_cnt')
-    unknown_cnt = eq_zero(result, 'unknown_cnt')
-    noteval_cnt = eq_zero(result, 'noteval_cnt')
-    return error_cnt and unknown_cnt and noteval_cnt
-
-
-def error_unknown_noteval_eq_zero(result):
-    error_cnt = eq_zero(result, 'error_cnt')
-    unknown_cnt = eq_zero(result, 'unknown_cnt')
-    noteval_cnt = eq_zero(result, 'noteval_cnt')
-    return error_cnt and unknown_cnt and noteval_cnt
-
-
-def error_unknown_eq_noteval_greater_zero(result):
-    error_cnt = eq_zero(result, 'error_cnt')
-    unknown_cnt = eq_zero(result, 'unknown_cnt')
-    noteval_cnt = greater_zero(result, 'noteval_cnt')
-    return error_cnt and unknown_cnt and noteval_cnt
-
-
-def error_unknown_eq_zero(result):
-    return eq_zero(result, 'error_cnt') and greater_zero(result, 'unknown_cnt')
-
-
-def is_notapp_result(result):
-    """Evaluates if the counts of values in
-       the result matches the notapp result.
-
-    Args:
-            result (dict): Dictionary storing occurrence of given values
-
-    Returns:
-            bool.
-     """
-    notappl_cnt = result['notappl_cnt'] > 0
-    false_cnt = eq_zero(result, 'false_cnt')
-    unknown_noteval_cnt = error_unknown_noteval_eq_zero(result)
-    true_cnt = eq_zero(result, 'true_cnt')
-    return notappl_cnt and false_cnt and unknown_noteval_cnt and true_cnt
diff --git a/oval_graph/oval_tree/oval_node.py b/oval_graph/oval_tree/oval_node.py
index ec8830ec..1ad85447 100644
--- a/oval_graph/oval_tree/oval_node.py
+++ b/oval_graph/oval_tree/oval_node.py
@@ -1,7 +1,17 @@
-from . import evaluate
+from collections import Counter
+
+from .oval_result import OvalResult
 
 ALLOWED_VALUES = ("true", "false", "error", "unknown", "noteval", "notappl")
 ALLOWED_OPERATORS = ("or", "and", "one", "xor")
+EMPTY_RESULT = {
+    "number_of_true": 0,
+    "number_of_false": 0,
+    "number_of_error": 0,
+    "number_of_unknown": 0,
+    "number_of_noteval": 0,
+    "number_of_notappl": 0
+}
 
 
 class OvalNode():
@@ -103,50 +113,43 @@ def add_child(self, node):
             "The value node cannot contain any child!")
 
     def _get_result_counts(self):
-        result = {
-            'true_cnt': 0,
-            'false_cnt': 0,
-            'error_cnt': 0,
-            'unknown_cnt': 0,
-            'noteval_cnt': 0,
-            'notappl_cnt': 0
-        }
-
+        result = Counter(EMPTY_RESULT)
         for child in self.children:
-            if child.value == 'true' and not child.negation:
-                result['true_cnt'] += 1
-            elif child.value == 'true' and child.negation:
-                result['false_cnt'] += 1
-            elif child.value == 'false' and not child.negation:
-                result['false_cnt'] += 1
-            elif child.value == 'false' and child.negation:
-                result['true_cnt'] += 1
+            if child.value == "true" and not child.negation:
+                result["number_of_true"] += 1
+            elif child.value == "true" and child.negation:
+                result["number_of_false"] += 1
+            elif child.value == "false" and not child.negation:
+                result["number_of_false"] += 1
+            elif child.value == "false" and child.negation:
+                result["number_of_true"] += 1
             else:
                 if child.node_type == "operator":
-                    result[child.evaluate_tree() + "_cnt"] += 1
+                    result["number_of_" + child.evaluate_tree()] += 1
                 else:
-                    result[child.value + "_cnt"] += 1
+                    result["number_of_" + child.value] += 1
         return result
 
     def evaluate_tree(self):
-        result = self._get_result_counts()
+        results_counts = self._get_result_counts()
+        oval_result = OvalResult(**results_counts)
         out_result = None
-        if evaluate.is_notapp_result(result):
+        if oval_result.is_notapp_result():
             out_result = "notappl"
         else:
             if self.value == "or":
-                out_result = evaluate.oval_operator_or(result)
+                out_result = oval_result.eval_operator_or()
             elif self.value == "and":
-                out_result = evaluate.oval_operator_and(result)
+                out_result = oval_result.eval_operator_and()
             elif self.value == "one":
-                out_result = evaluate.oval_operator_one(result)
+                out_result = oval_result.eval_operator_one()
             elif self.value == "xor":
-                out_result = evaluate.oval_operator_xor(result)
+                out_result = oval_result.eval_operator_xor()
 
-        if out_result == 'true' and self.negation:
-            out_result = 'false'
-        elif out_result == 'false' and self.negation:
-            out_result = 'true'
+        if out_result == "true" and self.negation:
+            out_result = "false"
+        elif out_result == "false" and self.negation:
+            out_result = "true"
 
         return out_result
 
diff --git a/oval_graph/oval_tree/oval_result.py b/oval_graph/oval_tree/oval_result.py
new file mode 100644
index 00000000..8ccf0589
--- /dev/null
+++ b/oval_graph/oval_tree/oval_result.py
@@ -0,0 +1,277 @@
+from typing import NamedTuple
+
+
+class OvalResult(NamedTuple):
+    number_of_true: int = 0
+    number_of_false: int = 0
+    number_of_error: int = 0
+    number_of_unknown: int = 0
+    number_of_noteval: int = 0
+    number_of_notappl: int = 0
+
+    def eval_operator_and(self):
+        """
+        The AND operator produces a true result if every argument is true. If one or more arguments
+        are false, the result of the AND is false. If one or more of the arguments are unknown, and
+        if none of the arguments are false, then the AND operator produces a result of unknown.
+
+        Returns:
+                str. return values::
+
+                    true
+                    false
+                    error
+                    unknown
+                    noteval
+        """
+        out_result = None
+        false_eq_zero = self.number_of_false == 0
+        true_gt_zero = self.number_of_true > 0
+        if true_gt_zero and false_eq_zero and self._error_unknown_noteval_eq_zero():
+            out_result = 'true'
+        elif self.number_of_false >= 1:
+            out_result = 'false'
+        else:
+            out_result = self._eval_error_unknown_noteval_for_operators_and_or('and')
+        return out_result
+
+    def eval_operator_one(self):
+        """
+        The ONE operator produces a true result if one and only one argument is true. If there are
+        more than argument is true (or if there are no true arguments), the result of the ONE
+        is false. If one or more of the arguments are unknown, then the ONE operator produces
+        a result of unknown.
+
+        Returns:
+            str. return values::
+
+                true
+                false
+                error
+                unknown
+                noteval
+        """
+        out_result = None
+        if self._one_is_true():
+            out_result = 'true'
+        elif self._one_is_false():
+            out_result = 'false'
+        elif self._one_is_error():
+            out_result = 'error'
+        elif self._one_is_unknown():
+            out_result = 'unknown'
+        elif self._one_is_noteval():
+            out_result = 'noteval'
+        return out_result
+
+    def _one_is_noteval(self):
+        """Evaluates if the result match noteval for one operator.
+
+        Returns:
+                bool.
+        """
+        true_lt_two = self.number_of_true < 2
+
+        false_ge_zero = self.number_of_false >= 0
+        notappl_ge_zero = self.number_of_notappl >= 0
+
+        noteval_ge_one = self.number_of_noteval >= 1
+
+        error_eq_zero = self.number_of_error == 0
+        unknown_eq_zero = self.number_of_unknown == 0
+
+        false_notappl_ge_zero = false_ge_zero and notappl_ge_zero
+        error_unknown_eq_zero = error_eq_zero and unknown_eq_zero
+        return true_lt_two and false_notappl_ge_zero and noteval_ge_one and error_unknown_eq_zero
+
+    def _one_is_unknown(self):
+        """Evaluates if the result match unknown for one operator.
+
+        Returns:
+                bool.
+        """
+        true_lt_two = self.number_of_true < 2
+
+        false_ge_zero = self.number_of_false >= 0
+        notappl_ge_zero = self.number_of_notappl >= 0
+        noteval_ge_zero = self.number_of_noteval >= 0
+
+        error_eq_zero = self.number_of_error == 0
+
+        unknown_ge_one = self.number_of_unknown >= 1
+
+        false_notappl_noteval_ge_zero = false_ge_zero and notappl_ge_zero and noteval_ge_zero
+        return true_lt_two and false_notappl_noteval_ge_zero and error_eq_zero and unknown_ge_one
+
+    def _one_is_error(self):
+        """Evaluates if the result match unknown for one operator.
+
+        Returns:
+                bool.
+        """
+        true_lt_two = self.number_of_true < 2
+
+        false_ge_zero = self.number_of_false >= 0
+
+        error_ge_one = self.number_of_error >= 1
+
+        unknown_noteval_notappl_ge_zero = self._unknown_noteval_notappl_ge_zero()
+        return true_lt_two and false_ge_zero and error_ge_one and unknown_noteval_notappl_ge_zero
+
+    def _one_is_false(self):
+        """
+        Evaluates if the result match false for one operator.
+        Operator ONE has two cases of false state.
+
+        Returns:
+                bool.
+        """
+        # The first case for false
+        true_ge_two = self.number_of_true >= 2
+        false_ge_zero = self.number_of_false >= 0
+        error_ge_zero = self.number_of_error >= 0
+        unknown_noteval_notappl_ge_zero = self._unknown_noteval_notappl_ge_zero()
+
+        false_error_ge_zero = false_ge_zero and error_ge_zero
+
+        first_case = true_ge_two and false_error_ge_zero and unknown_noteval_notappl_ge_zero
+
+        # The second case for false
+        true_eq_zero = self.number_of_true == 0
+        false_ge_one = self.number_of_false >= 1
+        notappl_ge_zero = self.number_of_notappl >= 0
+        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
+
+        true_error_unknown_noteval_eq_zero = true_eq_zero and error_unknown_noteval_eq_zero
+
+        second_case = true_error_unknown_noteval_eq_zero and false_ge_one and notappl_ge_zero
+
+        return first_case or second_case
+
+    def _one_is_true(self):
+        """
+        Evaluates if the result match true for one operator.
+
+        Returns:
+                bool.
+        """
+        true_eq_one = self.number_of_true == 1
+        false_ge_zero = self.number_of_false >= 0
+        notappl_ge_zero = self.number_of_notappl >= 0
+        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
+
+        false_notappl_ge_zero = false_ge_zero and notappl_ge_zero
+        return true_eq_one and error_unknown_noteval_eq_zero and false_notappl_ge_zero
+
+    def eval_operator_or(self):
+        """
+        The OR operator produces a true result if one or more arguments is true. If every argument
+        is false, the result of the OR is false. If one or more of the arguments are unknown and
+        if none of arguments are true, then the OR operator produces a result of unknown.
+
+        Returns:
+            str. return values::
+
+                true
+                false
+                error
+                unknown
+                noteval
+        """
+        out_result = None
+        true_eq_zero = self.number_of_true == 0
+        false_ge_one = self.number_of_false >= 1
+        if self.number_of_true >= 1:
+            out_result = 'true'
+        elif true_eq_zero and false_ge_one and self._error_unknown_noteval_eq_zero():
+            out_result = 'false'
+        else:
+            out_result = self._eval_error_unknown_noteval_for_operators_and_or('or')
+        return out_result
+
+    def eval_operator_xor(self):
+        """
+        XOR is defined to be true if an odd number of its arguments are true, and false otherwise.
+        If any of the arguments are unknown, then the XOR operator produces a result of unknown.
+
+        Returns:
+            str. return values::
+
+                true
+                false
+                error
+                unknown
+                noteval
+        """
+        out_result = None
+        error_eq_zero = self.number_of_error == 0
+        unknown_eq_zero = self.number_of_unknown == 0
+        is_number_of_true_even = (self.number_of_true % 2) == 0
+        if not is_number_of_true_even and self._error_unknown_noteval_eq_zero():
+            out_result = 'true'
+        elif is_number_of_true_even and self._error_unknown_noteval_eq_zero():
+            out_result = 'false'
+        elif self.number_of_error >= 1:
+            out_result = 'error'
+        elif error_eq_zero and self.number_of_unknown >= 1:
+            out_result = 'unknown'
+        elif error_eq_zero and unknown_eq_zero and self.number_of_noteval >= 1:
+            out_result = 'noteval'
+        return out_result
+
+    def _eval_error_unknown_noteval_for_operators_and_or(self, operator):
+        """
+        Evaluates if the operator result match the values for error, unknown, noteval.
+
+        Args:
+            operator (str): Specifies for which operator is used
+
+        Returns:
+            str or None. return values::
+
+                error
+                unknown
+                noteval
+        """
+        out_result = None
+        bool_eq_zero = self.number_of_false == 0 if operator == 'and' else self.number_of_true == 0
+        if bool_eq_zero and self.number_of_error >= 1:
+            out_result = 'error'
+        elif bool_eq_zero and self.number_of_error == 0 and self.number_of_unknown >= 1:
+            out_result = 'unknown'
+        elif bool_eq_zero and self._error_unknown_eq_zero_and_noteval_ge_one():
+            out_result = 'noteval'
+        return out_result
+
+    def _error_unknown_noteval_eq_zero(self):
+        error_eq_zero = self.number_of_error == 0
+        unknown_eq_zero = self.number_of_unknown == 0
+        noteval_eq_zero = self.number_of_noteval == 0
+        return error_eq_zero and unknown_eq_zero and noteval_eq_zero
+
+    def _error_unknown_eq_zero_and_noteval_ge_one(self):
+        error_eq_zero = self.number_of_error == 0
+        unknown_eq_zero = self.number_of_unknown == 0
+        noteval_ge_one = self.number_of_noteval >= 1
+        return error_eq_zero and unknown_eq_zero and noteval_ge_one
+
+    def _unknown_noteval_notappl_ge_zero(self):
+        unknown_ge_zero = self.number_of_unknown >= 0
+        noteval_ge_zero = self.number_of_noteval >= 0
+        notappl_ge_zero = self.number_of_notappl >= 0
+        return unknown_ge_zero and notappl_ge_zero and noteval_ge_zero
+
+    def is_notapp_result(self):
+        """
+        Evaluates if the counts of values in the result matches the notapp result.
+
+        Returns:
+            bool.
+        """
+        notappl_gt_zero = self.number_of_notappl > 0
+        false_eq_zero = self.number_of_false == 0
+        true_eq_zero = self.number_of_true == 0
+        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
+
+        true_false_eq_zero = false_eq_zero and true_eq_zero
+        return notappl_gt_zero and true_false_eq_zero and error_unknown_noteval_eq_zero


Test patch:
diff --git a/tests/test_evaluate.py b/tests/test_evaluate.py
index b4f614b3..1cb7b4b0 100644
--- a/tests/test_evaluate.py
+++ b/tests/test_evaluate.py
@@ -1,6 +1,7 @@
+import pytest
+
 import tests.any_test_help
-from oval_graph.oval_tree import evaluate
-from oval_graph.oval_tree.oval_node import OvalNode
+from oval_graph.oval_tree.oval_result import OvalResult
 
 # AND operator
 
@@ -136,60 +137,51 @@ def test_XORTreeNotappl():
         None, "notappl", 'XORTreeNotappl.json')
 
 
-results_counts = {
-    'true_cnt': -1,
-    'false_cnt': -1,
-    'error_cnt': -1,
-    'unknown_cnt': -1,
-    'noteval_cnt': -1,
-    'notappl_cnt': -1
-}
-
-results_counts1 = {
-    'true_cnt': 3,
-    'false_cnt': 3,
-    'error_cnt': 3,
-    'unknown_cnt': 0,
-    'noteval_cnt': -1,
-    'notappl_cnt': 3
-}
-
-
-def test_bad_results_counts_for_operator_and():
-    assert evaluate.oval_operator_and(results_counts) is None
-
-
-def test_bad_results_counts_for_operator_one():
-    assert evaluate.oval_operator_one(results_counts) is None
+@pytest.fixture
+def oval_result():
+    results_counts = {
+        "number_of_true": -1,
+        "number_of_false": -1,
+        "number_of_error": -1,
+        "number_of_unknown": -1,
+        "number_of_noteval": -1,
+        "number_of_notappl": -1
+    }
+    return OvalResult(**results_counts)
 
 
-def test_bad_results_counts_for_operator_or():
-    assert evaluate.oval_operator_or(results_counts) is None
+@pytest.fixture
+def oval_result1():
+    results_counts = {
+        "number_of_true": 3,
+        "number_of_false": 3,
+        "number_of_error": 3,
+        "number_of_unknown": 0,
+        "number_of_noteval": -1,
+        "number_of_notappl": 3
+    }
+    return OvalResult(**results_counts)
 
 
-def test_bad_results_counts_for_operator_xor():
-    assert evaluate.oval_operator_xor(results_counts) is None
+def test_bad_results_counts_for_operator_and(oval_result):
+    assert oval_result.eval_operator_and() is None
 
 
-def test_false_noteval_greater_zero():
-    assert not evaluate.greater_zero(results_counts, 'noteval_cnt')
+def test_bad_results_counts_for_operator_one(oval_result):
+    assert oval_result.eval_operator_one() is None
 
 
-def test_false_smaller_then_two():
-    assert not evaluate.smaller_than_two(
-        results_counts1, 'true_cnt')
+def test_bad_results_counts_for_operator_or(oval_result):
+    assert oval_result.eval_operator_or() is None
 
 
-def test_false_eq_zero_duo():
-    assert not evaluate.eq_zero_duo(
-        results_counts, 'noteval_cnt', 'error_cnt')
+def test_bad_results_counts_for_operator_xor(oval_result):
+    assert oval_result.eval_operator_xor() is None
 
 
-def test_false_eq_or_greater_zero_unknown_noteval_notappl():
-    assert not evaluate.eq_or_greater_zero_unknown_noteval_notappl(
-        results_counts1)
+def test_false_eq_or_greater_zero_unknown_noteval_notappl(oval_result1):
+    assert not oval_result1._unknown_noteval_notappl_ge_zero()
 
 
-def test_false_error_unknown_eq_noteval_greater_zero():
-    assert not evaluate.error_unknown_eq_noteval_greater_zero(
-        results_counts)
+def test_false_error_unknown_eq_noteval_greater_zero(oval_result):
+    assert not oval_result._error_unknown_eq_zero_and_noteval_ge_one()