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.

modes_test.go 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright (c) 2018 Shivaram Lingamneni
  2. // released under the MIT license
  3. package modes
  4. import (
  5. "reflect"
  6. "strings"
  7. "testing"
  8. )
  9. func assertEqual(supplied, expected interface{}, t *testing.T) {
  10. if !reflect.DeepEqual(supplied, expected) {
  11. t.Errorf("expected %v but got %v", expected, supplied)
  12. }
  13. }
  14. func TestParseUserModeChanges(t *testing.T) {
  15. emptyUnknown := make(map[rune]bool)
  16. changes, unknown := ParseUserModeChanges("+i")
  17. assertEqual(unknown, emptyUnknown, t)
  18. assertEqual(changes, ModeChanges{ModeChange{Op: Add, Mode: Invisible}}, t)
  19. // no-op change to sno
  20. changes, unknown = ParseUserModeChanges("+is")
  21. assertEqual(unknown, emptyUnknown, t)
  22. assertEqual(changes, ModeChanges{ModeChange{Op: Add, Mode: Invisible}, ModeChange{Op: Add, Mode: ServerNotice}}, t)
  23. // add snomasks
  24. changes, unknown = ParseUserModeChanges("+is", "ac")
  25. assertEqual(unknown, emptyUnknown, t)
  26. assertEqual(changes, ModeChanges{ModeChange{Op: Add, Mode: Invisible}, ModeChange{Op: Add, Mode: ServerNotice, Arg: "ac"}}, t)
  27. // remove snomasks
  28. changes, unknown = ParseUserModeChanges("+s", "-cx")
  29. assertEqual(unknown, emptyUnknown, t)
  30. assertEqual(changes, ModeChanges{ModeChange{Op: Add, Mode: ServerNotice, Arg: "-cx"}}, t)
  31. // remove all snomasks (arg is parsed but has no meaning)
  32. changes, unknown = ParseUserModeChanges("-is", "ac")
  33. assertEqual(unknown, emptyUnknown, t)
  34. assertEqual(changes, ModeChanges{ModeChange{Op: Remove, Mode: Invisible}, ModeChange{Op: Remove, Mode: ServerNotice, Arg: "ac"}}, t)
  35. // remove all snomasks
  36. changes, unknown = ParseUserModeChanges("-is")
  37. assertEqual(unknown, emptyUnknown, t)
  38. assertEqual(changes, ModeChanges{ModeChange{Op: Remove, Mode: Invisible}, ModeChange{Op: Remove, Mode: ServerNotice}}, t)
  39. }
  40. func TestIssue874(t *testing.T) {
  41. emptyUnknown := make(map[rune]bool)
  42. modes, unknown := ParseChannelModeChanges("+k")
  43. assertEqual(unknown, emptyUnknown, t)
  44. assertEqual(modes, ModeChanges{}, t)
  45. modes, unknown = ParseChannelModeChanges("+k", "beer")
  46. assertEqual(unknown, emptyUnknown, t)
  47. assertEqual(modes, ModeChanges{ModeChange{Op: Add, Mode: Key, Arg: "beer"}}, t)
  48. modes, unknown = ParseChannelModeChanges("-k")
  49. assertEqual(unknown, emptyUnknown, t)
  50. assertEqual(modes, ModeChanges{ModeChange{Op: Remove, Mode: Key, Arg: "*"}}, t)
  51. modes, unknown = ParseChannelModeChanges("-k", "beer")
  52. assertEqual(unknown, emptyUnknown, t)
  53. assertEqual(modes, ModeChanges{ModeChange{Op: Remove, Mode: Key, Arg: "*"}}, t)
  54. modes, unknown = ParseChannelModeChanges("+kb", "beer")
  55. assertEqual(unknown, emptyUnknown, t)
  56. assertEqual(modes, ModeChanges{
  57. ModeChange{Op: Add, Mode: Key, Arg: "beer"},
  58. ModeChange{Op: List, Mode: BanMask, Arg: ""},
  59. }, t)
  60. modes, unknown = ParseChannelModeChanges("-kb", "beer")
  61. assertEqual(unknown, emptyUnknown, t)
  62. assertEqual(modes, ModeChanges{
  63. ModeChange{Op: Remove, Mode: Key, Arg: "*"},
  64. ModeChange{Op: List, Mode: BanMask, Arg: ""},
  65. }, t)
  66. // "beer" is the ban arg, +k with no arg should be ignored
  67. modes, unknown = ParseChannelModeChanges("+bk", "beer")
  68. assertEqual(unknown, emptyUnknown, t)
  69. assertEqual(modes, ModeChanges{
  70. ModeChange{Op: Add, Mode: BanMask, Arg: "beer"},
  71. }, t)
  72. // "beer" is the ban arg again
  73. modes, unknown = ParseChannelModeChanges("-bk", "beer")
  74. assertEqual(unknown, emptyUnknown, t)
  75. assertEqual(modes, ModeChanges{
  76. ModeChange{Op: Remove, Mode: BanMask, Arg: "beer"},
  77. ModeChange{Op: Remove, Mode: Key, Arg: "*"},
  78. }, t)
  79. modes, unknown = ParseChannelModeChanges("+bk", "shivaram", "beer")
  80. assertEqual(unknown, emptyUnknown, t)
  81. assertEqual(modes, ModeChanges{
  82. ModeChange{Op: Add, Mode: BanMask, Arg: "shivaram"},
  83. ModeChange{Op: Add, Mode: Key, Arg: "beer"},
  84. }, t)
  85. modes, unknown = ParseChannelModeChanges("+kb", "beer", "shivaram")
  86. assertEqual(unknown, emptyUnknown, t)
  87. assertEqual(modes, ModeChanges{
  88. ModeChange{Op: Add, Mode: Key, Arg: "beer"},
  89. ModeChange{Op: Add, Mode: BanMask, Arg: "shivaram"},
  90. }, t)
  91. modes, unknown = ParseChannelModeChanges("-bk", "shivaram", "beer")
  92. assertEqual(unknown, emptyUnknown, t)
  93. assertEqual(modes, ModeChanges{
  94. ModeChange{Op: Remove, Mode: BanMask, Arg: "shivaram"},
  95. ModeChange{Op: Remove, Mode: Key, Arg: "*"},
  96. }, t)
  97. modes, unknown = ParseChannelModeChanges("-kb", "beer", "shivaram")
  98. assertEqual(unknown, emptyUnknown, t)
  99. assertEqual(modes, ModeChanges{
  100. ModeChange{Op: Remove, Mode: Key, Arg: "*"},
  101. ModeChange{Op: Remove, Mode: BanMask, Arg: "shivaram"},
  102. }, t)
  103. }
  104. func TestParseChannelModeChanges(t *testing.T) {
  105. modes, unknown := ParseChannelModeChanges("+h", "wrmsr")
  106. if len(unknown) > 0 {
  107. t.Errorf("unexpected unknown mode change: %v", unknown)
  108. }
  109. expected := ModeChange{
  110. Op: Add,
  111. Mode: Halfop,
  112. Arg: "wrmsr",
  113. }
  114. if len(modes) != 1 || modes[0] != expected {
  115. t.Errorf("unexpected mode change: %v", modes)
  116. }
  117. modes, unknown = ParseChannelModeChanges("-v", "shivaram")
  118. if len(unknown) > 0 {
  119. t.Errorf("unexpected unknown mode change: %v", unknown)
  120. }
  121. expected = ModeChange{
  122. Op: Remove,
  123. Mode: Voice,
  124. Arg: "shivaram",
  125. }
  126. if len(modes) != 1 || modes[0] != expected {
  127. t.Errorf("unexpected mode change: %v", modes)
  128. }
  129. modes, unknown = ParseChannelModeChanges("+tx")
  130. if len(unknown) != 1 || !unknown['x'] {
  131. t.Errorf("expected that x is an unknown mode, instead: %v", unknown)
  132. }
  133. expected = ModeChange{
  134. Op: Add,
  135. Mode: OpOnlyTopic,
  136. Arg: "",
  137. }
  138. if len(modes) != 1 || modes[0] != expected {
  139. t.Errorf("unexpected mode change: %v", modes)
  140. }
  141. modes, unknown = ParseChannelModeChanges("+b")
  142. if len(unknown) > 0 {
  143. t.Errorf("unexpected unknown mode change: %v", unknown)
  144. }
  145. // +b with no argument becomes a list operation
  146. expectedChanges := ModeChanges{{
  147. Op: List,
  148. Mode: BanMask,
  149. }}
  150. if !reflect.DeepEqual(modes, expectedChanges) {
  151. t.Errorf("unexpected mode change: %v instead of %v", modes, expectedChanges)
  152. }
  153. }
  154. func TestSetMode(t *testing.T) {
  155. set := NewModeSet()
  156. if applied := set.SetMode(Invisible, false); applied != false {
  157. t.Errorf("all modes should be false by default")
  158. }
  159. if applied := set.SetMode(Invisible, true); applied != true {
  160. t.Errorf("initial SetMode call should return true")
  161. }
  162. set.SetMode(Operator, true)
  163. if applied := set.SetMode(Invisible, true); applied != false {
  164. t.Errorf("redundant SetMode call should return false")
  165. }
  166. expected1 := []Mode{Invisible, Operator}
  167. expected2 := []Mode{Operator, Invisible}
  168. if allModes := set.AllModes(); !(reflect.DeepEqual(allModes, expected1) || reflect.DeepEqual(allModes, expected2)) {
  169. t.Errorf("unexpected AllModes value: %v", allModes)
  170. }
  171. if modeString := set.String(); !(modeString == "io" || modeString == "oi") {
  172. t.Errorf("unexpected modestring: %s", modeString)
  173. }
  174. }
  175. func TestModeString(t *testing.T) {
  176. set := NewModeSet()
  177. set.SetMode('A', true)
  178. set.SetMode('z', true)
  179. if modeString := set.String(); !(modeString == "Az" || modeString == "Za") {
  180. t.Errorf("unexpected modestring: %s", modeString)
  181. }
  182. }
  183. func TestNilReceivers(t *testing.T) {
  184. set := NewModeSet()
  185. set = nil
  186. if set.HasMode(Invisible) {
  187. t.Errorf("nil ModeSet should not have any modes")
  188. }
  189. str := set.String()
  190. if str != "" {
  191. t.Errorf("nil Modeset should have empty String(), got %v instead", str)
  192. }
  193. }
  194. func TestHighestChannelUserMode(t *testing.T) {
  195. set := NewModeSet()
  196. if set.HighestChannelUserMode() != Mode(0) {
  197. t.Errorf("no channel user modes should be present yet")
  198. }
  199. set.SetMode(Voice, true)
  200. if set.HighestChannelUserMode() != Voice {
  201. t.Errorf("should see that user is voiced")
  202. }
  203. set.SetMode(ChannelAdmin, true)
  204. if set.HighestChannelUserMode() != ChannelAdmin {
  205. t.Errorf("should see that user has channel admin")
  206. }
  207. set = nil
  208. if set.HighestChannelUserMode() != Mode(0) {
  209. t.Errorf("nil modeset should have the zero mode as highest channel-user mode")
  210. }
  211. }
  212. func TestChanmodesToken(t *testing.T) {
  213. tok := ChanmodesToken()
  214. for _, mode := range SupportedChannelModes {
  215. if strings.IndexRune(tok, rune(mode)) == -1 {
  216. t.Errorf("+%s not included in ChanmodesToken()", mode)
  217. }
  218. }
  219. }
  220. func TestModeChangesString(t *testing.T) {
  221. m := ModeChanges{
  222. ModeChange{Op: Add, Mode: RegisteredOnly},
  223. ModeChange{Op: Add, Mode: Key, Arg: "beer"},
  224. ModeChange{Op: Add, Mode: BanMask, Arg: "shivaram"},
  225. }
  226. assertEqual(m.Strings(), []string{"+Rkb", "beer", "shivaram"}, t)
  227. m = ModeChanges{
  228. ModeChange{Op: Add, Mode: RegisteredOnly},
  229. ModeChange{Op: Remove, Mode: Key, Arg: "beer"},
  230. ModeChange{Op: Add, Mode: BanMask, Arg: "shivaram"},
  231. }
  232. assertEqual(m.Strings(), []string{"+R-k+b", "beer", "shivaram"}, t)
  233. }
  234. func BenchmarkModeString(b *testing.B) {
  235. set := NewModeSet()
  236. set.SetMode('A', true)
  237. set.SetMode('N', true)
  238. set.SetMode('b', true)
  239. set.SetMode('i', true)
  240. set.SetMode('x', true)
  241. b.ResetTimer()
  242. for i := 0; i < b.N; i++ {
  243. _ = set.String()
  244. }
  245. }