Esempio n. 1
0
    def test_function_filter(self):
        """Verify the function filter class
        """
        s = ValueListSensor(1, value_stream)
        st = SensorAsOutputThing(s)
        captured_list_ref = [[]]
        got_completed_ref = [
            False,
        ]

        def on_next(self, x):
            captured_list_ref[0].append(x.val)
            self._dispatch_next(x)

        def on_completed(self):
            got_completed_ref[0] = True
            self._dispatch_completed()

        ff = FunctionFilter(st, on_next=on_next, on_completed=on_completed)
        vo = ValidationInputThing(value_stream, self.test_function_filter)
        ff.connect(vo)
        st.print_downstream()
        scheduler = Scheduler(asyncio.get_event_loop())
        scheduler.schedule_periodic(st, 0.5)  # sample twice every second
        scheduler.run_forever()
        self.assertTrue(
            vo.completed,
            "Schedule exited before validation observer completed")
        self.assertEqual(value_stream, captured_list_ref[0])
        self.assertTrue(got_completed_ref[0])
        print("That's all folks")
Esempio n. 2
0
    def test_function_filter_error_handling(self):
        """Verify the error handling functionality of the function filter. We do
        this by connecting two downstream paths to the sensor. The first includes
        a function filter that throws an error when it encouters a sensor reading
        of 120. This should disconnect th stream at this point. The second is
        a normal validation input thing. It is connected directly to the sensor,
        and thus should not see any errors.
        """
        s = ValueListSensor(1, value_stream)
        st = SensorAsOutputThing(s)
        captured_list_ref = [[]]
        got_completed_ref = [
            False,
        ]
        got_on_error_ref = [
            False,
        ]

        def on_next_throw_exc(self, x):
            if x.val == 120:
                raise Exception("expected exc")
            else:
                captured_list_ref[0].append(x.val)
                self._dispatch_next(x)

        def on_completed(self):
            got_completed_ref[0] = True
            self._dispatch_completed()

        def on_error(self, e):
            got_on_error_ref[0] = True
            self._dispatch_error(e)

        ff = FunctionFilter(st,
                            on_next=on_next_throw_exc,
                            on_completed=on_completed,
                            on_error=on_error)
        ct = CaptureInputThing(expecting_error=True)
        ff.map(lambda x: x.val).connect(ct)
        vo = ValidationInputThing(value_stream,
                                  self.test_function_filter_error_handling)
        st.connect(vo)
        st.print_downstream()
        scheduler = Scheduler(asyncio.get_event_loop())
        scheduler.schedule_periodic(st, 0.5)  # sample twice every second
        scheduler.run_forever()
        self.assertTrue(
            vo.completed,
            "Schedule exited before validation observer completed")
        self.assertFalse(ct.completed,
                         "Capture thing should not have completed")
        self.assertTrue(ct.errored, "Capture thing should have seen an error")
        self.assertFalse(got_completed_ref[0])
        self.assertTrue(got_on_error_ref[0])
        self.assertEqual([20, 30, 100], ct.events,
                         "Capture thing event mismatch")
        self.assertEqual([20, 30, 100], captured_list_ref[0],
                         "captured_list_ref mismatch")
        print("That's all folks")
Esempio n. 3
0
def buffer_with_count(this, count):
    """
    """
    if count < 0:
        raise FatalError

    q = [[]]
    num_seen = [0]

    def on_next(self, x):
        num_seen[0] += 1
        q[0].append(x)
        if num_seen[0] == count:
            self._dispatch_next(q[0])
            num_seen[0] = 0
            q[0] = []

    def on_completed(self):
        self._dispatch_next(q[0])
        q[0] = []
        self._dispatch_completed()

    def on_error(self, e):
        self._dispatch_next(q[0])
        q[0] = []
        self._dispatch_error(e)

    return FunctionFilter(this,
                          on_next,
                          on_error=on_error,
                          on_completed=on_completed,
                          name="buffer_with_count")
Esempio n. 4
0
def to_json(this):
    """Convert the events in the stream to a json string.
    """
    def on_next(self, x):
        self._dispatch_next(json.dumps(x))
        
    return FunctionFilter(this, on_next=on_next, name='to_json')
Esempio n. 5
0
def take(this, count):
    """Takes a specified number of contiguous elements in an event sequence.
    Keyword arguments:
    count: The number of elements to send forward before skipping the remaining
           elements.
    """

    if count < 0:
        raise ArgumentOutOfRangeException()

    remaining = [count]
    completed = [False]

    def on_next(self, value):
        if remaining[0] > 0:
            remaining[0] -= 1
            self._dispatch_next(value)
        if remaining[0] == 0 and completed[0] == False:
            completed[0] = True
            self.disconnect_from_upstream()
            self._dispatch_completed()

    def on_completed(self):
        # We may have already given a completed notification if we hit count
        # elements. On the other hand, we might still need to provide a notification
        # if the actual sequence length is less than count.
        if completed[0] == False:
            completed[0] = True
            self._dispatch_completed()

    return FunctionFilter(this,
                          on_next=on_next,
                          on_completed=on_completed,
                          name="take(%s)" % count)
Esempio n. 6
0
def where(this, predicate):
    """Filter a stream based on the specified predicate function.
    """
    def on_next(self, x):
        if predicate(x):
            self._dispatch_next(x)

    return FunctionFilter(this, on_next, name="where")
Esempio n. 7
0
def select(this, mapfun):
    """Returns a stream whose elements are the result of
    invoking the transform function on each element of source.
    If the function returns None, no event is passed downstream.
    """
    def on_next(self, x):
        y = mapfun(x)
        if y is not None:
            self._dispatch_next(y)

    return FunctionFilter(this, on_next, name='select')
Esempio n. 8
0
def from_json(this, constructor=None):
    """Parse a sequence of json strings. If constructor is specified, the
    parsed value is passed as *args to the constructor to return the actual
    object.
    """
    def on_next(self, x):
        obj = json.loads(x)
        if constructor:
            obj = constructor(*obj)
        self._dispatch_next(obj)
        
    return FunctionFilter(this, on_next=on_next, name='from_json')
Esempio n. 9
0
def fill_in_missing_times(this):
    def on_next(self, x):
        if (self.last_time is not None) and \
           (x.ts - self.last_time)>MAX_TIME_INTERVAL:
            ts = self.last_time + EXPECTED_TIME_INTERVAL
            missing = 0
            while (x.ts - ts) > EXPECTED_TIME_INTERVAL:
                if missing == 0:
                    self._dispatch_next(
                        SensorEvent(sensor_id=x.sensor_id, ts=ts, val=NaN))
                ts += EXPECTED_TIME_INTERVAL
                missing += 1
            print("Found %s missing samples" % missing)
        self.last_time = x.ts
        self._dispatch_next(x)

    f = FunctionFilter(this, on_next=on_next, name="fill_in_missing_times()")
    setattr(f, 'last_time', None)
    return f
Esempio n. 10
0
def last(this, default=None):
    value = [default]
    seen_value = [False]

    def on_next(self, x):
        value[0] = x
        seen_value[0] = True

    def on_completed(self):
        if not seen_value[0] and default is None:
            self._dispatch_error(SequenceContainsNoElementsError())
        else:
            self._dispatch_next(value[0])
            self._dispatch_completed()

    return FunctionFilter(this,
                          on_next=on_next,
                          on_completed=on_completed,
                          name='last')
Esempio n. 11
0
def skip(this, count):
    """Bypasses a specified number of elements in an event sequence
    and then returns the remaining elements.
    Keyword arguments:
    count: The number of elements to skip before returning the remaining
        elements.
    Returns an event sequence that contains the elements that occur
    after the specified index in the input sequence.
    """

    if count < 0:
        raise ArgumentOutOfRangeException()

    remaining = [count]

    def on_next(self, value):
        if remaining[0] <= 0:
            self._dispatch_next(value)
        else:
            remaining[0] -= 1

    return FunctionFilter(this, on_next=on_next, name="skip")
Esempio n. 12
0
def take_last(this, count):
    """Takes a specified number of contiguous elements from the end of an observable sequence.
    This operator accumulates a buffer with a length enough to store
    elements count elements. Upon completion of the source sequence, this
    buffer is drained on the result sequence. This causes the elements to be
    delayed.
    Keyword arguments:
    count: The number of elements to take from the end of the sequence
    """
    q = []

    def on_next(self, x):
        q.append(x)
        if len(q) > count:
            q.pop(0)

    def on_completed(self):
        while len(q):
            v = q.pop(0)
            self._dispatch_next(v)
        self._dispatch_completed()

    return FunctionFilter(this, on_next=on_next, on_completed=on_completed)
Esempio n. 13
0
def some(this, predicate=None):
    """Determines whether some element of an observable sequence satisfies a
    condition if present, else if some items are in the sequence.
    Example:
    result = source.some()
    result = source.some(lambda x: x > 3)
    Keyword arguments:
    predicate -- A function to test each element for a condition.
    Returns {OutputThing} an observable sequence containing a single element
    determining whether some elements in the source sequence pass the test
    in the specified predicate if given, else if some items are in the
    sequence.
    """
    def on_next(self, x):
        self._dispatch_next(True)
        self._dispatch_completed()
        self.disconnect_from_upstream()

    def on_error(self, e):
        self._dispatch_next(False)
        self._dispatch_completed()
        self.disconnect_from_upstream()

    def on_completed(self):
        self._dispatch_next(False)
        self._dispatch_completed()
        self.disconnect_from_upstream()

    if predicate:
        return this.filter(predicate).some()
    else:
        return FunctionFilter(this,
                              on_next=on_next,
                              on_error=on_error,
                              on_completed=on_completed,
                              name="some")