from functools import reduce
import pytest


def add(numbers):
    delimiter = ','
    negatives = []
    positives = []

    if len(numbers) == 0:
        return 0

    if numbers[:2] == '//':
        delimiter = numbers[2]
        numbers = numbers[4:]
    numbers = numbers.replace('\n', delimiter)
    split = numbers.split(delimiter)

    for n in map(lambda x: int(x), split):
        if n < 0:
            negatives.append(n)
        elif n < 1000:
            positives.append(n)

    if len(negatives):
        raise ValueError('Negatives not allowed: ' + ','.join(str(e) for e in negatives))

    return reduce(lambda x, y: x+y, positives)


def test_add_with_0_1_or_2_numbers():
    assert add("") == 0
    assert add("1") == 1
    assert add("1,2") == 3
    assert add("10") == 10


def test_add_with_more_numbers():
    assert add("1,4,5") == 10
    assert add("6,1,0") == 7


def test_add_with_new_lines():
    assert add("1\n2,3") == 6
    assert add("2,3\n6") == 11


def test_add_with_different_delimiters():
    assert add("//;\n1;2") == 3


def test_add_negative_numbers_throw_exception():
    with pytest.raises(ValueError) as excinfo:
        assert add("1,-2,3")
    excinfo.match(r'Negatives not allowed: -2')
    with pytest.raises(ValueError) as excinfo:
        assert add("1,-2,3,-4")
    excinfo.match(r'Negatives not allowed: -2,-4')


def test_add_ignore_big_numbers():
    assert add('1000,2') == 2
