OverlappedTests.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. using System;
  2. using Terminal.Gui;
  3. using Xunit;
  4. using Xunit.Abstractions;
  5. namespace TerminalGui.ViewsTests;
  6. public class OverlappedTests {
  7. readonly ITestOutputHelper _output;
  8. public OverlappedTests (ITestOutputHelper output)
  9. {
  10. _output = output;
  11. #if DEBUG_IDISPOSABLE
  12. Responder.Instances.Clear ();
  13. RunState.Instances.Clear ();
  14. #endif
  15. }
  16. [Fact]
  17. [TestRespondersDisposed]
  18. public void Dispose_Toplevel_IsOverlappedContainer_False_With_Begin_End ()
  19. {
  20. Application.Init (new FakeDriver ());
  21. var top = new Toplevel ();
  22. var rs = Application.Begin (top);
  23. #if DEBUG_IDISPOSABLE
  24. Assert.Equal (4, Responder.Instances.Count);
  25. #endif
  26. Application.End (rs);
  27. Application.Shutdown ();
  28. #if DEBUG_IDISPOSABLE
  29. Assert.Empty (Responder.Instances);
  30. #endif
  31. }
  32. [Fact]
  33. [TestRespondersDisposed]
  34. public void Dispose_Toplevel_IsOverlappedContainer_True_With_Begin ()
  35. {
  36. Application.Init (new FakeDriver ());
  37. var overlapped = new Toplevel { IsOverlappedContainer = true };
  38. var rs = Application.Begin (overlapped);
  39. Application.End (rs);
  40. Application.Shutdown ();
  41. }
  42. [Fact]
  43. [AutoInitShutdown]
  44. public void Application_RequestStop_With_Params_On_A_Not_OverlappedContainer_Always_Use_Application_Current ()
  45. {
  46. var top1 = new Toplevel ();
  47. var top2 = new Toplevel ();
  48. var top3 = new Window ();
  49. var top4 = new Window ();
  50. var d = new Dialog ();
  51. // top1, top2, top3, d1 = 4
  52. var iterations = 4;
  53. top1.Ready += (s, e) => {
  54. Assert.Null (Application.OverlappedChildren);
  55. Application.Run (top2);
  56. };
  57. top2.Ready += (s, e) => {
  58. Assert.Null (Application.OverlappedChildren);
  59. Application.Run (top3);
  60. };
  61. top3.Ready += (s, e) => {
  62. Assert.Null (Application.OverlappedChildren);
  63. Application.Run (top4);
  64. };
  65. top4.Ready += (s, e) => {
  66. Assert.Null (Application.OverlappedChildren);
  67. Application.Run (d);
  68. };
  69. d.Ready += (s, e) => {
  70. Assert.Null (Application.OverlappedChildren);
  71. // This will close the d because on a not OverlappedContainer the Application.Current it always used.
  72. Application.RequestStop (top1);
  73. Assert.True (Application.Current == d);
  74. };
  75. d.Closed += (s, e) => Application.RequestStop (top1);
  76. Application.Iteration += (s, a) => {
  77. Assert.Null (Application.OverlappedChildren);
  78. if (iterations == 4) {
  79. Assert.True (Application.Current == d);
  80. } else if (iterations == 3) {
  81. Assert.True (Application.Current == top4);
  82. } else if (iterations == 2) {
  83. Assert.True (Application.Current == top3);
  84. } else if (iterations == 1) {
  85. Assert.True (Application.Current == top2);
  86. } else {
  87. Assert.True (Application.Current == top1);
  88. }
  89. Application.RequestStop (top1);
  90. iterations--;
  91. };
  92. Application.Run (top1);
  93. Assert.Null (Application.OverlappedChildren);
  94. }
  95. [Fact]
  96. [AutoInitShutdown]
  97. public void OverlappedContainer_With_Toplevel_RequestStop_Balanced ()
  98. {
  99. var overlapped = new Overlapped ();
  100. var c1 = new Toplevel ();
  101. var c2 = new Window ();
  102. var c3 = new Window ();
  103. var d = new Dialog ();
  104. // OverlappedChild = c1, c2, c3
  105. // d1 = 1
  106. var iterations = 4;
  107. overlapped.Ready += (s, e) => {
  108. Assert.Empty (Application.OverlappedChildren);
  109. Application.Run (c1);
  110. };
  111. c1.Ready += (s, e) => {
  112. Assert.Single (Application.OverlappedChildren);
  113. Application.Run (c2);
  114. };
  115. c2.Ready += (s, e) => {
  116. Assert.Equal (2, Application.OverlappedChildren.Count);
  117. Application.Run (c3);
  118. };
  119. c3.Ready += (s, e) => {
  120. Assert.Equal (3, Application.OverlappedChildren.Count);
  121. Application.Run (d);
  122. };
  123. // More easy because the Overlapped Container handles all at once
  124. d.Ready += (s, e) => {
  125. Assert.Equal (3, Application.OverlappedChildren.Count);
  126. // This will not close the OverlappedContainer because d is a modal Toplevel and will be closed.
  127. overlapped.RequestStop ();
  128. };
  129. // Now this will close the OverlappedContainer propagating through the OverlappedChildren.
  130. d.Closed += (s, e) => {
  131. overlapped.RequestStop ();
  132. };
  133. Application.Iteration += (s, a) => {
  134. if (iterations == 4) {
  135. // The Dialog was not closed before and will be closed now.
  136. Assert.True (Application.Current == d);
  137. Assert.False (d.Running);
  138. } else {
  139. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  140. for (var i = 0; i < iterations; i++) {
  141. Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
  142. }
  143. }
  144. iterations--;
  145. };
  146. Application.Run (overlapped);
  147. Assert.Empty (Application.OverlappedChildren);
  148. }
  149. [Fact]
  150. [AutoInitShutdown]
  151. public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_With_Params ()
  152. {
  153. var overlapped = new Overlapped ();
  154. var c1 = new Toplevel ();
  155. var c2 = new Window ();
  156. var c3 = new Window ();
  157. var d = new Dialog ();
  158. // OverlappedChild = c1, c2, c3
  159. // d1 = 1
  160. var iterations = 4;
  161. overlapped.Ready += (s, e) => {
  162. Assert.Empty (Application.OverlappedChildren);
  163. Application.Run (c1);
  164. };
  165. c1.Ready += (s, e) => {
  166. Assert.Single (Application.OverlappedChildren);
  167. Application.Run (c2);
  168. };
  169. c2.Ready += (s, e) => {
  170. Assert.Equal (2, Application.OverlappedChildren.Count);
  171. Application.Run (c3);
  172. };
  173. c3.Ready += (s, e) => {
  174. Assert.Equal (3, Application.OverlappedChildren.Count);
  175. Application.Run (d);
  176. };
  177. // Also easy because the Overlapped Container handles all at once
  178. d.Ready += (s, e) => {
  179. Assert.Equal (3, Application.OverlappedChildren.Count);
  180. // This will not close the OverlappedContainer because d is a modal Toplevel
  181. Application.RequestStop (overlapped);
  182. };
  183. // Now this will close the OverlappedContainer propagating through the OverlappedChildren.
  184. d.Closed += (s, e) => Application.RequestStop (overlapped);
  185. Application.Iteration += (s, a) => {
  186. if (iterations == 4) {
  187. // The Dialog was not closed before and will be closed now.
  188. Assert.True (Application.Current == d);
  189. Assert.False (d.Running);
  190. } else {
  191. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  192. for (var i = 0; i < iterations; i++) {
  193. Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
  194. }
  195. }
  196. iterations--;
  197. };
  198. Application.Run (overlapped);
  199. Assert.Empty (Application.OverlappedChildren);
  200. }
  201. [Fact]
  202. [AutoInitShutdown]
  203. public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_Without_Params ()
  204. {
  205. var overlapped = new Overlapped ();
  206. var c1 = new Toplevel ();
  207. var c2 = new Window ();
  208. var c3 = new Window ();
  209. var d = new Dialog ();
  210. // OverlappedChild = c1, c2, c3 = 3
  211. // d1 = 1
  212. var iterations = 4;
  213. overlapped.Ready += (s, e) => {
  214. Assert.Empty (Application.OverlappedChildren);
  215. Application.Run (c1);
  216. };
  217. c1.Ready += (s, e) => {
  218. Assert.Single (Application.OverlappedChildren);
  219. Application.Run (c2);
  220. };
  221. c2.Ready += (s, e) => {
  222. Assert.Equal (2, Application.OverlappedChildren.Count);
  223. Application.Run (c3);
  224. };
  225. c3.Ready += (s, e) => {
  226. Assert.Equal (3, Application.OverlappedChildren.Count);
  227. Application.Run (d);
  228. };
  229. //More harder because it's sequential.
  230. d.Ready += (s, e) => {
  231. Assert.Equal (3, Application.OverlappedChildren.Count);
  232. // Close the Dialog
  233. Application.RequestStop ();
  234. };
  235. // Now this will close the OverlappedContainer propagating through the OverlappedChildren.
  236. d.Closed += (s, e) => Application.RequestStop (overlapped);
  237. Application.Iteration += (s, a) => {
  238. if (iterations == 4) {
  239. // The Dialog still is the current top and we can't request stop to OverlappedContainer
  240. // because we are not using parameter calls.
  241. Assert.True (Application.Current == d);
  242. Assert.False (d.Running);
  243. } else {
  244. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  245. for (var i = 0; i < iterations; i++) {
  246. Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
  247. }
  248. }
  249. iterations--;
  250. };
  251. Application.Run (overlapped);
  252. Assert.Empty (Application.OverlappedChildren);
  253. }
  254. [Fact]
  255. [AutoInitShutdown]
  256. public void IsOverlappedChild_Testing ()
  257. {
  258. var overlapped = new Overlapped ();
  259. var c1 = new Toplevel ();
  260. var c2 = new Window ();
  261. var c3 = new Window ();
  262. var d = new Dialog ();
  263. Application.Iteration += (s, a) => {
  264. Assert.False (overlapped.IsOverlapped);
  265. Assert.True (c1.IsOverlapped);
  266. Assert.True (c2.IsOverlapped);
  267. Assert.True (c3.IsOverlapped);
  268. Assert.False (d.IsOverlapped);
  269. overlapped.RequestStop ();
  270. };
  271. Application.Run (overlapped);
  272. }
  273. [Fact]
  274. [AutoInitShutdown]
  275. public void Modal_Toplevel_Can_Open_Another_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
  276. {
  277. var overlapped = new Overlapped ();
  278. var c1 = new Toplevel ();
  279. var c2 = new Window ();
  280. var c3 = new Window ();
  281. var d1 = new Dialog ();
  282. var d2 = new Dialog ();
  283. // OverlappedChild = c1, c2, c3 = 3
  284. // d1, d2 = 2
  285. var iterations = 5;
  286. overlapped.Ready += (s, e) => {
  287. Assert.Empty (Application.OverlappedChildren);
  288. Application.Run (c1);
  289. };
  290. c1.Ready += (s, e) => {
  291. Assert.Single (Application.OverlappedChildren);
  292. Application.Run (c2);
  293. };
  294. c2.Ready += (s, e) => {
  295. Assert.Equal (2, Application.OverlappedChildren.Count);
  296. Application.Run (c3);
  297. };
  298. c3.Ready += (s, e) => {
  299. Assert.Equal (3, Application.OverlappedChildren.Count);
  300. Application.Run (d1);
  301. };
  302. d1.Ready += (s, e) => {
  303. Assert.Equal (3, Application.OverlappedChildren.Count);
  304. Application.Run (d2);
  305. };
  306. d2.Ready += (s, e) => {
  307. Assert.Equal (3, Application.OverlappedChildren.Count);
  308. Assert.True (Application.Current == d2);
  309. Assert.True (Application.Current.Running);
  310. // Trying to close the Dialog1
  311. d1.RequestStop ();
  312. };
  313. // Now this will close the OverlappedContainer propagating through the OverlappedChildren.
  314. d1.Closed += (s, e) => {
  315. Assert.True (Application.Current == d1);
  316. Assert.False (Application.Current.Running);
  317. overlapped.RequestStop ();
  318. };
  319. Application.Iteration += (s, a) => {
  320. if (iterations == 5) {
  321. // The Dialog2 still is the current top and we can't request stop to OverlappedContainer
  322. // because Dialog2 and Dialog1 must be closed first.
  323. // Dialog2 will be closed in this iteration.
  324. Assert.True (Application.Current == d2);
  325. Assert.False (Application.Current.Running);
  326. Assert.False (d1.Running);
  327. } else if (iterations == 4) {
  328. // Dialog1 will be closed in this iteration.
  329. Assert.True (Application.Current == d1);
  330. Assert.False (Application.Current.Running);
  331. } else {
  332. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  333. for (var i = 0; i < iterations; i++) {
  334. Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
  335. }
  336. }
  337. iterations--;
  338. };
  339. Application.Run (overlapped);
  340. Assert.Empty (Application.OverlappedChildren);
  341. }
  342. [Fact]
  343. [AutoInitShutdown]
  344. public void Modal_Toplevel_Can_Open_Another_Not_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
  345. {
  346. var overlapped = new Overlapped ();
  347. var c1 = new Toplevel ();
  348. var c2 = new Window ();
  349. var c3 = new Window ();
  350. var d1 = new Dialog ();
  351. var c4 = new Toplevel ();
  352. // OverlappedChild = c1, c2, c3, c4 = 4
  353. // d1 = 1
  354. var iterations = 5;
  355. overlapped.Ready += (s, e) => {
  356. Assert.Empty (Application.OverlappedChildren);
  357. Application.Run (c1);
  358. };
  359. c1.Ready += (s, e) => {
  360. Assert.Single (Application.OverlappedChildren);
  361. Application.Run (c2);
  362. };
  363. c2.Ready += (s, e) => {
  364. Assert.Equal (2, Application.OverlappedChildren.Count);
  365. Application.Run (c3);
  366. };
  367. c3.Ready += (s, e) => {
  368. Assert.Equal (3, Application.OverlappedChildren.Count);
  369. Application.Run (d1);
  370. };
  371. d1.Ready += (s, e) => {
  372. Assert.Equal (3, Application.OverlappedChildren.Count);
  373. Application.Run (c4);
  374. };
  375. c4.Ready += (s, e) => {
  376. Assert.Equal (4, Application.OverlappedChildren.Count);
  377. // Trying to close the Dialog1
  378. d1.RequestStop ();
  379. };
  380. // Now this will close the OverlappedContainer propagating through the OverlappedChildren.
  381. d1.Closed += (s, e) => {
  382. overlapped.RequestStop ();
  383. };
  384. Application.Iteration += (s, a) => {
  385. if (iterations == 5) {
  386. // The Dialog2 still is the current top and we can't request stop to OverlappedContainer
  387. // because Dialog2 and Dialog1 must be closed first.
  388. // Using request stop here will call the Dialog again without need
  389. Assert.True (Application.Current == d1);
  390. Assert.False (Application.Current.Running);
  391. Assert.True (c4.Running);
  392. } else {
  393. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  394. for (var i = 0; i < iterations; i++) {
  395. Assert.Equal ((iterations - i + (iterations == 4 && i == 0 ? 2 : 1)).ToString (),
  396. Application.OverlappedChildren [i].Id);
  397. }
  398. }
  399. iterations--;
  400. };
  401. Application.Run (overlapped);
  402. Assert.Empty (Application.OverlappedChildren);
  403. }
  404. [Fact]
  405. [AutoInitShutdown]
  406. public void MoveCurrent_Returns_False_If_The_Current_And_Top_Parameter_Are_Both_With_Running_Set_To_False ()
  407. {
  408. var overlapped = new Overlapped ();
  409. var c1 = new Toplevel ();
  410. var c2 = new Window ();
  411. var c3 = new Window ();
  412. // OverlappedChild = c1, c2, c3
  413. var iterations = 3;
  414. overlapped.Ready += (s, e) => {
  415. Assert.Empty (Application.OverlappedChildren);
  416. Application.Run (c1);
  417. };
  418. c1.Ready += (s, e) => {
  419. Assert.Single (Application.OverlappedChildren);
  420. Application.Run (c2);
  421. };
  422. c2.Ready += (s, e) => {
  423. Assert.Equal (2, Application.OverlappedChildren.Count);
  424. Application.Run (c3);
  425. };
  426. c3.Ready += (s, e) => {
  427. Assert.Equal (3, Application.OverlappedChildren.Count);
  428. c3.RequestStop ();
  429. c1.RequestStop ();
  430. };
  431. // Now this will close the OverlappedContainer propagating through the OverlappedChildren.
  432. c1.Closed += (s, e) => {
  433. overlapped.RequestStop ();
  434. };
  435. Application.Iteration += (s, a) => {
  436. if (iterations == 3) {
  437. // The Current still is c3 because Current.Running is false.
  438. Assert.True (Application.Current == c3);
  439. Assert.False (Application.Current.Running);
  440. // But the Children order were reorder by Running = false
  441. Assert.True (Application.OverlappedChildren [0] == c3);
  442. Assert.True (Application.OverlappedChildren [1] == c1);
  443. Assert.True (Application.OverlappedChildren [^1] == c2);
  444. } else if (iterations == 2) {
  445. // The Current is c1 and Current.Running is false.
  446. Assert.True (Application.Current == c1);
  447. Assert.False (Application.Current.Running);
  448. Assert.True (Application.OverlappedChildren [0] == c1);
  449. Assert.True (Application.OverlappedChildren [^1] == c2);
  450. } else if (iterations == 1) {
  451. // The Current is c2 and Current.Running is false.
  452. Assert.True (Application.Current == c2);
  453. Assert.False (Application.Current.Running);
  454. Assert.True (Application.OverlappedChildren [^1] == c2);
  455. } else {
  456. // The Current is overlapped.
  457. Assert.True (Application.Current == overlapped);
  458. Assert.Empty (Application.OverlappedChildren);
  459. }
  460. iterations--;
  461. };
  462. Application.Run (overlapped);
  463. Assert.Empty (Application.OverlappedChildren);
  464. }
  465. [Fact]
  466. [AutoInitShutdown]
  467. public void OverlappedContainer_Throws_If_More_Than_One ()
  468. {
  469. var overlapped = new Overlapped ();
  470. var overlapped2 = new Overlapped ();
  471. overlapped.Ready += (s, e) => {
  472. Assert.Throws<InvalidOperationException> (() => Application.Run (overlapped2));
  473. overlapped.RequestStop ();
  474. };
  475. Application.Run (overlapped);
  476. }
  477. [Fact]
  478. [AutoInitShutdown]
  479. public void OverlappedContainer_Open_And_Close_Modal_And_Open_Not_Modal_Toplevels_Randomly ()
  480. {
  481. var overlapped = new Overlapped ();
  482. var logger = new Toplevel ();
  483. var iterations = 1; // The logger
  484. var running = true;
  485. var stageCompleted = true;
  486. var allStageClosed = false;
  487. var overlappedRequestStop = false;
  488. overlapped.Ready += (s, e) => {
  489. Assert.Empty (Application.OverlappedChildren);
  490. Application.Run (logger);
  491. };
  492. logger.Ready += (s, e) => Assert.Single (Application.OverlappedChildren);
  493. Application.Iteration += (s, a) => {
  494. if (stageCompleted && running) {
  495. stageCompleted = false;
  496. var stage = new Window { Modal = true };
  497. stage.Ready += (s, e) => {
  498. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  499. stage.RequestStop ();
  500. };
  501. stage.Closed += (_, _) => {
  502. if (iterations == 11) {
  503. allStageClosed = true;
  504. }
  505. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  506. if (running) {
  507. stageCompleted = true;
  508. var rpt = new Window ();
  509. rpt.Ready += (s, e) => {
  510. iterations++;
  511. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  512. };
  513. Application.Run (rpt);
  514. }
  515. };
  516. Application.Run (stage);
  517. } else if (iterations == 11 && running) {
  518. running = false;
  519. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  520. } else if (!overlappedRequestStop && running && !allStageClosed) {
  521. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  522. } else if (!overlappedRequestStop && !running && allStageClosed) {
  523. Assert.Equal (iterations, Application.OverlappedChildren.Count);
  524. overlappedRequestStop = true;
  525. overlapped.RequestStop ();
  526. } else {
  527. Assert.Empty (Application.OverlappedChildren);
  528. }
  529. };
  530. Application.Run (overlapped);
  531. Assert.Empty (Application.OverlappedChildren);
  532. }
  533. [Fact]
  534. [AutoInitShutdown]
  535. public void AllChildClosed_Event_Test ()
  536. {
  537. var overlapped = new Overlapped ();
  538. var c1 = new Toplevel ();
  539. var c2 = new Window ();
  540. var c3 = new Window ();
  541. // OverlappedChild = c1, c2, c3
  542. var iterations = 3;
  543. overlapped.Ready += (s, e) => {
  544. Assert.Empty (Application.OverlappedChildren);
  545. Application.Run (c1);
  546. };
  547. c1.Ready += (s, e) => {
  548. Assert.Single (Application.OverlappedChildren);
  549. Application.Run (c2);
  550. };
  551. c2.Ready += (s, e) => {
  552. Assert.Equal (2, Application.OverlappedChildren.Count);
  553. Application.Run (c3);
  554. };
  555. c3.Ready += (s, e) => {
  556. Assert.Equal (3, Application.OverlappedChildren.Count);
  557. c3.RequestStop ();
  558. c2.RequestStop ();
  559. c1.RequestStop ();
  560. };
  561. // Now this will close the OverlappedContainer when all OverlappedChildren was closed
  562. overlapped.AllChildClosed += (s, e) => {
  563. overlapped.RequestStop ();
  564. };
  565. Application.Iteration += (s, a) => {
  566. if (iterations == 3) {
  567. // The Current still is c3 because Current.Running is false.
  568. Assert.True (Application.Current == c3);
  569. Assert.False (Application.Current.Running);
  570. // But the Children order were reorder by Running = false
  571. Assert.True (Application.OverlappedChildren [0] == c3);
  572. Assert.True (Application.OverlappedChildren [1] == c2);
  573. Assert.True (Application.OverlappedChildren [^1] == c1);
  574. } else if (iterations == 2) {
  575. // The Current is c2 and Current.Running is false.
  576. Assert.True (Application.Current == c2);
  577. Assert.False (Application.Current.Running);
  578. Assert.True (Application.OverlappedChildren [0] == c2);
  579. Assert.True (Application.OverlappedChildren [^1] == c1);
  580. } else if (iterations == 1) {
  581. // The Current is c1 and Current.Running is false.
  582. Assert.True (Application.Current == c1);
  583. Assert.False (Application.Current.Running);
  584. Assert.True (Application.OverlappedChildren [^1] == c1);
  585. } else {
  586. // The Current is overlapped.
  587. Assert.True (Application.Current == overlapped);
  588. Assert.False (Application.Current.Running);
  589. Assert.Empty (Application.OverlappedChildren);
  590. }
  591. iterations--;
  592. };
  593. Application.Run (overlapped);
  594. Assert.Empty (Application.OverlappedChildren);
  595. }
  596. [Fact]
  597. public void MoveToOverlappedChild_Throw_NullReferenceException_Passing_Null_Parameter () => Assert.Throws<NullReferenceException> (delegate { Application.MoveToOverlappedChild (null); });
  598. [Fact]
  599. [AutoInitShutdown]
  600. public void Visible_False_Does_Not_Clear ()
  601. {
  602. var overlapped = new Overlapped ();
  603. var win1 = new Window { Width = 5, Height = 5, Visible = false };
  604. var win2 = new Window { X = 1, Y = 1, Width = 5, Height = 5 };
  605. ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
  606. var rs = Application.Begin (overlapped);
  607. Application.Begin (win1);
  608. Application.Begin (win2);
  609. Assert.Equal (win2, Application.Current);
  610. var firstIteration = false;
  611. Application.RunIteration (ref rs, ref firstIteration);
  612. TestHelpers.AssertDriverContentsWithFrameAre (@"
  613. ┌───┐
  614. │ │
  615. │ │
  616. │ │
  617. └───┘", _output);
  618. var attributes = new [] {
  619. // 0
  620. Colors.TopLevel.Normal,
  621. // 1
  622. Colors.Base.Normal
  623. };
  624. TestHelpers.AssertDriverColorsAre (@"
  625. 0000000000
  626. 0111110000
  627. 0111110000
  628. 0111110000
  629. 0111110000
  630. 0111110000
  631. 0000000000
  632. 0000000000
  633. 0000000000
  634. 0000000000", null, attributes);
  635. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.Button1Pressed }));
  636. Assert.Equal (win2, Application.MouseGrabView);
  637. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }));
  638. // Need to fool MainLoop into thinking it's running
  639. Application.MainLoop.Running = true;
  640. Application.RunIteration (ref rs, ref firstIteration);
  641. TestHelpers.AssertDriverContentsWithFrameAre (@"
  642. ┌───┐
  643. │ │
  644. │ │
  645. │ │
  646. └───┘", _output);
  647. TestHelpers.AssertDriverColorsAre (@"
  648. 0000000000
  649. 0000000000
  650. 0011111000
  651. 0011111000
  652. 0011111000
  653. 0011111000
  654. 0011111000
  655. 0000000000
  656. 0000000000
  657. 0000000000", null, attributes);
  658. Application.Shutdown ();
  659. }
  660. class Overlapped : Toplevel {
  661. public Overlapped () => IsOverlappedContainer = true;
  662. }
  663. }