code-review-test.html 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <div>Tests for some of the easily unittestable parts of code-review.js. You should see a series of "PASS" lines.</div>
  2. <div>FIXME: Run these as part of the layout test suite?</div>
  3. <script>
  4. CODE_REVIEW_UNITTEST = true;
  5. window.onerror = function(errorMsg, url, lineNumber) {
  6. log('FAIL: Received an error at line ' + lineNumber);
  7. return false;
  8. }
  9. </script>
  10. <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
  11. <script src="code-review.js"></script>
  12. <pre id="output"></pre>
  13. <div id="diff-content"></div>
  14. <script>
  15. function inherits(childConstructor, parentConstructor) {
  16. function tempConstructor() {};
  17. tempConstructor.prototype = parentConstructor.prototype;
  18. childConstructor.prototype = new tempConstructor();
  19. childConstructor.prototype.constructor = childConstructor;
  20. }
  21. function log(msg) {
  22. document.getElementById('output').textContent += msg + '\n\n';
  23. }
  24. function ASSERT(msg, assertion) {
  25. if (assertion)
  26. log('PASS');
  27. else
  28. log('FAIL: ' + msg);
  29. }
  30. function ASSERT_EQUAL(actual, expected) {
  31. if (actual == expected)
  32. log('PASS');
  33. else
  34. log('FAIL:\ngot:\n' + actual + '\nexpected:\n' + expected + '');
  35. }
  36. function testTracLinks() {
  37. var links = tracLinks('foo/bar/baz.cpp', '');
  38. ASSERT_EQUAL($('<div>').append(links).html(),
  39. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/bar/baz.h">header</a>' +
  40. '<a target="_blank" href="http://trac.webkit.org/browser/trunk/foo/bar/baz.cpp?annotate=blame">annotate</a>' +
  41. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/bar/baz.cpp">revision log</a>');
  42. var links = tracLinks('foo/bar.cpp/qux.mm', '');
  43. ASSERT_EQUAL($('<div>').append(links).html(),
  44. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/bar.cpp/qux.h">header</a>' +
  45. '<a target="_blank" href="http://trac.webkit.org/browser/trunk/foo/bar.cpp/qux.mm?annotate=blame">annotate</a>' +
  46. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/bar.cpp/qux.mm">revision log</a>');
  47. var links = tracLinks('foo/bar.h', '');
  48. ASSERT_EQUAL($('<div>').append(links).html(),
  49. '<a target="_blank" href="http://trac.webkit.org/browser/trunk/foo/bar.h?annotate=blame">annotate</a>' +
  50. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/bar.h">revision log</a>');
  51. var links = tracLinks('foo/bar.gypi', '');
  52. ASSERT_EQUAL($('<div>').append(links).html(),
  53. '<a target="_blank" href="http://trac.webkit.org/browser/trunk/foo/bar.gypi?annotate=blame">annotate</a>' +
  54. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/bar.gypi">revision log</a>');
  55. var links = tracLinks('foo/ChangeLog', '');
  56. ASSERT_EQUAL($('<div>').append(links).html(),
  57. '<a target="_blank" href="http://trac.webkit.org/browser/trunk/foo/ChangeLog?annotate=blame">annotate</a>' +
  58. '<a target="_blank" href="http://trac.webkit.org/log/trunk/foo/ChangeLog">revision log</a>');
  59. }
  60. function testDraftCommentSaver() {
  61. function MockLocalStorage() {
  62. this.localStorageStore = {};
  63. this.log = [];
  64. this.getItem = function(key) {
  65. this.log.push('getItem:' + key);
  66. return this.localStorageStore[key];
  67. };
  68. this.setItem = function(key, value) {
  69. // For testing sake, consider having more than 2 items to exceed the storage quota.
  70. if (Object.keys(this.localStorageStore).length > 2) {
  71. this.log.push('QuotaExceeded on setItem:' + key + ',' + value);
  72. throw "QuotaExceeded";
  73. }
  74. this.log.push('setItem:' + key + ',' + value);
  75. this.localStorageStore[key] = value;
  76. };
  77. this.removeItem = function(key) {
  78. this.log.push('removeItem:' + key);
  79. delete this.localStorageStore[key];
  80. };
  81. this.log_string = function() {
  82. return this.log.join('\n');
  83. };
  84. this.key = function(i) {
  85. return Object.keys(this.localStorageStore)[i];
  86. };
  87. this.__defineGetter__('length', function() {
  88. return Object.keys(this.localStorageStore).length;
  89. });
  90. }
  91. function MockDraftCommentSaver(attachment_id, opt_localStorage) {
  92. DraftCommentSaver.call(this, attachment_id, opt_localStorage);
  93. }
  94. inherits(MockDraftCommentSaver, DraftCommentSaver)
  95. MockDraftCommentSaver.prototype._json = function() {
  96. return "{MOCK JSON}";
  97. }
  98. MockDraftCommentSaver.prototype._should_remove_comments = function(message) {
  99. return false;
  100. }
  101. // Basic setItem.
  102. var ls = new MockLocalStorage();
  103. new MockDraftCommentSaver('1234', ls).save();
  104. ASSERT_EQUAL(ls.log_string(), 'setItem:draft-comments-for-attachment-1234,{MOCK JSON}');
  105. // Exceed quota, but succeed after erasing old reviews.
  106. var ls = new MockLocalStorage();
  107. ls.localStorageStore = {
  108. 'draft-comments-for-attachment-1': '{"born-on": 100, "comments":[]}',
  109. 'draft-comments-for-attachment-2': '{"born-on": 100, "comments":[]}',
  110. 'draft-comments-for-attachment-3': '{"born-on": 100, "comments":[]}',
  111. 'draft-comments-for-attachment-4': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}'
  112. };
  113. new MockDraftCommentSaver('1234', ls).save();
  114. ASSERT_EQUAL(ls.log_string(), 'QuotaExceeded on setItem:draft-comments-for-attachment-1234,{MOCK JSON}\ngetItem:draft-comments-for-attachment-1\ngetItem:draft-comments-for-attachment-2\ngetItem:draft-comments-for-attachment-3\ngetItem:draft-comments-for-attachment-4\nremoveItem:draft-comments-for-attachment-1\nremoveItem:draft-comments-for-attachment-2\nremoveItem:draft-comments-for-attachment-3\nsetItem:draft-comments-for-attachment-1234,{MOCK JSON}');
  115. // Exceed quota after erasing old reviews and fail after prompt.
  116. var ls = new MockLocalStorage();
  117. ls.localStorageStore = {
  118. 'draft-comments-for-attachment-1': '{"born-on": 100, "comments":[]}',
  119. 'draft-comments-for-attachment-2': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}',
  120. 'draft-comments-for-attachment-3': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}',
  121. 'draft-comments-for-attachment-4': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}'
  122. };
  123. var mockDraftSaver = new MockDraftCommentSaver('1234', ls);
  124. mockDraftSaver.save();
  125. // Second save to ensure that we stop trying to save when we fail the prompt.
  126. mockDraftSaver.save();
  127. ASSERT_EQUAL(ls.log_string(), 'QuotaExceeded on setItem:draft-comments-for-attachment-1234,{MOCK JSON}\ngetItem:draft-comments-for-attachment-1\ngetItem:draft-comments-for-attachment-2\ngetItem:draft-comments-for-attachment-3\ngetItem:draft-comments-for-attachment-4\nremoveItem:draft-comments-for-attachment-1\nQuotaExceeded on setItem:draft-comments-for-attachment-1234,{MOCK JSON}');
  128. // Exceed quota after erasing old reviews, but succeed after prompt.
  129. var ls = new MockLocalStorage();
  130. ls.localStorageStore = {
  131. 'draft-comments-for-attachment-1': '{"born-on": 100, "comments":[]}',
  132. 'draft-comments-for-attachment-2': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}',
  133. 'draft-comments-for-attachment-3': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}',
  134. 'draft-comments-for-attachment-4': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}'
  135. };
  136. var mockDraftSaver = new MockDraftCommentSaver('1234', ls);
  137. mockDraftSaver._should_remove_comments = function() { return true; };
  138. mockDraftSaver.save();
  139. ASSERT_EQUAL(ls.log_string(), 'QuotaExceeded on setItem:draft-comments-for-attachment-1234,{MOCK JSON}\ngetItem:draft-comments-for-attachment-1\ngetItem:draft-comments-for-attachment-2\ngetItem:draft-comments-for-attachment-3\ngetItem:draft-comments-for-attachment-4\nremoveItem:draft-comments-for-attachment-1\nQuotaExceeded on setItem:draft-comments-for-attachment-1234,{MOCK JSON}\nremoveItem:draft-comments-for-attachment-2\nremoveItem:draft-comments-for-attachment-3\nremoveItem:draft-comments-for-attachment-4\nsetItem:draft-comments-for-attachment-1234,{MOCK JSON}');
  140. // Always exceeds quota, even after erasing all review comments. There should be no setItem calls.
  141. var ls = new MockLocalStorage();
  142. ls.setItem = function() {
  143. this.log.push('QuotaExceeded on setItem:' + key + ',' + value);
  144. throw "QuotaExceeded";
  145. }
  146. ls.localStorageStore = {
  147. 'draft-comments-for-attachment-1': '{"born-on": 100, "comments":[]}',
  148. 'draft-comments-for-attachment-2': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}',
  149. 'draft-comments-for-attachment-3': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}',
  150. 'draft-comments-for-attachment-4': '{"born-on": ' + (Date.now() - 100) + ', "comments":[]}'
  151. };
  152. var mockDraftSaver = new MockDraftCommentSaver('1234', ls);
  153. mockDraftSaver._should_remove_comments = function() { return true; };
  154. mockDraftSaver.save();
  155. // Second save to ensure that we stop trying to save when we fail the prompt.
  156. mockDraftSaver.save();
  157. ASSERT_EQUAL(ls.log_string(), 'getItem:draft-comments-for-attachment-1\ngetItem:draft-comments-for-attachment-2\ngetItem:draft-comments-for-attachment-3\ngetItem:draft-comments-for-attachment-4\nremoveItem:draft-comments-for-attachment-1\nremoveItem:draft-comments-for-attachment-2\nremoveItem:draft-comments-for-attachment-3\nremoveItem:draft-comments-for-attachment-4');
  158. var ls = new MockLocalStorage();
  159. ls.localStorageStore = {
  160. 'draft-comments-for-attachment-1': '{"born-on": 100, "comments":[]}',
  161. 'draft-comments-for-attachment-2': '{"born-on": 100, "comments":[{"start_line_id": 1, "end_line_id": 2, "contents": "DUMMY CONTENTS"}, {"start_line_id": 3, "end_line_id": 4, "contents": "DUMMY CONTENTS 2"}]}'
  162. };
  163. var comments = new MockDraftCommentSaver('2', ls).saved_comments().comments;
  164. ASSERT_EQUAL(comments.length, 2);
  165. ASSERT_EQUAL(ls.log_string(), 'getItem:draft-comments-for-attachment-2');
  166. var ls = new MockLocalStorage();
  167. ls.localStorageStore = {
  168. 'draft-comments-for-attachment-1': 'corrupt comments'
  169. };
  170. var comments = new MockDraftCommentSaver('1', ls).saved_comments().comments;
  171. ASSERT_EQUAL(ls.log_string(), 'getItem:draft-comments-for-attachment-1\nremoveItem:draft-comments-for-attachment-1');
  172. var ls = new MockLocalStorage();
  173. ls.localStorageStore = {
  174. 'draft-comments-for-attachment-1': '["also corrupt comments"]'
  175. };
  176. var comments = new MockDraftCommentSaver('1', ls).saved_comments().comments;
  177. ASSERT_EQUAL(ls.log_string(), 'getItem:draft-comments-for-attachment-1\nremoveItem:draft-comments-for-attachment-1');
  178. }
  179. function stripBornOn(json) {
  180. return json.replace(/\"born\-on\"\:\d+,/, "");
  181. }
  182. function strippedSavedComments() {
  183. return stripBornOn(localStorage[g_draftCommentSaver.localStorageKey()]);
  184. }
  185. function syncSlideUp(type, handler) {
  186. handler.call(this);
  187. }
  188. function testReaddDiscardedCommentWithPreviousComment() {
  189. document.getElementById('diff-content').innerHTML =
  190. '<div class="FileDiff">' +
  191. '<h1><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/ChangeLog">Source/WebCore/ChangeLog</a></h1>' +
  192. '<div class="DiffSection">' +
  193. '<div class="DiffBlock">' +
  194. '<div class="DiffBlockPart add">' +
  195. '<div class="Line LineContainer add">' +
  196. '<span class="from lineNumber">&nbsp;</span><span class="to lineNumber">1</span><span class="text">first diff block first line</span>' +
  197. '</div>' +
  198. '<div class="Line LineContainer add">' +
  199. '<span class="from lineNumber">&nbsp;</span><span class="to lineNumber">2</span><span class="text"></span>' +
  200. '</div>' +
  201. '</div>' +
  202. '<div class="clear_float"></div>' +
  203. '</div>' +
  204. '<div class="DiffBlock">' +
  205. '<div class="DiffBlockPart shared">' +
  206. '<div class="Line LineContainer">' +
  207. '<span class="from lineNumber">1</span><span class="to lineNumber">12</span><span class="text">second diff block first line</span>' +
  208. '</div>' +
  209. '</div><div class="clear_float">' +
  210. '</div>' +
  211. '</div>' +
  212. '</div>' +
  213. '</div>';
  214. eraseDraftComments();
  215. crawlDiff();
  216. appendToolbar();
  217. var line = document.getElementById('line0');
  218. var author = "ojan@chromium.org";
  219. var comment_text = "This change sux.";
  220. addPreviousComment(line, author, comment_text);
  221. var previous_comment = document.querySelector('.previousComment');
  222. ASSERT("Line with only a previous comment should not have 'data-has-comment' attribute.", !line.getAttribute('data-has-comment'));
  223. var new_comment = addCommentField(previous_comment);
  224. new_comment.find('textarea').val("dummy content");
  225. var frozen_comment = acceptComment(new_comment);
  226. ASSERT_EQUAL(document.querySelectorAll('.comment').length, 1);
  227. ASSERT_EQUAL(strippedSavedComments(), '{"comments":[{"start_line_id":"line0","end_line_id":"line0","contents":"dummy content"}],"overall-comments":""}');
  228. unfreezeComment(frozen_comment);
  229. // This is a hack to make slideUp synchronous so that we can keep this test from needing to be async.
  230. jQuery.fn.slideUp = syncSlideUp;
  231. discardComment(new_comment);
  232. ASSERT('There should be no draft comments.', !document.querySelector('.comment'));
  233. ASSERT_EQUAL(strippedSavedComments(), '{"comments":[],"overall-comments":""}');
  234. ASSERT("Line with only a previous comment should not have 'data-has-comment' attribute.", !line.getAttribute('data-has-comment'));
  235. new_comment = addCommentField(previous_comment);
  236. new_comment.find('textarea').val("dummy content");
  237. acceptComment(new_comment);
  238. ASSERT_EQUAL(document.querySelectorAll('.comment').length, 1);
  239. ASSERT_EQUAL(strippedSavedComments(), '{"comments":[{"start_line_id":"line0","end_line_id":"line0","contents":"dummy content"}],"overall-comments":""}');
  240. document.getElementById('diff-content').innerHTML = '';
  241. }
  242. function testSideBySideDiffWithPreviousCommentsOnSharedLine() {
  243. document.getElementById('diff-content').innerHTML =
  244. '<div class="FileDiff">' +
  245. '<h1><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/ChangeLog">Source/WebCore/ChangeLog</a></h1>' +
  246. '<div class="DiffSection">' +
  247. '<div class="DiffBlock">' +
  248. '<div class="DiffBlockPart shared">' +
  249. '<div class="Line LineContainer">' +
  250. '<span class="from lineNumber">336</span><span class="to lineNumber">338</span><span class="text"> layoutFlexItems(*m_orderIterator, lineContexts);</span>' +
  251. '</div>' +
  252. '<div class="Line LineContainer">' +
  253. '<span class="from lineNumber">337</span><span class="to lineNumber">339</span><span class="text"></span>' +
  254. '</div>' +
  255. '<div class="Line LineContainer">' +
  256. '<span class="from lineNumber">338</span><span class="to lineNumber">340</span><span class="text"> LayoutUnit oldClientAfterEdge = clientLogicalBottom();</span>' +
  257. '</div>' +
  258. '</div><div class="clear_float">' +
  259. '</div>' +
  260. '</div>' +
  261. '</div>';
  262. eraseDraftComments();
  263. crawlDiff();
  264. convertAllFileDiffs('sidebyside', $('.FileDiff'));
  265. displayPreviousComments([{
  266. author: 'ojan@chromium.org',
  267. file_name: 'Source/WebCore/ChangeLog',
  268. line_number: 338,
  269. comment_text: 'This change sux.'
  270. }]);
  271. var previous_comment = document.querySelector('.previousComment');
  272. ASSERT_EQUAL(previous_comment.getAttribute('data-comment-for'), 'line0');
  273. var new_comment = addCommentField(previous_comment);
  274. ASSERT("New comment should exist and contain a textarea.", new_comment.find('textarea'));
  275. document.getElementById('diff-content').innerHTML = '';
  276. }
  277. function testSanitizeFragmentForCopy() {
  278. var fragment = document.createElement('div');
  279. fragment.innerHTML = '<div class="FileDiff">' +
  280. '<h1><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/ChangeLog">Source/WebCore/ChangeLog</a></h1>' +
  281. '<div class="FileDiffLinkContainer LinkContainer" style="opacity: 0;"><a href="javascript:" class="unify-link cremed" style="display: inline;">unified</a></div>' +
  282. '<div class="DiffSection">' +
  283. '<div class="DiffBlock">' +
  284. '<div class="DiffBlockPart shared">' +
  285. '<div class="Line LineContainer">' +
  286. '<span class="from lineNumber">336</span><span class="to lineNumber">338</span><span class="text"> layoutFlexItems(*m_orderIterator, lineContexts);</span>' +
  287. '</div>' +
  288. '<div class="Line LineContainer">' +
  289. '<span class="from lineNumber">337</span><span class="to lineNumber">339</span><span class="text"></span>' +
  290. '</div>' +
  291. '<div class="Line LineContainer">' +
  292. '<span class="from lineNumber">338</span><span class="to lineNumber">340</span><span class="text"> LayoutUnit oldClientAfterEdge = clientLogicalBottom();</span>' +
  293. '</div>' +
  294. '</div><div class="clear_float"></div>' +
  295. '</div>' +
  296. '</div>' +
  297. '</div>';
  298. var expectedWithLineNumbers = '<div class="FileDiff">' +
  299. '<h1><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/ChangeLog">Source/WebCore/ChangeLog</a></h1>' +
  300. '<div class="DiffSection">' +
  301. '<div class="DiffBlock">' +
  302. '<div class="DiffBlockPart shared">' +
  303. '<div class="Line LineContainer">' +
  304. '<span class="from lineNumber">336</span><span class="to lineNumber">338</span><span class="text"> layoutFlexItems(*m_orderIterator, lineContexts);</span>' +
  305. '</div>' +
  306. '<div class="Line LineContainer">' +
  307. '<span class="from lineNumber">337</span><span class="to lineNumber">339</span><span class="text"><br></span>' +
  308. '</div>' +
  309. '<div class="Line LineContainer">' +
  310. '<span class="from lineNumber">338</span><span class="to lineNumber">340</span><span class="text"> LayoutUnit oldClientAfterEdge = clientLogicalBottom();</span>' +
  311. '</div>' +
  312. '</div><div class="clear_float"></div>' +
  313. '</div>' +
  314. '</div>' +
  315. '</div>';
  316. var fragmentCopy = fragment.cloneNode(true);
  317. sanitizeFragmentForCopy(fragmentCopy, false);
  318. ASSERT_EQUAL(fragmentCopy.innerHTML, expectedWithLineNumbers);
  319. var expectedWithOutLineNumbers = '<div class="FileDiff">' +
  320. '<h1><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/ChangeLog">Source/WebCore/ChangeLog</a></h1>' +
  321. '<div class="DiffSection">' +
  322. '<div class="DiffBlock">' +
  323. '<div class="DiffBlockPart shared">' +
  324. '<div class="Line LineContainer">' +
  325. '<span class="text"> layoutFlexItems(*m_orderIterator, lineContexts);</span>' +
  326. '</div>' +
  327. '<div class="Line LineContainer">' +
  328. '<span class="text"><br></span>' +
  329. '</div>' +
  330. '<div class="Line LineContainer">' +
  331. '<span class="text"> LayoutUnit oldClientAfterEdge = clientLogicalBottom();</span>' +
  332. '</div>' +
  333. '</div><div class="clear_float"></div>' +
  334. '</div>' +
  335. '</div>' +
  336. '</div>';
  337. var fragmentCopy = fragment.cloneNode(true);
  338. sanitizeFragmentForCopy(fragmentCopy, true);
  339. ASSERT_EQUAL(fragmentCopy.innerHTML, expectedWithOutLineNumbers);
  340. }
  341. function testIsChangeLog() {
  342. ASSERT("Top-level ChangeLog file is a ChangeLog file", isChangeLog("ChangeLog"));
  343. ASSERT("Second-level ChangeLog file is a ChangeLog file", isChangeLog("Tools/ChangeLog"));
  344. ASSERT("prepare-ChangeLog is not a ChangeLog file", !isChangeLog("Tools/Scripts/prepare-ChangeLog"));
  345. ASSERT("ChangeLog-script is not a ChangeLog file", !isChangeLog("Tools/Scripts/ChangeLog-script"));
  346. }
  347. function testSaveCommentsWithMissingLineIds() {
  348. document.getElementById('diff-content').innerHTML =
  349. '<div class="FileDiff">' +
  350. '<h1><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/ChangeLog">Source/WebCore/dummy.txt</a></h1>' +
  351. '<div class="DiffSection">' +
  352. '<div class="DiffBlock">' +
  353. '<div class="DiffBlockPart shared">' +
  354. '<div class="Line LineContainer">' +
  355. '<span class="from lineNumber">6</span><span class="to lineNumber">8</span><span class="text">a</span>' +
  356. '</div>' +
  357. '<div class="Line LineContainer">' +
  358. '<span class="from lineNumber">7</span><span class="to lineNumber">9</span><span class="text">b</span>' +
  359. '</div>' +
  360. '<div class="Line LineContainer">' +
  361. '<span class="from lineNumber">8</span><span class="to lineNumber">10</span><span class="text">c</span>' +
  362. '</div>' +
  363. '</div><div class="clear_float">' +
  364. '</div>' +
  365. '</div>' +
  366. '<div class="DiffSection">' +
  367. '<div class="Line LineContainer context">' +
  368. '<span class="from lineNumber">@</span><span class="to lineNumber">@</span><span class="text">static void willRemoveChildren(ContainerNode* container)</span>' +
  369. '</div>' +
  370. '<div class="DiffBlock">' +
  371. '<div class="DiffBlockPart shared">' +
  372. '<div class="Line LineContainer">' +
  373. '<span class="from lineNumber">15</span><span class="to lineNumber">17</span><span class="text">d</span>' +
  374. '</div>' +
  375. '</div><div class="clear_float"></div></div>' +
  376. '</div>' +
  377. '</div>';
  378. var file_name = "Source/WebCore/dummy.txt";
  379. var file_contents = [];
  380. for (var i = 0; i < 20; i++)
  381. file_contents[i] = i;
  382. setFileContents(file_name, file_contents, file_contents);
  383. eraseDraftComments();
  384. crawlDiff();
  385. var new_comment = addCommentFor($('#line4'));
  386. new_comment.find('textarea').val("dummy content");
  387. acceptComment(new_comment);
  388. $('.ExpandLink')[0].click();
  389. // Strip the link to the context since that points to window.location.
  390. ASSERT_EQUAL(serializedComments().replace(/View in context.*code-review-test.html/, ''),
  391. '\n\n' +
  392. '> Source/WebCore/dummy.txt:17\n\n\n' +
  393. 'dummy content');
  394. document.getElementById('diff-content').innerHTML = '';
  395. }
  396. for (var property in window) {
  397. if (property.indexOf('test') == 0) {
  398. window[property]();
  399. }
  400. }
  401. </script>