yql_expr_builder_ut.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. #include "yql_expr.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. namespace NYql {
  4. Y_UNIT_TEST_SUITE(TExprBuilder) {
  5. Y_UNIT_TEST(TestEmpty) {
  6. TExprContext ctx;
  7. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  8. .Build(), yexception);
  9. }
  10. Y_UNIT_TEST(TestRootAtom) {
  11. TExprContext ctx;
  12. auto res = ctx.Builder(TPositionHandle()).Atom("ABC").Build();
  13. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Atom);
  14. UNIT_ASSERT_VALUES_EQUAL(res->Content(), "ABC");
  15. }
  16. Y_UNIT_TEST(TestRootAtomTwice) {
  17. TExprContext ctx;
  18. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  19. .Atom("ABC")
  20. .Atom("ABC")
  21. .Build(), yexception);
  22. }
  23. Y_UNIT_TEST(TestRootEmptyList) {
  24. TExprContext ctx;
  25. auto res = ctx.Builder(TPositionHandle()).List().Seal().Build();
  26. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
  27. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 0);
  28. }
  29. Y_UNIT_TEST(TestRootEmptyListTwice) {
  30. TExprContext ctx;
  31. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  32. .List()
  33. .List()
  34. .Build(), yexception);
  35. }
  36. Y_UNIT_TEST(TestListWithAtoms) {
  37. TExprContext ctx;
  38. auto res = ctx.Builder(TPositionHandle())
  39. .List()
  40. .Atom(0, "ABC")
  41. .Atom(1, "XYZ")
  42. .Seal()
  43. .Build();
  44. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
  45. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  46. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
  47. UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
  48. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  49. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
  50. }
  51. Y_UNIT_TEST(TestMismatchChildIndex) {
  52. TExprContext ctx;
  53. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  54. .List()
  55. .Atom(1, "")
  56. .Build(), yexception);
  57. }
  58. Y_UNIT_TEST(TestListWithAdd) {
  59. TExprContext ctx;
  60. auto res = ctx.Builder(TPositionHandle())
  61. .List()
  62. .Add(0, ctx.Builder(TPositionHandle()).Atom("ABC").Build())
  63. .Atom(1, "XYZ")
  64. .Seal()
  65. .Build();
  66. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
  67. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  68. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
  69. UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
  70. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  71. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
  72. }
  73. Y_UNIT_TEST(TestNestedListWithAtoms) {
  74. TExprContext ctx;
  75. auto res = ctx.Builder(TPositionHandle())
  76. .List()
  77. .List(0)
  78. .Atom(0, "ABC")
  79. .Atom(1, "DEF")
  80. .Seal()
  81. .Atom(1, "XYZ")
  82. .Seal()
  83. .Build();
  84. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
  85. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  86. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::List);
  87. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
  88. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom);
  89. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC");
  90. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
  91. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF");
  92. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  93. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
  94. }
  95. Y_UNIT_TEST(TestWrongLevelBuild) {
  96. TExprContext ctx;
  97. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  98. .List()
  99. .Build(), yexception);
  100. }
  101. Y_UNIT_TEST(TestWrongLevelSeal) {
  102. TExprContext ctx;
  103. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  104. .Seal(), yexception);
  105. }
  106. Y_UNIT_TEST(TestCallableWithAtoms) {
  107. TExprContext ctx;
  108. auto res = ctx.Builder(TPositionHandle())
  109. .Callable("Func")
  110. .Atom(0, "ABC")
  111. .Atom(1, "XYZ")
  112. .Seal()
  113. .Build();
  114. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable);
  115. UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func");
  116. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  117. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
  118. UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
  119. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  120. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
  121. }
  122. Y_UNIT_TEST(TestNestedCallableWithAtoms) {
  123. TExprContext ctx;
  124. auto res = ctx.Builder(TPositionHandle())
  125. .Callable("Func1")
  126. .Callable(0, "Func2")
  127. .Atom(0, "ABC")
  128. .Atom(1, "DEF")
  129. .Seal()
  130. .Atom(1, "XYZ")
  131. .Seal()
  132. .Build();
  133. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable);
  134. UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func1");
  135. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  136. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Callable);
  137. UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "Func2");
  138. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
  139. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom);
  140. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC");
  141. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
  142. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF");
  143. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  144. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
  145. }
  146. Y_UNIT_TEST(TestRootWorld) {
  147. TExprContext ctx;
  148. auto res = ctx.Builder(TPositionHandle()).World().Build();
  149. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::World);
  150. }
  151. Y_UNIT_TEST(TestCallableWithWorld) {
  152. TExprContext ctx;
  153. auto res = ctx.Builder(TPositionHandle())
  154. .Callable("Func")
  155. .World(0)
  156. .Seal()
  157. .Build();
  158. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable);
  159. UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func");
  160. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 1);
  161. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::World);
  162. }
  163. Y_UNIT_TEST(TestIncompleteRootLambda) {
  164. TExprContext ctx;
  165. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  166. .Lambda()
  167. .Build(), yexception);
  168. }
  169. Y_UNIT_TEST(TestIncompleteInnerLambda) {
  170. TExprContext ctx;
  171. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  172. .List()
  173. .Lambda()
  174. .Seal()
  175. .Build(), yexception);
  176. }
  177. Y_UNIT_TEST(TestRootLambda) {
  178. TExprContext ctx;
  179. auto res = ctx.Builder(TPositionHandle()).Lambda().Atom("ABC").Seal().Build();
  180. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  181. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  182. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  183. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0);
  184. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  185. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "ABC");
  186. }
  187. Y_UNIT_TEST(TestRootLambdaWithBodyAsSet) {
  188. TExprContext ctx;
  189. auto res = ctx.Builder(TPositionHandle())
  190. .Lambda()
  191. .Set(ctx.Builder(TPositionHandle()).Atom("ABC").Build())
  192. .Seal()
  193. .Build();
  194. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  195. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  196. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  197. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0);
  198. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
  199. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "ABC");
  200. }
  201. Y_UNIT_TEST(TestInnerLambdaWithParam) {
  202. TExprContext ctx;
  203. auto res = ctx.Builder(TPositionHandle())
  204. .List()
  205. .Lambda(0)
  206. .Param("x")
  207. .Atom("ABC")
  208. .Seal()
  209. .Seal()
  210. .Build();
  211. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
  212. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 1);
  213. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Lambda);
  214. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
  215. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Arguments);
  216. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().ChildrenSize(), 1);
  217. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Type(), TExprNode::Argument);
  218. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Content(), "x");
  219. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
  220. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "ABC");
  221. }
  222. Y_UNIT_TEST(TestDuplicateLambdaParamNames) {
  223. TExprContext ctx;
  224. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  225. .Lambda()
  226. .Param("x")
  227. .Param("x")
  228. .Atom("ABC")
  229. .Seal()
  230. .Build(), yexception);
  231. }
  232. Y_UNIT_TEST(TestParamAtRoot) {
  233. TExprContext ctx;
  234. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  235. .Param("aaa")
  236. .Build(), yexception);
  237. }
  238. Y_UNIT_TEST(TestParamInList) {
  239. TExprContext ctx;
  240. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  241. .List()
  242. .Param("aaa")
  243. .Seal()
  244. .Build(), yexception);
  245. }
  246. Y_UNIT_TEST(TestParamInCallable) {
  247. TExprContext ctx;
  248. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  249. .Callable("Func")
  250. .Param("aaa")
  251. .Seal()
  252. .Build(), yexception);
  253. }
  254. Y_UNIT_TEST(TestParamAfterLambdaBody) {
  255. TExprContext ctx;
  256. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  257. .Lambda()
  258. .Param("aaa")
  259. .Atom("ABC")
  260. .Param("bbb")
  261. .Seal()
  262. .Build(), yexception);
  263. }
  264. Y_UNIT_TEST(TestIndexedAtomAtRoot) {
  265. TExprContext ctx;
  266. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  267. .Atom(0, "ABC")
  268. .Build(), yexception);
  269. }
  270. Y_UNIT_TEST(TestIndexedListAtRoot) {
  271. TExprContext ctx;
  272. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  273. .List(0)
  274. .Seal()
  275. .Build(), yexception);
  276. }
  277. Y_UNIT_TEST(TestIndexedWorldAtRoot) {
  278. TExprContext ctx;
  279. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  280. .World(0)
  281. .Build(), yexception);
  282. }
  283. Y_UNIT_TEST(TestIndexedCallableAtRoot) {
  284. TExprContext ctx;
  285. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  286. .Callable(0, "Func")
  287. .Seal()
  288. .Build(), yexception);
  289. }
  290. Y_UNIT_TEST(TestIndexedLambdaAtRoot) {
  291. TExprContext ctx;
  292. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  293. .Lambda(0)
  294. .Atom("ABC")
  295. .Seal()
  296. .Build(), yexception);
  297. }
  298. Y_UNIT_TEST(TestWrongIndexAtomAtLambda) {
  299. TExprContext ctx;
  300. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  301. .Lambda()
  302. .Atom(1, "ABC")
  303. .Seal()
  304. .Build(), yexception);
  305. }
  306. Y_UNIT_TEST(TestWrongIndexListAtLambda) {
  307. TExprContext ctx;
  308. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  309. .Lambda()
  310. .List(1)
  311. .Seal()
  312. .Seal()
  313. .Build(), yexception);
  314. }
  315. Y_UNIT_TEST(TestWrongIndexWorldAtLambda) {
  316. TExprContext ctx;
  317. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  318. .Lambda()
  319. .World(1)
  320. .Seal()
  321. .Build(), yexception);
  322. }
  323. Y_UNIT_TEST(TestWrongIndexCallableAtLambda) {
  324. TExprContext ctx;
  325. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  326. .Lambda()
  327. .Callable(1, "Func")
  328. .Seal()
  329. .Seal()
  330. .Build(), yexception);
  331. }
  332. Y_UNIT_TEST(TestWrongIndexLambdaAtLambda) {
  333. TExprContext ctx;
  334. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  335. .Lambda()
  336. .Lambda(1)
  337. .Atom("ABC")
  338. .Seal()
  339. .Seal()
  340. .Build(), yexception);
  341. }
  342. Y_UNIT_TEST(TestAddAtLambda) {
  343. TExprContext ctx;
  344. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
  345. .Lambda()
  346. .Add(1, ctx.Builder(TPositionHandle()).Atom("ABC").Build())
  347. .Seal()
  348. .Build(), yexception);
  349. }
  350. Y_UNIT_TEST(TestLambdaWithArgAsBody) {
  351. TExprContext ctx;
  352. auto res = ctx.Builder(TPositionHandle())
  353. .Lambda()
  354. .Param("x")
  355. .Param("y")
  356. .Arg("x")
  357. .Seal()
  358. .Build();
  359. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  360. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  361. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  362. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
  363. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  364. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
  365. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
  366. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
  367. UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0));
  368. }
  369. Y_UNIT_TEST(TestIndexedArgAsLambdaBody) {
  370. TExprContext ctx;
  371. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda()
  372. .Param("x")
  373. .Arg(1, "x")
  374. .Seal()
  375. .Build(), yexception);
  376. }
  377. Y_UNIT_TEST(TestWrongArgName) {
  378. TExprContext ctx;
  379. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda()
  380. .Param("x")
  381. .Arg("y")
  382. .Seal()
  383. .Build(), yexception);
  384. }
  385. Y_UNIT_TEST(TestLambdaWithArgInCallables) {
  386. TExprContext ctx;
  387. auto res = ctx.Builder(TPositionHandle())
  388. .Lambda()
  389. .Param("x")
  390. .Param("y")
  391. .Callable("+")
  392. .Arg(0, "y")
  393. .Arg(1, "x")
  394. .Seal()
  395. .Seal()
  396. .Build();
  397. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  398. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  399. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  400. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
  401. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  402. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
  403. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
  404. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
  405. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Callable);
  406. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "+");
  407. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 2);
  408. UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(1));
  409. UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0));
  410. }
  411. Y_UNIT_TEST(TestNestedScopeInLambda) {
  412. TExprContext ctx;
  413. auto res = ctx.Builder(TPositionHandle())
  414. .Lambda()
  415. .Param("x")
  416. .Param("y")
  417. .Callable("Apply")
  418. .Lambda(0)
  419. .Param("x")
  420. .Callable("+")
  421. .Arg(0, "x")
  422. .Arg(1, "y")
  423. .Seal()
  424. .Seal()
  425. .Seal()
  426. .Seal()
  427. .Build();
  428. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  429. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  430. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  431. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
  432. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  433. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
  434. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
  435. UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
  436. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Callable);
  437. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "Apply");
  438. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 1);
  439. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Type(), TExprNode::Lambda);
  440. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().ChildrenSize(), 1);
  441. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Type(), TExprNode::Argument);
  442. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Content(), "x");
  443. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Type(), TExprNode::Callable);
  444. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Content(), "+");
  445. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->ChildrenSize(), 2);
  446. // nested x
  447. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(0),
  448. res->Child(1)->Head().Head().Child(0));
  449. // outer y
  450. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(1),
  451. res->Head().Child(1));
  452. }
  453. Y_UNIT_TEST(TestNonIndexedArg) {
  454. TExprContext ctx;
  455. UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda()
  456. .Param("x")
  457. .Callable("f")
  458. .Arg("x")
  459. .Seal()
  460. .Seal()
  461. .Build(), yexception);
  462. }
  463. Y_UNIT_TEST(TestApplyLambdaArgAsRoot) {
  464. TExprContext ctx;
  465. auto lambda = ctx.Builder(TPositionHandle())
  466. .Lambda()
  467. .Param("x")
  468. .Arg("x")
  469. .Seal()
  470. .Build();
  471. auto res = ctx.Builder(TPositionHandle())
  472. .Lambda()
  473. .Param("y")
  474. .Apply(lambda).With(0, "y").Seal()
  475. .Seal()
  476. .Build();
  477. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  478. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  479. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  480. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
  481. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  482. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
  483. UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0));
  484. }
  485. Y_UNIT_TEST(TestApplyLambdaArgInContainer) {
  486. TExprContext ctx;
  487. auto lambda = ctx.Builder(TPositionHandle())
  488. .Lambda()
  489. .Param("x")
  490. .Arg("x")
  491. .Seal()
  492. .Build();
  493. auto res = ctx.Builder(TPositionHandle())
  494. .Lambda()
  495. .Param("y")
  496. .List()
  497. .Apply(0, lambda).With(0, "y").Seal()
  498. .Seal()
  499. .Seal()
  500. .Build();
  501. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  502. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  503. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  504. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
  505. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  506. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
  507. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::List);
  508. UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 1);
  509. UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(0));
  510. }
  511. Y_UNIT_TEST(TestApplyPartialLambdaArgAsRoot) {
  512. TExprContext ctx;
  513. auto lambda = ctx.Builder(TPositionHandle())
  514. .Lambda()
  515. .Param("x")
  516. .Callable("Func1")
  517. .Callable(0, "Func2")
  518. .Atom(0, "ABC")
  519. .Arg(1, "x")
  520. .Seal()
  521. .Seal()
  522. .Seal()
  523. .Build();
  524. auto res = ctx.Builder(TPositionHandle())
  525. .Lambda()
  526. .Param("y")
  527. .ApplyPartial(lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal()
  528. .Seal()
  529. .Build();
  530. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  531. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  532. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  533. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
  534. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  535. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
  536. UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0));
  537. }
  538. Y_UNIT_TEST(TestApplyPartialLambdaArgInContainer) {
  539. TExprContext ctx;
  540. auto lambda = ctx.Builder(TPositionHandle())
  541. .Lambda()
  542. .Param("x")
  543. .Callable("Func1")
  544. .Callable(0, "Func2")
  545. .Atom(0, "ABC")
  546. .Arg(1, "x")
  547. .Seal()
  548. .Seal()
  549. .Seal()
  550. .Build();
  551. auto res = ctx.Builder(TPositionHandle())
  552. .Lambda()
  553. .Param("y")
  554. .Callable("Func3")
  555. .ApplyPartial(0, lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal()
  556. .Seal()
  557. .Seal()
  558. .Build();
  559. UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
  560. UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
  561. UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
  562. UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
  563. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
  564. UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
  565. UNIT_ASSERT_EQUAL(res->Child(1)->Head().Child(1), res->Head().Child(0));
  566. }
  567. Y_UNIT_TEST(TestApplyOuterArg) {
  568. TExprContext ctx;
  569. auto ast = ctx.Builder(TPositionHandle())
  570. .Lambda()
  571. .Param("x")
  572. .Callable("Func1")
  573. .Atom(0, "p1")
  574. .Lambda(1)
  575. .Callable("Func2")
  576. .Atom(0, "ABC")
  577. .Arg(1, "x")
  578. .Seal()
  579. .Seal()
  580. .Seal()
  581. .Seal()
  582. .Build();
  583. auto res1 = ctx.Builder(TPositionHandle())
  584. .Lambda()
  585. .Param("y")
  586. .Callable("Func3")
  587. .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1))
  588. .WithNode(*ast->Head().Child(0), "y").Seal()
  589. .Seal()
  590. .Seal()
  591. .Build();
  592. UNIT_ASSERT_VALUES_EQUAL(res1->Type(), TExprNode::Lambda);
  593. UNIT_ASSERT_VALUES_EQUAL(res1->ChildrenSize(), 2);
  594. UNIT_ASSERT_VALUES_EQUAL(res1->Head().Type(), TExprNode::Arguments);
  595. UNIT_ASSERT_VALUES_EQUAL(res1->Head().ChildrenSize(), 1);
  596. UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Type(), TExprNode::Argument);
  597. UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Content(), "y");
  598. UNIT_ASSERT_EQUAL(res1->Child(1)->Head().Child(1), res1->Head().Child(0));
  599. auto atom = ctx.Builder(TPositionHandle())
  600. .Atom("const")
  601. .Build();
  602. auto res2 = ctx.Builder(TPositionHandle())
  603. .Lambda()
  604. .Callable("Func3")
  605. .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1))
  606. .WithNode(ast->Head().Head(), TExprNode::TPtr(atom)).Seal()
  607. .Seal()
  608. .Seal()
  609. .Build();
  610. UNIT_ASSERT_VALUES_EQUAL(res2->Type(), TExprNode::Lambda);
  611. UNIT_ASSERT_VALUES_EQUAL(res2->ChildrenSize(), 2);
  612. UNIT_ASSERT_VALUES_EQUAL(res2->Head().Type(), TExprNode::Arguments);
  613. UNIT_ASSERT_VALUES_EQUAL(res2->Head().ChildrenSize(), 0);
  614. UNIT_ASSERT_EQUAL(res2->Child(1)->Head().ChildPtr(1), atom);
  615. }
  616. }
  617. } // namespace NYql