Skip to content

Commit ee53b08

Browse files
committed
Update common files and create CI action.
1 parent 59c69eb commit ee53b08

File tree

3 files changed

+125
-33
lines changed

3 files changed

+125
-33
lines changed

.github/workflows/ci.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# This workflow validates the document for markup and examples.
2+
name: CI
3+
4+
on:
5+
push:
6+
branches: [ '**' ]
7+
pull_request:
8+
branches: [ main ]
9+
10+
jobs:
11+
tests:
12+
name: Build and Validate
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v2
16+
- name: Set up Ruby
17+
uses: ruby/setup-ruby@v1
18+
with:
19+
ruby-version: 2.7
20+
- name: Install dependencies
21+
run: bundle install
22+
23+
- name: "Verify common files are consistent"
24+
run: |
25+
git remote add -f b https://github.com/w3c/json-ld-wg.git
26+
git remote update
27+
git diff --exit-code remotes/b/main -- common
28+
29+
- name: Verify examples are consistent
30+
run: bundle exec rake test
31+
32+
- name: Checks HTML5
33+
run: bundle exec rake check_html
34+
35+
# See https://github.com/w3c/spec-prod/blob/main/docs/examples.md
36+
#- name: ReSpec Checker
37+
# uses: w3c/spec-prod@v1
38+
# with:
39+
# VALIDATE_LINKS: true
40+
# VALIDATE_MARKUP: true

common/common.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require(["core/pubsubhub"], (respecEvents) => {
99

1010
respecEvents.sub('end-all', (documentElement) => {
1111
// remove data-cite on where the citation is to ourselves.
12-
const selfDfns = document.querySelectorAll("dfn[data-cite^='__SPEC__#']");
12+
const selfDfns = Array.from(document.querySelectorAll("dfn[data-cite^='__SPEC__#']"));
1313
for (const dfn of selfDfns) {
1414
const anchor = dfn.querySelector('a');
1515
if (anchor) {
@@ -27,6 +27,51 @@ require(["core/pubsubhub"], (respecEvents) => {
2727
delete anchor.dataset.cite;
2828
}
2929

30+
//
31+
// Remove/hide definitions which are unused
32+
// 1. Find all definitions in a termlist which are not preserved, indexed by data-cite
33+
// 2. Find all references to definitions not in termlist
34+
// 4. Hide definitions which are unreferenced
35+
//
36+
const remoteDfns = [];
37+
document.querySelectorAll(".termlist dfn:not(.preserve)")
38+
.forEach((item, index) => {
39+
if (!selfDfns.includes(item)) {
40+
remoteDfns[item.dataset["cite"]] = item;
41+
}
42+
});
43+
44+
// termlist internal references to definitions
45+
const internalRefs = Array.from(document.querySelectorAll(".termlist a[data-cite]"));
46+
47+
// all references to definitions which are not internal refs
48+
const allRefs = Array.from(document.querySelectorAll("a[data-cite]"))
49+
.filter(e => !internalRefs.includes(e));
50+
51+
// Remove terms which are referenced
52+
for (const item of allRefs) {
53+
const cite = item.dataset["cite"];
54+
// Delete this from remoteDfns, as it is referenced
55+
delete remoteDfns[cite];
56+
}
57+
58+
// Now remoteDfns only contains unreferenced terms
59+
for (const item of Object.values(remoteDfns)) {
60+
const dt = item.closest("dt");
61+
if(dt) {
62+
const dd = dt.nextElementSibling;
63+
// Note, removing messes up some ReSpec references, so hiding instead
64+
// dt.parentNode.removeChild(dt);
65+
// dd.parentNode.removeChild(dd);
66+
dt.hidden = true;
67+
dd.hidden = true;
68+
}
69+
}
70+
71+
//
72+
// Playground
73+
//
74+
3075
// Add playground links
3176
for (const link of document.querySelectorAll("a.playground")) {
3277
let pre;

common/extract-examples.rb

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
require 'getoptlong'
1212
require 'json'
1313
require 'json/ld/preloaded'
14+
require 'rdf/isomorphic'
15+
require 'rdf/vocab'
1416
require 'nokogiri'
1517
require 'linkeddata'
1618
require 'fileutils'
@@ -304,6 +306,17 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
304306
args = []
305307
content = ex[:content]
306308

309+
options = ex[:options].to_s.split(',').inject({}) do |memo, pair|
310+
k, v = pair.split('=')
311+
v = case v
312+
when 'true' then true
313+
when 'false' then false
314+
else v
315+
end
316+
memo.merge(k.to_sym => v)
317+
end
318+
options[:validate] = true unless options.key?(:validate)
319+
307320
$stderr.puts "example #{ex[:number]}: #{ex.select{|k,v| k != :content}.to_json(JSON::LD::JSON_STATE)}" if verbose
308321
$stderr.puts "content: #{ex[:content]}" if verbose
309322

@@ -332,6 +345,7 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
332345
rescue JSON::ParserError => exception
333346
errors << "Example #{ex[:number]} at line #{ex[:line]} parse error: #{exception.message}"
334347
$stdout.write "F".colorize(:red)
348+
$stderr.puts exception.backtrace.join("\n") if verbose
335349
next
336350
end
337351
when 'html'
@@ -355,30 +369,33 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
355369
rescue Nokogiri::XML::SyntaxError => exception
356370
errors << "Example #{ex[:number]} at line #{ex[:line]} parse error: #{exception.message}"
357371
$stdout.write "F".colorize(:red)
372+
$stderr.puts exception.backtrace.join("\n") if verbose
358373
next
359374
end
360375
when 'table'
361376
content = Nokogiri::HTML.parse(content)
362377
when 'ttl', 'trig'
363378
begin
364379
reader_errors = []
365-
RDF::Repository.new << RDF::TriG::Reader.new(content, validate: true, logger: reader_errors)
380+
RDF::Repository.new << RDF::TriG::Reader.new(content, logger: reader_errors, **options)
366381
rescue
367382
reader_errors.each do |er|
368383
errors << "Example #{ex[:number]} at line #{ex[:line]} parse error: #{er}"
369384
end
370385
$stdout.write "F".colorize(:red)
386+
$stderr.puts $!.backtrace.join("\n") if verbose
371387
next
372388
end
373389
when 'nq'
374390
begin
375391
reader_errors = []
376-
RDF::Repository.new << RDF::NQuads::Reader.new(content, validate: true, logger: reader_errors)
392+
RDF::Repository.new << RDF::NQuads::Reader.new(content, logger: reader_errors, **options)
377393
rescue
378394
reader_errors.each do |er|
379395
errors << "Example #{ex[:number]} at line #{ex[:line]} parse error: #{er}"
380396
end
381397
$stdout.write "F".colorize(:red)
398+
$stderr.puts $!.backtrace.join("\n") if verbose
382399
next
383400
end
384401
end
@@ -389,17 +406,6 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
389406
content.define_singleton_method(:content_type) {ex[:content_type]} if ex[:content_type]
390407
end
391408

392-
options = ex[:options].to_s.split(',').inject({}) do |memo, pair|
393-
k, v = pair.split('=')
394-
v = case v
395-
when 'true' then true
396-
when 'false' then false
397-
else v
398-
end
399-
memo.merge(k.to_sym => v)
400-
end
401-
options[:validate] = true
402-
403409
# Set API to use
404410
method = case
405411
when ex[:compact] then :compact
@@ -549,22 +555,26 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
549555
result = case method
550556
when nil then nil
551557
when :fromRdf
552-
args[0] = RDF::Reader.for(file_extension: ext).new(args[0])
553-
JSON::LD::API.fromRdf(*args)
558+
args[0] = RDF::Reader.for(file_extension: ext).new(args[0], **options)
559+
opts = args.last.is_a?(Hash) ? args.pop : {}
560+
JSON::LD::API.fromRdf(*args, **opts)
554561
when :toRdf
555-
RDF::Dataset.new statements: JSON::LD::API.toRdf(*args)
562+
opts = args.last.is_a?(Hash) ? args.pop : {}
563+
RDF::Repository.new << JSON::LD::API.toRdf(*args, **opts)
556564
else
557-
JSON::LD::API.method(method).call(*args)
565+
opts = args.last.is_a?(Hash) ? args.pop : {}
566+
JSON::LD::API.method(method).call(*args, **opts)
558567
end
559568
rescue
560569
errors << "Example #{ex[:number]} at line #{ex[:line]} parse error generating result: #{$!}"
561570
$stdout.write "F".colorize(:red)
571+
$stderr.puts $!.backtrace.join("\n") if verbose
562572
next
563573
end
564574

565575
if verbose
566-
if result.is_a?(RDF::Dataset)
567-
$stderr.puts "result:\n" + result.to_trig
576+
if result.is_a?(RDF::Enumerable)
577+
$stderr.puts "result:\n" + result.to_nquads
568578
else
569579
$stderr.puts "result:\n" + result.to_json(JSON::LD::JSON_STATE)
570580
end
@@ -575,24 +585,26 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
575585
# Compare to expected to result
576586
case ex[:ext]
577587
when 'ttl', 'trig', 'nq', 'html'
578-
reader = RDF::Reader.for(file_extension: ex[:ext]).new(content)
579-
expected = RDF::Dataset.new(statements: reader)
580-
$stderr.puts "expected:\n" + expected.to_trig if verbose
588+
reader = RDF::Reader.for(file_extension: ex[:ext]).new(content, **options)
589+
expected = RDF::Repository.new << reader
590+
$stderr.puts "expected:\n" + expected.to_nquads if verbose
581591
when 'table'
582592
expected = begin
583593
table_to_dataset(content.xpath('/html/body/table'))
584594
rescue
585595
errors << "Example #{ex[:number]} at line #{ex[:line]} raised error reading table: #{$!}"
586-
RDF::Dataset.new
596+
$stderr.puts $!.backtrace.join("\n") if verbose
597+
RDF::Repository.new
587598
end
588599

589600
if verbose
590-
$stderr.puts "expected:\n" + expected.to_trig
601+
$stderr.puts "expected:\n" + expected.to_nquads
591602
$stderr.puts "result table:\n" + begin
592603
dataset_to_table(result)
593604
rescue
594605
errors << "Example #{ex[:number]} at line #{ex[:line]} raised error turning into table: #{$!}"
595606
""
607+
$stderr.puts $!.backtrace.join("\n") if verbose
596608
end
597609
end
598610
else
@@ -601,14 +613,8 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
601613
end
602614

603615
# Perform appropriate comparsion
604-
if expected.is_a?(RDF::Dataset)
605-
expected_norm = RDF::Normalize.new(expected).map(&:to_nquads)
606-
result_norm = RDF::Normalize.new(result).map(&:to_nquads)
607-
if expected_norm.sort != result_norm.sort
608-
if verbose
609-
$stderr.puts "expected_norm:\n" + expected_norm.sort.join("")
610-
$stderr.puts "result_norm:\n" + result_norm.sort.join("")
611-
end
616+
if expected.is_a?(RDF::Enumerable)
617+
if !expected.isomorphic_with?(result)
612618
errors << "Example #{ex[:number]} at line #{ex[:line]} not isomorphic with #{examples[ex[:result_for]][:number]}"
613619
$stdout.write "F".colorize(:red)
614620
next
@@ -637,6 +643,7 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
637643
rescue
638644
errors << "Example #{ex[:number]} at line #{ex[:line]} parse error comparing result: #{$!}"
639645
$stdout.write "F".colorize(:red)
646+
$stderr.puts $!.backtrace.join("\n") if verbose
640647
next
641648
end
642649

0 commit comments

Comments
 (0)