diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0aaedb9..9a760e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: ruby: - 2.6 - 2.7 - - 3.0 + - "3.0" - 3.1 - ruby-head - jruby diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml new file mode 100644 index 0000000..b8d16ed --- /dev/null +++ b/.github/workflows/generate-docs.yml @@ -0,0 +1,27 @@ +name: Build & deploy documentation +on: + push: + branches: + - master + workflow_dispatch: +jobs: + build: + runs-on: ubuntu-latest + name: Update gh-pages with docs + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.1" + - name: Install required gem dependencies + run: gem install yard --no-document + - name: Build YARD Ruby Documentation + run: yardoc + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./doc/yard + publish_branch: gh-pages diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..d2ba358 --- /dev/null +++ b/.yardopts @@ -0,0 +1,11 @@ +--title "RDF:Normalize: RDF Dataset Normalization" +--output-dir doc/yard +--protected +--no-private +--hide-void-return +--markup markdown +--readme README.md +- +AUTHORS +LICENSE +VERSION diff --git a/README.md b/README.md index 69fe247..88531fe 100755 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ RDF Graph normalizer for [RDF.rb][RDF.rb]. [![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf) ## Description -This is a [Ruby][] implementation of a [RDF Normalize][] for [RDF.rb][]. +This is a [Ruby][] implementation of a [RDF Dataset Canonicalization][] for [RDF.rb][]. ## Features RDF::Normalize generates normalized [N-Quads][] output for an RDF Dataset using the algorithm @@ -16,8 +16,8 @@ to serialize normalized statements. Algorithms implemented: -* [URGNA2012](https://json-ld.github.io/normalization/spec/index.html#dfn-urgna2012) -* [URDNA2015](https://json-ld.github.io/normalization/spec/index.html#dfn-urdna2015) +* [URGNA2012](https://www.w3.org/TR/rdf-canon/#dfn-urgna2012) +* [URDNA2015](https://www.w3.org/TR/rdf-canon/#dfn-urdna2015) Install with `gem install rdf-normalize` @@ -27,7 +27,17 @@ Install with `gem install rdf-normalize` ## Usage ## Documentation -Full documentation available on [Rubydoc.info][Normalize doc] + +Full documentation available on [GitHub][Normalize doc] + +## Examples + +### Returning normalized N-Quads + + require 'rdf/normalize' + require 'rdf/turtle' + g = RDF::Graph.load("etc/doap.ttl") + puts g.dump(:normalize) ### Principle Classes * {RDF::Normalize} @@ -37,7 +47,6 @@ Full documentation available on [Rubydoc.info][Normalize doc] * {RDF::Normalize::URGNA2012} * {RDF::Normalize::URDNA2015} - ## Dependencies * [Ruby](https://ruby-lang.org/) (>= 2.6) @@ -80,7 +89,7 @@ see or the accompanying {file:LICENSE} file. [YARD]: https://yardoc.org/ [YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md [PDD]: https://unlicense.org/#unlicensing-contributions -[RDF.rb]: https://rubydoc.info/github/ruby-rdf/rdf-normalize +[RDF.rb]: https://ruby-rdf.github.io/rdf-normalize [N-Triples]: https://www.w3.org/TR/rdf-testcases/#ntriples -[RDF Normalize]:https://json-ld.github.io/normalization/spec/ -[Normalize doc]:https://rubydoc.info/github/ruby-rdf/rdf-normalize/master +[RDF Dataset Canonicalization]: https://www.w3.org/TR/rdf-canon/ +[Normalize doc]: https://ruby-rdf.github.io/rdf-normalize/ diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 index abcf5a1..1cf17e1 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,4 @@ #!/usr/bin/env ruby -$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib'))) -require 'rubygems' - namespace :gem do desc "Build the rdf-normalize-#{File.read('VERSION').chomp}.gem file" task :build do @@ -13,29 +10,3 @@ namespace :gem do sh "gem push pkg/rdf-normalize-#{File.read('VERSION').chomp}.gem" end end - -desc 'Default: run specs.' -task :default => :spec -task :specs => :spec - -require 'rspec/core/rake_task' -desc 'Run specifications' -RSpec::Core::RakeTask.new do |spec| - spec.rspec_opts = %w(--options spec/spec.opts) if File.exists?('spec/spec.opts') -end - -desc "Run specs through RCov" -RSpec::Core::RakeTask.new("spec:rcov") do |spec| - spec.rcov = true - spec.rcov_opts = %q[--exclude "spec"] -end - -desc "Generate HTML report specs" -RSpec::Core::RakeTask.new("doc:spec") do |spec| - spec.rspec_opts = ["--format", "html", "-o", "doc/spec.html"] -end - -require 'yard' -namespace :doc do - YARD::Rake::YardocTask.new -end diff --git a/VERSION b/VERSION index 8f0916f..4b9fcbe 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.0 +0.5.1 diff --git a/etc/doap.ttl b/etc/doap.ttl index a9b2271..502ea85 100644 --- a/etc/doap.ttl +++ b/etc/doap.ttl @@ -1,4 +1,3 @@ -@base . @prefix rdf: . @prefix rdfs: . @prefix dc: . @@ -7,18 +6,18 @@ @prefix ex: . @prefix xsd: . -<> a doap:Project ; + a doap:Project ; doap:name "RDF::Normalize" ; doap:homepage ; doap:license ; doap:shortdesc "RDF Dataset Normalization for RDF.rb."@en ; - doap:description "RDF::Normalize is a Dataset normalizer for the RDF.rb library suite."@en ; + doap:description "RDF::Normalize performs Dataset Canonicalization for RDF.rb."@en ; doap:created "2015-05-20"^^xsd:date; doap:programming-language "Ruby" ; - doap:implements ; + doap:implements ; doap:category , ; - doap:download-page <> ; + doap:download-page ; doap:mailing-list ; doap:bug-database ; doap:blog ; diff --git a/etc/earl.ttl b/etc/earl.ttl index 36d3109..b87a4a9 100644 --- a/etc/earl.ttl +++ b/etc/earl.ttl @@ -1,4 +1,3 @@ -@base . @prefix rdf: . @prefix rdfs: . @prefix dc: . @@ -7,1162 +6,1247 @@ @prefix ex: . @prefix xsd: . -<> a doap:Project ; + a doap:Project ; doap:name "RDF::Normalize" ; doap:homepage ; doap:license ; - doap:shortdesc "Turtle reader/writer for Ruby."@en ; - doap:description "RDF::Normalize is a Graph normalizer for the RDF.rb library suite."@en ; + doap:shortdesc "RDF Dataset Normalization for RDF.rb."@en ; + doap:description "RDF::Normalize is a Dataset normalizer for the RDF.rb library suite."@en ; doap:created "2015-05-20"^^xsd:date; doap:programming-language "Ruby" ; - doap:implements ; + doap:implements ; doap:category , ; - doap:download-page ; - doap:mailing-list ; + doap:download-page ; + doap:mailing-list ; doap:bug-database ; - doap:blog ; - doap:developer ; - doap:maintainer ; - doap:documenter ; - foaf:maker ; - dc:creator . - -<> foaf:primaryTopic ; - dc:issued "2015-05-20T12:08:28-07:00"^^xsd:dateTime ; - foaf:maker . - - a foaf:Person, earl:Assertor; + doap:blog ; + doap:developer ; + doap:maintainer ; + doap:documenter ; + foaf:maker ; + dc:creator . + + doap:release [ + doap:name "rdf-normalize-0.5.0"; + doap:revision "0.5.0"; + doap:created "2021-12-29"^^xsd:date; +] . +<> foaf:primaryTopic ; + dc:issued "2022-10-31T15:10:51-07:00"^^xsd:dateTime ; + foaf:maker . + + a foaf:Person, earl:Assertor; foaf:name "Gregg Kellogg"; foaf:title "Implementor"; - foaf:homepage . + foaf:homepage . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . [ a earl:Assertion; - earl:assertedBy ; - earl:subject ; + earl:assertedBy ; + earl:subject ; earl:test ; earl:result [ a earl:TestResult; earl:outcome earl:passed; - dc:date "2015-05-20T12:08:28-07:00"^^xsd:dateTime]; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; + earl:mode earl:automatic ] . + +[ a earl:Assertion; + earl:assertedBy ; + earl:subject ; + earl:test ; + earl:result [ + a earl:TestResult; + earl:outcome earl:passed; + dc:date "2022-10-31T15:10:51-07:00"^^xsd:dateTime]; earl:mode earl:automatic ] . diff --git a/lib/rdf/normalize.rb b/lib/rdf/normalize.rb index e8d2c18..6c38581 100644 --- a/lib/rdf/normalize.rb +++ b/lib/rdf/normalize.rb @@ -25,7 +25,7 @@ module RDF # writer << RDF::Repository.load("etc/doap.ttl") # end # - # @author [Gregg Kellogg](http://greggkellogg.net/) + # @author [Gregg Kellogg](https://greggkellogg.net/) module Normalize require 'rdf/normalize/format' autoload :Base, 'rdf/normalize/base' diff --git a/lib/rdf/normalize/urdna2015.rb b/lib/rdf/normalize/urdna2015.rb index 1dde506..27e1e51 100644 --- a/lib/rdf/normalize/urdna2015.rb +++ b/lib/rdf/normalize/urdna2015.rb @@ -27,30 +27,23 @@ def normalize_statements(ns, &block) end end - non_normalized_identifiers, simple = ns.bnode_to_statements.keys, true + ns.hash_to_bnodes = {} - while simple - simple = false - ns.hash_to_bnodes = {} - - # Calculate hashes for first degree nodes - non_normalized_identifiers.each do |node| - hash = log_depth {ns.hash_first_degree_quads(node)} - log_debug("1deg") {"hash: #{hash}"} - ns.add_bnode_hash(node, hash) - end + # Calculate hashes for first degree nodes + ns.bnode_to_statements.each_key do |node| + hash = log_depth {ns.hash_first_degree_quads(node)} + log_debug("1deg") {"hash: #{hash}"} + ns.add_bnode_hash(node, hash) + end - # Create canonical replacements for hashes mapping to a single node - ns.hash_to_bnodes.keys.sort.each do |hash| - identifier_list = ns.hash_to_bnodes[hash] - next if identifier_list.length > 1 - node = identifier_list.first - id = ns.canonical_issuer.issue_identifier(node) - log_debug("single node") {"node: #{node.to_ntriples}, hash: #{hash}, id: #{id}"} - non_normalized_identifiers -= identifier_list - ns.hash_to_bnodes.delete(hash) - simple = true - end + # Create canonical replacements for hashes mapping to a single node + ns.hash_to_bnodes.keys.sort.each do |hash| + identifier_list = ns.hash_to_bnodes[hash] + next if identifier_list.length > 1 + node = identifier_list.first + id = ns.canonical_issuer.issue_identifier(node) + log_debug("single node") {"node: #{node.to_ntriples}, hash: #{hash}, id: #{id}"} + ns.hash_to_bnodes.delete(hash) end # Iterate over hashs having more than one node @@ -107,12 +100,13 @@ def initialize(options) def add_statement(node, statement) bnode_to_statements[node] ||= [] - bnode_to_statements[node] << statement unless bnode_to_statements[node].include?(statement) + bnode_to_statements[node] << statement unless bnode_to_statements[node].any? {|st| st.eql?(statement)} end def add_bnode_hash(node, hash) hash_to_bnodes[hash] ||= [] - hash_to_bnodes[hash] << node unless hash_to_bnodes[hash].include?(node) + # Match on object IDs of nodes, rather than simple node equality + hash_to_bnodes[hash] << node unless hash_to_bnodes[hash].any? {|n| n.eql?(node)} end # @param [RDF::Node] node @@ -143,7 +137,7 @@ def hash_related_node(related, statement, issuer, position) identifier = canonical_issuer.identifier(related) || issuer.identifier(related) || hash_first_degree_quads(related) - input = position.to_s + input = "#{position}" input << statement.predicate.to_ntriples unless position == :g input << identifier log_debug("hrel") {"input: #{input.inspect}, hash: #{hexdigest(input)}"} @@ -225,7 +219,7 @@ def hash_related_statement(identifier, statement, issuer, map) hash = log_depth {hash_related_node(term, statement, issuer, pos)} map[hash] ||= [] - map[hash] << term unless map[hash].include?(term) + map[hash] << term unless map[hash].any? {|n| n.eql?(term)} end end end diff --git a/lib/rdf/normalize/urgna2012.rb b/lib/rdf/normalize/urgna2012.rb index 5005c61..c973bd0 100644 --- a/lib/rdf/normalize/urgna2012.rb +++ b/lib/rdf/normalize/urgna2012.rb @@ -23,9 +23,7 @@ def hash_related_node(related, statement, issuer, position) identifier = canonical_issuer.identifier(related) || issuer.identifier(related) || hash_first_degree_quads(related) - input = position.to_s - input << statement.predicate.to_s - input << identifier + input = "#{position}#{statement.predicate}#{identifier}" log_debug("hrel") {"input: #{input.inspect}, hash: #{hexdigest(input)}"} hexdigest(input) end @@ -35,11 +33,11 @@ def hash_related_statement(identifier, statement, issuer, map) if statement.subject.node? && statement.subject != identifier hash = log_depth {hash_related_node(statement.subject, statement, issuer, :p)} map[hash] ||= [] - map[hash] << statement.subject unless map[hash].include?(statement.subject) + map[hash] << statement.subject unless map[hash].any? {|n| n.eql?(statement.subject)} elsif statement.object.node? && statement.object != identifier hash = log_depth {hash_related_node(statement.object, statement, issuer, :r)} map[hash] ||= [] - map[hash] << statement.object unless map[hash].include?(statement.object) + map[hash] << statement.object unless map[hash].any? {|n| n.eql?(statement.object)} end end end diff --git a/lib/rdf/normalize/version.rb b/lib/rdf/normalize/version.rb index 856d0a7..dc126ae 100644 --- a/lib/rdf/normalize/version.rb +++ b/lib/rdf/normalize/version.rb @@ -1,5 +1,5 @@ module RDF::Normalize::VERSION - VERSION_FILE = File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "..", "VERSION") + VERSION_FILE = File.expand_path("../../../../VERSION", __FILE__) MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chop.split(".") STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.') diff --git a/lib/rdf/normalize/writer.rb b/lib/rdf/normalize/writer.rb index 5f38f72..4d9256a 100644 --- a/lib/rdf/normalize/writer.rb +++ b/lib/rdf/normalize/writer.rb @@ -4,7 +4,7 @@ module RDF::Normalize # # Normalizes the enumerated statements into normal form in the form of N-Quads. # - # @author [Gregg Kellogg](http://greggkellogg.net/) + # @author [Gregg Kellogg](https://greggkellogg.net/) class Writer < RDF::NQuads::Writer format RDF::Normalize::Format diff --git a/rdf-normalize.gemspec b/rdf-normalize.gemspec index 14ac1d9..fe2ef03 100755 --- a/rdf-normalize.gemspec +++ b/rdf-normalize.gemspec @@ -9,7 +9,14 @@ Gem::Specification.new do |gem| gem.homepage = "https://github.com/ruby-rdf/rdf-normalize" gem.license = 'Unlicense' gem.summary = "RDF Graph normalizer for Ruby." - gem.description = %q{RDF::Normalize is a Graph normalizer for the RDF.rb library suite.} + gem.description = %q{RDF::Normalize performs Dataset Canonicalization for RDF.rb.} + gem.metadata = { + "documentation_uri" => "https://ruby-rdf.github.io/rdf-normalize", + "bug_tracker_uri" => "https://github.com/ruby-rdf/rdf-normalize/issues", + "homepage_uri" => "https://github.com/ruby-rdf/rdf-normalize", + "mailing_list_uri" => "https://lists.w3.org/Archives/Public/public-rdf-ruby/", + "source_code_uri" => "https://github.com/ruby-rdf/rdf-normalize", + } gem.authors = ['Gregg Kellogg'] gem.email = 'public-rdf-ruby@w3.org' @@ -22,7 +29,6 @@ Gem::Specification.new do |gem| gem.add_dependency 'rdf', '~> 3.2' gem.add_development_dependency 'rdf-spec', '~> 3.2' gem.add_development_dependency 'rspec', '~> 3.10' - gem.add_development_dependency 'webmock', '~> 3.11' gem.add_development_dependency 'json-ld', '~> 3.2' gem.add_development_dependency 'yard' , '~> 0.9' gem.post_install_message = nil diff --git a/script/tc b/script/tc index 55c04ad..f0f6e0b 100755 --- a/script/tc +++ b/script/tc @@ -1,32 +1,37 @@ #!/usr/bin/env ruby require 'rubygems' -$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib'))) +$:.unshift(File.expand_path("../../lib", __FILE__)) require "bundler/setup" require 'logger' require 'rdf/normalize' -require File.expand_path(File.join(File.dirname(__FILE__), "..", 'spec', 'spec_helper')) -require File.expand_path(File.join(File.dirname(__FILE__), "..", 'spec', 'suite_helper')) +require_relative "../spec/spec_helper" +require_relative "../spec/suite_helper" require 'getoptlong' -ASSERTOR = "http://greggkellogg.net/foaf#me" +ASSERTOR = "https://greggkellogg.net/foaf#me" RUN_TIME = Time.now def earl_preamble(options) options[:output].write File.read(File.expand_path("../../etc/doap.ttl", __FILE__)) options[:output].puts %( -<> foaf:primaryTopic ; + doap:release [ + doap:name "rdf-normalize-#{RDF::Normalize::VERSION}"; + doap:revision "#{RDF::Normalize::VERSION}"; + doap:created "#{File.mtime(File.expand_path('../../VERSION', __FILE__)).strftime('%Y-%m-%d')}"^^xsd:date; +] . +<> foaf:primaryTopic ; dc:issued "#{RUN_TIME.xmlschema}"^^xsd:dateTime ; foaf:maker <#{ASSERTOR}> . <#{ASSERTOR}> a foaf:Person, earl:Assertor; foaf:name "Gregg Kellogg"; foaf:title "Implementor"; - foaf:homepage . + foaf:homepage . ) end def run_tc(tc, **options) - STDERR.write "run #{tc.id}" + $stderr.write "run #{tc.id}" if options[:verbose] puts "\nTestCase: #{tc.inspect}" @@ -41,24 +46,31 @@ def run_tc(tc, **options) options = {base_uri: tc.base}.merge(options) dataset = RDF::Repository.load(tc.action, format: :nquads) - output = dataset.dump(:normalize, tc.writer_options.merge(logger: options[:logger])) + output = dataset.dump(:normalize, **tc.writer_options.merge(logger: options[:logger])) + result = output == tc.expected ? "passed" : "failed" - rescue Exception => e - STDERR.puts "#{"exception:" unless options[:quiet]}: #{e}" + options[:results][result] ||= 0 + options[:results][result] += 1 + rescue Interrupt + $stderr.puts "(interrupt)" + exit 1 + rescue StandardError => e + $stderr.puts "#{"exception:" unless options[:quiet]}: #{e}" if options[:quiet] - return + options[:results]['failed'] ||= 0 + options[:results]['failed'] += 1 else raise end end - options[:output].puts("\nOutput:\n" + output) unless options[:quiet] + options[:output].puts("\nOutput:\n" + output) if options[:verbose] if options[:earl] options[:output].puts %{ [ a earl:Assertion; earl:assertedBy <#{ASSERTOR}>; - earl:subject ; + earl:subject ; earl:test <#{tc.id}>; earl:result [ a earl:TestResult; @@ -68,10 +80,7 @@ def run_tc(tc, **options) } end - options[:result_count][result] ||= 0 - options[:result_count][result] += 1 - - puts "#{"test result:" unless options[:quiet]} #{result}" + puts "#{" test result:" unless options[:quiet]} #{result}" end logger = Logger.new(STDERR) @@ -80,12 +89,13 @@ logger.formatter = lambda {|severity, datetime, progname, msg| "#{severity}: #{m options = { output: STDOUT, + results: {}, logger: logger } opts = GetoptLong.new( ["--help", "-?", GetoptLong::NO_ARGUMENT], - ["--dbg", GetoptLong::NO_ARGUMENT], + ["--debug", GetoptLong::NO_ARGUMENT], ["--earl", GetoptLong::NO_ARGUMENT], ["--quiet", "-q", GetoptLong::NO_ARGUMENT], ["--output", "-o", GetoptLong::REQUIRED_ARGUMENT], @@ -96,7 +106,7 @@ opts = GetoptLong.new( def help(options) puts "Usage: #{$0} [options] [test-number ...]" puts "Options:" - puts " --dbg: Display detailed debug output" + puts " --debug: Display detailed debug output" puts " --earl: Generate EARL report" puts " --quiet: Minimal output" puts " --output: Output to specified file" @@ -109,7 +119,7 @@ end opts.each do |opt, arg| case opt when '--help' then help(options) - when '--dbg' then logger.level = Logger::DEBUG + when '--debug' then logger.level = Logger::DEBUG when '--earl' options[:quiet] = options[:earl] = true logger.level = Logger::FATAL @@ -124,21 +134,15 @@ end earl_preamble(options) if options[:earl] -WebMock.allow_net_connect!(net_http_connect_on_start: true) - -result_count = {} - -%w(urgna2012 urdna2015).each do |variant| +%w(urdna2015).each do |variant| manifest = Fixtures::SuiteTest::BASE + "manifest-#{variant}.jsonld" Fixtures::SuiteTest::Manifest.open(manifest, manifest[0..-8]) do |m| m.entries.each do |tc| next unless ARGV.empty? || ARGV.any? {|n| tc.id.match(/#{n}/)} - run_tc(tc, options.merge(result_count: result_count)) + run_tc(tc, **options) end end end -result_count.each do |result, count| - puts "#{result}: #{count}" -end +options[:results].each {|k, v| puts "#{k}: #{v}"} diff --git a/spec/format_spec.rb b/spec/format_spec.rb index 47b2435..71b3d3c 100644 --- a/spec/format_spec.rb +++ b/spec/format_spec.rb @@ -1,5 +1,4 @@ -$:.unshift "." -require 'spec_helper' +require_relative 'spec_helper' require 'rdf/spec/format' describe RDF::Normalize::Format do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ce2ffe2..e373b8e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,7 +6,6 @@ require 'json/ld' require 'rdf/spec' require 'rdf/nquads' -require 'webmock/rspec' begin require 'simplecov' diff --git a/spec/suite_helper.rb b/spec/suite_helper.rb index a56eec2..e4407d2 100644 --- a/spec/suite_helper.rb +++ b/spec/suite_helper.rb @@ -5,8 +5,8 @@ # For now, override RDF::Utils::File.open_file to look for the file locally before attempting to retrieve it module RDF::Util module File - REMOTE_PATH = "http://json-ld.github.io/normalization/" - LOCAL_PATH = ::File.expand_path("../w3c-normalization", __FILE__) + '/' + REMOTE_PATH = "https://w3c.github.io/rdf-canon/" + LOCAL_PATH = ::File.expand_path("../../../w3c-rdf-canon", __FILE__) + '/' class << self alias_method :original_open_file, :open_file @@ -75,7 +75,7 @@ def self.open_file(filename_or_url, **options, &block) module Fixtures module SuiteTest - BASE = "http://json-ld.github.io/normalization/tests/" + BASE = "https://w3c.github.io/rdf-canon/tests/" class Manifest < JSON::LD::Resource def self.open(file, base) #puts "open: #{file}" @@ -122,7 +122,7 @@ def expected def writer_options res = {} - res[:algorithm] = type.sub('rdfn:', '').sub('EvalTest', '').downcase.to_sym + res[:algorithm] = type.sub('rdfc:', '').sub('EvalTest', '').downcase.to_sym res end end diff --git a/spec/suite_spec.rb b/spec/suite_spec.rb index 51abe9f..b00250c 100644 --- a/spec/suite_spec.rb +++ b/spec/suite_spec.rb @@ -1,15 +1,10 @@ -$:.unshift "." -require 'spec_helper' require 'fileutils' +require_relative 'spec_helper' -WebMock.allow_net_connect!(net_http_connect_on_start: true) describe RDF::Normalize::Writer do - require 'suite_helper' + require_relative 'suite_helper' - before(:all) {WebMock.allow_net_connect!(net_http_connect_on_start: true)} - after(:all) {WebMock.allow_net_connect!(net_http_connect_on_start: false)} - - %w(urgna2012 urdna2015).each do |variant| + %w(urdna2015).each do |variant| describe "w3c Normalization #{variant.upcase} tests" do manifest = Fixtures::SuiteTest::BASE + "manifest-#{variant}.jsonld" diff --git a/spec/writer_spec.rb b/spec/writer_spec.rb index 7233dcc..b5badd1 100644 --- a/spec/writer_spec.rb +++ b/spec/writer_spec.rb @@ -1,5 +1,4 @@ -$:.unshift "." -require 'spec_helper' +require_relative 'spec_helper' require 'rdf/spec/writer' describe RDF::Normalize::Writer do