jcrvalidator 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e68e95dd86cf0ba170eae8a3ead3acb7c44ab59
4
- data.tar.gz: fe3a8c25bf2e420c43db8c32f33e764f7356d766
3
+ metadata.gz: a0b80dde864c20a32ff286e29e11b5179b3fa935
4
+ data.tar.gz: 8670787681c6b2aa7639f5c1fad552f5843f2d88
5
5
  SHA512:
6
- metadata.gz: 6d8a19a053ff78eeb76b2b46ee0c48be126465a80825737e87881cbdf4c9f7e4e1b9dae9c15b0768ddb27f091f4196e761f44ab2c65cc19a19a86288bbdb8d51
7
- data.tar.gz: ba031e433185f9857056a62759caee2d7edf396cc6067d35e1bd4d3114c9dc9b27985f0bc0a299bd2128095739f0b48724afdda750e14dad575040cdb78a7a0e
6
+ metadata.gz: 3f3da7c4224cfe32ea94f0681a8bbc39b32dd095056ebdf94ae0cc8f55b5332b212fca7b07800b992e3c6357e01876bff05b3b282f45d914194ac4e3a0788708
7
+ data.tar.gz: 5cd168ff7ea72fd9671d337c4cd0830fd38e4bac75480bb4d65d7e22252186b6edf2e24576f469705483cb1dbcde127c2187c8e4c2a08c609aa5f7865f861647
@@ -14,6 +14,7 @@
14
14
 
15
15
  require 'jcr/parser'
16
16
  require 'jcr/map_rule_names'
17
+ require 'pp'
17
18
 
18
19
  module JCR
19
20
 
@@ -69,6 +70,9 @@ module JCR
69
70
  end
70
71
 
71
72
  def self.check_member_for_group node, mapping
73
+ if node.is_a? Array
74
+ node = node[0]
75
+ end
72
76
  if node[:target_rule_name]
73
77
  trule = get_name_mapping( node[:target_rule_name][:rule_name], mapping )
74
78
  disallowed_group_in_member?( trule, mapping )
@@ -51,7 +51,7 @@ module JCR
51
51
  trace( econs, "Evaluating array rule starting at #{slice_to_s(jcr)} against", data )
52
52
  trace_def( econs, "array", jcr, data )
53
53
  retval = evaluate_array( jcr, rule_atom, data, econs, behavior )
54
- trace_eval( econs, "Array", retval )
54
+ trace_eval( econs, "Array", retval, jcr, data, "array" )
55
55
  pop_trace_stack( econs )
56
56
  return retval
57
57
 
@@ -32,7 +32,7 @@ module JCR
32
32
  trace( econs, "Evaluating group rule against ", data )
33
33
  trace_def( econs, "group", jcr, data )
34
34
  retval = evaluate_group( jcr, rule_atom, data, econs, behavior )
35
- trace_eval( econs, "Group", retval )
35
+ trace_eval( econs, "Group", retval, jcr, data, "group" )
36
36
  pop_trace_stack( econs )
37
37
  return retval
38
38
 
@@ -31,7 +31,7 @@ module JCR
31
31
  trace( econs, "Evaluating member rule for key '#{data[0]}' starting at #{slice_to_s(jcr)} against ", data[1])
32
32
  trace_def( econs, "member", jcr, data )
33
33
  retval = evaluate_member( jcr, rule_atom, data, econs )
34
- trace_eval( econs, "Member", retval )
34
+ trace_eval( econs, "Member", retval, jcr, data, "member" )
35
35
  pop_trace_stack( econs )
36
36
  return retval
37
37
 
@@ -45,7 +45,7 @@ module JCR
45
45
 
46
46
 
47
47
  rules, annotations = get_rules_and_annotations( jcr )
48
- rule = rules[0]
48
+ rule = merge_rules( rules )
49
49
 
50
50
  member_match = false
51
51
 
@@ -55,7 +55,13 @@ module JCR
55
55
  member_match = true
56
56
  end
57
57
  else # must be regex
58
- match_spec = Regexp.new( rule[:member_regex][:regex].to_s )
58
+ regex = rule[:member_regex][:regex]
59
+ if regex.is_a? Array
60
+ match_spec = Regexp.new( "" )
61
+ trace( econs, "Noting empty regular expression." )
62
+ else
63
+ match_spec = Regexp.new( rule[:member_regex][:regex].to_s )
64
+ end
59
65
  if match_spec =~ data[ 0 ]
60
66
  member_match = true
61
67
  end
@@ -63,6 +69,7 @@ module JCR
63
69
 
64
70
  if member_match
65
71
  e = evaluate_rule( rule, rule_atom, data[ 1 ], econs )
72
+ e.member_found = true
66
73
  return evaluate_not( annotations, e, econs )
67
74
  end
68
75
 
@@ -74,7 +81,7 @@ module JCR
74
81
  def self.member_to_s( jcr, shallow=true )
75
82
  rules, annotations = get_rules_and_annotations( jcr )
76
83
  retval = ""
77
- rule = rules[ 0 ]
84
+ rule = merge_rules( rules )
78
85
  case
79
86
  when rule[:member_name]
80
87
  retval = %Q|"#{rule[:member_name][:q_string].to_s}"|
@@ -33,7 +33,7 @@ module JCR
33
33
  trace( econs, "Evaluating object rule starting at #{slice_to_s(jcr)} against", data )
34
34
  trace_def( econs, "object", jcr, data )
35
35
  retval = evaluate_object( jcr, rule_atom, data, econs, behavior )
36
- trace_eval( econs, "Object", retval )
36
+ trace_eval( econs, "Object", retval, jcr, data, "object" )
37
37
  pop_trace_stack( econs )
38
38
  return retval
39
39
 
@@ -124,22 +124,32 @@ module JCR
124
124
  end
125
125
  else
126
126
  trace( econs, "No member '#{k}' found in object.")
127
+ e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil)
128
+ repeat_results[ nil ] = nil if e.success
127
129
  end
128
130
 
129
131
  else
130
132
 
131
- trace( econs, "Scanning object.")
133
+ regex = lrules[0][:member_regex][:regex]
134
+ trace( econs, "Scanning object for #{regex}.")
132
135
  i = 0
136
+ found = false
133
137
  repeat_results = data.select do |k,v|
134
138
  unless behavior.checked_hash[k]
135
139
  if i < repeat_max
136
140
  e = evaluate_rule(rule, rule_atom, [k, v], econs, nil)
137
141
  behavior.checked_hash[k] = e.success
138
142
  i = i + 1 if e.success
143
+ found = true if e.member_found
139
144
  e.success
140
145
  end
141
146
  end
142
147
  end
148
+ unless found
149
+ trace( econs, "No member matching #{regex} found in object.")
150
+ e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil)
151
+ repeat_results[ nil ] = nil if e.success
152
+ end
143
153
 
144
154
  end
145
155
 
@@ -19,6 +19,7 @@ require 'addressable/uri'
19
19
  require 'addressable/template'
20
20
  require 'email_address_validator'
21
21
  require 'big-phoney'
22
+ require 'json'
22
23
 
23
24
  require 'jcr/parser'
24
25
  require 'jcr/map_rule_names'
@@ -45,7 +46,7 @@ end
45
46
  module JCR
46
47
 
47
48
  class Evaluation
48
- attr_accessor :success, :reason, :child_evaluation
49
+ attr_accessor :success, :reason, :member_found
49
50
  def initialize success, reason
50
51
  @success = success
51
52
  @reason = reason
@@ -53,8 +54,9 @@ module JCR
53
54
  end
54
55
 
55
56
  class EvalConditions
56
- attr_accessor :mapping, :callbacks, :trace, :trace_stack
57
+ attr_accessor :mapping, :callbacks, :trace, :trace_stack, :first_failure
57
58
  def initialize mapping, callbacks, trace = false
59
+ @first_failure = nil
58
60
  @mapping = mapping
59
61
  @trace = trace
60
62
  @trace_stack = []
@@ -207,6 +209,16 @@ module JCR
207
209
  return rules, annotations
208
210
  end
209
211
 
212
+ def self.merge_rules rules
213
+ new_rule = Hash.new
214
+ rules.each do |rule|
215
+ new_rule.merge!(rule) do |key,oldval,newval|
216
+ raise "error: conflict in merge of #{rule} with #{new_rule}"
217
+ end
218
+ end
219
+ return new_rule
220
+ end
221
+
210
222
  def self.evaluate_not annotations, evaluation, econs
211
223
  is_not = false
212
224
  annotations.each do |a|
@@ -296,15 +308,27 @@ module JCR
296
308
  else
297
309
  s = "** unknown rule **"
298
310
  end
299
- trace( econs, "#{type}: #{s}", data)
311
+ trace( econs, "#{type} definition: #{s}", data)
300
312
  end
301
313
  end
302
314
 
303
- def self.trace_eval econs, message, evaluation
315
+ def self.trace_eval econs, message, evaluation, jcr, data, type
304
316
  if evaluation.success
305
317
  trace( econs, "#{message} evaluation is true" )
306
318
  else
307
319
  trace( econs, "#{message} evaluation failed: #{evaluation.reason}")
320
+ unless econs.first_failure
321
+ econs.first_failure = evaluation
322
+ trace( econs, "** LIKELY ROOT CAUSE FOR FAILURE **" )
323
+ trace( econs, "***********************************" )
324
+ rule = find_first_slice( jcr )
325
+ pos = "Failed rule at line,column: #{rule.line_and_column} file position offset: #{rule.offset}"
326
+ trace( econs, pos )
327
+ trace_def( econs, type, jcr, data )
328
+ data_s = "JSON that failed to validate: #{data.to_json}"
329
+ trace( econs, data_s )
330
+ trace( econs, "***********************************" )
331
+ end
308
332
  end
309
333
  end
310
334
 
@@ -363,7 +387,7 @@ module JCR
363
387
  elsif rule[:rule]
364
388
  retval = rule_to_s( rule[:rule], shallow )
365
389
  else
366
- retval = "** unknown rule definition **"
390
+ retval = "** unknown rule definition ** #{rule}"
367
391
  end
368
392
  return retval
369
393
  end
@@ -33,7 +33,7 @@ module JCR
33
33
  rules, annotations = get_rules_and_annotations( jcr )
34
34
 
35
35
  retval = evaluate_not( annotations, evaluate_values( rules[0], rule_atom, data, econs ), econs )
36
- trace_eval( econs, "Value", retval)
36
+ trace_eval( econs, "Value", retval, jcr, data, "value")
37
37
  pop_trace_stack( econs )
38
38
  return retval
39
39
  end
@@ -219,25 +219,17 @@ module JCR
219
219
  end
220
220
 
221
221
  #
222
- # uri and uri templates
222
+ # uri and uri scheme
223
223
  #
224
224
 
225
225
  when jcr[:uri]
226
226
  return bad_value( jcr, rule_atom, "URI", data ) unless data.is_a?( String )
227
227
  uri = Addressable::URI.parse( data )
228
228
  return bad_value( jcr, rule_atom, "URI", data ) unless uri.is_a?( Addressable::URI )
229
- when jcr[:uri_template]
230
- t = jcr[:uri_template].to_s
229
+ when jcr[:uri_scheme]
230
+ t = jcr[:uri_scheme].to_s
231
231
  return bad_value( jcr, rule_atom, t, data ) unless data.is_a? String
232
- template = Addressable::Template.new( t )
233
- e = template.extract( data )
234
- if e == nil
235
- return bad_value( jcr, rule_atom, t, data )
236
- else
237
- e.each do |k,v|
238
- return bad_value( jcr, rule_atom, t, data ) unless v
239
- end
240
- end
232
+ return bad_value( jcr, rule_atom, t, data ) unless data.start_with?( t )
241
233
 
242
234
  #
243
235
  # phone and email value rules
@@ -476,8 +468,8 @@ module JCR
476
468
 
477
469
  when rule[:uri]
478
470
  retval = "URI"
479
- when rule[:uri_template]
480
- retval = "URI template #{rule[:uri_template].to_s}"
471
+ when rule[:uri_scheme]
472
+ retval = "URI with specific scheme #{rule[:uri_scheme].to_s}"
481
473
 
482
474
  when rule[:email]
483
475
  retval = "email"
data/lib/jcr/jcr.rb CHANGED
@@ -207,6 +207,13 @@ module JCR
207
207
  opt.on("-h","display help") do |help|
208
208
  options[:help] = true
209
209
  end
210
+
211
+ opt.separator ""
212
+ opt.separator "Return codes:"
213
+ opt.separator " 0 = success"
214
+ opt.separator " 1 = parsing or other bad condition"
215
+ opt.separator " 2 = fall through bad condition"
216
+ opt.separator " 3 = unsuccessful evaluation of JSON"
210
217
  end
211
218
 
212
219
  opt_parser.parse! my_argv
@@ -286,7 +293,7 @@ module JCR
286
293
  if verbose
287
294
  puts "Failure: #{e.reason}"
288
295
  end
289
- ec = 1
296
+ ec = 3
290
297
  end
291
298
  return ec
292
299
  end
data/lib/jcr/parser.rb CHANGED
@@ -36,34 +36,46 @@ module JCR
36
36
  #/ spaces? -> [ spaces ]
37
37
  rule(:wsp) { match('[\t ]') }
38
38
  # WSP is a standard ABNF production so is not expanded here
39
- rule(:comment) { str(';') >> ( str('\;') | match('[^\r\n;]') ).repeat >> match('[\r\n;]') }
40
- #! comment = ";" *( "\;" / comment-char ) comment-end-char
41
- #! comment-char = HTAB / %x20-3A / %x3C-10FFFF
42
- #! ; Any char other than ";" / CR / LF
43
- #! comment-end-char = CR / LF / ";"
39
+ rule(:dsps) { spcCmnt.repeat(1) | wsp.repeat(1) }
40
+ #! DSPs = ; Directive spaces
41
+ #! 1*WSP / ; When in one-line directive
42
+ #! 1*spcCmnt ; When in muti-line directive
43
+ rule(:dsps?) { dsps.maybe }
44
+ #/ DSPs? -> [ DSPs ]
45
+ rule(:comment) { str(';') >> match('[^\r\n]').repeat >> match('[\r\n]') }
46
+ #! comment = ";" *comment-char comment-end-char
47
+ #! comment-char = HTAB / %x20-10FFFF
48
+ #! ; Any char other than CR / LF
49
+ #! comment-end-char = CR / LF
44
50
  #!
45
51
 
46
52
  rule(:directive) { ( str('#') >> (one_line_directive | multi_line_directive) ).as(:directive) }
47
53
  #! directive = "#" (one_line_directive / multi_line_directive)
48
- rule(:one_line_directive) { ( spaces? >> ( directive_def | one_line_tbd_directive_d ) >> wsp.repeat >> match('[\r\n]') ) }
49
- #! one_line_directive = spaces?
54
+ rule(:one_line_directive) { ( dsps? >> ( directive_def | one_line_tbd_directive_d ) >> wsp.repeat >> match('[\r\n]') ) }
55
+ #! one_line_directive = DSPs?
50
56
  #! (directive_def / one_line_tbd_directive_d) *WSP eol
51
57
  rule(:multi_line_directive) { str('{') >> spcCmnt? >> (directive_def | multi_line_tbd_directive_d) >> spcCmnt? >> str('}') }
52
58
  #! multi_line_directive = "{" spcCmnt?
53
59
  #! (directive_def / multi_line_tbd_directive_d) spcCmnt? "}"
54
60
  rule(:directive_def) { jcr_version_d | ruleset_id_d | import_d }
55
61
  #! directive_def = jcr_version_d / ruleset_id_d / import_d
56
- rule(:jcr_version_d) { (str('jcr-version') >> spaces >> non_neg_integer.as(:major_version) >> str('.') >> non_neg_integer.as(:minor_version)).as(:jcr_version_d) }
57
- #! jcr_version_d = jcr-version-kw spaces major_version "." minor_version
62
+ rule(:jcr_version_d) { ( str('jcr-version') >> dsps >>
63
+ non_neg_integer.as(:major_version) >> str('.') >> non_neg_integer.as(:minor_version) >>
64
+ ( dsps >> str('+') >> dsps? >> extension_id ).repeat
65
+ ).as(:jcr_version_d) }
66
+ #! jcr_version_d = jcr-version-kw DSPs major_version "." minor_version
67
+ #! *( DSPs "+" DSPs? extension_id )
58
68
  #> jcr-version-kw = "jcr-version"
59
69
  #! major_version = non_neg_integer
60
70
  #! minor_version = non_neg_integer
61
- rule(:ruleset_id_d) { (str('ruleset-id') >> spaces >> ruleset_id.as(:ruleset_id)).as(:ruleset_id_d) }
62
- #! ruleset_id_d = ruleset-id-kw spaces ruleset_id
71
+ rule(:extension_id) { match('[a-zA-Z]') >> match('[\S]').repeat }
72
+ #! extension_id = ALPHA *not-space
73
+ rule(:ruleset_id_d) { (str('ruleset-id') >> dsps >> ruleset_id.as(:ruleset_id)).as(:ruleset_id_d) }
74
+ #! ruleset_id_d = ruleset-id-kw DSPs ruleset_id
63
75
  #> ruleset-id-kw = "ruleset-id"
64
- rule(:import_d) { (str('import') >> spaces >> ruleset_id.as(:ruleset_id) >> ( spaces >> str('as') >> spaces >> ruleset_id_alias ).maybe).as(:import_d) }
65
- #! import_d = import-kw spaces ruleset_id
66
- #! [ spaces as_kw spaces ruleset_id_alias ]
76
+ rule(:import_d) { (str('import') >> dsps >> ruleset_id.as(:ruleset_id) >> ( dsps >> str('as') >> dsps >> ruleset_id_alias ).maybe).as(:import_d) }
77
+ #! import_d = import-kw DSPs ruleset_id
78
+ #! [ DSPs as_kw DSPs ruleset_id_alias ]
67
79
  #> import-kw = "import"
68
80
  #> as-kw = "as"
69
81
  rule(:ruleset_id) { match('[a-zA-Z]') >> match('[\S]').repeat }
@@ -77,9 +89,9 @@ module JCR
77
89
  #! one_line_directive_parameters = *not_eol
78
90
  #! not_eol = HTAB / %x20-10FFFF
79
91
  #! eol = CR / LF
80
- rule(:multi_line_tbd_directive_d) { name.as(:directive_name) >> ( spaces >> multi_line_directive_parameters.as(:directive_parameters) ).maybe }
92
+ rule(:multi_line_tbd_directive_d) { name.as(:directive_name) >> ( spcCmnt.repeat(1) >> multi_line_directive_parameters.as(:directive_parameters) ).maybe }
81
93
  #! multi_line_tbd_directive_d = directive_name
82
- #! [ spaces multi_line_directive_parameters ]
94
+ #! [ 1*spcCmnt multi_line_directive_parameters ]
83
95
  rule(:multi_line_directive_parameters) { multi_line_parameters }
84
96
  #! multi_line_directive_parameters = multi_line_parameters
85
97
  rule(:multi_line_parameters) { (comment | q_string | regex | match('[^"/;}]')).repeat }
@@ -243,8 +255,8 @@ module JCR
243
255
  rule(:idn_type) { str('idn').as(:idn) }
244
256
  #! idn_type = idn-kw
245
257
  #> idn-kw = "idn"
246
- rule(:uri_range) { str('uri..') >> uri_template }
247
- #! uri_range = uri-dotdot-kw uri_template
258
+ rule(:uri_range) { str('uri..') >> uri_scheme }
259
+ #! uri_range = uri-dotdot-kw uri_scheme
248
260
  #> uri-dotdot-kw = "uri.."
249
261
  rule(:uri_type) { str('uri').as(:uri) }
250
262
  #! uri_type = uri-kw
@@ -414,8 +426,8 @@ module JCR
414
426
  #! regex_modifiers = *( "i" / "s" / "x" )
415
427
  #!
416
428
 
417
- rule(:uri_template) { ( match('[a-zA-Z{}]').repeat(1) >> str(':') >> match('[\S]').repeat(1) ).as(:uri_template) }
418
- #! uri_template = 1*ALPHA ":" 1*not-space
429
+ rule(:uri_scheme) { ( match('[a-zA-Z]').repeat(1) ).as(:uri_scheme) }
430
+ #! uri_scheme = 1*ALPHA
419
431
 
420
432
  end
421
433
 
@@ -52,10 +52,10 @@ module JCR
52
52
  major = directive[:major_version].to_str.to_i
53
53
  minor = directive[:minor_version].to_str.to_i
54
54
  if major != 0
55
- raise "jcr version #{major}.#{minor} is incompatible with 0.5"
55
+ raise "jcr version #{major}.#{minor} is incompatible with 0.7"
56
56
  end
57
- if minor != 5
58
- raise "jcr version #{major}.#{minor} is incompatible with 0.5"
57
+ if minor != 7
58
+ raise "jcr version #{major}.#{minor} is incompatible with 0.7"
59
59
  end
60
60
  end
61
61
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jcrvalidator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Newton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-16 00:00:00.000000000 Z
12
+ date: 2016-07-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parslet