Skip to content

Commit

Permalink
Finish 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Feb 2, 2021
2 parents 5987186 + 248b04b commit 21594f0
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 82 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
- 2.5
- 2.6
- 2.7
#- 3.0 # until net-http-persistent is updaated
#- ruby-head # until net-http-persistent is updaated
- 3.0
- ruby-head
- jruby
steps:
- name: Clone repository
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is a pure-Ruby library for working with the [Shape Constraint Language][SHA

[![Gem Version](https://badge.fury.io/rb/shacl.png)](https://badge.fury.io/rb/shacl)
[![Build Status](https://github.com/ruby-rdf/shacl/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/shacl/actions?query=workflow%3ACI)
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/shacl/badge.svg)](https://coveralls.io/github/ruby-rdf/shacl)
[![Coverage Status](https://coveralls.io/repos/github/ruby-rdf/shacl/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/shacl?branch=develop)
[![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)

## Features
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0
0.1.1
9 changes: 3 additions & 6 deletions etc/doap.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

<https://rubygems.org/gems/shacl> a doap:Project, earl:TestSubject, earl:Software ;
sh:shapesGraph <doap-shacl.ttl>;
doap:name "Ruby SHACL" ;
doap:name "SHACL" ;
doap:homepage <https://ruby-rdf.github.com/shacl> ;
doap:license <https://unlicense.org/1.0/> ;
doap:shortdesc "shacl is a Shapes Constraint engine for Ruby."@en ;
doap:description "shacl is an Shape Constraint engine for the RDF.rb library suite."@en ;
doap:shortdesc "SHACL is a Shapes Constraint engine for Ruby."@en ;
doap:description "SHACL is a Shape Constraint engine for the Ruby RDF.rb library suite."@en ;
doap:created "2020-11-26"^^xsd:date ;
doap:programming-language "Ruby" ;
doap:implements <https://www.w3.org/TR/shacl/> ;
Expand All @@ -28,8 +28,5 @@
doap:maintainer <https://greggkellogg.net/foaf#me> ;
doap:documenter <https://greggkellogg.net/foaf#me> ;
foaf:maker <https://greggkellogg.net/foaf#me> ;
dc:title "Ruby SHACL" ;
dc:description "shacl is an Shape Constraint engine for the RDF.rb library suite."@en ;
dc:date "2020-11-26"^^xsd:date ;
dc:creator <https://greggkellogg.net/foaf#me> ;
dc:isPartOf <https://rubygems.org/gems/rdf> .
6 changes: 3 additions & 3 deletions etc/earl.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
doap:name "Ruby SHACL" ;
doap:homepage <https://ruby-rdf.github.com/shacl> ;
doap:license <https://unlicense.org/1.0/> ;
doap:shortdesc "shacl is a Shapes Constraint engine for Ruby."@en ;
doap:description "shacl is an Shape Constraint engine for the RDF.rb library suite."@en ;
doap:shortdesc "SHACL is a Shapes Constraint engine for Ruby."@en ;
doap:description "SHACL is an Shape Constraint engine for the RDF.rb library suite."@en ;
doap:created "2020-11-26"^^xsd:date ;
doap:programming-language "Ruby" ;
doap:implements <https://www.w3.org/TR/shacl/> ;
Expand All @@ -28,7 +28,7 @@
doap:documenter <https://greggkellogg.net/foaf#me> ;
foaf:maker <https://greggkellogg.net/foaf#me> ;
dc:title "Ruby SHACL" ;
dc:description "shacl is an Shape Constraint engine for the RDF.rb library suite."@en ;
dc:description "SHACL is an Shape Constraint engine for the RDF.rb library suite."@en ;
dc:date "2020-11-26"^^xsd:date ;
dc:creator <https://greggkellogg.net/foaf#me> ;
dc:isPartOf <https://rubygems.org/gems/rdf> .
Expand Down
5 changes: 5 additions & 0 deletions etc/template.haml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@
%p
This document reports conformance for for
%a{property: "doap:name", href: "https://www.w3.org/TR/shacl/"}=tests['name']
%p
Alternate versions of the report are available in
%a{rel: :alternate, href: "earl.ttl"}="Turtle"
and
%a{rel: :alternate, href: "earl.jsonld"}="JSON-LD"
%dl
- subjects.each_with_index do |subject, index|
- subject_refs[subject['@id']] = "subj_#{index}"
Expand Down
2 changes: 1 addition & 1 deletion lib/shacl/algebra/node_shape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def conforms(node, depth: 0, **options)
shape_properties = shape_paths.select {|p| p.is_a?(RDF::URI)}
shape_properties += Array(@options[:ignoredProperties])

closed_results = graph.query(subject: node).map do |statement|
closed_results = graph.query({subject: node}).map do |statement|
next if shape_properties.include?(statement.predicate)
not_satisfied(focus: node,
value: statement.object,
Expand Down
6 changes: 3 additions & 3 deletions lib/shacl/algebra/property_shape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def conforms(node, depth: 0, **options)

# Turn the `path` attribute into a SPARQL Property Path and evaluate to find related nodes.
value_nodes = if path.is_a?(RDF::URI)
graph.query(subject: node, predicate: path).objects
graph.query({subject: node, predicate: path}).objects
elsif path.evaluatable?
path.execute(graph,
subject: node,
Expand Down Expand Up @@ -100,7 +100,7 @@ def path
# @param [Array<RDF::Term>] value_nodes
# @return [Array<SHACL::ValidationResult>]
def builtin_lessThan(property, node, path, value_nodes, **options)
terms = graph.query(subject: node, predicate: property).objects
terms = graph.query({subject: node, predicate: property}).objects
compare(:<, terms, node, path, value_nodes,
RDF::Vocab::SHACL.LessThanConstraintComponent, **options)
end
Expand All @@ -113,7 +113,7 @@ def builtin_lessThan(property, node, path, value_nodes, **options)
# @param [Array<RDF::Term>] value_nodes
# @return [Array<SHACL::ValidationResult>]
def builtin_lessThanOrEquals(property, node, path, value_nodes, **options)
terms = graph.query(subject: node, predicate: property).objects
terms = graph.query({subject: node, predicate: property}).objects
compare(:<=, terms, node, path, value_nodes,
RDF::Vocab::SHACL.LessThanOrEqualsConstraintComponent, **options)
end
Expand Down
14 changes: 7 additions & 7 deletions lib/shacl/algebra/shape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ class Shape < Operator
def targetNodes
(Array(@options[:targetNode]) +
Array(@options[:targetClass]).map do |cls|
graph.query(predicate: RDF.type, object: cls).subjects
graph.query({predicate: RDF.type, object: cls}).subjects
end +
Array(@options[:targetSubjectsOf]).map do |pred|
graph.query(predicate: pred).subjects
graph.query({predicate: pred}).subjects
end +
Array(@options[:targetObjectsOf]).map do |pred|
graph.query(predicate: pred).objects
graph.query({predicate: pred}).objects
end + (
Array(type).include?(RDF::RDFS.Class) ?
graph.query(predicate: RDF.type, object: id).subjects :
graph.query({predicate: RDF.type, object: id}).subjects :
[]
)).flatten.uniq
end
Expand Down Expand Up @@ -52,7 +52,7 @@ def targetNodes
def builtin_class(types, node, path, value_nodes, **options)
value_nodes.map do |n|
has_type = n.resource? && begin
objects = graph.query(subject: n, predicate: RDF.type).objects
objects = graph.query({subject: n, predicate: RDF.type}).objects
types.all? {|t| objects.include?(t)}
end
satisfy(focus: node, path: path,
Expand Down Expand Up @@ -110,7 +110,7 @@ def builtin_datatype(datatype, node, path, value_nodes, **options)
# @return [Array<SHACL::ValidationResult>]
def builtin_disjoint(properties, node, path, value_nodes, **options)
disjoint_nodes = properties.map do |prop|
graph.query(subject: node, predicate: prop).objects
graph.query({subject: node, predicate: prop}).objects
end.flatten.compact
value_nodes.map do |n|
has_value = disjoint_nodes.include?(n)
Expand Down Expand Up @@ -140,7 +140,7 @@ def builtin_disjoint(properties, node, path, value_nodes, **options)
# @param [Array<RDF::Term>] value_nodes
# @return [Array<SHACL::ValidationResult>]
def builtin_equals(property, node, path, value_nodes, **options)
equal_nodes = graph.query(subject: node, predicate: property).objects
equal_nodes = graph.query({subject: node, predicate: property}).objects
(value_nodes.map do |n|
has_value = equal_nodes.include?(n)
satisfy(focus: node, path: path,
Expand Down
2 changes: 1 addition & 1 deletion lib/shacl/algebra/xone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def conforms(node, path: nil, depth: 0, **options)
log_debug(NAME, depth: depth) {SXP::Generator.string({node: node}.to_sxp_bin)}
num_conform = operands.inject(0) do |memo, op|
results = op.conforms(node, depth: depth + 1, **options)
memo += (results.all?(&:conform?) ? 1 : 0)
memo += (results.flatten.all?(&:conform?) ? 1 : 0)
end
case num_conform
when 0
Expand Down
4 changes: 2 additions & 2 deletions lib/shacl/shapes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def self.from_graph(graph, loaded_graphs: [], **options)
@loded_graphs = loaded_graphs

import_count = 0
while (imports = graph.query(predicate: RDF::OWL.imports).map(&:object)).count > import_count
while (imports = graph.query({predicate: RDF::OWL.imports}).map(&:object)).count > import_count
# Load each imported graph
imports.each do |ref|
graph.load(imports)
Expand Down Expand Up @@ -65,7 +65,7 @@ def self.from_graph(graph, loaded_graphs: [], **options)
# @raise [SHACL::Error]
def self.from_queryable(queryable, **options)
# Query queryable to find one ore more shapes graphs
graphs = queryable.query(predicate: RDF::Vocab::SHACL.shapesGraph).objects
graphs = queryable.query({predicate: RDF::Vocab::SHACL.shapesGraph}).objects
graph = RDF::Graph.new do |g|
graphs.each {|iri| g.load(iri)}
end
Expand Down
136 changes: 83 additions & 53 deletions script/tc
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ def run_tc(t, **options)
"failed"
end
end
rescue Interrupt
exit(1)
rescue Interupt => e
raise e
rescue Exception, NoMethodError => e
result = "exception"
unless options[:quiet]
Expand Down Expand Up @@ -123,40 +123,62 @@ ensure
end

options = {
level: Logger::WARN,
output: STDOUT,
results: {},
validate: true,
verbose: false,
}
opts = GetoptLong.new(
["--debug", GetoptLong::NO_ARGUMENT],
["--earl", GetoptLong::NO_ARGUMENT],
["--help", "-?", GetoptLong::NO_ARGUMENT],
["--output", "-o", GetoptLong::REQUIRED_ARGUMENT],
["--quiet", "-q", GetoptLong::NO_ARGUMENT],
["--verbose", "-v", GetoptLong::NO_ARGUMENT],
["--write-manifests", GetoptLong::NO_ARGUMENT],
)

def help(options)
puts "Usage: #{$0} [options] [test-number ...]"
puts "Options:"
puts " -debug: Display detailed debug output"
puts " -earl: Generate EARL report"
puts " -quiet: Minimal output"
puts " -output: Output to specified file"
puts " -verbose: Verbose processing"
puts " --write-manifests Write out the parsed manifests for earl reporting"
puts " -help,-?: This message"
exit(0)
OPT_ARGS = [
["--debug", GetoptLong::NO_ARGUMENT, "Debugging output"],
["--earl", GetoptLong::NO_ARGUMENT, "Generate EARL report"],
["--help", "-?", GetoptLong::NO_ARGUMENT, "print this message"],
["--info", GetoptLong::NO_ARGUMENT, "Show progress on execution"],
["--live", GetoptLong::NO_ARGUMENT, "Show live parsing results, not buffered"],
["--output", "-o", GetoptLong::REQUIRED_ARGUMENT, "Output to specified file"],
["--quiet", "-q", GetoptLong::NO_ARGUMENT, "Minimal output"],
["--validate", GetoptLong::NO_ARGUMENT, "Validate input"],
["--verbose", "-v", GetoptLong::NO_ARGUMENT, "Verbose output"],
["--write-manifests", GetoptLong::NO_ARGUMENT, "Write out the parsed manifests for earl reporting"],
]

def usage
STDERR.puts %{
SHACL version #{SHACL::VERSION}
Run SHACL tests.
Usage: #{$0} [options] [test-number ...]
}.gsub(/^ /, '')
width = OPT_ARGS.map do |o|
l = o.first.length
l += o[1].length + 2 if o[1].is_a?(String)
l
end.max
OPT_ARGS.each do |o|
s = " %-*s " % [width, (o[1].is_a?(String) ? "#{o[0,2].join(', ')}" : o[0])]
s += o.last
STDERR.puts s
end
exit(1)
end

opts = GetoptLong.new(*OPT_ARGS.map {|o| o[0..-2]})

opts.each do |opt, arg|
case opt
when '--earl' then options[:quiet] = options[:earl] = true
when '--debug' then options[:debug] = true
when '--debug' then options[:level] = Logger::DEBUG
when '--earl'
options[:quiet] = options[:earl] = true
options[:level] = Logger::FATAL
when '--help' then usage()
when '--info' then options[:level] = Logger::INFO
when '--live' then options[:live] = true
when '--output' then options[:output] = File.open(arg, "w")
when '--quiet' then options[:quiet] = true
when '--quiet'
options[:quiet] = true
options[:level] = Logger::FATAL
when '--validate' then options[:validate] = true
when '--verbose' then options[:verbose] = true
when '--write-manifests' then options[:write_manifests] = true
end
Expand All @@ -174,39 +196,47 @@ if options[:write_manifests]
end
result_count = {}

%w(
core/node
core/property
core/targets
core/misc
core/path
core/complex
core/validation-reports
).each do |variant|
manifest = TEST_BASE + variant + '/manifest.ttl'

Fixtures::SuiteTest::Manifest.open(manifest) do |m|
if options[:write_manifests]
options[:output].puts %(\n<#{m.id}> a mf:Manifest ;)
options[:output].puts %( rdfs:label "#{m.label}" ;) if m.label
options[:output].puts %{ mf:entries (<#{m.entries.map(&:id).join('> <')}>)}
options[:output].puts %( .)
end
m.entries.each do |t|
begin
%w(
core/node
core/property
core/targets
core/misc
core/path
core/complex
core/validation-reports
).each do |variant|
manifest = TEST_BASE + variant + '/manifest.ttl'

Fixtures::SuiteTest::Manifest.open(manifest) do |m|
if options[:write_manifests]
options[:output].puts %(\n<#{t.id}> a sht:Validate ;)
options[:output].puts %( rdfs:label "#{t.label}" ;) if t.label
options[:output].puts %( mf:action [)
options[:output].puts %( sht:dataGraph <#{t.action['dataGraph']}> ;)
options[:output].puts %( sht:shapesGraph <#{t.action['shapesGraph']}> ;)
options[:output].puts %( ] ;)
options[:output].puts %(\n<#{m.id}> a mf:Manifest ;)
options[:output].puts %( rdfs:label "#{m.label}" ;) if m.label
options[:output].puts %( rdfs:comment "#{m.comment}" ;) if m.comment
options[:output].puts %{ mf:entries (<#{m.entries.map(&:id).join('> <')}>)}
options[:output].puts %( .)
next
end
next unless ARGV.empty? || ARGV.any? {|n| "#{t.id}: #{t.label}".include?(n)}
run_tc(t, **options)
m.entries.each do |t|
if options[:write_manifests]
options[:output].puts %(\n<#{t.id}> a sht:Validate ;)
options[:output].puts %( rdfs:label "#{t.label}" ;) if t.label
options[:output].puts %( rdfs:comment "#{t.label}" ;) if t.comment
options[:output].puts %( mf:action [)
options[:output].puts %( sht:dataGraph <#{t.action['dataGraph']}> ;)
options[:output].puts %( sht:shapesGraph <#{t.action['shapesGraph']}> ;)
options[:output].puts %( ] ;)
options[:output].puts %( .)
next
end
next unless ARGV.empty? || ARGV.any? {|n| "#{t.id}: #{t.label}".include?(n)}
run_tc(t, **options)
end
end
end
rescue Interrupt => e
STDERR.puts "(interrupt)"
STDERR.puts "Backtrace: " + e.backtrace.join("\n ") if options[:verbose]
exit 1
end

STDERR.puts "" if options[:quiet]
Expand Down
2 changes: 1 addition & 1 deletion shacl.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
gem.homepage = 'https://ruby-rdf.github.com/shacl'
gem.license = 'Unlicense'
gem.summary = 'Implementation of Shapes Constraint Language (SHACL) for RDF.rb'
gem.description = 'Implements SHACL Core and SHACL-SPARQL within the RDF.rb ecosystem.'
gem.description = 'SHACL is an Shape Constraint engine for the Ruby RDF.rb library suite.'

gem.authors = ['Gregg Kellogg']
gem.email = '[email protected]'
Expand Down
2 changes: 1 addition & 1 deletion spec/suite_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def self.open(file)
g = RDF::OrderedRepo.load(file)
label = g.first_object(predicate: RDF::RDFS.label).to_s

g.query(predicate: RDF::URI("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#include")).objects.each do |f|
g.query({predicate: RDF::URI("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#include")}).objects.each do |f|
g.load(f)
end
JSON::LD::API.fromRDF(g, useNativeTypes: true) do |expanded|
Expand Down

0 comments on commit 21594f0

Please sign in to comment.