ircparser 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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.