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

/ClojureCLR/Clojure/Clojure.Tests/LibTests/LispReaderTests.cs

https://github.com/dsebban/clojure-contrib
C# | 1827 lines | 1638 code | 155 blank | 34 comment | 0 complexity | f8f203821686776237f663058e0f0020 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /**
  2. * Copyright (c) David Miller. All rights reserved.
  3. * The use and distribution terms for this software are covered by the
  4. * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
  5. * which can be found in the file epl-v10.html at the root of this distribution.
  6. * By using this software in any fashion, you are agreeing to be bound by
  7. * the terms of this license.
  8. * You must not remove this notice, or any other, from this software.
  9. **/
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using System.IO;
  15. using NUnit.Framework;
  16. using Rhino.Mocks;
  17. using clojure.lang;
  18. using RMExpect = Rhino.Mocks.Expect;
  19. using java.math;
  20. namespace Clojure.Tests.LibTests
  21. {
  22. [TestFixture]
  23. public class LispReaderTests : AssertionHelper
  24. {
  25. #region matchNumber tests
  26. [Test]
  27. public void MatchNumberMatchesZero()
  28. {
  29. object o1 = LispReader.matchNumber("0");
  30. object o2 = LispReader.matchNumber("-0");
  31. object o3 = LispReader.matchNumber("+0");
  32. Expect(o1, EqualTo(0));
  33. Expect(o2, EqualTo(0));
  34. Expect(o3, EqualTo(0));
  35. }
  36. [Test]
  37. public void MatchNumberMatchesDecimal()
  38. {
  39. object o1 = LispReader.matchNumber("123");
  40. object o2 = LispReader.matchNumber("+123");
  41. object o3 = LispReader.matchNumber("-123");
  42. object o4 = LispReader.matchNumber("123456789123456789123456789");
  43. Expect(o1, EqualTo(123));
  44. Expect(o2, EqualTo(123));
  45. Expect(o3, EqualTo(-123));
  46. Expect(o4, EqualTo(new BigInteger("123456789123456789123456789")));
  47. }
  48. [Test]
  49. public void MatchNumberMatchesHexadecimal()
  50. {
  51. object o1 = LispReader.matchNumber("0X12A");
  52. object o2 = LispReader.matchNumber("0xFFF");
  53. object o3 = LispReader.matchNumber("0xFFFFFFFFFFFFFFFFFFFFFFFF");
  54. Expect(o1, EqualTo(0x12A));
  55. Expect(o2, EqualTo(0xFFF));
  56. Expect(o3, EqualTo(new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFF", 16)));
  57. }
  58. [Test]
  59. public void MatchNumberMatchesOctal()
  60. {
  61. object o1 = LispReader.matchNumber("0123");
  62. object o2 = LispReader.matchNumber("+0123");
  63. object o3 = LispReader.matchNumber("-0123");
  64. object o4 = LispReader.matchNumber("01234567012345670123456777");
  65. Expect(o1, EqualTo(83));
  66. Expect(o2, EqualTo(83));
  67. Expect(o3, EqualTo(-83));
  68. Expect(o4, EqualTo(new BigInteger("1234567012345670123456777", 8)));
  69. }
  70. [Test]
  71. public void MatchNumberMatchesSpecifiedRadix()
  72. {
  73. object o1 = LispReader.matchNumber("2R1100");
  74. object o2 = LispReader.matchNumber("4R123");
  75. object o3 = LispReader.matchNumber("-4R123");
  76. object o4 = LispReader.matchNumber("30R1234AQ");
  77. Expect(o1, EqualTo(12));
  78. Expect(o2, EqualTo(27));
  79. Expect(o3, EqualTo(-27));
  80. Expect(o4, EqualTo(new BigInteger("1234AQ", 30).longValue()));
  81. }
  82. [Test]
  83. public void MatchNumberMatchesFloats()
  84. {
  85. object o1 = LispReader.matchNumber("123.7");
  86. object o2 = LispReader.matchNumber("-123.7E4");
  87. object o3 = LispReader.matchNumber("+1.237e4");
  88. object o4 = LispReader.matchNumber("+1.237e-4");
  89. object o5 = LispReader.matchNumber("1.237e+4");
  90. Expect(o1, EqualTo(123.7));
  91. Expect(o2, EqualTo(-1237000.0));
  92. Expect(o3, EqualTo(1.237e4));
  93. Expect(o4, EqualTo(1.237e-4));
  94. Expect(o5, EqualTo(1.237e4));
  95. }
  96. [Test]
  97. public void MatchNumberMatchesDecimals()
  98. {
  99. object o1 = LispReader.matchNumber("123.7M");
  100. // MS implementation of BigDecimal parser does not allow these.
  101. //object o2 = LispReader.matchNumber("-123.7E4M");
  102. //object o3 = LispReader.matchNumber("+1.237e4M");
  103. //object o4 = LispReader.matchNumber("+1.237e-4M");
  104. //object o5 = LispReader.matchNumber("1.237e+4M");
  105. Expect(o1, EqualTo(new BigDecimal("123.7")));
  106. //Expect(o2, EqualTo(-1237000.0M));
  107. //Expect(o3, EqualTo(1.237e4M));
  108. //Expect(o4, EqualTo(1.237e-4M));
  109. //Expect(o5, EqualTo(1.237e4M));
  110. }
  111. [Test]
  112. public void MatchNumberMatchesRatios()
  113. {
  114. object o1 = LispReader.matchNumber("12/1");
  115. object o2 = LispReader.matchNumber("12/4");
  116. object o3 = LispReader.matchNumber("12/5");
  117. object o4 = LispReader.matchNumber("12345678900000/123456789");
  118. Expect(o1, EqualTo(12));
  119. Expect(o2, EqualTo(3));
  120. Expect(o3, EqualTo(new Ratio(new BigInteger("12"),new BigInteger("5"))));
  121. Expect(o4, EqualTo(100000));
  122. }
  123. [Test]
  124. public void MatchNumberReadsWholeString()
  125. {
  126. object o1 = LispReader.matchNumber(" 123");
  127. object o2 = LispReader.matchNumber("123 ");
  128. object o3 = LispReader.matchNumber(" 12.3");
  129. object o4 = LispReader.matchNumber("12.3 ");
  130. object o5 = LispReader.matchNumber(" 1/23");
  131. object o6 = LispReader.matchNumber("1/23 ");
  132. Expect(o1, Null);
  133. Expect(o2, Null);
  134. Expect(o3, Null);
  135. Expect(o4, Null);
  136. Expect(o5, Null);
  137. Expect(o6, Null);
  138. }
  139. [Test]
  140. public void MatchNumberFailsToMatchWeirdThings()
  141. {
  142. object o1 = LispReader.matchNumber("123a");
  143. object o2 = LispReader.matchNumber("0x123Z");
  144. object o4 = LispReader.matchNumber("12.4/24.2");
  145. object o5 = LispReader.matchNumber("1.7M3");
  146. Expect(o1, Null);
  147. Expect(o2, Null);
  148. Expect(o4, Null);
  149. Expect(o5, Null);
  150. }
  151. [Test]
  152. [ExpectedException(typeof(java.lang.NumberFormatException))]
  153. public void MatchNumberFailsOnRadixSnafu()
  154. {
  155. object o3 = LispReader.matchNumber("10RAA");
  156. }
  157. #endregion
  158. #region Helpers
  159. static PushbackTextReader CreatePushbackReaderFromString(string s)
  160. {
  161. return new PushbackTextReader(new StringReader(s));
  162. }
  163. static object ReadFromString(string s)
  164. {
  165. return LispReader.read(CreatePushbackReaderFromString(s),true,null,false);
  166. }
  167. static LineNumberingTextReader CreateLNPBRFromString(string s)
  168. {
  169. return new LineNumberingTextReader(new StringReader(s));
  170. }
  171. static object ReadFromStringNumbering(string s)
  172. {
  173. return LispReader.read(CreateLNPBRFromString(s),true,null,false);
  174. }
  175. #endregion
  176. #region Testing EOF
  177. [Test]
  178. public void EofValueReturnedOnEof()
  179. {
  180. object o = LispReader.read(CreatePushbackReaderFromString(" "), false, 7, false);
  181. Expect(o, EqualTo(7));
  182. }
  183. [Test]
  184. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  185. public void EofValueFailsOnEof()
  186. {
  187. object o = LispReader.read(CreatePushbackReaderFromString(" "), true, 7, false);
  188. }
  189. #endregion
  190. #region Testing a few numbers
  191. [Test]
  192. public void ReadReadsIntegers()
  193. {
  194. object o1 = ReadFromString("123");
  195. object o2 = ReadFromString("-123");
  196. object o3 = ReadFromString("+123");
  197. object o4 = ReadFromString("123456789123456789123456789");
  198. Expect(o1, EqualTo(123));
  199. Expect(o2, EqualTo(-123));
  200. Expect(o3, EqualTo(123));
  201. Expect(o4, EqualTo(new BigInteger("123456789123456789123456789")));
  202. }
  203. [Test]
  204. public void ReadReadsFloats()
  205. {
  206. object o1 = ReadFromString("123.4");
  207. object o2 = ReadFromString("-123.4E4");
  208. object o3 = ReadFromString("+123.4E-2");
  209. Expect(o1, EqualTo(123.4));
  210. Expect(o2, EqualTo(-123.4E4));
  211. Expect(o3, EqualTo(123.4E-2));
  212. }
  213. [Test]
  214. public void ReadReadsRatios()
  215. {
  216. object o1 = ReadFromString("123/456");
  217. object o2 = ReadFromString("-123/456");
  218. object o3 = ReadFromString("+123/456");
  219. Expect(o1, TypeOf(typeof(Ratio)));
  220. Expect(o2, TypeOf(typeof(Ratio)));
  221. Expect(o3, TypeOf(typeof(Ratio)));
  222. }
  223. #endregion
  224. #region Special tokens
  225. [Test]
  226. public void SlashAloneIsSlash()
  227. {
  228. object o = ReadFromString("/");
  229. Expect(o, TypeOf(typeof(Symbol)));
  230. Expect(((Symbol)o).Name, EqualTo("/"));
  231. Expect(((Symbol)o).Namespace, Null);
  232. }
  233. [Test]
  234. public void ClojureSlashIsSpecial()
  235. {
  236. object o = ReadFromString("clojure.core//");
  237. Expect(o, TypeOf(typeof(Symbol)));
  238. Expect(((Symbol)o).Name, EqualTo("/"));
  239. Expect(((Symbol)o).Namespace, EqualTo("clojure.core"));
  240. }
  241. [Test]
  242. public void TrueReturnsT()
  243. {
  244. object o = ReadFromString("true");
  245. Expect(o, TypeOf(typeof(bool)));
  246. Expect(o,EqualTo(true));
  247. }
  248. [Test]
  249. public void FalseReturnsF()
  250. {
  251. object o = ReadFromString("false");
  252. Expect(o, TypeOf(typeof(bool)));
  253. Expect(o, EqualTo(false));
  254. }
  255. [Test]
  256. public void NilIsNull()
  257. {
  258. object o = ReadFromString("nil");
  259. Expect(o, Null);
  260. }
  261. #endregion
  262. #region Symbolic tests
  263. [Test]
  264. public void ReadReadsSymbolWithNoNS()
  265. {
  266. object o1 = ReadFromString("abc");
  267. Expect(o1, TypeOf(typeof(Symbol)));
  268. Expect(((Symbol)o1).Name, EqualTo("abc"));
  269. Expect(((Symbol)o1).Namespace, Null);
  270. }
  271. [Test]
  272. public void ReadReadsSymbolWithNS()
  273. {
  274. object o1 = ReadFromString("ab/cd");
  275. Expect(o1, TypeOf(typeof(Symbol)));
  276. Expect(((Symbol)o1).Name, EqualTo("cd"));
  277. Expect(((Symbol)o1).Namespace, EqualTo("ab"));
  278. }
  279. [Test]
  280. public void TwoSlashesIsOkayApparently()
  281. {
  282. object o1 = ReadFromString("ab/cd/e");
  283. Expect(o1, TypeOf(typeof(Symbol)));
  284. Expect(((Symbol)o1).Name, EqualTo("e"));
  285. Expect(((Symbol)o1).Namespace, EqualTo("ab/cd"));
  286. }
  287. [Test]
  288. [ExpectedException(typeof(Exception))]
  289. public void NamespaceEndingWithColonSlashIsBad()
  290. {
  291. object o1 = ReadFromString("ab:/cd");
  292. }
  293. [Test]
  294. [ExpectedException(typeof(Exception))]
  295. public void NameEndingWithColonIsBad()
  296. {
  297. object o1 = ReadFromString("ab/cd:");
  298. }
  299. [Test]
  300. [ExpectedException(typeof(Exception))]
  301. public void NameEndingWithColonIsBad2()
  302. {
  303. object o1 = ReadFromString("cd:");
  304. }
  305. [Test]
  306. public void NameMayContainMultipleColons()
  307. {
  308. object o1 = ReadFromString("a:b:c/d:e:f");
  309. Expect(o1, TypeOf(typeof(Symbol)));
  310. }
  311. [Test]
  312. [ExpectedException(typeof(Exception))]
  313. public void NameContainingDoubleColonNotAtBeginningIsBad()
  314. {
  315. object o1 = ReadFromString("ab::cd");
  316. }
  317. [Test]
  318. [ExpectedException(typeof(Exception))]
  319. public void NamespaceContainingDoubleColonNotAtBeginningIsBad()
  320. {
  321. object o1 = ReadFromString("ab::cd/ef");
  322. }
  323. #endregion
  324. #region Keyword tests
  325. [Test]
  326. public void LeadingColonIsKeyword()
  327. {
  328. object o1 = ReadFromString(":abc");
  329. Expect(o1, TypeOf(typeof(Keyword)));
  330. Expect(((Keyword)o1).Namespace, Null);
  331. Expect(((Keyword)o1).Name, EqualTo("abc"));
  332. }
  333. [Test]
  334. public void LeadingColonWithNSIsKeyword()
  335. {
  336. object o1 = ReadFromString(":ab/cd");
  337. Expect(o1, TypeOf(typeof(Keyword)));
  338. Expect(((Keyword)o1).Namespace, EqualTo("ab"));
  339. Expect(((Keyword)o1).Name, EqualTo("cd"));
  340. }
  341. // TODO: Add more tests dealing with :: resolution.
  342. [Test]
  343. public void LeadingDoubleColonMakesKeywordInCurrentNamespace()
  344. {
  345. object o1 = ReadFromString("::abc");
  346. Expect(o1, TypeOf(typeof(Keyword)));
  347. Expect(((Keyword)o1).Namespace, EqualTo(((Namespace)RT.CURRENT_NS.deref()).Name.Name));
  348. Expect(((Keyword)o1).Name, EqualTo("abc"));
  349. }
  350. // At one time, this test worked. Now, according to the documentation, it should not work. Did something change? Never mind.
  351. //[Test]
  352. //public void LeadingDoubleColonDoesNotSetNamespaceIfPeriodsInName()
  353. //{
  354. // object o1 = ReadFromString("::ab.cd");
  355. // Expect(o1, TypeOf(typeof(Keyword)));
  356. // Expect(((Keyword)o1).Namespace, Null);
  357. // Expect(((Keyword)o1).Name, EqualTo("ab.cd"));
  358. //}
  359. #endregion
  360. #region String tests
  361. [Test]
  362. public void DoubleQuotesSurroundAString()
  363. {
  364. object o1 = ReadFromString("\"abc\"");
  365. Expect(o1,TypeOf(typeof(string)));
  366. Expect(o1, EqualTo("abc"));
  367. }
  368. [Test]
  369. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  370. public void NoEndingDoubleQuoteFails()
  371. {
  372. object o1 = ReadFromString("\"abc");
  373. }
  374. [Test]
  375. public void EmptyStringWorks()
  376. {
  377. object o1 = ReadFromString("\"\"");
  378. Expect(o1, TypeOf(typeof(string)));
  379. Expect(o1, EqualTo(String.Empty));
  380. }
  381. [Test]
  382. public void EscapesWorkInStrings()
  383. {
  384. char[] chars = new char[] {
  385. '"', 'a',
  386. '\\', 't', 'b',
  387. '\\', 'r', 'c',
  388. '\\', 'n', 'd',
  389. '\\', '\\', 'e',
  390. '\\', '"', 'f',
  391. '\\', 'b', 'g',
  392. '\\', 'f', 'h', '"'
  393. };
  394. string s = new String(chars);
  395. Expect(s.Length, EqualTo(24));
  396. object o1 = ReadFromString(s);
  397. Expect(o1, EqualTo("a\tb\rc\nd\\e\"f\bg\fh"));
  398. }
  399. [Test]
  400. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  401. public void EOFinEscapeIsError()
  402. {
  403. char[] chars = new char[] {
  404. '"', 'a',
  405. '\\', 't', 'b',
  406. '\\', 'r', 'c',
  407. '\\', 'n', 'd',
  408. '\\'
  409. };
  410. string s = new String(chars);
  411. object o1 = ReadFromString(s);
  412. }
  413. [Test]
  414. public void UnicodeEscapeInsertsUnicodeCharacter()
  415. {
  416. char[] chars = new char[] {
  417. '"', 'a',
  418. '\\', 'u', '1', '2', 'C', '4',
  419. 'b', '"'
  420. };
  421. string s = new String(chars);
  422. object o1 = ReadFromString(s);
  423. Expect(o1, EqualTo("a\u12C4b"));
  424. }
  425. [Test]
  426. [ExpectedException(typeof(ArgumentException))]
  427. public void UnicodeEscapeWithBadCharacterFails()
  428. {
  429. char[] chars = new char[] {
  430. '"', 'a',
  431. '\\', 'u', '1', '2', 'X', '4',
  432. 'b', '"'
  433. };
  434. string s = new String(chars);
  435. object o1 = ReadFromString(s);
  436. }
  437. [Test]
  438. [ExpectedException(typeof(ArgumentException))]
  439. public void UnicodeEscapeWithEOFFails()
  440. {
  441. char[] chars = new char[] {
  442. '"', 'a',
  443. '\\', 'u', '1', '2', 'A', '"'
  444. };
  445. string s = new String(chars);
  446. object o1 = ReadFromString(s);
  447. }
  448. [Test]
  449. public void OctalEscapeInsertsCharacter()
  450. {
  451. char[] chars = new char[] {
  452. '"', 'a',
  453. '\\', '1', '2', '4',
  454. 'b', '"'
  455. };
  456. string s = new String(chars);
  457. object o1 = ReadFromString(s);
  458. Expect(o1, EqualTo("a\x0054b")); // hex/octal conversion
  459. }
  460. [Test]
  461. [ExpectedException(typeof(ArgumentException))]
  462. public void OctalEscapeWithBadDigitFails()
  463. {
  464. char[] chars = new char[] {
  465. '"', 'a',
  466. '\\', '1', '8', '4',
  467. 'b', '"'
  468. };
  469. string s = new String(chars);
  470. object o1 = ReadFromString(s);
  471. }
  472. [Test]
  473. [ExpectedException(typeof(ArgumentException))]
  474. public void OctalEscapeWithEOFFails()
  475. {
  476. char[] chars = new char[] {
  477. '"', 'a',
  478. '\\', '1', '8', '"'
  479. };
  480. string s = new String(chars);
  481. object o1 = ReadFromString(s);
  482. }
  483. [ExpectedException(typeof(ArgumentException))]
  484. public void OctalEscapeOutOfRangeFails()
  485. {
  486. char[] chars = new char[] {
  487. '"', 'a',
  488. '\\', '4', '7', '7',
  489. 'b', '"'
  490. };
  491. string s = new String(chars);
  492. object o1 = ReadFromString(s);
  493. }
  494. #endregion
  495. #region Character tests
  496. [Test]
  497. public void BackslashYieldsNextCharacter()
  498. {
  499. object o1 = ReadFromString("\\a");
  500. Expect(o1, TypeOf(typeof(Char)));
  501. Expect(o1, EqualTo('a'));
  502. }
  503. [Test]
  504. public void BackslashYieldsNextCharacterStoppingAtTerminator()
  505. {
  506. object o1 = ReadFromString("\\a b");
  507. Expect(o1, TypeOf(typeof(Char)));
  508. Expect(o1, EqualTo('a'));
  509. }
  510. [Test]
  511. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  512. public void BackslashFollowedByEOFFails()
  513. {
  514. object o1 = ReadFromString("\\");
  515. }
  516. [Test]
  517. public void BackslashRecognizesSpecialNames()
  518. {
  519. object o1 = ReadFromString("\\newline");
  520. object o2 = ReadFromString("\\space");
  521. object o3 = ReadFromString("\\tab");
  522. object o4 = ReadFromString("\\backspace");
  523. object o5 = ReadFromString("\\formfeed");
  524. object o6 = ReadFromString("\\return");
  525. Expect(o1, EqualTo('\n'));
  526. Expect(o2, EqualTo(' '));
  527. Expect(o3, EqualTo('\t'));
  528. Expect(o4, EqualTo('\b'));
  529. Expect(o5, EqualTo('\f'));
  530. Expect(o6, EqualTo('\r'));
  531. }
  532. [Test]
  533. public void BackslashRecognizesUnicode()
  534. {
  535. object o1 = ReadFromString("\\u12C4");
  536. Expect(o1, EqualTo('\u12C4'));
  537. }
  538. [Test]
  539. [ExpectedException(typeof(ArgumentException))]
  540. public void BackslashUnicodeWithEOFFails()
  541. {
  542. object o1 = ReadFromString("\\u12C 4");
  543. }
  544. [Test]
  545. [ExpectedException(typeof(Exception))]
  546. public void BackslashUnicodeInBadRangeFails()
  547. {
  548. object o1 = ReadFromString("\\uDAAA");
  549. }
  550. [Test]
  551. [ExpectedException(typeof(ArgumentException))]
  552. public void BackslashUnicodeWithBadDigitFails()
  553. {
  554. object o1 = ReadFromString("\\u12X4");
  555. }
  556. [Test]
  557. public void BackslashRecognizesOctal()
  558. {
  559. object o1 = ReadFromString("\\o124");
  560. Expect(o1, EqualTo('\x54'));
  561. }
  562. [Test]
  563. [ExpectedException(typeof(ArgumentException))]
  564. public void BackslashOctalWithEOFFails()
  565. {
  566. object o1 = ReadFromString("\\u12 4");
  567. }
  568. [Test]
  569. [ExpectedException(typeof(Exception))]
  570. public void BackslashOctalInBadRangeFails()
  571. {
  572. object o1 = ReadFromString("\\o444");
  573. }
  574. [Test]
  575. [ExpectedException(typeof(ArgumentException))]
  576. public void BackslashOctalWithBadDigitFails()
  577. {
  578. object o1 = ReadFromString("\\o128");
  579. }
  580. [Test]
  581. [ExpectedException(typeof(Exception))]
  582. public void BackslashOctalWithTooManyDigitsFails()
  583. {
  584. object o1 = ReadFromString("\\o0012 aa");
  585. }
  586. [Test]
  587. [ExpectedException(typeof(Exception))]
  588. public void BackslashWithOtherFails()
  589. {
  590. object o1 = ReadFromString("\\aa");
  591. }
  592. #endregion
  593. #region comment tests
  594. [Test]
  595. public void SemicolonIgnoresToEndOfLine()
  596. {
  597. object o1 = ReadFromString(" ; ignore \n 123");
  598. Expect(o1, EqualTo(123));
  599. }
  600. [Test]
  601. public void SharpBangIgnoresToEndOfLine()
  602. {
  603. object o1 = ReadFromString(" #! ignore \n 123");
  604. Expect(o1, EqualTo(123));
  605. }
  606. #endregion
  607. #region Discard tests
  608. [Test]
  609. public void SharpUnderscoreIgnoresNextForm()
  610. {
  611. object o1 = ReadFromString("#_ (1 2 3) 4");
  612. Expect(o1, EqualTo(4));
  613. }
  614. [Test]
  615. public void SharpUnderscoreIgnoresNextFormInList()
  616. {
  617. object o1 = ReadFromString("( abc #_ (1 2 3) 12)");
  618. Expect(o1, TypeOf(typeof(PersistentList)));
  619. PersistentList pl = o1 as PersistentList;
  620. Expect(pl.count(), EqualTo(2));
  621. Expect(pl.first(), TypeOf(typeof(Symbol)));
  622. Expect(((Symbol)pl.first()).Name, EqualTo("abc"));
  623. Expect(((Symbol)pl.first()).Namespace, Null);
  624. Expect(pl.next().first(), TypeOf(typeof(int)));
  625. Expect(pl.next().first(), EqualTo(12));
  626. Expect(pl.next().next(), Null);
  627. }
  628. #endregion
  629. #region List tests
  630. [Test]
  631. public void CanReadBasicList()
  632. {
  633. Object o1 = ReadFromString("(abc 12)");
  634. Expect(o1, TypeOf(typeof(PersistentList)));
  635. PersistentList pl = o1 as PersistentList;
  636. Expect(pl.count(), EqualTo(2));
  637. Expect(pl.first(), TypeOf(typeof(Symbol)));
  638. Expect(((Symbol)pl.first()).Name, EqualTo("abc"));
  639. Expect(((Symbol)pl.first()).Namespace, Null);
  640. Expect(pl.next().first(), TypeOf(typeof(int)));
  641. Expect(pl.next().first(), EqualTo(12));
  642. Expect(pl.next().next(), Null);
  643. }
  644. [Test]
  645. public void CanReadEmptyList()
  646. {
  647. Object o1 = ReadFromString("( )");
  648. Expect(o1, InstanceOfType(typeof(IPersistentList)));
  649. IPersistentList pl = o1 as IPersistentList;
  650. Expect(pl.count(), EqualTo(0));
  651. }
  652. [Test]
  653. public void CanReadNestedList()
  654. {
  655. Object o1 = ReadFromString("(a (b c) d)");
  656. Expect(o1, InstanceOfType(typeof(IPersistentList)));
  657. IPersistentList pl = o1 as IPersistentList;
  658. ISeq seq = pl.seq();
  659. Expect(pl.count(), EqualTo(3));
  660. Expect(seq.next().first(), InstanceOfType(typeof(IPersistentList)));
  661. IPersistentList sub = seq.next().first() as IPersistentList;
  662. Expect(sub.count(), EqualTo(2));
  663. }
  664. [Test]
  665. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  666. public void MissingListTerminatorFails()
  667. {
  668. Object o1 = ReadFromString("(a b 1 2");
  669. }
  670. [Test]
  671. public void ListGetsLineNumber()
  672. {
  673. Object o1 = ReadFromStringNumbering("\n\n(a b \n1 2)");
  674. Expect(o1, InstanceOfType(typeof(IObj)));
  675. IObj io = o1 as IObj;
  676. Expect(io.meta().valAt(Keyword.intern(null,"line")), EqualTo(3));
  677. }
  678. #endregion
  679. #region VectorTests
  680. [Test]
  681. public void CanReadBasicVector()
  682. {
  683. Object o1 = ReadFromString("[abc 12]");
  684. Expect(o1, TypeOf(typeof(LazilyPersistentVector)));
  685. LazilyPersistentVector pl = o1 as LazilyPersistentVector;
  686. Expect(pl.count(), EqualTo(2));
  687. Expect(pl.nth(0), TypeOf(typeof(Symbol)));
  688. Expect(((Symbol)pl.nth(0)).Name, EqualTo("abc"));
  689. Expect(((Symbol)pl.nth(0)).Namespace, Null);
  690. Expect(pl.nth(1), TypeOf(typeof(int)));
  691. Expect(pl.nth(1), EqualTo(12));
  692. }
  693. [Test]
  694. public void CanReadEmptyVector()
  695. {
  696. Object o1 = ReadFromString("[ ]");
  697. Expect(o1, InstanceOfType(typeof(IPersistentVector)));
  698. IPersistentVector v = o1 as IPersistentVector;
  699. Expect(v.count(), EqualTo(0));
  700. }
  701. [Test]
  702. public void VectorCanContainNestedList()
  703. {
  704. Object o1 = ReadFromString("[a (b c) d]");
  705. Expect(o1, InstanceOfType(typeof(IPersistentVector)));
  706. IPersistentVector v = o1 as IPersistentVector;
  707. Expect(v.count(), EqualTo(3));
  708. Expect(v.nth(1), InstanceOfType(typeof(IPersistentList)));
  709. IPersistentList sub = v.nth(1) as IPersistentList;
  710. Expect(sub.count(), EqualTo(2));
  711. }
  712. [Test]
  713. public void VectorCanContainNestedVector()
  714. {
  715. Object o1 = ReadFromString("[a [b c] d]");
  716. Expect(o1, InstanceOfType(typeof(IPersistentVector)));
  717. IPersistentVector v = o1 as IPersistentVector;
  718. Expect(v.count(), EqualTo(3));
  719. Expect(v.nth(1), InstanceOfType(typeof(IPersistentVector)));
  720. IPersistentVector sub = v.nth(1) as IPersistentVector;
  721. Expect(sub.count(), EqualTo(2));
  722. }
  723. [Test]
  724. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  725. public void MissingVectorTerminatorFails()
  726. {
  727. Object o1 = ReadFromString("[a b 1 2");
  728. }
  729. #endregion
  730. #region Map tests
  731. [Test]
  732. public void CanReadBasicMap()
  733. {
  734. Object o1 = ReadFromString("{:abc 12 14 a}");
  735. Expect(o1, InstanceOfType(typeof(IPersistentMap)));
  736. IPersistentMap m = o1 as IPersistentMap;
  737. Expect(m.count(), EqualTo(2));
  738. Expect(m.valAt(Keyword.intern(null, "abc")), EqualTo(12));
  739. Expect(m.valAt(14), EqualTo(Symbol.intern("a")));
  740. }
  741. [Test]
  742. public void CanReadEmptyMap()
  743. {
  744. Object o1 = ReadFromString("{ }");
  745. Expect(o1, InstanceOfType(typeof(IPersistentMap)));
  746. IPersistentMap m = o1 as IPersistentMap;
  747. Expect(m.count(), EqualTo(0));
  748. }
  749. [Test]
  750. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  751. public void MissingRightBraceFails()
  752. {
  753. Object o1 = ReadFromString("{a b 1 2");
  754. }
  755. [Test]
  756. [ExpectedException(typeof(ArgumentException))]
  757. public void MapWithOddNumberOfEntriesFails()
  758. {
  759. Object o1 = ReadFromString("{a b 1}");
  760. }
  761. #endregion
  762. #region Set tests
  763. [Test]
  764. public void CanReadBasicSet()
  765. {
  766. Object o1 = ReadFromString("#{abc 12}");
  767. Expect(o1, InstanceOfType(typeof(IPersistentSet)));
  768. IPersistentSet s = o1 as IPersistentSet;
  769. Expect(s.count(), EqualTo(2));
  770. Expect(s.contains(Symbol.intern("abc")));
  771. Expect(s.contains(12));
  772. }
  773. [Test]
  774. public void CanReadEmptySet()
  775. {
  776. Object o1 = ReadFromString("#{ }");
  777. Expect(o1, InstanceOfType(typeof(IPersistentSet)));
  778. IPersistentSet s = o1 as IPersistentSet;
  779. Expect(s.count(), EqualTo(0));
  780. }
  781. [Test]
  782. [ExpectedException(typeof(System.IO.EndOfStreamException))]
  783. public void MissingSetTerminatorFails()
  784. {
  785. Object o1 = ReadFromString("#{a b 1 2");
  786. }
  787. #endregion
  788. #region Unmatched delimiter tests
  789. [Test]
  790. [ExpectedException(typeof(Exception))]
  791. public void NakedRightParenIsBad()
  792. {
  793. Object o1 = ReadFromString("}");
  794. }
  795. [Test]
  796. [ExpectedException(typeof(Exception))]
  797. public void NakedRightBracketIsBad()
  798. {
  799. Object o1 = ReadFromString("]");
  800. }
  801. [Test]
  802. [ExpectedException(typeof(Exception))]
  803. public void NakedRightBraceIsBad()
  804. {
  805. Object o1 = ReadFromString("}");
  806. }
  807. [Test]
  808. [ExpectedException(typeof(Exception))]
  809. public void MismatchedDelimiterIsBad()
  810. {
  811. Object o1 = ReadFromString("( a b c }");
  812. }
  813. #endregion
  814. #region Wrapping forms
  815. [Test]
  816. public void QuoteWraps()
  817. {
  818. object o1 = ReadFromString("'a");
  819. Expect(o1, InstanceOfType(typeof(ISeq)));
  820. ISeq s = o1 as ISeq;
  821. Expect(s.count(), EqualTo(2));
  822. Expect(s.first(),EqualTo(Symbol.intern("quote")));
  823. Expect(s.next().first(),TypeOf(typeof(Symbol)));
  824. }
  825. [Test]
  826. public void QuoteWraps2()
  827. {
  828. object o1 = ReadFromString("'(a b c)");
  829. Expect(o1, InstanceOfType(typeof(ISeq)));
  830. ISeq s = o1 as ISeq;
  831. Expect(s.count(), EqualTo(2));
  832. Expect(s.first(), EqualTo(Symbol.intern("quote")));
  833. Expect(s.next().first(), InstanceOfType(typeof(IPersistentList)));
  834. Expect(((IPersistentList)s.next().first()).count(), EqualTo(3));
  835. }
  836. [Test]
  837. public void MetaWraps()
  838. {
  839. object o1 = ReadFromString("^a");
  840. Expect(o1, InstanceOfType(typeof(ISeq)));
  841. ISeq s = o1 as ISeq;
  842. Expect(s.count(), EqualTo(2));
  843. Expect(s.first(), EqualTo(Symbol.intern("clojure.core","meta")));
  844. Expect(s.next().first(), TypeOf(typeof(Symbol)));
  845. }
  846. [Test]
  847. public void MetaWraps2()
  848. {
  849. object o1 = ReadFromString("^(a b c)");
  850. Expect(o1, InstanceOfType(typeof(ISeq)));
  851. ISeq s = o1 as ISeq;
  852. Expect(s.count(), EqualTo(2));
  853. Expect(s.first(), EqualTo(Symbol.intern("clojure.core", "meta")));
  854. Expect(s.next().first(), InstanceOfType(typeof(IPersistentList)));
  855. Expect(((IPersistentList)s.next().first()).count(), EqualTo(3));
  856. }
  857. [Test]
  858. public void DerefWraps()
  859. {
  860. object o1 = ReadFromString("@a");
  861. Expect(o1, InstanceOfType(typeof(ISeq)));
  862. ISeq s = o1 as ISeq;
  863. Expect(s.count(), EqualTo(2));
  864. Expect(s.first(), EqualTo(Symbol.intern("clojure.core", "deref")));
  865. Expect(s.next().first(), TypeOf(typeof(Symbol)));
  866. }
  867. [Test]
  868. public void DerefWraps2()
  869. {
  870. object o1 = ReadFromString("@(a b c)");
  871. Expect(o1, InstanceOfType(typeof(ISeq)));
  872. ISeq s = o1 as ISeq;
  873. Expect(s.count(), EqualTo(2));
  874. Expect(s.first(), EqualTo(Symbol.intern("clojure.core", "deref")));
  875. Expect(s.next().first(), InstanceOfType(typeof(IPersistentList)));
  876. Expect(((IPersistentList)s.next().first()).count(), EqualTo(3));
  877. }
  878. #endregion
  879. #region Syntax-quote tests
  880. [Test]
  881. public void SQOnSelfEvaluatingReturnsQuotedThing()
  882. {
  883. object o1 = ReadFromString("`:abc");
  884. object o2 = ReadFromString("`222");
  885. object o3 = ReadFromString("`\\a)");
  886. object o4 = ReadFromString("`\"abc\"");
  887. Expect(o1, TypeOf(typeof(Keyword)));
  888. Expect(o1, EqualTo(Keyword.intern(null, "abc")));
  889. Expect(o2, TypeOf(typeof(int)));
  890. Expect(o2, EqualTo(222));
  891. Expect(o3, TypeOf(typeof(char)));
  892. Expect(o3, EqualTo('a'));
  893. Expect(o4, TypeOf(typeof(string)));
  894. Expect(o4, EqualTo("abc"));
  895. }
  896. [Test]
  897. public void SQOnSpecialFormQuotes()
  898. {
  899. object o1 = ReadFromString("`def");
  900. Expect(o1,InstanceOfType(typeof(ISeq)));
  901. ISeq s = o1 as ISeq;
  902. Expect(s.count(),EqualTo(2) );
  903. Expect(s.first(),EqualTo(Symbol.intern("quote")));
  904. Expect(s.next().first(),InstanceOfType(typeof(Symbol)));
  905. Symbol sym = s.next().first() as Symbol;
  906. Expect(sym.Namespace, Null);
  907. Expect(sym.Name, EqualTo("def"));
  908. }
  909. [Test]
  910. public void SQOnRegularSymbolResolves()
  911. {
  912. object o1 = ReadFromString("`abc");
  913. Expect(o1, InstanceOfType(typeof(ISeq)));
  914. ISeq s = o1 as ISeq;
  915. Expect(s.count(), EqualTo(2));
  916. Expect(s.first(), EqualTo(Symbol.intern("quote")));
  917. Expect(s.next().first(), InstanceOfType(typeof(Symbol)));
  918. Symbol sym = s.next().first() as Symbol;
  919. Expect(sym.Namespace, EqualTo(((Namespace)RT.CURRENT_NS.deref()).Name.Name));
  920. Expect(sym.Name, EqualTo("abc"));
  921. }
  922. [Test]
  923. public void SQOnGensymGenerates()
  924. {
  925. object o1 = ReadFromString("`abc#");
  926. Expect(o1, InstanceOfType(typeof(ISeq)));
  927. ISeq s = o1 as ISeq;
  928. Expect(s.count(), EqualTo(2));
  929. Expect(s.first(), EqualTo(Symbol.intern("quote")));
  930. Expect(s.next().first(), InstanceOfType(typeof(Symbol)));
  931. Symbol sym = s.next().first() as Symbol;
  932. Expect(sym.Namespace, Null);
  933. Expect(sym.Name.StartsWith("abc_")); ;
  934. }
  935. [Test]
  936. public void SQOnGensymSeesSameTwice()
  937. {
  938. object o1 = ReadFromString("`(abc# abc#)");
  939. // Return should be
  940. // (clojure/seq (clojure/concat (clojure/list (quote abc__N))
  941. // (clojure/list (quote abc__N)))))
  942. string str = o1.ToString();
  943. Expect(o1, InstanceOfType(typeof(ISeq)));
  944. ISeq s = o1 as ISeq;
  945. Expect(s.count(),EqualTo(2));
  946. Expect(s.first(),EqualTo(Symbol.intern("clojure.core","seq")));
  947. Expect(s.next().first(),InstanceOfType(typeof(ISeq)));
  948. ISeq s1 = s.next().first() as ISeq;
  949. Expect(s1.count(), EqualTo(3));
  950. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core","concat")));
  951. Expect(s1.next().first(), InstanceOfType(typeof(ISeq)));
  952. ISeq s2 = s1.next().first() as ISeq;
  953. Expect(s2.count(), EqualTo(2));
  954. Expect(s2.next().first(), InstanceOfType(typeof(ISeq)));
  955. ISeq s2a = s2.next().first() as ISeq;
  956. Expect(s2a.next().first(), InstanceOfType(typeof(Symbol)));
  957. Symbol sym1 = s2a.next().first() as Symbol;
  958. Expect(s1.next().next().first(), InstanceOfType(typeof(ISeq)));
  959. ISeq s3 = s1.next().next().first() as ISeq;
  960. Expect(s3.count(), EqualTo(2));
  961. Expect(s3.next().first(), InstanceOfType(typeof(ISeq)));
  962. ISeq s3a = s3.next().first() as ISeq;
  963. Expect(s3a.next().first(), InstanceOfType(typeof(Symbol)));
  964. Symbol sym2 = s3a.next().first() as Symbol;
  965. Expect(sym1.Namespace, Null);
  966. Expect(sym1.Name.StartsWith("abc__"));
  967. Expect(sym1, EqualTo(sym2));
  968. }
  969. [Test]
  970. public void SQOnMapMakesMap()
  971. {
  972. Object o1 = ReadFromString("`{:a 1 :b 2}");
  973. // (clojure/apply
  974. // clojure/hash-map
  975. // (clojure/seq
  976. // (clojure/concat (clojure/list :a)
  977. // (clojure/list 1)
  978. // (clojure/list :b)
  979. // (clojure/list 2))))
  980. Expect(o1, InstanceOfType(typeof(ISeq)));
  981. ISeq s = o1 as ISeq;
  982. Expect(s.count(), EqualTo(3));
  983. Expect(s.first(), EqualTo(Symbol.intern("clojure.core/apply")));
  984. Expect(s.next().first(), EqualTo(Symbol.intern("clojure.core/hash-map")));
  985. Expect(s.next().next().first(), InstanceOfType(typeof(ISeq)));
  986. ISeq s0 = s.next().next().first() as ISeq;
  987. ISeq s2;
  988. Expect(s0.count(), EqualTo(2));
  989. Expect(s0.first(), EqualTo(Symbol.intern("clojure.core/seq")));
  990. Expect(s0.next().first(),InstanceOfType(typeof(ISeq)));
  991. ISeq s1 = s0.next().first() as ISeq;
  992. Expect(s1.count(), EqualTo(5));
  993. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core/concat")));
  994. s1 = s1.next();
  995. Expect(s1.first(),InstanceOfType(typeof(ISeq)));
  996. s2 = s1.first() as ISeq;
  997. Expect(s2.first(),EqualTo(Symbol.intern("clojure.core/list")));
  998. Expect(s2.next().first(),EqualTo(Keyword.intern(null,"a")));
  999. s1 = s1.next();
  1000. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1001. s2 = s1.first() as ISeq;
  1002. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1003. Expect(s2.next().first(), EqualTo(1));
  1004. s1 = s1.next();
  1005. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1006. s2 = s1.first() as ISeq;
  1007. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1008. Expect(s2.next().first(), EqualTo(Keyword.intern(null, "b")));
  1009. s1 = s1.next();
  1010. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1011. s2 = s1.first() as ISeq;
  1012. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1013. Expect(s2.next().first(), EqualTo(2));
  1014. }
  1015. public void SQOnVectorMakesVector()
  1016. {
  1017. Object o1 = ReadFromString("`[:b 2]");
  1018. // (clojure/apply
  1019. // clojure/vector
  1020. // (clojure/concat (clojure/list :b)
  1021. // (clojure/list 2)))
  1022. Expect(o1, InstanceOfType(typeof(ISeq)));
  1023. ISeq s = o1 as ISeq;
  1024. Expect(s.count(), EqualTo(3));
  1025. Expect(s.first(), EqualTo(Symbol.intern("clojure.core/apply")));
  1026. Expect(s.next().first(), EqualTo(Symbol.intern("clojure.core/vector")));
  1027. Expect(s.next().next().first(), InstanceOfType(typeof(ISeq)));
  1028. ISeq s1 = s.next().next().first() as ISeq;
  1029. ISeq s2;
  1030. Expect(s1.count(), EqualTo(3));
  1031. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core/concat")));
  1032. s1 = s1.next();
  1033. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1034. s2 = s1.first() as ISeq;
  1035. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1036. Expect(s2.next().first(), EqualTo(Keyword.intern(null, "b")));
  1037. s1 = s1.next();
  1038. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1039. s2 = s1.first() as ISeq;
  1040. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1041. Expect(s2.next().first(), EqualTo(2));
  1042. }
  1043. [Test]
  1044. public void SQOnSetMakesSet()
  1045. {
  1046. Object o1 = ReadFromString("`#{:b 2}");
  1047. // (clojure/apply
  1048. // clojure/hash-set
  1049. // (clojure/seq
  1050. // (clojure/concat (clojure/list :b)
  1051. // (clojure/list 2))))
  1052. Expect(o1, InstanceOfType(typeof(ISeq)));
  1053. ISeq s = o1 as ISeq;
  1054. Expect(s.count(), EqualTo(3));
  1055. Expect(s.first(), EqualTo(Symbol.intern("clojure.core/apply")));
  1056. Expect(s.next().first(), EqualTo(Symbol.intern("clojure.core/hash-set")));
  1057. Expect(s.next().next().first(), InstanceOfType(typeof(ISeq)));
  1058. ISeq s0 = s.next().next().first() as ISeq;
  1059. Expect(s0.count(), EqualTo(2));
  1060. Expect(s0.first(),EqualTo(Symbol.intern("clojure.core/seq")));
  1061. Expect(s0.next().first(),InstanceOfType(typeof(ISeq)));
  1062. ISeq s1 = s0.next().first() as ISeq;
  1063. Expect(s1.count(), EqualTo(3));
  1064. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core/concat")));
  1065. s1 = s1.next();
  1066. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1067. ISeq s2 = s1.first() as ISeq;
  1068. s1 = s1.next();
  1069. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1070. ISeq s3 = s1.first() as ISeq;
  1071. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1072. Expect(s3.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1073. object e1 = s2.next().first();
  1074. object e2 = s3.next().first();
  1075. // Set elements can occur in any order
  1076. Expect(e1, EqualTo(Keyword.intern(null, "b")) | EqualTo(2));
  1077. Expect(e2, EqualTo(Keyword.intern(null, "b")) | EqualTo(2));
  1078. Expect(e1, Not.EqualTo(e2));
  1079. }
  1080. [Test]
  1081. public void SQOnListMakesList()
  1082. {
  1083. Object o1 = ReadFromString("`(:b 2)");
  1084. // (clojure/seq (clojure/concat (clojure/list :b)
  1085. // (clojure/list 2))))
  1086. Expect(o1, InstanceOfType(typeof(ISeq)));
  1087. ISeq s0 = o1 as ISeq;
  1088. Expect(s0.count(), EqualTo(2));
  1089. Expect(s0.first(), EqualTo(Symbol.intern("clojure.core/seq")));
  1090. Expect(s0.next().first(),InstanceOfType(typeof(ISeq)));
  1091. ISeq s1 = s0.next().first() as ISeq;
  1092. ISeq s2;
  1093. Expect(s1.count(), EqualTo(3));
  1094. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core/concat")));
  1095. s1 = s1.next();
  1096. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1097. s2 = s1.first() as ISeq;
  1098. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1099. Expect(s2.next().first(), EqualTo(Keyword.intern(null, "b")));
  1100. s1 = s1.next();
  1101. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1102. s2 = s1.first() as ISeq;
  1103. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1104. Expect(s2.next().first(), EqualTo(2));
  1105. }
  1106. [Test]
  1107. public void UnquoteStandaloneReturnsUnquoteObject()
  1108. {
  1109. object o1 = ReadFromString("~x");
  1110. //Expect(o1, InstanceOfType(typeof(LispReader.Unquote)));
  1111. //LispReader.Unquote u = o1 as LispReader.Unquote;
  1112. //Expect(u.Obj, EqualTo(Symbol.intern("x")));
  1113. Expect(o1, InstanceOfType(typeof(ISeq)));
  1114. ISeq s = o1 as ISeq;
  1115. Expect(s.first(), EqualTo(Symbol.intern("clojure.core/unquote")));
  1116. Expect(s.next().first(), EqualTo(Symbol.intern("x")));
  1117. Expect(s.count(), EqualTo(2));
  1118. }
  1119. [Test]
  1120. public void UnquoteSpliceStandaloneReturnsUnquoteSpliceObject()
  1121. {
  1122. object o1 = ReadFromString("~@x");
  1123. Expect(o1, InstanceOfType(typeof(ISeq)));
  1124. ISeq s = o1 as ISeq;
  1125. Expect(s.first(), EqualTo(Symbol.intern("clojure.core/unquote-splicing")));
  1126. Expect(s.next().first(), EqualTo(Symbol.intern("x")));
  1127. Expect(s.count(), EqualTo(2));
  1128. }
  1129. [Test]
  1130. public void SQonUnquoteDequotes()
  1131. {
  1132. object o1 = ReadFromString("`(a ~b)");
  1133. // (clojure/seq (clojure/concat (clojure/list (quote NS/a))
  1134. // (clojure/list b)))
  1135. Expect(o1, InstanceOfType(typeof(ISeq)));
  1136. ISeq s0 = o1 as ISeq;
  1137. Expect(s0.count(),EqualTo(2));
  1138. Expect(s0.first(),EqualTo(Symbol.intern("clojure.core/seq")));
  1139. Expect(s0.next().first(),InstanceOfType(typeof(ISeq)));
  1140. ISeq s1 = s0.next().first() as ISeq;
  1141. ISeq s2;
  1142. Expect(s1.count(), EqualTo(3));
  1143. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core/concat")));
  1144. s1 = s1.next();
  1145. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1146. s2 = s1.first() as ISeq;
  1147. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1148. Expect(s2.next().first(), InstanceOfType(typeof(ISeq)));
  1149. ISeq s3 = s2.next().first() as ISeq;
  1150. Expect(s3.count(), EqualTo(2));
  1151. Expect(s3.first(), EqualTo(Symbol.intern("quote")));
  1152. Expect(s3.next().first(), EqualTo(Symbol.intern(((Namespace)RT.CURRENT_NS.deref()).Name.Name,"a")));
  1153. s1 = s1.next();
  1154. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1155. s2 = s1.first() as ISeq;
  1156. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1157. Expect(s2.next().first(), EqualTo(Symbol.intern("b")));
  1158. }
  1159. [Test]
  1160. [ExpectedException(typeof(ArgumentException))]
  1161. public void SQonUnquoteSpliceNotInListFails()
  1162. {
  1163. object o1 = ReadFromString("`~@x");
  1164. }
  1165. [Test]
  1166. public void SqOnUnquoteSpliceSplices()
  1167. {
  1168. object o1 = ReadFromString("`(a ~@b)");
  1169. // (clojure/seq (clojure/concat (clojure/list (quote user/a)) b))
  1170. Expect(o1, InstanceOfType(typeof(ISeq)));
  1171. ISeq s0 = o1 as ISeq;
  1172. Expect(s0.count(), EqualTo(2));
  1173. Expect(s0.first(), EqualTo(Symbol.intern("clojure.core/seq")));
  1174. Expect(s0.next().first(), InstanceOfType(typeof(ISeq)));
  1175. ISeq s1 = s0.next().first() as ISeq;
  1176. ISeq s2;
  1177. Expect(s1.count(), EqualTo(3));
  1178. Expect(s1.first(), EqualTo(Symbol.intern("clojure.core/concat")));
  1179. s1 = s1.next();
  1180. Expect(s1.first(), InstanceOfType(typeof(ISeq)));
  1181. s2 = s1.first() as ISeq;
  1182. Expect(s2.first(), EqualTo(Symbol.intern("clojure.core/list")));
  1183. Expect(s2.next().first(), InstanceOfType(typeof(ISeq)));
  1184. ISeq s3 = s2.next().first() as ISeq;
  1185. Expect(s3.count(), EqualTo(2));
  1186. Expect(s3.first(), EqualTo(Symbol.intern("quote")));
  1187. Expect(s3.next().first(), EqualTo(Symbol.intern(((Namespace)RT.CURRENT_NS.deref()).Name.Name, "a")));
  1188. s1 = s1.next();
  1189. Expect(s1.first(), EqualTo(Symbol.intern("b")));
  1190. }
  1191. // We should test to see that 'line' meta info is not preserved.
  1192. [Test]
  1193. public void SQOnLparenRParenReturnsEmptyList()
  1194. {
  1195. object o1 = ReadFromString("`()");
  1196. // (clojure/list)
  1197. Expect(o1,InstanceOfType(typeof(ISeq)));
  1198. ISeq s = o1 as ISeq;
  1199. Expect(s.count(),EqualTo(1));
  1200. Expect(s.first(),EqualTo(Symbol.intern("clojure.core/list")));
  1201. }
  1202. #endregion
  1203. #region #-dispatch tests
  1204. [Test]
  1205. [ExpectedException(typeof(Exception))]
  1206. public void SharpDispatchOnInvalidCharFails()
  1207. {
  1208. object o1 = ReadFromString("#a(1 2)");
  1209. }
  1210. #endregion
  1211. #region Meta reader tests
  1212. [Test]
  1213. [ExpectedException(typeof(ArgumentException))]
  1214. public void MetaOnImproperMetadataFails()
  1215. {
  1216. object o1 = ReadFromString("#^1 (a b c");
  1217. }
  1218. [Test]
  1219. [ExpectedException(typeof(ArgumentException))]
  1220. public void MetaOnAppliedToNonIObjFails()
  1221. {
  1222. object o1 = ReadFromString("#^{:a 1} 7");
  1223. }
  1224. [Test]
  1225. public void MetaAppliesHashMetaDataToObject()
  1226. {
  1227. object o1 = ReadFromString("#^{a 1} (a b)");
  1228. Expect(o1, InstanceOfType(typeof(

Large files files are truncated, but you can click here to view the full file