Skip to content
Browse files

Allow invalid date, time & dateTime literals. Perform comparisons of …

…objects rather than values for lexically valid literals.
  • Loading branch information...
1 parent 395bfdf commit 4b19e62c85f9e709f4d428f64ff5263444abe58e @gkellogg gkellogg committed Sep 6, 2011
Showing with 57 additions and 239 deletions.
  1. +18 −1 lib/rdf/model/literal/date.rb
  2. +18 −1 lib/rdf/model/literal/datetime.rb
  3. +20 −1 lib/rdf/model/literal/time.rb
  4. +1 −236 spec/model_literal_spec.rb
View
19 lib/rdf/model/literal/date.rb
@@ -19,7 +19,7 @@ def initialize(value, options = {})
when value.is_a?(::Date) then value
when value.respond_to?(:to_date) then value.to_date # Ruby 1.9+
else ::Date.parse(value.to_s)
- end
+ end rescue nil
end
##
@@ -51,5 +51,22 @@ def valid?
def to_s
@string || @object.strftime('%Y-%m-%d%Z').sub(/\+00:00|UTC/, 'Z')
end
+
+ ##
+ # Equal compares as Date objects
+ def ==(other)
+ # If lexically invalid, use regular literal testing
+ return super unless self.valid?
+
+ case other
+ when Literal::Date
+ return super unless other.valid?
+ self.object == other.object
+ when Literal::Time, Literal::DateTime
+ false
+ else
+ super
+ end
+ end
end # Date
end; end # RDF::Literal
View
19 lib/rdf/model/literal/datetime.rb
@@ -19,7 +19,7 @@ def initialize(value, options = {})
when value.is_a?(::DateTime) then value
when value.respond_to?(:to_datetime) then value.to_datetime # Ruby 1.9+
else ::DateTime.parse(value.to_s)
- end
+ end rescue nil
end
##
@@ -51,5 +51,22 @@ def valid?
def to_s
@string || @object.strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
end
+
+ ##
+ # Equal compares as DateTime objects
+ def ==(other)
+ # If lexically invalid, use regular literal testing
+ return super unless self.valid?
+
+ case other
+ when Literal::DateTime
+ return super unless other.valid?
+ self.object == other.object
+ when Literal::Time, Literal::Date
+ false
+ else
+ super
+ end
+ end
end # DateTime
end; end # RDF::Literal
View
21 lib/rdf/model/literal/time.rb
@@ -23,7 +23,7 @@ def initialize(value, options = {})
when value.is_a?(::Time) then value
when value.respond_to?(:to_time) then value.to_time # Ruby 1.9+
else ::Time.parse(value.to_s)
- end
+ end rescue nil
end
##
@@ -51,5 +51,24 @@ def canonicalize!
def to_s
@string || @object.strftime('%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
end
+
+ ##
+ # Equal compares as Time objects
+ def ==(other)
+ # If lexically invalid, use regular literal testing
+ return super unless self.valid?
+
+ case other
+ when Literal::Time
+ return super unless other.valid?
+ # Compare as strings, as time includes a date portion, and adjusting for UTC
+ # can create a mismatch in the date portion.
+ self.object.utc.strftime('%H%M%S') == other.object.utc.strftime('%H%M%S')
+ when Literal::DateTime, Literal::Date
+ false
+ else
+ super
+ end
+ end
end # Time
end; end # RDF::Literal
View
237 spec/model_literal_spec.rb
@@ -427,7 +427,7 @@ def self.literals(*selector)
literal(:xml_def_ns) => %("foo <sup xmlns=\\"http://purl.org/dc/terms/\\">bar</sup> baz!"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>),
literal(:xml_ns2) => %(fixme),
}.each_pair do |args, rep|
- it "returns n3 rep for #{args.inspect}" do
+ it "returns ntriples rep for #{args.inspect}" do
literal = RDF::Literal.new(*args)
pending {literal.to_s.should == rep}
end
@@ -626,239 +626,4 @@ def self.literals(*selector)
end
end
end
-
- describe RDF::Literal::Numeric do
- context "type-promotion" do
- context "for numbers" do
- {
- :integer => {
- :integer => :integer,
- :nonPositiveInteger => :integer,
- :negativeInteger => :integer,
- :long => :integer,
- :int => :integer,
- :short => :integer,
- :byte => :integer,
- :nonNegativeInteger => :integer,
- :unsignedLong => :integer,
- :unsignedInt => :integer,
- :unsignedShort => :integer,
- :unsignedByte => :integer,
- :positiveInteger => :integer,
- :decimal => :decimal,
- :float => :float,
- :double => :double,
- },
- :decimal => {
- :integer => :decimal,
- :nonPositiveInteger => :decimal,
- :negativeInteger => :decimal,
- :long => :decimal,
- :int => :decimal,
- :short => :decimal,
- :byte => :decimal,
- :nonNegativeInteger => :decimal,
- :unsignedLong => :decimal,
- :unsignedInt => :decimal,
- :unsignedShort => :decimal,
- :unsignedByte => :decimal,
- :positiveInteger => :decimal,
- :decimal => :decimal,
- :float => :float,
- :double => :double,
- },
- :float => {
- :integer => :float,
- :nonPositiveInteger => :float,
- :negativeInteger => :float,
- :long => :float,
- :int => :float,
- :short => :float,
- :byte => :float,
- :nonNegativeInteger => :float,
- :unsignedLong => :float,
- :unsignedInt => :float,
- :unsignedShort => :float,
- :unsignedByte => :float,
- :positiveInteger => :float,
- :decimal => :float,
- :float => :float,
- :double => :double,
- },
- :double => {
- :integer => :double,
- :nonPositiveInteger => :double,
- :negativeInteger => :double,
- :long => :double,
- :int => :double,
- :short => :double,
- :byte => :double,
- :nonNegativeInteger => :double,
- :unsignedLong => :double,
- :unsignedInt => :double,
- :unsignedShort => :double,
- :unsignedByte => :double,
- :positiveInteger => :double,
- :decimal => :double,
- :float => :double,
- :double => :double,
- },
- }.each do |left, right_result|
- if left == :integer
- # Type promotion is equivalent for sub-types of xsd:integer
- (right_result.keys - [:integer, :decimal, :float, :double]).each do |l|
- o_l = RDF::Literal.new(([:nonPositiveInteger, :negativeInteger].include?(l) ? "-1" : "1"), :datatype => RDF::XSD.send(l))
- right_result.each do |right, result|
- o_r = RDF::Literal.new(([:nonPositiveInteger, :negativeInteger].include?(right) ? "-1" : "1"), :datatype => RDF::XSD.send(right))
-
- it "returns #{result} for #{l} + #{right}" do
- (o_l + o_r).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{l} - #{right}" do
- (o_l - o_r).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{l} * #{right}" do
- (o_l * o_r).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{l} / #{right}" do
- (o_l / o_r).datatype.should == RDF::XSD.send(result)
- end
-
- it "returns #{result} for #{right} + #{l}" do
- (o_r + o_l).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{right} - #{l}" do
- (o_r - o_l).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{right} * #{l}" do
- (o_r * o_l).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{right} / #{l}" do
- (o_r / o_l).datatype.should == RDF::XSD.send(result)
- end
- end
- end
- end
-
- o_l = RDF::Literal.new("1", :datatype => RDF::XSD.send(left))
- right_result.each do |right, result|
- o_r = RDF::Literal.new(([:nonPositiveInteger, :negativeInteger].include?(right) ? "-1" : "1"), :datatype => RDF::XSD.send(right))
-
- it "returns #{result} for #{left} + #{right}" do
- (o_l + o_r).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{left} - #{right}" do
- (o_l - o_r).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{left} * #{right}" do
- (o_l * o_r).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{left} / #{right}" do
- (o_l / o_r).datatype.should == RDF::XSD.send(result)
- end
-
- it "returns #{result} for #{right} + #{left}" do
- (o_r + o_l).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{right} - #{left}" do
- (o_r - o_l).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{right} * #{left}" do
- (o_r * o_l).datatype.should == RDF::XSD.send(result)
- end
- it "returns #{result} for #{right} / #{left}" do
- (o_r / o_l).datatype.should == RDF::XSD.send(result)
- end
- end
- end
- end
- end
-
- [RDF::Literal::Float, RDF::Literal::Double].each do |c|
- describe c do
- before(:each) do
- @nan = c.new("NaN")
- @inf = c.new("INF")
- end
-
- it "recognizes INF" do
- @inf.should be_infinite
- RDF::Literal.new('INF', :datatype => c::DATATYPE).should == @inf
- end
-
- it "recognizes -INF" do
- @inf.should be_infinite
- RDF::Literal.new('-INF', :datatype => c::DATATYPE).should == -@inf
- end
-
- it "recognizes NaN" do
- @nan.should be_nan
- RDF::Literal.new('NaN', :datatype => c::DATATYPE).should be_nan
- end
-
- [-1, 0, 1].map {|n| c.new(n)}.each do |n|
- {
- :"+" => [c.new("INF"), c.new("INF"), c.new("-INF"), c.new("-INF")],
- :"-" => [c.new("INF"), c.new("-INF"), c.new("-INF"), c.new("INF")],
- }.each do |op, (lp, rp, lm, rm)|
- it "returns #{lp} for INF #{op} #{n}" do
- @inf.send(op, n).should == lp
- end
-
- it "returns #{rp} for #{n} #{op} INF" do
- n.send(op, @inf).should == rp
- end
-
- it "returns #{lm} for -INF #{op} #{n}" do
- (-@inf).send(op, n).should == lm
- end
-
- it "returns #{rm} for #{n} #{op} -INF" do
- n.send(op, -@inf).should == rm
- end
- end
-
- it "#{n} + NaN" do
- (n + -@nan).should be_nan
- (-@nan + n).should be_nan
- end
- end
-
- # Multiplication
- {
- -1 => [c.new("-INF"), c.new("-INF")],
- 0 => [:nan, :nan],
- 1 => [c.new("INF"), c.new("INF")],
- }.each do |n, (p, m)|
- it "returns #{p} for #{n} * INF" do
- if p == :nan
- (c.new(n) * @inf).should be_nan
- else
- (c.new(n) * @inf).should == p
- end
- end
-
- it "returns #{p} for INF * #{n}" do
- if p == :nan
- (@inf * c.new(n)).should be_nan
- else
- (@inf * c.new(n)).should == p
- end
- end
- end
-
- it "adds infinities" do
- (@inf + @inf).should == @inf
- (@inf + -@inf).should be_nan
- (-@inf + -@inf).should == -@inf
- (-@inf + @inf).should be_nan
- end
-
- it "adds NaN" do
- (@inf + @nan).should be_nan
- (@nan + @nan).should be_nan
- end
- end
- end
- end
end

0 comments on commit 4b19e62

Please sign in to comment.
Something went wrong with that request. Please try again.