json-schema 0.2.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +25 -4
- data/lib/json-schema.rb +2 -1
- data/lib/json-schema/attributes/maxdecimal.rb +15 -0
- data/lib/json-schema/attributes/maximum_inclusive.rb +16 -0
- data/lib/json-schema/attributes/minimum_inclusive.rb +16 -0
- data/lib/json-schema/attributes/properties_optional.rb +23 -0
- data/lib/json-schema/uri/uuid.rb +387 -0
- data/lib/json-schema/validator.rb +28 -9
- data/lib/json-schema/validators/draft1.rb +32 -0
- data/lib/json-schema/validators/draft2.rb +33 -0
- data/test/test_jsonschema_draft1.rb +760 -0
- data/test/test_jsonschema_draft2.rb +832 -0
- metadata +15 -4
data/README.textile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
h1. Ruby JSON Schema Validator
|
2
2
|
|
3
|
-
This library is intended to provide Ruby with an interface for validating JSON objects against a JSON schema conforming to "JSON Schema Draft 3":http://tools.ietf.org/html/draft-zyp-json-schema-03.
|
3
|
+
This library is intended to provide Ruby with an interface for validating JSON objects against a JSON schema conforming to "JSON Schema Draft 3":http://tools.ietf.org/html/draft-zyp-json-schema-03. Legacy support for "JSON Schema Draft 2":http://tools.ietf.org/html/draft-zyp-json-schema-02 and "JSON Schema Draft 1":http://tools.ietf.org/html/draft-zyp-json-schema-01 is also included.
|
4
4
|
|
5
5
|
h2. Dependencies
|
6
6
|
|
@@ -18,7 +18,7 @@ From the git repo:
|
|
18
18
|
|
19
19
|
<pre>
|
20
20
|
$ gem build json-schema.gemspec
|
21
|
-
$ gem install json-schema-0.
|
21
|
+
$ gem install json-schema-0.9.0.gem
|
22
22
|
</pre>
|
23
23
|
|
24
24
|
|
@@ -26,9 +26,9 @@ h2. Usage
|
|
26
26
|
|
27
27
|
Two base validation methods exist: <code>validate</code> and <code>validate!</code>. The first returns a boolean on whether a validation attempt passes and the latter will throw a <code>JSON::Schema::ValidationError</code> with an appropriate message/trace on where the validation failed.
|
28
28
|
|
29
|
-
Both methods take two arguments, which can be either a JSON string, a file containing JSON, or a Ruby object representing JSON data. The first argument to these methods is always the schema, the second is always the data to validate.
|
29
|
+
Both methods take two arguments, which can be either a JSON string, a file containing JSON, or a Ruby object representing JSON data. The first argument to these methods is always the schema, the second is always the data to validate. An optional third options argument is also accepted; available options are used in the examples below.
|
30
30
|
|
31
|
-
By default, the validator uses
|
31
|
+
By default, the validator uses the "JSON Schema Draft 3":http://tools.ietf.org/html/draft-zyp-json-schema-03 specification for validation; however, the user is free to specify additional specifications or extend existing ones. Legacy support for Draft 1 and Draft 2 is included by either passing an optional <code>:version</code> parameter to the <code>validate</code> method (set either as <code>:draft1</code> or <code>draft2</code>), or by declaring the <code>$schema</code> attribute in the schema and referencing the appropriate specification URI. Note that the <code>$schema</code> attribute takes precedence over the <code>:version</code> option during parsing and validation.
|
32
32
|
|
33
33
|
h3. Validate Ruby objects against a Ruby schema
|
34
34
|
|
@@ -93,6 +93,27 @@ rescue JSON::Schema::ValidationError
|
|
93
93
|
end
|
94
94
|
</pre>
|
95
95
|
|
96
|
+
h3. Validate an object against a JSON Schema Draft 2 schema
|
97
|
+
|
98
|
+
<pre>
|
99
|
+
require 'rubygems'
|
100
|
+
require 'json-schema'
|
101
|
+
|
102
|
+
schema = {
|
103
|
+
"type" => "object",
|
104
|
+
"properties" => {
|
105
|
+
"a" => {"type" => "integer", "optional" => true}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
data = {
|
110
|
+
"a" => 5
|
111
|
+
}
|
112
|
+
|
113
|
+
JSON::Validator.validate(schema, data, :version => :draft2)
|
114
|
+
</pre>
|
115
|
+
|
116
|
+
|
96
117
|
h3. Extend an existing schema and validating against it
|
97
118
|
|
98
119
|
For this example, we are going to extend the "JSON Schema Draft 3":http://tools.ietf.org/html/draft-zyp-json-schema-03 specification by adding a 'bitwise-and' property for validation.
|
data/lib/json-schema.rb
CHANGED
@@ -5,4 +5,5 @@ require 'schema'
|
|
5
5
|
require 'validator'
|
6
6
|
Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/*")].each {|file| require file }
|
7
7
|
Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*")].each {|file| require file }
|
8
|
-
require 'uri/file'
|
8
|
+
require 'uri/file'
|
9
|
+
require 'uri/uuid'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class MaxDecimalAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
s = data.to_s.split(".")[1]
|
7
|
+
if s && s.length > current_schema.schema['maxDecimal']
|
8
|
+
message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{current_schema.schema['maxDecimal']}"
|
9
|
+
raise ValidationError.new(message, fragments, current_schema)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class MaximumInclusiveAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
current_schema.schema['maximumCanEqual'] = true if current_schema.schema['maximumCanEqual'].nil?
|
7
|
+
if (current_schema.schema['maximumCanEqual'] ? data > current_schema.schema['maximum'] : data >= current_schema.schema['maximum'])
|
8
|
+
message = "The property '#{build_fragment(fragments)}' did not have a maximum value of #{current_schema.schema['maximum']}, "
|
9
|
+
message += current_schema.schema['exclusiveMaximum'] ? 'exclusively' : 'inclusively'
|
10
|
+
raise ValidationError.new(message, fragments, current_schema)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class MinimumInclusiveAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
current_schema.schema['minimumCanEqual'] = true if current_schema.schema['minimumCanEqual'].nil?
|
7
|
+
if (current_schema.schema['minimumCanEqual'] ? data < current_schema.schema['minimum'] : data <= current_schema.schema['minimum'])
|
8
|
+
message = "The property '#{build_fragment(fragments)}' did not have a minimum value of #{current_schema.schema['minimum']}, "
|
9
|
+
message += current_schema.schema['exclusiveMinimum'] ? 'exclusively' : 'inclusively'
|
10
|
+
raise ValidationError.new(message, fragments, current_schema)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class PropertiesOptionalAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
5
|
+
if data.is_a?(Hash)
|
6
|
+
current_schema.schema['properties'].each do |property,property_schema|
|
7
|
+
if ((property_schema['optional'].nil? || property_schema['optional'] == false) && !data.has_key?(property))
|
8
|
+
message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
|
9
|
+
raise ValidationError.new(message, fragments, current_schema)
|
10
|
+
end
|
11
|
+
|
12
|
+
if data.has_key?(property)
|
13
|
+
schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
|
14
|
+
fragments << property
|
15
|
+
schema.validate(data[property],fragments)
|
16
|
+
fragments.pop
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,387 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
### http://mput.dip.jp/mput/uuid.txt
|
3
|
+
|
4
|
+
# Copyright(c) 2005 URABE, Shyouhei.
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this code, to deal in the code without restriction, including without
|
8
|
+
# limitation the rights to use, copy, modify, merge, publish, distribute,
|
9
|
+
# sublicense, and/or sell copies of the code, and to permit persons to whom the
|
10
|
+
# code is furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the code.
|
14
|
+
#
|
15
|
+
# THE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# CODE.
|
22
|
+
#
|
23
|
+
# 2009-02-20: Modified by Pablo Lorenzoni <pablo@propus.com.br> to correctly
|
24
|
+
# include the version in the raw_bytes.
|
25
|
+
|
26
|
+
|
27
|
+
require 'digest/md5'
|
28
|
+
require 'digest/sha1'
|
29
|
+
require 'tmpdir'
|
30
|
+
|
31
|
+
# Pure ruby UUID generator, which is compatible with RFC4122
|
32
|
+
UUID = Struct.new :raw_bytes
|
33
|
+
|
34
|
+
class UUID
|
35
|
+
private_class_method :new
|
36
|
+
|
37
|
+
class << self
|
38
|
+
def mask19 v, str # :nodoc
|
39
|
+
nstr = str.bytes.to_a
|
40
|
+
version = [0, 16, 32, 48, 64, 80][v]
|
41
|
+
nstr[6] &= 0b00001111
|
42
|
+
nstr[6] |= version
|
43
|
+
# nstr[7] &= 0b00001111
|
44
|
+
# nstr[7] |= 0b01010000
|
45
|
+
nstr[8] &= 0b00111111
|
46
|
+
nstr[8] |= 0b10000000
|
47
|
+
str = ''
|
48
|
+
nstr.each { |s| str << s.chr }
|
49
|
+
str
|
50
|
+
end
|
51
|
+
|
52
|
+
def mask18 v, str # :nodoc
|
53
|
+
version = [0, 16, 32, 48, 64, 80][v]
|
54
|
+
str[6] &= 0b00001111
|
55
|
+
str[6] |= version
|
56
|
+
# str[7] &= 0b00001111
|
57
|
+
# str[7] |= 0b01010000
|
58
|
+
str[8] &= 0b00111111
|
59
|
+
str[8] |= 0b10000000
|
60
|
+
str
|
61
|
+
end
|
62
|
+
|
63
|
+
def mask v, str
|
64
|
+
if RUBY_VERSION >= "1.9.0"
|
65
|
+
return mask19 v, str
|
66
|
+
else
|
67
|
+
return mask18 v, str
|
68
|
+
end
|
69
|
+
end
|
70
|
+
private :mask, :mask18, :mask19
|
71
|
+
|
72
|
+
# UUID generation using SHA1. Recommended over create_md5.
|
73
|
+
# Namespace object is another UUID, some of them are pre-defined below.
|
74
|
+
def create_sha1 str, namespace
|
75
|
+
sha1 = Digest::SHA1.new
|
76
|
+
sha1.update namespace.raw_bytes
|
77
|
+
sha1.update str
|
78
|
+
sum = sha1.digest
|
79
|
+
raw = mask 5, sum[0..15]
|
80
|
+
ret = new raw
|
81
|
+
ret.freeze
|
82
|
+
ret
|
83
|
+
end
|
84
|
+
alias :create_v5 :create_sha1
|
85
|
+
|
86
|
+
# UUID generation using MD5 (for backward compat.)
|
87
|
+
def create_md5 str, namespace
|
88
|
+
md5 = Digest::MD5.new
|
89
|
+
md5.update namespace.raw_bytes
|
90
|
+
md5.update str
|
91
|
+
sum = md5.digest
|
92
|
+
raw = mask 3, sum[0..16]
|
93
|
+
ret = new raw
|
94
|
+
ret.freeze
|
95
|
+
ret
|
96
|
+
end
|
97
|
+
alias :create_v3 :create_md5
|
98
|
+
|
99
|
+
# UUID generation using random-number generator. From it's random
|
100
|
+
# nature, there's no warranty that the created ID is really universaly
|
101
|
+
# unique.
|
102
|
+
def create_random
|
103
|
+
rnd = [
|
104
|
+
rand(0x100000000),
|
105
|
+
rand(0x100000000),
|
106
|
+
rand(0x100000000),
|
107
|
+
rand(0x100000000),
|
108
|
+
].pack "N4"
|
109
|
+
raw = mask 4, rnd
|
110
|
+
ret = new raw
|
111
|
+
ret.freeze
|
112
|
+
ret
|
113
|
+
end
|
114
|
+
alias :create_v4 :create_random
|
115
|
+
|
116
|
+
def read_state fp # :nodoc:
|
117
|
+
fp.rewind
|
118
|
+
Marshal.load fp.read
|
119
|
+
end
|
120
|
+
|
121
|
+
def write_state fp, c, m # :nodoc:
|
122
|
+
fp.rewind
|
123
|
+
str = Marshal.dump [c, m]
|
124
|
+
fp.write str
|
125
|
+
end
|
126
|
+
|
127
|
+
private :read_state, :write_state
|
128
|
+
STATE_FILE = 'ruby-uuid'
|
129
|
+
|
130
|
+
# create the "version 1" UUID with current system clock, current UTC
|
131
|
+
# timestamp, and the IEEE 802 address (so-called MAC address).
|
132
|
+
#
|
133
|
+
# Speed notice: it's slow. It writes some data into hard drive on every
|
134
|
+
# invokation. If you want to speed this up, try remounting tmpdir with a
|
135
|
+
# memory based filesystem (such as tmpfs). STILL slow? then no way but
|
136
|
+
# rewrite it with c :)
|
137
|
+
def create clock=nil, time=nil, mac_addr=nil
|
138
|
+
c = t = m = nil
|
139
|
+
Dir.chdir Dir.tmpdir do
|
140
|
+
unless FileTest.exist? STATE_FILE then
|
141
|
+
# Generate a pseudo MAC address because we have no pure-ruby way
|
142
|
+
# to know the MAC address of the NIC this system uses. Note
|
143
|
+
# that cheating with pseudo arresses here is completely legal:
|
144
|
+
# see Section 4.5 of RFC4122 for details.
|
145
|
+
sha1 = Digest::SHA1.new
|
146
|
+
256.times do
|
147
|
+
r = [rand(0x100000000)].pack "N"
|
148
|
+
sha1.update r
|
149
|
+
end
|
150
|
+
str = sha1.digest
|
151
|
+
r = rand 14 # 20-6
|
152
|
+
node = str[r, 6] || str
|
153
|
+
if RUBY_VERSION >= "1.9.0"
|
154
|
+
nnode = node.bytes.to_a
|
155
|
+
nnode[0] |= 0x01
|
156
|
+
node = ''
|
157
|
+
nnode.each { |s| node << s.chr }
|
158
|
+
else
|
159
|
+
node[0] |= 0x01 # multicast bit
|
160
|
+
end
|
161
|
+
k = rand 0x40000
|
162
|
+
open STATE_FILE, 'w' do |fp|
|
163
|
+
fp.flock IO::LOCK_EX
|
164
|
+
write_state fp, k, node
|
165
|
+
fp.chmod 0o777 # must be world writable
|
166
|
+
end
|
167
|
+
end
|
168
|
+
open STATE_FILE, 'r+' do |fp|
|
169
|
+
fp.flock IO::LOCK_EX
|
170
|
+
c, m = read_state fp
|
171
|
+
c = clock % 0x4000 if clock
|
172
|
+
m = mac_addr if mac_addr
|
173
|
+
t = time
|
174
|
+
if t.nil? then
|
175
|
+
# UUID epoch is 1582/Oct/15
|
176
|
+
tt = Time.now
|
177
|
+
t = tt.to_i*10000000 + tt.tv_usec*10 + 0x01B21DD213814000
|
178
|
+
end
|
179
|
+
c = c.succ # important; increment here
|
180
|
+
write_state fp, c, m
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
tl = t & 0xFFFF_FFFF
|
185
|
+
tm = t >> 32
|
186
|
+
tm = tm & 0xFFFF
|
187
|
+
th = t >> 48
|
188
|
+
th = th & 0x0FFF
|
189
|
+
th = th | 0x1000
|
190
|
+
cl = c & 0xFF
|
191
|
+
ch = c & 0x3F00
|
192
|
+
ch = ch >> 8
|
193
|
+
ch = ch | 0x80
|
194
|
+
pack tl, tm, th, cl, ch, m
|
195
|
+
end
|
196
|
+
alias :create_v1 :create
|
197
|
+
|
198
|
+
# A simple GUID parser: just ignores unknown characters and convert
|
199
|
+
# hexadecimal dump into 16-octet object.
|
200
|
+
def parse obj
|
201
|
+
str = obj.to_s.sub %r/\Aurn:uuid:/, ''
|
202
|
+
str.gsub! %r/[^0-9A-Fa-f]/, ''
|
203
|
+
raw = str[0..31].lines.to_a.pack 'H*'
|
204
|
+
ret = new raw
|
205
|
+
ret.freeze
|
206
|
+
ret
|
207
|
+
end
|
208
|
+
|
209
|
+
# The 'primitive constructor' of this class
|
210
|
+
# Note UUID.pack(uuid.unpack) == uuid
|
211
|
+
def pack tl, tm, th, ch, cl, n
|
212
|
+
raw = [tl, tm, th, ch, cl, n].pack "NnnCCa6"
|
213
|
+
ret = new raw
|
214
|
+
ret.freeze
|
215
|
+
ret
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# The 'primitive deconstructor', or the dual to pack.
|
220
|
+
# Note UUID.pack(uuid.unpack) == uuid
|
221
|
+
def unpack
|
222
|
+
raw_bytes.unpack "NnnCCa6"
|
223
|
+
end
|
224
|
+
|
225
|
+
# Generate the string representation (a.k.a GUID) of this UUID
|
226
|
+
def to_s
|
227
|
+
a = unpack
|
228
|
+
tmp = a[-1].unpack 'C*'
|
229
|
+
a[-1] = sprintf '%02x%02x%02x%02x%02x%02x', *tmp
|
230
|
+
"%08x-%04x-%04x-%02x%02x-%s" % a
|
231
|
+
end
|
232
|
+
alias guid to_s
|
233
|
+
|
234
|
+
# Convert into a RFC4122-comforming URN representation
|
235
|
+
def to_uri
|
236
|
+
"urn:uuid:" + self.to_s
|
237
|
+
end
|
238
|
+
alias urn to_uri
|
239
|
+
|
240
|
+
# Convert into 128-bit unsigned integer
|
241
|
+
# Typically a Bignum instance, but can be a Fixnum.
|
242
|
+
def to_int
|
243
|
+
tmp = self.raw_bytes.unpack "C*"
|
244
|
+
tmp.inject do |r, i|
|
245
|
+
r * 256 | i
|
246
|
+
end
|
247
|
+
end
|
248
|
+
alias to_i to_int
|
249
|
+
|
250
|
+
# Gets the version of this UUID
|
251
|
+
# returns nil if bad version
|
252
|
+
def version
|
253
|
+
a = unpack
|
254
|
+
v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
|
255
|
+
return v if (1..5).include? v
|
256
|
+
return nil
|
257
|
+
end
|
258
|
+
|
259
|
+
# Two UUIDs are said to be equal if and only if their (byte-order
|
260
|
+
# canonicalized) integer representations are equivallent. Refer RFC4122 for
|
261
|
+
# details.
|
262
|
+
def == other
|
263
|
+
to_i == other.to_i
|
264
|
+
end
|
265
|
+
|
266
|
+
include Comparable
|
267
|
+
# UUIDs are comparable (don't know what benefits are there, though).
|
268
|
+
def <=> other
|
269
|
+
to_s <=> other.to_s
|
270
|
+
end
|
271
|
+
|
272
|
+
# Pre-defined UUID Namespaces described in RFC4122 Appendix C.
|
273
|
+
NameSpace_DNS = parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
274
|
+
NameSpace_URL = parse "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
|
275
|
+
NameSpace_OID = parse "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
|
276
|
+
NameSpace_X500 = parse "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
|
277
|
+
|
278
|
+
# The Nil UUID in RFC4122 Section 4.1.7
|
279
|
+
Nil = parse "00000000-0000-0000-0000-000000000000"
|
280
|
+
end
|
281
|
+
|
282
|
+
__END__
|
283
|
+
if __FILE__ == $0 then
|
284
|
+
require 'test/unit'
|
285
|
+
|
286
|
+
class TC_UUID < Test::Unit::TestCase
|
287
|
+
def test_v1
|
288
|
+
u1 = UUID.create
|
289
|
+
u2 = UUID.create
|
290
|
+
assert_not_equal u1, u2
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_v1_repeatability
|
294
|
+
u1 = UUID.create 1, 2, "345678"
|
295
|
+
u2 = UUID.create 1, 2, "345678"
|
296
|
+
assert_equal u1, u2
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_v3
|
300
|
+
u1 = UUID.create_md5 "foo", UUID::NameSpace_DNS
|
301
|
+
u2 = UUID.create_md5 "foo", UUID::NameSpace_DNS
|
302
|
+
u3 = UUID.create_md5 "foo", UUID::NameSpace_URL
|
303
|
+
assert_equal u1, u2
|
304
|
+
assert_not_equal u1, u3
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_v5
|
308
|
+
u1 = UUID.create_sha1 "foo", UUID::NameSpace_DNS
|
309
|
+
u2 = UUID.create_sha1 "foo", UUID::NameSpace_DNS
|
310
|
+
u3 = UUID.create_sha1 "foo", UUID::NameSpace_URL
|
311
|
+
assert_equal u1, u2
|
312
|
+
assert_not_equal u1, u3
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_v4
|
316
|
+
# This test is not perfect, because the random nature of version 4
|
317
|
+
# UUID it is not always true that the three objects below really
|
318
|
+
# differ. But in real life it's enough to say we're OK when this
|
319
|
+
# passes.
|
320
|
+
u1 = UUID.create_random
|
321
|
+
u2 = UUID.create_random
|
322
|
+
u3 = UUID.create_random
|
323
|
+
assert_not_equal u1.raw_bytes, u2.raw_bytes
|
324
|
+
assert_not_equal u1.raw_bytes, u3.raw_bytes
|
325
|
+
assert_not_equal u2.raw_bytes, u3.raw_bytes
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_pack
|
329
|
+
u1 = UUID.pack 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4,
|
330
|
+
"\000\300O\3240\310"
|
331
|
+
assert_equal UUID::NameSpace_DNS, u1
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_unpack
|
335
|
+
tl, tm, th, cl, ch, m = UUID::NameSpace_DNS.unpack
|
336
|
+
assert_equal 0x6ba7b810, tl
|
337
|
+
assert_equal 0x9dad, tm
|
338
|
+
assert_equal 0x11d1, th
|
339
|
+
assert_equal 0x80, cl
|
340
|
+
assert_equal 0xb4, ch
|
341
|
+
assert_equal "\000\300O\3240\310", m
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_parse
|
345
|
+
u1 = UUID.pack 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4,
|
346
|
+
"\000\300O\3240\310"
|
347
|
+
u2 = UUID.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
348
|
+
u3 = UUID.parse "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
349
|
+
assert_equal u1, u2
|
350
|
+
assert_equal u1, u3
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_to_s
|
354
|
+
u1 = UUID.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
355
|
+
assert_equal "6ba7b810-9dad-11d1-80b4-00c04fd430c8", u1.to_s
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_to_i
|
359
|
+
u1 = UUID.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
360
|
+
assert_equal 0x6ba7b8109dad11d180b400c04fd430c8, u1.to_i
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_version
|
364
|
+
u1 = UUID.create_v1
|
365
|
+
assert_equal 1, u1.version
|
366
|
+
u3 = UUID.create_v3 "foo", UUID::NameSpace_DNS
|
367
|
+
assert_equal 3, u3.version
|
368
|
+
u4 = UUID.create_v4
|
369
|
+
assert_equal 4, u4.version
|
370
|
+
u5 = UUID.create_v5 "foo", UUID::NameSpace_DNS
|
371
|
+
assert_equal 5, u5.version
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
# Local Variables:
|
379
|
+
# mode: ruby
|
380
|
+
# code: utf-8
|
381
|
+
# indent-tabs-mode: t
|
382
|
+
# tab-width: 3
|
383
|
+
# ruby-indent-level: 3
|
384
|
+
# fill-column: 79
|
385
|
+
# default-justification: full
|
386
|
+
# End:
|
387
|
+
# vi: ts=3 sw=3
|