ircparser 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5beae91923832297ad9f4005057e85283b072981
4
- data.tar.gz: 788844a68185df07bc39ab2106e7606dee8e43e4
2
+ SHA256:
3
+ metadata.gz: 3b3ba0c73061105629280badf2eda78d434a53c09bca59f77f73397740a6f062
4
+ data.tar.gz: b49d3de744a1fec6d9c9fabb17ca2df3c4416dc38f8d0afe953e9d0f4587d7b9
5
5
  SHA512:
6
- metadata.gz: 7ed4efc1b2e78605eb68f8b0a8964995d69d861a124f8342d2a759ac037daa43904c1ab7ff50d3f5a39d2c482482f3a6cd653da8b1bedd4e094f9345e2b36bf5
7
- data.tar.gz: d9c63829d0f9f462caedc2e285968b35096c3c8bb469c59dad73cb3536427da79e0e930d3d2fe722efaea77e27d30d8c6715b6d1290544fe4ed03096e895cc3c
6
+ metadata.gz: 04633fd5973f4b80cfdfa50b7c01c75683e9ecea0fe4e087c9d410d3a6cce649158eecc57e4902909fee8900031ebe50c3b5a6c9f070363120b711d762d29de8
7
+ data.tar.gz: fc2a8e5cadb156963f16743d857703c3bdf4900da0f86a18a9814e13ef52532282d7eee4ba7d1ee761439d46ee7107a62a5da1eb833de330ddc8bf7e33c22762
data/lib/ircparser.rb CHANGED
@@ -16,9 +16,11 @@
16
16
  module IRCParser
17
17
 
18
18
  # Public: The version of IRCParser in use.
19
- VERSION = '0.5.0'
19
+ VERSION = '0.6.0'
20
20
  end
21
21
 
22
22
  require_relative 'ircparser/error'
23
23
  require_relative 'ircparser/message'
24
24
  require_relative 'ircparser/prefix'
25
+ require_relative 'ircparser/stream'
26
+ require_relative 'ircparser/wire/rfc'
@@ -21,7 +21,7 @@ module IRCParser
21
21
  # Public: The value which failed to parse correctly.
22
22
  attr_reader :value
23
23
 
24
- # Public: Initialise a new parse error with the specified invalid value.
24
+ # Public: Initialises a new parse error with the specified invalid value.
25
25
  #
26
26
  # value - The value which failed to parse correctly.
27
27
  def initialize value
@@ -18,31 +18,24 @@ module IRCParser
18
18
  # Public: Represents an IRC message.
19
19
  class Message
20
20
 
21
- # Internal: A regular expression which matches a tag.
22
- MATCH_TAG = /^(?<name>[^\s=]+?)(?:=(?<value>[^\s;]+))?$/
23
-
24
- # Internal: The characters which need to be escaped in tag values.
25
- TAG_ESCAPES = {
26
- '\\' => '\\\\',
27
- ';' => '\:',
28
- "\s" => '\s',
29
- "\r" => '\r',
30
- "\n" => '\n'
31
- }
32
-
33
21
  # Public: Command name (e.g. PRIVMSG).
34
22
  attr_reader :command
35
23
 
36
24
  # Public: An array of command parameters.
37
25
  attr_reader :parameters
38
26
 
39
- # Public: The prefix of this command or nil if unprefixd.
27
+ # Public: The prefix of this command or nil if unprefixed.
40
28
  attr_reader :prefix
41
29
 
42
30
  # Public: A hash of IRCv3 message tags.
43
31
  attr_reader :tags
44
32
 
45
- # Public: Initialize a new message.
33
+ # Public: Initializes a new message.
34
+ #
35
+ # command - Command name (e.g. PRIVMSG).
36
+ # parameters - An array of command parameters.
37
+ # prefix - The prefix of this command or nil if unprefixed.
38
+ # tags - A hash of IRCv3 message tags.
46
39
  def initialize command: String.new, parameters: Array.new, prefix: nil, tags: Hash.new
47
40
  @command = command
48
41
  @parameters = parameters
@@ -50,163 +43,16 @@ module IRCParser
50
43
  @tags = tags
51
44
  end
52
45
 
53
- # Public: Parses an IRC message from network form.
46
+ # Public: Parses an IRC message from wire form.
54
47
  #
55
48
  # line - The line to attempt to parse.
56
49
  def self.parse line
57
-
58
- # Ruby really needs some kind of basic type checking.
59
- raise IRCParser::Error.new(line), "line is not a string" unless line.is_a? String
60
-
61
- # Split the message up into an array of tokens.
62
- buffer = line.clone
63
- current_token = __get_token buffer
64
- components = Hash.new
65
-
66
- # Have we encountered IRCv3 message tags?
67
- components[:tags] = Hash.new
68
- if current_token != nil && current_token[0] == '@'
69
- components[:tags] = __parse_tags current_token
70
- current_token = __get_token buffer
71
- end
72
-
73
- # Have we encountered the prefix of this message?
74
- if current_token != nil && current_token[0] == ':'
75
- components[:prefix] = IRCParser::Prefix.new current_token[1..-1]
76
- current_token = __get_token buffer
77
- end
78
-
79
- # The command parameter is mandatory.
80
- if current_token != nil
81
- components[:command] = current_token.upcase
82
- current_token = __get_final_token buffer
83
- else
84
- raise IRCParser::Error.new(line), 'message is missing the command name'
85
- end
86
-
87
- # Try to parse all of the remaining parameters.
88
- components[:parameters] = Array.new
89
- while current_token != nil
90
- components[:parameters] << current_token
91
- current_token = __get_final_token buffer
92
- end
93
-
94
- return IRCParser::Message.new components
50
+ return IRCParser::RFCWireFormat.objectify line.clone
95
51
  end
96
52
 
97
-
98
53
  # Public: Serializes the message to a string.
99
54
  def to_s
100
- buffer = String.new
101
-
102
- # Serialize the tags.
103
- unless tags.empty?
104
- buffer += '@'
105
- buffer += __serialize_tags
106
- buffer += ' '
107
- end
108
-
109
- # Serialize the prefix.
110
- unless prefix.nil?
111
- buffer += ':'
112
- buffer += prefix.to_s
113
- buffer += ' '
114
- end
115
-
116
- # Serialize the command.
117
- buffer += command
118
-
119
- # Serialize the parameters
120
- buffer += __serialize_parameters
121
-
122
- # We're done!
123
- return buffer
124
- end
125
-
126
- private
127
-
128
- # Internal: Retrieves a space delimited token from the buffer.
129
- #
130
- # data - The buffer to retrieve the token from.
131
- def self.__get_token buffer
132
- return nil if buffer.empty?
133
- position = buffer.index ' '
134
- if position == nil
135
- token = buffer.clone
136
- buffer.clear
137
- return token
138
- end
139
- token = buffer.slice! 0...position
140
- position = buffer.index /\S+/
141
- if position == nil
142
- buffer.clear
143
- else
144
- buffer.slice! 0...position
145
- end
146
- return token
147
- end
148
-
149
- # Internal: Retrieves a space delimited token that may be a <trailing> parameter.
150
- #
151
- # data - The buffer to retrieve the token from.
152
- def self.__get_final_token buffer
153
- return nil if buffer.empty?
154
- if buffer[0] == ':'
155
- token = buffer[1..-1]
156
- buffer.clear
157
- return token
158
- end
159
- return __get_token buffer
160
- end
161
-
162
- # Internal: Parse tags from network form to a Hash.
163
- #
164
- # token - A list of tags in network form.
165
- def self.__parse_tags token
166
- tags = Hash.new
167
- token[1..-1].split(';').each do |tag|
168
- if tag =~ MATCH_TAG
169
- name, value = $~['name'], $~['value']
170
- TAG_ESCAPES.each do |unescaped, escaped|
171
- value.gsub! escaped, unescaped
172
- end unless value.nil?
173
- tags[name] = value
174
- else
175
- raise IRCParser::Error.new(tag), "tag is malformed"
176
- end
177
- end
178
- return tags
179
- end
180
-
181
- # Internal: Serializes parameters from an Array to network form.
182
- def __serialize_parameters
183
- buffer = String.new
184
- @parameters.each_with_index do |parameter, index|
185
- trailing = parameter.include? ' '
186
- if trailing && index != @parameters.size-1
187
- raise IRCParser::Error.new(parameter), "only the last parameter may contain spaces"
188
- end
189
-
190
- buffer += ' '
191
- if trailing || parameter.empty?
192
- buffer += ':'
193
- buffer += parameter
194
- break
195
- end
196
- buffer += parameter
197
- end
198
- return buffer
199
- end
200
-
201
- # Internal: Serializes tags from a Hash to network form.
202
- def __serialize_tags
203
- buffer = @tags.dup.map do |key, value|
204
- TAG_ESCAPES.each do |unescaped, escaped|
205
- value.gsub! unescaped, Regexp.escape(escaped)
206
- end unless value.nil?
207
- value.nil? ? key : key + '=' + value
208
- end.join ';'
209
- return buffer
55
+ return IRCParser::RFCWireFormat.stringify self.clone
210
56
  end
211
57
  end
212
58
  end
@@ -18,9 +18,6 @@ module IRCParser
18
18
  # Public: Represents the prefix of an IRC message.
19
19
  class Prefix
20
20
 
21
- # Internal: A regular expression which matches a n!u@h mask.
22
- MATCH_PREFIX = /^(?<nick>[^@!]+) (?:!(?<user>[^@]+))? (?:@(?<host>.+))?$/x
23
-
24
21
  # Public: The hostname of this prefix or nil if no hostname was given.
25
22
  attr_reader :host
26
23
 
@@ -30,25 +27,15 @@ module IRCParser
30
27
  # Public: The username of this prefix or nil if no username was given.
31
28
  attr_reader :user
32
29
 
33
- # Public: Initialise a new message prefix from a serialised prefix.
30
+ # Public: Initialises a new message prefix.
34
31
  #
35
- # prefix - Either a n!u@h mask or a server name.
36
- def initialize prefix
37
- if MATCH_PREFIX =~ prefix
38
- @nick = $~[:nick]
39
- @user = $~[:user]
40
- @host = $~[:host]
41
- else
42
- raise IRCParser::Error.new(prefix), 'prefix is not a user mask or server name'
43
- end
44
- end
45
-
46
- # Public: serialises this prefix to the network form.
47
- def to_s
48
- buffer = @nick
49
- buffer += "!#{@user}" unless @user.nil?
50
- buffer += "@#{@host}" unless @host.nil?
51
- return buffer
32
+ # nick - The nickname of this user.
33
+ # user - The username of this prefix or nil if no username was given.
34
+ # host - The hostname of this prefix or nil if no hostname was given.
35
+ def initialize nick: nil, user: nil, host: nil
36
+ @nick = nick
37
+ @user = user
38
+ @host = host
52
39
  end
53
40
  end
54
41
  end
@@ -0,0 +1,46 @@
1
+ # IRCParser - Internet Relay Chat Message Parser
2
+ #
3
+ # Copyright (C) 2015-2017 Peter "SaberUK" Powell <petpow@saberuk.com>
4
+ #
5
+ # Permission to use, copy, modify, and/or distribute this software for any purpose with or without
6
+ # fee is hereby granted, provided that the above copyright notice and this permission notice appear
7
+ # in all copies.
8
+ #
9
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
10
+ # SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
11
+ # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
13
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
14
+ # OF THIS SOFTWARE.
15
+
16
+ module IRCParser
17
+
18
+ # Public: Parses IRC messages from a stream of data.
19
+ class Stream
20
+
21
+ # Public: The contents of the stream buffer.
22
+ attr_reader :buffer
23
+
24
+ # Public: The block which is called when a message is parsed.
25
+ attr_reader :block
26
+
27
+ # Public: Initialize a new stream.
28
+ def initialize &block
29
+ unless block.is_a? Proc
30
+ raise TypeError, "Wrong argument type #{block.class} (expected Proc)"
31
+ end
32
+ @block = block
33
+ end
34
+
35
+ # Public: Appends data to the stream buffer.
36
+ #
37
+ # data - The data to append.
38
+ def append data
39
+ (@buffer ||= '') << data
40
+ while @buffer.slice! /(.*?)\r?\n/
41
+ message = IRCParser::Message.parse $1
42
+ @block.call message
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,248 @@
1
+ # IRCParser - Internet Relay Chat Message Parser
2
+ #
3
+ # Copyright (C) 2015-2017 Peter "SaberUK" Powell <petpow@saberuk.com>
4
+ #
5
+ # Permission to use, copy, modify, and/or distribute this software for any purpose with or without
6
+ # fee is hereby granted, provided that the above copyright notice and this permission notice appear
7
+ # in all copies.
8
+ #
9
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
10
+ # SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
11
+ # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
13
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
14
+ # OF THIS SOFTWARE.
15
+
16
+ module IRCParser
17
+
18
+ # Internal: Implements objectification and stringification for the RFC wire format.
19
+ module RFCWireFormat
20
+
21
+ # Internal: Objectifies a message from the RFC wire format to an IRCParser::Message.
22
+ #
23
+ # str - A String containing a message in the RFC wire format.
24
+ def self.objectify str
25
+
26
+ # Ruby really needs some kind of basic type checking.
27
+ unless str.is_a? String
28
+ raise IRCParser::Error.new(line), "message is not a string"
29
+ end
30
+
31
+ # Split the message up into an array of tokens.
32
+ current_token = self.__get_token str
33
+ components = Hash.new
34
+
35
+ # Have we encountered IRCv3 message tags?
36
+ components[:tags] = Hash.new
37
+ if current_token != nil && current_token[0] == '@'
38
+ components[:tags] = self.__objectify_tags current_token
39
+ current_token = self.__get_token str
40
+ end
41
+
42
+ # Have we encountered the prefix of this message?
43
+ if current_token != nil && current_token[0] == ':'
44
+ components[:prefix] = self.__objectify_prefix current_token
45
+ current_token = self.__get_token str
46
+ end
47
+
48
+ # The command parameter is mandatory.
49
+ if current_token != nil
50
+ components[:command] = current_token.upcase
51
+ current_token = self.__get_final_token str
52
+ else
53
+ raise IRCParser::Error.new(line), 'message is missing the command name'
54
+ end
55
+
56
+ # Try to parse all of the remaining parameters.
57
+ components[:parameters] = Array.new
58
+ while current_token != nil
59
+ components[:parameters] << current_token
60
+ current_token = self.__get_final_token str
61
+ end
62
+
63
+ return IRCParser::Message.new components
64
+ end
65
+
66
+ # Internal: Stringifies a message from an IRCParser::Message to the RFC wire format.
67
+ #
68
+ # obj - An IRCParser::Message to stringify to the RFC wire format.
69
+ def self.stringify obj
70
+
71
+ # Ruby really needs some kind of basic type checking.
72
+ unless obj.is_a? IRCParser::Message
73
+ raise IRCParser::Error.new(obj), "message is not an IRCParser::Message"
74
+ end
75
+
76
+ # Stringify the tags.
77
+ buffer = String.new
78
+ unless obj.tags.empty?
79
+ buffer += '@'
80
+ buffer += self.__stringify_tags obj.tags
81
+ buffer += ' '
82
+ end
83
+
84
+ # Stringify the prefix.
85
+ unless obj.prefix.nil?
86
+ buffer += ':'
87
+ buffer += self.__stringify_prefix obj.prefix
88
+ buffer += ' '
89
+ end
90
+
91
+ # Stringify the command.
92
+ buffer += obj.command
93
+
94
+ # Stringify the parameters
95
+ buffer += self.__stringify_parameters obj.parameters
96
+
97
+ # We're done!
98
+ return buffer
99
+ end
100
+
101
+ private
102
+
103
+ # Internal: A regular expression which matches a n!u@h mask.
104
+ MATCH_PREFIX = /^:(?<nick>[^@!]+) (?:!(?<user>[^@]+))? (?:@(?<host>.+))?$/x
105
+
106
+ # Internal: A regular expression which matches a tag.
107
+ MATCH_TAG = /^(?<name>[^\s=]+?)(?:=(?<value>[^\s;]+))?$/
108
+
109
+ # Internal: The characters which need to be escaped in tag values.
110
+ TAG_ESCAPES = {
111
+ '\\\\' => '\\',
112
+ '\:' => ';',
113
+ '\s' => "\s",
114
+ '\r' => "\r",
115
+ '\n' => "\n",
116
+ }
117
+
118
+ # Internal: Retrieves a space delimited token from the buffer.
119
+ #
120
+ # buffer - The buffer to retrieve the token from.
121
+ def self.__get_token buffer
122
+ return nil if buffer.empty?
123
+ position = buffer.index ' '
124
+ if position == nil
125
+ token = buffer.clone
126
+ buffer.clear
127
+ return token
128
+ end
129
+ token = buffer.slice! 0...position
130
+ position = buffer.index /\S+/
131
+ if position == nil
132
+ buffer.clear
133
+ else
134
+ buffer.slice! 0...position
135
+ end
136
+ return token
137
+ end
138
+
139
+ # Internal: Retrieves a space delimited token that may be a <trailing> parameter.
140
+ #
141
+ # buffer - The buffer to retrieve the token from.
142
+ def self.__get_final_token buffer
143
+ return nil if buffer.empty?
144
+ if buffer[0] == ':'
145
+ token = buffer[1..-1]
146
+ buffer.clear
147
+ return token
148
+ end
149
+ return self.__get_token buffer
150
+ end
151
+
152
+ # Internal: Objectifies the prefix from the RFC wire format to an IRCParser::Prefix.
153
+ #
154
+ # token - A String containing the prefix in the RFC wire format.
155
+ def self.__objectify_prefix prefix
156
+ unless MATCH_PREFIX =~ prefix
157
+ raise IRCParser::Error.new(prefix), 'prefix is not a user mask or server name'
158
+ end
159
+ return IRCParser::Prefix.new nick: $~[:nick], user: $~[:user], host: $~[:host]
160
+ end
161
+
162
+ # Internal: Objectifies tags from the RFC wire format to a Hash.
163
+ #
164
+ # token - A String containing tags in the RFC wire format.
165
+ def self.__objectify_tags token
166
+ tags = Hash.new
167
+ token[1..-1].split(';').each do |tag|
168
+ if tag =~ MATCH_TAG
169
+ value = nil
170
+ value_index = 0
171
+ while $~['value'] != nil && value_index < $~['value'].size
172
+ value ||= String.new
173
+ if $~['value'][value_index] == '\\'
174
+ escape = $~['value'].slice(value_index, 2)
175
+ if TAG_ESCAPES.include? escape
176
+ value += TAG_ESCAPES[escape]
177
+ value_index += 1
178
+ end
179
+ else
180
+ value += $~['value'][value_index]
181
+ end
182
+ value_index += 1
183
+ end
184
+ tags[$~['name']] = value
185
+ else
186
+ raise IRCParser::Error.new(tag), 'tag is malformed'
187
+ end
188
+ end
189
+ return tags
190
+ end
191
+
192
+ # Internal: Stringifies parameters from an Array to the RFC wire format.
193
+ #
194
+ # parameters - An Array to stringify to the RFC wire format.
195
+ def self.__stringify_parameters parameters
196
+ buffer = String.new
197
+ parameters.each_with_index do |parameter, index|
198
+ trailing = parameter.include? ' '
199
+ if trailing && index != parameters.size-1
200
+ raise IRCParser::Error.new(parameter), 'only the last parameter may contain spaces'
201
+ end
202
+
203
+ buffer += ' '
204
+ if trailing || parameter.empty?
205
+ buffer += ':'
206
+ buffer += parameter
207
+ break
208
+ end
209
+ buffer += parameter
210
+ end
211
+ return buffer
212
+ end
213
+
214
+ # Internal: Stringifies the prefix from an IRCParser::Prefix to the RFC wire format.
215
+ #
216
+ # tags - An IRCParser::Prefix to stringify to the RFC wire format.
217
+ def self.__stringify_prefix prefix
218
+ buffer = prefix.nick
219
+ buffer += "!#{prefix.user}" unless prefix.user.nil?
220
+ buffer += "@#{prefix.host}" unless prefix.host.nil?
221
+ return buffer
222
+ end
223
+
224
+ # Internal: Stringifies tags from a Hash to the RFC wire format.
225
+ #
226
+ # tags - A Hash of tags to stringify to the RFC wire format.
227
+ def self.__stringify_tags tags
228
+ buffer = String.new
229
+ tags.each.with_index do |tag, idx|
230
+ key, value = tag
231
+ buffer += key
232
+ unless value.nil?
233
+ buffer += '='
234
+ value.each_char do |chr|
235
+ if TAG_ESCAPES.has_value? chr
236
+ buffer += TAG_ESCAPES.key chr
237
+ else
238
+ buffer += chr
239
+ end
240
+ end
241
+ end
242
+ buffer += ';' if idx < tags.size - 1
243
+ end
244
+ return buffer
245
+ end
246
+
247
+ end
248
+ end
data/test/test_message.rb CHANGED
@@ -168,6 +168,31 @@ describe IRCParser::Message do
168
168
  end
169
169
  end
170
170
 
171
+ describe 'when checking we can handle parsing malformed tags' do
172
+ before do
173
+ @text = '@foo=wibble\Zwobble\\ COMMAND'
174
+ @message = IRCParser::Message.parse @text
175
+ end
176
+ it 'should strip invalid and trailing escapes' do
177
+ @message.tags['foo'].must_equal 'wibbleZwobble'
178
+ end
179
+ it 'should serialise back to a well formed value' do
180
+ @message.to_s.must_equal '@foo=wibbleZwobble COMMAND'
181
+ end
182
+ end
183
+
184
+ describe 'when checking we can handle serialising without creating malformed tags' do
185
+ before do
186
+ @tags = {
187
+ 'foo' => 'wibble\Zwobble\\'
188
+ }
189
+ @message = IRCParser::Message.new tags: @tags, command: 'COMMAND'
190
+ end
191
+ it 'should serialise without creating malformed tags' do
192
+ @message.to_s.must_equal '@foo=wibble\\\\Zwobble\\\\ COMMAND'
193
+ end
194
+ end
195
+
171
196
  describe 'when checking we can handle serialising malformed parameters' do
172
197
  it 'should throw an IRCParser::Error when a non <trailing> parameter contains spaces' do
173
198
  proc {
data/test/test_prefix.rb CHANGED
@@ -20,41 +20,70 @@ require 'minitest/autorun'
20
20
 
21
21
  describe IRCParser::Prefix do
22
22
  PREFIXES = {
23
- 'nick!user@host' => { nick: 'nick', user: 'user', host: 'host' },
24
- 'nick!user' => { nick: 'nick', user: 'user', host: nil },
25
- 'nick@host' => { nick: 'nick', user: nil, host: 'host' },
26
- 'nick' => { nick: 'nick', user: nil, host: nil },
27
- 'irc.example.com' => { nick: 'irc.example.com', user: nil, host: nil },
23
+ 'nick!user@host' => {
24
+ nick: 'nick',
25
+ user: 'user',
26
+ host: 'host'
27
+ },
28
+ 'nick!user' => {
29
+ nick: 'nick',
30
+ user: 'user',
31
+ host: nil
32
+ },
33
+ 'nick@host' => {
34
+ nick: 'nick',
35
+ user: nil,
36
+ host: 'host'
37
+ },
38
+ 'nick' => {
39
+ nick: 'nick',
40
+ user: nil,
41
+ host: nil
42
+ },
43
+ 'irc.example.com' => {
44
+ nick: 'irc.example.com',
45
+ user: nil,
46
+ host: nil
47
+ },
28
48
  }
29
49
 
30
50
  PREFIXES.each do |serialized, deserialized|
31
51
  describe 'when checking a valid prefix' do
32
52
  before do
33
- @prefix = IRCParser::Prefix.new serialized
53
+ @text = ":#{serialized} COMMAND"
54
+ @message = IRCParser::Message.parse @text
34
55
  end
35
56
  it 'should consist of the correct components' do
36
57
  %i(nick user host).each do |component|
37
58
  if deserialized[component].nil?
38
- @prefix.send(component).must_be_nil
59
+ @message.prefix.send(component).must_be_nil
39
60
  else
40
- @prefix.send(component).must_equal deserialized[component]
61
+ @message.prefix.send(component).must_equal deserialized[component]
41
62
  end
42
63
  end
43
64
  end
44
65
  it 'should serialise back to the same text' do
45
- @prefix.to_s.must_equal serialized
66
+ @message.to_s.must_equal @text
46
67
  end
47
68
  end
48
69
  end
49
70
 
50
- describe 'when checking an invalid user prefix' do
51
- it 'should throw an IRCParser::Error when components are missing' do
52
- proc { IRCParser::Prefix.new 'nick!@' }.must_raise IRCParser::Error
53
- proc { IRCParser::Prefix.new '!user@' }.must_raise IRCParser::Error
54
- proc { IRCParser::Prefix.new '!@host' }.must_raise IRCParser::Error
55
- proc { IRCParser::Prefix.new 'nick!user@' }.must_raise IRCParser::Error
56
- proc { IRCParser::Prefix.new 'nick!@host' }.must_raise IRCParser::Error
57
- proc { IRCParser::Prefix.new '!user@host' }.must_raise IRCParser::Error
71
+ MALFORMED = [
72
+ 'nick!@',
73
+ '!user@',
74
+ '!@host',
75
+ 'nick!user@',
76
+ 'nick!@host',
77
+ '!user@host',
78
+ ]
79
+
80
+ MALFORMED.each do |prefix|
81
+ describe 'when checking an invalid user prefix' do
82
+ it 'should throw an IRCParser::Error when components are missing' do
83
+ proc {
84
+ IRCParser::Message.parse ":#{prefix} COMMAND"
85
+ }.must_raise IRCParser::Error
86
+ end
58
87
  end
59
88
  end
60
89
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ircparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter "SaberUK" Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-04 00:00:00.000000000 Z
11
+ date: 2018-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -68,6 +68,8 @@ files:
68
68
  - lib/ircparser/error.rb
69
69
  - lib/ircparser/message.rb
70
70
  - lib/ircparser/prefix.rb
71
+ - lib/ircparser/stream.rb
72
+ - lib/ircparser/wire/rfc.rb
71
73
  - test/test_message.rb
72
74
  - test/test_prefix.rb
73
75
  homepage: https://github.com/SaberUK/ircparser
@@ -90,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
92
  version: '0'
91
93
  requirements: []
92
94
  rubyforge_project:
93
- rubygems_version: 2.6.12
95
+ rubygems_version: 2.7.5
94
96
  signing_key:
95
97
  specification_version: 4
96
98
  summary: An IRCv3 message parser.