OverlappedTests.cs 21 KB

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