rng 0.1.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +63 -0
- data/.github/workflows/release.yml +8 -3
- data/.gitignore +11 -0
- data/.rubocop.yml +11 -6
- data/.rubocop_todo.yml +270 -0
- data/CHANGELOG.md +317 -0
- data/CLAUDE.md +139 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/Gemfile +11 -10
- data/README.adoc +1929 -0
- data/Rakefile +11 -3
- data/docs/Gemfile +8 -0
- data/docs/_config.yml +23 -0
- data/docs/getting-started/index.adoc +75 -0
- data/docs/guides/error-handling.adoc +137 -0
- data/docs/guides/external-references.adoc +128 -0
- data/docs/guides/index.adoc +24 -0
- data/docs/guides/parsing-rnc.adoc +141 -0
- data/docs/guides/parsing-rng-xml.adoc +81 -0
- data/docs/guides/rng-to-rnc.adoc +101 -0
- data/docs/guides/validation.adoc +85 -0
- data/docs/index.adoc +52 -0
- data/docs/reference/api.adoc +126 -0
- data/docs/reference/cli.adoc +182 -0
- data/docs/understanding/architecture.adoc +58 -0
- data/docs/understanding/rng-vs-rnc.adoc +118 -0
- data/exe/rng +5 -0
- data/lib/rng/any_name.rb +28 -0
- data/lib/rng/attribute.rb +61 -5
- data/lib/rng/choice.rb +60 -0
- data/lib/rng/cli.rb +607 -0
- data/lib/rng/data.rb +32 -0
- data/lib/rng/datatype_declaration.rb +26 -0
- data/lib/rng/define.rb +56 -5
- data/lib/rng/div.rb +36 -0
- data/lib/rng/documentation.rb +9 -0
- data/lib/rng/element.rb +66 -18
- data/lib/rng/empty.rb +23 -0
- data/lib/rng/except.rb +62 -0
- data/lib/rng/external_ref.rb +28 -0
- data/lib/rng/external_ref_resolver.rb +582 -0
- data/lib/rng/foreign_attribute.rb +26 -0
- data/lib/rng/foreign_element.rb +33 -0
- data/lib/rng/grammar.rb +38 -0
- data/lib/rng/group.rb +62 -0
- data/lib/rng/include.rb +23 -0
- data/lib/rng/include_processor.rb +461 -0
- data/lib/rng/interleave.rb +58 -0
- data/lib/rng/list.rb +56 -0
- data/lib/rng/mixed.rb +58 -0
- data/lib/rng/name.rb +28 -0
- data/lib/rng/namespace_declaration.rb +47 -0
- data/lib/rng/namespaces.rb +15 -0
- data/lib/rng/not_allowed.rb +23 -0
- data/lib/rng/ns_name.rb +31 -0
- data/lib/rng/one_or_more.rb +58 -0
- data/lib/rng/optional.rb +58 -0
- data/lib/rng/param.rb +30 -0
- data/lib/rng/parent_ref.rb +28 -0
- data/lib/rng/parse_rnc.rb +26 -0
- data/lib/rng/parse_tree_processor.rb +695 -0
- data/lib/rng/pattern.rb +24 -0
- data/lib/rng/ref.rb +28 -0
- data/lib/rng/rnc_builder.rb +927 -0
- data/lib/rng/rnc_parser.rb +672 -115
- data/lib/rng/rnc_to_rng_converter.rb +1408 -0
- data/lib/rng/schema_preamble.rb +73 -0
- data/lib/rng/schema_validator.rb +1622 -0
- data/lib/rng/start.rb +57 -6
- data/lib/rng/test_suite_parser.rb +168 -0
- data/lib/rng/text.rb +29 -0
- data/lib/rng/to_rnc.rb +24 -0
- data/lib/rng/value.rb +28 -0
- data/lib/rng/version.rb +1 -1
- data/lib/rng/zero_or_more.rb +58 -0
- data/lib/rng.rb +80 -5
- data/rng.gemspec +19 -19
- data/scripts/extract_spectest_resources.rb +96 -0
- data/spec/fixtures/compacttest.xml +2511 -0
- data/spec/fixtures/external/circular_a.rng +7 -0
- data/spec/fixtures/external/circular_b.rng +7 -0
- data/spec/fixtures/external/circular_main.rng +7 -0
- data/spec/fixtures/external/external_ref_lib.rng +7 -0
- data/spec/fixtures/external/external_ref_main.rng +7 -0
- data/spec/fixtures/external/include_lib.rng +7 -0
- data/spec/fixtures/external/include_main.rng +3 -0
- data/spec/fixtures/external/nested_chain.rng +6 -0
- data/spec/fixtures/external/nested_leaf.rng +7 -0
- data/spec/fixtures/external/nested_mid.rng +8 -0
- data/spec/fixtures/metanorma/3gpp.rnc +35 -0
- data/spec/fixtures/metanorma/3gpp.rng +105 -0
- data/spec/fixtures/metanorma/basicdoc.rnc +11 -0
- data/spec/fixtures/metanorma/bipm.rnc +148 -0
- data/spec/fixtures/metanorma/bipm.rng +376 -0
- data/spec/fixtures/metanorma/bsi.rnc +104 -0
- data/spec/fixtures/metanorma/bsi.rng +332 -0
- data/spec/fixtures/metanorma/csa.rnc +45 -0
- data/spec/fixtures/metanorma/csa.rng +131 -0
- data/spec/fixtures/metanorma/csd.rnc +43 -0
- data/spec/fixtures/metanorma/csd.rng +132 -0
- data/spec/fixtures/metanorma/gbstandard.rnc +99 -0
- data/spec/fixtures/metanorma/gbstandard.rng +316 -0
- data/spec/fixtures/metanorma/iec.rnc +49 -0
- data/spec/fixtures/metanorma/iec.rng +193 -0
- data/spec/fixtures/metanorma/ietf.rnc +275 -0
- data/spec/fixtures/metanorma/ietf.rng +925 -0
- data/spec/fixtures/metanorma/iho.rnc +58 -0
- data/spec/fixtures/metanorma/iho.rng +179 -0
- data/spec/fixtures/metanorma/isodoc.rnc +873 -0
- data/spec/fixtures/metanorma/isodoc.rng +2704 -0
- data/spec/fixtures/metanorma/isostandard-amd.rnc +43 -0
- data/spec/fixtures/metanorma/isostandard-amd.rng +108 -0
- data/spec/fixtures/metanorma/isostandard.rnc +166 -0
- data/spec/fixtures/metanorma/isostandard.rng +494 -0
- data/spec/fixtures/metanorma/itu.rnc +122 -0
- data/spec/fixtures/metanorma/itu.rng +377 -0
- data/spec/fixtures/metanorma/m3d.rnc +41 -0
- data/spec/fixtures/metanorma/m3d.rng +122 -0
- data/spec/fixtures/metanorma/mpfd.rnc +36 -0
- data/spec/fixtures/metanorma/mpfd.rng +95 -0
- data/spec/fixtures/metanorma/nist.rnc +77 -0
- data/spec/fixtures/metanorma/nist.rng +216 -0
- data/spec/fixtures/metanorma/ogc.rnc +51 -0
- data/spec/fixtures/metanorma/ogc.rng +151 -0
- data/spec/fixtures/metanorma/reqt.rnc +6 -0
- data/spec/fixtures/metanorma/rsd.rnc +36 -0
- data/spec/fixtures/metanorma/rsd.rng +95 -0
- data/spec/fixtures/metanorma/un.rnc +103 -0
- data/spec/fixtures/metanorma/un.rng +367 -0
- data/spec/fixtures/rnc/address_book.rnc +10 -0
- data/spec/fixtures/rnc/base.rnc +4 -0
- data/spec/fixtures/rnc/complex_example.rnc +61 -0
- data/spec/fixtures/rnc/grammar_with_trailing.rnc +8 -0
- data/spec/fixtures/rnc/main_include_trailing.rnc +3 -0
- data/spec/fixtures/rnc/main_with_include.rnc +5 -0
- data/spec/fixtures/rnc/test_augment.rnc +10 -0
- data/spec/fixtures/rnc/test_isodoc_simple.rnc +9 -0
- data/spec/fixtures/rnc/top_level_include.rnc +8 -0
- data/spec/fixtures/rng/address_book.rng +20 -0
- data/spec/fixtures/rng/relaxng.rng +335 -0
- data/spec/fixtures/rng/testSuite.rng +163 -0
- data/spec/fixtures/spectest.xml +6845 -0
- data/spec/fixtures/spectest_external/case_10_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_10_4.7/y +7 -0
- data/spec/fixtures/spectest_external/case_11_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_12_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_13_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_13_4.7/y +3 -0
- data/spec/fixtures/spectest_external/case_14_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_15_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_16_4.7/x +5 -0
- data/spec/fixtures/spectest_external/case_17_4.7/x +5 -0
- data/spec/fixtures/spectest_external/case_18_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_19_4.7/level1.rng +9 -0
- data/spec/fixtures/spectest_external/case_19_4.7/level2.rng +7 -0
- data/spec/fixtures/spectest_external/case_1_4.5/sub1/x +3 -0
- data/spec/fixtures/spectest_external/case_1_4.5/sub3/x +3 -0
- data/spec/fixtures/spectest_external/case_1_4.5/x +3 -0
- data/spec/fixtures/spectest_external/case_20_4.6/x +3 -0
- data/spec/fixtures/spectest_external/case_2_4.5/x +3 -0
- data/spec/fixtures/spectest_external/case_3_4.6/x +3 -0
- data/spec/fixtures/spectest_external/case_4_4.6/x +3 -0
- data/spec/fixtures/spectest_external/case_5_4.6/x +1 -0
- data/spec/fixtures/spectest_external/case_6_4.6/x +5 -0
- data/spec/fixtures/spectest_external/case_7_4.6/x +1 -0
- data/spec/fixtures/spectest_external/case_7_4.6/y +1 -0
- data/spec/fixtures/spectest_external/case_8_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_9_4.7/x +7 -0
- data/spec/fixtures/spectest_external/resources.json +149 -0
- data/spec/rng/advanced_rnc_spec.rb +101 -0
- data/spec/rng/compacttest_spec.rb +197 -0
- data/spec/rng/datatype_declaration_spec.rb +28 -0
- data/spec/rng/div_spec.rb +207 -0
- data/spec/rng/external_ref_resolver_spec.rb +122 -0
- data/spec/rng/metanorma_conversion_spec.rb +159 -0
- data/spec/rng/namespace_declaration_spec.rb +60 -0
- data/spec/rng/namespace_support_spec.rb +199 -0
- data/spec/rng/rnc_parser_spec.rb +501 -23
- data/spec/rng/rnc_roundtrip_spec.rb +135 -0
- data/spec/rng/rng_generation_spec.rb +288 -0
- data/spec/rng/roundtrip_spec.rb +342 -0
- data/spec/rng/schema_preamble_spec.rb +145 -0
- data/spec/rng/schema_spec.rb +125 -172
- data/spec/rng/spectest_spec.rb +273 -0
- data/spec/rng_spec.rb +2 -2
- data/spec/spec_helper.rb +7 -9
- metadata +188 -8
- data/lib/rng/builder.rb +0 -158
- data/lib/rng/rng_parser.rb +0 -107
- data/lib/rng/schema.rb +0 -18
- data/spec/rng/rng_parser_spec.rb +0 -102
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"></externalRef>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="y"></externalRef>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"></externalRef>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"1": {
|
|
3
|
+
"section": "4.5",
|
|
4
|
+
"documentation": "",
|
|
5
|
+
"resources": [
|
|
6
|
+
"sub1/x",
|
|
7
|
+
"sub1/x",
|
|
8
|
+
"sub3/x",
|
|
9
|
+
"x"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"2": {
|
|
13
|
+
"section": "4.5",
|
|
14
|
+
"documentation": "",
|
|
15
|
+
"resources": [
|
|
16
|
+
"x"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"3": {
|
|
20
|
+
"section": "4.6",
|
|
21
|
+
"documentation": "",
|
|
22
|
+
"resources": [
|
|
23
|
+
"x"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"4": {
|
|
27
|
+
"section": "4.6",
|
|
28
|
+
"documentation": "",
|
|
29
|
+
"resources": [
|
|
30
|
+
"x"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"5": {
|
|
34
|
+
"section": "4.6",
|
|
35
|
+
"documentation": "",
|
|
36
|
+
"resources": [
|
|
37
|
+
"x"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"6": {
|
|
41
|
+
"section": "4.6",
|
|
42
|
+
"documentation": "",
|
|
43
|
+
"resources": [
|
|
44
|
+
"x"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"7": {
|
|
48
|
+
"section": "4.6",
|
|
49
|
+
"documentation": "",
|
|
50
|
+
"resources": [
|
|
51
|
+
"x",
|
|
52
|
+
"y"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"8": {
|
|
56
|
+
"section": "4.7",
|
|
57
|
+
"documentation": "",
|
|
58
|
+
"resources": [
|
|
59
|
+
"x"
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"9": {
|
|
63
|
+
"section": "4.7",
|
|
64
|
+
"documentation": "",
|
|
65
|
+
"resources": [
|
|
66
|
+
"x"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"10": {
|
|
70
|
+
"section": "4.7",
|
|
71
|
+
"documentation": "",
|
|
72
|
+
"resources": [
|
|
73
|
+
"x",
|
|
74
|
+
"y"
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
"11": {
|
|
78
|
+
"section": "4.7",
|
|
79
|
+
"documentation": "",
|
|
80
|
+
"resources": [
|
|
81
|
+
"x"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"12": {
|
|
85
|
+
"section": "4.7",
|
|
86
|
+
"documentation": "",
|
|
87
|
+
"resources": [
|
|
88
|
+
"x"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"13": {
|
|
92
|
+
"section": "4.7",
|
|
93
|
+
"documentation": "",
|
|
94
|
+
"resources": [
|
|
95
|
+
"x",
|
|
96
|
+
"y"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"14": {
|
|
100
|
+
"section": "4.7",
|
|
101
|
+
"documentation": "",
|
|
102
|
+
"resources": [
|
|
103
|
+
"x"
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
"15": {
|
|
107
|
+
"section": "4.7",
|
|
108
|
+
"documentation": "",
|
|
109
|
+
"resources": [
|
|
110
|
+
"x"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"16": {
|
|
114
|
+
"section": "4.7",
|
|
115
|
+
"documentation": "",
|
|
116
|
+
"resources": [
|
|
117
|
+
"x"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"17": {
|
|
121
|
+
"section": "4.7",
|
|
122
|
+
"documentation": "",
|
|
123
|
+
"resources": [
|
|
124
|
+
"x"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"18": {
|
|
128
|
+
"section": "4.7",
|
|
129
|
+
"documentation": "",
|
|
130
|
+
"resources": [
|
|
131
|
+
"x"
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
"19": {
|
|
135
|
+
"section": "4.7",
|
|
136
|
+
"documentation": "",
|
|
137
|
+
"resources": [
|
|
138
|
+
"level1.rng",
|
|
139
|
+
"level2.rng"
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
"20": {
|
|
143
|
+
"section": "4.6",
|
|
144
|
+
"documentation": "",
|
|
145
|
+
"resources": [
|
|
146
|
+
"x"
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'rng'
|
|
5
|
+
|
|
6
|
+
RSpec.describe 'Advanced RNC features' do
|
|
7
|
+
describe 'Name wildcards' do
|
|
8
|
+
context 'anyName in attributes' do
|
|
9
|
+
it 'parses wildcard attribute without except' do
|
|
10
|
+
rnc = 'start = element foo { attribute * { text } }'
|
|
11
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'parses wildcard attribute with except clause' do
|
|
15
|
+
rnc = 'start = element foo { attribute * - bar { text } }'
|
|
16
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'anyName in elements' do
|
|
21
|
+
it 'parses wildcard element without except' do
|
|
22
|
+
rnc = 'start = element * { text }'
|
|
23
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'nsName wildcards' do
|
|
28
|
+
it 'parses namespace wildcard in attributes' do
|
|
29
|
+
rnc = 'start = element foo { attribute xml:* { text } }'
|
|
30
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'parses namespace wildcard with except' do
|
|
34
|
+
rnc = 'start = element foo { attribute ns:* - ns:bar { text } }'
|
|
35
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe 'Augmentation operators' do
|
|
41
|
+
it 'parses choice augmentation (|=)' do
|
|
42
|
+
rnc = <<~RNC
|
|
43
|
+
start = foo
|
|
44
|
+
foo = bar
|
|
45
|
+
foo |= baz
|
|
46
|
+
RNC
|
|
47
|
+
schema = Rng.parse_rnc(rnc)
|
|
48
|
+
|
|
49
|
+
# Should have two define elements with combine="choice"
|
|
50
|
+
defines = schema.define.select { |d| d.name == 'foo' }
|
|
51
|
+
expect(defines.length).to eq(2)
|
|
52
|
+
expect(defines[1].combine).to eq('choice')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'parses interleave augmentation (&=)' do
|
|
56
|
+
rnc = <<~RNC
|
|
57
|
+
start = foo
|
|
58
|
+
foo = bar
|
|
59
|
+
foo &= baz
|
|
60
|
+
RNC
|
|
61
|
+
schema = Rng.parse_rnc(rnc)
|
|
62
|
+
|
|
63
|
+
defines = schema.define.select { |d| d.name == 'foo' }
|
|
64
|
+
expect(defines.length).to eq(2)
|
|
65
|
+
expect(defines[1].combine).to eq('interleave')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe 'List patterns' do
|
|
70
|
+
it 'parses simple list pattern' do
|
|
71
|
+
rnc = 'start = element foo { list { xsd:token+ } }'
|
|
72
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'parses list with text' do
|
|
76
|
+
rnc = 'start = element foo { list { text } }'
|
|
77
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe 'Parent references' do
|
|
82
|
+
it 'parses parent reference' do
|
|
83
|
+
rnc = 'start = parent start'
|
|
84
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe 'External references' do
|
|
89
|
+
it 'parses external reference' do
|
|
90
|
+
rnc = 'start = external "common.rng"'
|
|
91
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe 'notAllowed pattern' do
|
|
96
|
+
it 'parses notAllowed' do
|
|
97
|
+
rnc = 'start = element foo { notAllowed }'
|
|
98
|
+
expect { Rng.parse_rnc(rnc) }.not_to raise_error
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'rng/test_suite_parser'
|
|
5
|
+
require 'tmpdir'
|
|
6
|
+
|
|
7
|
+
RSpec.describe 'Official RELAX NG Compact Test Suite' do
|
|
8
|
+
let(:test_suite_path) do
|
|
9
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
10
|
+
end
|
|
11
|
+
let(:test_suite) { Rng::TestSuiteParser.load(test_suite_path) }
|
|
12
|
+
|
|
13
|
+
describe 'Test Suite Loading' do
|
|
14
|
+
it 'loads the test suite successfully' do
|
|
15
|
+
expect(test_suite).to be_a(Rng::TestSuiteParser)
|
|
16
|
+
expect(test_suite.test_cases).not_to be_empty
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'provides test case categorization' do
|
|
20
|
+
expect(test_suite.test_cases).not_to be_empty
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe 'Valid RNC Parsing' do
|
|
25
|
+
let(:valid_cases) { test_suite.valid_rnc_cases }
|
|
26
|
+
|
|
27
|
+
context 'without external resources' do
|
|
28
|
+
let(:cases_without_resources) do
|
|
29
|
+
valid_cases.reject(&:has_resources?)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'has test cases to validate' do
|
|
33
|
+
expect(cases_without_resources).not_to be_empty
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
0
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe 'Valid RNC Schema Parsing (Individual Tests)' do
|
|
41
|
+
let(:test_suite_instance) { Rng::TestSuiteParser.load(test_suite_path) }
|
|
42
|
+
|
|
43
|
+
before(:all) do
|
|
44
|
+
@suite = Rng::TestSuiteParser.load(
|
|
45
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
46
|
+
)
|
|
47
|
+
@results = {
|
|
48
|
+
passed: 0,
|
|
49
|
+
failed: 0,
|
|
50
|
+
skipped: 0,
|
|
51
|
+
errors: []
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test_suite_parser = Rng::TestSuiteParser.load(
|
|
56
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
test_suite_parser.valid_rnc_cases.each_with_index do |test_case, _idx|
|
|
60
|
+
next if test_case.has_resources? # Skip resource-based tests for now
|
|
61
|
+
|
|
62
|
+
it "parses test case ##{test_case.id} (#{test_case.description})" do
|
|
63
|
+
rnc_content = test_case.compact_correct
|
|
64
|
+
|
|
65
|
+
begin
|
|
66
|
+
grammar = Rng.parse_rnc(rnc_content)
|
|
67
|
+
|
|
68
|
+
expect(grammar).to be_a(Rng::Grammar)
|
|
69
|
+
@results[:passed] += 1
|
|
70
|
+
rescue StandardError => e
|
|
71
|
+
@results[:failed] += 1
|
|
72
|
+
@results[:errors] << {
|
|
73
|
+
id: test_case.id,
|
|
74
|
+
message: e.message,
|
|
75
|
+
rnc: rnc_content[0..200]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Re-raise to fail the test
|
|
79
|
+
raise e
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe 'Invalid RNC Rejection (Individual Tests)' do
|
|
86
|
+
before(:all) do
|
|
87
|
+
@suite = Rng::TestSuiteParser.load(
|
|
88
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
89
|
+
)
|
|
90
|
+
@results = {
|
|
91
|
+
correctly_rejected: 0,
|
|
92
|
+
incorrectly_accepted: 0,
|
|
93
|
+
errors: []
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
test_suite_parser = Rng::TestSuiteParser.load(
|
|
98
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
test_suite_parser.invalid_rnc_cases.each do |test_case|
|
|
102
|
+
it "rejects test case ##{test_case.id} (should fail parsing)" do
|
|
103
|
+
rnc_content = test_case.compact_incorrect
|
|
104
|
+
|
|
105
|
+
expect do
|
|
106
|
+
Rng.parse_rnc(rnc_content)
|
|
107
|
+
end.to raise_error(StandardError)
|
|
108
|
+
|
|
109
|
+
@results[:correctly_rejected] += 1
|
|
110
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
|
111
|
+
@results[:incorrectly_accepted] += 1
|
|
112
|
+
@results[:errors] << {
|
|
113
|
+
id: test_case.id,
|
|
114
|
+
rnc: rnc_content
|
|
115
|
+
}
|
|
116
|
+
raise
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe 'RNC ↔ RNG Round-Trip Conversion' do
|
|
122
|
+
let(:roundtrip_cases) do
|
|
123
|
+
test_suite.roundtrip_cases.reject(&:has_resources?)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
before(:all) do
|
|
127
|
+
@suite = Rng::TestSuiteParser.load(
|
|
128
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
129
|
+
)
|
|
130
|
+
@results = {
|
|
131
|
+
passed: 0,
|
|
132
|
+
failed: 0,
|
|
133
|
+
parse_errors: 0,
|
|
134
|
+
errors: []
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
test_suite_parser = Rng::TestSuiteParser.load(
|
|
139
|
+
File.expand_path('../fixtures/compacttest.xml', __dir__)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
test_suite_parser.roundtrip_cases
|
|
143
|
+
.reject(&:has_resources?)
|
|
144
|
+
.each do |test_case|
|
|
145
|
+
it "round-trips test case ##{test_case.id}" do
|
|
146
|
+
rnc_content = test_case.compact_correct
|
|
147
|
+
expected_rng = test_case.xml_correct
|
|
148
|
+
|
|
149
|
+
begin
|
|
150
|
+
# Parse RNC to Grammar
|
|
151
|
+
grammar = Rng.parse_rnc(rnc_content)
|
|
152
|
+
|
|
153
|
+
# Generate RNG XML
|
|
154
|
+
generated_rng = grammar.to_xml
|
|
155
|
+
|
|
156
|
+
# Parse both RNG versions to Grammar for comparison
|
|
157
|
+
# Use Grammar.from_xml to skip schema validation - test suite schemas
|
|
158
|
+
# may have non-standard root elements (e.g., bare value patterns)
|
|
159
|
+
expected_grammar = Rng::Grammar.from_xml(expected_rng)
|
|
160
|
+
generated_grammar = Rng::Grammar.from_xml(generated_rng)
|
|
161
|
+
|
|
162
|
+
# Compare using structural equivalence
|
|
163
|
+
# For now, just check both parse successfully
|
|
164
|
+
expect(generated_grammar).to be_a(Rng::Grammar)
|
|
165
|
+
expect(expected_grammar).to be_a(Rng::Grammar)
|
|
166
|
+
|
|
167
|
+
@results[:passed] += 1
|
|
168
|
+
rescue Parslet::ParseFailed, StandardError => e
|
|
169
|
+
if e.is_a?(Parslet::ParseFailed) || e.message.include?('parse')
|
|
170
|
+
@results[:parse_errors] += 1
|
|
171
|
+
else
|
|
172
|
+
@results[:failed] += 1
|
|
173
|
+
@results[:errors] << {
|
|
174
|
+
id: test_case.id,
|
|
175
|
+
message: e.message
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Don't fail the test for parse errors, only conversion errors
|
|
180
|
+
raise e unless e.is_a?(Parslet::ParseFailed) || e.message.include?('parse')
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
describe 'Resource-Based Tests' do
|
|
187
|
+
let(:resource_cases) { test_suite.resource_cases }
|
|
188
|
+
|
|
189
|
+
it 'identifies resource-based test cases' do
|
|
190
|
+
expect(resource_cases).not_to be_empty
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'skips resource-based tests (not yet implemented)' do
|
|
194
|
+
skip 'External resource handling not yet implemented'
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require_relative '../../lib/rng/datatype_declaration'
|
|
5
|
+
|
|
6
|
+
RSpec.describe Rng::DatatypeDeclaration do
|
|
7
|
+
describe '#initialize' do
|
|
8
|
+
it 'creates a datatype declaration with prefix and URI' do
|
|
9
|
+
decl = described_class.new(
|
|
10
|
+
prefix: 'xsd',
|
|
11
|
+
uri: 'http://www.w3.org/2001/XMLSchema-datatypes'
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
expect(decl.prefix).to eq('xsd')
|
|
15
|
+
expect(decl.uri).to eq('http://www.w3.org/2001/XMLSchema-datatypes')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'creates a datatype declaration with custom prefix' do
|
|
19
|
+
decl = described_class.new(
|
|
20
|
+
prefix: 'custom',
|
|
21
|
+
uri: 'http://example.com/datatypes'
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
expect(decl.prefix).to eq('custom')
|
|
25
|
+
expect(decl.uri).to eq('http://example.com/datatypes')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|