#include "mkql_computation_node_ut.h" #include namespace NKikimr { namespace NMiniKQL { Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) { Y_UNIT_TEST_LLVM(TestOverListAndPartialLists) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data1 = pb.NewDataLiteral(1); const auto data2 = pb.NewDataLiteral(2); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data1, data2}); const auto pgmReturn = pb.FlatMap(list, [&](TRuntimeNode item) { return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)}); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 3); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 4); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverListAndStreams) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(-7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data1, data2}); const auto pgmReturn = pb.FlatMap(list, [&](TRuntimeNode item) { return pb.Iterator(pb.NewList(dataType, {pb.Plus(item), pb.Minus(item)}), {}); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 3); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -3); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverStreamAndPartialLists) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data1 = pb.NewDataLiteral(10); const auto data2 = pb.NewDataLiteral(20); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data1, data2}); const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}), [&](TRuntimeNode item) { return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral(""), "", 0, 0)}); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 0); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 0); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 10); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndPartialLists) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data1 = pb.NewDataLiteral(10); const auto data2 = pb.NewDataLiteral(20); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})), [&](TRuntimeNode item) { return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral(""), "", 0, 0)}); })); const auto& graph = setup.BuildGraph(pgmReturn); const NUdf::TUnboxedValue& iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 0); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 0); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 10); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverStreamAndStreams) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}), [&](TRuntimeNode item) { return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType), {pb.Mod(data, item), pb.Div(data, item)}), {}); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -2); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndStreams) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) { return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType), {pb.Mod(data, item), pb.Div(data, item)}), {}); })); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -2); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) { return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType), {pb.Mod(data, item), pb.Div(data, item)})); })); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -2); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverListAndFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(list, [&](TRuntimeNode item) { return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType), {pb.Mod(data, item), pb.Div(data, item)})); })); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -2); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode) { return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Abs(it); }); })); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverListAndIndependentFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(list, [&](TRuntimeNode) { return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Minus(it); }); })); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndPartialOptionals) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})), [&](TRuntimeNode item) { return pb.Div(data, item); })); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverStreamAndPartialOptionals) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}), [&](TRuntimeNode item) { return pb.Div(data, item); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionals) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(1); const auto data2 = pb.NewDataLiteral(2); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FlatMap(list, [&](TRuntimeNode item) { return pb.Div(data2, item); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverListAndDoubleOptionals) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(1); const auto data2 = pb.NewDataLiteral(2); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FlatMap(list, [&](TRuntimeNode item) { return pb.NewOptional(pb.Div(data2, item)); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT(!item); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialOptionals) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data2 = pb.NewDataLiteral(2); const auto list = pb.NewOptional(data2); const auto pgmReturn = pb.FlatMap(list, [&](TRuntimeNode item) { return pb.Div(item, data2); }); const auto graph = setup.BuildGraph(pgmReturn); const auto value = graph->GetValue(); UNIT_ASSERT(value); UNIT_ASSERT_VALUES_EQUAL(value.template Get(), 1); } Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialLists) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data1 = pb.NewDataLiteral(1); const auto data2 = pb.NewDataLiteral(2); const auto list = pb.NewOptional(data2); const auto pgmReturn = pb.FlatMap(list, [&](TRuntimeNode item) { return pb.Append(pb.AsList(item), data1); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverListAndPartialListsLazy) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data1 = pb.NewDataLiteral(1U); const auto data2 = pb.NewDataLiteral(2U); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data1, data2}); const auto pgmReturn = pb.FlatMap(pb.LazyList(list), [&](TRuntimeNode item) { return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)}); }); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 3); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 4); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionalsLazy) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data0 = pb.NewDataLiteral(0U); const auto data2 = pb.NewDataLiteral(2U); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data2}); const auto pgmReturn = pb.FlatMap(pb.LazyList(list), [&](TRuntimeNode item) { return pb.Div(data2, item); } ); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } #if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u Y_UNIT_TEST_LLVM(TestNarrowWithList) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType::Id)); const auto tupleType = pb.NewTupleType({dataType, dataType, dataType}); const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(-1))}); const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(2)), pb.NewOptional(pb.NewDataLiteral(-2))}); const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(-3))}); const auto list = pb.NewList(tupleType, {data1, data2, data3}); const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }), [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.NewList(dataType, items), [](TRuntimeNode item){ return item; }); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 3); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -3); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestNarrowWithFlow) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType::Id)); const auto tupleType = pb.NewTupleType({dataType, dataType, dataType}); const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(-1))}); const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(2)), pb.NewOptional(pb.NewDataLiteral(-2))}); const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(-3))}); const auto list = pb.NewList(tupleType, {data1, data2, data3}); const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }), [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.ToFlow(pb.NewList(dataType, items)), [](TRuntimeNode item){ return item; }); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 1); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -2); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 3); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -3); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestNarrowWithIndependentFlow) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType::Id)); const auto tupleType = pb.NewTupleType({dataType, dataType, dataType}); const auto data = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral(-1))}); const auto list = pb.NewList(tupleType, {data, data, data}); const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }), [&](TRuntimeNode::TList) { return pb.Map( pb.ToFlow(pb.NewList(pb.NewDataType(NUdf::TDataType::Id), {pb.NewDataLiteral(+1.f), pb.NewDataLiteral(-1.f)})), [&](TRuntimeNode item) { return pb.Minus(item); }); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1.f); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), +1.f); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1.f); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), +1.f); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), -1.f); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), +1.f); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestThinNarrowWithList) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto tupleType = pb.NewTupleType({}); const auto data = pb.NewTuple(tupleType, {}); const auto list = pb.NewList(tupleType, {data, data, data}); const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list), [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }), [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.Replicate(pb.NewDataLiteral(7), pb.NewDataLiteral(3), __FILE__, __LINE__, 0); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue().GetListIterator(); NUdf::TUnboxedValue item; UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(iterator.Next(item)); UNIT_ASSERT_VALUES_EQUAL(item.template Get(), 7); UNIT_ASSERT(!iterator.Next(item)); UNIT_ASSERT(!iterator.Next(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndWideFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) { return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType), {pb.Mod(data, item), pb.Div(data, item)})), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; }); }), [&](TRuntimeNode::TList items) { return pb.NewTuple(items); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item.GetElement(0)); UNIT_ASSERT(!item.GetElement(1)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item.GetElement(0)); UNIT_ASSERT(!item.GetElement(1)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -1); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -2); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +2); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverListAndWideFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list, [&](TRuntimeNode item) { return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType), {pb.Mod(data, item), pb.Div(data, item)})), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; }); }), [&](TRuntimeNode::TList items) { return pb.NewTuple(items); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item.GetElement(0)); UNIT_ASSERT(!item.GetElement(1)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT(!item.GetElement(0)); UNIT_ASSERT(!item.GetElement(1)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +1); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -1); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +33); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -33); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +2); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -2); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +14); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -14); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentWideFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode) { return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; }); }), [&](TRuntimeNode::TList items) { return pb.NewTuple(items); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } Y_UNIT_TEST_LLVM(TestOverListAndIndependentWideFlows) { TSetup setup; TProgramBuilder& pb = *setup.PgmBuilder; const auto data = pb.NewDataLiteral(-100); const auto data0 = pb.NewDataLiteral(0); const auto data1 = pb.NewDataLiteral(3); const auto data2 = pb.NewDataLiteral(7); const auto dataType = pb.NewDataType(NUdf::TDataType::Id); const auto list = pb.NewList(dataType, {data0, data1, data2}); const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list, [&](TRuntimeNode) { return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; }); }), [&](TRuntimeNode::TList items) { return pb.NewTuple(items); } )); const auto graph = setup.BuildGraph(pgmReturn); const auto iterator = graph->GetValue(); NUdf::TUnboxedValue item; UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get(), +100); UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get(), -100); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item)); } #endif } } }