Skip to content

Commit

Permalink
Finish 3.2.11
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Jun 8, 2023
2 parents 105d295 + b8f79ca commit 4765724
Show file tree
Hide file tree
Showing 17 changed files with 120 additions and 122 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Run tests
run: ruby --version; bundle exec rspec spec || $ALLOW_FAILURES
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v1.1.2
uses: coverallsapp/github-action@v2
if: "matrix.ruby == '3.0'"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
- name: Run tests
run: ruby --version; bundle exec rspec spec || $ALLOW_FAILURES
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v1.1.2
uses: coverallsapp/github-action@v2
if: "matrix.ruby == '3.0'"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -5,7 +5,7 @@ This is a pure-Ruby library for working with [Resource Description Framework

* <https://ruby-rdf.github.io/rdf>

[![Gem Version](https://badge.fury.io/rb/rdf.png)](https://badge.fury.io/rb/rdf)
[![Gem Version](https://badge.fury.io/rb/rdf.svg)](https://badge.fury.io/rb/rdf)
[![Build Status](https://github.com/ruby-rdf/rdf/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/rdf/actions?query=workflow%3ACI)
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/rdf/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/rdf?branch=develop)
[![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
3.2.10
3.2.11
1 change: 0 additions & 1 deletion lib/rdf.rb
Expand Up @@ -5,7 +5,6 @@
require "ostruct"

require 'rdf/version'
require 'rdf/extensions'

module RDF
# RDF mixins
Expand Down
22 changes: 0 additions & 22 deletions lib/rdf/extensions.rb

This file was deleted.

13 changes: 0 additions & 13 deletions lib/rdf/model/list.rb
Expand Up @@ -280,19 +280,6 @@ def *(int_or_str)
end
end

##
# Returns the element at `index`.
#
# @example
# RDF::List[1, 2, 3][0] #=> RDF::Literal(1)
#
# @param [Integer] index
# @return [RDF::Term]
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-5B-5D
def [](index)
at(index)
end

##
# Element Assignment — Sets the element at `index`, or replaces a subarray from the `start` index for `length` elements, or replaces a subarray specified by the `range` of indices.
#
Expand Down
103 changes: 60 additions & 43 deletions lib/rdf/model/uri.rb
@@ -1,4 +1,5 @@
# coding: utf-8
# frozen_string_literal: true
require 'cgi'

module RDF
Expand Down Expand Up @@ -28,27 +29,27 @@ class URI
include RDF::Resource

# IRI components
UCSCHAR = Regexp.compile(<<-EOS.gsub(/\s+/, ''))
[\\u00A0-\\uD7FF]|[\\uF900-\\uFDCF]|[\\uFDF0-\\uFFEF]|
[\\u{10000}-\\u{1FFFD}]|[\\u{20000}-\\u{2FFFD}]|[\\u{30000}-\\u{3FFFD}]|
[\\u{40000}-\\u{4FFFD}]|[\\u{50000}-\\u{5FFFD}]|[\\u{60000}-\\u{6FFFD}]|
[\\u{70000}-\\u{7FFFD}]|[\\u{80000}-\\u{8FFFD}]|[\\u{90000}-\\u{9FFFD}]|
[\\u{A0000}-\\u{AFFFD}]|[\\u{B0000}-\\u{BFFFD}]|[\\u{C0000}-\\u{CFFFD}]|
[\\u{D0000}-\\u{DFFFD}]|[\\u{E1000}-\\u{EFFFD}]
EOS
IPRIVATE = Regexp.compile("[\\uE000-\\uF8FF]|[\\u{F0000}-\\u{FFFFD}]|[\\u100000-\\u10FFFD]").freeze
UCSCHAR = %(
\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF
\\u{10000}-\\u{1FFFD}\\u{20000}-\\u{2FFFD}\\u{30000}-\\u{3FFFD}
\\u{40000}-\\u{4FFFD}\\u{50000}-\\u{5FFFD}\\u{60000}-\\u{6FFFD}
\\u{70000}-\\u{7FFFD}\\u{80000}-\\u{8FFFD}\\u{90000}-\\u{9FFFD}
\\u{A0000}-\\u{AFFFD}\\u{B0000}-\\u{BFFFD}\\u{C0000}-\\u{CFFFD}
\\u{D0000}-\\u{DFFFD}\\u{E1000}-\\u{EFFFD}
).gsub(/\s+/, '')
IPRIVATE = Regexp.compile("[\\uE000-\\uF8FF\\u{F0000}-\\u{FFFFD}\\u{100000}-\\u{10FFFD}]").freeze
SCHEME = Regexp.compile("[A-Za-z](?:[A-Za-z0-9+-\.])*").freeze
PORT = Regexp.compile("[0-9]*").freeze
IP_literal = Regexp.compile("\\[[0-9A-Fa-f:\\.]*\\]").freeze # Simplified, no IPvFuture
PCT_ENCODED = Regexp.compile("%[0-9A-Fa-f][0-9A-Fa-f]").freeze
GEN_DELIMS = Regexp.compile("[:/\\?\\#\\[\\]@]").freeze
SUB_DELIMS = Regexp.compile("[!\\$&'\\(\\)\\*\\+,;=]").freeze
RESERVED = Regexp.compile("(?:#{GEN_DELIMS}|#{SUB_DELIMS})").freeze
GEN_DELIMS = Regexp.compile(%q{[:/\?\#\[\]@]}).freeze
SUB_DELIMS = Regexp.compile(%q{[!\$&'\(\)\*\+,;=]}).freeze
RESERVED = Regexp.union(GEN_DELIMS, SUB_DELIMS).freeze
UNRESERVED = Regexp.compile("[A-Za-z0-9\._~-]").freeze

IUNRESERVED = Regexp.compile("[A-Za-z0-9\._~-]|#{UCSCHAR}").freeze
IUNRESERVED = Regexp.union(UNRESERVED, Regexp.compile("[#{UCSCHAR}]")).freeze

IPCHAR = Regexp.compile("(?:#{IUNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|:|@)").freeze
IPCHAR = Regexp.union(IUNRESERVED, PCT_ENCODED, SUB_DELIMS, /[:|@]/).freeze

IQUERY = Regexp.compile("(?:#{IPCHAR}|#{IPRIVATE}|/|\\?)*").freeze

Expand All @@ -65,7 +66,7 @@ class URI
IPATH_EMPTY = Regexp.compile("").freeze

IREG_NAME = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS}))*").freeze
IHOST = Regexp.compile("(?:#{IP_literal})|(?:#{IREG_NAME})").freeze
IHOST = Regexp.union(IP_literal, IREG_NAME).freeze
IUSERINFO = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|:)*").freeze
IAUTHORITY = Regexp.compile("(?:#{IUSERINFO}@)?#{IHOST}(?::#{PORT})?").freeze

Expand Down Expand Up @@ -116,7 +117,21 @@ class URI
# Note: not all reserved characters need to be escaped in SPARQL/Turtle, but they must be unescaped when encountered
PN_ESCAPE_CHARS = /[~\.!\$&'\(\)\*\+,;=\/\?\#@%]/.freeze
PN_ESCAPES = /\\#{Regexp.union(PN_ESCAPE_CHARS, /[\-_]/)}/.freeze


# For URI encoding
# iuserinfo = *( iunreserved / pct-encoded / sub-delims / ":" )
ENCODE_USER =
ENCODE_PASSWORD = Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}!$&'\(\)\*\+,;=:-]").freeze
# isegment = *ipchar
# ipchar = iunreserved / pct-encoded / sub-delims / ":" / "@"
ENCODE_ISEGMENT = Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}!$&'\(\)\*\+,;=:-]").freeze
# isegment-nz-nc = 1*( iunreserved / pct-encoded / sub-delims / "@" )
ENCODE_ISEGMENT_NC = Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}!$&'\(\)\*\+,;=-]").freeze
# iquery = *( ipchar / iprivate / "/" / "?" )
ENCODE_IQUERY = Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}\\uE000-\\uF8FF\\u{F0000}-\\u{FFFFD}\\u{100000}-\\u{10FFFD}/?=]").freeze
# ifragment = *( ipchar / "/" / "?" )
ENCODE_IFRAGMENT = Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}/?]").freeze

##
# Cache size may be set through {RDF.config} using `uri_cache_size`.
#
Expand Down Expand Up @@ -170,7 +185,7 @@ def self.parse(str)
# @return [String] normalized path
# @see http://tools.ietf.org/html/rfc3986#section-5.2.4
def self.normalize_path(path)
output, input = "", path.to_s
output, input = String.new, path.to_s
if input.encoding != Encoding::ASCII_8BIT
input = input.dup.force_encoding(Encoding::ASCII_8BIT)
end
Expand Down Expand Up @@ -353,7 +368,7 @@ def length
# @return [Boolean] `true` or `false`
# @since 0.3.9
def valid?
RDF::URI::IRI.match(to_s) || false
RDF::URI::IRI.match?(to_s) || false
end

##
Expand Down Expand Up @@ -920,7 +935,7 @@ def scheme=(value)
# Return normalized version of scheme, if any
# @return [String]
def normalized_scheme
normalize_segment(scheme.strip, SCHEME, true) if scheme
scheme.strip.downcase if scheme
end

##
Expand All @@ -946,7 +961,7 @@ def user=(value)
# Normalized version of user
# @return [String]
def normalized_user
URI.encode(CGI.unescape(user), /[^#{IUNRESERVED}|#{SUB_DELIMS}]/).force_encoding(Encoding::UTF_8) if user
URI.encode(CGI.unescape(user), ENCODE_USER).force_encoding(Encoding::UTF_8) if user
end

##
Expand All @@ -972,7 +987,7 @@ def password=(value)
# Normalized version of password
# @return [String]
def normalized_password
URI.encode(CGI.unescape(password), /[^#{IUNRESERVED}|#{SUB_DELIMS}]/).force_encoding(Encoding::UTF_8) if password
URI.encode(CGI.unescape(password), ENCODE_PASSWORD).force_encoding(Encoding::UTF_8) if password
end

HOST_FROM_AUTHORITY_RE = /(?:[^@]+@)?([^:]+)(?::.*)?$/.freeze
Expand Down Expand Up @@ -1000,7 +1015,7 @@ def host=(value)
# @return [String]
def normalized_host
# Remove trailing '.' characters
normalize_segment(host, IHOST, true).chomp('.') if host
host.sub(/\.*$/, '').downcase if host
end

PORT_FROM_AUTHORITY_RE = /:(\d+)$/.freeze
Expand Down Expand Up @@ -1028,12 +1043,8 @@ def port=(value)
# @return [String]
def normalized_port
if port
np = normalize_segment(port.to_s, PORT)
if PORT_MAPPING[normalized_scheme] == np.to_i
nil
else
np.to_i
end
np = port.to_i
PORT_MAPPING[normalized_scheme] != np ? np : nil
end
end

Expand Down Expand Up @@ -1064,30 +1075,36 @@ def path=(value)
# Normalized version of path
# @return [String]
def normalized_path
if normalized_scheme == "urn"
# Special-case URI. Normalize the NID component only
nid, p = path.to_s.split(':', 2)
return "#{nid.downcase}:#{p}"
end

segments = path.to_s.split('/', -1) # preserve null segments

norm_segs = case
when authority
# ipath-abempty
segments.map {|s| normalize_segment(s, ISEGMENT)}
segments.map {|s| normalize_segment(s, ENCODE_ISEGMENT)}
when segments[0].nil?
# ipath-absolute
res = [nil]
res << normalize_segment(segments[1], ISEGMENT_NZ) if segments.length > 1
res += segments[2..-1].map {|s| normalize_segment(s, ISEGMENT)} if segments.length > 2
res << normalize_segment(segments[1], ENCODE_ISEGMENT) if segments.length > 1
res += segments[2..-1].map {|s| normalize_segment(s, ENCODE_ISEGMENT)} if segments.length > 2
res
when segments[0].to_s.index(':')
# ipath-noscheme
res = []
res << normalize_segment(segments[0], ISEGMENT_NZ_NC)
res += segments[1..-1].map {|s| normalize_segment(s, ISEGMENT)} if segments.length > 1
res << normalize_segment(segments[0], ENCODE_ISEGMENT_NC)
res += segments[1..-1].map {|s| normalize_segment(s, ENCODE_ISEGMENT)} if segments.length > 1
res
when segments[0]
# ipath-rootless
# ipath-noscheme
res = []
res << normalize_segment(segments[0], ISEGMENT_NZ)
res += segments[1..-1].map {|s| normalize_segment(s, ISEGMENT)} if segments.length > 1
res << normalize_segment(segments[0], ENCODE_ISEGMENT)
res += segments[1..-1].map {|s| normalize_segment(s, ENCODE_ISEGMENT)} if segments.length > 1
res
else
# Should be empty
Expand All @@ -1096,7 +1113,7 @@ def normalized_path

res = self.class.normalize_path(norm_segs.join("/"))
# Special rules for specific protocols having empty paths
normalize_segment(res.empty? ? (%w(http https ftp tftp).include?(normalized_scheme) ? '/' : "") : res, IHIER_PART)
(res.empty? && %w(http https ftp tftp).include?(normalized_scheme)) ? '/' : res
end

##
Expand All @@ -1120,7 +1137,7 @@ def query=(value)
# Normalized version of query
# @return [String]
def normalized_query
normalize_segment(query, IQUERY) if query
normalize_segment(query, ENCODE_IQUERY) if query
end

##
Expand All @@ -1144,7 +1161,7 @@ def fragment=(value)
# Normalized version of fragment
# @return [String]
def normalized_fragment
normalize_segment(fragment, IFRAGMENT) if fragment
normalize_segment(fragment, ENCODE_IFRAGMENT) if fragment
end

##
Expand Down Expand Up @@ -1274,15 +1291,15 @@ def query_values=(value)
self.query = case value
when Array, Hash
value.map do |(k,v)|
k = normalize_segment(k.to_s, UNRESERVED)
k = normalize_segment(k.to_s, /[^A-Za-z0-9\._~-]/)
if v.nil?
k
else
Array(v).map do |vv|
if vv === TrueClass
k
else
"#{k}=#{normalize_segment(vv.to_s, UNRESERVED)}"
"#{k}=#{normalize_segment(vv.to_s, /[^A-Za-z0-9\._~-]/)}"
end
end.join("&")
end
Expand Down Expand Up @@ -1331,15 +1348,15 @@ def self._load(data)
# Normalize a segment using a character range
#
# @param [String] value
# @param [Regexp] expr
# @param [Regexp] expr matches characters to be encoded
# @param [Boolean] downcase
# @return [String]
def normalize_segment(value, expr, downcase = false)
if value
value = value.dup.force_encoding(Encoding::UTF_8)
decoded = CGI.unescape(value)
decoded.downcase! if downcase
URI.encode(decoded, /[^(?:#{expr})]/).force_encoding(Encoding::UTF_8)
URI.encode(decoded, expr).force_encoding(Encoding::UTF_8)
end
end

Expand All @@ -1364,7 +1381,7 @@ def format_authority
def self.encode(str, expr)
str.gsub(expr) do
us = $&
tmp = ''
tmp = String.new
us.each_byte do |uc|
tmp << sprintf('%%%02X', uc)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rdf/util/cache.rb
Expand Up @@ -127,7 +127,7 @@ def initialize(capacity = nil)
def [](key)
if (ref = @cache[key])
if ref.weakref_alive?
value = ref.__getobj__ rescue nil
ref.__getobj__ rescue nil
else
@cache.delete(key)
nil
Expand Down
4 changes: 2 additions & 2 deletions lib/rdf/util/uuid.rb
Expand Up @@ -22,11 +22,11 @@ def self.generate(format: :default)
begin
require 'uuid'
::UUID.generate(format)
rescue LoadError => e
rescue LoadError
begin
require 'uuidtools'
::UUIDTools::UUID.random_create.hexdigest
rescue LoadError => e
rescue LoadError
raise LoadError.new("no such file to load -- uuid or uuidtools")
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/mixin_queryable_spec.rb
Expand Up @@ -29,7 +29,7 @@
end

context "Querying for solutions from a BGP" do
let(:query) { query = RDF::Query.new {pattern %i(s p o)} }
let(:query) { RDF::Query.new {pattern %i(s p o)} }
it "calls #query_execute" do
is_expected.to receive(:query_execute)
is_expected.not_to receive(:query_pattern)
Expand Down

0 comments on commit 4765724

Please sign in to comment.