diff_refiner_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package uast
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path"
  6. "testing"
  7. "time"
  8. "unicode/utf8"
  9. "github.com/sergi/go-diff/diffmatchpatch"
  10. "github.com/stretchr/testify/assert"
  11. "gopkg.in/bblfsh/sdk.v2/uast/nodes"
  12. "gopkg.in/bblfsh/sdk.v2/uast/nodes/nodesproto"
  13. "gopkg.in/src-d/go-git.v4/plumbing/object"
  14. "gopkg.in/src-d/hercules.v10/internal/core"
  15. "gopkg.in/src-d/hercules.v10/internal/plumbing"
  16. "gopkg.in/src-d/hercules.v10/internal/test"
  17. )
  18. func fixtureFileDiffRefiner() *FileDiffRefiner {
  19. fd := &FileDiffRefiner{}
  20. fd.Initialize(test.Repository)
  21. return fd
  22. }
  23. func TestFileDiffRefinerMeta(t *testing.T) {
  24. fd := fixtureFileDiffRefiner()
  25. assert.Equal(t, fd.Name(), "FileDiffRefiner")
  26. assert.Equal(t, len(fd.Provides()), 1)
  27. assert.Equal(t, fd.Provides()[0], plumbing.DependencyFileDiff)
  28. assert.Equal(t, len(fd.Requires()), 2)
  29. assert.Equal(t, fd.Requires()[0], plumbing.DependencyFileDiff)
  30. assert.Equal(t, fd.Requires()[1], DependencyUastChanges)
  31. assert.Len(t, fd.ListConfigurationOptions(), 0)
  32. fd.Configure(nil)
  33. features := fd.Features()
  34. assert.Len(t, features, 1)
  35. assert.Equal(t, features[0], FeatureUast)
  36. }
  37. func TestFileDiffRefinerRegistration(t *testing.T) {
  38. summoned := core.Registry.Summon((&FileDiffRefiner{}).Name())
  39. assert.Len(t, summoned, 1)
  40. assert.Equal(t, summoned[0].Name(), "FileDiffRefiner")
  41. summoned = core.Registry.Summon((&FileDiffRefiner{}).Provides()[0])
  42. assert.True(t, len(summoned) >= 1)
  43. matched := false
  44. for _, tp := range summoned {
  45. matched = matched || tp.Name() == "FileDiffRefiner"
  46. }
  47. assert.True(t, matched)
  48. }
  49. func loadUast(t *testing.T, name string) nodes.Node {
  50. filename := path.Join("..", "..", "test_data", name)
  51. reader, err := os.Open(filename)
  52. if err != nil {
  53. assert.Failf(t, "cannot load %s: %v", filename, err)
  54. }
  55. node, err := nodesproto.ReadTree(reader)
  56. if err != nil {
  57. assert.Failf(t, "cannot load %s: %v", filename, err)
  58. }
  59. return node
  60. }
  61. func TestFileDiffRefinerConsume(t *testing.T) {
  62. bytes1, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "1.java"))
  63. assert.Nil(t, err)
  64. bytes2, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "2.java"))
  65. assert.Nil(t, err)
  66. dmp := diffmatchpatch.New()
  67. dmp.DiffTimeout = time.Hour
  68. src, dst, _ := dmp.DiffLinesToRunes(string(bytes1), string(bytes2))
  69. state := map[string]interface{}{}
  70. fileDiffs := map[string]plumbing.FileDiffData{}
  71. const fileName = "test.java"
  72. fileDiffs[fileName] = plumbing.FileDiffData{
  73. OldLinesOfCode: len(src),
  74. NewLinesOfCode: len(dst),
  75. Diffs: dmp.DiffMainRunes(src, dst, false),
  76. }
  77. state[plumbing.DependencyFileDiff] = fileDiffs
  78. uastChanges := make([]Change, 1)
  79. state[DependencyUastChanges] = uastChanges
  80. uastChanges[0] = Change{
  81. Change: &object.Change{
  82. From: object.ChangeEntry{Name: fileName},
  83. To: object.ChangeEntry{Name: fileName}},
  84. Before: loadUast(t, "uast1.pb"), After: loadUast(t, "uast2.pb"),
  85. }
  86. fd := fixtureFileDiffRefiner()
  87. iresult, err := fd.Consume(state)
  88. assert.Nil(t, err)
  89. result := iresult[plumbing.DependencyFileDiff].(map[string]plumbing.FileDiffData)
  90. assert.Len(t, result, 1)
  91. oldDiff := fileDiffs[fileName]
  92. newDiff := result[fileName]
  93. assert.Equal(t, oldDiff.OldLinesOfCode, newDiff.OldLinesOfCode)
  94. assert.Equal(t, oldDiff.NewLinesOfCode, newDiff.NewLinesOfCode)
  95. assert.Equal(t, len(oldDiff.Diffs)+1, len(newDiff.Diffs))
  96. assert.Equal(t, dmp.DiffText2(oldDiff.Diffs), dmp.DiffText2(newDiff.Diffs))
  97. // Some hardcoded length checks
  98. assert.Equal(t, utf8.RuneCountInString(newDiff.Diffs[6].Text), 11)
  99. assert.Equal(t, utf8.RuneCountInString(newDiff.Diffs[7].Text), 41)
  100. assert.Equal(t, utf8.RuneCountInString(newDiff.Diffs[8].Text), 231)
  101. }
  102. func TestFileDiffRefinerConsumeNoUast(t *testing.T) {
  103. bytes1, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "1.java"))
  104. assert.Nil(t, err)
  105. bytes2, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "2.java"))
  106. assert.Nil(t, err)
  107. dmp := diffmatchpatch.New()
  108. dmp.DiffTimeout = time.Hour
  109. src, dst, _ := dmp.DiffLinesToRunes(string(bytes1), string(bytes2))
  110. state := map[string]interface{}{}
  111. fileDiffs := map[string]plumbing.FileDiffData{}
  112. const fileName = "test.java"
  113. fileDiffs[fileName] = plumbing.FileDiffData{
  114. OldLinesOfCode: len(src),
  115. NewLinesOfCode: len(dst),
  116. Diffs: dmp.DiffMainRunes(src, dst, false),
  117. }
  118. state[plumbing.DependencyFileDiff] = fileDiffs
  119. uastChanges := make([]Change, 1)
  120. state[DependencyUastChanges] = uastChanges
  121. uastChanges[0] = Change{
  122. Change: &object.Change{
  123. From: object.ChangeEntry{Name: fileName},
  124. To: object.ChangeEntry{Name: fileName}},
  125. Before: loadUast(t, "uast1.pb"), After: nil,
  126. }
  127. fd := fixtureFileDiffRefiner()
  128. iresult, err := fd.Consume(state)
  129. assert.Nil(t, err)
  130. result := iresult[plumbing.DependencyFileDiff].(map[string]plumbing.FileDiffData)
  131. assert.Len(t, result, 1)
  132. assert.Equal(t, fileDiffs[fileName], result[fileName])
  133. fileDiffs[fileName] = plumbing.FileDiffData{
  134. OldLinesOfCode: 100,
  135. NewLinesOfCode: 100,
  136. Diffs: []diffmatchpatch.Diff{{}},
  137. }
  138. uastChanges[0] = Change{
  139. Change: &object.Change{
  140. From: object.ChangeEntry{Name: fileName},
  141. To: object.ChangeEntry{Name: fileName}},
  142. Before: loadUast(t, "uast1.pb"), After: loadUast(t, "uast2.pb"),
  143. }
  144. iresult, err = fd.Consume(state)
  145. assert.Nil(t, err)
  146. result = iresult[plumbing.DependencyFileDiff].(map[string]plumbing.FileDiffData)
  147. assert.Len(t, result, 1)
  148. assert.Equal(t, fileDiffs[fileName], result[fileName])
  149. }
  150. func TestFileDiffRefinerFork(t *testing.T) {
  151. fd1 := fixtureFileDiffRefiner()
  152. clones := fd1.Fork(1)
  153. assert.Len(t, clones, 1)
  154. fd2 := clones[0].(*FileDiffRefiner)
  155. assert.True(t, fd1 == fd2)
  156. fd1.Merge([]core.PipelineItem{fd2})
  157. }