PageRenderTime 54ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/PossibleMultipleEnumerationIssueTests.cs

https://github.com/bbqchickenrobot/NRefactory
C# | 733 lines | 675 code | 33 blank | 25 comment | 0 complexity | 62f7bc2ddfe74a703889969225f0c3a0 MD5 | raw file
  1. //
  2. // MultipleEnumerationIssueTests.cs
  3. //
  4. // Author:
  5. // Mansheng Yang <lightyang0@gmail.com>
  6. //
  7. // Copyright (c) 2012 Mansheng Yang <lightyang0@gmail.com>
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. using ICSharpCode.NRefactory.CSharp.Refactoring;
  27. using NUnit.Framework;
  28. using System.Collections.Generic;
  29. using System.Linq;
  30. namespace ICSharpCode.NRefactory.CSharp.CodeIssues
  31. {
  32. [TestFixture]
  33. public class PossibleMultipleEnumerationIssueTests : InspectionActionTestBase
  34. {
  35. [Test]
  36. public void TestVariableInvocation ()
  37. {
  38. var input = @"
  39. using System.Collections.Generic;
  40. using System.Linq;
  41. class TestClass
  42. {
  43. void TestMethod ()
  44. {
  45. IEnumerable<object> e = null;
  46. var type = e.GetType();
  47. var x = e.First ();
  48. var y = e.Count ();
  49. }
  50. }";
  51. Test<PossibleMultipleEnumerationIssue> (
  52. input,
  53. 2,
  54. @"
  55. using System.Collections.Generic;
  56. using System.Linq;
  57. class TestClass
  58. {
  59. void TestMethod ()
  60. {
  61. IEnumerable<object> e = null;
  62. var type = e.GetType();
  63. var enumerable = e as object[] ?? e.ToArray ();
  64. var x = enumerable.First ();
  65. var y = enumerable.Count ();
  66. }
  67. }", 0);
  68. }
  69. [Test]
  70. public void TestVariableForeach ()
  71. {
  72. var input = @"
  73. using System.Collections.Generic;
  74. using System.Linq;
  75. class TestClass
  76. {
  77. void TestMethod ()
  78. {
  79. IEnumerable<object> e = null;
  80. foreach (var x in e) ;
  81. foreach (var y in e) ;
  82. }
  83. }";
  84. Test<PossibleMultipleEnumerationIssue> (
  85. input,
  86. 2,
  87. @"
  88. using System.Collections.Generic;
  89. using System.Linq;
  90. class TestClass
  91. {
  92. void TestMethod ()
  93. {
  94. IEnumerable<object> e = null;
  95. var enumerable = e as IList<object> ?? e.ToList ();
  96. foreach (var x in enumerable) ;
  97. foreach (var y in enumerable) ;
  98. }
  99. }", 1, 1);
  100. }
  101. [Test]
  102. public void TestVariableMixed ()
  103. {
  104. var input = @"
  105. using System.Collections.Generic;
  106. using System.Linq;
  107. class TestClass
  108. {
  109. void TestMethod ()
  110. {
  111. IEnumerable<object> e = null;
  112. foreach (var x in e) ;
  113. var y = e.Count ();
  114. }
  115. }";
  116. Test<PossibleMultipleEnumerationIssue> (input, 2);
  117. }
  118. [Test]
  119. public void TestParameter ()
  120. {
  121. var input = @"
  122. using System.Collections.Generic;
  123. using System.Linq;
  124. class TestClass
  125. {
  126. void TestMethod (IEnumerable<object> e)
  127. {
  128. foreach (var x in e) ;
  129. var y = e.Count ();
  130. }
  131. }";
  132. Test<PossibleMultipleEnumerationIssue> (input, 2);
  133. }
  134. [Test]
  135. public void TestObjectMethodInvocation ()
  136. {
  137. var input = @"
  138. using System.Collections.Generic;
  139. using System.Linq;
  140. class TestClass
  141. {
  142. void TestMethod ()
  143. {
  144. IEnumerable<object> e;
  145. var a = e.GetType ();
  146. var b = e.ToString ();
  147. }
  148. }";
  149. Test<PossibleMultipleEnumerationIssue> (input, 0);
  150. }
  151. [Test]
  152. public void TestIf ()
  153. {
  154. var input = @"
  155. using System.Collections.Generic;
  156. using System.Linq;
  157. class TestClass
  158. {
  159. void TestMethod (int i)
  160. {
  161. IEnumerable<object> e;
  162. if (i > 0) {
  163. var a = e.Count ();
  164. } else {
  165. var b = e.First ();
  166. var c = e.Count ();
  167. }
  168. }
  169. }";
  170. Test<PossibleMultipleEnumerationIssue> (input, 2);
  171. }
  172. [Test]
  173. public void TestIf2 ()
  174. {
  175. var input = @"
  176. using System.Collections.Generic;
  177. using System.Linq;
  178. class TestClass
  179. {
  180. void TestMethod (int i)
  181. {
  182. IEnumerable<object> e;
  183. if (i > 0) {
  184. var a = e.Count ();
  185. } else {
  186. var b = e.First ();
  187. }
  188. var c = e.Count ();
  189. }
  190. }";
  191. Test<PossibleMultipleEnumerationIssue> (input, 3);
  192. }
  193. [Test]
  194. public void TestIf3 ()
  195. {
  196. var input = @"
  197. using System.Collections.Generic;
  198. using System.Linq;
  199. class TestClass
  200. {
  201. void TestMethod (int i)
  202. {
  203. IEnumerable<object> e;
  204. if (i > 0) {
  205. var a = e.Count ();
  206. } else {
  207. var b = e.First ();
  208. }
  209. }
  210. }";
  211. Test<PossibleMultipleEnumerationIssue> (input, 0);
  212. }
  213. [Test]
  214. public void TestFor ()
  215. {
  216. var input = @"
  217. using System.Collections.Generic;
  218. using System.Linq;
  219. class TestClass
  220. {
  221. void TestMethod ()
  222. {
  223. IEnumerable<object> e;
  224. for (int i = 0; i < 10; i++) {
  225. var a = e.Count ();
  226. }
  227. }
  228. }";
  229. Test<PossibleMultipleEnumerationIssue> (input, 1);
  230. }
  231. [Test]
  232. public void TestWhile ()
  233. {
  234. var input = @"
  235. using System.Collections.Generic;
  236. using System.Linq;
  237. class TestClass
  238. {
  239. void TestMethod ()
  240. {
  241. IEnumerable<object> e;
  242. int i;
  243. while (i > 1) {
  244. var a = e.Count ();
  245. }
  246. }
  247. }";
  248. Test<PossibleMultipleEnumerationIssue> (input, 1);
  249. }
  250. [Test]
  251. public void TestWhile2 ()
  252. {
  253. var input = @"
  254. using System.Collections.Generic;
  255. using System.Linq;
  256. class TestClass
  257. {
  258. void TestMethod ()
  259. {
  260. IEnumerable<object> e;
  261. int i;
  262. while (i > e.Count ()) {
  263. }
  264. }
  265. }";
  266. Test<PossibleMultipleEnumerationIssue> (input, 1);
  267. }
  268. [Test]
  269. public void TestWhile3 ()
  270. {
  271. var input = @"
  272. using System.Collections.Generic;
  273. using System.Linq;
  274. class TestClass
  275. {
  276. void TestMethod ()
  277. {
  278. IEnumerable<object> e;
  279. int i;
  280. object x;
  281. while (true) {
  282. if (i > 1) {
  283. x = e.First ();
  284. break;
  285. }
  286. }
  287. }
  288. }";
  289. Test<PossibleMultipleEnumerationIssue> (input, 0);
  290. }
  291. [Test]
  292. public void TestWhile4 ()
  293. {
  294. var input = @"
  295. using System;
  296. using System.Collections.Generic;
  297. using System.Linq;
  298. class TestClass
  299. {
  300. IEnumerable<object> GetEnum () { }
  301. void TestMethod (int i)
  302. {
  303. IEnumerable<object> e = GetEnum ();
  304. var a1 = e.First ();
  305. while ((e = GetEnum ()) != null) {
  306. var a2 = e.First ();
  307. }
  308. }
  309. }";
  310. Test<PossibleMultipleEnumerationIssue> (input, 0);
  311. }
  312. [Test]
  313. public void TestDo ()
  314. {
  315. var input = @"
  316. using System;
  317. using System.Collections.Generic;
  318. using System.Linq;
  319. class TestClass
  320. {
  321. IEnumerable<object> GetEnum () { }
  322. void TestMethod (int i)
  323. {
  324. IEnumerable<object> e = GetEnum ();
  325. var a1 = e.First ();
  326. do {
  327. var a2 = e.First ();
  328. } while ((e = GetEnum ()) != null);
  329. }
  330. }";
  331. Test<PossibleMultipleEnumerationIssue> (input, 2);
  332. }
  333. [Test]
  334. public void TestDo2 ()
  335. {
  336. var input = @"
  337. using System;
  338. using System.Collections.Generic;
  339. using System.Linq;
  340. class TestClass
  341. {
  342. IEnumerable<object> GetEnum () { }
  343. void TestMethod (int i)
  344. {
  345. IEnumerable<object> e = GetEnum ();
  346. do {
  347. var a2 = e.First ();
  348. } while ((e = GetEnum ()) != null);
  349. }
  350. }";
  351. Test<PossibleMultipleEnumerationIssue> (input, 0);
  352. }
  353. [Test]
  354. public void TestLambda ()
  355. {
  356. var input = @"
  357. using System;
  358. using System.Collections.Generic;
  359. using System.Linq;
  360. class TestClass
  361. {
  362. void TestMethod ()
  363. {
  364. IEnumerable<object> e;
  365. Action a = () => {
  366. var x = e.Count ();
  367. var y = e.Count ();
  368. };
  369. var z = e.Count ();
  370. }
  371. }";
  372. Test<PossibleMultipleEnumerationIssue> (input, 2);
  373. }
  374. [Test]
  375. public void TestLambda2 ()
  376. {
  377. var input = @"
  378. using System;
  379. using System.Collections.Generic;
  380. using System.Linq;
  381. class TestClass
  382. {
  383. void Test (object a, object b) { }
  384. void TestMethod ()
  385. {
  386. IEnumerable<object> e;
  387. Action a = () => Test(e.First (), e.Count ());
  388. }
  389. }";
  390. Test<PossibleMultipleEnumerationIssue> (input, 2);
  391. }
  392. [Test]
  393. public void TestLambda3 ()
  394. {
  395. var input = @"
  396. using System;
  397. using System.Collections.Generic;
  398. using System.Linq;
  399. class TestClass
  400. {
  401. void Test (object a, Action b) { }
  402. void TestMethod ()
  403. {
  404. IEnumerable<object> e;
  405. Test(e.First (), () => e.Count ());
  406. e = null;
  407. var x = e.First ();
  408. Action a = () => e.Count();
  409. }
  410. }";
  411. Test<PossibleMultipleEnumerationIssue> (input, 0);
  412. }
  413. [Test]
  414. public void TestLambda4 ()
  415. {
  416. var input = @"
  417. using System;
  418. using System.Collections.Generic;
  419. using System.Linq;
  420. class TestClass
  421. {
  422. void Test (object a, object b) { }
  423. void TestMethod ()
  424. {
  425. IEnumerable<object> e;
  426. Action a = () => Test(e.ToString (), e.ToString ());
  427. }
  428. }";
  429. Test<PossibleMultipleEnumerationIssue> (input, 0);
  430. }
  431. [Test]
  432. public void TestConditionalExpression ()
  433. {
  434. var input = @"
  435. using System;
  436. using System.Collections.Generic;
  437. using System.Linq;
  438. class TestClass
  439. {
  440. void TestMethod (int i)
  441. {
  442. IEnumerable<object> e;
  443. var a = i > 0 ? e.First () : e.FirstOrDefault ();
  444. Action b = () => i > 0 ? e.First () : e.FirstOrDefault ();
  445. }
  446. }";
  447. Test<PossibleMultipleEnumerationIssue> (input, 0);
  448. }
  449. [Test]
  450. public void TestConditionalExpression2 ()
  451. {
  452. var input = @"
  453. using System;
  454. using System.Collections.Generic;
  455. using System.Linq;
  456. class TestClass
  457. {
  458. void TestMethod (int i)
  459. {
  460. IEnumerable<object> e;
  461. var a = i > 0 ? e.First () : new object ();
  462. var b = e.First ();
  463. }
  464. }";
  465. Test<PossibleMultipleEnumerationIssue> (input, 2);
  466. }
  467. [Test]
  468. public void TestConstantConditionalExpression ()
  469. {
  470. var input = @"
  471. using System;
  472. using System.Collections.Generic;
  473. using System.Linq;
  474. class TestClass
  475. {
  476. void TestMethod (int i)
  477. {
  478. IEnumerable<object> e;
  479. var a = 1 > 2 ? e.First () : new object ();
  480. var b = e.First ();
  481. }
  482. }";
  483. Test<PossibleMultipleEnumerationIssue> (input, 0);
  484. }
  485. [Test]
  486. public void TestAssignmentInConditionalExpression ()
  487. {
  488. var input = @"
  489. using System;
  490. using System.Collections.Generic;
  491. using System.Linq;
  492. class TestClass
  493. {
  494. IEnumerable<object> GetEnum () { }
  495. void TestMethod (int i)
  496. {
  497. IEnumerable<object> e;
  498. var x1 = e.First ();
  499. var a = i > 0 ? e = GetEnum () : GetEnum ();
  500. var x2 = e.First ();
  501. }
  502. }";
  503. Test<PossibleMultipleEnumerationIssue> (input, 2);
  504. }
  505. [Test]
  506. public void TestAssignmentInConditionalExpression2 ()
  507. {
  508. var input = @"
  509. using System;
  510. using System.Collections.Generic;
  511. using System.Linq;
  512. class TestClass
  513. {
  514. IEnumerable<object> GetEnum () { }
  515. void TestMethod (int i)
  516. {
  517. IEnumerable<object> e;
  518. var x1 = e.First ();
  519. var a = i > 0 ? e = GetEnum () : e = GetEnum ();
  520. var x2 = e.First ();
  521. }
  522. }";
  523. Test<PossibleMultipleEnumerationIssue> (input, 0);
  524. }
  525. [Test]
  526. public void TestAssignment ()
  527. {
  528. var input = @"
  529. using System.Collections.Generic;
  530. using System.Linq;
  531. class TestClass
  532. {
  533. void TestMethod (IEnumerable<object> e)
  534. {
  535. foreach (var x in e) ;
  536. e = null;
  537. var y = e.Count ();
  538. }
  539. }";
  540. Test<PossibleMultipleEnumerationIssue> (input, 0);
  541. }
  542. [Test]
  543. public void TestAssignment2 ()
  544. {
  545. var input = @"
  546. using System.Collections.Generic;
  547. using System.Linq;
  548. class TestClass
  549. {
  550. void TestMethod (IEnumerable<object> e)
  551. {
  552. foreach (var x in e) ;
  553. e = null;
  554. var y = e.Count ();
  555. e = null;
  556. var a = e.First ();
  557. var b = e.First ();
  558. }
  559. }";
  560. Test<PossibleMultipleEnumerationIssue> (input, 2);
  561. }
  562. [Test]
  563. public void TestNoIssue ()
  564. {
  565. var input = @"
  566. using System.Collections.Generic;
  567. using System.Linq;
  568. class TestClass
  569. {
  570. void TestMethod (IEnumerable<object> e)
  571. {
  572. foreach (var x in e) ;
  573. IEnumerable<object> e2;
  574. }
  575. }";
  576. Test<PossibleMultipleEnumerationIssue> (input, 0);
  577. }
  578. [Test]
  579. public void TestExpression ()
  580. {
  581. var input = @"
  582. using System.Collections.Generic;
  583. using System.Linq;
  584. class TestClass
  585. {
  586. int Test (params object[] args) { }
  587. void TestMethod ()
  588. {
  589. IEnumerable<object> e = null;
  590. var type = e.GetType();
  591. var x = Test (e.First (), e.Count ());
  592. }
  593. }";
  594. Test<PossibleMultipleEnumerationIssue> (input, 2);
  595. }
  596. [Test]
  597. public void TestExpression2 ()
  598. {
  599. var input = @"
  600. using System.Collections.Generic;
  601. using System.Linq;
  602. class TestClass
  603. {
  604. int Test (params object[] args) { }
  605. void TestMethod ()
  606. {
  607. IEnumerable<object> e = null;
  608. var type = e.GetType();
  609. var x = Test (e.First (), e = new objct[0], e.Count ());
  610. }
  611. }";
  612. Test<PossibleMultipleEnumerationIssue> (input, 0);
  613. }
  614. [Test]
  615. public void TestOutArgument ()
  616. {
  617. var input = @"
  618. using System.Collections.Generic;
  619. using System.Linq;
  620. class TestClass
  621. {
  622. void Test (out IEnumerable<object> e)
  623. {
  624. e = null;
  625. }
  626. void TestMethod (IEnumerable<object> e)
  627. {
  628. foreach (var x in e) ;
  629. Test (out e);
  630. var y = e.Count ();
  631. }
  632. }";
  633. Test<PossibleMultipleEnumerationIssue> (input, 0);
  634. }
  635. [Test]
  636. public void TestOutArgument2 ()
  637. {
  638. var input = @"
  639. using System.Collections.Generic;
  640. using System.Linq;
  641. class TestClass
  642. {
  643. void Test (out IEnumerable<object> e)
  644. {
  645. e = null;
  646. }
  647. void TestMethod (IEnumerable<object> e)
  648. {
  649. foreach (var x in e) ;
  650. Test (out e);
  651. var y = e.Count ();
  652. var z = e.Count ();
  653. }
  654. }";
  655. Test<PossibleMultipleEnumerationIssue> (input, 2);
  656. }
  657. [Test]
  658. public void TestOutArgument3 ()
  659. {
  660. var input = @"
  661. using System.Collections.Generic;
  662. using System.Linq;
  663. class TestClass
  664. {
  665. void Test (object arg1, out IEnumerable<object> e, object arg2)
  666. {
  667. e = null;
  668. }
  669. void TestMethod (IEnumerable<object> e)
  670. {
  671. Test (e.First (), out e, e.First ());
  672. }
  673. }";
  674. Test<PossibleMultipleEnumerationIssue> (input, 2);
  675. }
  676. [Test]
  677. public void TestDisable ()
  678. {
  679. var input = @"
  680. using System.Collections.Generic;
  681. using System.Linq;
  682. class TestClass
  683. {
  684. void TestMethod ()
  685. {
  686. // ReSharper disable PossibleMultipleEnumeration
  687. IEnumerable<object> e = null;
  688. var type = e.GetType();
  689. var x = e.First ();
  690. var y = e.Count ();
  691. // ReSharper restore PossibleMultipleEnumeration
  692. }
  693. }";
  694. TestWrongContext<PossibleMultipleEnumerationIssue> (input);
  695. }
  696. }
  697. }