Skip to content

Commit

Permalink
ISlice.fill_into is tested with Hypothesis. Improve docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
ynikitenko committed Apr 28, 2021
1 parent ed5d74d commit 365c8bd
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 25 deletions.
9 changes: 9 additions & 0 deletions lena/flow/iterators.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ def fill_into(self, element, value):
Values are filled in the order defined by *(start, stop, step)*.
*Element* must have a ``fill(value)`` method.
When the filling should stop,
:exc:`.LenaStopFill` is raised
(:class:`.Split` handles this normally).
Sometimes for *step* more than one
:exc:`.LenaStopFill` will be raised
before reaching *stop* elements.
Early exceptions are an optimization and
don't affect the correctness of this method.
"""
if self._index > self._next_index:
try:
Expand Down
114 changes: 89 additions & 25 deletions tests/flow/test_iterators.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
from __future__ import print_function

import pytest
import sys
from itertools import count, islice

import pytest
from hypothesis import strategies as s
from hypothesis import given

import lena.flow
from lena.core import Source, LenaStopFill
from lena.flow import DropContext, CountFrom
from lena.flow.iterators import ISlice, Reverse
from tests.examples.fill import StoreFilled

from hypothesis import strategies as s
from hypothesis import given
# all bugs converged to at most 3.
hypo_int_max = 20

Expand Down Expand Up @@ -52,7 +54,7 @@ def test_count_from():
assert list(islice(it(), 5)) == list(range(10, 20, 2))


def test_islice():
def test_islice_run():
c = count()
### test __init__ and run ###
# stop works
Expand All @@ -68,25 +70,6 @@ def test_islice():
isl = ISlice(0, 10, 2)
list(isl.run(count())) == list(range(0, 10, 2))

### test fill ###
store = StoreFilled()
# start, stop work
isl = ISlice(10, 15)
for i in range(0, 15):
isl.fill_into(store, i)
assert store.list == list(range(10, 15))
with pytest.raises(LenaStopFill):
isl = ISlice(10, 15)
for i in range(0, 16):
isl.fill_into(store, i)
# step works
store.reset()
isl = ISlice(10, 20, 2)
# 18 will be filled last
for i in range(0, 19):
isl.fill_into(store, i)
assert store.list == list(range(10, 20, 2))


def test_negative_islice():
# negative stop
Expand Down Expand Up @@ -154,8 +137,9 @@ def test_negative_islice():
assert list(isl.run(iter(data))) == [0, 1]


start_stop_s = s.one_of(s.none(), s.integers(-hypo_int_max, hypo_int_max))
step_s = s.integers(1, hypo_int_max)
start_stop_s = s.one_of(s.none(),
s.integers(-hypo_int_max, hypo_int_max))
step_s = s.integers(1, hypo_int_max)

@given(start=start_stop_s, stop=start_stop_s, step=step_s,
data_len=s.integers(0, hypo_int_max))
Expand All @@ -165,6 +149,86 @@ def test_islice_hypothesis(start, stop, step, data_len):
assert list(isl.run(iter(data))) == data[start:stop:step]


def test_islice_fill_into():
store = StoreFilled()
# start, stop work
isl = ISlice(10, 15)
for i in range(0, 15):
isl.fill_into(store, i)
assert store.list == list(range(10, 15))
with pytest.raises(LenaStopFill):
isl = ISlice(10, 15)
for i in range(0, 16):
isl.fill_into(store, i)
# step works
store.reset()
isl = ISlice(10, 20, 2)
# 18 will be filled last
for i in range(0, 19):
isl.fill_into(store, i)
assert store.list == list(range(10, 20, 2))

# found by hypothesis
store = StoreFilled()
isl = ISlice(None, None, 1)
data = [0]
for val in data:
isl.fill_into(store, val)
assert store.list == [0]

store = StoreFilled()
isl = ISlice(None, 1, 2)
data = [0, 1]
with pytest.raises(LenaStopFill):
for val in data:
isl.fill_into(store, val)
assert store.list == [0]

store = StoreFilled()
isl = ISlice(None, 2, 2)
data = [0, 1]
with pytest.raises(LenaStopFill):
for val in data:
isl.fill_into(store, val)
assert store.list == [0]


start_stop_non_neg = s.one_of(s.none(),
s.integers(0, hypo_int_max))
@given(start=start_stop_non_neg,
# stop=s.integers(0, hypo_int_max),
stop=start_stop_non_neg,
step=step_s,
data_len=s.integers(1, hypo_int_max))
def test_islice_hypothesis_fill_into(start, stop, step, data_len):
# data_len >= 1, because if the flow is empty,
# there is nothing to check.
data = list(range(data_len))
isl = ISlice(start, stop, step)
if start is None:
start = 0
if stop is None:
stop = sys.maxsize
store = StoreFilled()
if True:
# to check this condition is pretty hard. For earliest raise
# we don't check about when and whether LenaStopFill is raised.
# if stop == 0 or data_len > stop or (data_len == stop and step != 1):
# if stop == 0 or stop < data_len:
try:
for val in data:
isl.fill_into(store, val)
except LenaStopFill:
assert store.list == data[start:stop:step]
else:
assert store.list == data[start:stop:step]
# assert "should had raised" and False
else:
for val in data:
isl.fill_into(store, val)
assert store.list == data[start:stop:step]


def test_reverse():
r = Reverse()
assert list(r.run(iter([]))) == []
Expand Down

0 comments on commit 365c8bd

Please sign in to comment.