You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unit_tests.go 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2016 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package unittest
  4. import (
  5. "math"
  6. "code.gitea.io/gitea/models/db"
  7. "github.com/stretchr/testify/assert"
  8. "xorm.io/builder"
  9. )
  10. // Code in this file is mainly used by unittest.CheckConsistencyFor, which is not in the unit test for various reasons.
  11. // In the future if we can decouple CheckConsistencyFor into separate unit test code, then this file can be moved into unittest package too.
  12. // NonexistentID an ID that will never exist
  13. const NonexistentID = int64(math.MaxInt64)
  14. type testCond struct {
  15. query any
  16. args []any
  17. }
  18. type testOrderBy string
  19. // Cond create a condition with arguments for a test
  20. func Cond(query any, args ...any) any {
  21. return &testCond{query: query, args: args}
  22. }
  23. // OrderBy creates "ORDER BY" a test query
  24. func OrderBy(orderBy string) any {
  25. return testOrderBy(orderBy)
  26. }
  27. func whereOrderConditions(e db.Engine, conditions []any) db.Engine {
  28. orderBy := "id" // query must have the "ORDER BY", otherwise the result is not deterministic
  29. for _, condition := range conditions {
  30. switch cond := condition.(type) {
  31. case *testCond:
  32. e = e.Where(cond.query, cond.args...)
  33. case testOrderBy:
  34. orderBy = string(cond)
  35. default:
  36. e = e.Where(cond)
  37. }
  38. }
  39. return e.OrderBy(orderBy)
  40. }
  41. // LoadBeanIfExists loads beans from fixture database if exist
  42. func LoadBeanIfExists(bean any, conditions ...any) (bool, error) {
  43. e := db.GetEngine(db.DefaultContext)
  44. return whereOrderConditions(e, conditions).Get(bean)
  45. }
  46. // BeanExists for testing, check if a bean exists
  47. func BeanExists(t assert.TestingT, bean any, conditions ...any) bool {
  48. exists, err := LoadBeanIfExists(bean, conditions...)
  49. assert.NoError(t, err)
  50. return exists
  51. }
  52. // AssertExistsAndLoadBean assert that a bean exists and load it from the test database
  53. func AssertExistsAndLoadBean[T any](t assert.TestingT, bean T, conditions ...any) T {
  54. exists, err := LoadBeanIfExists(bean, conditions...)
  55. assert.NoError(t, err)
  56. assert.True(t, exists,
  57. "Expected to find %+v (of type %T, with conditions %+v), but did not",
  58. bean, bean, conditions)
  59. return bean
  60. }
  61. // AssertExistsAndLoadMap assert that a row exists and load it from the test database
  62. func AssertExistsAndLoadMap(t assert.TestingT, table string, conditions ...any) map[string]string {
  63. e := db.GetEngine(db.DefaultContext).Table(table)
  64. res, err := whereOrderConditions(e, conditions).Query()
  65. assert.NoError(t, err)
  66. assert.True(t, len(res) == 1,
  67. "Expected to find one row in %s (with conditions %+v), but found %d",
  68. table, conditions, len(res),
  69. )
  70. if len(res) == 1 {
  71. rec := map[string]string{}
  72. for k, v := range res[0] {
  73. rec[k] = string(v)
  74. }
  75. return rec
  76. }
  77. return nil
  78. }
  79. // GetCount get the count of a bean
  80. func GetCount(t assert.TestingT, bean any, conditions ...any) int {
  81. e := db.GetEngine(db.DefaultContext)
  82. for _, condition := range conditions {
  83. switch cond := condition.(type) {
  84. case *testCond:
  85. e = e.Where(cond.query, cond.args...)
  86. default:
  87. e = e.Where(cond)
  88. }
  89. }
  90. count, err := e.Count(bean)
  91. assert.NoError(t, err)
  92. return int(count)
  93. }
  94. // AssertNotExistsBean assert that a bean does not exist in the test database
  95. func AssertNotExistsBean(t assert.TestingT, bean any, conditions ...any) {
  96. exists, err := LoadBeanIfExists(bean, conditions...)
  97. assert.NoError(t, err)
  98. assert.False(t, exists)
  99. }
  100. // AssertExistsIf asserts that a bean exists or does not exist, depending on
  101. // what is expected.
  102. func AssertExistsIf(t assert.TestingT, expected bool, bean any, conditions ...any) {
  103. exists, err := LoadBeanIfExists(bean, conditions...)
  104. assert.NoError(t, err)
  105. assert.Equal(t, expected, exists)
  106. }
  107. // AssertSuccessfulInsert assert that beans is successfully inserted
  108. func AssertSuccessfulInsert(t assert.TestingT, beans ...any) {
  109. err := db.Insert(db.DefaultContext, beans...)
  110. assert.NoError(t, err)
  111. }
  112. // AssertCount assert the count of a bean
  113. func AssertCount(t assert.TestingT, bean, expected any) bool {
  114. return assert.EqualValues(t, expected, GetCount(t, bean))
  115. }
  116. // AssertInt64InRange assert value is in range [low, high]
  117. func AssertInt64InRange(t assert.TestingT, low, high, value int64) {
  118. assert.True(t, value >= low && value <= high,
  119. "Expected value in range [%d, %d], found %d", low, high, value)
  120. }
  121. // GetCountByCond get the count of database entries matching bean
  122. func GetCountByCond(t assert.TestingT, tableName string, cond builder.Cond) int64 {
  123. e := db.GetEngine(db.DefaultContext)
  124. count, err := e.Table(tableName).Where(cond).Count()
  125. assert.NoError(t, err)
  126. return count
  127. }
  128. // AssertCountByCond test the count of database entries matching bean
  129. func AssertCountByCond(t assert.TestingT, tableName string, cond builder.Cond, expected int) bool {
  130. return assert.EqualValues(t, expected, GetCountByCond(t, tableName, cond),
  131. "Failed consistency test, the counted bean (of table %s) was %+v", tableName, cond)
  132. }