MdiTests.cs 19 KB

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