urn 0.1.3 → 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.
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