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.

MessageParserTest.kt 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package com.dmdirc.ktirc.io
  2. import org.junit.jupiter.api.Assertions.*
  3. import org.junit.jupiter.api.Test
  4. import org.junit.jupiter.params.ParameterizedTest
  5. import org.junit.jupiter.params.provider.Arguments
  6. import org.junit.jupiter.params.provider.Arguments.arguments
  7. import org.junit.jupiter.params.provider.MethodSource
  8. import java.util.stream.Stream
  9. internal class MessageParserTest {
  10. companion object {
  11. @JvmStatic
  12. @Suppress("unused")
  13. fun ircMessageArgumentsProvider(): Stream<Arguments> = Stream.of(
  14. arguments("test", null, null, "test", emptyList<String>()),
  15. arguments("test 1 2", null, null, "test", listOf("1", "2")),
  16. arguments("test 1 2 ", null, null, "test", listOf("1", "2")),
  17. arguments("test :1 2", null, null, "test", listOf("1 2")),
  18. arguments("test :1 2 ", null, null, "test", listOf("1 2 ")),
  19. arguments("123 :1 2 ", null, null, "123", listOf("1 2 ")),
  20. arguments(":test abc 1 2 ", null, "test", "abc", listOf("1", "2")),
  21. arguments("@tags :test abc 1 2 :three four", "tags", "test", "abc", listOf("1", "2", "three four")),
  22. arguments("@tags abc 1 2 : three four ", "tags", null, "abc", listOf("1", "2", " three four "))
  23. )
  24. }
  25. @ParameterizedTest
  26. @MethodSource("ircMessageArgumentsProvider")
  27. fun `Parses IRC messages`(input: String, tags: String?, prefix: String?, command: String, params: List<String>) {
  28. val parsed = MessageParser().parse(input.toByteArray())
  29. assertEquals(tags, parsed.tags?.let { String(it) }) { "Expected '$input' to have tags '$tags'" }
  30. assertEquals(prefix, parsed.prefix?.let { String(it) }) { "Expected '$input' to have prefix '$prefix'" }
  31. assertEquals(command, parsed.command) { "Expected '$input' to have command '$command'" }
  32. assertEquals(params, parsed.params.map { String(it) }) { "Expected '$input' to have params '$params'" }
  33. }
  34. }
  35. internal class CursorByteArrayTest {
  36. @Test
  37. fun `Peek returns next byte without advancing cursor`() {
  38. val cursorByteArray = CursorByteArray(byteArrayOf(0x08, 0x09, 0x10))
  39. assertEquals(0x08, cursorByteArray.peek()) { "Peek should return the byte at the start" }
  40. assertEquals(0x08, cursorByteArray.peek()) { "Peek shouldn't advance the cursor" }
  41. cursorByteArray.cursor = 2
  42. assertEquals(0x10, cursorByteArray.peek()) { "Peek should return the byte at the current cursor" }
  43. cursorByteArray.cursor = 3
  44. assertThrows(ArrayIndexOutOfBoundsException::class.java, { cursorByteArray.peek() }) { "Peek should throw if cursor is out of bounds" }
  45. }
  46. @Test
  47. fun `Exhausted returns true when no more bytes available`() {
  48. val cursorByteArray = CursorByteArray(byteArrayOf(0x08, 0x09, 0x10))
  49. assertFalse(cursorByteArray.exhausted()) { "Exhausted should be false with a new array" }
  50. cursorByteArray.cursor = 1
  51. assertFalse(cursorByteArray.exhausted()) { "Exhausted should be false with an in-bound cursor" }
  52. cursorByteArray.cursor = 2
  53. assertFalse(cursorByteArray.exhausted()) { "Exhausted should be false at the last element" }
  54. cursorByteArray.cursor = 3
  55. assertTrue(cursorByteArray.exhausted()) { "Exhausted should be true when past the last element" }
  56. assertTrue(CursorByteArray(byteArrayOf()).exhausted()) { "Exhausted should be true on an empty array" }
  57. }
  58. @Test
  59. fun `TakeWord reads next word and advances cursor beyond trailing whitespace`() {
  60. val cursorByteArray = CursorByteArray("Hello this is a test".toByteArray())
  61. assertEquals("Hello", String(cursorByteArray.takeWord())) { "TakeWord should read first word" }
  62. assertEquals(6, cursorByteArray.cursor) { "TakeWord should advance cursor to next word" }
  63. assertEquals("this", String(cursorByteArray.takeWord())) { "TakeWord should read word at cursor" }
  64. assertEquals(14, cursorByteArray.cursor) { "TakeWord should advance cursor past trailing whitespace" }
  65. assertEquals("s", String(cursorByteArray.takeWord(1))) { "TakeWord should skip given number of bytes" }
  66. cursorByteArray.cursor = 22
  67. assertEquals("test", String(cursorByteArray.takeWord())) { "TakeWord should read word at end" }
  68. assertEquals(26, cursorByteArray.cursor) { "TakeWord should advance cursor past last word" }
  69. }
  70. @Test
  71. fun `TakeRemaining takes all remaining bytes and advances the cursor to exhaustion`() {
  72. var cursorByteArray = CursorByteArray("Test1234".toByteArray(), 4)
  73. assertEquals("1234", String(cursorByteArray.takeRemaining())) { "TakeRemaining should return remaining bytes" }
  74. assertEquals(8, cursorByteArray.cursor) { "TakeRemaining should advance cursor to end of array" }
  75. cursorByteArray = CursorByteArray("Test1234".toByteArray(), 0)
  76. assertEquals("est1234", String(cursorByteArray.takeRemaining(1))) { "TakeRemaining should skip specified number of bytes" }
  77. assertEquals(8, cursorByteArray.cursor) { "TakeRemaining should advance cursor to end of array when skipping" }
  78. }
  79. private fun byteArrayOf(vararg bytes: Byte) = ByteArray(bytes.size) { i -> bytes[i] }
  80. }