You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gitdiff_test.go 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. package gitdiff
  5. import (
  6. "fmt"
  7. "strconv"
  8. "strings"
  9. "testing"
  10. "code.gitea.io/gitea/models/db"
  11. issues_model "code.gitea.io/gitea/models/issues"
  12. "code.gitea.io/gitea/models/unittest"
  13. user_model "code.gitea.io/gitea/models/user"
  14. "code.gitea.io/gitea/modules/git"
  15. "code.gitea.io/gitea/modules/json"
  16. "code.gitea.io/gitea/modules/setting"
  17. dmp "github.com/sergi/go-diff/diffmatchpatch"
  18. "github.com/stretchr/testify/assert"
  19. )
  20. func TestDiffToHTML(t *testing.T) {
  21. assert.Equal(t, "foo <span class=\"added-code\">bar</span> biz", diffToHTML(nil, []dmp.Diff{
  22. {Type: dmp.DiffEqual, Text: "foo "},
  23. {Type: dmp.DiffInsert, Text: "bar"},
  24. {Type: dmp.DiffDelete, Text: " baz"},
  25. {Type: dmp.DiffEqual, Text: " biz"},
  26. }, DiffLineAdd))
  27. assert.Equal(t, "foo <span class=\"removed-code\">bar</span> biz", diffToHTML(nil, []dmp.Diff{
  28. {Type: dmp.DiffEqual, Text: "foo "},
  29. {Type: dmp.DiffDelete, Text: "bar"},
  30. {Type: dmp.DiffInsert, Text: " baz"},
  31. {Type: dmp.DiffEqual, Text: " biz"},
  32. }, DiffLineDel))
  33. }
  34. func TestParsePatch_skipTo(t *testing.T) {
  35. type testcase struct {
  36. name string
  37. gitdiff string
  38. wantErr bool
  39. addition int
  40. deletion int
  41. oldFilename string
  42. filename string
  43. skipTo string
  44. }
  45. tests := []testcase{
  46. {
  47. name: "readme.md2readme.md",
  48. gitdiff: `diff --git "a/A \\ B" "b/A \\ B"
  49. --- "a/A \\ B"
  50. +++ "b/A \\ B"
  51. @@ -1,3 +1,6 @@
  52. # gitea-github-migrator
  53. +
  54. + Build Status
  55. - Latest Release
  56. Docker Pulls
  57. + cut off
  58. + cut off
  59. diff --git "\\a/README.md" "\\b/README.md"
  60. --- "\\a/README.md"
  61. +++ "\\b/README.md"
  62. @@ -1,3 +1,6 @@
  63. # gitea-github-migrator
  64. +
  65. + Build Status
  66. - Latest Release
  67. Docker Pulls
  68. + cut off
  69. + cut off
  70. `,
  71. addition: 4,
  72. deletion: 1,
  73. filename: "README.md",
  74. oldFilename: "README.md",
  75. skipTo: "README.md",
  76. },
  77. {
  78. name: "A \\ B",
  79. gitdiff: `diff --git "a/A \\ B" "b/A \\ B"
  80. --- "a/A \\ B"
  81. +++ "b/A \\ B"
  82. @@ -1,3 +1,6 @@
  83. # gitea-github-migrator
  84. +
  85. + Build Status
  86. - Latest Release
  87. Docker Pulls
  88. + cut off
  89. + cut off`,
  90. addition: 4,
  91. deletion: 1,
  92. filename: "A \\ B",
  93. oldFilename: "A \\ B",
  94. skipTo: "A \\ B",
  95. },
  96. {
  97. name: "A \\ B",
  98. gitdiff: `diff --git "\\a/README.md" "\\b/README.md"
  99. --- "\\a/README.md"
  100. +++ "\\b/README.md"
  101. @@ -1,3 +1,6 @@
  102. # gitea-github-migrator
  103. +
  104. + Build Status
  105. - Latest Release
  106. Docker Pulls
  107. + cut off
  108. + cut off
  109. diff --git "a/A \\ B" "b/A \\ B"
  110. --- "a/A \\ B"
  111. +++ "b/A \\ B"
  112. @@ -1,3 +1,6 @@
  113. # gitea-github-migrator
  114. +
  115. + Build Status
  116. - Latest Release
  117. Docker Pulls
  118. + cut off
  119. + cut off`,
  120. addition: 4,
  121. deletion: 1,
  122. filename: "A \\ B",
  123. oldFilename: "A \\ B",
  124. skipTo: "A \\ B",
  125. },
  126. {
  127. name: "readme.md2readme.md",
  128. gitdiff: `diff --git "a/A \\ B" "b/A \\ B"
  129. --- "a/A \\ B"
  130. +++ "b/A \\ B"
  131. @@ -1,3 +1,6 @@
  132. # gitea-github-migrator
  133. +
  134. + Build Status
  135. - Latest Release
  136. Docker Pulls
  137. + cut off
  138. + cut off
  139. diff --git "a/A \\ B" "b/A \\ B"
  140. --- "a/A \\ B"
  141. +++ "b/A \\ B"
  142. @@ -1,3 +1,6 @@
  143. # gitea-github-migrator
  144. +
  145. + Build Status
  146. - Latest Release
  147. Docker Pulls
  148. + cut off
  149. + cut off
  150. diff --git "\\a/README.md" "\\b/README.md"
  151. --- "\\a/README.md"
  152. +++ "\\b/README.md"
  153. @@ -1,3 +1,6 @@
  154. # gitea-github-migrator
  155. +
  156. + Build Status
  157. - Latest Release
  158. Docker Pulls
  159. + cut off
  160. + cut off
  161. `,
  162. addition: 4,
  163. deletion: 1,
  164. filename: "README.md",
  165. oldFilename: "README.md",
  166. skipTo: "README.md",
  167. },
  168. }
  169. for _, testcase := range tests {
  170. t.Run(testcase.name, func(t *testing.T) {
  171. got, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), testcase.skipTo)
  172. if (err != nil) != testcase.wantErr {
  173. t.Errorf("ParsePatch(%q) error = %v, wantErr %v", testcase.name, err, testcase.wantErr)
  174. return
  175. }
  176. gotMarshaled, _ := json.MarshalIndent(got, "", " ")
  177. if got.NumFiles != 1 {
  178. t.Errorf("ParsePath(%q) did not receive 1 file:\n%s", testcase.name, string(gotMarshaled))
  179. return
  180. }
  181. if got.TotalAddition != testcase.addition {
  182. t.Errorf("ParsePath(%q) does not have correct totalAddition %d, wanted %d", testcase.name, got.TotalAddition, testcase.addition)
  183. }
  184. if got.TotalDeletion != testcase.deletion {
  185. t.Errorf("ParsePath(%q) did not have correct totalDeletion %d, wanted %d", testcase.name, got.TotalDeletion, testcase.deletion)
  186. }
  187. file := got.Files[0]
  188. if file.Addition != testcase.addition {
  189. t.Errorf("ParsePath(%q) does not have correct file addition %d, wanted %d", testcase.name, file.Addition, testcase.addition)
  190. }
  191. if file.Deletion != testcase.deletion {
  192. t.Errorf("ParsePath(%q) did not have correct file deletion %d, wanted %d", testcase.name, file.Deletion, testcase.deletion)
  193. }
  194. if file.OldName != testcase.oldFilename {
  195. t.Errorf("ParsePath(%q) did not have correct OldName %q, wanted %q", testcase.name, file.OldName, testcase.oldFilename)
  196. }
  197. if file.Name != testcase.filename {
  198. t.Errorf("ParsePath(%q) did not have correct Name %q, wanted %q", testcase.name, file.Name, testcase.filename)
  199. }
  200. })
  201. }
  202. }
  203. func TestParsePatch_singlefile(t *testing.T) {
  204. type testcase struct {
  205. name string
  206. gitdiff string
  207. wantErr bool
  208. addition int
  209. deletion int
  210. oldFilename string
  211. filename string
  212. }
  213. tests := []testcase{
  214. {
  215. name: "readme.md2readme.md",
  216. gitdiff: `diff --git "\\a/README.md" "\\b/README.md"
  217. --- "\\a/README.md"
  218. +++ "\\b/README.md"
  219. @@ -1,3 +1,6 @@
  220. # gitea-github-migrator
  221. +
  222. + Build Status
  223. - Latest Release
  224. Docker Pulls
  225. + cut off
  226. + cut off
  227. `,
  228. addition: 4,
  229. deletion: 1,
  230. filename: "README.md",
  231. oldFilename: "README.md",
  232. },
  233. {
  234. name: "A \\ B",
  235. gitdiff: `diff --git "a/A \\ B" "b/A \\ B"
  236. --- "a/A \\ B"
  237. +++ "b/A \\ B"
  238. @@ -1,3 +1,6 @@
  239. # gitea-github-migrator
  240. +
  241. + Build Status
  242. - Latest Release
  243. Docker Pulls
  244. + cut off
  245. + cut off`,
  246. addition: 4,
  247. deletion: 1,
  248. filename: "A \\ B",
  249. oldFilename: "A \\ B",
  250. },
  251. {
  252. name: "really weird filename",
  253. gitdiff: `diff --git "\\a/a b/file b/a a/file" "\\b/a b/file b/a a/file"
  254. index d2186f1..f5c8ed2 100644
  255. --- "\\a/a b/file b/a a/file" ` + `
  256. +++ "\\b/a b/file b/a a/file" ` + `
  257. @@ -1,3 +1,2 @@
  258. Create a weird file.
  259. ` + `
  260. -and what does diff do here?
  261. \ No newline at end of file`,
  262. addition: 0,
  263. deletion: 1,
  264. filename: "a b/file b/a a/file",
  265. oldFilename: "a b/file b/a a/file",
  266. },
  267. {
  268. name: "delete file with blanks",
  269. gitdiff: `diff --git "\\a/file with blanks" "\\b/file with blanks"
  270. deleted file mode 100644
  271. index 898651a..0000000
  272. --- "\\a/file with blanks" ` + `
  273. +++ /dev/null
  274. @@ -1,5 +0,0 @@
  275. -a blank file
  276. -
  277. -has a couple o line
  278. -
  279. -the 5th line is the last
  280. `,
  281. addition: 0,
  282. deletion: 5,
  283. filename: "file with blanks",
  284. oldFilename: "file with blanks",
  285. },
  286. {
  287. name: "rename a—as",
  288. gitdiff: `diff --git "a/\360\243\220\265b\342\200\240vs" "b/a\342\200\224as"
  289. similarity index 100%
  290. rename from "\360\243\220\265b\342\200\240vs"
  291. rename to "a\342\200\224as"
  292. `,
  293. addition: 0,
  294. deletion: 0,
  295. oldFilename: "𣐵b†vs",
  296. filename: "a—as",
  297. },
  298. {
  299. name: "rename with spaces",
  300. gitdiff: `diff --git "\\a/a b/file b/a a/file" "\\b/a b/a a/file b/b file"
  301. similarity index 100%
  302. rename from a b/file b/a a/file
  303. rename to a b/a a/file b/b file
  304. `,
  305. oldFilename: "a b/file b/a a/file",
  306. filename: "a b/a a/file b/b file",
  307. },
  308. {
  309. name: "ambiguous deleted",
  310. gitdiff: `diff --git a/b b/b b/b b/b
  311. deleted file mode 100644
  312. index 92e798b..0000000
  313. --- a/b b/b` + "\t" + `
  314. +++ /dev/null
  315. @@ -1 +0,0 @@
  316. -b b/b
  317. `,
  318. oldFilename: "b b/b",
  319. filename: "b b/b",
  320. addition: 0,
  321. deletion: 1,
  322. },
  323. {
  324. name: "ambiguous addition",
  325. gitdiff: `diff --git a/b b/b b/b b/b
  326. new file mode 100644
  327. index 0000000..92e798b
  328. --- /dev/null
  329. +++ b/b b/b` + "\t" + `
  330. @@ -0,0 +1 @@
  331. +b b/b
  332. `,
  333. oldFilename: "b b/b",
  334. filename: "b b/b",
  335. addition: 1,
  336. deletion: 0,
  337. },
  338. {
  339. name: "rename",
  340. gitdiff: `diff --git a/b b/b b/b b/b b/b b/b
  341. similarity index 100%
  342. rename from b b/b b/b b/b b/b
  343. rename to b
  344. `,
  345. oldFilename: "b b/b b/b b/b b/b",
  346. filename: "b",
  347. },
  348. {
  349. name: "ambiguous 1",
  350. gitdiff: `diff --git a/b b/b b/b b/b b/b b/b
  351. similarity index 100%
  352. rename from b b/b b/b b/b b/b
  353. rename to b
  354. `,
  355. oldFilename: "b b/b b/b b/b b/b",
  356. filename: "b",
  357. },
  358. {
  359. name: "ambiguous 2",
  360. gitdiff: `diff --git a/b b/b b/b b/b b/b b/b
  361. similarity index 100%
  362. rename from b b/b b/b b/b
  363. rename to b b/b
  364. `,
  365. oldFilename: "b b/b b/b b/b",
  366. filename: "b b/b",
  367. },
  368. {
  369. name: "minuses-and-pluses",
  370. gitdiff: `diff --git a/minuses-and-pluses b/minuses-and-pluses
  371. index 6961180..9ba1a00 100644
  372. --- a/minuses-and-pluses
  373. +++ b/minuses-and-pluses
  374. @@ -1,4 +1,4 @@
  375. --- 1st line
  376. -++ 2nd line
  377. --- 3rd line
  378. -++ 4th line
  379. +++ 1st line
  380. +-- 2nd line
  381. +++ 3rd line
  382. +-- 4th line
  383. `,
  384. oldFilename: "minuses-and-pluses",
  385. filename: "minuses-and-pluses",
  386. addition: 4,
  387. deletion: 4,
  388. },
  389. }
  390. for _, testcase := range tests {
  391. t.Run(testcase.name, func(t *testing.T) {
  392. got, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "")
  393. if (err != nil) != testcase.wantErr {
  394. t.Errorf("ParsePatch(%q) error = %v, wantErr %v", testcase.name, err, testcase.wantErr)
  395. return
  396. }
  397. gotMarshaled, _ := json.MarshalIndent(got, "", " ")
  398. if got.NumFiles != 1 {
  399. t.Errorf("ParsePath(%q) did not receive 1 file:\n%s", testcase.name, string(gotMarshaled))
  400. return
  401. }
  402. if got.TotalAddition != testcase.addition {
  403. t.Errorf("ParsePath(%q) does not have correct totalAddition %d, wanted %d", testcase.name, got.TotalAddition, testcase.addition)
  404. }
  405. if got.TotalDeletion != testcase.deletion {
  406. t.Errorf("ParsePath(%q) did not have correct totalDeletion %d, wanted %d", testcase.name, got.TotalDeletion, testcase.deletion)
  407. }
  408. file := got.Files[0]
  409. if file.Addition != testcase.addition {
  410. t.Errorf("ParsePath(%q) does not have correct file addition %d, wanted %d", testcase.name, file.Addition, testcase.addition)
  411. }
  412. if file.Deletion != testcase.deletion {
  413. t.Errorf("ParsePath(%q) did not have correct file deletion %d, wanted %d", testcase.name, file.Deletion, testcase.deletion)
  414. }
  415. if file.OldName != testcase.oldFilename {
  416. t.Errorf("ParsePath(%q) did not have correct OldName %q, wanted %q", testcase.name, file.OldName, testcase.oldFilename)
  417. }
  418. if file.Name != testcase.filename {
  419. t.Errorf("ParsePath(%q) did not have correct Name %q, wanted %q", testcase.name, file.Name, testcase.filename)
  420. }
  421. })
  422. }
  423. // Test max lines
  424. diffBuilder := &strings.Builder{}
  425. diff := `diff --git a/newfile2 b/newfile2
  426. new file mode 100644
  427. index 0000000..6bb8f39
  428. --- /dev/null
  429. +++ b/newfile2
  430. @@ -0,0 +1,35 @@
  431. `
  432. diffBuilder.WriteString(diff)
  433. for i := 0; i < 35; i++ {
  434. diffBuilder.WriteString("+line" + strconv.Itoa(i) + "\n")
  435. }
  436. diff = diffBuilder.String()
  437. result, err := ParsePatch(20, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "")
  438. if err != nil {
  439. t.Errorf("There should not be an error: %v", err)
  440. }
  441. if !result.Files[0].IsIncomplete {
  442. t.Errorf("Files should be incomplete! %v", result.Files[0])
  443. }
  444. result, err = ParsePatch(40, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "")
  445. if err != nil {
  446. t.Errorf("There should not be an error: %v", err)
  447. }
  448. if result.Files[0].IsIncomplete {
  449. t.Errorf("Files should not be incomplete! %v", result.Files[0])
  450. }
  451. result, err = ParsePatch(40, 5, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "")
  452. if err != nil {
  453. t.Errorf("There should not be an error: %v", err)
  454. }
  455. if !result.Files[0].IsIncomplete {
  456. t.Errorf("Files should be incomplete! %v", result.Files[0])
  457. }
  458. // Test max characters
  459. diff = `diff --git a/newfile2 b/newfile2
  460. new file mode 100644
  461. index 0000000..6bb8f39
  462. --- /dev/null
  463. +++ b/newfile2
  464. @@ -0,0 +1,35 @@
  465. `
  466. diffBuilder.Reset()
  467. diffBuilder.WriteString(diff)
  468. for i := 0; i < 33; i++ {
  469. diffBuilder.WriteString("+line" + strconv.Itoa(i) + "\n")
  470. }
  471. diffBuilder.WriteString("+line33")
  472. for i := 0; i < 512; i++ {
  473. diffBuilder.WriteString("0123456789ABCDEF")
  474. }
  475. diffBuilder.WriteByte('\n')
  476. diffBuilder.WriteString("+line" + strconv.Itoa(34) + "\n")
  477. diffBuilder.WriteString("+line" + strconv.Itoa(35) + "\n")
  478. diff = diffBuilder.String()
  479. result, err = ParsePatch(20, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "")
  480. if err != nil {
  481. t.Errorf("There should not be an error: %v", err)
  482. }
  483. if !result.Files[0].IsIncomplete {
  484. t.Errorf("Files should be incomplete! %v", result.Files[0])
  485. }
  486. result, err = ParsePatch(40, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "")
  487. if err != nil {
  488. t.Errorf("There should not be an error: %v", err)
  489. }
  490. if !result.Files[0].IsIncomplete {
  491. t.Errorf("Files should be incomplete! %v", result.Files[0])
  492. }
  493. diff = `diff --git "a/README.md" "b/README.md"
  494. --- a/README.md
  495. +++ b/README.md
  496. @@ -1,3 +1,6 @@
  497. # gitea-github-migrator
  498. +
  499. + Build Status
  500. - Latest Release
  501. Docker Pulls
  502. + cut off
  503. + cut off`
  504. _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "")
  505. if err != nil {
  506. t.Errorf("ParsePatch failed: %s", err)
  507. }
  508. diff2 := `diff --git "a/A \\ B" "b/A \\ B"
  509. --- "a/A \\ B"
  510. +++ "b/A \\ B"
  511. @@ -1,3 +1,6 @@
  512. # gitea-github-migrator
  513. +
  514. + Build Status
  515. - Latest Release
  516. Docker Pulls
  517. + cut off
  518. + cut off`
  519. _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2), "")
  520. if err != nil {
  521. t.Errorf("ParsePatch failed: %s", err)
  522. }
  523. diff2a := `diff --git "a/A \\ B" b/A/B
  524. --- "a/A \\ B"
  525. +++ b/A/B
  526. @@ -1,3 +1,6 @@
  527. # gitea-github-migrator
  528. +
  529. + Build Status
  530. - Latest Release
  531. Docker Pulls
  532. + cut off
  533. + cut off`
  534. _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a), "")
  535. if err != nil {
  536. t.Errorf("ParsePatch failed: %s", err)
  537. }
  538. diff3 := `diff --git a/README.md b/README.md
  539. --- a/README.md
  540. +++ b/README.md
  541. @@ -1,3 +1,6 @@
  542. # gitea-github-migrator
  543. +
  544. + Build Status
  545. - Latest Release
  546. Docker Pulls
  547. + cut off
  548. + cut off`
  549. _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3), "")
  550. if err != nil {
  551. t.Errorf("ParsePatch failed: %s", err)
  552. }
  553. }
  554. func setupDefaultDiff() *Diff {
  555. return &Diff{
  556. Files: []*DiffFile{
  557. {
  558. Name: "README.md",
  559. Sections: []*DiffSection{
  560. {
  561. Lines: []*DiffLine{
  562. {
  563. LeftIdx: 4,
  564. RightIdx: 4,
  565. },
  566. },
  567. },
  568. },
  569. },
  570. },
  571. }
  572. }
  573. func TestDiff_LoadCommentsNoOutdated(t *testing.T) {
  574. assert.NoError(t, unittest.PrepareTestDatabase())
  575. issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
  576. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  577. diff := setupDefaultDiff()
  578. assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, false))
  579. assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 2)
  580. }
  581. func TestDiff_LoadCommentsWithOutdated(t *testing.T) {
  582. assert.NoError(t, unittest.PrepareTestDatabase())
  583. issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
  584. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  585. diff := setupDefaultDiff()
  586. assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, true))
  587. assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 3)
  588. }
  589. func TestDiffLine_CanComment(t *testing.T) {
  590. assert.False(t, (&DiffLine{Type: DiffLineSection}).CanComment())
  591. assert.False(t, (&DiffLine{Type: DiffLineAdd, Comments: []*issues_model.Comment{{Content: "bla"}}}).CanComment())
  592. assert.True(t, (&DiffLine{Type: DiffLineAdd}).CanComment())
  593. assert.True(t, (&DiffLine{Type: DiffLineDel}).CanComment())
  594. assert.True(t, (&DiffLine{Type: DiffLinePlain}).CanComment())
  595. }
  596. func TestDiffLine_GetCommentSide(t *testing.T) {
  597. assert.Equal(t, "previous", (&DiffLine{Comments: []*issues_model.Comment{{Line: -3}}}).GetCommentSide())
  598. assert.Equal(t, "proposed", (&DiffLine{Comments: []*issues_model.Comment{{Line: 3}}}).GetCommentSide())
  599. }
  600. func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
  601. gitRepo, err := git.OpenRepository(git.DefaultContext, "./testdata/academic-module")
  602. if !assert.NoError(t, err) {
  603. return
  604. }
  605. defer gitRepo.Close()
  606. for _, behavior := range []git.TrustedCmdArgs{{"-w"}, {"--ignore-space-at-eol"}, {"-b"}, nil} {
  607. diffs, err := GetDiff(gitRepo,
  608. &DiffOptions{
  609. AfterCommitID: "bd7063cc7c04689c4d082183d32a604ed27a24f9",
  610. BeforeCommitID: "559c156f8e0178b71cb44355428f24001b08fc68",
  611. MaxLines: setting.Git.MaxGitDiffLines,
  612. MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
  613. MaxFiles: setting.Git.MaxGitDiffFiles,
  614. WhitespaceBehavior: behavior,
  615. })
  616. assert.NoError(t, err, fmt.Sprintf("Error when diff with %s", behavior))
  617. for _, f := range diffs.Files {
  618. assert.True(t, len(f.Sections) > 0, fmt.Sprintf("%s should have sections", f.Name))
  619. }
  620. }
  621. }
  622. func TestNoCrashes(t *testing.T) {
  623. type testcase struct {
  624. gitdiff string
  625. }
  626. tests := []testcase{
  627. {
  628. gitdiff: "diff --git \n--- a\t\n",
  629. },
  630. {
  631. gitdiff: "diff --git \"0\n",
  632. },
  633. }
  634. for _, testcase := range tests {
  635. // It shouldn't crash, so don't care about the output.
  636. ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "")
  637. }
  638. }