PageRenderTime 66ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/test/System.Web.Razor.Test/Parser/PartialParsing/CSharpPartialParsingTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 400 lines | 355 code | 37 blank | 8 comment | 0 complexity | 3714c9005c9a91ae59dd8ffb5a3229af MD5 | raw file
  1. using System.Web.Razor.Parser;
  2. using System.Web.Razor.Parser.SyntaxTree;
  3. using System.Web.Razor.Test.Framework;
  4. using System.Web.Razor.Text;
  5. using System.Web.WebPages.TestUtils;
  6. using Xunit;
  7. namespace System.Web.Razor.Test.Parser.PartialParsing
  8. {
  9. public class CSharpPartialParsingTest : PartialParsingTestBase<CSharpRazorCodeLanguage>
  10. {
  11. [Fact]
  12. public void ImplicitExpressionProvisionallyAcceptsDeleteOfIdentifierPartsIfDotRemains()
  13. {
  14. var factory = SpanFactory.CreateCsHtml();
  15. StringTextBuffer changed = new StringTextBuffer("foo @User. baz");
  16. StringTextBuffer old = new StringTextBuffer("foo @User.Name baz");
  17. RunPartialParseTest(new TextChange(10, 4, old, 0, changed),
  18. new MarkupBlock(
  19. factory.Markup("foo "),
  20. new ExpressionBlock(
  21. factory.CodeTransition(),
  22. factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
  23. factory.Markup(" baz")),
  24. additionalFlags: PartialParseResult.Provisional);
  25. }
  26. [Fact]
  27. public void ImplicitExpressionAcceptsDeleteOfIdentifierPartsIfSomeOfIdentifierRemains()
  28. {
  29. var factory = SpanFactory.CreateCsHtml();
  30. StringTextBuffer changed = new StringTextBuffer("foo @Us baz");
  31. StringTextBuffer old = new StringTextBuffer("foo @User baz");
  32. RunPartialParseTest(new TextChange(7, 2, old, 0, changed),
  33. new MarkupBlock(
  34. factory.Markup("foo "),
  35. new ExpressionBlock(
  36. factory.CodeTransition(),
  37. factory.Code("Us").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
  38. factory.Markup(" baz")));
  39. }
  40. [Fact]
  41. public void ImplicitExpressionProvisionallyAcceptsMultipleInsertionIfItCausesIdentifierExpansionAndTrailingDot()
  42. {
  43. var factory = SpanFactory.CreateCsHtml();
  44. StringTextBuffer changed = new StringTextBuffer("foo @User. baz");
  45. StringTextBuffer old = new StringTextBuffer("foo @U baz");
  46. RunPartialParseTest(new TextChange(6, 0, old, 4, changed),
  47. new MarkupBlock(
  48. factory.Markup("foo "),
  49. new ExpressionBlock(
  50. factory.CodeTransition(),
  51. factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
  52. factory.Markup(" baz")),
  53. additionalFlags: PartialParseResult.Provisional);
  54. }
  55. [Fact]
  56. public void ImplicitExpressionAcceptsMultipleInsertionIfItOnlyCausesIdentifierExpansion()
  57. {
  58. var factory = SpanFactory.CreateCsHtml();
  59. StringTextBuffer changed = new StringTextBuffer("foo @barbiz baz");
  60. StringTextBuffer old = new StringTextBuffer("foo @bar baz");
  61. RunPartialParseTest(new TextChange(8, 0, old, 3, changed),
  62. new MarkupBlock(
  63. factory.Markup("foo "),
  64. new ExpressionBlock(
  65. factory.CodeTransition(),
  66. factory.Code("barbiz").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
  67. factory.Markup(" baz")));
  68. }
  69. [Fact]
  70. public void ImplicitExpressionAcceptsIdentifierExpansionAtEndOfNonWhitespaceCharacters()
  71. {
  72. var factory = SpanFactory.CreateCsHtml();
  73. StringTextBuffer changed = new StringTextBuffer(@"@{
  74. @food
  75. }");
  76. StringTextBuffer old = new StringTextBuffer(@"@{
  77. @foo
  78. }");
  79. RunPartialParseTest(new TextChange(12, 0, old, 1, changed),
  80. new MarkupBlock(
  81. factory.EmptyHtml(),
  82. new StatementBlock(
  83. factory.CodeTransition(),
  84. factory.MetaCode("{").Accepts(AcceptedCharacters.None),
  85. factory.Code("\r\n ").AsStatement(),
  86. new ExpressionBlock(
  87. factory.CodeTransition(),
  88. factory.Code("food")
  89. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  90. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  91. factory.Code("\r\n").AsStatement(),
  92. factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
  93. factory.EmptyHtml()));
  94. }
  95. [Fact]
  96. public void ImplicitExpressionAcceptsIdentifierAfterDotAtEndOfNonWhitespaceCharacters()
  97. {
  98. var factory = SpanFactory.CreateCsHtml();
  99. StringTextBuffer changed = new StringTextBuffer(@"@{
  100. @foo.d
  101. }");
  102. StringTextBuffer old = new StringTextBuffer(@"@{
  103. @foo.
  104. }");
  105. RunPartialParseTest(new TextChange(13, 0, old, 1, changed),
  106. new MarkupBlock(
  107. factory.EmptyHtml(),
  108. new StatementBlock(
  109. factory.CodeTransition(),
  110. factory.MetaCode("{").Accepts(AcceptedCharacters.None),
  111. factory.Code("\r\n ").AsStatement(),
  112. new ExpressionBlock(
  113. factory.CodeTransition(),
  114. factory.Code("foo.d")
  115. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  116. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  117. factory.Code("\r\n").AsStatement(),
  118. factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
  119. factory.EmptyHtml()));
  120. }
  121. [Fact]
  122. public void ImplicitExpressionAcceptsDotAtEndOfNonWhitespaceCharacters()
  123. {
  124. var factory = SpanFactory.CreateCsHtml();
  125. StringTextBuffer changed = new StringTextBuffer(@"@{
  126. @foo.
  127. }");
  128. StringTextBuffer old = new StringTextBuffer(@"@{
  129. @foo
  130. }");
  131. RunPartialParseTest(new TextChange(12, 0, old, 1, changed),
  132. new MarkupBlock(
  133. factory.EmptyHtml(),
  134. new StatementBlock(
  135. factory.CodeTransition(),
  136. factory.MetaCode("{").Accepts(AcceptedCharacters.None),
  137. factory.Code("\r\n ").AsStatement(),
  138. new ExpressionBlock(
  139. factory.CodeTransition(),
  140. factory.Code(@"foo.")
  141. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  142. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  143. factory.Code("\r\n").AsStatement(),
  144. factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
  145. factory.EmptyHtml()));
  146. }
  147. [Fact]
  148. public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
  149. {
  150. var factory = SpanFactory.CreateCsHtml();
  151. // Arrange
  152. TextChange dotTyped = new TextChange(8, 0, new StringTextBuffer("foo @foo @bar"), 1, new StringTextBuffer("foo @foo. @bar"));
  153. TextChange charTyped = new TextChange(14, 0, new StringTextBuffer("foo @foo. @bar"), 1, new StringTextBuffer("foo @foo. @barb"));
  154. TestParserManager manager = CreateParserManager();
  155. manager.InitializeWithDocument(dotTyped.OldBuffer);
  156. // Apply the dot change
  157. Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
  158. // Act (apply the identifier start char change)
  159. PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);
  160. // Assert
  161. Assert.Equal(PartialParseResult.Rejected, result);
  162. Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
  163. ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
  164. new MarkupBlock(
  165. factory.Markup("foo "),
  166. new ExpressionBlock(
  167. factory.CodeTransition(),
  168. factory.Code("foo")
  169. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  170. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  171. factory.Markup(". "),
  172. new ExpressionBlock(
  173. factory.CodeTransition(),
  174. factory.Code("barb")
  175. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  176. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  177. factory.EmptyHtml()));
  178. }
  179. [Fact]
  180. public void ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot()
  181. {
  182. var factory = SpanFactory.CreateCsHtml();
  183. // Arrange
  184. TextChange dotTyped = new TextChange(8, 0, new StringTextBuffer("foo @foo bar"), 1, new StringTextBuffer("foo @foo. bar"));
  185. TextChange charTyped = new TextChange(9, 0, new StringTextBuffer("foo @foo. bar"), 1, new StringTextBuffer("foo @foo.b bar"));
  186. TestParserManager manager = CreateParserManager();
  187. manager.InitializeWithDocument(dotTyped.OldBuffer);
  188. // Apply the dot change
  189. Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
  190. // Act (apply the identifier start char change)
  191. PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);
  192. // Assert
  193. Assert.Equal(PartialParseResult.Accepted, result);
  194. Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
  195. ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
  196. new MarkupBlock(
  197. factory.Markup("foo "),
  198. new ExpressionBlock(
  199. factory.CodeTransition(),
  200. factory.Code("foo.b")
  201. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  202. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  203. factory.Markup(" bar")));
  204. }
  205. [Fact]
  206. public void ImplicitExpressionProvisionallyAcceptsDotAfterIdentifierInMarkup()
  207. {
  208. var factory = SpanFactory.CreateCsHtml();
  209. StringTextBuffer changed = new StringTextBuffer("foo @foo. bar");
  210. StringTextBuffer old = new StringTextBuffer("foo @foo bar");
  211. RunPartialParseTest(new TextChange(8, 0, old, 1, changed),
  212. new MarkupBlock(
  213. factory.Markup("foo "),
  214. new ExpressionBlock(
  215. factory.CodeTransition(),
  216. factory.Code("foo.")
  217. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  218. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  219. factory.Markup(" bar")),
  220. additionalFlags: PartialParseResult.Provisional);
  221. }
  222. [Fact]
  223. public void ImplicitExpressionAcceptsAdditionalIdentifierCharactersIfEndOfSpanIsIdentifier()
  224. {
  225. var factory = SpanFactory.CreateCsHtml();
  226. StringTextBuffer changed = new StringTextBuffer("foo @foob bar");
  227. StringTextBuffer old = new StringTextBuffer("foo @foo bar");
  228. RunPartialParseTest(new TextChange(8, 0, old, 1, changed),
  229. new MarkupBlock(
  230. factory.Markup("foo "),
  231. new ExpressionBlock(
  232. factory.CodeTransition(),
  233. factory.Code("foob")
  234. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  235. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  236. factory.Markup(" bar")));
  237. }
  238. [Fact]
  239. public void ImplicitExpressionAcceptsAdditionalIdentifierStartCharactersIfEndOfSpanIsDot()
  240. {
  241. var factory = SpanFactory.CreateCsHtml();
  242. StringTextBuffer changed = new StringTextBuffer("@{@foo.b}");
  243. StringTextBuffer old = new StringTextBuffer("@{@foo.}");
  244. RunPartialParseTest(new TextChange(7, 0, old, 1, changed),
  245. new MarkupBlock(
  246. factory.EmptyHtml(),
  247. new StatementBlock(
  248. factory.CodeTransition(),
  249. factory.MetaCode("{").Accepts(AcceptedCharacters.None),
  250. factory.EmptyCSharp().AsStatement(),
  251. new ExpressionBlock(
  252. factory.CodeTransition(),
  253. factory.Code("foo.b")
  254. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  255. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  256. factory.EmptyCSharp().AsStatement(),
  257. factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
  258. factory.EmptyHtml()));
  259. }
  260. [Fact]
  261. public void ImplicitExpressionAcceptsDotIfTrailingDotsAreAllowed()
  262. {
  263. var factory = SpanFactory.CreateCsHtml();
  264. StringTextBuffer changed = new StringTextBuffer("@{@foo.}");
  265. StringTextBuffer old = new StringTextBuffer("@{@foo}");
  266. RunPartialParseTest(new TextChange(6, 0, old, 1, changed),
  267. new MarkupBlock(
  268. factory.EmptyHtml(),
  269. new StatementBlock(
  270. factory.CodeTransition(),
  271. factory.MetaCode("{").Accepts(AcceptedCharacters.None),
  272. factory.EmptyCSharp().AsStatement(),
  273. new ExpressionBlock(
  274. factory.CodeTransition(),
  275. factory.Code("foo.")
  276. .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  277. .Accepts(AcceptedCharacters.NonWhiteSpace)),
  278. factory.EmptyCSharp().AsStatement(),
  279. factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
  280. factory.EmptyHtml()));
  281. }
  282. [Fact]
  283. public void ImplicitExpressionCorrectlyTriggersReparseIfIfKeywordTyped()
  284. {
  285. RunTypeKeywordTest("if");
  286. }
  287. [Fact]
  288. public void ImplicitExpressionCorrectlyTriggersReparseIfDoKeywordTyped()
  289. {
  290. RunTypeKeywordTest("do");
  291. }
  292. [Fact]
  293. public void ImplicitExpressionCorrectlyTriggersReparseIfTryKeywordTyped()
  294. {
  295. RunTypeKeywordTest("try");
  296. }
  297. [Fact]
  298. public void ImplicitExpressionCorrectlyTriggersReparseIfForKeywordTyped()
  299. {
  300. RunTypeKeywordTest("for");
  301. }
  302. [Fact]
  303. public void ImplicitExpressionCorrectlyTriggersReparseIfForEachKeywordTyped()
  304. {
  305. RunTypeKeywordTest("foreach");
  306. }
  307. [Fact]
  308. public void ImplicitExpressionCorrectlyTriggersReparseIfWhileKeywordTyped()
  309. {
  310. RunTypeKeywordTest("while");
  311. }
  312. [Fact]
  313. public void ImplicitExpressionCorrectlyTriggersReparseIfSwitchKeywordTyped()
  314. {
  315. RunTypeKeywordTest("switch");
  316. }
  317. [Fact]
  318. public void ImplicitExpressionCorrectlyTriggersReparseIfLockKeywordTyped()
  319. {
  320. RunTypeKeywordTest("lock");
  321. }
  322. [Fact]
  323. public void ImplicitExpressionCorrectlyTriggersReparseIfUsingKeywordTyped()
  324. {
  325. RunTypeKeywordTest("using");
  326. }
  327. [Fact]
  328. public void ImplicitExpressionCorrectlyTriggersReparseIfSectionKeywordTyped()
  329. {
  330. RunTypeKeywordTest("section");
  331. }
  332. [Fact]
  333. public void ImplicitExpressionCorrectlyTriggersReparseIfInheritsKeywordTyped()
  334. {
  335. RunTypeKeywordTest("inherits");
  336. }
  337. [Fact]
  338. public void ImplicitExpressionCorrectlyTriggersReparseIfHelperKeywordTyped()
  339. {
  340. RunTypeKeywordTest("helper");
  341. }
  342. [Fact]
  343. public void ImplicitExpressionCorrectlyTriggersReparseIfFunctionsKeywordTyped()
  344. {
  345. RunTypeKeywordTest("functions");
  346. }
  347. [Fact]
  348. public void ImplicitExpressionCorrectlyTriggersReparseIfNamespaceKeywordTyped()
  349. {
  350. RunTypeKeywordTest("namespace");
  351. }
  352. [Fact]
  353. public void ImplicitExpressionCorrectlyTriggersReparseIfClassKeywordTyped()
  354. {
  355. RunTypeKeywordTest("class");
  356. }
  357. [Fact]
  358. public void ImplicitExpressionCorrectlyTriggersReparseIfLayoutKeywordTyped()
  359. {
  360. RunTypeKeywordTest("layout");
  361. }
  362. }
  363. }