test_{field,value}.py: add comments
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Sat, 29 Jun 2019 15:28:34 +0000 (11:28 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 3 Jul 2019 01:31:27 +0000 (21:31 -0400)
Those files contain code which is very similar. It should be a single
helper base class eventually, but this patch only adds comments to both
files to clarify the usage of some classes and methods.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I15d8d4e1d8d3444491b9f01deb6d2cdcc5d406d1
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1584
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
tests/bindings/python/bt2/test_field.py
tests/bindings/python/bt2/test_value.py

index a22d3f4a89064549dc068562d701a3f1db3edac9..015be10ec1ed9588862434231cc95e2d893b35ea 100644 (file)
@@ -120,56 +120,90 @@ def _create_struct_array_field(tc, length):
     return packet.context_field[field_name]
 
 
+# Base class for numeric field test cases.
+#
+# To be compatible with this base class, a derived class must, in its
+# setUp() method:
+#
+# * Set `self._def` to a field object with an arbitrary value.
+# * Set `self._def_value` to the equivalent value of `self._def`.
 class _TestNumericField:
+    # Tries the binary operation `op`:
+    #
+    # 1. Between `self._def`, which is a field object, and `rhs`.
+    # 2. Between `self._def_value`, which is the raw value of
+    #    `self._def`, and `rhs`.
+    #
+    # Returns the results of 1. and 2.
+    #
+    # If there's an exception while performing 1. or 2., asserts that
+    # both operations raised exceptions, that both exceptions have the
+    # same type, and returns `None` for both results.
     def _binop(self, op, rhs):
-        rexc = None
-        rvexc = None
+        type_rexc = None
+        type_rvexc = None
         comp_value = rhs
 
+        # try with field object
         try:
             r = op(self._def, rhs)
         except Exception as e:
-            rexc = e
+            type_rexc = type(e)
 
+        # try with value
         try:
             rv = op(self._def_value, comp_value)
         except Exception as e:
-            rvexc = e
+            type_rvexc = type(e)
 
-        if rexc is not None or rvexc is not None:
+        if type_rexc is not None or type_rvexc is not None:
             # at least one of the operations raised an exception: in
             # this case both operations should have raised the same
             # type of exception (division by zero, bit shift with a
             # floating point number operand, etc.)
-            self.assertIs(type(rexc), type(rvexc))
+            self.assertIs(type_rexc, type_rvexc)
             return None, None
 
         return r, rv
 
+    # Tries the unary operation `op`:
+    #
+    # 1. On `self._def`, which is a field object.
+    # 2. On `self._def_value`, which is the value of `self._def`.
+    #
+    # Returns the results of 1. and 2.
+    #
+    # If there's an exception while performing 1. or 2., asserts that
+    # both operations raised exceptions, that both exceptions have the
+    # same type, and returns `None` for both results.
     def _unaryop(self, op):
-        rexc = None
-        rvexc = None
+        type_rexc = None
+        type_rvexc = None
 
+        # try with field object
         try:
             r = op(self._def)
         except Exception as e:
-            rexc = e
+            type_rexc = type(e)
 
+        # try with value
         try:
             rv = op(self._def_value)
         except Exception as e:
-            rvexc = e
+            type_rvexc = type(e)
 
-        if rexc is not None or rvexc is not None:
+        if type_rexc is not None or type_rvexc is not None:
             # at least one of the operations raised an exception: in
             # this case both operations should have raised the same
             # type of exception (division by zero, bit shift with a
             # floating point number operand, etc.)
-            self.assertIs(type(rexc), type(rvexc))
+            self.assertIs(type_rexc, type_rvexc)
             return None, None
 
         return r, rv
 
+    # Tests that the unary operation `op` gives results with the same
+    # type for both `self._def` and `self._def_value`.
     def _test_unaryop_type(self, op):
         r, rv = self._unaryop(op)
 
@@ -178,6 +212,9 @@ class _TestNumericField:
 
         self.assertIsInstance(r, type(rv))
 
+    # Tests that the unary operation `op` gives results with the same
+    # value for both `self._def` and `self._def_value`. This uses the
+    # __eq__() operator of `self._def`.
     def _test_unaryop_value(self, op):
         r, rv = self._unaryop(op)
 
@@ -186,16 +223,22 @@ class _TestNumericField:
 
         self.assertEqual(r, rv)
 
+    # Tests that the unary operation `op`, when applied to `self._def`,
+    # does not change its underlying BT object address.
     def _test_unaryop_addr_same(self, op):
         addr_before = self._def.addr
         self._unaryop(op)
         self.assertEqual(self._def.addr, addr_before)
 
+    # Tests that the unary operation `op`, when applied to `self._def`,
+    # does not change its value.
     def _test_unaryop_value_same(self, op):
         value_before = copy.copy(self._def_value)
         self._unaryop(op)
         self.assertEqual(self._def, value_before)
 
+    # Tests that the binary operation `op` gives results with the same
+    # type for both `self._def` and `self._def_value`.
     def _test_binop_type(self, op, rhs):
         r, rv = self._binop(op, rhs)
 
@@ -208,6 +251,9 @@ class _TestNumericField:
         else:
             self.assertIsInstance(r, type(rv))
 
+    # Tests that the binary operation `op` gives results with the same
+    # value for both `self._def` and `self._def_value`. This uses the
+    # __eq__() operator of `self._def`.
     def _test_binop_value(self, op, rhs):
         r, rv = self._binop(op, rhs)
 
@@ -216,17 +262,36 @@ class _TestNumericField:
 
         self.assertEqual(r, rv)
 
+    # Tests that the binary operation `op`, when applied to `self._def`,
+    # does not change its underlying BT object address.
     def _test_binop_lhs_addr_same(self, op, rhs):
         addr_before = self._def.addr
         r, rv = self._binop(op, rhs)
         self.assertEqual(self._def.addr, addr_before)
 
+    # Tests that the binary operation `op`, when applied to `self._def`,
+    # does not change its value.
     @unittest.skip('copy is not implemented')
     def _test_binop_lhs_value_same(self, op, rhs):
         value_before = copy.copy(self._def)
         r, rv = self._binop(op, rhs)
         self.assertEqual(self._def, value_before)
 
+    # The methods below which take the `test_cb` and/or `op` parameters
+    # are meant to be used with one of the _test_binop_*() functions
+    # above as `test_cb` and a binary operator function as `op`.
+    #
+    # For example:
+    #
+    #     self._test_binop_rhs_pos_int(self._test_binop_value,
+    #                                  operator.add)
+    #
+    # This tests that a numeric field object added to a positive integer
+    # value gives a result with the expected value.
+    #
+    # `vint` and `vfloat` mean a signed integer value object and a real
+    # value object.
+
     def _test_binop_invalid_unknown(self, op):
         if op in _COMP_BINOPS:
             self.skipTest('not testing')
@@ -482,6 +547,11 @@ class _TestNumericField:
         self.assertTrue(self._def != None) # noqa: E711
 
 
+# This is a list of binary operators used for
+# _inject_numeric_testing_methods().
+#
+# Each entry is a pair of binary operator name (used as part of the
+# created testing method's name) and operator function.
 _BINOPS = (
     ('lt', operator.lt),
     ('le', operator.le),
@@ -516,6 +586,11 @@ _BINOPS = (
 )
 
 
+# This is a list of unary operators used for
+# _inject_numeric_testing_methods().
+#
+# Each entry is a pair of unary operator name (used as part of the
+# created testing method's name) and operator function.
 _UNARYOPS = (
     ('neg', operator.neg),
     ('pos', operator.pos),
@@ -532,6 +607,20 @@ _UNARYOPS = (
 )
 
 
+# This function injects a bunch of testing methods to a numeric
+# field test case.
+#
+# It is meant to be used like this:
+#
+#     _inject_numeric_testing_methods(MyNumericFieldTestCase)
+#
+# This function injects:
+#
+# * One testing method for each _TestNumericField._test_binop_*()
+#   method, for each binary operator in the _BINOPS tuple.
+#
+# * One testing method for each _TestNumericField._test_unaryop*()
+#   method, for each unary operator in the _UNARYOPS tuple.
 def _inject_numeric_testing_methods(cls):
     def test_binop_name(suffix):
         return 'test_binop_{}_{}'.format(name, suffix)
index 6f66930e93ca9c3e009fbd8434898fd48a79d30e..a56f2c1ed996b5ad8c15bdd8197ee46cc46b3835 100644 (file)
@@ -25,6 +25,9 @@ import copy
 import bt2
 
 
+# The value object classes explicitly do not implement the copy methods,
+# raising `NotImplementedError`, just in case we decide to implement
+# them someday.
 class _TestCopySimple:
     def test_copy(self):
         with self.assertRaises(NotImplementedError):
@@ -41,56 +44,90 @@ _COMP_BINOPS = (
 )
 
 
+# Base class for numeric value test cases.
+#
+# To be compatible with this base class, a derived class must, in its
+# setUp() method:
+#
+# * Set `self._def` to a value object with an arbitrary raw value.
+# * Set `self._def_value` to the equivalent raw value of `self._def`.
 class _TestNumericValue(_TestCopySimple):
+    # Tries the binary operation `op`:
+    #
+    # 1. Between `self._def`, which is a value object, and `rhs`.
+    # 2. Between `self._def_value`, which is the raw value of
+    #    `self._def`, and `rhs`.
+    #
+    # Returns the results of 1. and 2.
+    #
+    # If there's an exception while performing 1. or 2., asserts that
+    # both operations raised exceptions, that both exceptions have the
+    # same type, and returns `None` for both results.
     def _binop(self, op, rhs):
-        rexc = None
-        rvexc = None
+        type_rexc = None
+        type_rvexc = None
         comp_value = rhs
 
+        # try with value object
         try:
             r = op(self._def, rhs)
         except Exception as e:
-            rexc = e
+            type_rexc = type(e)
 
+        # try with raw value
         try:
             rv = op(self._def_value, comp_value)
         except Exception as e:
-            rvexc = e
+            type_rvexc = type(e)
 
-        if rexc is not None or rvexc is not None:
+        if type_rexc is not None or type_rvexc is not None:
             # at least one of the operations raised an exception: in
             # this case both operations should have raised the same
             # type of exception (division by zero, bit shift with a
             # floating point number operand, etc.)
-            self.assertIs(type(rexc), type(rvexc))
+            self.assertIs(type_rexc, type_rvexc)
             return None, None
 
         return r, rv
 
+    # Tries the unary operation `op`:
+    #
+    # 1. On `self._def`, which is a value object.
+    # 2. On `self._def_value`, which is the raw value of `self._def`.
+    #
+    # Returns the results of 1. and 2.
+    #
+    # If there's an exception while performing 1. or 2., asserts that
+    # both operations raised exceptions, that both exceptions have the
+    # same type, and returns `None` for both results.
     def _unaryop(self, op):
-        rexc = None
-        rvexc = None
+        type_rexc = None
+        type_rvexc = None
 
+        # try with value object
         try:
             r = op(self._def)
         except Exception as e:
-            rexc = e
+            type_rexc = type(e)
 
+        # try with raw value
         try:
             rv = op(self._def_value)
         except Exception as e:
-            rvexc = e
+            type_rvexc = type(e)
 
-        if rexc is not None or rvexc is not None:
+        if type_rexc is not None or type_rvexc is not None:
             # at least one of the operations raised an exception: in
             # this case both operations should have raised the same
             # type of exception (division by zero, bit shift with a
             # floating point number operand, etc.)
-            self.assertIs(type(rexc), type(rvexc))
+            self.assertIs(type_rexc, type_rvexc)
             return None, None
 
         return r, rv
 
+    # Tests that the unary operation `op` gives results with the same
+    # type for both `self._def` and `self._def_value`.
     def _test_unaryop_type(self, op):
         r, rv = self._unaryop(op)
 
@@ -99,6 +136,9 @@ class _TestNumericValue(_TestCopySimple):
 
         self.assertIsInstance(r, type(rv))
 
+    # Tests that the unary operation `op` gives results with the same
+    # value for both `self._def` and `self._def_value`. This uses the
+    # __eq__() operator of `self._def`.
     def _test_unaryop_value(self, op):
         r, rv = self._unaryop(op)
 
@@ -107,16 +147,22 @@ class _TestNumericValue(_TestCopySimple):
 
         self.assertEqual(r, rv)
 
+    # Tests that the unary operation `op`, when applied to `self._def`,
+    # does not change its underlying BT object address.
     def _test_unaryop_addr_same(self, op):
         addr_before = self._def.addr
         self._unaryop(op)
         self.assertEqual(self._def.addr, addr_before)
 
+    # Tests that the unary operation `op`, when applied to `self._def`,
+    # does not change its value.
     def _test_unaryop_value_same(self, op):
         value_before = self._def.__class__(self._def)
         self._unaryop(op)
         self.assertEqual(self._def, value_before)
 
+    # Tests that the binary operation `op` gives results with the same
+    # type for both `self._def` and `self._def_value`.
     def _test_binop_type(self, op, rhs):
         r, rv = self._binop(op, rhs)
 
@@ -129,6 +175,9 @@ class _TestNumericValue(_TestCopySimple):
         else:
             self.assertIsInstance(r, type(rv))
 
+    # Tests that the binary operation `op` gives results with the same
+    # value for both `self._def` and `self._def_value`. This uses the
+    # __eq__() operator of `self._def`.
     def _test_binop_value(self, op, rhs):
         r, rv = self._binop(op, rhs)
 
@@ -137,25 +186,41 @@ class _TestNumericValue(_TestCopySimple):
 
         self.assertEqual(r, rv)
 
+    # Tests that the binary operation `op`, when applied to `self._def`,
+    # does not change its underlying BT object address.
     def _test_binop_lhs_addr_same(self, op, rhs):
         addr_before = self._def.addr
         r, rv = self._binop(op, rhs)
         self.assertEqual(self._def.addr, addr_before)
 
+    # Tests that the binary operation `op`, when applied to `self._def`,
+    # does not change its value.
     def _test_binop_lhs_value_same(self, op, rhs):
         value_before = self._def.__class__(self._def)
         r, rv = self._binop(op, rhs)
         self.assertEqual(self._def, value_before)
 
+    # The methods below which take the `test_cb` and `op` parameters
+    # are meant to be used with one of the _test_binop_*() functions
+    # above as `test_cb` and a binary operator function as `op`.
+    #
+    # For example:
+    #
+    #     self._test_binop_rhs_pos_int(self._test_binop_value,
+    #                                  operator.add)
+    #
+    # This tests that a numeric value object added to a positive integer
+    # raw value gives a result with the expected value.
+    #
+    # `vint` and `vfloat` mean a signed integer value object and a real
+    # value object.
+
     def _test_binop_invalid_unknown(self, op):
         if op in _COMP_BINOPS:
             self.skipTest('not testing')
 
-        class A:
-            pass
-
         with self.assertRaises(TypeError):
-            op(self._def, A())
+            op(self._def, object())
 
     def _test_binop_invalid_none(self, op):
         if op in _COMP_BINOPS:
@@ -396,6 +461,11 @@ class _TestNumericValue(_TestCopySimple):
         self.assertTrue(self._def != None)
 
 
+# This is a list of binary operators used for
+# _inject_numeric_testing_methods().
+#
+# Each entry is a pair of binary operator name (used as part of the
+# created testing method's name) and operator function.
 _BINOPS = (
     ('lt', operator.lt),
     ('le', operator.le),
@@ -430,6 +500,11 @@ _BINOPS = (
 )
 
 
+# This is a list of unary operators used for
+# _inject_numeric_testing_methods().
+#
+# Each entry is a pair of unary operator name (used as part of the
+# created testing method's name) and operator function.
 _UNARYOPS = (
     ('neg', operator.neg),
     ('pos', operator.pos),
@@ -446,6 +521,23 @@ _UNARYOPS = (
 )
 
 
+# This function injects a bunch of testing methods to a numeric
+# value test case.
+#
+# It is meant to be used like this:
+#
+#     _inject_numeric_testing_methods(MyNumericValueTestCase)
+#
+# If `has_neg` is true, then the function injects testing methods which
+# involve operations with a negative value.
+#
+# This function injects:
+#
+# * One testing method for each _TestNumericValue._test_binop_*()
+#   method, for each binary operator in the _BINOPS tuple.
+#
+# * One testing method for each _TestNumericValue._test_unaryop*()
+#   method, for each unary operator in the _UNARYOPS tuple.
 def _inject_numeric_testing_methods(cls, has_neg=True):
     def test_binop_name(suffix):
         return 'test_binop_{}_{}'.format(name, suffix)
This page took 0.030095 seconds and 4 git commands to generate.