utils_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Copyright (C) 2016 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package util
  7. import "testing"
  8. type Defaulter struct {
  9. Value string
  10. }
  11. func (d *Defaulter) ParseDefault(v string) error {
  12. *d = Defaulter{Value: v}
  13. return nil
  14. }
  15. func TestSetDefaults(t *testing.T) {
  16. x := &struct {
  17. A string `default:"string"`
  18. B int `default:"2"`
  19. C float64 `default:"2.2"`
  20. D bool `default:"true"`
  21. E Defaulter `default:"defaulter"`
  22. }{}
  23. if x.A != "" {
  24. t.Error("string failed")
  25. } else if x.B != 0 {
  26. t.Error("int failed")
  27. } else if x.C != 0 {
  28. t.Errorf("float failed")
  29. } else if x.D {
  30. t.Errorf("bool failed")
  31. } else if x.E.Value != "" {
  32. t.Errorf("defaulter failed")
  33. }
  34. SetDefaults(x)
  35. if x.A != "string" {
  36. t.Error("string failed")
  37. } else if x.B != 2 {
  38. t.Error("int failed")
  39. } else if x.C != 2.2 {
  40. t.Errorf("float failed")
  41. } else if !x.D {
  42. t.Errorf("bool failed")
  43. } else if x.E.Value != "defaulter" {
  44. t.Errorf("defaulter failed")
  45. }
  46. }
  47. func TestUniqueStrings(t *testing.T) {
  48. tests := []struct {
  49. input []string
  50. expected []string
  51. }{
  52. {
  53. []string{"a", "b"},
  54. []string{"a", "b"},
  55. },
  56. {
  57. []string{"a", "a"},
  58. []string{"a"},
  59. },
  60. {
  61. []string{"a", "a", "a", "a"},
  62. []string{"a"},
  63. },
  64. {
  65. nil,
  66. nil,
  67. },
  68. {
  69. []string{" a ", " a ", "b ", " b"},
  70. []string{"a", "b"},
  71. },
  72. }
  73. for _, test := range tests {
  74. result := UniqueTrimmedStrings(test.input)
  75. if len(result) != len(test.expected) {
  76. t.Errorf("%s != %s", result, test.expected)
  77. }
  78. for i := range result {
  79. if test.expected[i] != result[i] {
  80. t.Errorf("%s != %s", result, test.expected)
  81. }
  82. }
  83. }
  84. }
  85. func TestFillNillSlices(t *testing.T) {
  86. // Nil
  87. x := &struct {
  88. A []string `default:"a,b"`
  89. }{}
  90. if x.A != nil {
  91. t.Error("not nil")
  92. }
  93. if err := FillNilSlices(x); err != nil {
  94. t.Error(err)
  95. }
  96. if len(x.A) != 2 {
  97. t.Error("length")
  98. }
  99. // Already provided
  100. y := &struct {
  101. A []string `default:"c,d,e"`
  102. }{[]string{"a", "b"}}
  103. if len(y.A) != 2 {
  104. t.Error("length")
  105. }
  106. if err := FillNilSlices(y); err != nil {
  107. t.Error(err)
  108. }
  109. if len(y.A) != 2 {
  110. t.Error("length")
  111. }
  112. // Non-nil but empty
  113. z := &struct {
  114. A []string `default:"c,d,e"`
  115. }{[]string{}}
  116. if len(z.A) != 0 {
  117. t.Error("length")
  118. }
  119. if err := FillNilSlices(z); err != nil {
  120. t.Error(err)
  121. }
  122. if len(z.A) != 0 {
  123. t.Error("length")
  124. }
  125. }
  126. func TestAddress(t *testing.T) {
  127. tests := []struct {
  128. network string
  129. host string
  130. result string
  131. }{
  132. {"tcp", "google.com", "tcp://google.com"},
  133. {"foo", "google", "foo://google"},
  134. {"123", "456", "123://456"},
  135. }
  136. for _, test := range tests {
  137. result := Address(test.network, test.host)
  138. if result != test.result {
  139. t.Errorf("%s != %s", result, test.result)
  140. }
  141. }
  142. }
  143. func TestCopyMatching(t *testing.T) {
  144. type Nested struct {
  145. A int
  146. }
  147. type Test struct {
  148. CopyA int
  149. CopyB []string
  150. CopyC Nested
  151. CopyD *Nested
  152. NoCopy int `restart:"true"`
  153. }
  154. from := Test{
  155. CopyA: 1,
  156. CopyB: []string{"friend", "foe"},
  157. CopyC: Nested{
  158. A: 2,
  159. },
  160. CopyD: &Nested{
  161. A: 3,
  162. },
  163. NoCopy: 4,
  164. }
  165. to := Test{
  166. CopyA: 11,
  167. CopyB: []string{"foot", "toe"},
  168. CopyC: Nested{
  169. A: 22,
  170. },
  171. CopyD: &Nested{
  172. A: 33,
  173. },
  174. NoCopy: 44,
  175. }
  176. // Copy empty fields
  177. CopyMatchingTag(&from, &to, "restart", func(v string) bool {
  178. return v != "true"
  179. })
  180. if to.CopyA != 1 {
  181. t.Error("CopyA")
  182. }
  183. if len(to.CopyB) != 2 || to.CopyB[0] != "friend" || to.CopyB[1] != "foe" {
  184. t.Error("CopyB")
  185. }
  186. if to.CopyC.A != 2 {
  187. t.Error("CopyC")
  188. }
  189. if to.CopyD.A != 3 {
  190. t.Error("CopyC")
  191. }
  192. if to.NoCopy != 44 {
  193. t.Error("NoCopy")
  194. }
  195. }