Skip to content

Commit

Permalink
Finish 3.1.14
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed May 29, 2021
2 parents 455fa89 + e6f2255 commit bb94168
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.13
3.1.14
57 changes: 57 additions & 0 deletions lib/rdf/model/literal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,37 @@ def ==(other)
end
alias_method :===, :==

##
# Compares `self` to `other` for sorting purposes (with type check).
#
# @param [Object] other
# @return [Integer] `-1`, `0`, or `1`
def <=>(other)
case other
when Literal
case
when self.eql?(other)
0
when self.language? && other.language?
# Literals with languages can compare if languages are identical
self.to_s <=> other.to_s
when self.simple? && other.simple?
self.to_s <=> other.to_s
when !self.valid?
type_error("#{self.inspect} is invalid") || 0
when !other.valid?
type_error("#{other.inspect} is invalid") || 0
when self.comperable_datatype2?(other)
self.object <=> other.object
else
type_error("#{self.inspect} and #{other.inspect} are not comperable") || 0
end
when String
self.simple? && self.value <=> other
else 1
end
end

##
# Returns `true` if this is a plain literal. A plain literal
# may have a language, but may not have a datatype. For
Expand Down Expand Up @@ -399,6 +430,32 @@ def comperable_datatype?(other)
end
end

##
# Returns `true` if the literal has a datatype and the comparison should
# return false instead of raise a type error.
#
# Used for <=> operator.
#
# This behavior is intuited from SPARQL data-r2/expr-equal/eq-2-2
# @return [Boolean]
def comperable_datatype2?(other)
case self
when RDF::Literal::Numeric, RDF::Literal::Boolean
case other
when RDF::Literal::Numeric, RDF::Literal::Boolean
true
else
self.plain? || other.plain? ||
self.language? || other.language? ||
self.datatype == other.datatype
end
else
self.plain? || other.plain? ||
self.language? || other.language? ||
self.datatype == other.datatype
end
end

##
# Converts this literal into its canonical lexical representation.
#
Expand Down
6 changes: 4 additions & 2 deletions lib/rdf/model/literal/numeric.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class Numeric < Literal
# @return [Integer] `-1`, `0`, or `1`
# @since 0.3.0
def <=>(other)
# If lexically invalid, use regular literal testing
return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)

case other
when ::Numeric
to_d <=> other
Expand All @@ -30,11 +33,10 @@ def <=>(other)
# @since 0.3.0
def ==(other)
# If lexically invalid, use regular literal testing
return super unless self.valid?
return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)

case other
when Literal::Numeric
return super unless other.valid?
(cmp = (self <=> other)) ? cmp.zero? : false
when RDF::URI, RDF::Node
# Interpreting SPARQL data-r2/expr-equal/eq-2-2, numeric can't be compared with other types
Expand Down
2 changes: 1 addition & 1 deletion lib/rdf/model/statement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def node?
# @see RDF::Literal#==
# @see RDF::Query::Variable#==
def eql?(other)
other.is_a?(Statement) && self == other && (self.graph_name || false) == (other.graph_name || false)
other.is_a?(Statement) && self.to_a.eql?(other.to_a) && (self.graph_name || false) == (other.graph_name || false)
end

##
Expand Down
6 changes: 6 additions & 0 deletions lib/rdf/query/pattern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ def initialize!
super
end

##
# Create a new pattern from the quads, recursivly dupping sub-patterns.
def dup
self.class.from(self.to_quad.map {|t| t.is_a?(RDF::Query::Pattern) ? t.dup : t})
end

##
# Any additional options for this pattern.
#
Expand Down
4 changes: 2 additions & 2 deletions spec/model_literal_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1454,9 +1454,9 @@ def self.literals(*selector)
"eq-2-2(bug) 'zzz'='zzz'^^<unknown>" => [RDF::Literal("zzz"), RDF::Literal("zzz", datatype: RDF::URI("unknown"))],
"numeric '1'=1" => [RDF::Literal("1"), RDF::Literal(1)],
"numeric 1='1'" => [RDF::Literal(1), RDF::Literal("1")],
"numeric 1=<xyz>" => [RDF::Literal(1), RDF::URI("xyz")], # From expr-equal/expr-2-2
"numeric 1=<xyz>" => [RDF::Literal(1), RDF::URI("http://example/xyz")], # From expr-equal/expr-2-2
"numeric 1=_:xyz" => [RDF::Literal(1), RDF::Node.new("xyz")], # From expr-equal/expr-2-2
"numeric <xyz>=1" => [RDF::URI("xyz"), RDF::Literal(1)], # From expr-equal/expr-2-2
"numeric <xyz>=1" => [RDF::URI("http://example/xyz"), RDF::Literal(1)], # From expr-equal/expr-2-2
"numeric _:xyz=1" => [RDF::Node.new("xyz"), RDF::Literal(1)], # From expr-equal/expr-2-2
"open-eq-04 'a'^^<unknown>=1" => [RDF::Literal.new("a", datatype: RDF::URI("unknown")), RDF::Literal(1)],
"open-eq-06 'b'^^<unknown>='a'^^<unknown>" => [RDF::Literal.new("b", datatype: RDF::URI("unknown")), RDF::Literal.new("a", datatype: RDF::URI("unknown"))],
Expand Down

0 comments on commit bb94168

Please sign in to comment.