Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package util
  4. import (
  5. "regexp"
  6. "strings"
  7. "testing"
  8. "code.gitea.io/gitea/modules/optional"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. func TestURLJoin(t *testing.T) {
  12. type test struct {
  13. Expected string
  14. Base string
  15. Elements []string
  16. }
  17. newTest := func(expected, base string, elements ...string) test {
  18. return test{Expected: expected, Base: base, Elements: elements}
  19. }
  20. for _, test := range []test{
  21. newTest("https://try.gitea.io/a/b/c",
  22. "https://try.gitea.io", "a/b", "c"),
  23. newTest("https://try.gitea.io/a/b/c",
  24. "https://try.gitea.io/", "/a/b/", "/c/"),
  25. newTest("https://try.gitea.io/a/c",
  26. "https://try.gitea.io/", "/a/./b/", "../c/"),
  27. newTest("a/b/c",
  28. "a", "b/c/"),
  29. newTest("a/b/d",
  30. "a/", "b/c/", "/../d/"),
  31. newTest("https://try.gitea.io/a/b/c#d",
  32. "https://try.gitea.io", "a/b", "c#d"),
  33. newTest("/a/b/d",
  34. "/a/", "b/c/", "/../d/"),
  35. newTest("/a/b/c",
  36. "/a", "b/c/"),
  37. newTest("/a/b/c#hash",
  38. "/a", "b/c#hash"),
  39. } {
  40. assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
  41. }
  42. }
  43. func TestIsEmptyString(t *testing.T) {
  44. cases := []struct {
  45. s string
  46. expected bool
  47. }{
  48. {"", true},
  49. {" ", true},
  50. {" ", true},
  51. {" a", false},
  52. }
  53. for _, v := range cases {
  54. assert.Equal(t, v.expected, IsEmptyString(v.s))
  55. }
  56. }
  57. func Test_NormalizeEOL(t *testing.T) {
  58. data1 := []string{
  59. "",
  60. "This text starts with empty lines",
  61. "another",
  62. "",
  63. "",
  64. "",
  65. "Some other empty lines in the middle",
  66. "more.",
  67. "And more.",
  68. "Ends with empty lines too.",
  69. "",
  70. "",
  71. "",
  72. }
  73. data2 := []string{
  74. "This text does not start with empty lines",
  75. "another",
  76. "",
  77. "",
  78. "",
  79. "Some other empty lines in the middle",
  80. "more.",
  81. "And more.",
  82. "Ends without EOLtoo.",
  83. }
  84. buildEOLData := func(data []string, eol string) []byte {
  85. return []byte(strings.Join(data, eol))
  86. }
  87. dos := buildEOLData(data1, "\r\n")
  88. unix := buildEOLData(data1, "\n")
  89. mac := buildEOLData(data1, "\r")
  90. assert.Equal(t, unix, NormalizeEOL(dos))
  91. assert.Equal(t, unix, NormalizeEOL(mac))
  92. assert.Equal(t, unix, NormalizeEOL(unix))
  93. dos = buildEOLData(data2, "\r\n")
  94. unix = buildEOLData(data2, "\n")
  95. mac = buildEOLData(data2, "\r")
  96. assert.Equal(t, unix, NormalizeEOL(dos))
  97. assert.Equal(t, unix, NormalizeEOL(mac))
  98. assert.Equal(t, unix, NormalizeEOL(unix))
  99. assert.Equal(t, []byte("one liner"), NormalizeEOL([]byte("one liner")))
  100. assert.Equal(t, []byte("\n"), NormalizeEOL([]byte("\n")))
  101. assert.Equal(t, []byte("\ntwo liner"), NormalizeEOL([]byte("\ntwo liner")))
  102. assert.Equal(t, []byte("two liner\n"), NormalizeEOL([]byte("two liner\n")))
  103. assert.Equal(t, []byte{}, NormalizeEOL([]byte{}))
  104. assert.Equal(t, []byte("mix\nand\nmatch\n."), NormalizeEOL([]byte("mix\r\nand\rmatch\n.")))
  105. }
  106. func Test_RandomInt(t *testing.T) {
  107. int, err := CryptoRandomInt(255)
  108. assert.True(t, int >= 0)
  109. assert.True(t, int <= 255)
  110. assert.NoError(t, err)
  111. }
  112. func Test_RandomString(t *testing.T) {
  113. str1, err := CryptoRandomString(32)
  114. assert.NoError(t, err)
  115. matches, err := regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
  116. assert.NoError(t, err)
  117. assert.True(t, matches)
  118. str2, err := CryptoRandomString(32)
  119. assert.NoError(t, err)
  120. matches, err = regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
  121. assert.NoError(t, err)
  122. assert.True(t, matches)
  123. assert.NotEqual(t, str1, str2)
  124. str3, err := CryptoRandomString(256)
  125. assert.NoError(t, err)
  126. matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str3)
  127. assert.NoError(t, err)
  128. assert.True(t, matches)
  129. str4, err := CryptoRandomString(256)
  130. assert.NoError(t, err)
  131. matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str4)
  132. assert.NoError(t, err)
  133. assert.True(t, matches)
  134. assert.NotEqual(t, str3, str4)
  135. }
  136. func Test_RandomBytes(t *testing.T) {
  137. bytes1, err := CryptoRandomBytes(32)
  138. assert.NoError(t, err)
  139. bytes2, err := CryptoRandomBytes(32)
  140. assert.NoError(t, err)
  141. assert.NotEqual(t, bytes1, bytes2)
  142. bytes3, err := CryptoRandomBytes(256)
  143. assert.NoError(t, err)
  144. bytes4, err := CryptoRandomBytes(256)
  145. assert.NoError(t, err)
  146. assert.NotEqual(t, bytes3, bytes4)
  147. }
  148. func TestOptionalBoolParse(t *testing.T) {
  149. assert.Equal(t, optional.None[bool](), OptionalBoolParse(""))
  150. assert.Equal(t, optional.None[bool](), OptionalBoolParse("x"))
  151. assert.Equal(t, optional.Some(false), OptionalBoolParse("0"))
  152. assert.Equal(t, optional.Some(false), OptionalBoolParse("f"))
  153. assert.Equal(t, optional.Some(false), OptionalBoolParse("False"))
  154. assert.Equal(t, optional.Some(true), OptionalBoolParse("1"))
  155. assert.Equal(t, optional.Some(true), OptionalBoolParse("t"))
  156. assert.Equal(t, optional.Some(true), OptionalBoolParse("True"))
  157. }
  158. // Test case for any function which accepts and returns a single string.
  159. type StringTest struct {
  160. in, out string
  161. }
  162. var upperTests = []StringTest{
  163. {"", ""},
  164. {"ONLYUPPER", "ONLYUPPER"},
  165. {"abc", "ABC"},
  166. {"AbC123", "ABC123"},
  167. {"azAZ09_", "AZAZ09_"},
  168. {"longStrinGwitHmixofsmaLLandcAps", "LONGSTRINGWITHMIXOFSMALLANDCAPS"},
  169. {"long\u0250string\u0250with\u0250nonascii\u2C6Fchars", "LONG\u0250STRING\u0250WITH\u0250NONASCII\u2C6FCHARS"},
  170. {"\u0250\u0250\u0250\u0250\u0250", "\u0250\u0250\u0250\u0250\u0250"},
  171. {"a\u0080\U0010FFFF", "A\u0080\U0010FFFF"},
  172. {"lél", "LéL"},
  173. }
  174. func TestToUpperASCII(t *testing.T) {
  175. for _, tc := range upperTests {
  176. assert.Equal(t, ToUpperASCII(tc.in), tc.out)
  177. }
  178. }
  179. func BenchmarkToUpper(b *testing.B) {
  180. for _, tc := range upperTests {
  181. b.Run(tc.in, func(b *testing.B) {
  182. for i := 0; i < b.N; i++ {
  183. ToUpperASCII(tc.in)
  184. }
  185. })
  186. }
  187. }
  188. func TestToTitleCase(t *testing.T) {
  189. assert.Equal(t, ToTitleCase(`foo bar baz`), `Foo Bar Baz`)
  190. assert.Equal(t, ToTitleCase(`FOO BAR BAZ`), `Foo Bar Baz`)
  191. }
  192. func TestToPointer(t *testing.T) {
  193. assert.Equal(t, "abc", *ToPointer("abc"))
  194. assert.Equal(t, 123, *ToPointer(123))
  195. abc := "abc"
  196. assert.False(t, &abc == ToPointer(abc))
  197. val123 := 123
  198. assert.False(t, &val123 == ToPointer(val123))
  199. }
  200. func TestReserveLineBreakForTextarea(t *testing.T) {
  201. assert.Equal(t, ReserveLineBreakForTextarea("test\r\ndata"), "test\ndata")
  202. assert.Equal(t, ReserveLineBreakForTextarea("test\r\ndata\r\n"), "test\ndata\n")
  203. }