noid 0.4.0 → 0.5.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/lib/noid/base.rb DELETED
@@ -1,154 +0,0 @@
1
- require 'backports'
2
-
3
- module Noid
4
- module Base
5
- XDIGIT = ['0','1','2','3','4','5','6','7','8','9','b','c','d','f','g','h','j','k','l','n','p','q','r','s','t','v','w','x','z']
6
- MAX_COUNTERS = 293
7
-
8
- def initialize args = {}
9
- @max = nil
10
- @min = nil
11
- @config = { :identifier => {} }.merge args
12
- super() if respond_to?('super')
13
- setup_mask args
14
- end
15
-
16
-
17
- def mint
18
- str = @prefix
19
- n = @s
20
- @s += 1
21
-
22
- case @type
23
- when 's'
24
- when 'z'
25
- when 'r'
26
- raise Exception if @counters.size == 0
27
- i = @rand.rand(@counters.size)
28
- n = @counters[i][:value]
29
- @counters[i][:value] += 1
30
- @counters.delete_at(i) if @counters[i][:value] == @counters[i][:max]
31
- end
32
- str += n2xdig(n)
33
-
34
- str += checkdigit(str) if @check
35
-
36
- identifier.new str
37
- end
38
-
39
- def valid? id
40
- prefix = id[0..@prefix.length-1]
41
- ch = id[@prefix.length..-1].split('')
42
- check = ch.pop if @check
43
- return false unless prefix == @prefix
44
-
45
- return false unless @characters.length == ch.length
46
- @characters.each_with_index do |c, i|
47
- return false unless XDIGIT.include? ch[i]
48
- return false if c == 'd' and ch[i] =~ /[^\d]/
49
- end
50
-
51
- return false unless check.nil? or check == checkdigit(id[0..-2])
52
-
53
- true
54
- end
55
-
56
- protected
57
- def identifier
58
- @config[:identifier][:class] || String
59
- end
60
-
61
- def checkdigit str
62
- i = 1
63
- XDIGIT[str.split('').map { |x| XDIGIT.index(x).to_i }.inject { |sum, n| i+=1; sum += (n * i) } % XDIGIT.length]
64
- end
65
-
66
- def min
67
- return @min if @min
68
- @min = 0
69
- end
70
-
71
- def max
72
- return @max if @max
73
- return @max = nil if @type == 'z'
74
- @max = @characters.inject(1) do |sum, n|
75
- i = case n
76
- when 'e'
77
- XDIGIT.length
78
- when 'd'
79
- 10
80
- else
81
- 1
82
- end
83
- sum *= i
84
- end
85
- end
86
-
87
- def n2xdig n
88
- xdig = @characters.reverse.map do |c|
89
- div = case c
90
- when 'e' then XDIGIT.length
91
- when 'd' then 10
92
- end
93
- next if div.nil?
94
-
95
- value = n % div
96
- n = n / div
97
- XDIGIT[value]
98
- end.compact.join ''
99
-
100
- if @type == 'z'
101
- while n > 0
102
- c = @characters.last
103
- div = case c
104
- when 'e' then XDIGIT.length
105
- when 'd' then 10
106
- end
107
- next if div.nil?
108
-
109
- value = n % div
110
- n = n / div
111
- xdig += XDIGIT[value]
112
- end
113
- end
114
-
115
- raise Exception if n > 0
116
-
117
- xdig.reverse
118
- end
119
-
120
- def setup_mask args
121
- @template = args[:template]
122
- @prefix, @mask = @template.split('.')
123
-
124
- @prefix = "#{args[:namespace]}/#{@prefix}" if args[:namespace]
125
-
126
- @type, @characters = @mask.split '', 2
127
- @characters = @characters.split ''
128
- @check = @characters.pop and true if @characters.last == 'k'
129
- @s = args[:s] || 0
130
- case @type
131
- when 's'
132
- when 'z'
133
- when 'r'
134
- @rand = Random.new(args[:seed]) if args[:seed]
135
- @rand ||= Random.new
136
- @seed = @rand.seed
137
-
138
- if args[:s]
139
- args[:s].times { @rand.rand }
140
- end
141
-
142
- percounter = max / (args[:max_counters] || MAX_COUNTERS) + 1
143
- t = 0
144
- @counters = args[:counters]
145
- @counters ||= Array.new(max/percounter) do |i|
146
- { :value => case i
147
- when 0 then 0
148
- else t += percounter
149
- end, :max => t + percounter }
150
- end
151
- end
152
- end
153
- end
154
- end
@@ -1,24 +0,0 @@
1
- module Noid::Identifier
2
- class Base
3
- def initialize id
4
- @id = id
5
- @metadata = {}
6
- end
7
-
8
- def id
9
- @id
10
- end
11
-
12
- def [] key
13
- @metadata[key]
14
- end
15
-
16
- def []= key, value
17
- @metadata[key] = value
18
- end
19
-
20
- def push hash
21
- @metadata.merge! hash
22
- end
23
- end
24
- end
@@ -1,32 +0,0 @@
1
- module Noid::Identifier
2
- class Anvl < Base
3
- def initialize id
4
- @id = id
5
- @metadata = ::ANVL::Document.new
6
- end
7
-
8
- def []= key, value
9
- super
10
- save
11
- end
12
-
13
- def push hash
14
- @metadata << hash
15
- save
16
- end
17
-
18
- private
19
- def file
20
- @id
21
- end
22
-
23
- def save
24
- File.open(file, 'w') do |f|
25
- f.write @metadata.to_s
26
- end
27
-
28
- end
29
-
30
-
31
- end
32
- end
@@ -1,14 +0,0 @@
1
- module Noid::Identifier
2
- class Singleton < Base
3
- @@identifiers = {}
4
- @@identifiers = {}
5
- def self.new id
6
- @@identifiers[id] ||= super(id)
7
- @@identifiers[id]
8
- end
9
-
10
- def self.identifiers
11
- @@identifiers
12
- end
13
- end
14
- end
@@ -1,4 +0,0 @@
1
- module Noid
2
- module Persistence
3
- end
4
- end
@@ -1,11 +0,0 @@
1
- module Noid::Persistence
2
- class Base
3
- include Noid::Base
4
-
5
- def mint
6
- a = super
7
- save
8
- return a
9
- end
10
- end
11
- end
@@ -1,38 +0,0 @@
1
- require 'json'
2
- module Noid::Persistence
3
- class JSON < Base
4
- FILENAME = 'NOID.js'
5
- def initialize args = {}
6
- @file = args[:filename] || FILENAME
7
- @json = args[:json] || File.read(@file) rescue nil
8
- data = load_json if @json
9
- data ||= {}
10
- super data.merge(args)
11
- save
12
- end
13
-
14
- protected
15
- def load_json
16
- data = ::JSON.parse(@json) rescue nil
17
- data ||= {}
18
- data = data.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} unless data.empty?
19
- data[:counters] = data[:counters].map { |x| x.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} } if data[:counters]
20
- data[:identifier] = { :class => Kernel.const_get(data[:identifier]['class']) } if data[:identifier]
21
- data
22
- end
23
-
24
- def save
25
- str = self.to_json
26
- File.open(@file, 'w') do |f|
27
- f.write(str)
28
- end unless @file == '/dev/null'
29
-
30
- str
31
- end
32
-
33
- def to_json
34
- str = { :template => @template, :identifier => { :class => identifier.name }, :s => @s, :counters => @counters, :seed => @seed }.to_json
35
- end
36
-
37
- end
38
- end
data/test/helper.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
-
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
15
- require 'noid'
16
-
17
- class Test::Unit::TestCase
18
- end
data/test/test_binding.rb DELETED
@@ -1,42 +0,0 @@
1
- require 'helper'
2
- require 'anvl'
3
- require 'tmpdir'
4
-
5
- class TestNoidBinding < Test::Unit::TestCase
6
- context "Noid" do
7
- should "accept identifier_class for NOID bindings" do
8
- Dir.mktmpdir do |d|
9
- Dir.chdir d
10
- n = Noid::Minter.new :template => 'r.rek', :identifier => { :class => Noid::Identifier::Base }
11
- id = n.mint
12
- assert_equal(Noid::Identifier::Base, id.class)
13
- id['abc'] = 123
14
- assert_equal(123, id['abc'])
15
- end
16
- end
17
-
18
- should "use singleton instance to persist NOID bindings" do
19
- Dir.mktmpdir do |d|
20
- Dir.chdir d
21
- n = Noid::Minter.new :template => 'r.rek', :identifier => { :class => Noid::Identifier::Singleton }
22
- id = n.mint
23
- id['abc'] = 123
24
- assert_equal(123, id['abc'])
25
-
26
- id2 = Noid::Identifier::Singleton.new id.id
27
- assert_equal(123, id2['abc'])
28
- end
29
- end
30
-
31
- should "user anvl instance to persist NOID binding info" do
32
- Dir.mktmpdir do |d|
33
- Dir.chdir d
34
- n = Noid::Minter.new :template => 'r.rek', :identifier => { :class => Noid::Identifier::Anvl }
35
- id = n.mint
36
- id['abc'] = "123"
37
- assert_equal(Noid::Identifier::Anvl, id.class)
38
- assert_equal("123", id['abc'])
39
- end
40
- end
41
- end
42
- end
data/test/test_noid.rb DELETED
@@ -1,134 +0,0 @@
1
- require 'helper'
2
-
3
- class TestNoid < Test::Unit::TestCase
4
- context "Noid" do
5
- should "generate checkdigits correctly" do
6
- n = Noid::Minter.new :template => 's.zd'
7
- assert_equal('q', n.send(:checkdigit, '13030/xf93gt2'))
8
- end
9
-
10
- should "generate max sequence for type 'r'" do
11
- n = Noid::Minter.new :template => 's.rd'
12
- assert_equal(0, n.send(:min))
13
- assert_equal(10, n.send(:max))
14
-
15
- n = Noid::Minter.new :template => 's.rdd'
16
- assert_equal(0, n.send(:min))
17
- assert_equal(100, n.send(:max))
18
- end
19
-
20
- should "generate quasi-random counters for type 'r'" do
21
- n = Noid::Minter.new :template => 's.rd'
22
- assert_equal((0..9).map { |x| {:value => x, :max => (x + 1)} }, n.instance_variable_get('@counters'))
23
-
24
- n = Noid::Minter.new :template => 's.rdde'
25
- s = n.instance_variable_get('@counters')
26
- assert_contains(s, {:value => 2890, :max => 2900})
27
- end
28
-
29
- should "generate random sequence for type 'r'" do
30
- n = Noid::Minter.new :template => 's.rd'
31
- a = 10.times.map { |i| n.mint }
32
-
33
- 10.times do |i|
34
- assert_contains(a, "s#{i}")
35
- end
36
-
37
- end
38
-
39
- should "generate numeric sequence for type 's'" do
40
- n = Noid::Minter.new :template => 's.sd'
41
- 10.times do |i|
42
- assert_equal("s#{i}", n.mint)
43
- end
44
- end
45
-
46
- should "generate extended sequence for type 's'" do
47
- n = Noid::Minter.new :template => 's.se'
48
- 10.times do |i|
49
- assert_equal("s#{i}", n.mint)
50
- end
51
- assert_equal("sb", n.mint)
52
- 10.times { n.mint }
53
- assert_equal("sq", n.mint)
54
-
55
- end
56
-
57
- should "raise an exception when overflowing sequence" do
58
- n = Noid::Minter.new :template => 's.sd'
59
- 10.times do |i|
60
- assert_equal("s#{i}", n.mint)
61
- end
62
-
63
- assert_raise Exception do
64
- n.mint
65
- end
66
- end
67
-
68
- should "generate sequence for type 's' with checkdigit" do
69
- n = Noid::Minter.new :template => 's.sdk'
70
- assert_equal('s0s', n.mint)
71
- assert_equal('s1v', n.mint)
72
- assert_equal('s2x', n.mint)
73
- end
74
-
75
- should "generate sequence for type 'z' with checkdigit" do
76
- n = Noid::Minter.new :template => 'z.zdk'
77
- assert_equal('z0z', n.mint)
78
- assert_equal('z11', n.mint)
79
- assert_equal('z23', n.mint)
80
- end
81
- should "generate sequence for type 'z', adding new digits as needed" do
82
- n = Noid::Minter.new :template => 'z.zdk'
83
- assert_equal('z0z', n.mint)
84
- assert_equal('z11', n.mint)
85
- assert_equal('z23', n.mint)
86
- 10.times { n.mint }
87
- assert_equal('z13b', n.mint)
88
- end
89
-
90
- should "generate sequence for type 'z', adding new xdigits as needed" do
91
- n = Noid::Minter.new :template => 'z.zdek'
92
- assert_equal('z00z', n.mint)
93
- assert_equal('z012', n.mint)
94
- assert_equal('z025', n.mint)
95
- 10.times {
96
- assert_match(/^z[0-9]/, n.mint)
97
- }
98
- assert_equal('z0f9', n.mint)
99
- 100.times {
100
- assert_match(/^z[0-9]/, n.mint)
101
- }
102
- assert_equal('z3xz', n.mint)
103
- 1000.times {
104
- assert_match(/^z[0-9]/, n.mint)
105
- }
106
- assert_equal('z38fs', n.mint)
107
- end
108
-
109
- should "validate 'r' digit sequences" do
110
- n = Noid::Minter.new :template => 'r.rd'
111
-
112
- assert_equal(true, n.valid?('r1') )
113
- assert_equal(true, n.valid?('r9') )
114
- assert_equal(false, n.valid?('r11') )
115
- assert_equal(false, n.valid?('ro'))
116
- assert_equal(false, n.valid?('rb'))
117
- end
118
-
119
- should "validate 'r' xdigit sequences" do
120
- n = Noid::Minter.new :template => 'r.re'
121
-
122
- assert_equal(true, n.valid?('r1') )
123
- assert_equal(true, n.valid?('r9') )
124
- assert_equal(false, n.valid?('ro'))
125
- assert_equal(true, n.valid?('rb'))
126
- end
127
- should "validate 'r' xdigit + checkdigit sequences" do
128
- n = Noid::Minter.new :template => 'r.rek'
129
-
130
- assert_equal(true, n.valid?('r2w') )
131
- assert_equal(false, n.valid?('r2b') )
132
- end
133
- end
134
- end