|
| 1 | +-# This template is used for generating a rollup EARL report. It expects to be |
| 2 | +-# called with a single _tests_ local with the following structure |
| 3 | +-# |
| 4 | +-# { |
| 5 | +-# "@context": {...}, |
| 6 | +-# "@id": "", |
| 7 | +-# "@type": "earl:Software", |
| 8 | +-# "name": "...", |
| 9 | +-# "bibRef": "[[...]]", |
| 10 | +-# "assertions": ["rdfxml-streaming-parser.js.ttl"], |
| 11 | +-# "testSubjects": [ |
| 12 | +-# { |
| 13 | +-# "@id": "https://www.npmjs.com/package/rdfxml-streaming-parser/", |
| 14 | +-# "@type": "earl:TestSubject", |
| 15 | +-# "name": "rdfxml-streaming-parser" |
| 16 | +-# }, |
| 17 | +-# ... |
| 18 | +-# ], |
| 19 | +-# "tests": [{ |
| 20 | +-# "@id": "http://www.w3.org/2013/TurtleTests/manifest.ttl#turtle-syntax-file-01", |
| 21 | +-# "@type": ["earl:TestCriterion", "earl:TestCase"], |
| 22 | +-# "title": "subm-test-00", |
| 23 | +-# "description": "Blank subject", |
| 24 | +-# "testAction": "http://www.w3.org/2013/TurtleTests/turtle-syntax-file-01.ttl", |
| 25 | +-# "testResult": "http://www.w3.org/2013/TurtleTests/turtle-syntax-file-01.out" |
| 26 | +-# "mode": "earl:automatic", |
| 27 | +-# "assertions": [ |
| 28 | +-# { |
| 29 | +-# "@type": "earl:Assertion", |
| 30 | +-# "assertedBy": "http://greggkellogg.net/foaf#me", |
| 31 | +-# "test": "http://svn.apache.org/repos/asf/jena/Experimental/riot-reader/testing/RIOT/Lang/TurtleSubm/manifest.ttl#testeval00", |
| 32 | +-# "subject": "http://rubygems.org/gems/rdf-turtle", |
| 33 | +-# "result": { |
| 34 | +-# "@type": "earl:TestResult", |
| 35 | +-# "outcome": "earl:passed" |
| 36 | +-# } |
| 37 | +-# } |
| 38 | +-# ] |
| 39 | +-# }] |
| 40 | +-# } |
| 41 | +- require 'cgi' |
| 42 | + |
| 43 | +!!! 5 |
| 44 | +%html{:prefix => "earl: http://www.w3.org/ns/earl# doap: http://usefulinc.com/ns/doap# mf: http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#"} |
| 45 | + - test_info = {} |
| 46 | + - test_refs = {} |
| 47 | + - subject_refs = {} |
| 48 | + - passed_tests = [] |
| 49 | + - subjects = tests['testSubjects'].sort_by {|s| s['name'].to_s.downcase} |
| 50 | + - subjects.each_with_index do |subject, index| |
| 51 | + - subject_refs[subject['@id']] = "subj_#{index}" |
| 52 | + %head |
| 53 | + %meta{"http-equiv" => "Content-Type", :content => "text/html;charset=utf-8"} |
| 54 | + %link{:rel => "alternate", :href => "earl.ttl"} |
| 55 | + %link{:rel => "alternate", :href => "earl.jsonld"} |
| 56 | + - tests['assertions'].each do |file| |
| 57 | + %link{:rel => "related", :href => file} |
| 58 | + %title |
| 59 | + = tests['name'] |
| 60 | + Implementation Report |
| 61 | + %script.remove{:src => "../../local-biblio.js"} |
| 62 | + %script.remove{:type => "text/javascript", :src => "https://www.w3.org/Tools/respec/respec-w3c-common"} |
| 63 | + :javascript |
| 64 | + var respecConfig = { |
| 65 | + // extend the bibliography entries |
| 66 | + localBiblio: localBibliography, |
| 67 | + |
| 68 | + // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED. |
| 69 | + specStatus: "base", |
| 70 | + copyrightStart: "2010", |
| 71 | + doRDFa: "1.1", |
| 72 | + |
| 73 | + // the specification's short name, as in http://www.w3.org/TR/short-name/ |
| 74 | + shortName: "rdf-syntax-grammar", |
| 75 | + //subtitle: "RDF/XML Implementation Conformance Report", |
| 76 | + // if you wish the publication date to be other than today, set this |
| 77 | + publishDate: "#{Time.now.strftime("%Y/%m/%d")}", |
| 78 | + |
| 79 | + // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date |
| 80 | + // and its maturity status |
| 81 | + //previousPublishDate: "2011-10-23", |
| 82 | + //previousMaturity: "ED", |
| 83 | + //previousDiffURI: "http://json-ld.org/spec/ED/json-ld-syntax/20111023/index.html", |
| 84 | + //diffTool: "http://www.aptest.com/standards/htmldiff/htmldiff.pl", |
| 85 | + |
| 86 | + // if there a publicly available Editor's Draft, this is the link |
| 87 | + //edDraftURI: "", |
| 88 | + |
| 89 | + // if this is a LCWD, uncomment and set the end of its review period |
| 90 | + // lcEnd: "2009-08-05", |
| 91 | + |
| 92 | + // editors, add as many as you like |
| 93 | + // only "name" is required |
| 94 | + editors: [ |
| 95 | + { name: "Gregg Kellogg", url: "http://greggkellogg.net/", |
| 96 | + company: "Kellogg Associates" }, |
| 97 | + { name: "Andy Seaborne", |
| 98 | + company: "The Apache Software Foundation"} |
| 99 | + ], |
| 100 | + |
| 101 | + // authors, add as many as you like. |
| 102 | + // This is optional, uncomment if you have authors as well as editors. |
| 103 | + // only "name" is required. Same format as editors. |
| 104 | + //authors: [ |
| 105 | + //RDF Working Group], |
| 106 | + |
| 107 | + // name of the WG |
| 108 | + wg: "RDF Working Group", |
| 109 | + |
| 110 | + // URI of the public WG page |
| 111 | + wgURI: "http://www.w3.org/2011/rdf-wg/", |
| 112 | + |
| 113 | + // name (with the @w3c.org) of the public mailing to which comments are due |
| 114 | + wgPublicList: "public-rdf-comments", |
| 115 | + |
| 116 | + // URI of the patent status for this WG, for Rec-track documents |
| 117 | + // !!!! IMPORTANT !!!! |
| 118 | + // This is important for Rec-track documents, do not copy a patent URI from a random |
| 119 | + // document unless you know what you're doing. If in doubt ask your friendly neighbourhood |
| 120 | + // Team Contact. |
| 121 | + wgPatentURI: "http://www.w3.org/2004/01/pp-impl/46168/status", |
| 122 | + alternateFormats: [ |
| 123 | + {uri: "earl.ttl", label: "Turtle"}, |
| 124 | + {uri: "earl.jsonld", label: "JSON-LD"} |
| 125 | + ], |
| 126 | + }; |
| 127 | + :css |
| 128 | + span[property='dc:description'] { display: none; } |
| 129 | + td.PASS { color: green; } |
| 130 | + td.FAIL { color: red; } |
| 131 | + table.report { |
| 132 | + border-width: 1px; |
| 133 | + border-spacing: 2px; |
| 134 | + border-style: outset; |
| 135 | + border-color: gray; |
| 136 | + border-collapse: separate; |
| 137 | + background-color: white; |
| 138 | + } |
| 139 | + table.report th { |
| 140 | + border-width: 1px; |
| 141 | + padding: 1px; |
| 142 | + border-style: inset; |
| 143 | + border-color: gray; |
| 144 | + background-color: white; |
| 145 | + -moz-border-radius: ; |
| 146 | + } |
| 147 | + table.report td { |
| 148 | + border-width: 1px; |
| 149 | + padding: 1px; |
| 150 | + border-style: inset; |
| 151 | + border-color: gray; |
| 152 | + background-color: white; |
| 153 | + -moz-border-radius: ; |
| 154 | + } |
| 155 | + tr.summary {font-weight: bold;} |
| 156 | + td.passed-all {color: green;} |
| 157 | + td.passed-most {color: darkorange;} |
| 158 | + td.passed-some {color: red;} |
| 159 | + %body{:prefix => "earl: http://www.w3.org/ns/earl# doap: http://usefulinc.com/ns/doap# mf: http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#"} |
| 160 | + %section#abstract{:about => tests['@id'], :typeof => [tests['@type']].flatten.join(" ")} |
| 161 | + %p |
| 162 | + This document report test subject conformance for and related specifications for |
| 163 | + %span{:property => "doap:name"}<=tests['name'] |
| 164 | + %span{:property => "dc:bibliographicCitation"}< |
| 165 | + = tests['bibRef'] |
| 166 | + according to the requirements of the Evaluation and Report Language (EARL) 1.0 Schema [[EARL10-SCHEMA]]. |
| 167 | + %p |
| 168 | + This report is also available in alternate formats: |
| 169 | + %a{:rel => "xhv:alternate", :href => "earl.ttl"} |
| 170 | + Turtle |
| 171 | + and |
| 172 | + %a{:rel => "xhv:alternate", :href => "earl.jsonld"} |
| 173 | + JSON-LD |
| 174 | + %section#sodt |
| 175 | + %section |
| 176 | + :markdown |
| 177 | + ## Instructions for submitting implementation reports |
| 178 | + |
| 179 | + Tests should be run using the test manifests defined in the |
| 180 | + [Test Manifests](#test-manifests) Section. |
| 181 | + |
| 182 | + The assumed base URI for the tests is `<http://example/base/>` if needed. |
| 183 | + |
| 184 | + Reports should be submitted in Turtle format to [[email protected]](mailto:[email protected]) |
| 185 | + and include an `earl:Assertion` |
| 186 | + for each test, referencing the test resource from the associated manifest |
| 187 | + and the test subject being reported upon. An example test entry is be the following: |
| 188 | + |
| 189 | + [ a earl:Assertion; |
| 190 | + earl:assertedBy <https://www.rubensworks.net/#me>; |
| 191 | + earl:subject <https://www.npmjs.com/package/rdfxml-streaming-parser/>; |
| 192 | + earl:test <https://www.w3.org/2013/RDFXMLTests/manifest.ttl#rdf-element-not-mandatory-test001>; |
| 193 | + earl:result [ |
| 194 | + a earl:TestResult; |
| 195 | + earl:outcome earl:passed; |
| 196 | + dc:date "2018-10-08T23:16:03.823Z"^^xsd:dateTime]; |
| 197 | + earl:mode earl:automatic ] . |
| 198 | + |
| 199 | + The Test Subject should be defined as a `doap:Project`, including the name, |
| 200 | + homepage and developer(s) of the software (see [[DOAP]]). Optionally, including the |
| 201 | + project description and programming language. An example test subject description is the following: |
| 202 | + |
| 203 | + <> foaf:primaryTopic <https://www.npmjs.com/package/rdfxml-streaming-parser/>; |
| 204 | + dc:issued "2018-10-08T23:16:03.823Z"^^xsd:dateTime; |
| 205 | + foaf:maker <https://www.rubensworks.net/#me>. |
| 206 | + |
| 207 | + <https://www.npmjs.com/package/rdfxml-streaming-parser/> a earl:Software, earl:TestSubject, doap:Project; |
| 208 | + doap:name "rdfxml-streaming-parser"; |
| 209 | + dc:title "rdfxml-streaming-parser"; |
| 210 | + doap:homepage <https://github.com/rdfjs/rdfxml-streaming-parser.js#readme>; |
| 211 | + doap:license <http://opensource.org/licenses/MIT>; |
| 212 | + doap:programming-language "JavaScript"; |
| 213 | + doap:implements <https://www.w3.org/TR/rdf-syntax-grammar/>; |
| 214 | + doap:category <http://dbpedia.org/resource/Resource_Description_Framework>; |
| 215 | + doap:download-page <https://npmjs.org/package/rdfxml-streaming-parser>; |
| 216 | + doap:bug-database <https://github.com/rdfjs/rdfxml-streaming-parser.js/issues>; |
| 217 | + doap:developer <https://www.rubensworks.net/#me>; |
| 218 | + doap:maintainer <https://www.rubensworks.net/#me>; |
| 219 | + doap:documenter <https://www.rubensworks.net/#me>; |
| 220 | + doap:maker <https://www.rubensworks.net/#me>; |
| 221 | + dc:creator <https://www.rubensworks.net/#me>; |
| 222 | + dc:description "Streaming RDF/XML parser"@en; |
| 223 | + doap:description "Streaming RDF/XML parser"@en. |
| 224 | + |
| 225 | + The software developer, either an organization or one or more individuals SHOULD be |
| 226 | + referenced from `doap:developer` using [[FOAF]]. For example: |
| 227 | + |
| 228 | + <https://www.rubensworks.net/#me> a foaf:Person, earl:Assertor; |
| 229 | + foaf:name "Ruben Taelman <[email protected]>"; |
| 230 | + foaf:homepage <https://www.rubensworks.net/>. |
| 231 | + |
| 232 | + See [RDF Test Suite Wiki](https://www.w3.org/2011/rdf-wg/wiki/RDF_Test_Suites) |
| 233 | + for more information. |
| 234 | + %section |
| 235 | + %h2 |
| 236 | + Test Manifests |
| 237 | + - tests['entries'].each_with_index do |manifest, ndx2| |
| 238 | + - test_cases = manifest['entries'] |
| 239 | + %section{:typeof => manifest['@type'].join(" "), :resource => manifest['@id']} |
| 240 | + %h2<="RDF/XML Tests" |
| 241 | + - [manifest['description']].flatten.compact.each do |desc| |
| 242 | + %p< |
| 243 | + ~ CGI.escapeHTML desc.to_s |
| 244 | + %table.report |
| 245 | + - skip_subject = {} |
| 246 | + - passed_tests[ndx2] = [] |
| 247 | + %tr |
| 248 | + %th |
| 249 | + Test |
| 250 | + - subjects.each_with_index do |subject, index| |
| 251 | + -# If subject is untested for every test in this manifest, skip it |
| 252 | + - skip_subject[subject['@id']] = manifest['entries'].all? {|t| t['assertions'][index]['result']['outcome'] == 'earl:untested'} |
| 253 | + - unless skip_subject[subject['@id']] |
| 254 | + %th |
| 255 | + %a{:href => '#' + subject_refs[subject['@id']]}<=Array(subject['name']).first |
| 256 | + - test_cases.each do |test| |
| 257 | + - tid = 'test_' + (test['@id'][0,2] == '_:' ? test['@id'][2..-1] : test['@id'].split('#').last) |
| 258 | + - (test_info[tid] ||= []) << test |
| 259 | + - test_refs[test['@id']] = tid |
| 260 | + %tr{:rel => "mf:entries", :typeof => test['@type'].join(" "), :resource => test['@id'], :inlist => true} |
| 261 | + %td |
| 262 | + %a{:href => "##{tid}"}< |
| 263 | + ~ CGI.escapeHTML test['title'].to_s |
| 264 | + - subjects.each_with_index do |subject, ndx| |
| 265 | + - next if skip_subject[subject['@id']] |
| 266 | + - assertion = test['assertions'].detect {|a| a['subject'] == subject['@id']} |
| 267 | + - pass_fail = assertion['result']['outcome'].split(':').last.upcase.sub(/(PASS|FAIL)ED$/, '\1') |
| 268 | + - passed_tests[ndx2][ndx] = (passed_tests[ndx2][ndx] || 0) + (pass_fail == 'PASS' ? 1 : 0) |
| 269 | + %td{:class => pass_fail, :property => "earl:assertions", :typeof => assertion['@type']} |
| 270 | + - if assertion['assertedBy'] |
| 271 | + %link{:property => "earl:assertedBy", :href => assertion['assertedBy']} |
| 272 | + %link{:property => "earl:test", :href => assertion['test']} |
| 273 | + %link{:property => "earl:subject", :href => assertion['subject']} |
| 274 | + - if assertion['mode'] |
| 275 | + %link{:property => 'earl:mode', :href => assertion['mode']} |
| 276 | + %span{:property => "earl:result", :typeof => assertion['result']['@type']} |
| 277 | + %span{:property => 'earl:outcome', :resource => assertion['result']['outcome']} |
| 278 | + = pass_fail |
| 279 | + %tr.summary |
| 280 | + %td |
| 281 | + = "Percentage passed out of #{manifest['entries'].length} Tests" |
| 282 | + - passed_tests[ndx2].compact.each do |r| |
| 283 | + - pct = (r * 100.0) / manifest['entries'].length |
| 284 | + %td{:class => (pct == 100.0 ? 'passed-all' : (pct >= 95.0 ? 'passed-most' : 'passed-some'))} |
| 285 | + = "#{'%.1f' % pct}%" |
| 286 | + %section.appendix |
| 287 | + %h2 |
| 288 | + Test Subjects |
| 289 | + %p |
| 290 | + This report was tested using the following test subjects: |
| 291 | + %dl |
| 292 | + - subjects.each_with_index do |subject, index| |
| 293 | + %dt{:id => subject_refs[subject['@id']]} |
| 294 | + %a{:href => subject['@id']} |
| 295 | + %span{:about => subject['@id'], :property => "doap:name"}<= Array(subject['name']).first |
| 296 | + %dd{:property => "earl:testSubjects", :resource => subject['@id'], :typeof => [subject['@type']].flatten.join(" ")} |
| 297 | + %dl |
| 298 | + - if subject['doapDesc'] |
| 299 | + %dt= "Description" |
| 300 | + %dd{:property => "doap:description", :lang => 'en'}< |
| 301 | + ~ CGI.escapeHTML subject['doapDesc'].to_s |
| 302 | + - if subject['language'] |
| 303 | + %dt= "Programming Language" |
| 304 | + %dd{:property => "doap:programming-language"}< |
| 305 | + ~ CGI.escapeHTML subject['language'].to_s |
| 306 | + - if subject['homepage'] |
| 307 | + %dt= "Home Page" |
| 308 | + %dd{:property => "doap:homepage"} |
| 309 | + %a{:href=> subject['homepage']} |
| 310 | + ~ CGI.escapeHTML subject['homepage'].to_s |
| 311 | + - if subject['developer'] |
| 312 | + %dt= "Developer" |
| 313 | + - subject['developer'].each do |dev| |
| 314 | + %dd{:rel => "doap:developer"} |
| 315 | + %div{:resource => dev['@id'], :typeof => [dev['@type']].flatten.join(" ")} |
| 316 | + - if dev.has_key?('@id') |
| 317 | + %a{:href => dev['@id']} |
| 318 | + %span{:property => "foaf:name"}< |
| 319 | + ~ CGI.escapeHTML dev['foaf:name'].to_s |
| 320 | + - else |
| 321 | + %span{:property => "foaf:name"}< |
| 322 | + ~ CGI.escapeHTML dev['foaf:name'].to_s |
| 323 | + %dt |
| 324 | + Test Suite Compliance |
| 325 | + %dd |
| 326 | + %table.report |
| 327 | + %tbody |
| 328 | + - tests['entries'].each_with_index do |manifest, ndx| |
| 329 | + - passed = passed_tests[ndx][index].to_i |
| 330 | + - next if passed == 0 |
| 331 | + - total = manifest['entries'].length |
| 332 | + - pct = (passed * 100.0) / total |
| 333 | + %tr |
| 334 | + %td{:class => (pct == 100.0 ? 'passed-all' : (pct >= 85.0 ? 'passed-most' : 'passed-some'))} |
| 335 | + = "#{passed}/#{total} (#{'%.1f' % pct}%)" |
| 336 | + - unless tests['assertions'].empty? |
| 337 | + %section.appendix{:rel => "xhv:related earl:assertions"} |
| 338 | + %h2 |
| 339 | + Individual Test Results |
| 340 | + %p |
| 341 | + Individual test results used to construct this report are available here: |
| 342 | + %ul |
| 343 | + - tests['assertions'].each do |file| |
| 344 | + %li |
| 345 | + %a.source{:href => file}<= file |
| 346 | + %section#appendix{:property => "earl:generatedBy", :resource => tests['generatedBy']['@id'], :typeof => tests['generatedBy']['@type']} |
| 347 | + %h2 |
| 348 | + Report Generation Software |
| 349 | + - doap = tests['generatedBy'] |
| 350 | + - rel = doap['release'] |
| 351 | + %p |
| 352 | + This report generated by |
| 353 | + %span{:property => "doap:name"}< |
| 354 | + %a{:href => tests['generatedBy']['@id']}< |
| 355 | + = doap['name'] |
| 356 | + %meta{:property => "doap:shortdesc", :content => doap['shortdesc'], :lang => 'en'} |
| 357 | + %meta{:property => "doap:description", :content => doap['doapDesc'], :lang => 'en'} |
| 358 | + version |
| 359 | + %span{:property => "doap:release", :resource => rel['@id'], :typeof => 'doap:Version'} |
| 360 | + %span{:property => "doap:revision"}<=rel['revision'] |
| 361 | + %meta{:property => "doap:name", :content => rel['name']} |
| 362 | + %meta{:property => "doap:created", :content => rel['created'], :datatype => "xsd:date"} |
| 363 | + an |
| 364 | + %a{:property => "doap:license", :href => doap['license']}<="Unlicensed" |
| 365 | + %span{:property => "doap:programming-language"}<="Ruby" |
| 366 | + application. More information is available at |
| 367 | + %a{:property => "doap:homepage", :href => doap['homepage']}<=doap['homepage'] |
| 368 | + = "." |
| 369 | + %p{:property => "doap:developer", :resource => "http://greggkellogg.net/foaf#me", :typeof => "foaf:Person"} |
| 370 | + This software is provided by |
| 371 | + %a{:property => "foaf:homepage", :href => "http://greggkellogg.net/"}< |
| 372 | + %span{:aboue => "http://greggkellogg.net/foaf#me", :property => "foaf:name"}< |
| 373 | + Gregg Kellogg |
| 374 | + in hopes that it might make the lives of conformance testers easier. |
0 commit comments