utils_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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{"b", "a"},
  70. []string{"a", "b"},
  71. },
  72. {
  73. []string{" a ", " a ", "b ", " b"},
  74. []string{"a", "b"},
  75. },
  76. }
  77. for _, test := range tests {
  78. result := UniqueStrings(test.input)
  79. if len(result) != len(test.expected) {
  80. t.Errorf("%s != %s", result, test.expected)
  81. }
  82. for i := range result {
  83. if test.expected[i] != result[i] {
  84. t.Errorf("%s != %s", result, test.expected)
  85. }
  86. }
  87. }
  88. }
  89. func TestFillNillSlices(t *testing.T) {
  90. // Nil
  91. x := &struct {
  92. A []string `default:"a,b"`
  93. }{}
  94. if x.A != nil {
  95. t.Error("not nil")
  96. }
  97. if err := FillNilSlices(x); err != nil {
  98. t.Error(err)
  99. }
  100. if len(x.A) != 2 {
  101. t.Error("length")
  102. }
  103. // Already provided
  104. y := &struct {
  105. A []string `default:"c,d,e"`
  106. }{[]string{"a", "b"}}
  107. if len(y.A) != 2 {
  108. t.Error("length")
  109. }
  110. if err := FillNilSlices(y); err != nil {
  111. t.Error(err)
  112. }
  113. if len(y.A) != 2 {
  114. t.Error("length")
  115. }
  116. // Non-nil but empty
  117. z := &struct {
  118. A []string `default:"c,d,e"`
  119. }{[]string{}}
  120. if len(z.A) != 0 {
  121. t.Error("length")
  122. }
  123. if err := FillNilSlices(z); err != nil {
  124. t.Error(err)
  125. }
  126. if len(z.A) != 0 {
  127. t.Error("length")
  128. }
  129. }
  130. func TestAddress(t *testing.T) {
  131. tests := []struct {
  132. network string
  133. host string
  134. result string
  135. }{
  136. {"tcp", "google.com", "tcp://google.com"},
  137. {"foo", "google", "foo://google"},
  138. {"123", "456", "123://456"},
  139. }
  140. for _, test := range tests {
  141. result := Address(test.network, test.host)
  142. if result != test.result {
  143. t.Errorf("%s != %s", result, test.result)
  144. }
  145. }
  146. }
  147. func TestCopyMatching(t *testing.T) {
  148. type Nested struct {
  149. A int
  150. }
  151. type Test struct {
  152. CopyA int
  153. CopyB []string
  154. CopyC Nested
  155. CopyD *Nested
  156. NoCopy int `restart:"true"`
  157. }
  158. from := Test{
  159. CopyA: 1,
  160. CopyB: []string{"friend", "foe"},
  161. CopyC: Nested{
  162. A: 2,
  163. },
  164. CopyD: &Nested{
  165. A: 3,
  166. },
  167. NoCopy: 4,
  168. }
  169. to := Test{
  170. CopyA: 11,
  171. CopyB: []string{"foot", "toe"},
  172. CopyC: Nested{
  173. A: 22,
  174. },
  175. CopyD: &Nested{
  176. A: 33,
  177. },
  178. NoCopy: 44,
  179. }
  180. // Copy empty fields
  181. CopyMatchingTag(&from, &to, "restart", func(v string) bool {
  182. return v != "true"
  183. })
  184. if to.CopyA != 1 {
  185. t.Error("CopyA")
  186. }
  187. if len(to.CopyB) != 2 || to.CopyB[0] != "friend" || to.CopyB[1] != "foe" {
  188. t.Error("CopyB")
  189. }
  190. if to.CopyC.A != 2 {
  191. t.Error("CopyC")
  192. }
  193. if to.CopyD.A != 3 {
  194. t.Error("CopyC")
  195. }
  196. if to.NoCopy != 44 {
  197. t.Error("NoCopy")
  198. }
  199. }