noid 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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