typos_test.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // +build !disable_babelfish
  2. package research
  3. import (
  4. "bytes"
  5. "testing"
  6. "github.com/gogo/protobuf/proto"
  7. "github.com/stretchr/testify/assert"
  8. "gopkg.in/bblfsh/client-go.v3/tools"
  9. "gopkg.in/bblfsh/sdk.v2/uast"
  10. "gopkg.in/bblfsh/sdk.v2/uast/nodes"
  11. "gopkg.in/src-d/go-git.v4/plumbing"
  12. "gopkg.in/src-d/go-git.v4/plumbing/object"
  13. "gopkg.in/src-d/hercules.v10/internal/core"
  14. "gopkg.in/src-d/hercules.v10/internal/pb"
  15. items "gopkg.in/src-d/hercules.v10/internal/plumbing"
  16. uast_items "gopkg.in/src-d/hercules.v10/internal/plumbing/uast"
  17. "gopkg.in/src-d/hercules.v10/internal/test"
  18. )
  19. func TestTyposDatasetMeta(t *testing.T) {
  20. tdb := TyposDatasetBuilder{}
  21. assert.Equal(t, tdb.Name(), "TyposDataset")
  22. assert.Len(t, tdb.Provides(), 0)
  23. required := [...]string{
  24. uast_items.DependencyUastChanges, items.DependencyFileDiff, items.DependencyBlobCache}
  25. for _, name := range required {
  26. assert.Contains(t, tdb.Requires(), name)
  27. }
  28. opts := tdb.ListConfigurationOptions()
  29. assert.Len(t, opts, 1)
  30. assert.Equal(t, opts[0].Name, ConfigTyposDatasetMaximumAllowedDistance)
  31. assert.Equal(t, opts[0].Type, core.IntConfigurationOption)
  32. assert.Equal(t, tdb.Flag(), "typos-dataset")
  33. logger := core.NewLogger()
  34. assert.NoError(t, tdb.Configure(map[string]interface{}{
  35. core.ConfigLogger: logger,
  36. }))
  37. assert.Equal(t, logger, tdb.l)
  38. }
  39. func TestTyposDatasetRegistration(t *testing.T) {
  40. summoned := core.Registry.Summon((&TyposDatasetBuilder{}).Name())
  41. assert.Len(t, summoned, 1)
  42. assert.Equal(t, summoned[0].Name(), "TyposDataset")
  43. leaves := core.Registry.GetLeaves()
  44. matched := false
  45. for _, tp := range leaves {
  46. if tp.Flag() == (&TyposDatasetBuilder{}).Flag() {
  47. matched = true
  48. break
  49. }
  50. }
  51. assert.True(t, matched)
  52. }
  53. func TestTyposDatasetConfigure(t *testing.T) {
  54. tdb := TyposDatasetBuilder{}
  55. facts := map[string]interface{}{}
  56. facts[ConfigTyposDatasetMaximumAllowedDistance] = 5
  57. assert.Nil(t, tdb.Configure(facts))
  58. assert.Equal(t, tdb.MaximumAllowedDistance, 5)
  59. facts = map[string]interface{}{}
  60. assert.Nil(t, tdb.Configure(facts))
  61. assert.Equal(t, tdb.MaximumAllowedDistance, 5)
  62. }
  63. func AddHash(t *testing.T, cache map[plumbing.Hash]*items.CachedBlob, hash string) {
  64. objhash := plumbing.NewHash(hash)
  65. blob, err := test.Repository.BlobObject(objhash)
  66. assert.Nil(t, err)
  67. cb := &items.CachedBlob{Blob: *blob}
  68. err = cb.Cache()
  69. assert.Nil(t, err)
  70. cache[objhash] = cb
  71. }
  72. func bakeTyposDeps(t *testing.T) map[string]interface{} {
  73. deps := map[string]interface{}{}
  74. cache := map[plumbing.Hash]*items.CachedBlob{}
  75. AddHash(t, cache, "b9a12fd144274c99c7c9a0a32a0268f8b36d2f2c")
  76. AddHash(t, cache, "d5f8e61069136f3578457a3131800ede353527b8")
  77. AddHash(t, cache, "75bb0a09fc01db55d7322f0fae523453edba7846")
  78. deps[items.DependencyBlobCache] = cache
  79. changes := make(object.Changes, 2)
  80. treeFrom, _ := test.Repository.TreeObject(plumbing.NewHash(
  81. "eac25f9126db00e38fa72a59d49773a84580d4ce"))
  82. treeTo, _ := test.Repository.TreeObject(plumbing.NewHash(
  83. "828467b465864b1f757dcec9a034be49030fc8b9"))
  84. changes[0] = &object.Change{From: object.ChangeEntry{
  85. Name: "file_test.go",
  86. Tree: treeFrom,
  87. TreeEntry: object.TreeEntry{
  88. Name: "file_test.go",
  89. Mode: 0100644,
  90. Hash: plumbing.NewHash("75bb0a09fc01db55d7322f0fae523453edba7846"),
  91. },
  92. }, To: object.ChangeEntry{
  93. Name: "file_test.go",
  94. Tree: treeTo,
  95. TreeEntry: object.TreeEntry{
  96. Name: "file_test.go",
  97. Mode: 0100644,
  98. Hash: plumbing.NewHash("75bb0a09fc01db55d7322f0fae523453edba7846"),
  99. },
  100. }}
  101. changes[1] = &object.Change{From: object.ChangeEntry{}, To: object.ChangeEntry{
  102. Name: "blob_cache_test.go",
  103. Tree: treeTo,
  104. TreeEntry: object.TreeEntry{
  105. Name: "blob_cache_test.go",
  106. Mode: 0100644,
  107. Hash: plumbing.NewHash("b9a12fd144274c99c7c9a0a32a0268f8b36d2f2c"),
  108. },
  109. },
  110. }
  111. deps[items.DependencyTreeChanges] = changes
  112. deps[core.DependencyCommit], _ = test.Repository.CommitObject(plumbing.NewHash(
  113. "84165d3b02647fae12cc026c7a580045246e8c98"))
  114. deps[core.DependencyIsMerge] = false
  115. uastItem := &uast_items.Extractor{}
  116. assert.Nil(t, uastItem.Initialize(test.Repository))
  117. uastResult, err := uastItem.Consume(deps)
  118. assert.Nil(t, err)
  119. deps[uast_items.DependencyUasts] = uastResult[uast_items.DependencyUasts]
  120. uastChanges := &uast_items.Changes{}
  121. assert.Nil(t, uastChanges.Initialize(test.Repository))
  122. _, err = uastChanges.Consume(deps)
  123. assert.Nil(t, err)
  124. changes[0].To.TreeEntry.Hash = plumbing.NewHash("d5f8e61069136f3578457a3131800ede353527b8")
  125. uastResult, err = uastItem.Consume(deps)
  126. assert.Nil(t, err)
  127. deps[uast_items.DependencyUasts] = uastResult[uast_items.DependencyUasts]
  128. changesResult, err := uastChanges.Consume(deps)
  129. assert.Nil(t, err)
  130. deps[uast_items.DependencyUastChanges] = changesResult[uast_items.DependencyUastChanges]
  131. fd := &items.FileDiff{}
  132. assert.Nil(t, fd.Initialize(test.Repository))
  133. diffResult, err := fd.Consume(deps)
  134. assert.Nil(t, err)
  135. deps[items.DependencyFileDiff] = diffResult[items.DependencyFileDiff]
  136. return deps
  137. }
  138. func TestTyposDatasetConsume(t *testing.T) {
  139. deps := bakeTyposDeps(t)
  140. tbd := &TyposDatasetBuilder{}
  141. assert.Nil(t, tbd.Initialize(test.Repository))
  142. res, err := tbd.Consume(deps)
  143. assert.Nil(t, res)
  144. assert.Nil(t, err)
  145. assert.Len(t, tbd.typos, 26)
  146. assert.Equal(t, tbd.typos[0].Wrong, "TestInitialize")
  147. assert.Equal(t, tbd.typos[0].Correct, "TestInitializeFile")
  148. assert.Equal(t, tbd.typos[0].Commit, plumbing.NewHash(
  149. "84165d3b02647fae12cc026c7a580045246e8c98"))
  150. assert.Equal(t, tbd.typos[0].File, "file_test.go")
  151. assert.Equal(t, tbd.typos[0].Line, 19)
  152. deps[core.DependencyIsMerge] = true
  153. res, err = tbd.Consume(deps)
  154. assert.Nil(t, res)
  155. assert.Nil(t, err)
  156. assert.Len(t, tbd.typos, 26)
  157. }
  158. func dropPositions(root nodes.Node, target string) {
  159. for element := range tools.Iterate(tools.NewIterator(root, tools.PreOrder)) {
  160. obj, isobj := element.(nodes.Object)
  161. if !isobj {
  162. continue
  163. }
  164. nameval, exists := obj["Name"]
  165. if !exists {
  166. continue
  167. }
  168. if name, isstr := nameval.(nodes.String); !isstr || string(name) != target {
  169. continue
  170. }
  171. posval, exists := obj[uast.KeyPos]
  172. if !exists {
  173. continue
  174. }
  175. posobj, isobj := posval.(nodes.Object)
  176. if !isobj {
  177. continue
  178. }
  179. for k, v := range posobj {
  180. po, _ := v.(nodes.Object)
  181. if uast.AsPosition(po) != nil {
  182. posobj[k] = nil
  183. }
  184. }
  185. }
  186. }
  187. func TestTyposDatasetConsumeMissingPosition(t *testing.T) {
  188. deps := bakeTyposDeps(t)
  189. uastChanges := deps[uast_items.DependencyUastChanges].([]uast_items.Change)
  190. dropPositions(uastChanges[0].Before, "TestZeroInitialize")
  191. dropPositions(uastChanges[0].After, "TestZeroInitializeFile")
  192. tbd := &TyposDatasetBuilder{}
  193. assert.Nil(t, tbd.Initialize(test.Repository))
  194. res, err := tbd.Consume(deps)
  195. assert.Nil(t, res)
  196. assert.Nil(t, err)
  197. assert.Len(t, tbd.typos, 25)
  198. }
  199. func fixtureTyposDataset() *TyposDatasetBuilder {
  200. tdb := TyposDatasetBuilder{}
  201. tdb.Initialize(test.Repository)
  202. tdb.typos = append(tdb.typos, Typo{
  203. Wrong: "Fo",
  204. Correct: "Foo",
  205. Commit: plumbing.ZeroHash,
  206. File: "bar.go",
  207. Line: 7,
  208. })
  209. return &tdb
  210. }
  211. func TestTyposDatasetFinalize(t *testing.T) {
  212. tdb := fixtureTyposDataset()
  213. tdb.typos = append(tdb.typos, tdb.typos[0])
  214. x := tdb.Finalize().(TyposResult)
  215. assert.Len(t, x.Typos, 1)
  216. assert.Equal(t, x.Typos[0], Typo{
  217. Wrong: "Fo",
  218. Correct: "Foo",
  219. Commit: plumbing.ZeroHash,
  220. File: "bar.go",
  221. Line: 7,
  222. })
  223. }
  224. func TestTyposDatasetSerialize(t *testing.T) {
  225. ca := fixtureTyposDataset()
  226. res := ca.Finalize().(TyposResult)
  227. buffer := &bytes.Buffer{}
  228. err := ca.Serialize(res, false, buffer)
  229. assert.Nil(t, err)
  230. assert.Equal(t, ` - wrong: "Fo"
  231. correct: "Foo"
  232. commit: 0000000000000000000000000000000000000000
  233. file: "bar.go"
  234. line: 7
  235. `, buffer.String())
  236. buffer = &bytes.Buffer{}
  237. err = ca.Serialize(res, true, buffer)
  238. assert.Nil(t, err)
  239. msg := pb.TyposDataset{}
  240. assert.Nil(t, proto.Unmarshal(buffer.Bytes(), &msg))
  241. assert.Len(t, msg.Typos, 1)
  242. assert.Equal(t, *msg.Typos[0], pb.Typo{
  243. Wrong: "Fo",
  244. Correct: "Foo",
  245. Commit: "0000000000000000000000000000000000000000",
  246. File: "bar.go",
  247. Line: 7,
  248. })
  249. }