vimsupport_test.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. #!/usr/bin/env python
  2. #
  3. # Copyright (C) 2015 YouCompleteMe contributors
  4. #
  5. # This file is part of YouCompleteMe.
  6. #
  7. # YouCompleteMe is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # YouCompleteMe is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
  19. from ycm import vimsupport
  20. from nose.tools import eq_
  21. def ReplaceChunk_SingleLine_Repl_1_test():
  22. # Replace with longer range
  23. # 12345678901234567
  24. result_buffer = [ "This is a string" ]
  25. start, end = _BuildLocations( 1, 1, 1, 5 )
  26. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  27. end,
  28. 'How long',
  29. 0,
  30. 0,
  31. result_buffer )
  32. eq_( [ "How long is a string" ], result_buffer )
  33. eq_( line_offset, 0 )
  34. eq_( char_offset, 4 )
  35. # and replace again, using delta
  36. start, end = _BuildLocations( 1, 10, 1, 11 )
  37. ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
  38. start,
  39. end,
  40. ' piece of ',
  41. line_offset,
  42. char_offset,
  43. result_buffer )
  44. line_offset += new_line_offset
  45. char_offset += new_char_offset
  46. eq_( [ 'How long is a piece of string' ], result_buffer )
  47. eq_( new_line_offset, 0 )
  48. eq_( new_char_offset, 9 )
  49. eq_( line_offset, 0 )
  50. eq_( char_offset, 13 )
  51. # and once more, for luck
  52. start, end = _BuildLocations( 1, 11, 1, 17 )
  53. ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
  54. start,
  55. end,
  56. 'pie',
  57. line_offset,
  58. char_offset,
  59. result_buffer )
  60. line_offset += new_line_offset
  61. char_offset += new_char_offset
  62. eq_( ['How long is a piece of pie' ], result_buffer )
  63. eq_( new_line_offset, 0 )
  64. eq_( new_char_offset, -3 )
  65. eq_( line_offset, 0 )
  66. eq_( char_offset, 10 )
  67. def ReplaceChunk_SingleLine_Repl_2_test():
  68. # Replace with shorter range
  69. # 12345678901234567
  70. result_buffer = [ "This is a string" ]
  71. start, end = _BuildLocations( 1, 11, 1, 17 )
  72. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  73. end,
  74. 'test',
  75. 0,
  76. 0,
  77. result_buffer )
  78. eq_( [ "This is a test" ], result_buffer )
  79. eq_( line_offset, 0 )
  80. eq_( char_offset, -2 )
  81. def ReplaceChunk_SingleLine_Repl_3_test():
  82. # Replace with equal range
  83. # 12345678901234567
  84. result_buffer = [ "This is a string" ]
  85. start, end = _BuildLocations( 1, 6, 1, 8 )
  86. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  87. end,
  88. 'be',
  89. 0,
  90. 0,
  91. result_buffer )
  92. eq_( [ "This be a string" ], result_buffer )
  93. eq_( line_offset, 0 )
  94. eq_( char_offset, 0 )
  95. def ReplaceChunk_SingleLine_Add_1_test():
  96. # Insert at start
  97. result_buffer = [ "is a string" ]
  98. start, end = _BuildLocations( 1, 1, 1, 1 )
  99. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  100. end,
  101. 'This ',
  102. 0,
  103. 0,
  104. result_buffer )
  105. eq_( [ "This is a string" ], result_buffer )
  106. eq_( line_offset, 0 )
  107. eq_( char_offset, 5 )
  108. def ReplaceChunk_SingleLine_Add_2_test():
  109. # Insert at end
  110. result_buffer = [ "This is a " ]
  111. start, end = _BuildLocations( 1, 11, 1, 11 )
  112. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  113. end,
  114. 'string',
  115. 0,
  116. 0,
  117. result_buffer )
  118. eq_( [ "This is a string" ], result_buffer )
  119. eq_( line_offset, 0 )
  120. eq_( char_offset, 6 )
  121. def ReplaceChunk_SingleLine_Add_3_test():
  122. # Insert in the middle
  123. result_buffer = [ "This is a string" ]
  124. start, end = _BuildLocations( 1, 8, 1, 8 )
  125. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  126. end,
  127. ' not',
  128. 0,
  129. 0,
  130. result_buffer )
  131. eq_( [ "This is not a string" ], result_buffer )
  132. eq_( line_offset, 0 )
  133. eq_( char_offset, 4 )
  134. def ReplaceChunk_SingleLine_Del_1_test():
  135. # Delete from start
  136. result_buffer = [ "This is a string" ]
  137. start, end = _BuildLocations( 1, 1, 1, 6 )
  138. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  139. end,
  140. '',
  141. 0,
  142. 0,
  143. result_buffer )
  144. eq_( [ "is a string" ], result_buffer )
  145. eq_( line_offset, 0 )
  146. eq_( char_offset, -5 )
  147. def ReplaceChunk_SingleLine_Del_2_test():
  148. # Delete from end
  149. result_buffer = [ "This is a string" ]
  150. start, end = _BuildLocations( 1, 10, 1, 18 )
  151. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  152. end,
  153. '',
  154. 0,
  155. 0,
  156. result_buffer )
  157. eq_( [ "This is a" ], result_buffer )
  158. eq_( line_offset, 0 )
  159. eq_( char_offset, -8 )
  160. def ReplaceChunk_SingleLine_Del_3_test():
  161. # Delete from middle
  162. result_buffer = [ "This is not a string" ]
  163. start, end = _BuildLocations( 1, 9, 1, 13 )
  164. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  165. end,
  166. '',
  167. 0,
  168. 0,
  169. result_buffer )
  170. eq_( [ "This is a string" ], result_buffer )
  171. eq_( line_offset, 0 )
  172. eq_( char_offset, -4 )
  173. def ReplaceChunk_RemoveSingleLine_test():
  174. result_buffer = [ "aAa", "aBa", "aCa" ]
  175. start, end = _BuildLocations( 2, 1, 3, 1 )
  176. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, '',
  177. 0, 0, result_buffer )
  178. expected_buffer = [ "aAa", "aCa" ]
  179. eq_( expected_buffer, result_buffer )
  180. eq_( line_offset, -1 )
  181. eq_( char_offset, 0 )
  182. def ReplaceChunk_SingleToMultipleLines_test():
  183. result_buffer = [ "aAa",
  184. "aBa",
  185. "aCa" ]
  186. start, end = _BuildLocations( 2, 2, 2, 2 )
  187. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
  188. 0, 0, result_buffer )
  189. expected_buffer = [ "aAa",
  190. "aEb",
  191. "bFBa",
  192. "aCa" ]
  193. eq_( expected_buffer, result_buffer )
  194. eq_( line_offset, 1 )
  195. eq_( char_offset, 1 )
  196. # now make another change to the "2nd" line
  197. start, end = _BuildLocations( 2, 3, 2, 4 )
  198. ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
  199. start,
  200. end,
  201. 'cccc',
  202. line_offset,
  203. char_offset,
  204. result_buffer )
  205. line_offset += new_line_offset
  206. char_offset += new_char_offset
  207. eq_( [ "aAa", "aEb", "bFBcccc", "aCa" ], result_buffer )
  208. eq_( line_offset, 1 )
  209. eq_( char_offset, 4 )
  210. def ReplaceChunk_SingleToMultipleLines2_test():
  211. result_buffer = [ "aAa", "aBa", "aCa" ]
  212. start, end = _BuildLocations( 2, 2, 2, 2 )
  213. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  214. end,
  215. 'Eb\nbFb\nG',
  216. 0,
  217. 0,
  218. result_buffer )
  219. expected_buffer = [ "aAa", "aEb", "bFb", "GBa", "aCa" ]
  220. eq_( expected_buffer, result_buffer )
  221. eq_( line_offset, 2 )
  222. eq_( char_offset, 0 )
  223. def ReplaceChunk_SingleToMultipleLines3_test():
  224. result_buffer = [ "aAa", "aBa", "aCa" ]
  225. start, end = _BuildLocations( 2, 2, 2, 2 )
  226. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  227. end,
  228. 'Eb\nbFb\nbGb',
  229. 0,
  230. 0,
  231. result_buffer )
  232. expected_buffer = [ "aAa", "aEb", "bFb", "bGbBa", "aCa" ]
  233. eq_( expected_buffer, result_buffer )
  234. eq_( line_offset, 2 )
  235. eq_( char_offset, 2 )
  236. def ReplaceChunk_SingleToMultipleLinesReplace_test():
  237. result_buffer = [ "aAa", "aBa", "aCa" ]
  238. start, end = _BuildLocations( 1, 2, 1, 4 )
  239. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  240. end,
  241. 'Eb\nbFb\nbGb',
  242. 0,
  243. 0,
  244. result_buffer )
  245. expected_buffer = [ "aEb", "bFb", "bGb", "aBa", "aCa" ]
  246. eq_( expected_buffer, result_buffer )
  247. eq_( line_offset, 2 )
  248. eq_( char_offset, 0 )
  249. def ReplaceChunk_SingleToMultipleLinesReplace_2_test():
  250. result_buffer = [ "aAa",
  251. "aBa",
  252. "aCa" ]
  253. start, end = _BuildLocations( 1, 2, 1, 4 )
  254. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  255. end,
  256. 'Eb\nbFb\nbGb',
  257. 0,
  258. 0,
  259. result_buffer )
  260. expected_buffer = [ "aEb",
  261. "bFb",
  262. "bGb",
  263. "aBa",
  264. "aCa" ]
  265. eq_( expected_buffer, result_buffer )
  266. eq_( line_offset, 2 )
  267. eq_( char_offset, 0 )
  268. # now do a subsequent change (insert at end of line "1")
  269. start, end = _BuildLocations( 1, 4, 1, 4 )
  270. ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
  271. start,
  272. end,
  273. 'cccc',
  274. line_offset,
  275. char_offset,
  276. result_buffer )
  277. line_offset += new_line_offset
  278. char_offset += new_char_offset
  279. eq_( [ "aEb",
  280. "bFb",
  281. "bGbcccc",
  282. "aBa",
  283. "aCa" ], result_buffer )
  284. eq_( line_offset, 2 )
  285. eq_( char_offset, 4 )
  286. def ReplaceChunk_MultipleLinesToSingleLine_test():
  287. result_buffer = [ "aAa", "aBa", "aCaaaa" ]
  288. start, end = _BuildLocations( 2, 2, 3, 2 )
  289. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'E',
  290. 0, 0, result_buffer )
  291. expected_buffer = [ "aAa", "aECaaaa" ]
  292. eq_( expected_buffer, result_buffer )
  293. eq_( line_offset, -1 )
  294. eq_( char_offset, 1 )
  295. # make another modification applying offsets
  296. start, end = _BuildLocations( 3, 3, 3, 4 )
  297. ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
  298. start,
  299. end,
  300. 'cccc',
  301. line_offset,
  302. char_offset,
  303. result_buffer )
  304. line_offset += new_line_offset
  305. char_offset += new_char_offset
  306. eq_( [ "aAa", "aECccccaaa" ], result_buffer )
  307. eq_( line_offset, -1 )
  308. eq_( char_offset, 4 )
  309. # and another, for luck
  310. start, end = _BuildLocations( 3, 4, 3, 5 )
  311. ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
  312. start,
  313. end,
  314. 'dd\ndd',
  315. line_offset,
  316. char_offset,
  317. result_buffer )
  318. line_offset += new_line_offset
  319. char_offset += new_char_offset
  320. eq_( [ "aAa", "aECccccdd", "ddaa" ], result_buffer )
  321. eq_( line_offset, 0 )
  322. eq_( char_offset, -2 )
  323. def ReplaceChunk_MultipleLinesToSameMultipleLines_test():
  324. result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
  325. start, end = _BuildLocations( 2, 2, 3, 2 )
  326. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
  327. 0, 0, result_buffer )
  328. expected_buffer = [ "aAa", "aEb", "bFCa", "aDe" ]
  329. eq_( expected_buffer, result_buffer )
  330. eq_( line_offset, 0 )
  331. eq_( char_offset, 1 )
  332. def ReplaceChunk_MultipleLinesToMoreMultipleLines_test():
  333. result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
  334. start, end = _BuildLocations( 2, 2, 3, 2 )
  335. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  336. end,
  337. 'Eb\nbFb\nbG',
  338. 0,
  339. 0,
  340. result_buffer )
  341. expected_buffer = [ "aAa", "aEb", "bFb", "bGCa", "aDe" ]
  342. eq_( expected_buffer, result_buffer )
  343. eq_( line_offset, 1 )
  344. eq_( char_offset, 1 )
  345. def ReplaceChunk_MultipleLinesToLessMultipleLines_test():
  346. result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
  347. start, end = _BuildLocations( 1, 2, 3, 2 )
  348. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
  349. 0, 0, result_buffer )
  350. expected_buffer = [ "aEb", "bFCa", "aDe" ]
  351. eq_( expected_buffer, result_buffer )
  352. eq_( line_offset, -1 )
  353. eq_( char_offset, 1 )
  354. def ReplaceChunk_MultipleLinesToEvenLessMultipleLines_test():
  355. result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
  356. start, end = _BuildLocations( 1, 2, 4, 2 )
  357. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
  358. 0, 0, result_buffer )
  359. expected_buffer = [ "aEb", "bFDe" ]
  360. eq_( expected_buffer, result_buffer )
  361. eq_( line_offset, -2 )
  362. eq_( char_offset, 1 )
  363. def ReplaceChunk_SpanBufferEdge_test():
  364. result_buffer = [ "aAa", "aBa", "aCa" ]
  365. start, end = _BuildLocations( 1, 1, 1, 3 )
  366. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
  367. 0, 0, result_buffer )
  368. expected_buffer = [ "bDba", "aBa", "aCa" ]
  369. eq_( expected_buffer, result_buffer )
  370. eq_( line_offset, 0 )
  371. eq_( char_offset, 1 )
  372. def ReplaceChunk_DeleteTextInLine_test():
  373. result_buffer = [ "aAa", "aBa", "aCa" ]
  374. start, end = _BuildLocations( 2, 2, 2, 3 )
  375. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, '',
  376. 0, 0, result_buffer )
  377. expected_buffer = [ "aAa", "aa", "aCa" ]
  378. eq_( expected_buffer, result_buffer )
  379. eq_( line_offset, 0 )
  380. eq_( char_offset, -1 )
  381. def ReplaceChunk_AddTextInLine_test():
  382. result_buffer = [ "aAa", "aBa", "aCa" ]
  383. start, end = _BuildLocations( 2, 2, 2, 2 )
  384. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
  385. 0, 0, result_buffer )
  386. expected_buffer = [ "aAa", "abDbBa", "aCa" ]
  387. eq_( expected_buffer, result_buffer )
  388. eq_( line_offset, 0 )
  389. eq_( char_offset, 3 )
  390. def ReplaceChunk_ReplaceTextInLine_test():
  391. result_buffer = [ "aAa", "aBa", "aCa" ]
  392. start, end = _BuildLocations( 2, 2, 2, 3 )
  393. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
  394. 0, 0, result_buffer )
  395. expected_buffer = [ "aAa", "abDba", "aCa" ]
  396. eq_( expected_buffer, result_buffer )
  397. eq_( line_offset, 0 )
  398. eq_( char_offset, 2 )
  399. def ReplaceChunk_SingleLineOffsetWorks_test():
  400. result_buffer = [ "aAa", "aBa", "aCa" ]
  401. start, end = _BuildLocations( 1, 1, 1, 2 )
  402. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
  403. 1, 1, result_buffer )
  404. expected_buffer = [ "aAa", "abDba", "aCa" ]
  405. eq_( expected_buffer, result_buffer )
  406. eq_( line_offset, 0 )
  407. eq_( char_offset, 2 )
  408. def ReplaceChunk_SingleLineToMultipleLinesOffsetWorks_test():
  409. result_buffer = [ "aAa", "aBa", "aCa" ]
  410. start, end = _BuildLocations( 1, 1, 1, 2 )
  411. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Db\nE',
  412. 1, 1, result_buffer )
  413. expected_buffer = [ "aAa", "aDb", "Ea", "aCa" ]
  414. eq_( expected_buffer, result_buffer )
  415. eq_( line_offset, 1 )
  416. eq_( char_offset, -1 )
  417. def ReplaceChunk_MultipleLinesToSingleLineOffsetWorks_test():
  418. result_buffer = [ "aAa", "aBa", "aCa" ]
  419. start, end = _BuildLocations( 1, 1, 2, 2 )
  420. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
  421. 1, 1, result_buffer )
  422. expected_buffer = [ "aAa", "abDbCa" ]
  423. eq_( expected_buffer, result_buffer )
  424. eq_( line_offset, -1 )
  425. eq_( char_offset, 3 )
  426. def ReplaceChunk_MultipleLineOffsetWorks_test():
  427. result_buffer = [ "aAa", "aBa", "aCa" ]
  428. start, end = _BuildLocations( 3, 1, 4, 3 )
  429. ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
  430. end,
  431. 'bDb\nbEb\nbFb',
  432. -1,
  433. 1,
  434. result_buffer )
  435. expected_buffer = [ "aAa", "abDb", "bEb", "bFba" ]
  436. eq_( expected_buffer, result_buffer )
  437. eq_( line_offset, 1 )
  438. eq_( char_offset, 1 )
  439. def _BuildLocations( start_line, start_column, end_line, end_column ):
  440. return {
  441. 'line_num' : start_line,
  442. 'column_num': start_column,
  443. }, {
  444. 'line_num' : end_line,
  445. 'column_num': end_column,
  446. }
  447. def ReplaceChunksList_SortedChunks_test():
  448. chunks = [
  449. _BuildChunk( 1, 4, 1, 4, '('),
  450. _BuildChunk( 1, 11, 1, 11, ')' )
  451. ]
  452. result_buffer = [ "CT<10 >> 2> ct" ]
  453. vimsupport.ReplaceChunksList( chunks, result_buffer )
  454. expected_buffer = [ "CT<(10 >> 2)> ct" ]
  455. eq_( expected_buffer, result_buffer )
  456. def ReplaceChunksList_UnsortedChunks_test():
  457. chunks = [
  458. _BuildChunk( 1, 11, 1, 11, ')'),
  459. _BuildChunk( 1, 4, 1, 4, '(' )
  460. ]
  461. result_buffer = [ "CT<10 >> 2> ct" ]
  462. vimsupport.ReplaceChunksList( chunks, result_buffer )
  463. expected_buffer = [ "CT<(10 >> 2)> ct" ]
  464. eq_( expected_buffer, result_buffer )
  465. def _BuildChunk( start_line, start_column, end_line, end_column,
  466. replacement_text ):
  467. return {
  468. 'range': {
  469. 'start': {
  470. 'line_num': start_line,
  471. 'column_num': start_column,
  472. },
  473. 'end': {
  474. 'line_num': end_line,
  475. 'column_num': end_column,
  476. },
  477. },
  478. 'replacement_text': replacement_text
  479. }