From 6f7af11e14e65564ce551ee61e32f5eb5237a286 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Thu, 24 Feb 2022 15:33:06 -0800 Subject: [PATCH 1/5] In Temporal#to_s, set `@string` if it is nil. --- lib/rdf/model/literal/temporal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rdf/model/literal/temporal.rb b/lib/rdf/model/literal/temporal.rb index dbca6661..46904ca3 100644 --- a/lib/rdf/model/literal/temporal.rb +++ b/lib/rdf/model/literal/temporal.rb @@ -128,7 +128,7 @@ def milliseconds? # # @return [String] def to_s - @string || (@object.strftime(self.class.const_get(:FORMAT)).sub('.000', '') + self.tz) + @string ||= (@object.strftime(self.class.const_get(:FORMAT)).sub('.000', '') + self.tz) end ## From 1caf735880ea4406e61e1480f461027cad3f6adc Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Thu, 24 Feb 2022 15:33:52 -0800 Subject: [PATCH 2/5] Reset the string representation for Time values having an hour > 23. --- lib/rdf/model/literal/time.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/rdf/model/literal/time.rb b/lib/rdf/model/literal/time.rb index ea7bbc83..7d3a4d7b 100644 --- a/lib/rdf/model/literal/time.rb +++ b/lib/rdf/model/literal/time.rb @@ -39,7 +39,10 @@ def initialize(value, datatype: nil, lexical: nil, **options) end # Normalize 24:00:00 to 00:00:00 hr, mi, se = tm.split(':') - hr = "%.2i" % (hr.to_i % 24) if hr.to_i > 23 + if hr.to_i > 23 + hr = "%.2i" % (hr.to_i % 24) + @string = nil + end value = "#{hr}:#{mi}:#{se}" # Normalize to 1972-12-31 dateTime base ::DateTime.parse("1972-12-31T#{hr}:#{mi}:#{se}#{@zone}") From a4971d97727cbca2bac716d592031b1b401cc34c Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Thu, 24 Feb 2022 15:35:26 -0800 Subject: [PATCH 3/5] Temporal#adjust_to_timezone! can certainly take a Literal::DayTimeOffset, in addition to a String. Treat the empty string as nil, to remove the timezone. --- lib/rdf/model/literal/temporal.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rdf/model/literal/temporal.rb b/lib/rdf/model/literal/temporal.rb index 46904ca3..8cd2673d 100644 --- a/lib/rdf/model/literal/temporal.rb +++ b/lib/rdf/model/literal/temporal.rb @@ -146,18 +146,18 @@ def to_s # # Otherwise, the timezone is set based on the difference between the current timezone offset (if any) and `zone`. # - # @param [String] zone (nil) In the form of {ZONE_GRAMMAR}. + # @param [DayTimeDuration, String] zone (nil) In the form of {ZONE_GRAMMAR}. # @return [Temporal] `self` # @raise [RangeError] if `zone < -14*60` or `zone > 14*60` # @see https://www.w3.org/TR/xpath-functions/#func-adjust-dateTime-to-timezone def adjust_to_timezone!(*args) zone = args.empty? ? '+00:00' : args.first - if zone.nil? + if zone.to_s.empty? # Remove timezone component @object = self.class.new(@object.strftime(self.class.const_get(:FORMAT))).object @zone = nil else - md = zone.match(ZONE_GRAMMAR) + md = zone.to_s.match(ZONE_GRAMMAR) raise ArgumentError, "expected #{zone.inspect} to be a xsd:dayTimeDuration or +/-HH:MM" unless md From ed93bfd5acfb46c8436e381443461a9e0cc70701 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 27 Feb 2022 15:58:40 -0800 Subject: [PATCH 4/5] Add `Solutions#variable_names=` to override automated variable name count. Add `Solutions#==` and `Solutions`#eql?` to test solutions including variable names. --- lib/rdf/query/solution.rb | 3 +-- lib/rdf/query/solutions.rb | 21 ++++++++++++++++ spec/query_solutions_spec.rb | 48 ++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/lib/rdf/query/solution.rb b/lib/rdf/query/solution.rb index 43fc2a3c..d1d071b4 100644 --- a/lib/rdf/query/solution.rb +++ b/lib/rdf/query/solution.rb @@ -317,13 +317,12 @@ def to_h def hash @bindings.hash end - + ## # Equivalence of solution def eql?(other) other.is_a?(Solution) && @bindings.eql?(other.bindings) end - alias_method :==, :eql? ## # Equals of solution diff --git a/lib/rdf/query/solutions.rb b/lib/rdf/query/solutions.rb index 0a780cc5..d0b57b30 100644 --- a/lib/rdf/query/solutions.rb +++ b/lib/rdf/query/solutions.rb @@ -77,6 +77,15 @@ def variable_names end end + ## + # Sets variable names used in these solutions. If not set, the default is determined by the variables used in each solution. + # + # @param [Array] vars + # @return [Array] + def variable_names=(vars) + @variable_names = vars.map(&:to_sym) + end + ## # @overload variable? # Returns `false`. @@ -294,5 +303,17 @@ def limit(length) self end alias_method :limit!, :limit + + ## + # Equivalence of solution + def eql?(other) + super && (!other.respond_to?(:variable_names) || variable_names.eql?(other.variable_names)) + end + + ## + # Equals of solution + def ==(other) + super && (!other.respond_to?(:variable_names) || variable_names.eql?(other.variable_names)) + end end # Solutions end; end # RDF::Query diff --git a/spec/query_solutions_spec.rb b/spec/query_solutions_spec.rb index cdfc3c85..ba986e92 100644 --- a/spec/query_solutions_spec.rb +++ b/spec/query_solutions_spec.rb @@ -305,6 +305,20 @@ specify {is_expected.to include(:author, :age, :name, :description, :updated, :created, :title, :price, :date)} end + describe "#variable_names=" do + it "can set variable names from constants" do + solutions.variable_names = %i{author age foo} + expect(solutions.variable_names).to include(:author, :age, :foo) + expect(solutions.variable_names).not_to include(:name) + end + + it "can set variable names from variables" do + solutions.variable_names = %w{author age foo}.map {|n| RDF::Query::Variable.new(n)} + expect(solutions.variable_names).to include(:author, :age, :foo) + expect(solutions.variable_names).not_to include(:name) + end + end + describe "#count" do its(:count) {is_expected.to eq 2} it "Counting the number of matching solutions" do @@ -318,6 +332,40 @@ end end + describe "#eql?" do + it "is true for equivalent solutions" do + expect(solutions).to eql solutions.dup + end + + it "is false for different solutions" do + solns2 = RDF::Query::Solutions(uri) + expect(solutions).not_to eql solns2 + end + + it "is false for the same solution with different variable_names" do + solns2 = solutions.dup + solns2.variable_names = %i{foo bar} + expect(solutions).not_to eql solns2 + end + end + + describe "#==" do + it "is true for equivalent solutions" do + expect(solutions).to eq solutions.dup + end + + it "is false for different solutions" do + solns2 = RDF::Query::Solutions(uri) + expect(solutions).not_to eq solns2 + end + + it "is false for the same solution with different variable_names" do + solns2 = solutions.dup + solns2.variable_names = %i{foo bar} + expect(solutions).not_to eq solns2 + end + end + describe "#bindings" do subject { RDF::Query::Solutions( From 6f9e254f1bca67b2d1f3de728f48d1bae903f49f Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 14 Mar 2022 11:42:06 -0700 Subject: [PATCH 5/5] Version 3.2.6. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5ae69bd5..34cde569 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.2.5 +3.2.6