lib/shex/algebra/node_constraint.rb in shex-0.4.0 vs lib/shex/algebra/node_constraint.rb in shex-0.5.0

- old
+ new

@@ -1,5 +1,6 @@ +# -*- encoding: utf-8 -*- module ShEx::Algebra ## class NodeConstraint < Operator include ShapeExpression NAME = :nodeConstraint @@ -56,39 +57,47 @@ def satisfies_datatype?(value, depth: 0) dt = op_fetch(:datatype) return true unless dt not_satisfied "Node was #{value.inspect}, expected datatype #{dt}", depth: depth unless - value.is_a?(RDF::Literal) && value.datatype == RDF::URI(dt) + value.is_a?(RDF::Literal) && value.datatype == RDF::URI(dt) && value.valid? status "right datatype: #{value}: #{dt}", depth: depth true end ## # String Facet Constraint # Checks all length/minlength/maxlength/pattern facets against the string representation of the value. # @return [Boolean] `true` if satisfied, `false` if it does not apply # @raise [ShEx::NotSatisfied] if not satisfied + # @todo using the XPath regexp engine supports additional flags "s" and "q" def satisfies_string_facet?(value, depth: 0) length = op_fetch(:length) minlength = op_fetch(:minlength) maxlength = op_fetch(:maxlength) - pattern = op_fetch(:pattern) + pat = (operands.detect {|op| op.is_a?(Array) && op[0] == :pattern} || []) + pattern = pat[1] + flags = 0 + flags |= Regexp::EXTENDED if pat[2].to_s.include?("x") + flags |= Regexp::IGNORECASE if pat[2].to_s.include?("i") + flags |= Regexp::MULTILINE if pat[2].to_s.include?("m") + return true if (length || minlength || maxlength || pattern).nil? v_s = case value when RDF::Node then value.id else value.to_s end + not_satisfied "Node #{v_s.inspect} length not #{length}", depth: depth if length && v_s.length != length.to_i not_satisfied"Node #{v_s.inspect} length < #{minlength}", depth: depth if minlength && v_s.length < minlength.to_i not_satisfied "Node #{v_s.inspect} length > #{maxlength}", depth: depth if maxlength && v_s.length > maxlength.to_i not_satisfied "Node #{v_s.inspect} does not match #{pattern}", depth: depth if - pattern && !Regexp.new(pattern).match(v_s) + pattern && !Regexp.new(pattern, flags).match(v_s) status "right string facet: #{value}", depth: depth true end ##