def test_home_automation(self): """A simple example in the home automation domain""" brightness_1 = Input() brightness_2 = Input() brightness_sum = Node(action=lambda *args: sum(args), inputs=Node.inputs(brightness_1, brightness_2)) def inverse(value): """Return the inverse of a value in the range 0..510""" return 510 - value brightness_inverse = Node(action=inverse, inputs=Node.inputs(brightness_sum)) lamp_power_changes = [] def set_lamp_power(value): """Log changes to lamp power""" lamp_power_changes.append(value) _lamp_power = Node(action=set_lamp_power, inputs=Node.inputs(brightness_inverse), triggered=True) update_inputs_get_triggered([(brightness_1, 20), (brightness_2, 40)]) self.assertEqual([450], lamp_power_changes) update_inputs_get_triggered([(brightness_1, 20), (brightness_2, 40)]) self.assertEqual([450], lamp_power_changes) update_inputs_get_triggered([(brightness_1, 24), (brightness_2, 40)]) self.assertEqual([450, 446], lamp_power_changes)
def inner(): input_node = Input() output_node = Node(action=lambda value: value, inputs=Node.inputs(input_node)) self.assertEqual(set([output_node]), input_node._dependents) self.assertEqual((input_node, ), output_node._positional_inputs) return weakref.ref(input_node), weakref.ref(output_node)
def test_enabled_and_wrong_output_type(self): with patch('lusmu.core.VERIFY_OUTPUT_TYPES', True): with assert_raises(TypeError) as exc: node = Node(name='node', action=IntOutputTypeAction(), inputs=Node.inputs(self.input)) self.input.value = '42' node._evaluate() self.assertEqual( "The output value type 'str' for [node]\n" "doesn't match the expected type 'int' for action " '"int_action".', str(exc.exception))
def test_garbage_collection(self): """Interconnected nodes are garbage collected""" input_node = Input() output_node = Node(action=lambda value: value, inputs=Node.inputs(input_node)) self.assertEqual(set([output_node]), input_node._dependents) self.assertEqual((input_node, ), output_node._positional_inputs) input_ref = weakref.ref(input_node) output_ref = weakref.ref(output_node) del input_node del output_node gc.collect() self.assertEqual(None, input_ref()) self.assertEqual(None, output_ref())
def test_garbage_collection_with_finalizer_values(self): """Interconnected nodes with gc-unfriendly values are gc'd""" class Val(object): def __del__(self): pass val = Val() input_node = Input(value=val) output_node = Node(action=lambda value: value, inputs=Node.inputs(input_node)) self.assertEqual(set([output_node]), input_node._dependents) self.assertEqual((input_node, ), output_node._positional_inputs) self.assertEqual(val, input_node._value) input_ref = weakref.ref(input_node) output_ref = weakref.ref(output_node) del input_node del output_node gc.collect() self.assertEqual(None, input_ref()) self.assertEqual(None, output_ref())
def test_value_property_getter(self): """The value of a Node can be set with the .value property""" root = Input(value=5) leaf = Node(action=lambda value: value, inputs=Node.inputs(root)) self.assertEqual(5, leaf.value)
def square(x): return x**2 def sum_(*args): return sum(args) def sqrt(square): print '** taking square root of {:.2f}'.format(square) return math.sqrt(square) area_a = Node(name='square of a', action=square, inputs=Node.inputs(a)) area_b = Node(name='square of b', action=square, inputs=Node.inputs(b)) area_hypothenuse = Node(name='square of hypothenuse', action=sum_, inputs=Node.inputs(area_a, area_b)) hypothenuse = Node(name='length of hypothenuse', action=sqrt, inputs=Node.inputs(area_hypothenuse)) sin_alpha = Node(name='sin of alpha', action=operator.div, inputs=Node.inputs(a, hypothenuse)) alpha = Node(name='angle alpha', action=math.asin, inputs=Node.inputs(sin_alpha)) sin_beta = Node(name='sin of beta', action=operator.div,
def test_enabled_and_correct_output_type(self): with patch('lusmu.core.VERIFY_OUTPUT_TYPES', True): node = Node(action=IntOutputTypeAction(), inputs=Node.inputs(self.input)) self.input.value = 42 node._evaluate()
def test_disabled_and_wrong_output_type(self): node = Node(action=IntOutputTypeAction(), inputs=Node.inputs(self.input)) self.input.value = '42' node._evaluate()
def test_disabled_and_correct_output_type(self): node = Node(action=IntOutputTypeAction(), inputs=Node.inputs(self.input)) self.input.value = 42 node._evaluate()
dy = y - TARGET['y'] return math.sqrt(dx ** 2 + dy ** 2) def is_close_to_target(distance): return distance < RADIUS def get_distance_description(is_close): return "INSIDE" if is_close else "OUTSIDE" mousex = Input(name='mouse x') mousey = Input(name='mouse y') distance = Node( name='distance', action=get_distance, inputs=Node.inputs(mousex, mousey)) is_close = Node( name='is close', action=is_close_to_target, inputs=Node.inputs(distance)) alert = Node( name='alert', action=get_distance_description, inputs=Node.inputs(is_close)) def onclick(event): update_inputs([(mousex, event.x), (mousey, event.y)]) print 'distance.value == {:.1f}'.format(distance.value)