moxml 0.5.76 → 0.5.77
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/lib/moxml/adapter/base.rb +12 -0
- data/lib/moxml/adapter/leptris.rb +62 -1
- data/lib/moxml/document.rb +10 -0
- data/lib/moxml/version.rb +1 -1
- data/spec/moxml/document_parse_diagnostics_spec.rb +43 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0a7016ee5591571ecbf834dd6f948592967264e18abff80246d8527898090ce7
|
|
4
|
+
data.tar.gz: fb1f4b91c68dde1883a010e38cf35cbc3d21e396f990b4677e755a1dbf10ab90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 74b8599a7b3a8e0e7dcef25c6375a712cfe52b8788f361ca7689ddd6823691135a8b33d70ac2a343304361d3615093c98842b53fe6c7a1f60934a6e9df082304
|
|
7
|
+
data.tar.gz: d643d89e4c8ee3ce3ab583cb0b0155363ff8b1bd130133b2836f340a0af46dd7adf8873160dbb56edcb32a14db6786a05de4c06559f0ea48dfff29a6e124c0e8
|
data/lib/moxml/adapter/base.rb
CHANGED
|
@@ -403,6 +403,18 @@ namespace_validation_mode: :strict)
|
|
|
403
403
|
nil
|
|
404
404
|
end
|
|
405
405
|
|
|
406
|
+
# Parse diagnostics (issue #271): recover-class events the
|
|
407
|
+
# engine recorded during the parse — duplicate-attribute
|
|
408
|
+
# recoveries and siblings — as [{ kind:, message: }] in
|
|
409
|
+
# record order, [] for a clean parse. Reads must happen
|
|
410
|
+
# while the native document is alive (the engine owns the
|
|
411
|
+
# list); adapters without the surface answer []. Distinct
|
|
412
|
+
# from #parse_errors (the strict-parse failure channel):
|
|
413
|
+
# diagnostics describe RECOVERED documents.
|
|
414
|
+
def parse_diagnostics(_native_doc)
|
|
415
|
+
[]
|
|
416
|
+
end
|
|
417
|
+
|
|
406
418
|
# Recover-mode parse diagnostics (issue #147): the error
|
|
407
419
|
# messages the engine recorded while parsing, [] when the
|
|
408
420
|
# parse was clean. Engines with a native recover channel
|
|
@@ -333,11 +333,39 @@ module Moxml
|
|
|
333
333
|
|
|
334
334
|
root.visit do |node, entering, depth|
|
|
335
335
|
if entering && depth.positive?
|
|
336
|
-
yield
|
|
336
|
+
yield wrap_binding_node(node, context)
|
|
337
337
|
end
|
|
338
338
|
end
|
|
339
339
|
end
|
|
340
340
|
|
|
341
|
+
# Fast mint for walk-yielded binding nodes (#312): one
|
|
342
|
+
# class-keyed hash answers wrapper class AND type — the
|
|
343
|
+
# generic wrap path's node_type probe, wrap_native detour,
|
|
344
|
+
# type map, and tap all drop out. Identity rides the
|
|
345
|
+
# @moxml_wrapper ivar (cache-stable nodes, #270).
|
|
346
|
+
BINDING_FAST_WRAP = {
|
|
347
|
+
::Leptris::XML::Element => [Moxml::Wrappers::Element, :element],
|
|
348
|
+
::Leptris::XML::Text => [Moxml::Wrappers::Text, :text],
|
|
349
|
+
::Leptris::XML::CDATA => [Moxml::Wrappers::Cdata, :cdata],
|
|
350
|
+
::Leptris::XML::Comment => [Moxml::Wrappers::Comment, :comment],
|
|
351
|
+
::Leptris::XML::ProcessingInstruction =>
|
|
352
|
+
[Moxml::Wrappers::ProcessingInstruction, :processing_instruction],
|
|
353
|
+
}.freeze
|
|
354
|
+
|
|
355
|
+
def wrap_binding_node(node, context)
|
|
356
|
+
if node.instance_variable_defined?(:@moxml_wrapper)
|
|
357
|
+
cached = node.instance_variable_get(:@moxml_wrapper)
|
|
358
|
+
return cached if cached
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
entry = BINDING_FAST_WRAP[node.class]
|
|
362
|
+
return nil unless entry
|
|
363
|
+
|
|
364
|
+
wrapper = entry[0].new(node, context, self, entry[1])
|
|
365
|
+
node.instance_variable_set(:@moxml_wrapper, wrapper)
|
|
366
|
+
wrapper
|
|
367
|
+
end
|
|
368
|
+
|
|
341
369
|
def record_native_doc(root_native, doc)
|
|
342
370
|
@native_doc_roots[root_native] = doc
|
|
343
371
|
end
|
|
@@ -842,6 +870,39 @@ module Moxml
|
|
|
842
870
|
attachments.get(native_doc, :parse_errors) || NO_PARSE_ERRORS
|
|
843
871
|
end
|
|
844
872
|
|
|
873
|
+
# leptris#1200 recover diagnostics (binding FFI >= the
|
|
874
|
+
# 1.9.206 surface adoption; probed, not version-gated —
|
|
875
|
+
# lockstep trains have shipped gems without faces).
|
|
876
|
+
DIAG_KINDS = %i[
|
|
877
|
+
invalid not_allowed_anywhere not_allowed_here
|
|
878
|
+
not_allowed_yet incomplete missing_required_attr
|
|
879
|
+
attr_not_allowed attr_value_invalid
|
|
880
|
+
char_content_invalid recover
|
|
881
|
+
].freeze
|
|
882
|
+
|
|
883
|
+
def parse_diagnostics(native_doc)
|
|
884
|
+
ffi = ::Leptris::XML::FFI
|
|
885
|
+
return [] unless native_doc.is_a?(::Leptris::XML::Document) &&
|
|
886
|
+
ffi.respond_to?(:leptris_document_parse_diag_count)
|
|
887
|
+
|
|
888
|
+
doc = native_doc.c_ptr
|
|
889
|
+
count = ffi.leptris_document_parse_diag_count(doc)
|
|
890
|
+
return [] if count.zero?
|
|
891
|
+
|
|
892
|
+
kind_ptr = ::FFI::MemoryPointer.new(:int)
|
|
893
|
+
diagnostics = []
|
|
894
|
+
count.times do |i|
|
|
895
|
+
buffer = ::FFI::MemoryPointer.new(512)
|
|
896
|
+
next unless ffi.leptris_document_parse_diag(
|
|
897
|
+
doc, i, kind_ptr, buffer, 512
|
|
898
|
+
) == 1
|
|
899
|
+
|
|
900
|
+
kind = DIAG_KINDS[kind_ptr.read_int] || :unknown
|
|
901
|
+
diagnostics << { kind: kind, message: buffer.read_string }
|
|
902
|
+
end
|
|
903
|
+
diagnostics
|
|
904
|
+
end
|
|
905
|
+
|
|
845
906
|
def create_document(_native_doc = nil)
|
|
846
907
|
::Leptris::XML::Document.create
|
|
847
908
|
end
|
data/lib/moxml/document.rb
CHANGED
|
@@ -58,6 +58,16 @@ module Moxml
|
|
|
58
58
|
# reports the fatal error that emptied it; Nokogiri reports its
|
|
59
59
|
# recover-mode syntax errors; engines without an error channel
|
|
60
60
|
# answer [].
|
|
61
|
+
# Recover-class diagnostics the engine recorded during this
|
|
62
|
+
# document's parse (issue #271): duplicate-attribute
|
|
63
|
+
# recoveries and siblings, as [{ kind:, message: }] in record
|
|
64
|
+
# order. Read while the document is alive — the engine owns
|
|
65
|
+
# the list. [] when the parse was clean or the adapter has no
|
|
66
|
+
# diagnostic surface.
|
|
67
|
+
def parse_diagnostics
|
|
68
|
+
adapter.parse_diagnostics(@native)
|
|
69
|
+
end
|
|
70
|
+
|
|
61
71
|
def parse_errors
|
|
62
72
|
adapter.parse_errors(@native)
|
|
63
73
|
end
|
data/lib/moxml/version.rb
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# Document#parse_diagnostics (issue #271, option A — additive):
|
|
6
|
+
# recover-class events the engine recorded during the parse, as
|
|
7
|
+
# [{ kind:, message: }]. Clean parses answer []; adapters without
|
|
8
|
+
# the surface answer []. Reads happen through the live native
|
|
9
|
+
# document (the engine owns the list — read before free).
|
|
10
|
+
RSpec.describe Moxml::Document do
|
|
11
|
+
def with_leptris
|
|
12
|
+
ctx = Moxml.new(:leptris)
|
|
13
|
+
yield ctx
|
|
14
|
+
rescue StandardError, LoadError
|
|
15
|
+
skip "leptris adapter unavailable"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "answers [] for a clean parse" do
|
|
19
|
+
with_leptris do |ctx|
|
|
20
|
+
expect(ctx.parse("<r><a/></r>").parse_diagnostics).to eq([])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "surfaces duplicate-attribute recoveries with kind and message" do
|
|
25
|
+
with_leptris do |ctx|
|
|
26
|
+
doc = ctx.parse(%(<r a="1" a="2"/>), recover: true) ||
|
|
27
|
+
ctx.parse(%(<r a="1" a="2"/>))
|
|
28
|
+
next skip "engine recovered without diagnostics" if doc.nil?
|
|
29
|
+
|
|
30
|
+
diags = doc.parse_diagnostics
|
|
31
|
+
expect(diags).not_to be_empty
|
|
32
|
+
expect(diags.first[:kind]).to eq(:recover)
|
|
33
|
+
expect(diags.first[:message]).to be_a(String)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "answers [] on adapters without the surface" do
|
|
38
|
+
ctx = Moxml.new(:rexml)
|
|
39
|
+
expect(ctx.parse("<r/>").parse_diagnostics).to eq([])
|
|
40
|
+
rescue StandardError, LoadError
|
|
41
|
+
skip "rexml adapter unavailable"
|
|
42
|
+
end
|
|
43
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.77
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -466,6 +466,7 @@ files:
|
|
|
466
466
|
- spec/moxml/doctype_spec.rb
|
|
467
467
|
- spec/moxml/document_builder_spec.rb
|
|
468
468
|
- spec/moxml/document_free_spec.rb
|
|
469
|
+
- spec/moxml/document_parse_diagnostics_spec.rb
|
|
469
470
|
- spec/moxml/document_spec.rb
|
|
470
471
|
- spec/moxml/element_attribute_pairs_spec.rb
|
|
471
472
|
- spec/moxml/element_spec.rb
|