json-schema 2.8.1 → 6.1.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -11
  3. data/lib/json-schema/attribute.rb +15 -16
  4. data/lib/json-schema/attributes/additionalitems.rb +1 -0
  5. data/lib/json-schema/attributes/additionalproperties.rb +4 -7
  6. data/lib/json-schema/attributes/allof.rb +33 -6
  7. data/lib/json-schema/attributes/anyof.rb +4 -4
  8. data/lib/json-schema/attributes/const.rb +15 -0
  9. data/lib/json-schema/attributes/dependencies.rb +1 -0
  10. data/lib/json-schema/attributes/disallow.rb +2 -1
  11. data/lib/json-schema/attributes/divisibleby.rb +1 -1
  12. data/lib/json-schema/attributes/enum.rb +3 -3
  13. data/lib/json-schema/attributes/extends.rb +10 -8
  14. data/lib/json-schema/attributes/format.rb +2 -1
  15. data/lib/json-schema/attributes/formats/custom.rb +5 -7
  16. data/lib/json-schema/attributes/formats/date.rb +2 -1
  17. data/lib/json-schema/attributes/formats/date_time.rb +4 -3
  18. data/lib/json-schema/attributes/formats/date_time_v4.rb +2 -1
  19. data/lib/json-schema/attributes/formats/ip.rb +3 -3
  20. data/lib/json-schema/attributes/formats/time.rb +1 -1
  21. data/lib/json-schema/attributes/formats/uri.rb +2 -1
  22. data/lib/json-schema/attributes/items.rb +1 -0
  23. data/lib/json-schema/attributes/limit.rb +2 -2
  24. data/lib/json-schema/attributes/limits/numeric.rb +1 -1
  25. data/lib/json-schema/attributes/maxdecimal.rb +2 -2
  26. data/lib/json-schema/attributes/not.rb +2 -2
  27. data/lib/json-schema/attributes/oneof.rb +9 -11
  28. data/lib/json-schema/attributes/pattern.rb +1 -1
  29. data/lib/json-schema/attributes/patternproperties.rb +2 -1
  30. data/lib/json-schema/attributes/properties.rb +10 -10
  31. data/lib/json-schema/attributes/properties_v4.rb +2 -2
  32. data/lib/json-schema/attributes/propertynames.rb +23 -0
  33. data/lib/json-schema/attributes/ref.rb +19 -18
  34. data/lib/json-schema/attributes/required.rb +6 -5
  35. data/lib/json-schema/attributes/type.rb +11 -10
  36. data/lib/json-schema/attributes/type_v4.rb +3 -3
  37. data/lib/json-schema/attributes/uniqueitems.rb +1 -1
  38. data/lib/json-schema/errors/validation_error.rb +10 -10
  39. data/lib/json-schema/schema/reader.rb +4 -2
  40. data/lib/json-schema/schema/validator.rb +4 -4
  41. data/lib/json-schema/schema.rb +13 -14
  42. data/lib/json-schema/util/array_set.rb +2 -4
  43. data/lib/json-schema/util/uri.rb +100 -77
  44. data/lib/json-schema/util/uuid.rb +204 -226
  45. data/lib/json-schema/validator.rb +173 -156
  46. data/lib/json-schema/validators/draft1.rb +21 -23
  47. data/lib/json-schema/validators/draft2.rb +22 -24
  48. data/lib/json-schema/validators/draft3.rb +26 -28
  49. data/lib/json-schema/validators/draft4.rb +34 -36
  50. data/lib/json-schema/validators/draft6.rb +36 -36
  51. data/lib/json-schema/validators/hyper-draft1.rb +2 -3
  52. data/lib/json-schema/validators/hyper-draft2.rb +2 -3
  53. data/lib/json-schema/validators/hyper-draft3.rb +2 -3
  54. data/lib/json-schema/validators/hyper-draft4.rb +2 -3
  55. data/lib/json-schema/validators/hyper-draft6.rb +2 -3
  56. data/lib/json-schema.rb +3 -3
  57. data/resources/draft-06.json +12 -12
  58. metadata +60 -32
@@ -23,262 +23,240 @@
23
23
  # 2009-02-20: Modified by Pablo Lorenzoni <pablo@propus.com.br> to correctly
24
24
  # include the version in the raw_bytes.
25
25
 
26
-
27
26
  require 'digest/md5'
28
27
  require 'digest/sha1'
29
28
  require 'tmpdir'
30
29
 
31
30
  module JSON
32
31
  module Util
33
-
34
32
  # Pure ruby UUID generator, which is compatible with RFC4122
35
33
  UUID = Struct.new :raw_bytes
36
-
34
+
37
35
  class UUID
38
- private_class_method :new
36
+ private_class_method :new
37
+
38
+ class << self
39
+ def mask(v, str)
40
+ nstr = str.bytes.to_a
41
+ version = [0, 16, 32, 48, 64, 80][v]
42
+ nstr[6] &= 0b00001111
43
+ nstr[6] |= version
44
+ # nstr[7] &= 0b00001111
45
+ # nstr[7] |= 0b01010000
46
+ nstr[8] &= 0b00111111
47
+ nstr[8] |= 0b10000000
48
+ str = +''
49
+ nstr.each { |s| str << s.chr }
50
+ str
51
+ end
39
52
 
40
- class << self
41
- def mask19 v, str # :nodoc
42
- nstr = str.bytes.to_a
43
- version = [0, 16, 32, 48, 64, 80][v]
44
- nstr[6] &= 0b00001111
45
- nstr[6] |= version
46
- # nstr[7] &= 0b00001111
47
- # nstr[7] |= 0b01010000
48
- nstr[8] &= 0b00111111
49
- nstr[8] |= 0b10000000
50
- str = ''
51
- nstr.each { |s| str << s.chr }
52
- str
53
- end
53
+ private :mask
54
54
 
55
- def mask18 v, str # :nodoc
56
- version = [0, 16, 32, 48, 64, 80][v]
57
- str[6] &= 0b00001111
58
- str[6] |= version
59
- # str[7] &= 0b00001111
60
- # str[7] |= 0b01010000
61
- str[8] &= 0b00111111
62
- str[8] |= 0b10000000
63
- str
64
- end
55
+ # UUID generation using SHA1. Recommended over create_md5.
56
+ # Namespace object is another UUID, some of them are pre-defined below.
57
+ def create_sha1(str, namespace)
58
+ sha1 = Digest::SHA1.new
59
+ sha1.update namespace.raw_bytes
60
+ sha1.update str
61
+ sum = sha1.digest
62
+ raw = mask 5, sum[0..15]
63
+ ret = new raw
64
+ ret.freeze
65
+ ret
66
+ end
67
+ alias create_v5 create_sha1
65
68
 
66
- def mask v, str
67
- if RUBY_VERSION >= "1.9.0"
68
- return mask19 v, str
69
- else
70
- return mask18 v, str
71
- end
72
- end
73
- private :mask, :mask18, :mask19
69
+ # UUID generation using MD5 (for backward compat.)
70
+ def create_md5(str, namespace)
71
+ md5 = Digest::MD5.new
72
+ md5.update namespace.raw_bytes
73
+ md5.update str
74
+ sum = md5.digest
75
+ raw = mask 3, sum[0..16]
76
+ ret = new raw
77
+ ret.freeze
78
+ ret
79
+ end
80
+ alias create_v3 create_md5
74
81
 
75
- # UUID generation using SHA1. Recommended over create_md5.
76
- # Namespace object is another UUID, some of them are pre-defined below.
77
- def create_sha1 str, namespace
78
- sha1 = Digest::SHA1.new
79
- sha1.update namespace.raw_bytes
80
- sha1.update str
81
- sum = sha1.digest
82
- raw = mask 5, sum[0..15]
83
- ret = new raw
84
- ret.freeze
85
- ret
86
- end
87
- alias :create_v5 :create_sha1
82
+ # UUID generation using random-number generator. From it's random
83
+ # nature, there's no warranty that the created ID is really universaly
84
+ # unique.
85
+ def create_random
86
+ rnd = [
87
+ rand(0x100000000),
88
+ rand(0x100000000),
89
+ rand(0x100000000),
90
+ rand(0x100000000),
91
+ ].pack 'N4'
92
+ raw = mask 4, rnd
93
+ ret = new raw
94
+ ret.freeze
95
+ ret
96
+ end
97
+ alias create_v4 create_random
88
98
 
89
- # UUID generation using MD5 (for backward compat.)
90
- def create_md5 str, namespace
91
- md5 = Digest::MD5.new
92
- md5.update namespace.raw_bytes
93
- md5.update str
94
- sum = md5.digest
95
- raw = mask 3, sum[0..16]
96
- ret = new raw
97
- ret.freeze
98
- ret
99
- end
100
- alias :create_v3 :create_md5
99
+ def read_state(fp) # :nodoc:
100
+ fp.rewind
101
+ Marshal.load fp.read
102
+ end
101
103
 
102
- # UUID generation using random-number generator. From it's random
103
- # nature, there's no warranty that the created ID is really universaly
104
- # unique.
105
- def create_random
106
- rnd = [
107
- rand(0x100000000),
108
- rand(0x100000000),
109
- rand(0x100000000),
110
- rand(0x100000000),
111
- ].pack "N4"
112
- raw = mask 4, rnd
113
- ret = new raw
114
- ret.freeze
115
- ret
116
- end
117
- alias :create_v4 :create_random
104
+ def write_state(fp, c, m) # :nodoc:
105
+ fp.rewind
106
+ str = Marshal.dump [c, m]
107
+ fp.write str
108
+ end
118
109
 
119
- def read_state fp # :nodoc:
120
- fp.rewind
121
- Marshal.load fp.read
122
- end
110
+ private :read_state, :write_state
111
+ STATE_FILE = 'ruby-uuid'
123
112
 
124
- def write_state fp, c, m # :nodoc:
125
- fp.rewind
126
- str = Marshal.dump [c, m]
127
- fp.write str
128
- end
113
+ # create the "version 1" UUID with current system clock, current UTC
114
+ # timestamp, and the IEEE 802 address (so-called MAC address).
115
+ #
116
+ # Speed notice: it's slow. It writes some data into hard drive on every
117
+ # invokation. If you want to speed this up, try remounting tmpdir with a
118
+ # memory based filesystem (such as tmpfs). STILL slow? then no way but
119
+ # rewrite it with c :)
120
+ def create(clock = nil, time = nil, mac_addr = nil)
121
+ c = t = m = nil
122
+ Dir.chdir Dir.tmpdir do
123
+ unless FileTest.exist? STATE_FILE
124
+ # Generate a pseudo MAC address because we have no pure-ruby way
125
+ # to know the MAC address of the NIC this system uses. Note
126
+ # that cheating with pseudo arresses here is completely legal:
127
+ # see Section 4.5 of RFC4122 for details.
128
+ sha1 = Digest::SHA1.new
129
+ 256.times do
130
+ r = [rand(0x100000000)].pack 'N'
131
+ sha1.update r
132
+ end
133
+ str = sha1.digest
134
+ r = rand 14 # 20-6
135
+ node = str[r, 6] || str
136
+ nnode = node.bytes.to_a
137
+ nnode[0] |= 0x01
138
+ node = ''
139
+ nnode.each { |s| node << s.chr }
140
+ k = rand 0x40000
141
+ open STATE_FILE, 'w' do |fp|
142
+ fp.flock IO::LOCK_EX
143
+ write_state fp, k, node
144
+ fp.chmod 0o777 # must be world writable
145
+ end
146
+ end
147
+ open STATE_FILE, 'r+' do |fp|
148
+ fp.flock IO::LOCK_EX
149
+ c, m = read_state fp
150
+ c = clock % 0x4000 if clock
151
+ m = mac_addr if mac_addr
152
+ t = time
153
+ if t.nil?
154
+ # UUID epoch is 1582/Oct/15
155
+ tt = Time.now
156
+ t = (tt.to_i * 10_000_000) + (tt.tv_usec * 10) + 0x01B21DD213814000
157
+ end
158
+ c = c.succ # important; increment here
159
+ write_state fp, c, m
160
+ end
161
+ end
129
162
 
130
- private :read_state, :write_state
131
- STATE_FILE = 'ruby-uuid'
163
+ tl = t & 0xFFFF_FFFF
164
+ tm = t >> 32
165
+ tm &= 0xFFFF
166
+ th = t >> 48
167
+ th &= 0x0FFF
168
+ th |= 0x1000
169
+ cl = c & 0xFF
170
+ ch = c & 0x3F00
171
+ ch >>= 8
172
+ ch |= 0x80
173
+ pack tl, tm, th, cl, ch, m
174
+ end
175
+ alias create_v1 create
132
176
 
133
- # create the "version 1" UUID with current system clock, current UTC
134
- # timestamp, and the IEEE 802 address (so-called MAC address).
135
- #
136
- # Speed notice: it's slow. It writes some data into hard drive on every
137
- # invokation. If you want to speed this up, try remounting tmpdir with a
138
- # memory based filesystem (such as tmpfs). STILL slow? then no way but
139
- # rewrite it with c :)
140
- def create clock=nil, time=nil, mac_addr=nil
141
- c = t = m = nil
142
- Dir.chdir Dir.tmpdir do
143
- unless FileTest.exist? STATE_FILE then
144
- # Generate a pseudo MAC address because we have no pure-ruby way
145
- # to know the MAC address of the NIC this system uses. Note
146
- # that cheating with pseudo arresses here is completely legal:
147
- # see Section 4.5 of RFC4122 for details.
148
- sha1 = Digest::SHA1.new
149
- 256.times do
150
- r = [rand(0x100000000)].pack "N"
151
- sha1.update r
152
- end
153
- str = sha1.digest
154
- r = rand 14 # 20-6
155
- node = str[r, 6] || str
156
- if RUBY_VERSION >= "1.9.0"
157
- nnode = node.bytes.to_a
158
- nnode[0] |= 0x01
159
- node = ''
160
- nnode.each { |s| node << s.chr }
161
- else
162
- node[0] |= 0x01 # multicast bit
163
- end
164
- k = rand 0x40000
165
- open STATE_FILE, 'w' do |fp|
166
- fp.flock IO::LOCK_EX
167
- write_state fp, k, node
168
- fp.chmod 0o777 # must be world writable
169
- end
170
- end
171
- open STATE_FILE, 'r+' do |fp|
172
- fp.flock IO::LOCK_EX
173
- c, m = read_state fp
174
- c = clock % 0x4000 if clock
175
- m = mac_addr if mac_addr
176
- t = time
177
- if t.nil? then
178
- # UUID epoch is 1582/Oct/15
179
- tt = Time.now
180
- t = tt.to_i*10000000 + tt.tv_usec*10 + 0x01B21DD213814000
181
- end
182
- c = c.succ # important; increment here
183
- write_state fp, c, m
184
- end
185
- end
177
+ # A simple GUID parser: just ignores unknown characters and convert
178
+ # hexadecimal dump into 16-octet object.
179
+ def parse(obj)
180
+ str = obj.to_s.sub(/\Aurn:uuid:/, '')
181
+ str.gsub!(/[^0-9A-Fa-f]/, '')
182
+ raw = str[0..31].lines.to_a.pack 'H*'
183
+ ret = new raw
184
+ ret.freeze
185
+ ret
186
+ end
186
187
 
187
- tl = t & 0xFFFF_FFFF
188
- tm = t >> 32
189
- tm = tm & 0xFFFF
190
- th = t >> 48
191
- th = th & 0x0FFF
192
- th = th | 0x1000
193
- cl = c & 0xFF
194
- ch = c & 0x3F00
195
- ch = ch >> 8
196
- ch = ch | 0x80
197
- pack tl, tm, th, cl, ch, m
198
- end
199
- alias :create_v1 :create
188
+ # The 'primitive constructor' of this class
189
+ # Note UUID.pack(uuid.unpack) == uuid
190
+ def pack(tl, tm, th, ch, cl, n)
191
+ raw = [tl, tm, th, ch, cl, n].pack 'NnnCCa6'
192
+ ret = new raw
193
+ ret.freeze
194
+ ret
195
+ end
196
+ end
200
197
 
201
- # A simple GUID parser: just ignores unknown characters and convert
202
- # hexadecimal dump into 16-octet object.
203
- def parse obj
204
- str = obj.to_s.sub %r/\Aurn:uuid:/, ''
205
- str.gsub! %r/[^0-9A-Fa-f]/, ''
206
- raw = str[0..31].lines.to_a.pack 'H*'
207
- ret = new raw
208
- ret.freeze
209
- ret
210
- end
198
+ # The 'primitive deconstructor', or the dual to pack.
199
+ # Note UUID.pack(uuid.unpack) == uuid
200
+ def unpack
201
+ raw_bytes.unpack 'NnnCCa6'
202
+ end
211
203
 
212
- # The 'primitive constructor' of this class
213
- # Note UUID.pack(uuid.unpack) == uuid
214
- def pack tl, tm, th, ch, cl, n
215
- raw = [tl, tm, th, ch, cl, n].pack "NnnCCa6"
216
- ret = new raw
217
- ret.freeze
218
- ret
219
- end
220
- end
204
+ # Generate the string representation (a.k.a GUID) of this UUID
205
+ def to_s
206
+ a = unpack
207
+ tmp = a[-1].unpack 'C*'
208
+ a[-1] = format '%02x%02x%02x%02x%02x%02x', *tmp
209
+ '%08x-%04x-%04x-%02x%02x-%s' % a
210
+ end
211
+ alias guid to_s
221
212
 
222
- # The 'primitive deconstructor', or the dual to pack.
223
- # Note UUID.pack(uuid.unpack) == uuid
224
- def unpack
225
- raw_bytes.unpack "NnnCCa6"
226
- end
213
+ # Convert into a RFC4122-comforming URN representation
214
+ def to_uri
215
+ 'urn:uuid:' + to_s
216
+ end
217
+ alias urn to_uri
227
218
 
228
- # Generate the string representation (a.k.a GUID) of this UUID
229
- def to_s
230
- a = unpack
231
- tmp = a[-1].unpack 'C*'
232
- a[-1] = sprintf '%02x%02x%02x%02x%02x%02x', *tmp
233
- "%08x-%04x-%04x-%02x%02x-%s" % a
234
- end
235
- alias guid to_s
219
+ # Convert into 128-bit unsigned integer
220
+ def to_int
221
+ tmp = raw_bytes.unpack 'C*'
222
+ tmp.inject do |r, i|
223
+ (r * 256) | i
224
+ end
225
+ end
226
+ alias to_i to_int
236
227
 
237
- # Convert into a RFC4122-comforming URN representation
238
- def to_uri
239
- "urn:uuid:" + self.to_s
240
- end
241
- alias urn to_uri
228
+ # Gets the version of this UUID
229
+ # returns nil if bad version
230
+ def version
231
+ a = unpack
232
+ v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
233
+ return v if (1..5).include? v
242
234
 
243
- # Convert into 128-bit unsigned integer
244
- def to_int
245
- tmp = self.raw_bytes.unpack "C*"
246
- tmp.inject do |r, i|
247
- r * 256 | i
248
- end
249
- end
250
- alias to_i to_int
235
+ nil
236
+ end
251
237
 
252
- # Gets the version of this UUID
253
- # returns nil if bad version
254
- def version
255
- a = unpack
256
- v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
257
- return v if (1..5).include? v
258
- return nil
259
- end
238
+ # Two UUIDs are said to be equal if and only if their (byte-order
239
+ # canonicalized) integer representations are equivalent. Refer RFC4122 for
240
+ # details.
241
+ def ==(other)
242
+ to_i == other.to_i
243
+ end
260
244
 
261
- # Two UUIDs are said to be equal if and only if their (byte-order
262
- # canonicalized) integer representations are equivallent. Refer RFC4122 for
263
- # details.
264
- def == other
265
- to_i == other.to_i
266
- end
245
+ include Comparable
267
246
 
268
- include Comparable
269
- # UUIDs are comparable (don't know what benefits are there, though).
270
- def <=> other
271
- to_s <=> other.to_s
272
- end
247
+ # UUIDs are comparable (don't know what benefits are there, though).
248
+ def <=>(other)
249
+ to_s <=> other.to_s
250
+ end
273
251
 
274
- # Pre-defined UUID Namespaces described in RFC4122 Appendix C.
275
- NameSpace_DNS = parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
276
- NameSpace_URL = parse "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
277
- NameSpace_OID = parse "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
278
- NameSpace_X500 = parse "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
252
+ # Pre-defined UUID Namespaces described in RFC4122 Appendix C.
253
+ NameSpace_DNS = parse '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
254
+ NameSpace_URL = parse '6ba7b811-9dad-11d1-80b4-00c04fd430c8'
255
+ NameSpace_OID = parse '6ba7b812-9dad-11d1-80b4-00c04fd430c8'
256
+ NameSpace_X500 = parse '6ba7b814-9dad-11d1-80b4-00c04fd430c8'
279
257
 
280
- # The Nil UUID in RFC4122 Section 4.1.7
281
- Nil = parse "00000000-0000-0000-0000-000000000000"
258
+ # The Nil UUID in RFC4122 Section 4.1.7
259
+ Nil = parse '00000000-0000-0000-0000-000000000000'
282
260
  end
283
261
  end
284
- end
262
+ end