gn0m30-uuid 2.1.2

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/CHANGELOG ADDED
@@ -0,0 +1,49 @@
1
+ 2.1.1 (2010-01-25)
2
+ * added the :teenie format
3
+
4
+ 2.1.0 (2009-12-16)
5
+ * Added uuid.validate -- easier to implement than explain why it's wrong.
6
+
7
+ 2.0.2 (2009-06-10)
8
+ * Maintenance release. Added uuid.gemspec file in packaging, tested against
9
+ Ruby 1.9.1.
10
+
11
+ 2.0.1 (2008-08-28)
12
+ * Fixed: MAC address parses correctly when using colon as separator, not
13
+ when using hyphen (ruby-mingw32). If your MAC address is all zero
14
+ (check with UUID.new.inspect), remove the ruby-uuid file, and it
15
+ will reset to the actual MAC address. (Rasha)
16
+ * Fixed: UUID.new.inspect not showing full MAC address.
17
+
18
+ 2.0.0 (2008-08-28)
19
+ * Changed: API. UUID.generate still works as it always did, but the rest of
20
+ the API is brand spanking new, so if you rely on anything besides
21
+ UUID.generate, or just curious, check out the rdocs.
22
+ * Changed: uuid.state replaced by ruby-uuid file. By default stored in
23
+ /var/tmp, or if that path is not accessible, as .ruby-uuid in the
24
+ home directory.
25
+ * Changed: ruby-uuid is now stored as binary file (faster read/write), if you
26
+ need to have a peek, open irb and type UUID.new.inspect.
27
+ * Changed: Source code and documentation for this release hosted on the
28
+ wonderful Github: http://github.com/assaf/uuid
29
+
30
+ 1.0.4 (2007-08-28)
31
+ * Changed: By default creates the uuid.state file in the working directory,
32
+ not in the installation directory, which requires sudo privileges
33
+ (e.g. gem).
34
+
35
+ 1.0.3 (2006-11-08)
36
+ * Fixed: Work around YAML bug in serializing that occurs when MAC address
37
+ consists only of decimal digits. Credit: ebuprofen"
38
+
39
+ 1.0.2 (2006-08-19)
40
+ * Changed: Constants are not conditionally defined (removes warnings when
41
+ using in Rails.
42
+
43
+ 1.0.1 (2006-07-27)
44
+ * Added: Regular expressions to test if a string is a UUID.
45
+ * Changed: When used in ActiveRecord, adds as callback instead of overriding
46
+ save.
47
+
48
+ 1.0.0 (2005-11-20)
49
+ * Changed: Separated form reliable-msg into its own package.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2008 Assaf Arkin, Eric Hodel
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,97 @@
1
+ = UUID Generator
2
+
3
+ Generates universally unique identifiers (UUIDs) for use in distributed
4
+ applications. Based on {RFC 4122}[http://www.ietf.org/rfc/rfc4122.txt].
5
+
6
+
7
+ == Generating UUIDs
8
+
9
+ Call #generate to generate a new UUID. The method returns a string in one of
10
+ four formats. The default format is 36 characters long, and contains the 32
11
+ hexadecimal octets and hyphens separating the various value parts. The
12
+ <tt>:compact</tt> format omits the hyphens, while the <tt>:urn</tt> format
13
+ adds the <tt>:urn:uuid</tt> prefix.
14
+
15
+ The gn0m30 fork of uuid adds another format, the <tt>:teenie</tt> format
16
+ converts the numeric portions of the default format to base 62 representations
17
+ for use in situations where case sensitive keys might be useful like Amazon S3.
18
+
19
+
20
+ For example:
21
+
22
+ uuid = UUID.new
23
+ 10.times do
24
+ p uuid.generate
25
+ end
26
+
27
+
28
+ == UUIDs in Brief
29
+
30
+ UUID (universally unique identifier) are guaranteed to be unique across time
31
+ and space.
32
+
33
+ A UUID is 128 bit long, and consists of a 60-bit time value, a 16-bit
34
+ sequence number and a 48-bit node identifier.
35
+
36
+ The time value is taken from the system clock, and is monotonically
37
+ incrementing. However, since it is possible to set the system clock
38
+ backward, a sequence number is added. The sequence number is incremented
39
+ each time the UUID generator is started. The combination guarantees that
40
+ identifiers created on the same machine are unique with a high degree of
41
+ probability.
42
+
43
+ Note that due to the structure of the UUID and the use of sequence number,
44
+ there is no guarantee that UUID values themselves are monotonically
45
+ incrementing. The UUID value cannot itself be used to sort based on order
46
+ of creation.
47
+
48
+ To guarantee that UUIDs are unique across all machines in the network,
49
+ the IEEE 802 MAC address of the machine's network interface card is used as
50
+ the node identifier.
51
+
52
+ For more information see {RFC 4122}[http://www.ietf.org/rfc/rfc4122.txt].
53
+
54
+
55
+ == UUID State File
56
+
57
+ The UUID generator uses a state file to hold the MAC address and sequence
58
+ number.
59
+
60
+ The MAC address is used to generate identifiers that are unique to your
61
+ machine, preventing conflicts in distributed applications. The MAC
62
+ address is six bytes (48 bit) long. It is automatically extracted from
63
+ one of the network cards on your machine.
64
+
65
+ The sequence number is incremented each time the UUID generator is
66
+ first used by the application, to prevent multiple processes from
67
+ generating the same set of identifiers, and deal with changes to the
68
+ system clock.
69
+
70
+ The UUID state file is created in <tt>/var/tmp/ruby-uuid</tt> or the Windows
71
+ common application data directory using mode 0644. If that directory is not
72
+ writable, the file is created as <tt>.ruby-uuid</tt> in the home directory.
73
+ If you need to create the file with a different mode, use UUID#state_file
74
+ before running the UUID generator.
75
+
76
+ State files are not portable across machines.
77
+
78
+
79
+ == Latest and Greatest
80
+
81
+ Stable release are made through Gemcutter, to upgrade simply:
82
+
83
+ gem upgrade gn0m30-uuid
84
+
85
+
86
+ gn0m30-uuid is forked from UUID available here: http://github.com/assaf/uuid
87
+
88
+ Source code and documentation hosted on Github: http://github.com/gn0m30/uuid
89
+
90
+
91
+ == License
92
+
93
+ This package is licensed under the MIT license and/or the Creative
94
+ Commons Attribution-ShareAlike.
95
+
96
+ :include: MIT-LICENSE
97
+
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+
4
+
5
+ spec = Gem::Specification.load(File.expand_path("gn0m30-uuid.gemspec", File.dirname(__FILE__)))
6
+
7
+ desc "Default Task"
8
+ task :default => :test
9
+
10
+
11
+ desc "If you're building from sources, run this task first to setup the necessary dependencies"
12
+ task 'setup' do
13
+ missing = spec.dependencies.select { |dep| Gem::SourceIndex.from_installed_gems.search(dep).empty? }
14
+ missing.each do |dep|
15
+ if Gem::SourceIndex.from_installed_gems.search(dep).empty?
16
+ puts "Installing #{dep.name} ..."
17
+ rb_bin = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
18
+ args = []
19
+ args << rb_bin << '-S' << 'gem' << 'install' << dep.name
20
+ args << '--version' << dep.version_requirements.to_s
21
+ args << '--source' << 'http://gems.rubyforge.org'
22
+ args << '--install-dir' << ENV['GEM_HOME'] if ENV['GEM_HOME']
23
+ sh *args
24
+ end
25
+ end
26
+ end
27
+
28
+
29
+ desc "Run all test cases"
30
+ Rake::TestTask.new do |test|
31
+ test.verbose = true
32
+ test.test_files = ['test/*.rb']
33
+ test.warning = true
34
+ end
35
+
36
+ # Create the documentation.
37
+ Rake::RDocTask.new do |rdoc|
38
+ rdoc.rdoc_files.include "README.rdoc", "lib/**/*.rb"
39
+ rdoc.options = spec.rdoc_options
40
+ end
41
+
42
+
43
+
44
+ desc "Push new release to gemcutter and git tag"
45
+ task :push do
46
+ sh "git push"
47
+ puts "Tagging version #{spec.version} .."
48
+ sh "git tag v#{spec.version}"
49
+ sh "git push --tag"
50
+ puts "Building and pushing gem .."
51
+ sh "gem build #{spec.name}.gemspec"
52
+ sh "gem push #{spec.name}-#{spec.version}.gem"
53
+ end
54
+
55
+ desc "Install #{spec.name} locally"
56
+ task :install do
57
+ sh "gem build #{spec.name}.gemspec"
58
+ sudo = "sudo" unless File.writable?( Gem::ConfigMap[:bindir])
59
+ sh "#{sudo} gem install #{spec.name}-#{spec.version}.gem"
60
+ end
@@ -0,0 +1,22 @@
1
+ spec = Gem::Specification.new do |spec|
2
+ spec.name = 'gn0m30-uuid'
3
+ spec.version = '2.1.2'
4
+ spec.summary = "UUID generator with teenie format"
5
+ spec.description = <<-EOF
6
+ UUID generator for producing universally unique identifiers based on RFC 4122
7
+ (http://www.ietf.org/rfc/rfc4122.txt).
8
+ EOF
9
+
10
+ spec.authors << 'Assaf Arkin' << 'Eric Hodel' << 'jim nist'
11
+ spec.email = 'reggie@loco8.org'
12
+ spec.homepage = 'http://github.com/gn0m30/uuid'
13
+
14
+ spec.files = Dir['{bin,test,lib,docs}/**/*'] + ['README.rdoc', 'MIT-LICENSE', 'Rakefile', 'CHANGELOG', 'gn0m30-uuid.gemspec']
15
+ spec.has_rdoc = true
16
+ spec.rdoc_options << '--main' << 'README.rdoc' << '--title' << 'UUID generator' << '--line-numbers'
17
+ '--webcvs' << 'http://github.com/assaf/uuid'
18
+ spec.extra_rdoc_files = ['README.rdoc', 'MIT-LICENSE']
19
+
20
+ spec.add_dependency 'macaddr', ['~>1.0']
21
+ spec.add_dependency 'base62', ['~>0.1.0']
22
+ end
data/lib/uuid.rb ADDED
@@ -0,0 +1,326 @@
1
+ #
2
+ # = uuid.rb - UUID generator
3
+ #
4
+ # Author:: Assaf Arkin assaf@labnotes.org
5
+ # Eric Hodel drbrain@segment7.net
6
+ # Copyright:: Copyright (c) 2005-2008 Assaf Arkin, Eric Hodel
7
+ # License:: MIT and/or Creative Commons Attribution-ShareAlike
8
+
9
+ require 'fileutils'
10
+ require 'thread'
11
+ require 'tmpdir'
12
+
13
+ require 'rubygems'
14
+ require 'macaddr'
15
+ require 'base62'
16
+
17
+
18
+ ##
19
+ # = Generating UUIDs
20
+ #
21
+ # Call #generate to generate a new UUID. The method returns a string in one of
22
+ # three formats. The default format is 36 characters long, and contains the 32
23
+ # hexadecimal octets and hyphens separating the various value parts. The
24
+ # <tt>:compact</tt> format omits the hyphens, while the <tt>:urn</tt> format
25
+ # adds the <tt>:urn:uuid</tt> prefix.
26
+ #
27
+ # For example:
28
+ #
29
+ # uuid = UUID.new
30
+ #
31
+ # 10.times do
32
+ # p uuid.generate
33
+ # end
34
+ #
35
+ # = UUIDs in Brief
36
+ #
37
+ # UUID (universally unique identifier) are guaranteed to be unique across time
38
+ # and space.
39
+ #
40
+ # A UUID is 128 bit long, and consists of a 60-bit time value, a 16-bit
41
+ # sequence number and a 48-bit node identifier.
42
+ #
43
+ # The time value is taken from the system clock, and is monotonically
44
+ # incrementing. However, since it is possible to set the system clock
45
+ # backward, a sequence number is added. The sequence number is incremented
46
+ # each time the UUID generator is started. The combination guarantees that
47
+ # identifiers created on the same machine are unique with a high degree of
48
+ # probability.
49
+ #
50
+ # Note that due to the structure of the UUID and the use of sequence number,
51
+ # there is no guarantee that UUID values themselves are monotonically
52
+ # incrementing. The UUID value cannot itself be used to sort based on order
53
+ # of creation.
54
+ #
55
+ # To guarantee that UUIDs are unique across all machines in the network,
56
+ # the IEEE 802 MAC address of the machine's network interface card is used as
57
+ # the node identifier.
58
+ #
59
+ # For more information see {RFC 4122}[http://www.ietf.org/rfc/rfc4122.txt].
60
+
61
+ class UUID
62
+
63
+ # Version number.
64
+ module Version
65
+ version = Gem::Specification.load(File.expand_path("../gn0m30-uuid.gemspec", File.dirname(__FILE__))).version.to_s.split(".").map { |i| i.to_i }
66
+ MAJOR = version[0]
67
+ MINOR = version[1]
68
+ PATCH = version[2]
69
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
70
+ end
71
+
72
+ VERSION = Version::STRING
73
+
74
+ ##
75
+ # Clock multiplier. Converts Time (resolution: seconds) to UUID clock
76
+ # (resolution: 10ns)
77
+ CLOCK_MULTIPLIER = 10000000
78
+
79
+ ##
80
+ # Clock gap is the number of ticks (resolution: 10ns) between two Ruby Time
81
+ # ticks.
82
+ CLOCK_GAPS = 100000
83
+
84
+ ##
85
+ # Version number stamped into the UUID to identify it as time-based.
86
+ VERSION_CLOCK = 0x0100
87
+
88
+ ##
89
+ # Formats supported by the UUID generator.
90
+ #
91
+ # <tt>:default</tt>:: Produces 36 characters, including hyphens separating
92
+ # the UUID value parts
93
+ # <tt>:compact</tt>:: Produces a 32 digits (hexadecimal) value with no
94
+ # hyphens
95
+ # <tt>:urn</tt>:: Adds the prefix <tt>urn:uuid:</tt> to the default format
96
+ # <tt>:teenie</tt>:: converts numeric portions of default format to base62
97
+ FORMATS = {
98
+ :compact => '%08x%04x%04x%04x%012x',
99
+ :default => '%08x-%04x-%04x-%04x-%012x',
100
+ :urn => 'urn:uuid:%08x-%04x-%04x-%04x-%012x',
101
+ :teenie => '%6.6s%3.3s%3.3s%3.3s%9.9s',
102
+ }
103
+
104
+ ##
105
+ # MAC address (48 bits), sequence number and last clock
106
+ STATE_FILE_FORMAT = 'SLLQ'
107
+
108
+ @state_file = nil
109
+ @mode = nil
110
+ @uuid = nil
111
+
112
+ ##
113
+ # The access mode of the state file. Set it with state_file.
114
+
115
+ def self.mode
116
+ @mode
117
+ end
118
+
119
+ ##
120
+ # Generates a new UUID string using +format+. See FORMATS for a list of
121
+ # supported formats.
122
+
123
+ def self.generate(format = :default)
124
+ @uuid ||= new
125
+ @uuid.generate format
126
+ end
127
+
128
+ ##
129
+ # Creates an empty state file in /var/tmp/ruby-uuid or the windows common
130
+ # application data directory using mode 0644. Call with a different mode
131
+ # before creating a UUID generator if you want to open access beyond your
132
+ # user by default.
133
+ #
134
+ # If the default state dir is not writable, UUID falls back to ~/.ruby-uuid.
135
+ #
136
+ # State files are not portable across machines.
137
+ def self.state_file(mode = 0644)
138
+ return @state_file if @state_file
139
+
140
+ @mode = mode
141
+
142
+ begin
143
+ require 'Win32API'
144
+
145
+ csidl_common_appdata = 0x0023
146
+ path = 0.chr * 260
147
+ get_folder_path = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L')
148
+ get_folder_path.call 0, csidl_common_appdata, 0, 1, path
149
+
150
+ state_dir = File.join(path.strip)
151
+ rescue LoadError
152
+ state_dir = File.join('', 'var', 'tmp')
153
+ end
154
+
155
+ if File.writable?(state_dir) then
156
+ @state_file = File.join(state_dir, 'ruby-uuid')
157
+ else
158
+ @state_file = File.expand_path(File.join('~', '.ruby-uuid'))
159
+ end
160
+
161
+ @state_file
162
+ end
163
+
164
+ ##
165
+ # Specify the path of the state file.
166
+ def self.state_file=(path)
167
+ @state_file = path
168
+ end
169
+
170
+ ##
171
+ # Returns true if +uuid+ is in compact, default or urn formats. Does not
172
+ # validate the layout (RFC 4122 section 4) of the UUID.
173
+ # does not validate :teenie format. see validate_teenie
174
+ def self.validate(uuid)
175
+ return true if uuid =~ /\A[\da-f]{32}\z/i
176
+ return true if
177
+ uuid =~ /\A(urn:uuid:)?[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}\z/i
178
+ end
179
+
180
+ ##
181
+ # Returns true if +uuid+ is in teenie format
182
+ def self.validate_teenie(uuid)
183
+ return true if uuid =~ /\A[\da-fA-f]{24}\z/i
184
+ end
185
+
186
+ ##
187
+ # Create a new UUID generator. You really only need to do this once.
188
+ def initialize
189
+ @drift = 0
190
+ @last_clock = (Time.now.to_f * CLOCK_MULTIPLIER).to_i
191
+ @mutex = Mutex.new
192
+
193
+ if File.exist?(self.class.state_file) then
194
+ next_sequence
195
+ else
196
+ @mac = Mac.addr.gsub(/:|-/, '').hex & 0x7FFFFFFFFFFF
197
+ fail "Cannot determine MAC address from any available interface, tried with #{Mac.addr}" if @mac == 0
198
+ @sequence = rand 0x10000
199
+
200
+ open_lock 'w' do |io|
201
+ write_state io
202
+ end
203
+ end
204
+ end
205
+
206
+ ##
207
+ # Generates a new UUID string using +format+. See FORMATS for a list of
208
+ # supported formats.
209
+ def generate(format = :default)
210
+ template = FORMATS[format]
211
+
212
+ raise ArgumentError, "invalid UUID format #{format.inspect}" unless template
213
+
214
+ # The clock must be monotonically increasing. The clock resolution is at
215
+ # best 100 ns (UUID spec), but practically may be lower (on my setup,
216
+ # around 1ms). If this method is called too fast, we don't have a
217
+ # monotonically increasing clock, so the solution is to just wait.
218
+ #
219
+ # It is possible for the clock to be adjusted backwards, in which case we
220
+ # would end up blocking for a long time. When backward clock is detected,
221
+ # we prevent duplicates by asking for a new sequence number and continue
222
+ # with the new clock.
223
+
224
+ clock = @mutex.synchronize do
225
+ clock = (Time.new.to_f * CLOCK_MULTIPLIER).to_i & 0xFFFFFFFFFFFFFFF0
226
+
227
+ if clock > @last_clock then
228
+ @drift = 0
229
+ @last_clock = clock
230
+ elsif clock == @last_clock then
231
+ drift = @drift += 1
232
+
233
+ if drift < 10000 then
234
+ @last_clock += 1
235
+ else
236
+ Thread.pass
237
+ nil
238
+ end
239
+ else
240
+ next_sequence
241
+ @last_clock = clock
242
+ end
243
+ end until clock
244
+
245
+ part1 = clock & 0xFFFFFFFF
246
+ part2 = (clock >> 32) & 0xFFFF
247
+ part3 = ((clock >> 48) & 0xFFFF | VERSION_CLOCK)
248
+ part4 = @sequence & 0xFFFF
249
+ part5 = @mac & 0xFFFFFFFFFFFF
250
+
251
+ # for this special case, the parts are going to be strings which we will 0 pad
252
+ if format == :teenie
253
+ part1 = part1.base62_encode
254
+ part2 = part2.base62_encode
255
+ part3 = part3.base62_encode
256
+ part4 = part4.base62_encode
257
+ part5 = part5.base62_encode
258
+
259
+ (template % [part1, part2, part3, part4, part5]).gsub(' ', '0')
260
+ else
261
+ template % [part1, part2, part3, part4, part5]
262
+ end
263
+ end
264
+
265
+ ##
266
+ # Updates the state file with a new sequence number.
267
+ def next_sequence
268
+ open_lock 'r+' do |io|
269
+ @mac, @sequence, @last_clock = read_state(io)
270
+
271
+ io.rewind
272
+ io.truncate 0
273
+
274
+ @sequence += 1
275
+
276
+ write_state io
277
+ end
278
+ rescue Errno::ENOENT
279
+ open_lock 'w' do |io|
280
+ write_state io
281
+ end
282
+ ensure
283
+ @last_clock = (Time.now.to_f * CLOCK_MULTIPLIER).to_i
284
+ @drift = 0
285
+ end
286
+
287
+ def inspect
288
+ mac = ("%012x" % @mac).scan(/[0-9a-f]{2}/).join(':')
289
+ "MAC: #{mac} Sequence: #{@sequence}"
290
+ end
291
+
292
+ protected
293
+
294
+ ##
295
+ # Open the state file with an exclusive lock and access mode +mode+.
296
+ def open_lock(mode)
297
+ File.open self.class.state_file, mode, self.class.mode do |io|
298
+ begin
299
+ io.flock File::LOCK_EX
300
+ yield io
301
+ ensure
302
+ io.flock File::LOCK_UN
303
+ end
304
+ end
305
+ end
306
+
307
+ ##
308
+ # Read the state from +io+
309
+ def read_state(io)
310
+ mac1, mac2, seq, last_clock = io.read(32).unpack(STATE_FILE_FORMAT)
311
+ mac = (mac1 << 32) + mac2
312
+
313
+ return mac, seq, last_clock
314
+ end
315
+
316
+
317
+ ##
318
+ # Write that state to +io+
319
+ def write_state(io)
320
+ mac2 = @mac & 0xffffffff
321
+ mac1 = (@mac >> 32) & 0xffff
322
+
323
+ io.write [mac1, mac2, @sequence, @last_clock].pack(STATE_FILE_FORMAT)
324
+ end
325
+
326
+ end
data/test/test-uuid.rb ADDED
@@ -0,0 +1,118 @@
1
+ # Author:: Assaf Arkin assaf@labnotes.org
2
+ # Eric Hodel drbrain@segment7.net
3
+ # Copyright:: Copyright (c) 2005-2008 Assaf Arkin, Eric Hodel
4
+ # License:: MIT and/or Creative Commons Attribution-ShareAlike
5
+
6
+ require 'test/unit'
7
+ require 'uuid'
8
+
9
+ class TestUUID < Test::Unit::TestCase
10
+
11
+ def test_state_file_creation
12
+ path = UUID.state_file
13
+ File.delete path if File.exist?(path)
14
+ UUID.new.generate
15
+ File.exist?(path)
16
+ end
17
+
18
+ def test_state_file_specify
19
+ path = File.join("path", "to", "ruby-uuid")
20
+ UUID.state_file = path
21
+ assert_equal path, UUID.state_file
22
+ end
23
+
24
+ def test_instance_generate
25
+ uuid = UUID.new
26
+ assert_match(/\A[\da-f]{32}\z/i, uuid.generate(:compact))
27
+
28
+ assert_match(/\A[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\z/i,
29
+ uuid.generate(:default))
30
+
31
+ assert_match(/^urn:uuid:[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\z/i,
32
+ uuid.generate(:urn))
33
+
34
+ assert_match(/\A[\da-fA-f]{24}\z/i, uuid.generate(:teenie))
35
+
36
+ e = assert_raise ArgumentError do
37
+ uuid.generate :unknown
38
+ end
39
+
40
+ assert_equal 'invalid UUID format :unknown', e.message
41
+ end
42
+
43
+ def test_class_generate
44
+ assert_match(/\A[\da-f]{32}\z/i, UUID.generate(:compact))
45
+
46
+ assert_match(/\A[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\z/i,
47
+ UUID.generate(:default))
48
+
49
+ assert_match(/^urn:uuid:[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\z/i,
50
+ UUID.generate(:urn))
51
+
52
+ assert_match(/\A[\da-fA-f]{24}\z/i, UUID.generate(:teenie))
53
+
54
+ e = assert_raise ArgumentError do
55
+ UUID.generate :unknown
56
+ end
57
+ assert_equal 'invalid UUID format :unknown', e.message
58
+ end
59
+
60
+ def test_class_validate
61
+ assert !UUID.validate('')
62
+
63
+ assert UUID.validate('01234567abcd8901efab234567890123'), 'compact'
64
+ assert UUID.validate('01234567-abcd-8901-efab-234567890123'), 'default'
65
+ assert UUID.validate('urn:uuid:01234567-abcd-8901-efab-234567890123'),
66
+ 'urn'
67
+ assert UUID.validate_teenie('4etJlQGyu04qEJs002f129iS'), 'teenie'
68
+
69
+ assert UUID.validate('01234567ABCD8901EFAB234567890123'), 'compact'
70
+ assert UUID.validate('01234567-ABCD-8901-EFAB-234567890123'), 'default'
71
+ assert UUID.validate('urn:uuid:01234567-ABCD-8901-EFAB-234567890123'),
72
+ 'urn'
73
+ assert UUID.validate_teenie('1ldIDgGyv04qEJs002f129iS'), 'teenie'
74
+ end
75
+
76
+ def test_class_invalids
77
+ assert_nil UUID.validate('01234567abcd8901efab234567890123000'), 'compact - too long'
78
+ assert_nil UUID.validate('01234567abcd8901efab23456789012'), 'compact - too short'
79
+ assert_nil UUID.validate('01234567abcd8901efzb234567890123'), 'compact - bad chars'
80
+
81
+ assert_nil UUID.validate_teenie('1ldIDgGyv04qEJs002f129iSaaaaa'), 'teenie - too long'
82
+ assert_nil UUID.validate_teenie('4etJlQGyu04qEJs02f129iS'), 'teenie - too short'
83
+ assert_nil UUID.validate_teenie('1ldIDgGyv04qEJs002f1-9iS'), 'teenie - bad chars'
84
+ end
85
+
86
+ def test_monotonic
87
+ seen = {}
88
+ uuid_gen = UUID.new
89
+
90
+ 20_000.times do
91
+ uuid = uuid_gen.generate
92
+ assert !seen.has_key?(uuid), "UUID repeated"
93
+ seen[uuid] = true
94
+ end
95
+ end
96
+
97
+ def test_same_mac
98
+ class << foo = UUID.new
99
+ attr_reader :mac
100
+ end
101
+ class << bar = UUID.new
102
+ attr_reader :mac
103
+ end
104
+ assert_equal foo.mac, bar.mac
105
+ end
106
+
107
+ def test_increasing_sequence
108
+ class << foo = UUID.new
109
+ attr_reader :sequence
110
+ end
111
+ class << bar = UUID.new
112
+ attr_reader :sequence
113
+ end
114
+ assert_equal foo.sequence + 1, bar.sequence
115
+ end
116
+
117
+ end
118
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gn0m30-uuid
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Assaf Arkin
8
+ - Eric Hodel
9
+ - jim nist
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2010-02-18 00:00:00 -05:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: macaddr
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ~>
24
+ - !ruby/object:Gem::Version
25
+ version: "1.0"
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: base62
29
+ type: :runtime
30
+ version_requirement:
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 0.1.0
36
+ version:
37
+ description: |
38
+ UUID generator for producing universally unique identifiers based on RFC 4122
39
+ (http://www.ietf.org/rfc/rfc4122.txt).
40
+
41
+ email: reggie@loco8.org
42
+ executables: []
43
+
44
+ extensions: []
45
+
46
+ extra_rdoc_files:
47
+ - README.rdoc
48
+ - MIT-LICENSE
49
+ files:
50
+ - test/test-uuid.rb
51
+ - lib/uuid.rb
52
+ - README.rdoc
53
+ - MIT-LICENSE
54
+ - Rakefile
55
+ - CHANGELOG
56
+ - gn0m30-uuid.gemspec
57
+ has_rdoc: true
58
+ homepage: http://github.com/gn0m30/uuid
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --main
64
+ - README.rdoc
65
+ - --title
66
+ - UUID generator
67
+ - --line-numbers
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.5
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: UUID generator with teenie format
89
+ test_files: []
90
+