Skip to content

Commit c7811ef

Browse files
committed
More tests, and validate example in README.
1 parent e8a1e8d commit c7811ef

File tree

8 files changed

+124
-51
lines changed

8 files changed

+124
-51
lines changed

.yardopts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--title "ShEx: Shape Expression language for Ruby"
2+
--output-dir doc/yard
3+
--protected
4+
--no-private
5+
--hide-void-return
6+
--markup markdown
7+
--readme README.md
8+
-
9+
AUTHORS
10+
VERSION
11+
LICENSE
12+
etc/shex.html
13+
etc/earl.ttl
14+
etc/earl.html

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ The ShEx gem implements a [ShEx][ShExSpec] Shape Expression engine.
5252
<http://rubydoc.info/github/ruby-rdf/shex>
5353

5454

55+
## Implementation Notes
56+
The ShExC parser uses the [EBNF][] gem to generate first, follow and branch tables, and uses the `Parser` and `Lexer` modules to implement the ShExC parser.
57+
58+
The parser takes branch and follow tables generated from the [ShEx Grammar](file.shex.html) described in the [specification][ShExSpec]. Branch and Follow tables are specified in the generated {ShEx::Meta}.
59+
5560
## Dependencies
5661

5762
* [Ruby](http://ruby-lang.org/) (>= 2.0)
@@ -115,4 +120,5 @@ see <http://unlicense.org/> or the accompanying {file:LICENSE} file.
115120

116121
[ShExSpec]: https://shexspec.github.io/spec/
117122
[RDF]: http://www.w3.org/RDF/
118-
[RDF.rb]: http://rubydoc.info/github/ruby-rdf/rdf
123+
[RDF.rb]: http://rubydoc.info/github/ruby-rdf/rdf
124+
[EBNF]: http://rubygems.org/gems/ebnf

etc/doap.shex

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
PREFIX doap: <http://usefulinc.com/ns/doap#>
22
PREFIX dc: <http://purl.org/dc/terms/>
33
<TestShape> EXTRA a {
4-
a doap:Project;
5-
(doap:name;doap:description|dc:title;dc:description)+;
6-
doap:category*;
7-
doap:developer IRI;
8-
doap:implements [<https://shexspec.github.io/spec/>]
4+
a [doap:Project];
5+
6+
# May have either or both of doap:name/doap:description or dc:title/dc:description
7+
( doap:name Literal;
8+
doap:description Literal
9+
| dc:title Literal;
10+
dc:description Literal)+;
11+
12+
# Good idea to use a category for what the project relates to
13+
doap:category IRI*;
14+
15+
# There must be at least one developer
16+
doap:developer IRI+;
17+
18+
# For our purposes, it MUST implement the ShEx specification.
19+
doap:implements [<https://shexspec.github.io/spec/>]
920
}

lib/shex/algebra/one_of.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def matches(t)
1919
status ""
2020
while num_iters < max
2121
matched_something = operands.select {|o| o.is_a?(TripleExpression)}.any? do |op|
22+
require 'byebug'; byebug
2223
begin
2324
matched = op.matches(statements)
2425
results += matched

lib/shex/algebra/operator.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ def structure_error(message, **opts)
108108

109109
def status(message, &block)
110110
log_info(self.class.const_get(:NAME), message, depth: options.fetch(:depth, 0), &block)
111+
true
111112
end
112113

113114
##

spec/data/_all.sse

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
("S5" <http://all.example/S5>)
2222
("xsd" <http://www.w3.org/2001/XMLSchema#>)
2323
("" <http://all.example/>)) )
24-
(semact (<http://all.example/act1> " START1 "))
25-
(semact (<http://all.example/act2> " START2 "))
26-
(start (shape (shapeRef <http://all.example/S3>)))
24+
(semact <http://all.example/act1> " START1 ")
25+
(semact <http://all.example/act2> " START2 ")
26+
(start (shapeRef <http://all.example/S3>))
2727
(shapes
2828
(
2929
(<http://all.example/S1>
@@ -47,7 +47,7 @@
4747
(value <http://a.example/a1>)
4848
(value
4949
(stemRange <http://all.example/>
50-
(exclusions (stem (<http://all.example/a>)) <http://all.example/b>)) ))
50+
(exclusions (stem <http://all.example/a>) <http://all.example/b>)) ))
5151
(nodeConstraint datatype <http://all.example/IRI>)) )
5252
(<http://all.example/S3>
5353
(shape
@@ -83,54 +83,55 @@
8383
(oneOf
8484
(eachOf
8585
(tripleConstraint inverse <http://all.example/extra>
86-
(tripleConstraint <http://all.example/p1>
87-
(nodeConstraint
88-
(value "STRING_LITERAL2")
89-
(value "STRING_LITERAL2"@en-uk)
90-
(value <http://all.example/>)
91-
(value <http://all.example/val1>)
92-
(value <http://all.example/>)
93-
(value
94-
<scheme:!$%25&amp;'()*+,-./0123456789:/@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~?#>
95-
)
96-
(value <http://a.example/p1>)
97-
(value 0.0)
98-
(value 0e0)
99-
(value 0E0)
100-
(value false)
101-
(value 0)
102-
(value "ab"^^<http://all.example/bloodType>)
103-
(value "o+"^^<http://all.example/bloodType>)
104-
(value " !\"\#$%&():;<=>?@[]^_`{|}~")
105-
(value "\t\v\f\x0E&([]\x7F")
106-
(value
107-
"\u{80}\u{7ff}\u{800}\u{fff}\u{1000}\u{cfff}\u{d000}\u{d7ff}\u{e000}\u{fffd}\u{10000}\u{3fffd}\u{40000}\u{ffffd}\u{100000}\u{10fffd}"
108-
)
109-
(value "\"\\")
110-
(value
111-
"\u{1d7d8}\u{1d7d9}\u{1d7da}\u{1d7db}\u{1d7dc}\u{1d7dd}\u{1d7de}\u{1d7df}\u{1d7e0}\u{1d7e1}"
112-
)
113-
(value "STRING_LITERAL_LONG2"@en-uk)) )
86+
(shape
87+
(tripleConstraint <http://all.example/p1>
88+
(nodeConstraint
89+
(value "STRING_LITERAL2")
90+
(value "STRING_LITERAL2"@en-uk)
91+
(value <http://all.example/>)
92+
(value <http://all.example/val1>)
93+
(value <http://all.example/>)
94+
(value
95+
<scheme:!$%25&amp;'()*+,-./0123456789:/@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~?#>
96+
)
97+
(value <http://a.example/p1>)
98+
(value 0.0)
99+
(value 0e0)
100+
(value 0E0)
101+
(value false)
102+
(value 0)
103+
(value "ab"^^<http://all.example/bloodType>)
104+
(value "o+"^^<http://all.example/bloodType>)
105+
(value " !\"\#$%&():;<=>?@[]^_`{|}~")
106+
(value "\t\v\f\x0E&([]\x7F")
107+
(value
108+
"\u{80}\u{7ff}\u{800}\u{fff}\u{1000}\u{cfff}\u{d000}\u{d7ff}\u{e000}\u{fffd}\u{10000}\u{3fffd}\u{40000}\u{ffffd}\u{100000}\u{10fffd}"
109+
)
110+
(value "\"\\")
111+
(value
112+
"\u{1d7d8}\u{1d7d9}\u{1d7da}\u{1d7db}\u{1d7dc}\u{1d7dd}\u{1d7de}\u{1d7df}\u{1d7e0}\u{1d7e1}"
113+
)
114+
(value "STRING_LITERAL_LONG2"@en-uk)) ))
114115
(min 2)
115116
(max 3)
116-
(semact (<http://all.example/act1> " code1 ")))
117+
(semact <http://all.example/act1> " code1 "))
117118
(tripleConstraint <http://all.example/iri>
118119
(nodeConstraint literal)
119120
(min 1)
120121
(max "*")
121-
(semact (<http://all.example/act1> " %{printf(\"品川\\n\");%} "))
122+
(semact <http://all.example/act1> " %{printf(\"\u{54c1}\u{5ddd}\\n\");%} ")
122123
(annotation <http://a.example/annot1> <http://a.example/IRIREF>)
123124
(annotation <http://a.example/annot2> "STRING_LITERAL2")
124125
(annotation <http://a.example/annot3> 3)) )
125126
(eachOf
126127
(tripleConstraint inverse <http://all.example/bnode>
127128
(min 1)
128129
(max "*")
129-
(semact (<http://all.example/act1> " code1 ")))
130+
(semact <http://all.example/act1> " code1 "))
130131
(tripleConstraint inverse <http://all.example/literal>
131132
(min 1)
132133
(max "*")
133-
(semact (<http://all.example/act1> " code1 "))) ))
134+
(semact <http://all.example/act1> " code1 ")) ))
134135
(tripleConstraint <http://all.example/nonliteral>
135136
(nodeConstraint datatype <http://www.w3.org/2001/XMLSchema#integer>
136137
(mininclusive 5)
@@ -141,13 +142,12 @@
141142
(tripleConstraint <http://all.example/pattern>
142143
(nodeConstraint
143144
(value
144-
(stemRange wildcard (exclusions (stem (<http://all.example/a>)) <http://all.example/b>))) )
145-
(semact (<http://all.example/act1> " code1 "))
146-
(semact (<http://all.example/act2> " code2 "))) )
145+
(stemRange wildcard (exclusions (stem <http://all.example/a>) <http://all.example/b>))) )
146+
(semact <http://all.example/act1> " code1 ")
147+
(semact <http://all.example/act2> " code2 ")) )
147148
(extra <http://all.example/a> <http://all.example/prefix>
148149
<http://all.example/base> )) )
149150
(<http://all.example/S5> (nodeConstraint iri))
150151
(_:a·̀ͯ‿.⁀
151152
(shape (eachOf (inclusion _:a·̀ͯ‿.⁀) (inclusion <http://all.example/S2>)) closed))
152-
(_:AZazÀÖØöø˿ͰͽͿ῿‌‍⁰↏Ⰰ⿯、퟿豈﷏ﷰ�𐀀󯿽 (shape (inclusion _:a·̀ͯ‿.⁀)))) ))
153-
153+
(_:AZazÀÖØöø˿ͰͽͿ῿‌‍⁰↏Ⰰ⿯、퟿豈﷏ﷰ�𐀀󯿽 (shape (inclusion _:a·̀ͯ‿.⁀)))) ))

spec/parser_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -946,13 +946,13 @@
946946
it file do
947947
input = File.read File.expand_path("../shexTest/schemas/#{file}.shex", __FILE__)
948948

949-
case file
950-
when '_all'
951-
pending("All has a self-including shape, which is invalid")
949+
validate = case file
950+
when '_all' then false # Has self-included shape
951+
else true
952952
end
953953

954954
sse = File.read(File.expand_path("../data/#{file}.sse", __FILE__))
955-
expect(input).to generate(sse, validate: true)
955+
expect(input).to generate(sse, validate: validate)
956956
end
957957
end
958958
end

spec/shex_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,45 @@
3131
expect(described_class.execute(input, nil, RDF::URI("http://example/foo"), RDF::URI("http://a.example/S1"))).to be_truthy
3232
end
3333
end
34+
35+
context "README" do
36+
let(:doap_shex) {File.expand_path("../../etc/doap.shex", __FILE__)}
37+
let(:doap_ttl) {File.expand_path("../../etc/doap.ttl", __FILE__)}
38+
let(:doap_subj) {RDF::URI("http://rubygems.org/gems/shex")}
39+
let(:doap_shape) {RDF::URI("TestShape")}
40+
it "parses doap.shex" do
41+
doap_sxp = %{(schema
42+
(prefix (("doap" <http://usefulinc.com/ns/doap#>) ("dc" <http://purl.org/dc/terms/>)))
43+
(shapes
44+
((<TestShape> (shape
45+
(eachOf
46+
(tripleConstraint a (nodeConstraint (value <http://usefulinc.com/ns/doap#Project>)))
47+
(oneOf
48+
(eachOf
49+
(tripleConstraint <http://usefulinc.com/ns/doap#name> (nodeConstraint literal))
50+
(tripleConstraint <http://usefulinc.com/ns/doap#description>
51+
(nodeConstraint literal)) )
52+
(eachOf
53+
(tripleConstraint <http://purl.org/dc/terms/title> (nodeConstraint literal))
54+
(tripleConstraint <http://purl.org/dc/terms/description> (nodeConstraint literal)))
55+
(min 1) (max "*"))
56+
(tripleConstraint <http://usefulinc.com/ns/doap#category>
57+
(nodeConstraint iri)
58+
(min 0) (max "*"))
59+
(tripleConstraint <http://usefulinc.com/ns/doap#developer>
60+
(nodeConstraint iri)
61+
(min 1) (max "*"))
62+
(tripleConstraint <http://usefulinc.com/ns/doap#implements>
63+
(nodeConstraint (value <https://shexspec.github.io/spec/>))) )
64+
(extra a))))))}
65+
expect(File.read(doap_shex)).to generate(doap_sxp)
66+
end
67+
68+
it "validates doap.ttl" do
69+
graph = RDF::Graph.load(doap_ttl)
70+
schema = ShEx.open(doap_shex)
71+
expect(schema).to satisfy(graph, File.read(doap_ttl), doap_subj, doap_shape, logger: RDF::Spec.logger)
72+
end
73+
end
3474
end
3575

0 commit comments

Comments
 (0)