"""Tests for my simple math nodes"""
# To make code more concise use a shortform in the import, much as you would for numpy -> np
import omni.graph.core as og

# This module contains some useful testing utilities
import omni.graph.core.tests as ogts


# By using the standard test case base class you get scene setUp() and tearDown(), and the current set of default
# OmniGraph settings. If you wish to use any non-standard settings, leave the scene in place after the test completes,
# or add your own scoped setting variables see the set of classes that derive from ogts.OmniGraphTestCase and look at
# the test configuration factory function ogts.test_case_class().
class TestMySimpleNodes(ogts.OmniGraphTestCase):
    """Class containing tests for my simple nodes. The base class allows the tests to be run asynchronously"""

    # ----------------------------------------------------------------------
    async def test_math(self):
        """Run a node network with the math operation (A + 6) * 10 = B
        Exercises the math nodes for addition (my.node.add) and multiplication (my.node.multiply)
        """
        # The Controller class is useful for manipulating the OmniGraph. See the Python help on it for details.
        # Using this shortcut keeps the graph configuration specification more readable.
        keys = og.Controller.Keys

        # This sets up the graph in the configuration required for the math operation to work
        (graph, (plus_node, times_node), _, _) = og.Controller.edit(
            "/mathGraph",
            {
                keys.CREATE_NODES: [("plus", "my.extension.addInts"), ("times", "my.extension.multiplyInts")],
                keys.CONNECT: [("plus.outputs:result", "times.inputs:a")],
                keys.SET_VALUES: [("plus.inputs:a", 6), ("times.inputs:b", 10)],
            },
        )

        # This contains pairs of (A, B) values that should satisfy the math equation.
        test_data = [(1, 70), (0, 60), (-6, 0)]

        # Creating specific controllers tied to the attributes that will be accessed multiple times in the loop
        # makes the access a little bit faster.
        in_controller = og.Controller(og.Controller.attribute("inputs:b", plus_node))
        out_controller = og.Controller(og.Controller.attribute("outputs:result", times_node))

        # Loop through the operation to set the input and test the output
        for (value_a, value_b) in test_data:
            # Set the test input on the node
            in_controller.set(value_a)

            # This has to be done to ensure the nodes do their computation before testing the results
            await og.Controller.evaluate(graph)

            # Compare the expected value from the test data against the computed value from the node
            self.assertEqual(value_b, out_controller.get())
