feat, wip: refactoring and simplification of how casts are made.
This commit is contained in:
62
tests/examples/test_example_change_some_fields.py
Normal file
62
tests/examples/test_example_change_some_fields.py
Normal file
@ -0,0 +1,62 @@
|
||||
from collections import namedtuple
|
||||
|
||||
import bonobo
|
||||
from bonobo.config import use_raw_input
|
||||
from bonobo.execution.contexts import GraphExecutionContext
|
||||
from bonobo.util.bags import BagType
|
||||
|
||||
Extracted = namedtuple('Extracted', ['id', 'name', 'value'])
|
||||
ExtractedBT = BagType('ExtractedBT', ['id', 'name', 'value'])
|
||||
|
||||
|
||||
def extract_nt():
|
||||
yield Extracted(id=1, name='Guido', value='.py')
|
||||
yield Extracted(id=2, name='Larry', value='.pl')
|
||||
yield Extracted(id=3, name='Dennis', value='.c')
|
||||
yield Extracted(id=4, name='Yukihiro', value='.rb')
|
||||
|
||||
|
||||
def extract_bt():
|
||||
yield ExtractedBT(id=1, name='Guido', value='.py')
|
||||
yield ExtractedBT(id=2, name='Larry', value='.pl')
|
||||
yield ExtractedBT(id=3, name='Dennis', value='.c')
|
||||
yield ExtractedBT(id=4, name='Yukihiro', value='.rb')
|
||||
|
||||
|
||||
def transform_using_args(id, name, value):
|
||||
yield Extracted(id=id * 2, name=name, value=name.lower() + value)
|
||||
|
||||
|
||||
@use_raw_input
|
||||
def transform_nt(row):
|
||||
yield row._replace(name=row.name.upper())
|
||||
|
||||
|
||||
def StoreInList(buffer: list):
|
||||
def store_in_list(*args, buffer=buffer):
|
||||
buffer.append(args)
|
||||
|
||||
return store_in_list
|
||||
|
||||
|
||||
def test_execution():
|
||||
graph = bonobo.Graph()
|
||||
|
||||
result_args = []
|
||||
result_nt = []
|
||||
result_bt = []
|
||||
|
||||
graph.add_chain(extract_nt, transform_using_args, StoreInList(result_args))
|
||||
graph.add_chain(transform_nt, StoreInList(result_nt), _input=extract_nt)
|
||||
graph.add_chain(extract_bt, transform_using_args, StoreInList(result_bt))
|
||||
|
||||
with GraphExecutionContext(graph) as context:
|
||||
context.run_until_complete()
|
||||
|
||||
assert result_args == [(2, 'Guido', 'guido.py'), (4, 'Larry', 'larry.pl'), (6, 'Dennis', 'dennis.c'),
|
||||
(8, 'Yukihiro', 'yukihiro.rb')]
|
||||
|
||||
assert result_nt == [(1, 'GUIDO', '.py'), (2, 'LARRY', '.pl'), (3, 'DENNIS', '.c'), (4, 'YUKIHIRO', '.rb')]
|
||||
|
||||
assert result_bt == [(2, 'Guido', 'guido.py'), (4, 'Larry', 'larry.pl'), (6, 'Dennis', 'dennis.c'),
|
||||
(8, 'Yukihiro', 'yukihiro.rb')]
|
||||
@ -3,9 +3,10 @@ from unittest.mock import MagicMock
|
||||
import pytest
|
||||
|
||||
from bonobo import Graph
|
||||
from bonobo.constants import EMPTY, NOT_MODIFIED, INHERIT
|
||||
from bonobo.constants import EMPTY
|
||||
from bonobo.execution.contexts.node import NodeExecutionContext, split_token
|
||||
from bonobo.execution.strategies import NaiveStrategy
|
||||
from bonobo.util.envelopes import F_NOT_MODIFIED, F_INHERIT
|
||||
from bonobo.util.testing import BufferingNodeExecutionContext, BufferingGraphExecutionContext
|
||||
|
||||
|
||||
@ -227,32 +228,36 @@ def test_node_lifecycle_with_kill():
|
||||
|
||||
|
||||
def test_split_token():
|
||||
assert split_token(('foo', 'bar')) == (set(), ('foo', 'bar'))
|
||||
assert split_token(()) == (set(), ())
|
||||
assert split_token('') == (set(), ('', ))
|
||||
with pytest.deprecated_call():
|
||||
assert split_token(('foo', 'bar')) == (set(), ('foo', 'bar'))
|
||||
assert split_token(()) == (set(), ())
|
||||
assert split_token('') == (set(), ('', ))
|
||||
|
||||
|
||||
def test_split_token_duplicate():
|
||||
with pytest.raises(ValueError):
|
||||
split_token((NOT_MODIFIED, NOT_MODIFIED))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((INHERIT, INHERIT))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((INHERIT, NOT_MODIFIED, INHERIT))
|
||||
with pytest.deprecated_call():
|
||||
with pytest.raises(ValueError):
|
||||
split_token((F_NOT_MODIFIED, F_NOT_MODIFIED))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((F_INHERIT, F_INHERIT))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((F_INHERIT, F_NOT_MODIFIED, F_INHERIT))
|
||||
|
||||
|
||||
def test_split_token_not_modified():
|
||||
with pytest.raises(ValueError):
|
||||
split_token((NOT_MODIFIED, 'foo', 'bar'))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((NOT_MODIFIED, INHERIT))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((INHERIT, NOT_MODIFIED))
|
||||
assert split_token(NOT_MODIFIED) == ({NOT_MODIFIED}, ())
|
||||
assert split_token((NOT_MODIFIED, )) == ({NOT_MODIFIED}, ())
|
||||
with pytest.deprecated_call():
|
||||
with pytest.raises(ValueError):
|
||||
split_token((F_NOT_MODIFIED, 'foo', 'bar'))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((F_NOT_MODIFIED, F_INHERIT))
|
||||
with pytest.raises(ValueError):
|
||||
split_token((F_INHERIT, F_NOT_MODIFIED))
|
||||
assert split_token(F_NOT_MODIFIED) == ({F_NOT_MODIFIED}, ())
|
||||
assert split_token((F_NOT_MODIFIED, )) == ({F_NOT_MODIFIED}, ())
|
||||
|
||||
|
||||
def test_split_token_inherit():
|
||||
assert split_token(INHERIT) == ({INHERIT}, ())
|
||||
assert split_token((INHERIT, )) == ({INHERIT}, ())
|
||||
assert split_token((INHERIT, 'foo', 'bar')) == ({INHERIT}, ('foo', 'bar'))
|
||||
with pytest.deprecated_call():
|
||||
assert split_token(F_INHERIT) == ({F_INHERIT}, ())
|
||||
assert split_token((F_INHERIT, )) == ({F_INHERIT}, ())
|
||||
assert split_token((F_INHERIT, 'foo', 'bar')) == ({F_INHERIT}, ('foo', 'bar'))
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from bonobo.constants import INHERIT
|
||||
from bonobo.util.envelopes import AppendingEnvelope
|
||||
from bonobo.util.testing import BufferingNodeExecutionContext
|
||||
|
||||
messages = [
|
||||
@ -8,7 +8,7 @@ messages = [
|
||||
|
||||
|
||||
def append(*args):
|
||||
return INHERIT, '!'
|
||||
return AppendingEnvelope('!')
|
||||
|
||||
|
||||
def test_inherit():
|
||||
|
||||
@ -15,4 +15,6 @@ def test_not_modified():
|
||||
with BufferingNodeExecutionContext(useless) as context:
|
||||
context.write_sync(*input_messages)
|
||||
|
||||
assert context.get_buffer() == input_messages
|
||||
result = context.get_buffer()
|
||||
print(result)
|
||||
assert result == input_messages
|
||||
|
||||
65
tests/nodes/test_casts.py
Normal file
65
tests/nodes/test_casts.py
Normal file
@ -0,0 +1,65 @@
|
||||
from collections import namedtuple
|
||||
from typing import Callable
|
||||
|
||||
import pytest
|
||||
|
||||
from bonobo.constants import EMPTY
|
||||
from bonobo.util.bags import BagType
|
||||
from bonobo.util.envelopes import Envelope
|
||||
from bonobo.util.testing import BufferingNodeExecutionContext
|
||||
|
||||
MyTuple = namedtuple('MyTuple', ['a', 'b', 'c'])
|
||||
MyBag = BagType('MyBag', ['a', 'b', 'c'])
|
||||
|
||||
|
||||
class MyCustomType():
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
|
||||
def as_tuple(self):
|
||||
return MyBag(*self.args)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(['factory', 'expected', 'expected_item0'], [
|
||||
[lambda: (1, 2, 3), tuple, int],
|
||||
[lambda: Envelope((1, 2, 3)), tuple, int],
|
||||
[lambda: MyTuple(1, 2, 3), MyTuple, int],
|
||||
[lambda: Envelope(MyTuple(1, 2, 3)), MyTuple, int],
|
||||
[lambda: MyBag(1, 2, 3), MyBag, int],
|
||||
[lambda: Envelope(MyBag(1, 2, 3)), MyBag, int],
|
||||
[lambda: MyCustomType(1, 2, 3), tuple, MyCustomType],
|
||||
[lambda: Envelope(MyCustomType(1, 2, 3)), tuple, MyCustomType],
|
||||
])
|
||||
def test_casts_after_output(factory: Callable, expected, expected_item0):
|
||||
def transform():
|
||||
yield factory()
|
||||
yield factory()
|
||||
|
||||
with BufferingNodeExecutionContext(transform) as context:
|
||||
context.write_sync(EMPTY)
|
||||
|
||||
result = context.get_buffer()
|
||||
assert expected == type(result[0])
|
||||
assert expected_item0 == type(result[0][0])
|
||||
assert expected == type(result[1])
|
||||
assert expected_item0 == type(result[1][0])
|
||||
|
||||
|
||||
def test_cast_after_returning_custom_type():
|
||||
def transform():
|
||||
yield MyCustomType(1, 2, 3)
|
||||
yield MyCustomType(4, 5, 6)
|
||||
|
||||
with BufferingNodeExecutionContext(transform) as context:
|
||||
context.write_sync(EMPTY)
|
||||
result = context.get_buffer()
|
||||
assert tuple == type(result[0])
|
||||
assert tuple == type(result[1])
|
||||
assert MyCustomType == type(result[0][0])
|
||||
assert MyCustomType == type(result[1][0])
|
||||
|
||||
with BufferingNodeExecutionContext(MyCustomType.as_tuple) as context:
|
||||
context.write_sync(*result)
|
||||
result = context.get_buffer()
|
||||
assert MyBag == type(result[0])
|
||||
assert MyBag == type(result[1])
|
||||
@ -3,7 +3,7 @@ import pytest
|
||||
from unittest.mock import sentinel
|
||||
|
||||
from bonobo.constants import BEGIN
|
||||
from bonobo.structs import Graph
|
||||
from bonobo.structs.graphs import Graph
|
||||
|
||||
identity = lambda x: x
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from bonobo.constants import Token
|
||||
from bonobo.structs.tokens import Token
|
||||
|
||||
|
||||
def test_token_repr():
|
||||
|
||||
@ -2,7 +2,7 @@ from bonobo.config.processors import use_context_processor
|
||||
from bonobo.constants import BEGIN, END
|
||||
from bonobo.execution.contexts.graph import GraphExecutionContext
|
||||
from bonobo.execution.strategies import NaiveStrategy
|
||||
from bonobo.structs import Graph
|
||||
from bonobo.structs.graphs import Graph
|
||||
|
||||
|
||||
def generate_integers():
|
||||
|
||||
Reference in New Issue
Block a user