moxml 0.1.8 → 0.1.10

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +22 -39
  3. data/README.adoc +51 -20
  4. data/docs/_config.yml +3 -3
  5. data/docs/_guides/index.adoc +15 -7
  6. data/docs/_guides/modifying-xml.adoc +0 -1
  7. data/docs/_guides/node-api-consistency.adoc +572 -0
  8. data/docs/_guides/parsing-xml.adoc +0 -1
  9. data/docs/_guides/xml-declaration.adoc +450 -0
  10. data/docs/_pages/adapter-compatibility.adoc +1 -1
  11. data/docs/_pages/adapters/headed-ox.adoc +9 -9
  12. data/docs/_pages/adapters/index.adoc +0 -1
  13. data/docs/_pages/adapters/libxml.adoc +1 -2
  14. data/docs/_pages/adapters/nokogiri.adoc +1 -2
  15. data/docs/_pages/adapters/oga.adoc +1 -2
  16. data/docs/_pages/adapters/ox.adoc +2 -1
  17. data/docs/_pages/adapters/rexml.adoc +2 -3
  18. data/docs/_pages/best-practices.adoc +0 -1
  19. data/docs/_pages/compatibility.adoc +0 -1
  20. data/docs/_pages/configuration.adoc +0 -1
  21. data/docs/_pages/error-handling.adoc +0 -1
  22. data/docs/_pages/headed-ox-limitations.adoc +16 -0
  23. data/docs/_pages/installation.adoc +0 -1
  24. data/docs/_pages/node-api-reference.adoc +93 -4
  25. data/docs/_pages/performance.adoc +0 -1
  26. data/docs/_pages/quick-start.adoc +0 -1
  27. data/docs/_pages/thread-safety.adoc +0 -1
  28. data/docs/_references/document-api.adoc +0 -1
  29. data/docs/_tutorials/basic-usage.adoc +0 -1
  30. data/docs/_tutorials/builder-pattern.adoc +0 -1
  31. data/docs/_tutorials/namespace-handling.adoc +0 -1
  32. data/docs/_tutorials/xpath-queries.adoc +0 -1
  33. data/lib/moxml/adapter/customized_rexml/formatter.rb +2 -2
  34. data/lib/moxml/adapter/libxml.rb +34 -4
  35. data/lib/moxml/adapter/nokogiri.rb +50 -2
  36. data/lib/moxml/adapter/oga.rb +80 -3
  37. data/lib/moxml/adapter/ox.rb +70 -7
  38. data/lib/moxml/adapter/rexml.rb +45 -10
  39. data/lib/moxml/attribute.rb +6 -0
  40. data/lib/moxml/context.rb +18 -1
  41. data/lib/moxml/declaration.rb +9 -0
  42. data/lib/moxml/doctype.rb +33 -0
  43. data/lib/moxml/document.rb +14 -0
  44. data/lib/moxml/document_builder.rb +7 -0
  45. data/lib/moxml/element.rb +6 -0
  46. data/lib/moxml/error.rb +5 -5
  47. data/lib/moxml/node.rb +73 -1
  48. data/lib/moxml/processing_instruction.rb +6 -0
  49. data/lib/moxml/version.rb +1 -1
  50. data/lib/moxml/xpath/compiler.rb +2 -0
  51. data/lib/moxml/xpath/errors.rb +1 -1
  52. data/spec/integration/shared_examples/node_wrappers/declaration_behavior.rb +0 -3
  53. data/spec/moxml/declaration_preservation_spec.rb +217 -0
  54. data/spec/moxml/doctype_spec.rb +19 -3
  55. data/spec/performance/memory_usage_spec.rb +3 -2
  56. metadata +5 -3
  57. data/.ruby-version +0 -1
@@ -348,6 +348,24 @@ module Moxml
348
348
  end
349
349
 
350
350
  def add_child(element, child)
351
+ # Special handling for declarations on Ox documents
352
+ if element.is_a?(::Ox::Document) && child.is_a?(::Ox::Instruct) && child.target == "xml"
353
+ # Transfer declaration attributes to document
354
+ element.attributes ||= {}
355
+ if child.attributes["version"]
356
+ element.attributes[:version] =
357
+ child.attributes["version"]
358
+ end
359
+ if child.attributes["encoding"]
360
+ element.attributes[:encoding] =
361
+ child.attributes["encoding"]
362
+ end
363
+ if child.attributes["standalone"]
364
+ element.attributes[:standalone] =
365
+ child.attributes["standalone"]
366
+ end
367
+ end
368
+
351
369
  child.parent = element if child.respond_to?(:parent)
352
370
  element.nodes ||= []
353
371
  element.nodes << child
@@ -380,6 +398,15 @@ module Moxml
380
398
 
381
399
  return unless parent(node)
382
400
 
401
+ # Special handling for declarations on Ox documents
402
+ if parent(node).is_a?(::Ox::Document) && node.is_a?(::Ox::Instruct) && node.target == "xml"
403
+ # Clear declaration attributes from document
404
+ doc = parent(node)
405
+ doc.attributes&.delete(:version)
406
+ doc.attributes&.delete(:encoding)
407
+ doc.attributes&.delete(:standalone)
408
+ end
409
+
383
410
  parent(node).nodes.delete(unpatch_node(node))
384
411
  end
385
412
 
@@ -483,6 +510,31 @@ module Moxml
483
510
  end.values
484
511
  end
485
512
 
513
+ # Doctype accessor methods
514
+ # Ox stores DOCTYPE as a string, so we parse it
515
+ def doctype_name(native)
516
+ # Parse: "name PUBLIC \"external_id\" \"system_id\"" or "name SYSTEM \"system_id\""
517
+ value = native.value.to_s.strip
518
+ # Extract the first word (the name)
519
+ value.split(/\s+/).first
520
+ end
521
+
522
+ def doctype_external_id(native)
523
+ value = native.value.to_s
524
+ # Match PUBLIC "external_id"
525
+ match = value.match(/PUBLIC\s+"([^"]*)"/)
526
+ match ? match[1] : nil
527
+ end
528
+
529
+ def doctype_system_id(native)
530
+ value = native.value.to_s
531
+ # Match the last quoted string (system_id)
532
+ # For PUBLIC: "name PUBLIC \"external_id\" \"system_id\""
533
+ # For SYSTEM: "name SYSTEM \"system_id\""
534
+ matches = value.scan(/"([^"]*)"/)
535
+ matches.last&.first
536
+ end
537
+
486
538
  def xpath(node, expression, namespaces = {})
487
539
  # Translate common XPath patterns to Ox locate() syntax
488
540
  locate_expr = translate_xpath_to_locate(expression, namespaces)
@@ -524,13 +576,24 @@ module Moxml
524
576
  def serialize(node, options = {})
525
577
  output = ""
526
578
  if node.is_a?(::Ox::Document)
527
- # add declaration
528
- version = node[:version] || "1.0"
529
- encoding = options[:encoding] || node[:encoding]
530
- standalone = node[:standalone]
531
-
532
- decl = create_native_declaration(version, encoding, standalone)
533
- output = ::Ox.dump(::Ox::Document.new << decl).strip
579
+ # Check if we should include declaration
580
+ # Priority: explicit option > document attributes
581
+ should_include_decl = if options.key?(:no_declaration)
582
+ !options[:no_declaration]
583
+ else
584
+ # Check if document has declaration attributes
585
+ node[:version] || node[:encoding] || node[:standalone]
586
+ end
587
+
588
+ # Only add declaration if should_include_decl is true
589
+ if should_include_decl
590
+ version = node[:version] || "1.0"
591
+ encoding = options[:encoding] || node[:encoding]
592
+ standalone = node[:standalone]
593
+
594
+ decl = create_native_declaration(version, encoding, standalone)
595
+ output = ::Ox.dump(::Ox::Document.new << decl).strip
596
+ end
534
597
  end
535
598
 
536
599
  ox_options = {
@@ -23,6 +23,7 @@ module Moxml
23
23
  end
24
24
  create_document
25
25
  end
26
+
26
27
  DocumentBuilder.new(Context.new(:rexml)).build(native_doc)
27
28
  end
28
29
 
@@ -255,6 +256,12 @@ module Moxml
255
256
  end
256
257
 
257
258
  def add_child(element, child)
259
+ # Special handling for declarations on REXML documents
260
+ if element.is_a?(::REXML::Document) && child.is_a?(::REXML::XMLDecl)
261
+ # Set document's xml_decl directly
262
+ element.instance_variable_set(:@xml_declaration, child)
263
+ end
264
+
258
265
  case child
259
266
  when String
260
267
  element.add_text(child)
@@ -279,6 +286,12 @@ module Moxml
279
286
  end
280
287
 
281
288
  def remove(node)
289
+ # Special handling for declarations on REXML documents
290
+ if node.is_a?(::REXML::XMLDecl) && node.parent.is_a?(::REXML::Document)
291
+ # Clear document's xml_declaration when removing declaration
292
+ node.parent.instance_variable_set(:@xml_declaration, nil)
293
+ end
294
+
282
295
  node.remove
283
296
  end
284
297
 
@@ -413,6 +426,19 @@ module Moxml
413
426
  end
414
427
  end
415
428
 
429
+ # Doctype accessor methods
430
+ def doctype_name(native)
431
+ native.name
432
+ end
433
+
434
+ def doctype_external_id(native)
435
+ native.public
436
+ end
437
+
438
+ def doctype_system_id(native)
439
+ native.system
440
+ end
441
+
416
442
  # not used at the moment
417
443
  # but may be useful when the xpath is upgraded to work with namespaces
418
444
  def prepare_xpath_namespaces(node)
@@ -453,16 +479,25 @@ module Moxml
453
479
  output = +""
454
480
 
455
481
  if node.is_a?(::REXML::Document)
456
- # Always include XML declaration
457
- decl = node.xml_decl || ::REXML::XMLDecl.new("1.0",
458
- options[:encoding] || "UTF-8")
459
- decl.encoding = options[:encoding] if options[:encoding]
460
- output << "<?xml"
461
- output << %( version="#{decl.version}") if decl.version
462
- output << %( encoding="#{decl.encoding}") if decl.encoding
463
- output << %( standalone="#{decl.standalone}") if decl.standalone
464
- output << "?>"
465
- # output << "\n"
482
+ # Check if we should include declaration
483
+ # Priority: explicit option > check if document has xml_decl
484
+ should_include_decl = if options.key?(:no_declaration)
485
+ !options[:no_declaration]
486
+ else
487
+ # Include declaration only if document has xml_decl
488
+ !node.xml_decl.nil?
489
+ end
490
+
491
+ # Include XML declaration only if should_include_decl and xml_decl exists
492
+ if should_include_decl && node.xml_decl
493
+ decl = node.xml_decl
494
+ decl.encoding = options[:encoding] if options[:encoding]
495
+ output << "<?xml"
496
+ output << %( version="#{decl.version}") if decl.version
497
+ output << %( encoding="#{decl.encoding}") if decl.encoding
498
+ output << %( standalone="#{decl.standalone}") if decl.standalone
499
+ output << "?>"
500
+ end
466
501
 
467
502
  # output << "\n"
468
503
  node.doctype&.write(output)
@@ -10,6 +10,12 @@ module Moxml
10
10
  adapter.set_attribute_name(@native, new_name)
11
11
  end
12
12
 
13
+ # Returns the primary identifier for this attribute (its name)
14
+ # @return [String] the attribute name
15
+ def identifier
16
+ name
17
+ end
18
+
13
19
  def value
14
20
  @native.value
15
21
  end
data/lib/moxml/context.rb CHANGED
@@ -13,7 +13,24 @@ module Moxml
13
13
  end
14
14
 
15
15
  def parse(xml, options = {})
16
- config.adapter.parse(xml, default_options.merge(options))
16
+ # Detect if input has XML declaration
17
+ xml_string = if xml.respond_to?(:read)
18
+ xml.read.tap do
19
+ xml.rewind if xml.respond_to?(:rewind)
20
+ end
21
+ else
22
+ xml.to_s
23
+ end
24
+ has_declaration = xml_string.strip.start_with?("<?xml")
25
+
26
+ # Parse with adapter (without declaration info - adapters don't need it)
27
+ parsed_options = default_options.merge(options)
28
+ doc = config.adapter.parse(xml_string, parsed_options)
29
+
30
+ # Set declaration flag on Document wrapper (proper OOP)
31
+ doc.has_xml_declaration = has_declaration if doc.is_a?(Document)
32
+
33
+ doc
17
34
  end
18
35
 
19
36
  # Parse XML using SAX (event-driven) parsing
@@ -33,6 +33,15 @@ module Moxml
33
33
  adapter.set_declaration_attribute(@native, "standalone", new_standalone)
34
34
  end
35
35
 
36
+ def remove
37
+ # Mark document as having no declaration when declaration is removed
38
+ # Store on native document so all wrappers see it
39
+ native_doc = adapter.document(@native)
40
+ native_doc&.instance_variable_set(:@moxml_has_declaration, false)
41
+
42
+ super
43
+ end
44
+
36
45
  def declaration?
37
46
  true
38
47
  end
data/lib/moxml/doctype.rb CHANGED
@@ -1,17 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
+ # Represents an XML DOCTYPE declaration
5
+ #
6
+ # @note Doctype accessor methods are not fully implemented across all adapters.
7
+ # The availability of #name, #external_id, and #system_id depends on whether
8
+ # the specific adapter implements the corresponding adapter methods:
9
+ # - adapter.doctype_name(native)
10
+ # - adapter.doctype_external_id(native)
11
+ # - adapter.doctype_system_id(native)
12
+ #
13
+ # Most adapters do not currently implement these methods. If you need DOCTYPE
14
+ # information, consider using adapter-specific methods or parsing the serialized
15
+ # XML manually.
4
16
  class Doctype < Node
17
+ # Returns the DOCTYPE name (root element name)
18
+ #
19
+ # @return [String, nil] the DOCTYPE name
20
+ # @raise [NotImplementedError] if the adapter doesn't implement doctype_name
5
21
  def name
6
22
  adapter.doctype_name(@native)
7
23
  end
8
24
 
25
+ # Returns the DOCTYPE external ID
26
+ #
27
+ # @return [String, nil] the external ID
28
+ # @raise [NotImplementedError] if the adapter doesn't implement doctype_external_id
9
29
  def external_id
10
30
  adapter.doctype_external_id(@native)
11
31
  end
12
32
 
33
+ # Returns the DOCTYPE system ID
34
+ #
35
+ # @return [String, nil] the system ID
36
+ # @raise [NotImplementedError] if the adapter doesn't implement doctype_system_id
13
37
  def system_id
14
38
  adapter.doctype_system_id(@native)
15
39
  end
40
+
41
+ # Returns the primary identifier for this doctype
42
+ # Since DOCTYPE information is not reliably available across adapters,
43
+ # this returns nil.
44
+ #
45
+ # @return [nil]
46
+ def identifier
47
+ name
48
+ end
16
49
  end
17
50
  end
@@ -12,6 +12,17 @@ require_relative "doctype"
12
12
 
13
13
  module Moxml
14
14
  class Document < Node
15
+ attr_accessor :has_xml_declaration
16
+
17
+ def initialize(native, context)
18
+ super
19
+ @has_xml_declaration = false
20
+ end
21
+
22
+ def document
23
+ self
24
+ end
25
+
15
26
  def root=(element)
16
27
  adapter.set_root(@native, element.native)
17
28
  end
@@ -61,6 +72,9 @@ module Moxml
61
72
  node = prepare_node(node)
62
73
 
63
74
  if node.is_a?(Declaration)
75
+ # Mark that document now has a declaration
76
+ @has_xml_declaration = true
77
+
64
78
  if children.empty?
65
79
  adapter.add_child(@native, node.native)
66
80
  else
@@ -12,6 +12,13 @@ module Moxml
12
12
  def build(native_doc)
13
13
  @current_doc = context.create_document(native_doc)
14
14
 
15
+ # Transfer has_declaration flag if present
16
+ if native_doc.respond_to?(:instance_variable_get) &&
17
+ native_doc.instance_variable_defined?(:@moxml_has_declaration)
18
+ has_declaration = native_doc.instance_variable_get(:@moxml_has_declaration)
19
+ @current_doc.has_xml_declaration = has_declaration
20
+ end
21
+
15
22
  # Transfer DOCTYPE from parsed document if it exists
16
23
  if native_doc.respond_to?(:instance_variable_get) &&
17
24
  native_doc.instance_variable_defined?(:@moxml_doctype)
data/lib/moxml/element.rb CHANGED
@@ -13,6 +13,12 @@ module Moxml
13
13
  adapter.set_node_name(@native, value)
14
14
  end
15
15
 
16
+ # Returns the primary identifier for this element (its tag name)
17
+ # @return [String] the element name
18
+ def identifier
19
+ name
20
+ end
21
+
16
22
  # Returns the expanded name including namespace prefix
17
23
  def expanded_name
18
24
  if namespace_prefix && !namespace_prefix.empty?
data/lib/moxml/error.rb CHANGED
@@ -40,7 +40,7 @@ module Moxml
40
40
  msg = super
41
41
  msg += "\n Expression: #{@expression}" if @expression
42
42
  msg += "\n Adapter: #{@adapter}" if @adapter
43
- msg += "\n Node: <#{@node.name}>" if @node.respond_to?(:name)
43
+ msg += "\n Node: <#{@node.name}>" if @node.is_a?(Element) || @node.is_a?(Attribute)
44
44
  msg += "\n Hint: Verify XPath syntax and ensure the adapter supports the expression"
45
45
  msg
46
46
  end
@@ -60,9 +60,9 @@ module Moxml
60
60
  def to_s
61
61
  msg = super
62
62
  # Only add extra details if any were provided
63
- has_details = @node.respond_to?(:name) || @constraint || @value
63
+ has_details = (@node.is_a?(Element) || @node.is_a?(Attribute)) || @constraint || @value
64
64
  if has_details
65
- msg += "\n Node: <#{@node.name}>" if @node.respond_to?(:name)
65
+ msg += "\n Node: <#{@node.name}>" if @node.is_a?(Element) || @node.is_a?(Attribute)
66
66
  msg += "\n Constraint: #{@constraint}" if @constraint
67
67
  msg += "\n Value: #{@value.inspect}" if @value
68
68
  msg += "\n Hint: Ensure the value meets XML specification requirements"
@@ -119,7 +119,7 @@ module Moxml
119
119
 
120
120
  def to_s
121
121
  msg = super
122
- msg += "\n Node: <#{@node.name}>" if @node.respond_to?(:name)
122
+ msg += "\n Node: <#{@node.name}>" if @node.is_a?(Element) || @node.is_a?(Attribute)
123
123
  msg += "\n Adapter: #{@adapter}" if @adapter
124
124
  msg += "\n Format: #{@format}" if @format
125
125
  msg += "\n Hint: Check that the node structure is valid for serialization"
@@ -160,7 +160,7 @@ module Moxml
160
160
  def to_s
161
161
  msg = super
162
162
  msg += "\n Attribute: #{@attribute_name}" if @attribute_name
163
- msg += "\n Element: <#{@element.name}>" if @element.respond_to?(:name)
163
+ msg += "\n Element: <#{@element.name}>" if @element.is_a?(Element)
164
164
  msg += "\n Value: #{@value.inspect}" if @value
165
165
  msg += "\n Hint: Verify attribute name follows XML naming rules"
166
166
  msg
data/lib/moxml/node.rb CHANGED
@@ -73,7 +73,13 @@ module Moxml
73
73
  end
74
74
 
75
75
  def to_xml(options = {})
76
- adapter.serialize(@native, default_options.merge(options))
76
+ # Determine if we should include XML declaration
77
+ # For Document nodes: check native then wrapper, unless explicitly overridden
78
+ # For other nodes: default to no declaration unless explicitly set
79
+ serialize_options = default_options.merge(options)
80
+ serialize_options[:no_declaration] = !should_include_declaration?(options)
81
+
82
+ adapter.serialize(@native, serialize_options)
77
83
  end
78
84
 
79
85
  def xpath(expression, namespaces = {})
@@ -180,6 +186,18 @@ module Moxml
180
186
  end
181
187
  end
182
188
 
189
+ # Returns the primary identifier for this node type
190
+ # For Element: the tag name
191
+ # For Attribute: the attribute name
192
+ # For ProcessingInstruction: the target
193
+ # For content nodes (Text, Comment, Cdata, Declaration): nil (no identifier)
194
+ # For Doctype: nil (not fully implemented across adapters)
195
+ #
196
+ # @return [String, nil] the node's primary identifier or nil
197
+ def identifier
198
+ nil
199
+ end
200
+
183
201
  def self.wrap(node, context)
184
202
  return nil if node.nil?
185
203
 
@@ -235,5 +253,59 @@ module Moxml
235
253
  expand_empty: true,
236
254
  }
237
255
  end
256
+
257
+ def should_include_declaration?(options)
258
+ return options[:declaration] if options.key?(:declaration)
259
+ return options.fetch(:declaration, false) unless is_a?(Document)
260
+
261
+ # For Document nodes, check both wrapper flag and native state
262
+ # Wrapper flag is set by Context.parse for parsed documents
263
+ # Native state reflects programmatic changes (e.g., add/remove)
264
+
265
+ adapter_name = adapter.to_s.split("::").last
266
+
267
+ case adapter_name
268
+ when "Nokogiri"
269
+ # Nokogiri: if @xml_decl is explicitly set, use that state
270
+ # Otherwise, trust wrapper flag (for parsed documents)
271
+ if native.respond_to?(:instance_variable_defined?) &&
272
+ native.instance_variable_defined?(:@xml_decl)
273
+ # Explicitly set (programmatically added) - check if nil
274
+ !native.instance_variable_get(:@xml_decl).nil?
275
+ else
276
+ # Not set (parsed document) - trust wrapper flag
277
+ has_xml_declaration
278
+ end
279
+ when "Rexml"
280
+ # REXML: check @xml_declaration instance variable
281
+ # If not defined (parsed doc), trust wrapper flag
282
+ if native.respond_to?(:instance_variable_defined?) &&
283
+ native.instance_variable_defined?(:@xml_declaration)
284
+ # Explicitly set - check if nil
285
+ !native.instance_variable_get(:@xml_declaration).nil?
286
+ else
287
+ # Not set (parsed document) - trust wrapper flag
288
+ has_xml_declaration
289
+ end
290
+ when "Oga"
291
+ native.respond_to?(:xml_declaration) && !native.xml_declaration.nil?
292
+ when "Ox", "HeadedOx"
293
+ # Ox stores declaration in document attributes
294
+ native[:version] || native[:encoding] || native[:standalone]
295
+ when "Libxml"
296
+ # LibXML stores declaration wrapper as instance variable
297
+ if native.respond_to?(:instance_variable_defined?) &&
298
+ native.instance_variable_defined?(:@moxml_declaration)
299
+ # Explicitly set - check if nil
300
+ !native.instance_variable_get(:@moxml_declaration).nil?
301
+ else
302
+ # Not set - trust wrapper flag
303
+ has_xml_declaration
304
+ end
305
+ else
306
+ # Fallback - trust wrapper flag
307
+ has_xml_declaration
308
+ end
309
+ end
238
310
  end
239
311
  end
@@ -10,6 +10,12 @@ module Moxml
10
10
  adapter.set_node_name(@native, new_target.to_s)
11
11
  end
12
12
 
13
+ # Returns the primary identifier for this processing instruction (its target)
14
+ # @return [String] the PI target
15
+ def identifier
16
+ target
17
+ end
18
+
13
19
  def content
14
20
  adapter.processing_instruction_content(@native)
15
21
  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.1.8"
4
+ VERSION = "0.1.10"
5
5
  end
@@ -976,8 +976,10 @@ module Moxml
976
976
  conversions << conversion.to_string(arg_var)
977
977
  end
978
978
 
979
+ # rubocop:disable Style/RedundantSum, Performance/Sum
979
980
  concatted = assigns.inject(:followed_by)
980
981
  .followed_by(conversions.inject(:+))
982
+ # rubocop:enable Style/RedundantSum, Performance/Sum
981
983
 
982
984
  block_given? ? concatted.empty?.if_false { yield concatted } : concatted
983
985
  end
@@ -36,7 +36,7 @@ module Moxml
36
36
 
37
37
  def to_s
38
38
  msg = super
39
- msg += "\n Context node: <#{@context_node.name}>" if @context_node.respond_to?(:name)
39
+ msg += "\n Context node: <#{@context_node.name}>" if @context_node.is_a?(Moxml::Element) || @context_node.is_a?(Moxml::Attribute)
40
40
  msg += "\n Step: #{@step}" if @step
41
41
  msg
42
42
  end
@@ -98,9 +98,6 @@ RSpec.shared_examples "Moxml::Declaration" do
98
98
  end
99
99
 
100
100
  it "removes from document" do
101
- if Moxml.new.config.adapter.name.match?(/Nokogiri|Rexml|Ox/)
102
- pending("The document contains a default declaration")
103
- end
104
101
  doc.add_child(declaration)
105
102
  declaration.remove
106
103
  expect(doc.to_xml).not_to include("<?xml")