schema_helper_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package schema_test
  2. import (
  3. "database/sql/driver"
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. "testing"
  8. "github.com/jinzhu/gorm/schema"
  9. "github.com/jinzhu/gorm/tests"
  10. )
  11. func checkSchema(t *testing.T, s *schema.Schema, v schema.Schema, primaryFields []string) {
  12. t.Run("CheckSchema/"+s.Name, func(t *testing.T) {
  13. tests.AssertEqual(t, s, v, "Name", "Table")
  14. for idx, field := range primaryFields {
  15. var found bool
  16. for _, f := range s.PrimaryFields {
  17. if f.Name == field {
  18. found = true
  19. }
  20. }
  21. if idx == 0 {
  22. if field != s.PrioritizedPrimaryField.Name {
  23. t.Errorf("schema %v prioritized primary field should be %v, but got %v", s, field, s.PrioritizedPrimaryField.Name)
  24. }
  25. }
  26. if !found {
  27. t.Errorf("schema %v failed to found priamry key: %v", s, field)
  28. }
  29. }
  30. })
  31. }
  32. func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(*schema.Field)) {
  33. t.Run("CheckField/"+f.Name, func(t *testing.T) {
  34. if fc != nil {
  35. fc(f)
  36. }
  37. if f.TagSettings == nil {
  38. if f.Tag != "" {
  39. f.TagSettings = schema.ParseTagSetting(f.Tag.Get("gorm"), ";")
  40. } else {
  41. f.TagSettings = map[string]string{}
  42. }
  43. }
  44. if parsedField, ok := s.FieldsByName[f.Name]; !ok {
  45. t.Errorf("schema %v failed to look up field with name %v", s, f.Name)
  46. } else {
  47. tests.AssertEqual(t, parsedField, f, "Name", "DBName", "BindNames", "DataType", "DBDataType", "PrimaryKey", "AutoIncrement", "Creatable", "Updatable", "HasDefaultValue", "DefaultValue", "NotNull", "Unique", "Comment", "Size", "Precision", "Tag", "TagSettings")
  48. if field, ok := s.FieldsByDBName[f.DBName]; !ok || parsedField != field {
  49. t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName)
  50. }
  51. for _, name := range []string{f.DBName, f.Name} {
  52. if field := s.LookUpField(name); field == nil || parsedField != field {
  53. t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName)
  54. }
  55. }
  56. if f.PrimaryKey {
  57. var found bool
  58. for _, primaryField := range s.PrimaryFields {
  59. if primaryField == parsedField {
  60. found = true
  61. }
  62. }
  63. if !found {
  64. t.Errorf("schema %v doesn't include field %v", s, f.Name)
  65. }
  66. }
  67. }
  68. })
  69. }
  70. type Relation struct {
  71. Name string
  72. Type schema.RelationshipType
  73. Schema string
  74. FieldSchema string
  75. Polymorphic Polymorphic
  76. JoinTable JoinTable
  77. References []Reference
  78. }
  79. type Polymorphic struct {
  80. ID string
  81. Type string
  82. Value string
  83. }
  84. type JoinTable struct {
  85. Name string
  86. Table string
  87. Fields []schema.Field
  88. }
  89. type Reference struct {
  90. PrimaryKey string
  91. PrimarySchema string
  92. ForeignKey string
  93. ForeignSchema string
  94. PrimaryValue string
  95. OwnPrimaryKey bool
  96. }
  97. func checkSchemaRelation(t *testing.T, s *schema.Schema, relation Relation) {
  98. t.Run("CheckRelation/"+relation.Name, func(t *testing.T) {
  99. if r, ok := s.Relationships.Relations[relation.Name]; ok {
  100. if r.Name != relation.Name {
  101. t.Errorf("schema %v relation name expects %v, but got %v", s, r.Name, relation.Name)
  102. }
  103. if r.Type != relation.Type {
  104. t.Errorf("schema %v relation name expects %v, but got %v", s, r.Type, relation.Type)
  105. }
  106. if r.Schema.Name != relation.Schema {
  107. t.Errorf("schema %v relation's schema expects %v, but got %v", s, relation.Schema, r.Schema.Name)
  108. }
  109. if r.FieldSchema.Name != relation.FieldSchema {
  110. t.Errorf("schema %v relation's schema expects %v, but got %v", s, relation.Schema, r.Schema.Name)
  111. }
  112. if r.Polymorphic != nil {
  113. if r.Polymorphic.PolymorphicID.Name != relation.Polymorphic.ID {
  114. t.Errorf("schema %v relation's polymorphic id field expects %v, but got %v", s, relation.Polymorphic.ID, r.Polymorphic.PolymorphicID.Name)
  115. }
  116. if r.Polymorphic.PolymorphicType.Name != relation.Polymorphic.Type {
  117. t.Errorf("schema %v relation's polymorphic type field expects %v, but got %v", s, relation.Polymorphic.Type, r.Polymorphic.PolymorphicType.Name)
  118. }
  119. if r.Polymorphic.Value != relation.Polymorphic.Value {
  120. t.Errorf("schema %v relation's polymorphic value expects %v, but got %v", s, relation.Polymorphic.Value, r.Polymorphic.Value)
  121. }
  122. }
  123. if r.JoinTable != nil {
  124. if r.JoinTable.Name != relation.JoinTable.Name {
  125. t.Errorf("schema %v relation's join table name expects %v, but got %v", s, relation.JoinTable.Name, r.JoinTable.Name)
  126. }
  127. if r.JoinTable.Table != relation.JoinTable.Table {
  128. t.Errorf("schema %v relation's join table tablename expects %v, but got %v", s, relation.JoinTable.Table, r.JoinTable.Table)
  129. }
  130. for _, f := range relation.JoinTable.Fields {
  131. checkSchemaField(t, r.JoinTable, &f, nil)
  132. }
  133. }
  134. if len(relation.References) != len(r.References) {
  135. t.Errorf("schema %v relation's reference's count doesn't match, expects %v, but got %v", s, len(relation.References), len(r.References))
  136. }
  137. for _, ref := range relation.References {
  138. var found bool
  139. for _, rf := range r.References {
  140. if (rf.PrimaryKey == nil || (rf.PrimaryKey.Name == ref.PrimaryKey && rf.PrimaryKey.Schema.Name == ref.PrimarySchema)) && (rf.PrimaryValue == ref.PrimaryValue) && (rf.ForeignKey.Name == ref.ForeignKey && rf.ForeignKey.Schema.Name == ref.ForeignSchema) && (rf.OwnPrimaryKey == ref.OwnPrimaryKey) {
  141. found = true
  142. }
  143. }
  144. if !found {
  145. var refs []string
  146. for _, rf := range r.References {
  147. var primaryKey, primaryKeySchema string
  148. if rf.PrimaryKey != nil {
  149. primaryKey, primaryKeySchema = rf.PrimaryKey.Name, rf.PrimaryKey.Schema.Name
  150. }
  151. refs = append(refs, fmt.Sprintf(
  152. "{PrimaryKey: %v PrimaryKeySchame: %v ForeignKey: %v ForeignKeySchema: %v PrimaryValue: %v OwnPrimaryKey: %v}",
  153. primaryKey, primaryKeySchema, rf.ForeignKey.Name, rf.ForeignKey.Schema.Name, rf.PrimaryValue, rf.OwnPrimaryKey,
  154. ))
  155. }
  156. t.Errorf("schema %v relation %v failed to found reference %+v, has %v", s, relation.Name, ref, strings.Join(refs, ", "))
  157. }
  158. }
  159. } else {
  160. t.Errorf("schema %v failed to find relations by name %v", s, relation.Name)
  161. }
  162. })
  163. }
  164. func checkField(t *testing.T, s *schema.Schema, value reflect.Value, values map[string]interface{}) {
  165. for k, v := range values {
  166. t.Run("CheckField/"+k, func(t *testing.T) {
  167. var (
  168. checker func(fv interface{}, v interface{})
  169. field = s.FieldsByDBName[k]
  170. fv, _ = field.ValueOf(value)
  171. )
  172. checker = func(fv interface{}, v interface{}) {
  173. if reflect.ValueOf(fv).Type() == reflect.ValueOf(v).Type() && fv != v {
  174. t.Errorf("expects: %p, but got %p", v, fv)
  175. } else if reflect.ValueOf(v).Type().ConvertibleTo(reflect.ValueOf(fv).Type()) {
  176. if reflect.ValueOf(v).Convert(reflect.ValueOf(fv).Type()).Interface() != fv {
  177. t.Errorf("expects: %p, but got %p", v, fv)
  178. }
  179. } else if reflect.ValueOf(fv).Type().ConvertibleTo(reflect.ValueOf(v).Type()) {
  180. if reflect.ValueOf(fv).Convert(reflect.ValueOf(fv).Type()).Interface() != v {
  181. t.Errorf("expects: %p, but got %p", v, fv)
  182. }
  183. } else if valuer, isValuer := fv.(driver.Valuer); isValuer {
  184. valuerv, _ := valuer.Value()
  185. checker(valuerv, v)
  186. } else if valuer, isValuer := v.(driver.Valuer); isValuer {
  187. valuerv, _ := valuer.Value()
  188. checker(fv, valuerv)
  189. } else if reflect.ValueOf(fv).Kind() == reflect.Ptr {
  190. checker(reflect.ValueOf(fv).Elem().Interface(), v)
  191. } else if reflect.ValueOf(v).Kind() == reflect.Ptr {
  192. checker(fv, reflect.ValueOf(v).Elem().Interface())
  193. } else {
  194. t.Errorf("expects: %+v, but got %+v", v, fv)
  195. }
  196. }
  197. checker(fv, v)
  198. })
  199. }
  200. }