endtoend_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package main
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "testing"
  9. "github.com/google/go-cmp/cmp"
  10. "github.com/google/go-cmp/cmp/cmpopts"
  11. "github.com/kyleconroy/sqlc/internal/cmd"
  12. )
  13. func TestExamples(t *testing.T) {
  14. t.Parallel()
  15. examples, err := filepath.Abs(filepath.Join("..", "..", "examples"))
  16. if err != nil {
  17. t.Fatal(err)
  18. }
  19. files, err := ioutil.ReadDir(examples)
  20. if err != nil {
  21. t.Fatal(err)
  22. }
  23. for _, replay := range files {
  24. if !replay.IsDir() {
  25. continue
  26. }
  27. tc := replay.Name()
  28. t.Run(tc, func(t *testing.T) {
  29. t.Parallel()
  30. path := filepath.Join(examples, tc)
  31. var stderr bytes.Buffer
  32. output, err := cmd.Generate(cmd.Env{}, path, &stderr)
  33. if err != nil {
  34. t.Fatalf("sqlc generate failed: %s", stderr.String())
  35. }
  36. cmpDirectory(t, path, output)
  37. })
  38. }
  39. }
  40. func TestReplay(t *testing.T) {
  41. t.Parallel()
  42. files, err := ioutil.ReadDir("testdata")
  43. if err != nil {
  44. t.Fatal(err)
  45. }
  46. for _, replay := range files {
  47. if !replay.IsDir() {
  48. continue
  49. }
  50. tc := replay.Name()
  51. t.Run(tc, func(t *testing.T) {
  52. t.Parallel()
  53. path, _ := filepath.Abs(filepath.Join("testdata", tc))
  54. var stderr bytes.Buffer
  55. expected := expectedStderr(t, path)
  56. output, err := cmd.Generate(cmd.Env{}, path, &stderr)
  57. if len(expected) == 0 && err != nil {
  58. t.Fatalf("sqlc generate failed: %s", stderr.String())
  59. }
  60. cmpDirectory(t, path, output)
  61. if diff := cmp.Diff(expected, stderr.String()); diff != "" {
  62. t.Errorf("stderr differed (-want +got):\n%s", diff)
  63. }
  64. })
  65. }
  66. }
  67. func cmpDirectory(t *testing.T, dir string, actual map[string]string) {
  68. expected := map[string]string{}
  69. var ff = func(path string, file os.FileInfo, err error) error {
  70. if err != nil {
  71. return err
  72. }
  73. if file.IsDir() {
  74. return nil
  75. }
  76. if !strings.HasSuffix(path, ".go") && !strings.HasSuffix(path, ".kt") {
  77. return nil
  78. }
  79. if strings.HasSuffix(path, "_test.go") || strings.Contains(path, "src/test/") {
  80. return nil
  81. }
  82. // TODO(mightyguava): Remove this after sqlc-kotlin-runtime is published to Maven.
  83. if strings.HasSuffix(path, "Query.kt") {
  84. return nil
  85. }
  86. blob, err := ioutil.ReadFile(path)
  87. if err != nil {
  88. return err
  89. }
  90. expected[path] = string(blob)
  91. return nil
  92. }
  93. if err := filepath.Walk(dir, ff); err != nil {
  94. t.Fatal(err)
  95. }
  96. if !cmp.Equal(expected, actual, cmpopts.EquateEmpty()) {
  97. t.Errorf("%s contents differ", dir)
  98. for name, contents := range expected {
  99. name := name
  100. tn := strings.Replace(name, dir+"/", "", -1)
  101. t.Run(tn, func(t *testing.T) {
  102. if actual[name] == "" {
  103. t.Errorf("%s is empty", name)
  104. return
  105. }
  106. if diff := cmp.Diff(contents, actual[name]); diff != "" {
  107. t.Errorf("%s differed (-want +got):\n%s", name, diff)
  108. }
  109. })
  110. }
  111. }
  112. }
  113. func expectedStderr(t *testing.T, dir string) string {
  114. t.Helper()
  115. path := filepath.Join(dir, "stderr.txt")
  116. if _, err := os.Stat(path); !os.IsNotExist(err) {
  117. blob, err := ioutil.ReadFile(path)
  118. if err != nil {
  119. t.Fatal(err)
  120. }
  121. return string(blob)
  122. }
  123. return ""
  124. }