ruby_jid 1.0.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.
- 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:
|