moxml 0.1.3 → 0.1.4

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.
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # This test works directly with native nodes which looks quite strange
4
+ # A better way is to run it through Moxml wrappers
3
5
  RSpec.shared_examples "xml adapter" do
4
6
  let(:xml) do
5
7
  <<~XML
@@ -80,7 +82,7 @@ RSpec.shared_examples "xml adapter" do
80
82
  expect(children.length).to eq(3)
81
83
  end
82
84
 
83
- it "gets siblings", skip: "Oga includes text nodes into siblings" do
85
+ it "gets siblings" do
84
86
  children = described_class.children(root)
85
87
  first = children[0]
86
88
  second = children[1]
@@ -97,13 +99,16 @@ RSpec.shared_examples "xml adapter" do
97
99
 
98
100
  it "adds text child" do
99
101
  described_class.add_child(root, "text")
100
- expect(described_class.children(root).last.text).to eq("text")
102
+ # a workaround for Rexml until we convert tests to work with Moxml wrappers
103
+ last_child = described_class.children(root).last
104
+ last_text = last_child.respond_to?(:text) ? last_child.text : last_child.to_s
105
+ expect(last_text).to eq("text")
101
106
  end
102
107
  end
103
108
 
104
109
  describe "attributes" do
105
- let(:doc) { described_class.parse(xml) }
106
- let(:element) { described_class.children(described_class.root(doc.native)).first }
110
+ let(:doc) { described_class.parse(xml).native }
111
+ let(:element) { described_class.children(described_class.root(doc)).first }
107
112
 
108
113
  it "gets attributes" do
109
114
  attrs = described_class.attributes(element)
@@ -123,7 +128,9 @@ RSpec.shared_examples "xml adapter" do
123
128
 
124
129
  it "handles special characters in attributes" do
125
130
  described_class.set_attribute(element, "special", '< > & " \'')
126
- value = described_class.get_attribute(element, "special")&.to_xml
131
+ # a workaround for Rexml until we convert tests to work with Moxml wrappers
132
+ attr = described_class.get_attribute(element, "special")
133
+ value = attr.respond_to?(:to_xml) ? attr&.to_xml : attr.to_s
127
134
  expect(value).to match(/&lt; &gt; &amp; (&quot;|") ('|&apos;)/)
128
135
  end
129
136
  end
@@ -156,7 +163,10 @@ RSpec.shared_examples "xml adapter" do
156
163
  expect(result).to include("</root>")
157
164
  end
158
165
 
159
- it "respects indentation settings", skip: "Indent cannot be negative, and zero indent doesn't remove newlines" do
166
+ it "respects indentation settings" do
167
+ pending("Oga does not support indentation settings") if described_class.name.include?("Oga")
168
+ pending("Postponed for Rexml till better times") if described_class.name.include?("Rexml")
169
+
160
170
  unindented = described_class.serialize(doc, indent: 0)
161
171
  indented = described_class.serialize(doc, indent: 2)
162
172
 
@@ -176,7 +186,7 @@ RSpec.shared_examples "xml adapter" do
176
186
  end
177
187
 
178
188
  describe "xpath" do
179
- let(:doc) { described_class.parse(xml) }
189
+ let(:doc) { described_class.parse(xml).native }
180
190
 
181
191
  it "finds nodes by xpath" do
182
192
  nodes = described_class.xpath(doc, "//xmlns:child")
@@ -188,4 +198,156 @@ RSpec.shared_examples "xml adapter" do
188
198
  expect(described_class.get_attribute_value(node, "id")).to eq("1")
189
199
  end
190
200
  end
201
+
202
+ describe "namespace handling" do
203
+ context "case 1" do
204
+ let(:xml) do
205
+ <<~XML
206
+ <?xml version="1.0" encoding="UTF-8"?>
207
+ <svg xmlns="http://www.w3.org/2000/svg"
208
+ xmlns:xlink="http://www.w3.org/1999/xlink"
209
+ width="100" height="100">
210
+ <defs>
211
+ <circle id="myCircle" cx="50" cy="50" r="40"/>
212
+ </defs>
213
+ <use xlink:href="#myCircle" fill="red"/>
214
+ <text x="50" y="50" text-anchor="middle">SVG</text>
215
+ </svg>
216
+ XML
217
+ end
218
+
219
+ it "preserves and correctly handles multiple namespaces" do
220
+ pending("Rexml does not respect ZPath namespaces") if described_class.name.include?("Rexml")
221
+ # Parse original XML
222
+ doc = described_class.parse(xml).native
223
+
224
+ # Test namespace preservation in serialization
225
+ result = described_class.serialize(doc)
226
+ expect(result).to include('xmlns="http://www.w3.org/2000/svg"')
227
+ expect(result).to include('xmlns:xlink="http://www.w3.org/1999/xlink"')
228
+
229
+ # Test xpath with namespaces
230
+ namespaces = {
231
+ "svg" => "http://www.w3.org/2000/svg",
232
+ "xlink" => "http://www.w3.org/1999/xlink"
233
+ }
234
+
235
+ # Find use element and verify xlink:href attribute
236
+ use_elem = described_class.at_xpath(doc, "//svg:use", namespaces)
237
+ expect(use_elem).not_to be_nil
238
+ expect(described_class.get_attribute_value(use_elem, "xlink:href")).to eq("#myCircle")
239
+
240
+ # Verify circle element exists in defs
241
+ circle = described_class.at_xpath(doc, "//svg:defs/svg:circle", namespaces)
242
+ expect(circle).not_to be_nil
243
+ expect(described_class.get_attribute_value(circle, "id")).to eq("myCircle")
244
+
245
+ # Test default SVG namespace
246
+ text = described_class.at_xpath(doc, "//svg:text", namespaces)
247
+ expect(described_class.text_content(text)).to eq("SVG")
248
+ end
249
+ end
250
+
251
+ context "case 2" do
252
+ let(:xml) do
253
+ <<~XML
254
+ <?xml version="1.0" encoding="UTF-8"?>
255
+ <rss version="2.0"#{" "}
256
+ xmlns:atom="http://www.w3.org/2005/Atom"
257
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
258
+ xmlns:content="http://purl.org/rss/1.0/modules/content/">
259
+ <channel>
260
+ <title>Example RSS Feed</title>
261
+ <atom:link href="http://example.com/feed" rel="self"/>
262
+ <item>
263
+ <title>Example Post</title>
264
+ <dc:creator>John Doe</dc:creator>
265
+ <content:encoded><![CDATA[<p>Post content</p>]]></content:encoded>
266
+ </item>
267
+ </channel>
268
+ </rss>
269
+ XML
270
+ end
271
+
272
+ it "preserves and correctly handles multiple namespaces" do
273
+ # Parse original XML
274
+ doc = described_class.parse(xml).native
275
+
276
+ # Test namespace preservation in serialization
277
+ result = described_class.serialize(doc)
278
+ expect(result).to include('xmlns:atom="http://www.w3.org/2005/Atom"')
279
+ expect(result).to include('xmlns:dc="http://purl.org/dc/elements/1.1/"')
280
+ expect(result).to include('xmlns:content="http://purl.org/rss/1.0/modules/content/"')
281
+
282
+ # Test xpath with namespaces
283
+ namespaces = {
284
+ "atom" => "http://www.w3.org/2005/Atom",
285
+ "dc" => "http://purl.org/dc/elements/1.1/",
286
+ "content" => "http://purl.org/rss/1.0/modules/content/"
287
+ }
288
+
289
+ # Find creator using namespaced xpath
290
+ creator = described_class.at_xpath(doc, "//dc:creator", namespaces)
291
+ expect(described_class.text_content(creator)).to eq("John Doe")
292
+
293
+ # Verify atom:link exists
294
+ link = described_class.at_xpath(doc, "//atom:link", namespaces)
295
+ expect(link).not_to be_nil
296
+ expect(described_class.get_attribute_value(link, "href")).to eq("http://example.com/feed")
297
+
298
+ # Verify CDATA in content:encoded
299
+ content = described_class.at_xpath(doc, "//content:encoded", namespaces)
300
+ expect(described_class.text_content(content)).to eq("<p>Post content</p>")
301
+ end
302
+ end
303
+
304
+ context "case 3" do
305
+ let(:xml) do
306
+ <<~XML
307
+ <?xml version="1.0" encoding="UTF-8"?>
308
+ <soap:Envelope#{" "}
309
+ xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
310
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
311
+ xmlns:ns="urn:example:namespace">
312
+ <soap:Header>
313
+ <ns:SessionId>12345</ns:SessionId>
314
+ </soap:Header>
315
+ <soap:Body>
316
+ <ns:GetUserRequest>
317
+ <ns:UserId xsi:type="xsi:string">user123</ns:UserId>
318
+ </ns:GetUserRequest>
319
+ </soap:Body>
320
+ </soap:Envelope>
321
+ XML
322
+ end
323
+
324
+ it "preserves and correctly handles multiple namespaces" do
325
+ # Parse original XML
326
+ doc = described_class.parse(xml).native
327
+
328
+ # Test namespace preservation in serialization
329
+ result = described_class.serialize(doc)
330
+ expect(result).to include('xmlns:soap="http://www.w3.org/2003/05/soap-envelope"')
331
+ expect(result).to include('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
332
+ expect(result).to include('xmlns:ns="urn:example:namespace"')
333
+
334
+ # Test xpath with namespaces
335
+ namespaces = {
336
+ "soap" => "http://www.w3.org/2003/05/soap-envelope",
337
+ "ns" => "urn:example:namespace"
338
+ }
339
+
340
+ # Find user ID using namespaced xpath
341
+ user_id = described_class.at_xpath(doc, "//ns:UserId", namespaces)
342
+ expect(described_class.text_content(user_id)).to eq("user123")
343
+
344
+ # Verify soap:Body exists
345
+ body = described_class.at_xpath(doc, "//soap:Body", namespaces)
346
+ expect(body).not_to be_nil
347
+
348
+ # Verify attribute with namespace
349
+ expect(described_class.get_attribute_value(user_id, "xsi:type")).to eq("xsi:string")
350
+ end
351
+ end
352
+ end
191
353
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-26 00:00:00.000000000 Z
11
+ date: 2025-05-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'Moxml is a unified XML manipulation library that provides a common API.
14
14
 
@@ -27,6 +27,7 @@ files:
27
27
  - ".rubocop_todo.yml"
28
28
  - ".ruby-version"
29
29
  - Gemfile
30
+ - LICENSE.md
30
31
  - README.adoc
31
32
  - Rakefile
32
33
  - bin/console
@@ -36,9 +37,11 @@ files:
36
37
  - lib/moxml/adapter/base.rb
37
38
  - lib/moxml/adapter/customized_oga/xml_declaration.rb
38
39
  - lib/moxml/adapter/customized_oga/xml_generator.rb
40
+ - lib/moxml/adapter/customized_rexml/formatter.rb
39
41
  - lib/moxml/adapter/nokogiri.rb
40
42
  - lib/moxml/adapter/oga.rb
41
43
  - lib/moxml/adapter/ox.rb
44
+ - lib/moxml/adapter/rexml.rb
42
45
  - lib/moxml/attribute.rb
43
46
  - lib/moxml/builder.rb
44
47
  - lib/moxml/cdata.rb
@@ -64,6 +67,7 @@ files:
64
67
  - spec/moxml/adapter/nokogiri_spec.rb
65
68
  - spec/moxml/adapter/oga_spec.rb
66
69
  - spec/moxml/adapter/ox_spec.rb
70
+ - spec/moxml/adapter/rexml_spec.rb
67
71
  - spec/moxml/all_with_adapters_spec.rb
68
72
  - spec/moxml/config_spec.rb
69
73
  - spec/moxml/error_spec.rb
@@ -116,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
120
  - !ruby/object:Gem::Version
117
121
  version: '0'
118
122
  requirements: []
119
- rubygems_version: 3.3.27
123
+ rubygems_version: 3.5.22
120
124
  signing_key:
121
125
  specification_version: 4
122
126
  summary: Unified XML manipulation library