moxml 0.5.134 → 0.5.136

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16541b7e14c315d57375c3ac583844239801ef5dd81e69e87df9f701553d62f9
4
- data.tar.gz: dad46bc86c7f5617813cb03ccc9f60a3d9b9be2785a991ffb9932f29d78fcbe1
3
+ metadata.gz: 7ae551e19c600eba6d19a7a2a1c764275673d4ad7deba04d3778d407464ec8b9
4
+ data.tar.gz: e546f3c3290bfde650efb0d42625146abaf87f20741be65aee93ab8dad0a1c84
5
5
  SHA512:
6
- metadata.gz: 99ef7ebe98b5722cff35e18f0862fba36628f9eef548bf166dc65cd3d207f1299706c7a7da92b17896ded2463f15114933b2ff17c79d549bf658620191974e48
7
- data.tar.gz: 41506cc4e7ca3ea53dd8b275830814ec37bc138b8b4a174840d894aaf63dd7a97d7cf6d75ec0b3a9e12ff40c156262bcfa39bec155c828256d7aa1b2191fba56
6
+ metadata.gz: 30ba4c3744a7742dcde2b457fcfa99a0a32f7ddac8ebd721ca79eff029b0faeb4ab91b8577d4270975973933193594b3ff7e05926e7e84500dee25d20c90ce3b
7
+ data.tar.gz: 12791df8b1c31cc43204904abbe4f7b5e3f3d1e3e4be248637efbb67d734fe6be36f9384a6345be95ba3993efcec43c0f387086d63cafc623d0f63a66c9c69fa
@@ -194,6 +194,15 @@ module Moxml
194
194
  ::Leptris::XML::ParseOptions.instance_method(:initialize)
195
195
  .parameters.any? { |_, key| key == :recover }
196
196
 
197
+ # moxml#375 — the element-attribute snapshot (binding
198
+ # 1.9.353.0, engine leptris#1689): every attribute's
199
+ # qualified name and value in ONE crossing, replacing the
200
+ # per-attribute reads behind ::Leptris::XML::Element
201
+ # #attribute_pairs.
202
+ ELEMENT_ATTR_SNAPSHOT =
203
+ Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.353.0") &&
204
+ ::Leptris::XML::Element.method_defined?(:attributes_snapshot)
205
+
197
206
  # Markup-accumulating builder face (leptris-ruby#374 lever 2,
198
207
  # binding 1.9.313): the DSL accumulates markup in a plain
199
208
  # String and ONE native crossing (parse + attach) flushes the
@@ -2059,6 +2068,7 @@ module Moxml
2059
2068
  def attribute_pairs(element)
2060
2069
  binding_element = to_binding(element)
2061
2070
  return super unless binding_element.respond_to?(:attribute_pairs)
2071
+ return binding_element.attributes_snapshot.to_a if ELEMENT_ATTR_SNAPSHOT
2062
2072
 
2063
2073
  binding_element.attribute_pairs
2064
2074
  end
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.134"
4
+ VERSION = "0.5.136"
5
5
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ # moxml#375 — element hydration through the binding's
6
+ # attributes_snapshot face (libleptris 1.9.353, engine
7
+ # leptris#1689): one crossing for every attribute instead of one
8
+ # per attribute. The output contract is stride-identical to the
9
+ # binding's per-attribute face: qualified names, document order,
10
+ # fresh values.
11
+ RSpec.describe "leptris element-attribute snapshot hydration" do
12
+ let(:ctx) { Moxml.new(:leptris) }
13
+
14
+ context "when the snapshot face is armed (>= 1.9.353.0)" do
15
+ before do
16
+ unless Moxml::Adapter::Leptris::ELEMENT_ATTR_SNAPSHOT
17
+ skip "binding #{Leptris::VERSION} has no attributes_snapshot face"
18
+ end
19
+ end
20
+
21
+ it "matches the binding per-attribute face stride for stride" do
22
+ doc = ctx.parse(
23
+ '<root a="1" xml:lang="en" xmlns:ns="urn:u" ns:p="v"/>',
24
+ )
25
+ binding_element = Moxml::Adapter::Leptris.to_binding(doc.root)
26
+ expected = binding_element.attribute_pairs
27
+
28
+ expect(doc.root.attribute_pairs).to eq(expected)
29
+ expect(doc.root.attribute_pairs).to eq(
30
+ [["a", "1"], ["xml:lang", "en"], ["ns:p", "v"]],
31
+ )
32
+ end
33
+
34
+ it "keeps document order across plain and prefixed attributes" do
35
+ doc = ctx.parse(
36
+ '<root z="9" xmlns:m="urn:m" m:x="8" k="7"/>',
37
+ )
38
+ expect(doc.root.attribute_pairs.map(&:first)).to eq(
39
+ %w[z m:x k],
40
+ )
41
+ end
42
+
43
+ it "keeps the per-attribute face's memoized-read semantics" do
44
+ doc = ctx.parse('<root a="1"/>')
45
+ first = doc.root.attribute_pairs
46
+ first[0][1] << "mutated"
47
+
48
+ # The wrapper memoizes attribute reads; the snapshot path
49
+ # preserves that (values are shared across reads exactly as
50
+ # the binding face's memo does).
51
+ expect(doc.root.attribute_pairs).to eq([["a", "1mutated"]])
52
+ end
53
+
54
+ it "hydrates child elements the same way" do
55
+ doc = ctx.parse('<r><child b="2" c="3"/></r>')
56
+ expect(doc.at("//child").attribute_pairs).to eq(
57
+ [["b", "2"], ["c", "3"]],
58
+ )
59
+ end
60
+
61
+ it "yields an empty list for attribute-less elements" do
62
+ doc = ctx.parse("<root/>")
63
+ expect(doc.root.attribute_pairs).to eq([])
64
+ end
65
+ end
66
+
67
+ context "with any arm state" do
68
+ it "agrees with the binding per-attribute face" do
69
+ doc = ctx.parse(
70
+ '<root a="1" xml:lang="en" xmlns:ns="urn:u" ns:p="v"/>',
71
+ )
72
+ binding_element = Moxml::Adapter::Leptris.to_binding(doc.root)
73
+ expect(doc.root.attribute_pairs).to eq(
74
+ binding_element.attribute_pairs,
75
+ )
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ # Engine 1.9.355 (leptris#1700) names the tag mismatch in strict-parse
6
+ # failures — "expected </a>, got </b>" instead of the generic
7
+ # "malformed input". moxml passes the binding message through
8
+ # verbatim, so strict callers get the diagnostic for free; the spec
9
+ # pins it so a regression (or a re-genericization upstream) is caught.
10
+ RSpec.describe "leptris strict-parse mismatch diagnostic" do
11
+ let(:ctx) { Moxml.new(:leptris) }
12
+
13
+ context "when the engine names the mismatch (>= 1.9.355.0)" do
14
+ before do
15
+ unless Gem::Version.new(Leptris::VERSION) >= Gem::Version.new("1.9.355.0")
16
+ skip "binding #{Leptris::VERSION} predates the mismatch diagnostic"
17
+ end
18
+ end
19
+
20
+ it "names expected and got in the raised message" do
21
+ expect do
22
+ ctx.parse("<root><a></b></root>", strict: true)
23
+ end.to raise_error(Moxml::ParseError) do |e|
24
+ expect(e.message).to include("tag mismatch")
25
+ expect(e.message).to include("</a>")
26
+ expect(e.message).to include("</b>")
27
+ end
28
+ end
29
+
30
+ it "reports the byte offset of the failure" do
31
+ expect do
32
+ ctx.parse("<root><a></b></root>", strict: true)
33
+ end.to raise_error(Moxml::ParseError, /byte 13/)
34
+ end
35
+ end
36
+
37
+ it "still raises Moxml::ParseError on strict parse failure" do
38
+ expect do
39
+ ctx.parse("<root><a></b></root>", strict: true)
40
+ end.to raise_error(Moxml::ParseError)
41
+ end
42
+ 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.134
4
+ version: 0.5.136
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -450,6 +450,7 @@ files:
450
450
  - spec/moxml/adapter/headed_ox_spec.rb
451
451
  - spec/moxml/adapter/leptris_adoption_spec.rb
452
452
  - spec/moxml/adapter/leptris_append_gc_spec.rb
453
+ - spec/moxml/adapter/leptris_attribute_snapshot_spec.rb
453
454
  - spec/moxml/adapter/leptris_binding_cap_spec.rb
454
455
  - spec/moxml/adapter/leptris_doc_parts_spec.rb
455
456
  - spec/moxml/adapter/leptris_parse_skips_spec.rb
@@ -457,6 +458,7 @@ files:
457
458
  - spec/moxml/adapter/leptris_sax_dup_attr_spec.rb
458
459
  - spec/moxml/adapter/leptris_sax_records_spec.rb
459
460
  - spec/moxml/adapter/leptris_spec.rb
461
+ - spec/moxml/adapter/leptris_strict_mismatch_spec.rb
460
462
  - spec/moxml/adapter/leptris_xpath_identity_spec.rb
461
463
  - spec/moxml/adapter/libxml_internals_spec.rb
462
464
  - spec/moxml/adapter/libxml_spec.rb