ruby_jid 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +25 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/Rakefile +13 -0
- data/lib/ruby_jid.rb +175 -0
- data/lib/ruby_jid/version.rb +3 -0
- data/ruby_jid.gemspec +28 -0
- data/spec/ruby_jid_spec.rb +197 -0
- data/spec/spec_helper.rb +21 -0
- metadata +181 -0
data/.gitignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Gem related stuff
|
2
|
+
*.gem
|
3
|
+
/pkg
|
4
|
+
/.bundle
|
5
|
+
/Gemfile.lock
|
6
|
+
/vendor
|
7
|
+
|
8
|
+
# Testing stuff
|
9
|
+
/coverage
|
10
|
+
/spec/reports
|
11
|
+
|
12
|
+
# RBX stuff
|
13
|
+
/.rbx/
|
14
|
+
|
15
|
+
# Editor temp/backup files
|
16
|
+
*~
|
17
|
+
.*.sw?
|
18
|
+
|
19
|
+
# General
|
20
|
+
/nbproject
|
21
|
+
.DS_Store
|
22
|
+
/.rvmrc
|
23
|
+
/.yardoc
|
24
|
+
/doc
|
25
|
+
/tmp
|
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2012 Ben Langfeld, NegativeCode, Jeff Smick
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
ruby_jid
|
2
|
+
===========
|
3
|
+
|
4
|
+
A Ruby representation of an XMPP JID. Provides parsing, validation & accessors.
|
5
|
+
|
6
|
+
Install
|
7
|
+
-------
|
8
|
+
|
9
|
+
gem install ruby_jid
|
10
|
+
|
11
|
+
Examples
|
12
|
+
--------
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'ruby_jid'
|
16
|
+
|
17
|
+
jid = RubyJID.new 'foo@bar.com'
|
18
|
+
jid.node # => "foo"
|
19
|
+
```
|
20
|
+
|
21
|
+
Author
|
22
|
+
------
|
23
|
+
|
24
|
+
Original authors: David Graham, Jeff Smick
|
25
|
+
|
26
|
+
Contributors:
|
27
|
+
|
28
|
+
* Ben Langfeld
|
29
|
+
|
30
|
+
Links
|
31
|
+
-----
|
32
|
+
* [Source](https://github.com/benlangfeld/ruby_jid)
|
33
|
+
* [Documentation](http://rdoc.info/github/benlangfeld/ruby_jid/master/frames)
|
34
|
+
* [Bug Tracker](https://github.com/benlangfeld/ruby_jid/issues)
|
35
|
+
|
36
|
+
Note on Patches/Pull Requests
|
37
|
+
-----------------------------
|
38
|
+
|
39
|
+
* Fork the project.
|
40
|
+
* Make your feature addition or bug fix.
|
41
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
42
|
+
* Commit, do not mess with rakefile, version, or history.
|
43
|
+
* If you want to have your own version, that is fine but bump version in a commit by itself so I can ignore when I pull
|
44
|
+
* Send me a pull request. Bonus points for topic branches.
|
45
|
+
|
46
|
+
Copyright
|
47
|
+
---------
|
48
|
+
|
49
|
+
Copyright (c) 2012 Ben Langfeld, NegativeCode, Jeff Smick. MIT licence (see LICENSE for details).
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
task :default => :spec
|
4
|
+
|
5
|
+
require 'rspec/core'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
9
|
+
spec.rspec_opts = '--color'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'yard'
|
13
|
+
YARD::Rake::YardocTask.new
|
data/lib/ruby_jid.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "ruby_jid/version"
|
4
|
+
|
5
|
+
# Jabber ID or JID
|
6
|
+
#
|
7
|
+
# See [RFC 3920 Section 3 - Addressing](http://xmpp.org/rfcs/rfc3920.html#addressing)
|
8
|
+
#
|
9
|
+
# An entity is anything that can be considered a network endpoint (i.e., an
|
10
|
+
# ID on the network) and that can communicate using XMPP. All such entities
|
11
|
+
# are uniquely addressable in a form that is consistent with RFC 2396 [URI].
|
12
|
+
# For historical reasons, the address of an XMPP entity is called a Jabber
|
13
|
+
# Identifier or JID. A valid JID contains a set of ordered elements formed
|
14
|
+
# of a domain identifier, node identifier, and resource identifier.
|
15
|
+
#
|
16
|
+
# The syntax for a JID is defined below using the Augmented Backus-Naur Form
|
17
|
+
# as defined in [ABNF]. (The IPv4address and IPv6address rules are defined
|
18
|
+
# in Appendix B of [IPv6]; the allowable character sequences that conform to
|
19
|
+
# the node rule are defined by the Nodeprep profile of [STRINGPREP] as
|
20
|
+
# documented in Appendix A of this memo; the allowable character sequences
|
21
|
+
# that conform to the resource rule are defined by the Resourceprep profile
|
22
|
+
# of [STRINGPREP] as documented in Appendix B of this memo; and the
|
23
|
+
# sub-domain rule makes reference to the concept of an internationalized
|
24
|
+
# domain label as described in [IDNA].)
|
25
|
+
#
|
26
|
+
# jid = [ node "@" ] domain [ "/" resource ]
|
27
|
+
# domain = fqdn / address-literal
|
28
|
+
# fqdn = (sub-domain 1*("." sub-domain))
|
29
|
+
# sub-domain = (internationalized domain label)
|
30
|
+
# address-literal = IPv4address / IPv6address
|
31
|
+
#
|
32
|
+
# All JIDs are based on the foregoing structure. The most common use of this
|
33
|
+
# structure is to identify an instant messaging user, the server to which
|
34
|
+
# the user connects, and the user's connected resource (e.g., a specific
|
35
|
+
# client) in the form of <user@host/resource>. However, node types other
|
36
|
+
# than clients are possible; for example, a specific chat room offered by a
|
37
|
+
# multi-user chat service could be addressed as <room@service> (where "room"
|
38
|
+
# is the name of the chat room and "service" is the hostname of the
|
39
|
+
# multi-user chat service) and a specific occupant of such a room could be
|
40
|
+
# addressed as <room@service/nick> (where "nick" is the occupant's room
|
41
|
+
# nickname). Many other JID types are possible (e.g., <domain/resource>
|
42
|
+
# could be a server-side script or service).
|
43
|
+
#
|
44
|
+
# Each allowable portion of a JID (node identifier, domain identifier, and
|
45
|
+
# resource identifier) MUST NOT be more than 1023 bytes in length, resulting
|
46
|
+
# in a maximum total size (including the '@' and '/' separators) of 3071
|
47
|
+
# bytes.
|
48
|
+
class RubyJID
|
49
|
+
include Comparable
|
50
|
+
|
51
|
+
PATTERN = /\A(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?\Z/.freeze
|
52
|
+
|
53
|
+
# http://tools.ietf.org/html/rfc6122#appendix-A
|
54
|
+
NODE_PREP = /[[:cntrl:] "&'\/:<>@]/.freeze
|
55
|
+
|
56
|
+
# http://tools.ietf.org/html/rfc3454#appendix-C
|
57
|
+
NAME_PREP = /[[:cntrl:] ]/.freeze
|
58
|
+
|
59
|
+
# http://tools.ietf.org/html/rfc6122#appendix-B
|
60
|
+
RESOURCE_PREP = /[[:cntrl:]]/.freeze
|
61
|
+
|
62
|
+
attr_reader :node, :domain, :resource
|
63
|
+
attr_writer :resource
|
64
|
+
|
65
|
+
# @private
|
66
|
+
def self.new(node, domain = nil, resource = nil)
|
67
|
+
node.is_a?(RubyJID) ? node : super
|
68
|
+
end
|
69
|
+
|
70
|
+
# Validate a JID
|
71
|
+
#
|
72
|
+
# @return [Boolean] true if a valid JID, otherwise false
|
73
|
+
def self.valid?(node, domain = nil, resource = nil)
|
74
|
+
!!new(node, domain, resource)
|
75
|
+
rescue ArgumentError
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
# Create a new JID object
|
80
|
+
#
|
81
|
+
# @overload initialize(jid)
|
82
|
+
# Passes the jid object right back out
|
83
|
+
# @param [RubyJID] jid a jid object
|
84
|
+
# @overload initialize(jid)
|
85
|
+
# Creates a new JID parsed out of the provided jid
|
86
|
+
# @param [String] jid a jid in the standard format
|
87
|
+
# ("node@domain/resource")
|
88
|
+
# @overload initialize(node, domain = nil, resource = nil)
|
89
|
+
# Creates a new JID
|
90
|
+
# @param [String] node the node of the JID
|
91
|
+
# @param [String, nil] domian the domain of the JID
|
92
|
+
# @param [String, nil] resource the resource of the JID
|
93
|
+
# @raise [ArgumentError] if the parts of the JID are too large (1023 bytes)
|
94
|
+
# @return [RubyJID] a new jid object
|
95
|
+
def initialize(node, domain = nil, resource = nil)
|
96
|
+
@node, @domain, @resource = node, domain, resource
|
97
|
+
|
98
|
+
if @domain.nil? && @resource.nil?
|
99
|
+
@node, @domain, @resource = @node.to_s.scan(PATTERN).first
|
100
|
+
end
|
101
|
+
@domain.downcase! if @domain
|
102
|
+
|
103
|
+
validate
|
104
|
+
end
|
105
|
+
|
106
|
+
# Strip the resource part from this JID and return it as a new
|
107
|
+
# JID object. The new JID contains only the optional node part
|
108
|
+
# and the required domain part from the original. This JID remains
|
109
|
+
# unchanged.
|
110
|
+
#
|
111
|
+
# @return [RubyJID] a new JID without a resource
|
112
|
+
def bare
|
113
|
+
RubyJID.new @node, @domain
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return true if this is a bare JID without a resource part.
|
117
|
+
def bare?
|
118
|
+
@resource.nil?
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return true if this is a domain-only JID without a node or resource part.
|
122
|
+
def domain?
|
123
|
+
!empty? && to_s == @domain
|
124
|
+
end
|
125
|
+
|
126
|
+
# Return true if this JID is equal to the empty string ''. That is, it's
|
127
|
+
# missing the node, domain, and resource parts that form a valid JID. It
|
128
|
+
# makes for easier error handling to be able to create JID objects from
|
129
|
+
# strings and then check if they're empty rather than nil.
|
130
|
+
def empty?
|
131
|
+
to_s == ''
|
132
|
+
end
|
133
|
+
|
134
|
+
def <=>(jid)
|
135
|
+
to_s.downcase <=> jid.to_s.downcase
|
136
|
+
end
|
137
|
+
|
138
|
+
def eql?(jid)
|
139
|
+
jid.is_a?(RubyJID) && self == jid
|
140
|
+
end
|
141
|
+
|
142
|
+
def hash
|
143
|
+
to_s.hash
|
144
|
+
end
|
145
|
+
|
146
|
+
# Turn the JID into a string
|
147
|
+
#
|
148
|
+
# * ""
|
149
|
+
# * "domain"
|
150
|
+
# * "node@domain"
|
151
|
+
# * "domain/resource"
|
152
|
+
# * "node@domain/resource"
|
153
|
+
#
|
154
|
+
# @return [String] the JID as a string
|
155
|
+
def to_s
|
156
|
+
s = @domain
|
157
|
+
s = "#{@node}@#{s}" if @node
|
158
|
+
s = "#{s}/#{@resource}" if @resource
|
159
|
+
s
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def validate
|
165
|
+
[@node, @domain, @resource].each do |part|
|
166
|
+
raise ArgumentError, 'jid too long' if (part || '').size > 1023
|
167
|
+
end
|
168
|
+
raise ArgumentError, 'empty node' if @node && @node.strip.empty?
|
169
|
+
raise ArgumentError, 'node contains invalid characters' if @node && @node =~ NODE_PREP
|
170
|
+
raise ArgumentError, 'empty resource' if @resource && @resource.strip.empty?
|
171
|
+
raise ArgumentError, 'resource contains invalid characters' if @resource && @resource =~ RESOURCE_PREP
|
172
|
+
raise ArgumentError, 'empty domain' if @domain == '' && (@node || @resource)
|
173
|
+
raise ArgumentError, 'domain contains invalid characters' if @domain && @domain =~ NAME_PREP
|
174
|
+
end
|
175
|
+
end
|
data/ruby_jid.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ruby_jid/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ruby_jid"
|
7
|
+
s.version = RubyJID::VERSION
|
8
|
+
s.authors = ["Ben Langfeld", "David Graham", "Jeff Smick"]
|
9
|
+
s.email = ["ben@langfeld.me"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{A Ruby representation of an XMPP JID}
|
12
|
+
s.description = %q{Provides parsing, validation & accessors}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ruby_jid"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency 'bundler', ["~> 1.0"]
|
22
|
+
s.add_development_dependency 'rspec', ["~> 2.8"]
|
23
|
+
s.add_development_dependency 'simplecov'
|
24
|
+
s.add_development_dependency 'simplecov-rcov'
|
25
|
+
s.add_development_dependency 'yard', ["~> 0.6"]
|
26
|
+
s.add_development_dependency 'rake'
|
27
|
+
s.add_development_dependency 'guard-rspec'
|
28
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RubyJID do
|
6
|
+
it 'handles empty input' do
|
7
|
+
[nil, ''].each do |text|
|
8
|
+
described_class.valid?(text).should be_true
|
9
|
+
jid = described_class.new text
|
10
|
+
jid.node.should be_nil
|
11
|
+
jid.resource.should be_nil
|
12
|
+
jid.domain.should be == ''
|
13
|
+
jid.to_s.should be == ''
|
14
|
+
jid.bare.to_s.should be == ''
|
15
|
+
jid.should be_empty
|
16
|
+
jid.should_not be_domain
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises when a jid part is too long' do
|
21
|
+
expect { described_class.new('n' * 1023) }.to_not raise_error
|
22
|
+
expect { described_class.new('n' * 1023, 'd' * 1023, 'r' * 1023) }.to_not raise_error
|
23
|
+
|
24
|
+
expect { described_class.new('n' * 1024) }.to raise_error(ArgumentError)
|
25
|
+
expect { described_class.new('n', 'd' * 1024) }.to raise_error(ArgumentError)
|
26
|
+
expect { described_class.new('n', 'd', 'r' * 1024) }.to raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'validates JID strings based on length' do
|
30
|
+
described_class.valid?('n' * 1023).should be_true
|
31
|
+
described_class.valid?('n' * 1023, 'd' * 1023, 'r' * 1023).should be_true
|
32
|
+
|
33
|
+
described_class.valid?('n' * 1024).should be_false
|
34
|
+
described_class.valid?('n', 'd' * 1024).should be_false
|
35
|
+
described_class.valid?('n', 'd', 'r' * 1024).should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'correctly handles domain only jids' do
|
39
|
+
described_class.valid?('wonderland.lit').should be_true
|
40
|
+
jid = described_class.new 'wonderland.lit'
|
41
|
+
jid.to_s.should be == 'wonderland.lit'
|
42
|
+
jid.domain.should be == 'wonderland.lit'
|
43
|
+
jid.node.should be_nil
|
44
|
+
jid.resource.should be_nil
|
45
|
+
jid.bare.should be == jid
|
46
|
+
jid.should be_domain
|
47
|
+
jid.should_not be_empty
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'correctly handles bare jid components' do
|
51
|
+
jid = described_class.new 'alice', 'wonderland.lit'
|
52
|
+
jid.to_s.should be == 'alice@wonderland.lit'
|
53
|
+
jid.domain.should be == 'wonderland.lit'
|
54
|
+
jid.node.should be == 'alice'
|
55
|
+
jid.resource.should be_nil
|
56
|
+
jid.bare.should be == jid
|
57
|
+
jid.should_not be_domain
|
58
|
+
jid.should_not be_empty
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'correctly parses bare jids' do
|
62
|
+
described_class.valid?('alice@wonderland.lit').should be_true
|
63
|
+
jid = described_class.new 'alice@wonderland.lit'
|
64
|
+
jid.to_s.should be == 'alice@wonderland.lit'
|
65
|
+
jid.domain.should be == 'wonderland.lit'
|
66
|
+
jid.node.should be == 'alice'
|
67
|
+
jid.resource.should be_nil
|
68
|
+
jid.bare.should be == jid
|
69
|
+
jid.should_not be_domain
|
70
|
+
jid.should_not be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'correctly handles full jid components' do
|
74
|
+
jid = described_class.new 'alice', 'wonderland.lit', 'tea'
|
75
|
+
jid.to_s.should be == 'alice@wonderland.lit/tea'
|
76
|
+
jid.domain.should be == 'wonderland.lit'
|
77
|
+
jid.node.should be == 'alice'
|
78
|
+
jid.resource.should be == 'tea'
|
79
|
+
jid.bare.should_not be == jid
|
80
|
+
jid.should_not be_domain
|
81
|
+
jid.should_not be_empty
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'correctly parses full jids' do
|
85
|
+
described_class.valid?('alice@wonderland.lit/tea').should be_true
|
86
|
+
jid = described_class.new 'alice@wonderland.lit/tea'
|
87
|
+
jid.to_s.should be == 'alice@wonderland.lit/tea'
|
88
|
+
jid.domain.should be == 'wonderland.lit'
|
89
|
+
jid.node.should be == 'alice'
|
90
|
+
jid.resource.should be == 'tea'
|
91
|
+
jid.bare.should_not be == jid
|
92
|
+
jid.should_not be_domain
|
93
|
+
jid.should_not be_empty
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'accepts separator characters in resource part' do
|
97
|
+
described_class.valid?('alice@wonderland.lit/foo/bar@blarg test').should be_true
|
98
|
+
jid = described_class.new 'alice@wonderland.lit/foo/bar@blarg test'
|
99
|
+
jid.node.should be == 'alice'
|
100
|
+
jid.domain.should be == 'wonderland.lit'
|
101
|
+
jid.resource.should be == 'foo/bar@blarg test'
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'accepts separator characters in resource part with missing node part' do
|
105
|
+
described_class.valid?('wonderland.lit/foo/bar@blarg').should be_true
|
106
|
+
jid = described_class.new 'wonderland.lit/foo/bar@blarg'
|
107
|
+
jid.node.should be_nil
|
108
|
+
jid.domain.should be == 'wonderland.lit'
|
109
|
+
jid.resource.should be == 'foo/bar@blarg'
|
110
|
+
jid.should_not be_domain
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'accepts strange characters in node part' do
|
114
|
+
string = %q{nasty!#$%()*+,-.;=?[\]^_`{|}~node@example.com}
|
115
|
+
described_class.valid?(string).should be_true
|
116
|
+
jid = described_class.new string
|
117
|
+
jid.node.should be == %q{nasty!#$%()*+,-.;=?[\]^_`{|}~node}
|
118
|
+
jid.domain.should be == 'example.com'
|
119
|
+
jid.resource.should be_nil
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'accepts strange characters in resource part' do
|
123
|
+
string = %q{node@example.com/repulsive !#"$%&'()*+,-./:;<=>?@[\]^_`{|}~resource}
|
124
|
+
described_class.valid?(string).should be_true
|
125
|
+
jid = described_class.new string
|
126
|
+
jid.node.should be == 'node'
|
127
|
+
jid.domain.should be == 'example.com'
|
128
|
+
jid.resource.should be == %q{repulsive !#"$%&'()*+,-./:;<=>?@[\]^_`{|}~resource}
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'maintains node and resource case, but downcases the domain' do
|
132
|
+
described_class.valid?("Foo@Bar.com/Baz").should be_true
|
133
|
+
jid = described_class.new "Foo@Bar.com/Baz"
|
134
|
+
jid.node.should be == 'Foo'
|
135
|
+
jid.domain.should be == 'bar.com'
|
136
|
+
jid.resource.should be == 'Baz'
|
137
|
+
jid.to_s.should be == 'Foo@bar.com/Baz'
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'compares case insensitively' do
|
141
|
+
jid1 = described_class.new "Foo@Bar.com/Baz"
|
142
|
+
jid2 = described_class.new "foo@bar.com/baz"
|
143
|
+
jid3 = described_class.new "Foo@Bar.com/other"
|
144
|
+
jid1.should be == jid2
|
145
|
+
jid1.should_not be == jid3
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'rejects empty jid parts' do
|
149
|
+
expect { described_class.new '@wonderland.lit' }.to raise_error(ArgumentError)
|
150
|
+
expect { described_class.new 'wonderland.lit/' }.to raise_error(ArgumentError)
|
151
|
+
expect { described_class.new '@' }.to raise_error(ArgumentError)
|
152
|
+
expect { described_class.new 'alice@' }.to raise_error(ArgumentError)
|
153
|
+
expect { described_class.new '/' }.to raise_error(ArgumentError)
|
154
|
+
expect { described_class.new '/res' }.to raise_error(ArgumentError)
|
155
|
+
expect { described_class.new '@/' }.to raise_error(ArgumentError)
|
156
|
+
end
|
157
|
+
|
158
|
+
let :invalid_jids do
|
159
|
+
[
|
160
|
+
%q{alice"s@wonderland.lit},
|
161
|
+
%q{alice&s@wonderland.lit},
|
162
|
+
%q{alice's@wonderland.lit},
|
163
|
+
%q{alice:s@wonderland.lit},
|
164
|
+
%q{alice<s@wonderland.lit},
|
165
|
+
%q{alice>s@wonderland.lit},
|
166
|
+
"alice\u0000s@wonderland.lit",
|
167
|
+
"alice\ts@wonderland.lit",
|
168
|
+
"alice\rs@wonderland.lit",
|
169
|
+
"alice\ns@wonderland.lit",
|
170
|
+
"alice\vs@wonderland.lit",
|
171
|
+
"alice\fs@wonderland.lit",
|
172
|
+
" alice@wonderland.lit",
|
173
|
+
"alice@wonderland.lit ",
|
174
|
+
"alice s@wonderland.lit",
|
175
|
+
"alice@w onderland.lit",
|
176
|
+
"alice@w\tonderland.lit",
|
177
|
+
"alice@w\ronderland.lit",
|
178
|
+
"alice@w\nonderland.lit",
|
179
|
+
"alice@w\vonderland.lit",
|
180
|
+
"alice@w\fonderland.lit",
|
181
|
+
"alice@w\u0000onderland.lit",
|
182
|
+
"alice@wonderland.lit/\u0000res"
|
183
|
+
]
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'rejects invalid characters' do
|
187
|
+
invalid_jids.each do |jid|
|
188
|
+
expect { described_class.new jid }.to raise_error(ArgumentError)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'validates invalid JID strings as false' do
|
193
|
+
invalid_jids.each do |jid|
|
194
|
+
described_class.valid?(jid).should be_false
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'simplecov-rcov'
|
3
|
+
class SimpleCov::Formatter::MergedFormatter
|
4
|
+
def format(result)
|
5
|
+
SimpleCov::Formatter::HTMLFormatter.new.format(result)
|
6
|
+
SimpleCov::Formatter::RcovFormatter.new.format(result)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
|
10
|
+
SimpleCov.start do
|
11
|
+
add_filter "/vendor/"
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'ruby_jid'
|
15
|
+
|
16
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.filter_run :focus => true
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_jid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ben Langfeld
|
9
|
+
- David Graham
|
10
|
+
- Jeff Smick
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-06-16 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: bundler
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.0'
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '1.0'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: rspec
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.8'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.8'
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: simplecov
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: simplecov-rcov
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
type: :development
|
73
|
+
prerelease: false
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: yard
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0.6'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ~>
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0.6'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: rake
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: guard-rspec
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
description: Provides parsing, validation & accessors
|
129
|
+
email:
|
130
|
+
- ben@langfeld.me
|
131
|
+
executables: []
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- .gitignore
|
136
|
+
- .rspec
|
137
|
+
- CHANGELOG.md
|
138
|
+
- Gemfile
|
139
|
+
- Guardfile
|
140
|
+
- LICENSE.txt
|
141
|
+
- README.md
|
142
|
+
- Rakefile
|
143
|
+
- lib/ruby_jid.rb
|
144
|
+
- lib/ruby_jid/version.rb
|
145
|
+
- ruby_jid.gemspec
|
146
|
+
- spec/ruby_jid_spec.rb
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
homepage: ''
|
149
|
+
licenses: []
|
150
|
+
post_install_message:
|
151
|
+
rdoc_options: []
|
152
|
+
require_paths:
|
153
|
+
- lib
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
segments:
|
161
|
+
- 0
|
162
|
+
hash: 500962306393099647
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ! '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
segments:
|
170
|
+
- 0
|
171
|
+
hash: 500962306393099647
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project: ruby_jid
|
174
|
+
rubygems_version: 1.8.24
|
175
|
+
signing_key:
|
176
|
+
specification_version: 3
|
177
|
+
summary: A Ruby representation of an XMPP JID
|
178
|
+
test_files:
|
179
|
+
- spec/ruby_jid_spec.rb
|
180
|
+
- spec/spec_helper.rb
|
181
|
+
has_rdoc:
|