urn 0.1.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -6
  3. data/lib/urn.rb +7 -6
  4. data/spec/urn_spec.rb +49 -18
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 876d68aec7c174c18b549b705653e20e49b8c14a
4
- data.tar.gz: 001402f4e00c733303f7631bdd6c1313750935ba
3
+ metadata.gz: f729f3390ecec4c9843f007a1be16632ca7b1516
4
+ data.tar.gz: b85858036290b073d73ddca76076f59fe4e9476e
5
5
  SHA512:
6
- metadata.gz: d69b2ea6ebb2c5b8b99165dbcbb626caef56fa3ee13260e09b320651dec79d655c085d2b71b72b6b13036ad534003c26d98f6ab4d2fa22fe2d640b21736a3544
7
- data.tar.gz: 3b4ccc977ad5f9c41001afdff892f03a67bb68c948c0c4d45c2bff0f950b7380f1b8bde314e55fcf2875b1941ca94b2e81ae1bf0612c75768ba6fde8e643e093
6
+ metadata.gz: 69b2624baef7186d9c1f4beea2fe468a01eb3c85134647a8b30761b46d3ce51a27bf2fa8d054744ff206a76010361a3b5eb39e6ba9e2551ef8d442da6aed82cc
7
+ data.tar.gz: 3ace937ef1827b479377959d3bba1b7ebf87ff31690b18ad359571a4d59c15c73e3a2edfc09f69690ec548b47fa0458cf0e84c7ecefc54e09e9e166e7cbf5e85
data/README.md CHANGED
@@ -2,14 +2,15 @@
2
2
 
3
3
  Ruby library to validate and normalize URNs.
4
4
 
5
- Note: This Gem doesn't strictly follow the [RFC2141](https://www.ietf.org/rfc/rfc2141.txt)
5
+ **Current version:** 0.1.3
6
+ **Supported Ruby versions:** 1.8.7, 1.9.2, 1.9.3, 2.0, 2.1, 2.2, 2.3
6
7
 
7
8
  ## Installation
8
9
 
9
- Add this line to your application's Gemfile:
10
+ Add this line to your application's `Gemfile`:
10
11
 
11
12
  ```ruby
12
- gem 'urn'
13
+ gem 'urn', '~> 0.1'
13
14
  ```
14
15
 
15
16
  And then execute:
@@ -18,7 +19,7 @@ And then execute:
18
19
 
19
20
  Or install it yourself as:
20
21
 
21
- $ gem install urn
22
+ $ gem install urn -v '~> 0.1'
22
23
 
23
24
  ## Usage
24
25
 
@@ -33,13 +34,54 @@ urn.normalize
33
34
  #=> "urn:namespace:Identifier"
34
35
  ```
35
36
 
37
+ ## API Documentation
38
+
39
+ ### `URN::PATTERN`
40
+
41
+ ```ruby
42
+ text.match(/\?urn=(#{URN::PATTERN})/)
43
+ ```
44
+
45
+ Return a `String` of an unanchored regular expression suitable for matching
46
+ URNs.
47
+
48
+ ### `URN.new`
49
+
50
+ ```ruby
51
+ urn = URN.new('urn:nid:nss')
52
+ #=> #<URN:0xdecafbad @urn="urn:nid:nss">
53
+ ```
54
+
55
+ Return a new `URN` instance with the given string.
56
+
57
+ ### `URN#valid?`
58
+
59
+ ```ruby
60
+ URN.new('foo').valid?
61
+ #=> false
62
+
63
+ URN.new('urn:foo:bar').valid?
64
+ #=> true
65
+ ```
66
+
67
+ Returns true if the `URN` is valid according to [RFC 2141](https://www.ietf.org/rfc/rfc2141.txt).
68
+
69
+ ### `URN#normalize`
70
+
71
+ ```ruby
72
+ URN.new('URN:FOO:BAR').normalize
73
+ #=> "urn:foo:BAR"
74
+ ```
75
+
76
+ Return a normalized `String` representation of the `URN`, normalizing the case
77
+ of the `urn` token and namespace identifier.
78
+
36
79
  ## Contributing
37
80
 
38
81
  Bug reports and pull requests are welcome on GitHub at https://github.com/altmetric/urn.
39
82
 
40
-
41
83
  ## License
42
84
 
43
- Copyright © 2015-2016 Altmetric LLP
85
+ Copyright © 2016 Altmetric LLP
44
86
 
45
87
  Distributed under the [MIT License](http://opensource.org/licenses/MIT).
data/lib/urn.rb CHANGED
@@ -1,8 +1,7 @@
1
- require 'cgi'
2
-
3
1
  class URN
4
- PATTERN = 'urn:(?!urn:)[a-z0-9\-]{1,31}:[\S]+'.freeze
5
- REGEX = /^#{PATTERN}$/i
2
+ PATTERN = %{(?i:urn:(?!urn:)[a-z0-9][a-z0-9\-]{1,31}:} +
3
+ %{(?:[a-z0-9()+,-.:=@;$_!*']|%[0-9a-f]{2})+)}.freeze
4
+ REGEX = /\A#{PATTERN}\z/
6
5
 
7
6
  attr_reader :urn
8
7
  private :urn
@@ -18,8 +17,10 @@ class URN
18
17
  def normalize
19
18
  return unless valid?
20
19
 
21
- urn_parts = urn.split(':', 3)
20
+ _scheme, nid, nss = urn.split(':', 3)
21
+ normalized_nid = nid.downcase
22
+ normalized_nss = nss.gsub(/%([0-9a-f]{2})/i) { |hex| hex.downcase }
22
23
 
23
- "#{urn_parts[0].downcase}:#{urn_parts[1].downcase}:#{CGI.unescape(urn_parts[2])}"
24
+ "urn:#{normalized_nid}:#{normalized_nss}"
24
25
  end
25
26
  end
@@ -1,35 +1,66 @@
1
+ # encoding: utf-8
1
2
  require 'urn'
2
3
 
3
4
  RSpec.describe URN do
4
5
  describe '#valid?' do
5
- context 'returns true' do
6
- it 'if it is valid' do
7
- expect(described_class.new('urn:namespace:specificstring')).to be_valid
8
- end
6
+ it 'returns true if it is valid' do
7
+ expect(described_class.new('urn:namespace:specificstring')).to be_valid
8
+ end
9
9
 
10
- it 'if namespace includes urn' do
11
- expect(described_class.new('urn:urnnamespace:specificstring')).to be_valid
12
- end
10
+ it 'returns true if namespace includes urn' do
11
+ expect(described_class.new('urn:urnnamespace:specificstring')).to be_valid
13
12
  end
14
13
 
15
- context 'returns false' do
16
- it 'if it does not start with urn' do
17
- expect(described_class.new('not-urn:namespace:specificstring')).not_to be_valid
18
- end
14
+ it 'returns false if it does not start with urn' do
15
+ expect(described_class.new('not-urn:namespace:specificstring')).not_to be_valid
16
+ end
19
17
 
20
- it 'if namespace is urn' do
21
- expect(described_class.new('urn:urn:specificstring')).not_to be_valid
22
- end
18
+ it 'returns false if namespace is urn' do
19
+ expect(described_class.new('urn:urn:specificstring')).not_to be_valid
23
20
  end
24
- end
25
21
 
26
- describe '#normalize' do
27
- it 'lowercases the urn and namespace identifier parts only' do
28
- expect(described_class.new('URN:NameSpace:SpecificString').normalize).to eq('urn:namespace:SpecificString')
22
+ it 'returns false if namespace is URN' do
23
+ expect(described_class.new('urn:URN:specificstring')).not_to be_valid
24
+ end
25
+
26
+ it 'returns true if the namespace identifier is 32 characters long' do
27
+ nid = 'a' * 32
28
+
29
+ expect(described_class.new("urn:#{nid}:bar")).to be_valid
30
+ end
31
+
32
+ it 'returns false if the namespace identifier begins with a hyphen' do
33
+ expect(described_class.new('urn:-foo:bar')).not_to be_valid
29
34
  end
30
35
 
36
+ it 'returns false if the namespace specific string has invalid escaping' do
37
+ expect(described_class.new('urn:foo:bar%2')).not_to be_valid
38
+ end
39
+
40
+ it 'returns false if the namespace specific string has reserved characters' do
41
+ expect(described_class.new('urn:foo:café')).not_to be_valid
42
+ end
43
+ end
44
+
45
+ describe '#normalize' do
31
46
  it 'returns nil if it is not valid' do
32
47
  expect(described_class.new('urn:').normalize).to be_nil
33
48
  end
49
+
50
+ it 'lowercases the leading "urn:" token' do
51
+ expect(described_class.new('URN:foo:123').normalize).to eq('urn:foo:123')
52
+ end
53
+
54
+ it 'lowercases the namespace identifier' do
55
+ expect(described_class.new('urn:FOO:123').normalize).to eq('urn:foo:123')
56
+ end
57
+
58
+ it 'lowercases %-escaping in the namespace specific string' do
59
+ expect(described_class.new('urn:foo:123%2C456').normalize).to eq('urn:foo:123%2c456')
60
+ end
61
+
62
+ it 'does not lowercase other characters in the namespace specific string' do
63
+ expect(described_class.new('urn:foo:BA%2CR').normalize).to eq('urn:foo:BA%2cR')
64
+ end
34
65
  end
35
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ana Castro
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2016-03-07 00:00:00.000000000 Z
13
+ date: 2016-03-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler