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,273 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'nokogiri'
|
|
5
|
+
require 'tmpdir'
|
|
6
|
+
|
|
7
|
+
# Load the test suite XML file once for all tests
|
|
8
|
+
SPEC_TEST_XML_PATH = 'spec/fixtures/spectest.xml'
|
|
9
|
+
SPECTEST_XML = Nokogiri::XML(File.read(SPEC_TEST_XML_PATH))
|
|
10
|
+
|
|
11
|
+
# Load resources mapping if available
|
|
12
|
+
SPECTEST_RESOURCES_PATH = 'spec/fixtures/spectest_external/resources.json'
|
|
13
|
+
SPECTEST_RESOURCES = File.exist?(SPECTEST_RESOURCES_PATH) ? JSON.parse(File.read(SPECTEST_RESOURCES_PATH)) : {}
|
|
14
|
+
|
|
15
|
+
# Helper to extract resources from a test case element
|
|
16
|
+
def extract_resources_from_test_case(test_case)
|
|
17
|
+
resources = {}
|
|
18
|
+
|
|
19
|
+
# Handle resources in directories
|
|
20
|
+
test_case.xpath('.//dir').each do |dir|
|
|
21
|
+
dir_name = dir['name']
|
|
22
|
+
dir.xpath('.//resource').each do |res|
|
|
23
|
+
resource_name = res['name']
|
|
24
|
+
content = res.inner_html.strip
|
|
25
|
+
resources["#{dir_name}/#{resource_name}"] = content unless content.empty?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Handle resources at root level
|
|
30
|
+
test_case.xpath('./resource').each do |res|
|
|
31
|
+
resource_name = res['name']
|
|
32
|
+
content = res.inner_html.strip
|
|
33
|
+
resources[resource_name] = content unless content.empty?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
resources
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Helper to check if schema has external refs
|
|
40
|
+
def schema_has_external_refs?(schema_xml)
|
|
41
|
+
(schema_xml.include?('<externalRef') && schema_xml.include?('href="')) ||
|
|
42
|
+
(schema_xml.include?('<include') && schema_xml.include?('href="'))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Helper to run a schema test with external ref resolution
|
|
46
|
+
def run_schema_test(schema_xml, resources, expect_error: false)
|
|
47
|
+
if resources.empty? && schema_has_external_refs?(schema_xml)
|
|
48
|
+
return { skipped: true,
|
|
49
|
+
reason: 'no resources for external refs' }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
if schema_has_external_refs?(schema_xml) && !resources.empty?
|
|
53
|
+
# Set up temp directory with resources
|
|
54
|
+
Dir.mktmpdir do |tmpdir|
|
|
55
|
+
# Write resources to temp dir
|
|
56
|
+
resources.each do |name, content|
|
|
57
|
+
file_path = File.join(tmpdir, name)
|
|
58
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
|
59
|
+
File.write(file_path, content)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Create a dummy schema file for location
|
|
63
|
+
schema_path = File.join(tmpdir, 'schema.rng')
|
|
64
|
+
File.write(schema_path, schema_xml)
|
|
65
|
+
|
|
66
|
+
# Parse with external ref resolution
|
|
67
|
+
begin
|
|
68
|
+
Rng.parse(schema_xml, location: schema_path, resolve_external: true)
|
|
69
|
+
|
|
70
|
+
if expect_error
|
|
71
|
+
{ passed: false, error: 'Expected validation error but schema parsed successfully' }
|
|
72
|
+
else
|
|
73
|
+
{ passed: true }
|
|
74
|
+
end
|
|
75
|
+
rescue Rng::SchemaValidationError => e
|
|
76
|
+
if expect_error
|
|
77
|
+
{ passed: true }
|
|
78
|
+
else
|
|
79
|
+
{ passed: false, error: "Unexpected validation error: #{e.message}" }
|
|
80
|
+
end
|
|
81
|
+
rescue StandardError => e
|
|
82
|
+
{ passed: false, error: "#{e.class}: #{e.message}" }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
# No external refs, just validate as-is
|
|
87
|
+
begin
|
|
88
|
+
Rng::SchemaValidator.validate(schema_xml)
|
|
89
|
+
if expect_error
|
|
90
|
+
{ passed: false, error: 'Expected validation error but schema validated' }
|
|
91
|
+
else
|
|
92
|
+
{ passed: true }
|
|
93
|
+
end
|
|
94
|
+
rescue Rng::SchemaValidationError
|
|
95
|
+
if expect_error
|
|
96
|
+
{ passed: true }
|
|
97
|
+
else
|
|
98
|
+
{ passed: false, error: 'Unexpected validation error' }
|
|
99
|
+
end
|
|
100
|
+
rescue StandardError => e
|
|
101
|
+
{ passed: false, error: "#{e.class}: #{e.message}" }
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# This helper function processes a test suite recursively and generates tests
|
|
107
|
+
def process_test_suite(suite_element, context_description = '', test_case_counter: 0)
|
|
108
|
+
# Get documentation or section number for the context description
|
|
109
|
+
documentation = suite_element.xpath('./documentation').text.strip
|
|
110
|
+
section = suite_element.xpath('./section').text.strip
|
|
111
|
+
|
|
112
|
+
# Build context description
|
|
113
|
+
context_desc = context_description
|
|
114
|
+
if !documentation.empty?
|
|
115
|
+
context_desc || documentation
|
|
116
|
+
elsif !section.empty?
|
|
117
|
+
context_desc || "Section #{section}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Use a non-empty description
|
|
121
|
+
context_desc = 'RELAX NG Test Suite' if context_desc.empty?
|
|
122
|
+
|
|
123
|
+
# Generate tests within a context
|
|
124
|
+
context(context_desc) do
|
|
125
|
+
# Process all test cases in this suite
|
|
126
|
+
suite_element.xpath('./testCase').each_with_index do |test_case, index|
|
|
127
|
+
test_case_counter += 1
|
|
128
|
+
test_documentation = test_case.xpath('./documentation').text.strip
|
|
129
|
+
test_section = test_case.xpath('./section')&.text || ''
|
|
130
|
+
|
|
131
|
+
# Create descriptive test name
|
|
132
|
+
test_desc = if !test_documentation.empty?
|
|
133
|
+
test_documentation
|
|
134
|
+
elsif !test_section.empty?
|
|
135
|
+
"Section #{test_section} compliance"
|
|
136
|
+
else
|
|
137
|
+
'Schema validation'
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Extract resources for this test case
|
|
141
|
+
resources = extract_resources_from_test_case(test_case)
|
|
142
|
+
|
|
143
|
+
context(test_desc) do
|
|
144
|
+
# Test correct schemas
|
|
145
|
+
test_case.xpath('./correct').each do |correct_schema|
|
|
146
|
+
schema_xml = correct_schema.inner_html.strip
|
|
147
|
+
|
|
148
|
+
# Skip empty schemas
|
|
149
|
+
next if schema_xml.empty?
|
|
150
|
+
|
|
151
|
+
it "#{test_desc} - correct schema parsing ##{index + 1}" do
|
|
152
|
+
schema = Rng::Grammar.from_xml(schema_xml)
|
|
153
|
+
expect(schema).not_to be_nil
|
|
154
|
+
rescue StandardError => e
|
|
155
|
+
raise "Expected schema to be valid but got: #{e.message}\nSchema:\n#{schema_xml}"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "#{test_desc} - correct schema round-trip ##{index + 1}" do
|
|
159
|
+
# Check for foreign elements/attributes (lutaml-model drops these)
|
|
160
|
+
doc = Nokogiri::XML(schema_xml)
|
|
161
|
+
has_foreign = doc.xpath("//*[namespace-uri() != 'http://relaxng.org/ns/structure/1.0']").any? ||
|
|
162
|
+
doc.xpath("//@*[namespace-uri() != '' and namespace-uri() != 'http://relaxng.org/ns/structure/1.0' and local-name() != 'base']").any?
|
|
163
|
+
skip 'foreign elements/attributes not supported (by design)' if has_foreign
|
|
164
|
+
|
|
165
|
+
# Parse the XML into a schema
|
|
166
|
+
xml_doc = Nokogiri::XML(schema_xml)
|
|
167
|
+
root_element_name = xml_doc.root&.name
|
|
168
|
+
|
|
169
|
+
# Choose the appropriate class based on the root element name
|
|
170
|
+
schema = case root_element_name
|
|
171
|
+
when 'grammar'
|
|
172
|
+
Rng::Grammar.from_xml(schema_xml)
|
|
173
|
+
when 'element'
|
|
174
|
+
Rng::Element.from_xml(schema_xml)
|
|
175
|
+
when 'group'
|
|
176
|
+
Rng::Group.from_xml(schema_xml)
|
|
177
|
+
when 'choice'
|
|
178
|
+
Rng::Choice.from_xml(schema_xml)
|
|
179
|
+
when 'notAllowed'
|
|
180
|
+
Rng::NotAllowed.from_xml(schema_xml)
|
|
181
|
+
when 'externalRef'
|
|
182
|
+
Rng::ExternalRef.from_xml(schema_xml)
|
|
183
|
+
else
|
|
184
|
+
# Default to Schema for other cases
|
|
185
|
+
raise "Unknown root element: #{root_element_name}"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Convert the schema back to XML
|
|
189
|
+
regenerated = schema.to_xml
|
|
190
|
+
|
|
191
|
+
# Verify the regenerated XML matches the original
|
|
192
|
+
expect(regenerated).to be_xml_equivalent_to(schema_xml)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Test incorrect schemas
|
|
197
|
+
test_case.xpath('./incorrect').each do |incorrect_schema|
|
|
198
|
+
schema_xml = incorrect_schema.inner_html.strip
|
|
199
|
+
|
|
200
|
+
# Skip empty schemas
|
|
201
|
+
next if schema_xml.empty?
|
|
202
|
+
|
|
203
|
+
it "#{test_desc} - incorrect schema ##{index + 1}" do
|
|
204
|
+
has_external_refs = schema_has_external_refs?(schema_xml)
|
|
205
|
+
|
|
206
|
+
# NCName tests with Thai char U+0E35 are valid in XML 1.0 5th ed
|
|
207
|
+
# but invalid in RELAX NG spec (October 26 version used stricter rules)
|
|
208
|
+
skip 'NCName with Thai char U+0E35: XML 1.0 5th ed allows but older RELAX NG spec did not' if schema_xml.include?('ี') || schema_xml.include?("\xE35")
|
|
209
|
+
|
|
210
|
+
skip 'externalRef/include href resolution requires external file I/O' if has_external_refs && resources.empty?
|
|
211
|
+
|
|
212
|
+
result = run_schema_test(schema_xml, resources, expect_error: true)
|
|
213
|
+
|
|
214
|
+
if result[:skipped]
|
|
215
|
+
skip result[:reason]
|
|
216
|
+
elsif result[:passed]
|
|
217
|
+
expect(result[:passed]).to be(true)
|
|
218
|
+
else
|
|
219
|
+
# If schema parsed/validated successfully after external ref resolution,
|
|
220
|
+
# it means the external refs were resolvable (test passes after resolution)
|
|
221
|
+
error_msg = result[:error] || ''
|
|
222
|
+
if error_msg.include?('Expected validation error but schema') ||
|
|
223
|
+
error_msg.include?('parsed successfully')
|
|
224
|
+
skip 'Schema was incorrect due to unresolvable refs, but resolution now works'
|
|
225
|
+
else
|
|
226
|
+
raise "Test failed: #{result[:error]}\nSchema:\n#{schema_xml}"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# XML instance validation (valid/invalid) requires a full RELAX NG
|
|
233
|
+
# validator implementation - out of scope for schema parsing library
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Process nested test suites recursively
|
|
238
|
+
suite_element.xpath('./testSuite').each do |nested_suite|
|
|
239
|
+
test_case_counter = process_test_suite(nested_suite, context_desc, test_case_counter: test_case_counter)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
test_case_counter
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
RSpec.describe 'RELAX NG Specification Tests' do
|
|
247
|
+
# First, confirm the test file exists
|
|
248
|
+
it 'finds the spectest.xml file' do
|
|
249
|
+
expect(File.exist?(SPEC_TEST_XML_PATH)).to be true
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Generate a summary of the test suite
|
|
253
|
+
describe 'Test Suite Summary' do
|
|
254
|
+
it 'contains test cases organized by section' do
|
|
255
|
+
sections = SPECTEST_XML.xpath('//section').map(&:text).uniq
|
|
256
|
+
expect(sections.length).to be > 0
|
|
257
|
+
|
|
258
|
+
correct_count = SPECTEST_XML.xpath('//correct').count
|
|
259
|
+
incorrect_count = SPECTEST_XML.xpath('//incorrect').count
|
|
260
|
+
SPECTEST_XML.xpath('//valid').count
|
|
261
|
+
SPECTEST_XML.xpath('//invalid').count
|
|
262
|
+
|
|
263
|
+
# Count test cases with resources
|
|
264
|
+
SPECTEST_XML.xpath('//testCase[resource]').count
|
|
265
|
+
|
|
266
|
+
total = correct_count + incorrect_count
|
|
267
|
+
expect(total).to be > 0
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Start processing from the root test suite
|
|
272
|
+
process_test_suite(SPECTEST_XML.xpath('/testSuite').first)
|
|
273
|
+
end
|
data/spec/rng_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'rng'
|
|
4
|
+
require 'canon'
|
|
5
5
|
|
|
6
6
|
RSpec.configure do |config|
|
|
7
7
|
# Enable flags like --only-failures and --next-failure
|
|
8
|
-
config.example_status_persistence_file_path =
|
|
8
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
|
9
9
|
|
|
10
10
|
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
11
11
|
config.disable_monkey_patching!
|
|
@@ -13,11 +13,9 @@ RSpec.configure do |config|
|
|
|
13
13
|
config.expect_with :rspec do |c|
|
|
14
14
|
c.syntax = :expect
|
|
15
15
|
end
|
|
16
|
+
end
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Xml::C14n.format(xml)
|
|
21
|
-
end
|
|
22
|
-
end)
|
|
18
|
+
require 'lutaml/model'
|
|
19
|
+
Lutaml::Model::Config.configure do |config|
|
|
20
|
+
config.xml_adapter_type = :nokogiri
|
|
23
21
|
end
|
metadata
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rng
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-04-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.8.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.8.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: nokogiri
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
16
30
|
requirements:
|
|
17
31
|
- - ">="
|
|
@@ -39,7 +53,7 @@ dependencies:
|
|
|
39
53
|
- !ruby/object:Gem::Version
|
|
40
54
|
version: '0'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
56
|
+
name: thor
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
44
58
|
requirements:
|
|
45
59
|
- - ">="
|
|
@@ -55,32 +69,198 @@ dependencies:
|
|
|
55
69
|
description:
|
|
56
70
|
email:
|
|
57
71
|
- open.source@ribose.com
|
|
58
|
-
executables:
|
|
72
|
+
executables:
|
|
73
|
+
- rng
|
|
59
74
|
extensions: []
|
|
60
75
|
extra_rdoc_files: []
|
|
61
76
|
files:
|
|
77
|
+
- ".github/workflows/docs.yml"
|
|
62
78
|
- ".github/workflows/rake.yml"
|
|
63
79
|
- ".github/workflows/release.yml"
|
|
64
80
|
- ".gitignore"
|
|
65
81
|
- ".rspec"
|
|
66
82
|
- ".rubocop.yml"
|
|
83
|
+
- ".rubocop_todo.yml"
|
|
84
|
+
- CHANGELOG.md
|
|
85
|
+
- CLAUDE.md
|
|
86
|
+
- CODE_OF_CONDUCT.md
|
|
67
87
|
- Gemfile
|
|
88
|
+
- README.adoc
|
|
68
89
|
- Rakefile
|
|
90
|
+
- docs/Gemfile
|
|
91
|
+
- docs/_config.yml
|
|
92
|
+
- docs/getting-started/index.adoc
|
|
93
|
+
- docs/guides/error-handling.adoc
|
|
94
|
+
- docs/guides/external-references.adoc
|
|
95
|
+
- docs/guides/index.adoc
|
|
96
|
+
- docs/guides/parsing-rnc.adoc
|
|
97
|
+
- docs/guides/parsing-rng-xml.adoc
|
|
98
|
+
- docs/guides/rng-to-rnc.adoc
|
|
99
|
+
- docs/guides/validation.adoc
|
|
100
|
+
- docs/index.adoc
|
|
101
|
+
- docs/reference/api.adoc
|
|
102
|
+
- docs/reference/cli.adoc
|
|
103
|
+
- docs/understanding/architecture.adoc
|
|
104
|
+
- docs/understanding/rng-vs-rnc.adoc
|
|
105
|
+
- exe/rng
|
|
69
106
|
- lib/rng.rb
|
|
107
|
+
- lib/rng/any_name.rb
|
|
70
108
|
- lib/rng/attribute.rb
|
|
71
|
-
- lib/rng/
|
|
109
|
+
- lib/rng/choice.rb
|
|
110
|
+
- lib/rng/cli.rb
|
|
111
|
+
- lib/rng/data.rb
|
|
112
|
+
- lib/rng/datatype_declaration.rb
|
|
72
113
|
- lib/rng/define.rb
|
|
114
|
+
- lib/rng/div.rb
|
|
115
|
+
- lib/rng/documentation.rb
|
|
73
116
|
- lib/rng/element.rb
|
|
117
|
+
- lib/rng/empty.rb
|
|
118
|
+
- lib/rng/except.rb
|
|
119
|
+
- lib/rng/external_ref.rb
|
|
120
|
+
- lib/rng/external_ref_resolver.rb
|
|
121
|
+
- lib/rng/foreign_attribute.rb
|
|
122
|
+
- lib/rng/foreign_element.rb
|
|
123
|
+
- lib/rng/grammar.rb
|
|
124
|
+
- lib/rng/group.rb
|
|
125
|
+
- lib/rng/include.rb
|
|
126
|
+
- lib/rng/include_processor.rb
|
|
127
|
+
- lib/rng/interleave.rb
|
|
128
|
+
- lib/rng/list.rb
|
|
129
|
+
- lib/rng/mixed.rb
|
|
130
|
+
- lib/rng/name.rb
|
|
131
|
+
- lib/rng/namespace_declaration.rb
|
|
132
|
+
- lib/rng/namespaces.rb
|
|
133
|
+
- lib/rng/not_allowed.rb
|
|
134
|
+
- lib/rng/ns_name.rb
|
|
135
|
+
- lib/rng/one_or_more.rb
|
|
136
|
+
- lib/rng/optional.rb
|
|
137
|
+
- lib/rng/param.rb
|
|
138
|
+
- lib/rng/parent_ref.rb
|
|
139
|
+
- lib/rng/parse_rnc.rb
|
|
140
|
+
- lib/rng/parse_tree_processor.rb
|
|
141
|
+
- lib/rng/pattern.rb
|
|
142
|
+
- lib/rng/ref.rb
|
|
143
|
+
- lib/rng/rnc_builder.rb
|
|
74
144
|
- lib/rng/rnc_parser.rb
|
|
75
|
-
- lib/rng/
|
|
76
|
-
- lib/rng/
|
|
145
|
+
- lib/rng/rnc_to_rng_converter.rb
|
|
146
|
+
- lib/rng/schema_preamble.rb
|
|
147
|
+
- lib/rng/schema_validator.rb
|
|
77
148
|
- lib/rng/start.rb
|
|
149
|
+
- lib/rng/test_suite_parser.rb
|
|
150
|
+
- lib/rng/text.rb
|
|
151
|
+
- lib/rng/to_rnc.rb
|
|
152
|
+
- lib/rng/value.rb
|
|
78
153
|
- lib/rng/version.rb
|
|
154
|
+
- lib/rng/zero_or_more.rb
|
|
79
155
|
- rng.gemspec
|
|
156
|
+
- scripts/extract_spectest_resources.rb
|
|
80
157
|
- sig/rng.rbs
|
|
158
|
+
- spec/fixtures/compacttest.xml
|
|
159
|
+
- spec/fixtures/external/circular_a.rng
|
|
160
|
+
- spec/fixtures/external/circular_b.rng
|
|
161
|
+
- spec/fixtures/external/circular_main.rng
|
|
162
|
+
- spec/fixtures/external/external_ref_lib.rng
|
|
163
|
+
- spec/fixtures/external/external_ref_main.rng
|
|
164
|
+
- spec/fixtures/external/include_lib.rng
|
|
165
|
+
- spec/fixtures/external/include_main.rng
|
|
166
|
+
- spec/fixtures/external/nested_chain.rng
|
|
167
|
+
- spec/fixtures/external/nested_leaf.rng
|
|
168
|
+
- spec/fixtures/external/nested_mid.rng
|
|
169
|
+
- spec/fixtures/metanorma/3gpp.rnc
|
|
170
|
+
- spec/fixtures/metanorma/3gpp.rng
|
|
171
|
+
- spec/fixtures/metanorma/basicdoc.rnc
|
|
172
|
+
- spec/fixtures/metanorma/bipm.rnc
|
|
173
|
+
- spec/fixtures/metanorma/bipm.rng
|
|
174
|
+
- spec/fixtures/metanorma/bsi.rnc
|
|
175
|
+
- spec/fixtures/metanorma/bsi.rng
|
|
176
|
+
- spec/fixtures/metanorma/csa.rnc
|
|
177
|
+
- spec/fixtures/metanorma/csa.rng
|
|
178
|
+
- spec/fixtures/metanorma/csd.rnc
|
|
179
|
+
- spec/fixtures/metanorma/csd.rng
|
|
180
|
+
- spec/fixtures/metanorma/gbstandard.rnc
|
|
181
|
+
- spec/fixtures/metanorma/gbstandard.rng
|
|
182
|
+
- spec/fixtures/metanorma/iec.rnc
|
|
183
|
+
- spec/fixtures/metanorma/iec.rng
|
|
184
|
+
- spec/fixtures/metanorma/ietf.rnc
|
|
185
|
+
- spec/fixtures/metanorma/ietf.rng
|
|
186
|
+
- spec/fixtures/metanorma/iho.rnc
|
|
187
|
+
- spec/fixtures/metanorma/iho.rng
|
|
188
|
+
- spec/fixtures/metanorma/isodoc.rnc
|
|
189
|
+
- spec/fixtures/metanorma/isodoc.rng
|
|
190
|
+
- spec/fixtures/metanorma/isostandard-amd.rnc
|
|
191
|
+
- spec/fixtures/metanorma/isostandard-amd.rng
|
|
192
|
+
- spec/fixtures/metanorma/isostandard.rnc
|
|
193
|
+
- spec/fixtures/metanorma/isostandard.rng
|
|
194
|
+
- spec/fixtures/metanorma/itu.rnc
|
|
195
|
+
- spec/fixtures/metanorma/itu.rng
|
|
196
|
+
- spec/fixtures/metanorma/m3d.rnc
|
|
197
|
+
- spec/fixtures/metanorma/m3d.rng
|
|
198
|
+
- spec/fixtures/metanorma/mpfd.rnc
|
|
199
|
+
- spec/fixtures/metanorma/mpfd.rng
|
|
200
|
+
- spec/fixtures/metanorma/nist.rnc
|
|
201
|
+
- spec/fixtures/metanorma/nist.rng
|
|
202
|
+
- spec/fixtures/metanorma/ogc.rnc
|
|
203
|
+
- spec/fixtures/metanorma/ogc.rng
|
|
204
|
+
- spec/fixtures/metanorma/reqt.rnc
|
|
205
|
+
- spec/fixtures/metanorma/rsd.rnc
|
|
206
|
+
- spec/fixtures/metanorma/rsd.rng
|
|
207
|
+
- spec/fixtures/metanorma/un.rnc
|
|
208
|
+
- spec/fixtures/metanorma/un.rng
|
|
209
|
+
- spec/fixtures/rnc/address_book.rnc
|
|
210
|
+
- spec/fixtures/rnc/base.rnc
|
|
211
|
+
- spec/fixtures/rnc/complex_example.rnc
|
|
212
|
+
- spec/fixtures/rnc/grammar_with_trailing.rnc
|
|
213
|
+
- spec/fixtures/rnc/main_include_trailing.rnc
|
|
214
|
+
- spec/fixtures/rnc/main_with_include.rnc
|
|
215
|
+
- spec/fixtures/rnc/test_augment.rnc
|
|
216
|
+
- spec/fixtures/rnc/test_isodoc_simple.rnc
|
|
217
|
+
- spec/fixtures/rnc/top_level_include.rnc
|
|
218
|
+
- spec/fixtures/rng/address_book.rng
|
|
219
|
+
- spec/fixtures/rng/relaxng.rng
|
|
220
|
+
- spec/fixtures/rng/testSuite.rng
|
|
221
|
+
- spec/fixtures/spectest.xml
|
|
222
|
+
- spec/fixtures/spectest_external/case_10_4.7/x
|
|
223
|
+
- spec/fixtures/spectest_external/case_10_4.7/y
|
|
224
|
+
- spec/fixtures/spectest_external/case_11_4.7/x
|
|
225
|
+
- spec/fixtures/spectest_external/case_12_4.7/x
|
|
226
|
+
- spec/fixtures/spectest_external/case_13_4.7/x
|
|
227
|
+
- spec/fixtures/spectest_external/case_13_4.7/y
|
|
228
|
+
- spec/fixtures/spectest_external/case_14_4.7/x
|
|
229
|
+
- spec/fixtures/spectest_external/case_15_4.7/x
|
|
230
|
+
- spec/fixtures/spectest_external/case_16_4.7/x
|
|
231
|
+
- spec/fixtures/spectest_external/case_17_4.7/x
|
|
232
|
+
- spec/fixtures/spectest_external/case_18_4.7/x
|
|
233
|
+
- spec/fixtures/spectest_external/case_19_4.7/level1.rng
|
|
234
|
+
- spec/fixtures/spectest_external/case_19_4.7/level2.rng
|
|
235
|
+
- spec/fixtures/spectest_external/case_1_4.5/sub1/x
|
|
236
|
+
- spec/fixtures/spectest_external/case_1_4.5/sub3/x
|
|
237
|
+
- spec/fixtures/spectest_external/case_1_4.5/x
|
|
238
|
+
- spec/fixtures/spectest_external/case_20_4.6/x
|
|
239
|
+
- spec/fixtures/spectest_external/case_2_4.5/x
|
|
240
|
+
- spec/fixtures/spectest_external/case_3_4.6/x
|
|
241
|
+
- spec/fixtures/spectest_external/case_4_4.6/x
|
|
242
|
+
- spec/fixtures/spectest_external/case_5_4.6/x
|
|
243
|
+
- spec/fixtures/spectest_external/case_6_4.6/x
|
|
244
|
+
- spec/fixtures/spectest_external/case_7_4.6/x
|
|
245
|
+
- spec/fixtures/spectest_external/case_7_4.6/y
|
|
246
|
+
- spec/fixtures/spectest_external/case_8_4.7/x
|
|
247
|
+
- spec/fixtures/spectest_external/case_9_4.7/x
|
|
248
|
+
- spec/fixtures/spectest_external/resources.json
|
|
249
|
+
- spec/rng/advanced_rnc_spec.rb
|
|
250
|
+
- spec/rng/compacttest_spec.rb
|
|
251
|
+
- spec/rng/datatype_declaration_spec.rb
|
|
252
|
+
- spec/rng/div_spec.rb
|
|
253
|
+
- spec/rng/external_ref_resolver_spec.rb
|
|
254
|
+
- spec/rng/metanorma_conversion_spec.rb
|
|
255
|
+
- spec/rng/namespace_declaration_spec.rb
|
|
256
|
+
- spec/rng/namespace_support_spec.rb
|
|
81
257
|
- spec/rng/rnc_parser_spec.rb
|
|
82
|
-
- spec/rng/
|
|
258
|
+
- spec/rng/rnc_roundtrip_spec.rb
|
|
259
|
+
- spec/rng/rng_generation_spec.rb
|
|
260
|
+
- spec/rng/roundtrip_spec.rb
|
|
261
|
+
- spec/rng/schema_preamble_spec.rb
|
|
83
262
|
- spec/rng/schema_spec.rb
|
|
263
|
+
- spec/rng/spectest_spec.rb
|
|
84
264
|
- spec/rng_spec.rb
|
|
85
265
|
- spec/spec_helper.rb
|
|
86
266
|
homepage: https://github.com/lutaml/rng
|