diff_refiner_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. logger := core.NewLogger()
  37. assert.NoError(t, fd.Configure(map[string]interface{}{
  38. core.ConfigLogger: logger,
  39. }))
  40. assert.Equal(t, logger, fd.l)
  41. }
  42. func TestFileDiffRefinerRegistration(t *testing.T) {
  43. summoned := core.Registry.Summon((&FileDiffRefiner{}).Name())
  44. assert.Len(t, summoned, 1)
  45. assert.Equal(t, summoned[0].Name(), "FileDiffRefiner")
  46. summoned = core.Registry.Summon((&FileDiffRefiner{}).Provides()[0])
  47. assert.True(t, len(summoned) >= 1)
  48. matched := false
  49. for _, tp := range summoned {
  50. matched = matched || tp.Name() == "FileDiffRefiner"
  51. }
  52. assert.True(t, matched)
  53. }
  54. func loadUast(t *testing.T, name string) nodes.Node {
  55. filename := path.Join("..", "..", "test_data", name)
  56. reader, err := os.Open(filename)
  57. if err != nil {
  58. assert.Failf(t, "cannot load %s: %v", filename, err)
  59. }
  60. node, err := nodesproto.ReadTree(reader)
  61. if err != nil {
  62. assert.Failf(t, "cannot load %s: %v", filename, err)
  63. }
  64. return node
  65. }
  66. func TestFileDiffRefinerConsume(t *testing.T) {
  67. bytes1, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "1.java"))
  68. assert.Nil(t, err)
  69. bytes2, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "2.java"))
  70. assert.Nil(t, err)
  71. dmp := diffmatchpatch.New()
  72. dmp.DiffTimeout = time.Hour
  73. src, dst, _ := dmp.DiffLinesToRunes(string(bytes1), string(bytes2))
  74. state := map[string]interface{}{}
  75. fileDiffs := map[string]plumbing.FileDiffData{}
  76. const fileName = "test.java"
  77. fileDiffs[fileName] = plumbing.FileDiffData{
  78. OldLinesOfCode: len(src),
  79. NewLinesOfCode: len(dst),
  80. Diffs: dmp.DiffMainRunes(src, dst, false),
  81. }
  82. state[plumbing.DependencyFileDiff] = fileDiffs
  83. uastChanges := make([]Change, 1)
  84. state[DependencyUastChanges] = uastChanges
  85. uastChanges[0] = Change{
  86. Change: &object.Change{
  87. From: object.ChangeEntry{Name: fileName},
  88. To: object.ChangeEntry{Name: fileName}},
  89. Before: loadUast(t, "uast1.pb"), After: loadUast(t, "uast2.pb"),
  90. }
  91. fd := fixtureFileDiffRefiner()
  92. iresult, err := fd.Consume(state)
  93. assert.Nil(t, err)
  94. result := iresult[plumbing.DependencyFileDiff].(map[string]plumbing.FileDiffData)
  95. assert.Len(t, result, 1)
  96. oldDiff := fileDiffs[fileName]
  97. newDiff := result[fileName]
  98. assert.Equal(t, oldDiff.OldLinesOfCode, newDiff.OldLinesOfCode)
  99. assert.Equal(t, oldDiff.NewLinesOfCode, newDiff.NewLinesOfCode)
  100. assert.Equal(t, len(oldDiff.Diffs)+1, len(newDiff.Diffs))
  101. assert.Equal(t, dmp.DiffText2(oldDiff.Diffs), dmp.DiffText2(newDiff.Diffs))
  102. // Some hardcoded length checks
  103. assert.Equal(t, utf8.RuneCountInString(newDiff.Diffs[6].Text), 11)
  104. assert.Equal(t, utf8.RuneCountInString(newDiff.Diffs[7].Text), 41)
  105. assert.Equal(t, utf8.RuneCountInString(newDiff.Diffs[8].Text), 231)
  106. }
  107. func TestFileDiffRefinerConsumeNoUast(t *testing.T) {
  108. bytes1, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "1.java"))
  109. assert.Nil(t, err)
  110. bytes2, err := ioutil.ReadFile(path.Join("..", "..", "test_data", "2.java"))
  111. assert.Nil(t, err)
  112. dmp := diffmatchpatch.New()
  113. dmp.DiffTimeout = time.Hour
  114. src, dst, _ := dmp.DiffLinesToRunes(string(bytes1), string(bytes2))
  115. state := map[string]interface{}{}
  116. fileDiffs := map[string]plumbing.FileDiffData{}
  117. const fileName = "test.java"
  118. fileDiffs[fileName] = plumbing.FileDiffData{
  119. OldLinesOfCode: len(src),
  120. NewLinesOfCode: len(dst),
  121. Diffs: dmp.DiffMainRunes(src, dst, false),
  122. }
  123. state[plumbing.DependencyFileDiff] = fileDiffs
  124. uastChanges := make([]Change, 1)
  125. state[DependencyUastChanges] = uastChanges
  126. uastChanges[0] = Change{
  127. Change: &object.Change{
  128. From: object.ChangeEntry{Name: fileName},
  129. To: object.ChangeEntry{Name: fileName}},
  130. Before: loadUast(t, "uast1.pb"), After: nil,
  131. }
  132. fd := fixtureFileDiffRefiner()
  133. iresult, err := fd.Consume(state)
  134. assert.Nil(t, err)
  135. result := iresult[plumbing.DependencyFileDiff].(map[string]plumbing.FileDiffData)
  136. assert.Len(t, result, 1)
  137. assert.Equal(t, fileDiffs[fileName], result[fileName])
  138. fileDiffs[fileName] = plumbing.FileDiffData{
  139. OldLinesOfCode: 100,
  140. NewLinesOfCode: 100,
  141. Diffs: []diffmatchpatch.Diff{{}},
  142. }
  143. uastChanges[0] = Change{
  144. Change: &object.Change{
  145. From: object.ChangeEntry{Name: fileName},
  146. To: object.ChangeEntry{Name: fileName}},
  147. Before: loadUast(t, "uast1.pb"), After: loadUast(t, "uast2.pb"),
  148. }
  149. iresult, err = fd.Consume(state)
  150. assert.Nil(t, err)
  151. result = iresult[plumbing.DependencyFileDiff].(map[string]plumbing.FileDiffData)
  152. assert.Len(t, result, 1)
  153. assert.Equal(t, fileDiffs[fileName], result[fileName])
  154. }
  155. func TestFileDiffRefinerFork(t *testing.T) {
  156. fd1 := fixtureFileDiffRefiner()
  157. clones := fd1.Fork(1)
  158. assert.Len(t, clones, 1)
  159. fd2 := clones[0].(*FileDiffRefiner)
  160. assert.True(t, fd1 == fd2)
  161. fd1.Merge([]core.PipelineItem{fd2})
  162. }