diff --git a/rethinkdb_mock/ast.py b/rethinkdb_mock/ast.py index 56aab39..97ccf9b 100644 --- a/rethinkdb_mock/ast.py +++ b/rethinkdb_mock/ast.py @@ -8,6 +8,7 @@ from future.utils import iteritems from future.utils import text_type from past.utils import old_div +from rethinkdb.errors import ReqlNonExistenceError from rethinkdb_mock import ast_base from rethinkdb_mock import joins @@ -256,6 +257,12 @@ class Or(BinOp): class Reduce(ByFuncBase): def do_run(self, sequence, reduce_fn, arg, scope): + if len(sequence) == 0: + raise ReqlNonExistenceError("Cannot reduce over an empty stream") + + if len(sequence) == 1: + return sequence[0] + first, second = sequence[0:2] result = reduce_fn([first, second]) for elem in sequence[2:]: diff --git a/tests/functional/test_misc.py b/tests/functional/test_misc.py index 80aacc0..7ec598b 100644 --- a/tests/functional/test_misc.py +++ b/tests/functional/test_misc.py @@ -1,4 +1,5 @@ from rethinkdb import r +from rethinkdb.errors import ReqlNonExistenceError from rethinkdb.errors import RqlRuntimeError from tests.common import as_db_and_table from tests.common import assertEqual @@ -399,6 +400,32 @@ def test_reduce_1(self, conn): ) assertEqual(expected, result) + def test_reduce_one(self, conn): + expected = {"count": 1} + result = ( + r.expr([{"count": 1}]) + .reduce( + lambda left, right: { + "count": left["count"] + right["count"], + } + ) + .run(conn) + ) + assertEqual(expected, result) + + def test_reduce_errors(self, conn): + err = None + try: + r.expr([]).reduce( + lambda left, right: { + "count": left["count"] + right["count"], + } + ).run(conn) + except ReqlNonExistenceError as e: + err = e + + assert isinstance(err, ReqlNonExistenceError) + class TestBranch(MockTest): @staticmethod