def test_zip_error(): error = RuntimeError("simulated error") f_a = f_return("a") f_b = f_return_error(error) f_c = f_return("c") future = f_zip(f_a, f_b, f_c) assert future.exception() is error
def test_num_types(): xint = f_proxy(f_return(123)) xfloat = f_proxy(f_return(1.23)) assert float(xint) == 123.0 assert complex(xint) == complex(123) assert int(xfloat) == 1
def test_bool(): xtrue = f_proxy(f_return(True)) xfalse = f_proxy(f_return(False)) xempty = f_proxy(f_return([])) # All of these count as truthy, as we want to allow testing if # a future was returned without blocking assert xtrue assert xfalse assert xempty
def test_len(): xlist = f_proxy(f_return([1, 2, 3])) xint = f_proxy(f_return(42)) xstr = f_proxy(f_return("hello")) assert len(xlist) == 3 assert len(xstr) == 5 with pytest.raises(TypeError) as exc: len(xint) assert "has no len" in str(exc.value)
def test_sign(): xint = f_proxy(f_return(123)) xnegint = f_proxy(f_return(-123)) assert -xint == -123 assert +xint == 123 assert abs(xnegint) == 123 assert ~xint == -124 assert ~xnegint == 122 assert ~~xint == 123 assert ~~xnegint == -123
def test_flat_map_error(): map_in = f_return(0) # This one should fail... mapped = f_flat_map(map_in, div10) # Now map it through an error handler mapped = f_flat_map(mapped, error_fn=lambda ex: f_return(str(ex))) result = mapped.result() assert "division" in result
def test_bits(): xbin = f_proxy(f_return(0b00110)) assert xbin << 1 == 0b01100 assert xbin >> 1 == 0b00011 assert xbin & 0b10010 == 0b00010 assert xbin | 0b10010 == 0b10110 assert xbin ^ 0b10010 == 0b10100
def test_or_gc(): """Inputs to f_or can be garbage collected if only output is held.""" inputs = [f_return(True), f_return(False)] weak_input = weakref.ref(inputs[0]) out = f_or(*inputs) assert out.result() is True # the input future is still live since inputs is still live gc.collect() assert weak_input() # But if we wipe out inputs, then it should be collected inputs[:] = [] gc.collect() assert not weak_input()
def test_math_basic(): xstr = f_proxy(f_return("xyz")) xint = f_proxy(f_return(12)) xfloat = f_proxy(f_return(5.0)) assert xstr * 2 == "xyzxyz" assert xstr + "abc" == "xyzabc" assert xint + 2 == 14 assert xint - 2 == 10 assert xint % 10 == 2 assert xint / 2 == 6 assert xint**2 == 144 assert xfloat // 2.0 == 2.0 assert divmod(xint, 5) == (2, 2)
def test_attrs(): xdict = f_proxy(f_return({"foo": "bar", "baz": "quux"})) assert sorted(xdict.keys()) == ["baz", "foo"] assert sorted(xdict.values()) == ["bar", "quux"] with pytest.raises(AttributeError): xdict.no_such_attr()
def test_math_round(): xstr = f_proxy(f_return("xyz")) xint = f_proxy(f_return(12)) xfloat = f_proxy(f_return(5.5)) assert round(xint) == 12 assert round(xfloat) == 6.0 assert floor(xint) == 12 assert floor(xfloat) == 5.0 assert ceil(xint) == 12 assert ceil(xfloat) == 6.0 assert trunc(xint) == 12 assert trunc(xfloat) == 5.0 with pytest.raises(Exception): assert round(xstr) == "foo"
def test_iter(): xlist = f_proxy(f_return(["a", "b", "c"])) xstr = f_proxy(f_return("xyz")) xint = f_proxy(f_return(12)) list_elems = [] for elem in xlist: list_elems.append(elem) assert list_elems == ["a", "b", "c"] str_elems = [] for elem in xstr: str_elems.append(elem) assert str_elems == ["x", "y", "z"] with pytest.raises(TypeError) as exc: for _ in xint: pass assert "not iterable" in str(exc.value)
def test_zip_cancel(): f_a = f_return("a") f_b = Future() f_c = Future() future = f_zip(f_a, f_b, f_c) future.cancel() assert f_b.cancelled() assert f_c.cancelled()
def test_flat_map_error_fn_raises(): map_in = f_return(0) # This one should fail... mapped = f_flat_map(map_in, div10) # Now map it through an error handler mapped = f_flat_map(mapped, error_fn=raise_str) ex = mapped.exception() assert "division" in str(ex) assert "oops, an error" in str(ex)
def test_zip_inner_cancel(): f_a = f_return("a") f_b = Future() f_c = Future() future = f_zip(f_a, f_b, f_c) assert f_b.cancel() # Cancelling the inner future should cause the outer # future to also become cancelled, as well as the # other inner futures. assert f_c.cancelled() assert future.cancelled()
def test_dict(): xdict = f_proxy(f_return({"foo": "bar", "baz": "quux"})) assert xdict["foo"] == "bar" assert "baz" in xdict xdict["added"] = 123 assert "added" in xdict del xdict["foo"] assert "foo" not in xdict with pytest.raises(KeyError): assert xdict["no_such_key"]
def test_f_apply_mixed(): applied = f_apply( f_return(dump_args), f_return("a"), f_return("b"), f_return("c"), key1=f_return("val1"), key2=f_return("val2"), key3=f_return("val3"), ) assert applied.result() == ( ("a", "b", "c"), { "key1": "val1", "key2": "val2", "key3": "val3" }, )
def test_and_large(): inputs = [f_return(True) for _ in range(0, 100000)] assert f_and(*inputs).result() is True
def test_sequence(): f = f_sequence([f_return("a"), f_return("b"), f_return("c")]) assert f.result() == ["a", "b", "c"]
def test_zip_two(): future = f_zip(f_return("a"), f_return("b")) assert future.result() == ("a", "b")
def test_zip_three(): f_a = f_return("a") f_b = f_return("b") f_c = f_return("c") future = f_zip(f_a, f_b, f_c) assert future.result() == ("a", "b", "c")
def test_or_large(): inputs = [f_return(0) for _ in range(0, 100000)] assert f_or(*inputs).result() == 0
def test_zip_single(): value = "foobar" future = f_zip(f_return(value)) assert future.result() == (value, ) assert "ZipTuple1" in repr(future)
def div10(x): try: return f_return(10 / x) except Exception as ex: return f_return_error(ex)
def test_sequence_large(): limit = 100000 f = f_sequence([f_return(i) for i in range(0, limit)]) assert f.result() == list(range(0, limit))
def test_flat_map(): map_in = f_return(10) mapped = f_flat_map(map_in, div10) assert mapped.result() == 1
def test_flat_map_nothing(): map_in = f_return(10) mapped = f_flat_map(map_in) assert mapped.result() == 10
def div100by_async(x): return f_return(100.0 / x)
def test_zip_large(): fs = [f_return(i) for i in range(0, 100000)] future = f_zip(*fs) result = future.result() assert result[0:5] == (0, 1, 2, 3, 4) assert len(result) == 100000
def test_sequence_error(): error = ValueError("simulated error") f = f_sequence([f_return("a"), f_return_error(error), f_return("c")]) assert f.exception() is error