Beispiel #1
0
    def test_input_output_symmetry_after_modification(self):
        n1 = Node("N1")
        n2 = Node("N2")
        flow = "flow"

        n1.inputs[n2] = flow
        eq_(n2.outputs, {n1: flow})
Beispiel #2
0
 def test_node_input_output_type_assertions(self):
     """
     `Node`s should only accept `Node` instances as input/output targets.
     """
     with assert_raises(AssertionError):
         Node('A node with an output', outputs={'Not a Node': 'A Flow'})
         Node('A node with an input', inputs={'Not a Node': 'A Flow'})
Beispiel #3
0
    def test_modifying_inputs_after_construction(self):
        """ One should be able to add and delete inputs of a node.
        """
        node = Node("N1")
        bus = Bus("N2")
        flow = "flow"

        eq_(node.inputs, {},
            ("\n  Expected an empty dictionary of inputs." +
             "\n  Got: {} (== {}) instead").format(
                node.inputs,
                dict(node.inputs)))
        node.inputs[bus] = flow
        eq_(node.inputs, {bus: flow},
            ("\n  Expected {} as `node.inputs`." +
             "\n  Got    : {} (== {}) instead").format(
                {bus: flow}, node.inputs, dict(node.inputs)))
        eq_(node.inputs[bus], flow,
            ("\n  Expected {} as `node.inputs[bus]`." +
             "\n  Got    : {} instead").format(flow, node.inputs[bus]))
        del node.inputs[bus]
        eq_(node.inputs, {},
            ("\n  Expected an empty dictionary of inputs." +
             "\n  Got: {} (== {}) instead").format(
                node.inputs,
                dict(node.inputs)))
Beispiel #4
0
    def test_that_nodes_do_not_get_undead_flows(self):
        """ Newly created nodes should only have flows assigned to them.

        A new node `n`, which re-used a previously used label `l`, retained the
        flows of those nodes which where labeled `l` before `n`. This incorrect
        behaviour is a problem if somebody wants to use different nodes with
        the same label in multiple energy systems. While this feature currently
        isn't used, it also lead to weird behaviour when running tests.

        This test ensures that new nodes only have those flows which are
        assigned to them on construction.
        """
        # We don't want a registry as we are re-using a label on purpose.
        # Having a registry would just throw and error generated by the DEFAULT
        # grouping in this case.
        Node.registry = None
        flow = object()
        old = Node(label="A reused label")
        bus = Bus(label="bus", inputs={old: flow})
        eq_(bus.inputs[old].flow, flow,
            ("\n  Expected: {}" +
             "\n  Got     : {} instead").format(flow, bus.inputs[old].flow))
        eq_(old.outputs[bus].flow, flow,
            ("\n  Expected: {}" +
             "\n  Got     : {} instead").format(flow, old.outputs[bus].flow))
        new = Node(label="A reused label")
        eq_(new.outputs, {},
            ("\n  Expected an empty dictionary of outputs." +
             "\n  Got: {} instead").format(new.outputs))
Beispiel #5
0
 def test_delayed_registration_when_setting_input(self):
     """`Edge` registration gets delayed until input and output are set.
     """
     i, o = (Node("input"), Node("output"))
     with registry_changed_to(EnSys()):
         e = Edge(output=o)
         ok_(e not in Node.registry.groups.values())
         e.input = i
         ok_(e in Node.registry.groups.values())
Beispiel #6
0
    def test_updating_outputs(self):
        n1 = Node("N1")
        n2 = Node("N2")
        n1n2 = "n1n2"

        n1.outputs.update({n2: n1n2})
        eq_(n2.inputs, {n1: n1n2})
        eq_(n2.inputs[n1], n1n2)
        eq_(n1.outputs, {n2: n1n2})
        eq_(n1.outputs[n2], n1n2)
Beispiel #7
0
 def test_alternative_edge_construction_from_mapping(self):
     """ `Edge.from_object` treats mappings as keyword arguments.
     """
     i, o, f = (Node("input"), Node("output"), "flow")
     with assert_raises(ValueError):
         Edge.from_object({"flow": i, "values": o})
     edge = Edge.from_object({"input": i, "output": o, "flow": f})
     eq_(edge.input, i)
     eq_(edge.output, o)
     eq_(edge.values, f)
     eq_(edge.flow, f)
Beispiel #8
0
 def test_grouping_filter_parameter(self):
     g1 = Grouping(key=lambda e: "The Special One",
                   filter=lambda e: "special" in str(e))
     g2 = Nodes(key=lambda e: "A Subset",
                filter=lambda e: "subset" in str(e))
     ES = es.EnergySystem(groupings=[g1, g2])
     special = Node(label="special")
     subset = set(Node(label="subset: {}".format(i)) for i in range(10))
     others = set(Node(label="other: {}".format(i)) for i in range(10))
     ES.add(special, *subset)
     ES.add(*others)
     eq_(ES.groups["The Special One"], special)
     eq_(ES.groups["A Subset"], subset)
Beispiel #9
0
    def test_edge_construction_side_effects(self):
        """ Constructing an `Edge` should affect it's input/output `Node`s.

        When constructing an `Edge`, the `inputs` and `outputs` of its output
        and input `Node`s should be set appropriately.
        """
        source = Node(label='source')
        target = Node(label='target')
        edge = Edge(input=source, output=target)
        ok_(target in source.outputs,
            "{} not in {} after constructing {}."
            .format(target, source.outputs, edge))
        ok_(source in target.inputs,
            "{} not in {} after constructing {}."
            .format(source, target.outputs, edge))
Beispiel #10
0
 def test_non_callable_group_keys(self):
     collect_everything = Nodes(key="everything")
     g1 = Grouping(key="The Special One",
                   filter=lambda e: "special" in e.label)
     g2 = Nodes(key="A Subset", filter=lambda e: "subset" in e.label)
     ES = es.EnergySystem(groupings=[g1, g2, collect_everything])
     special = Node(label="special")
     subset = set(Node(label="subset: {}".format(i)) for i in range(2))
     others = set(Node(label="other: {}".format(i)) for i in range(2))
     everything = subset.union(others)
     everything.add(special)
     ES.add(*everything)
     eq_(ES.groups["The Special One"], special)
     eq_(ES.groups["A Subset"], subset)
     eq_(ES.groups["everything"], everything)
Beispiel #11
0
 def test_node_label_without_private_attribute(self):
     """
     A `Node` with no explicit `label` doesn't have a `_label` attribute.
     """
     n = Node()
     with assert_raises(AttributeError):
         n._label
Beispiel #12
0
    def test_that_node_additions_are_signalled(self):
        """
        When a node gets `add`ed, a corresponding signal should be emitted.
        """
        node = Node(label="Node")

        def subscriber(sender, **kwargs):
            ok_(sender is node)
            ok_(kwargs['EnergySystem'] is self.es)
            subscriber.called = True

        subscriber.called = False

        es.EnergySystem.signals[es.EnergySystem.add].connect(
            subscriber, sender=node
        )
        self.es.add(node)
        ok_(
            subscriber.called,
            (
                "\nExpected `subscriber.called` to be `True`.\n"
                "Got {}.\n"
                "Probable reason: `subscriber` didn't get called."
            ).format(subscriber.called),
        )
Beispiel #13
0
 def test_label_as_positional_argument(self):
     o = object()
     n = Node(o)
     ok_(n.label is o, (
             "Setting `label` as positional parameter argument failed."
             "\n  Expected: {!r}"
             "\n  Got     : {!r}").format(o, n.label))
Beispiel #14
0
    def test_symmetric_input_output_assignment(self):
        n1 = Node(label="<N1>")

        n2 = Node(label="<From N1>", inputs=[n1])
        ok_(n1 in n2.inputs,
            "{0} not in {1}.inputs, ".format(n1, n2) +
            "although it should be by construction.")
        ok_(n2 in n1.outputs,
            "{0} in {1}.inputs but {1} not in {0}.outputs.".format(n1, n2))

        n3 = Node(label="<To N1>", outputs=[n1])
        ok_(n1 in n3.outputs,
            "{0} not in {1}.outputs, ".format(n1, n3) +
            "although it should be by construction.")
        ok_(n3 in n1.inputs,
            "{0} in {1}.outputs but {1} not in {0}.inputs.".format(n1, n3))
Beispiel #15
0
 def test_flows(self):
     key = object()
     ensys = es.EnergySystem(groupings=[Flows(key)])
     Node.registry = ensys
     flows = (object(), object())
     bus = NewBus(label="A Bus")
     Node(label="A Node", inputs={bus: flows[0]}, outputs={bus: flows[1]})
     eq_(ensys.groups[key], set(flows))
Beispiel #16
0
 def test_registry_modification_decorator(self):
     Node("registered")
     ok_("registered" in self.es.groups)
     @temporarily_modifies_registry
     def create_a_node():
         Node("not registered")
     create_a_node()
     ok_("not registered" not in self.es.groups)
Beispiel #17
0
 def test_Flows(self):
     key = object()
     ES = es.EnergySystem(groupings=[Flows(key)])
     flows = (object(), object())
     bus = NewBus(label="A Bus")
     node = Node(label="A Node",
                 inputs={bus: flows[0]},
                 outputs={bus: flows[1]})
     eq_(ES.groups[key], set(flows))
Beispiel #18
0
 def test_flows_with_nodes(self):
     key = object()
     ensys = es.EnergySystem(groupings=[FWNs(key)])
     Node.registry = ensys
     flows = (object(), object())
     bus = NewBus(label="A Bus")
     node = Node(label="A Node",
                 inputs={bus: flows[0]}, outputs={bus: flows[1]})
     eq_(ensys.groups[key], {(bus, node, flows[0]), (node, bus, flows[1])})
Beispiel #19
0
 def test_FlowsWithNodes(self):
     key = object()
     ES = es.EnergySystem(groupings=[FWNs(key)])
     Node.registry = ES
     flows = (object(), object())
     bus = NewBus(label="A Bus")
     node = Node(label="A Node",
                 inputs={bus: flows[0]},
                 outputs={bus: flows[1]})
     eq_(ES.groups[key], set(
         ((bus, node, flows[0]), (node, bus, flows[1]))))
Beispiel #20
0
 def test_that_the_outputs_attribute_of_a_node_is_a_mapping(self):
     n = Node()
     exception = None
     try:
         n.outputs.values()
     except AttributeError as e:
         exception = e
     ok_(exception is None,
         "\n  Test accessing `outputs.values()`" +
         " on {} having no inputs.".format(n) +
         "\n  Got unexpected exception:\n" +
         "\n      {}".format(feo(type(exception), exception)[0]))
Beispiel #21
0
    def test_proper_filtering(self):
        """ `Grouping.filter` should not be "all or nothing".

        There was a bug where, if `Grouping.filter` returned `False` only for
        some elements of `Grouping.value(e)`, those elements where actually
        retained.
        This test makes sure that the bug doesn't resurface again.
        """
        g = Nodes(key="group", value=lambda _: {1, 2, 3, 4},
                  filter=lambda x: x % 2 == 0)
        ensys = es.EnergySystem(groupings=[g])
        special = Node(label="object")
        ensys.add(special)
        eq_(ensys.groups["group"], {2, 4})
Beispiel #22
0
    def test_constant_group_keys(self):
        """ Callable keys passed in as `constant_key` should not be called.

        The `constant_key` parameter can be used to specify callable group keys
        without having to worry about `Grouping`s trying to call them. This
        test makes sure that the parameter is handled correctly.
        """
        everything = lambda: "everything"
        collect_everything = Nodes(constant_key=everything)
        ES = es.EnergySystem(groupings=[collect_everything])
        node = Node(label="A Node")
        ok_("everything" not in ES.groups)
        ok_(everything in ES.groups)
        eq_(ES.groups[everything], set([node]))
Beispiel #23
0
 def test_accessing_inputs_of_a_node_without_input_flows(self):
     n = Node()
     exception = None
     try:
         inputs = n.inputs
     except Exception as e:
         exception = e
     ok_(exception is None,
         "\n  Test accessing `inputs` on {} having no inputs.".format(n) +
         "\n  Got unexpected exception:\n" +
         "\n      {}".format(feo(type(exception), exception)[0]))
     ok_(len(inputs) == 0,
         "\n  Failure when testing `len(inputs)`." +
         "\n  Expected: 0." +
         "\n  Got     : {}".format(len(inputs)))
Beispiel #24
0
    def test_defining_multiple_groupings_with_one_function(self):
        def assign_to_multiple_groups_in_one_go(n):
            g1 = n.label[-1]
            g2 = n.label[0:3]
            return [g1, g2]

        ES = es.EnergySystem(groupings=[assign_to_multiple_groups_in_one_go])
        Node.registry = ES
        nodes = [
            Node(label=("Foo: " if i % 2 == 0 else "Bar: ") + "{}".format(i) +
                 ("A" if i < 5 else "B")) for i in range(10)
        ]
        for group in ["Foo", "Bar", "A", "B"]:
            eq_(len(ES.groups[group]), 5,
                ("\n  Failed testing length of group '{}'." +
                 "\n  Expected: 5" + "\n  Got     : {}" +
                 "\n  Group   : {}").format(
                     group, len(ES.groups[group]),
                     sorted([e.label for e in ES.groups[group]])))
Beispiel #25
0
 def test_that_attributes_cannot_be_added(self):
     node = Node()
     with assert_raises(AttributeError):
         node.foo = "bar"
Beispiel #26
0
 def test_error_for_duplicate_label_argument(self):
     """ `Node.__init__` should fail if positional and keyword args collide.
     """
     with assert_raises(TypeError):
         Node("Positional Label", label="Keyword Label")
Beispiel #27
0
 def create_a_node():
     Node("not registered")
Beispiel #28
0
 def test_that_attributes_cannot_be_added(self):
     node = Node()
     with assert_raises(AttributeError):
         node.foo = "bar"
Beispiel #29
0
 def test_node_label_if_its_not_explicitly_specified(self):
     """ If not explicitly given, a `Node`'s label is based on its `id`.
     """
     n = Node()
     ok_("0x{:x}>".format(id(n)) in n.label)