lutaml-model 0.3.28 → 0.3.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,8 @@
1
1
  require "spec_helper"
2
+
3
+ require "lutaml/model/xml_adapter/ox_adapter"
4
+ require "lutaml/model/xml_adapter/oga_adapter"
5
+
2
6
  require_relative "../../../lib/lutaml/model/xml_mapping"
3
7
  require_relative "../../../lib/lutaml/model/xml_mapping_rule"
4
8
 
@@ -177,8 +181,28 @@ module XmlMapping
177
181
  end
178
182
  end
179
183
 
184
+ class MapAllWithCustomMethod < Lutaml::Model::Serializable
185
+ attribute :all_content, :string
186
+
187
+ xml do
188
+ root "MapAllWithCustomMethod"
189
+
190
+ map_all to: :all_content, with: { to: :content_to_xml, from: :content_from_xml }
191
+ end
192
+
193
+ def content_to_xml(model, parent, doc)
194
+ content = model.all_content.sub(/^<div>/, "").sub(/<\/div>$/, "")
195
+ doc.add_xml_fragment(parent, content)
196
+ end
197
+
198
+ def content_from_xml(model, value)
199
+ model.all_content = "<div>#{value}</div>"
200
+ end
201
+ end
202
+
180
203
  class WithMapAll < Lutaml::Model::Serializable
181
204
  attribute :all_content, :string
205
+ attribute :attr, :string
182
206
 
183
207
  xml do
184
208
  root "WithMapAll"
@@ -258,674 +282,791 @@ module XmlMapping
258
282
  end
259
283
 
260
284
  RSpec.describe Lutaml::Model::XmlMapping do
261
- let(:mapping) { described_class.new }
285
+ shared_examples "having XML Mappings" do |adapter_class|
286
+ around do |example|
287
+ old_adapter = Lutaml::Model::Config.xml_adapter
288
+ Lutaml::Model::Config.xml_adapter = adapter_class
262
289
 
263
- context "attribute namespace" do
264
- input_xml = '<ns1:example ex1:alpha="hello" beta="bye" xmlns:ns1="http://www.check.com" xmlns:ex1="http://www.example.com"></ns1:example>'
265
-
266
- it "checks the attribute with and without namespace" do
267
- parsed = XmlMapping::AttributeNamespace.from_xml(input_xml)
268
- expect(parsed.alpha).to eq("hello")
269
- expect(parsed.beta).to eq("bye")
270
- expect(parsed.to_xml).to be_equivalent_to(input_xml)
290
+ example.run
291
+ ensure
292
+ Lutaml::Model::Config.xml_adapter = old_adapter
271
293
  end
272
- end
273
294
 
274
- context "explicit namespace" do
275
- mml = '<math xmlns="http://www.w3.org/1998/Math/MathML"><mfenced open="("></mfenced></math>'
295
+ let(:mapping) { Lutaml::Model::XmlMapping.new }
276
296
 
277
- it "nil namespace" do
278
- parsed = XmlMapping::MmlMath.from_xml(mml)
279
- expect(parsed.to_xml).to be_equivalent_to(mml)
280
- end
281
- end
282
-
283
- context "overriding child namespace prefix" do
284
- let(:input_xml) do
285
- <<~XML
286
- <OverrideDefaultNamespacePrefix xmlns:abc="http://www.omg.org/spec/XMI/20131001" xmlns:GML="http://www.sparxsystems.com/profiles/GML/1.0" xmlns:CityGML="http://www.sparxsystems.com/profiles/CityGML/1.0">
287
- <abc:SameElementName App="hello">
288
- <GML:ApplicationSchema>GML App</GML:ApplicationSchema>
289
- <CityGML:ApplicationSchema>CityGML App</CityGML:ApplicationSchema>
290
- <abc:ApplicationSchema>App</abc:ApplicationSchema>
291
- </abc:SameElementName>
292
- </OverrideDefaultNamespacePrefix>
297
+ context "attribute namespace" do
298
+ input_xml = <<~XML
299
+ <ns1:example ex1:alpha="hello"
300
+ beta="bye"
301
+ xmlns:ns1="http://www.check.com"
302
+ xmlns:ex1="http://www.example.com">
303
+ </ns1:example>
293
304
  XML
294
- end
295
-
296
- it "expect to round-trips" do
297
- parsed = XmlMapping::OverrideDefaultNamespacePrefix.from_xml(input_xml)
298
- expect(parsed.to_xml).to be_equivalent_to(input_xml)
299
- end
300
- end
301
305
 
302
- context "with same name elements" do
303
- let(:input_xml) do
304
- <<~XML
305
- <SameElementName App="hello" xmlns="http://www.omg.org/spec/XMI/20131001" xmlns:GML="http://www.sparxsystems.com/profiles/GML/1.0" xmlns:CityGML="http://www.sparxsystems.com/profiles/CityGML/1.0">
306
- <GML:ApplicationSchema>GML App</GML:ApplicationSchema>
307
- <CityGML:ApplicationSchema>CityGML App</CityGML:ApplicationSchema>
308
- <ApplicationSchema>App</ApplicationSchema>
309
- </SameElementName>
310
- XML
311
- end
312
-
313
- it "parses XML and serializes elements with the same name" do
314
- parsed = XmlMapping::SameNameDifferentNamespace.from_xml(input_xml)
315
-
316
- expect(parsed.citygml_application_schema).to eq("CityGML App")
317
- expect(parsed.gml_application_schema).to eq("GML App")
318
- expect(parsed.application_schema).to eq("App")
319
- expect(parsed.app).to eq("hello")
320
- expect(parsed.element_order).to eq(["text", "ApplicationSchema", "text",
321
- "ApplicationSchema", "text", "ApplicationSchema", "text"])
322
- expect(XmlMapping::SameNameDifferentNamespace.from_xml(input_xml).to_xml).to be_equivalent_to(input_xml)
323
- end
324
- end
325
-
326
- context "with elements have different prefixed namespaces" do
327
- before do
328
- mapping.root("XMI")
329
- mapping.namespace("http://www.omg.org/spec/XMI/20131001")
330
- mapping.map_element(
331
- "ApplicationSchema",
332
- to: :gml_application_schema,
333
- namespace: "http://www.sparxsystems.com/profiles/GML/1.0",
334
- prefix: "GML",
335
- )
336
- mapping.map_element(
337
- "ApplicationSchema",
338
- to: :citygml_application_schema,
339
- namespace: "http://www.sparxsystems.com/profiles/CityGML/1.0",
340
- prefix: "CityGML",
341
- )
342
- mapping.map_element(
343
- "ApplicationSchema",
344
- to: :citygml_application_schema,
345
- namespace: "http://www.sparxsystems.com/profiles/CGML/1.0",
346
- prefix: "CGML",
347
- )
348
- end
349
-
350
- it "maps elements correctly" do
351
- expect(mapping.elements[0].namespace).to eq("http://www.sparxsystems.com/profiles/GML/1.0")
352
- expect(mapping.elements[1].namespace).to eq("http://www.sparxsystems.com/profiles/CityGML/1.0")
353
- expect(mapping.elements[2].namespace).to eq("http://www.sparxsystems.com/profiles/CGML/1.0")
354
- expect(mapping.elements.size).to eq(3)
306
+ it "checks the attribute with and without namespace" do
307
+ parsed = XmlMapping::AttributeNamespace.from_xml(input_xml)
308
+ expect(parsed.alpha).to eq("hello")
309
+ expect(parsed.beta).to eq("bye")
310
+ expect(parsed.to_xml).to be_equivalent_to(input_xml)
311
+ end
355
312
  end
356
- end
357
313
 
358
- context "with child having explicit namespaces" do
359
- let(:xml) do
360
- <<~XML.strip
361
- <pn:WithChildExplicitNamespaceNil xmlns:pn="http://parent-namespace" xmlns:cn="http://child-namespace">
362
- <pn:DefaultNamespace>default namespace text</pn:DefaultNamespace>
363
- <cn:WithNamespace>explicit namespace text</cn:WithNamespace>
364
- <WithoutNamespace>without namespace text</WithoutNamespace>
365
- </pn:WithChildExplicitNamespaceNil>
314
+ context "explicit namespace" do
315
+ mml = <<~XML
316
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
317
+ <mfenced open="("></mfenced>
318
+ </math>
366
319
  XML
367
- end
368
-
369
- let(:parsed) do
370
- XmlMapping::WithChildExplicitNamespace.from_xml(xml)
371
- end
372
320
 
373
- it "reads element with default namespace" do
374
- expect(parsed.with_default_namespace).to eq("default namespace text")
375
- end
376
-
377
- it "reads element with explicit namespace" do
378
- expect(parsed.with_namespace).to eq("explicit namespace text")
379
- end
380
-
381
- it "reads element without namespace" do
382
- expect(parsed.without_namespace).to eq("without namespace text")
321
+ it "nil namespace" do
322
+ parsed = XmlMapping::MmlMath.from_xml(mml)
323
+ expect(parsed.to_xml).to be_equivalent_to(mml)
324
+ end
383
325
  end
384
326
 
385
- it "round-trips xml with child explicit namespace" do
386
- expect(parsed.to_xml).to be_equivalent_to(xml)
387
- end
388
- end
327
+ # Skipping for OX because it does not handle namespaces
328
+ context "overriding child namespace prefix", skip: adapter_class != Lutaml::Model::XmlAdapter::NokogiriAdapter do
329
+ let(:input_xml) do
330
+ <<~XML
331
+ <OverrideDefaultNamespacePrefix
332
+ xmlns:abc="http://www.omg.org/spec/XMI/20131001"
333
+ xmlns:GML="http://www.sparxsystems.com/profiles/GML/1.0"
334
+ xmlns:CityGML="http://www.sparxsystems.com/profiles/CityGML/1.0">
335
+
336
+ <abc:SameElementName App="hello">
337
+ <GML:ApplicationSchema>GML App</GML:ApplicationSchema>
338
+ <CityGML:ApplicationSchema>CityGML App</CityGML:ApplicationSchema>
339
+ <abc:ApplicationSchema>App</abc:ApplicationSchema>
340
+ </abc:SameElementName>
341
+ </OverrideDefaultNamespacePrefix>
342
+ XML
343
+ end
389
344
 
390
- context "with default namespace" do
391
- before do
392
- mapping.root("ceramic")
393
- mapping.namespace("https://example.com/ceramic/1.2")
394
- mapping.map_element("type", to: :type)
395
- mapping.map_element("color", to: :color, delegate: :glaze)
396
- mapping.map_element("finish", to: :finish, delegate: :glaze)
345
+ it "expect to round-trips" do
346
+ parsed = XmlMapping::OverrideDefaultNamespacePrefix.from_xml(input_xml)
347
+ expect(parsed.to_xml).to be_equivalent_to(input_xml)
348
+ end
397
349
  end
398
350
 
399
- it "sets the default namespace for the root element" do
400
- expect(mapping.namespace_uri).to eq("https://example.com/ceramic/1.2")
401
- expect(mapping.namespace_prefix).to be_nil
402
- end
351
+ context "with same name elements" do
352
+ let(:input_xml) do
353
+ <<~XML
354
+ <SameElementName App="hello"
355
+ xmlns="http://www.omg.org/spec/XMI/20131001"
356
+ xmlns:GML="http://www.sparxsystems.com/profiles/GML/1.0"
357
+ xmlns:CityGML="http://www.sparxsystems.com/profiles/CityGML/1.0">
403
358
 
404
- it "maps elements correctly" do
405
- expect(mapping.elements.size).to eq(3)
406
- expect(mapping.elements[0].name).to eq("type")
407
- expect(mapping.elements[1].delegate).to eq(:glaze)
408
- end
409
- end
359
+ <GML:ApplicationSchema>GML App</GML:ApplicationSchema>
360
+ <CityGML:ApplicationSchema>CityGML App</CityGML:ApplicationSchema>
361
+ <ApplicationSchema>App</ApplicationSchema>
362
+ </SameElementName>
363
+ XML
364
+ end
410
365
 
411
- context "with prefixed namespace" do
412
- before do
413
- mapping.root("ceramic")
414
- mapping.namespace("https://example.com/ceramic/1.2", "cera")
415
- mapping.map_element("type", to: :type)
416
- mapping.map_element("color", to: :color, delegate: :glaze)
417
- mapping.map_element("finish", to: :finish, delegate: :glaze)
418
- end
366
+ let(:expected_order) do
367
+ {
368
+ Lutaml::Model::XmlAdapter::NokogiriAdapter => [
369
+ "text",
370
+ "ApplicationSchema",
371
+ "text",
372
+ "ApplicationSchema",
373
+ "text",
374
+ "ApplicationSchema",
375
+ "text",
376
+ ],
377
+ Lutaml::Model::XmlAdapter::OxAdapter => [
378
+ "ApplicationSchema",
379
+ "ApplicationSchema",
380
+ "ApplicationSchema",
381
+ ],
382
+ }
383
+ end
419
384
 
420
- it "sets the namespace with prefix for the root element" do
421
- expect(mapping.namespace_uri).to eq("https://example.com/ceramic/1.2")
422
- expect(mapping.namespace_prefix).to eq("cera")
423
- end
385
+ let(:parsed) { XmlMapping::SameNameDifferentNamespace.from_xml(input_xml) }
424
386
 
425
- it "maps elements correctly" do
426
- expect(mapping.elements.size).to eq(3)
427
- expect(mapping.elements[0].name).to eq("type")
428
- expect(mapping.elements[1].delegate).to eq(:glaze)
429
- end
430
- end
387
+ it "citygml_application_schema should be correct" do
388
+ expect(parsed.citygml_application_schema).to eq("CityGML App")
389
+ end
431
390
 
432
- context "with element-level namespace" do
433
- before do
434
- mapping.root("ceramic")
435
- mapping.map_element(
436
- "type",
437
- to: :type,
438
- namespace: "https://example.com/ceramic/1.2",
439
- prefix: "cera",
440
- )
441
- mapping.map_element("color", to: :color, delegate: :glaze)
442
- mapping.map_element("finish", to: :finish, delegate: :glaze)
443
- end
444
-
445
- it "sets the namespace for individual elements" do
446
- expect(mapping.elements.size).to eq(3)
447
- expect(mapping.elements[0].namespace).to eq("https://example.com/ceramic/1.2")
448
- expect(mapping.elements[0].prefix).to eq("cera")
449
- expect(mapping.elements[1].delegate).to eq(:glaze)
450
- end
451
- end
391
+ it "gml_application_schema should be correct" do
392
+ expect(parsed.gml_application_schema).to eq("GML App")
393
+ end
452
394
 
453
- context "with attribute-level namespace" do
454
- before do
455
- mapping.root("ceramic")
456
- mapping.map_attribute(
457
- "date",
458
- to: :date,
459
- namespace: "https://example.com/ceramic/1.2",
460
- prefix: "cera",
461
- )
462
- mapping.map_element("type", to: :type)
463
- mapping.map_element("color", to: :color, delegate: :glaze)
464
- mapping.map_element("finish", to: :finish, delegate: :glaze)
465
- end
466
-
467
- it "sets the namespace for individual attributes" do
468
- expect(mapping.attributes.size).to eq(1)
469
- expect(mapping.attributes[0].namespace).to eq("https://example.com/ceramic/1.2")
470
- expect(mapping.attributes[0].prefix).to eq("cera")
471
- end
472
- end
395
+ it "application_schema should be correct" do
396
+ expect(parsed.application_schema).to eq("App")
397
+ end
473
398
 
474
- context "with nil element-level namespace" do
475
- let(:expected_xml) do
476
- <<~XML
477
- <xmi:ChildNamespaceNil xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:new="http://www.omg.org/spec/XMI/20161001">
478
- <xmi:ElementDefaultNamespace>Default namespace</xmi:ElementDefaultNamespace>
479
- <ElementNilNamespace>No namespace</ElementNilNamespace>
480
- <new:ElementNewNamespace>New namespace</new:ElementNewNamespace>
481
- </xmi:ChildNamespaceNil>
482
- XML
483
- end
399
+ it "app should be correct" do
400
+ expect(parsed.app).to eq("hello")
401
+ end
484
402
 
485
- let(:model) do
486
- XmlMapping::ChildNamespaceNil.new(
487
- {
488
- element_default_namespace: "Default namespace",
489
- element_nil_namespace: "No namespace",
490
- element_new_namespace: "New namespace",
491
- },
492
- )
493
- end
403
+ it "element_order should be correct" do
404
+ expect(parsed.element_order).to eq(expected_order[adapter_class])
405
+ end
494
406
 
495
- it "expect to apply correct namespaces" do
496
- expect(model.to_xml).to be_equivalent_to(expected_xml)
407
+ it "to_xml should be correct" do
408
+ expect(parsed.to_xml).to be_equivalent_to(input_xml)
409
+ end
497
410
  end
498
- end
499
411
 
500
- context "with schemaLocation" do
501
- context "when mixed: false" do
502
- let(:xml) do
503
- <<~XML
504
- <p xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
505
- xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd">
506
- <p xmlns:xsi="http://another-instance"
507
- xsi:schemaLocation="http://www.opengis.net/gml/3.7">
508
- Some text inside paragraph
509
- </p>
510
- </p>
511
- XML
412
+ context "with elements have different prefixed namespaces" do
413
+ before do
414
+ mapping.root("XMI")
415
+ mapping.namespace("http://www.omg.org/spec/XMI/20131001")
416
+ mapping.map_element(
417
+ "ApplicationSchema",
418
+ to: :gml_application_schema,
419
+ namespace: "http://www.sparxsystems.com/profiles/GML/1.0",
420
+ prefix: "GML",
421
+ )
422
+ mapping.map_element(
423
+ "ApplicationSchema",
424
+ to: :citygml_application_schema,
425
+ namespace: "http://www.sparxsystems.com/profiles/CityGML/1.0",
426
+ prefix: "CityGML",
427
+ )
428
+ mapping.map_element(
429
+ "ApplicationSchema",
430
+ to: :citygml_application_schema,
431
+ namespace: "http://www.sparxsystems.com/profiles/CGML/1.0",
432
+ prefix: "CGML",
433
+ )
512
434
  end
513
435
 
514
- it "contain schemaLocation attributes" do
515
- expect(Paragraph.from_xml(xml).to_xml).to be_equivalent_to(xml)
436
+ it "maps elements correctly" do
437
+ expect(mapping.elements[0].namespace).to eq("http://www.sparxsystems.com/profiles/GML/1.0")
438
+ expect(mapping.elements[1].namespace).to eq("http://www.sparxsystems.com/profiles/CityGML/1.0")
439
+ expect(mapping.elements[2].namespace).to eq("http://www.sparxsystems.com/profiles/CGML/1.0")
440
+ expect(mapping.elements.size).to eq(3)
516
441
  end
517
442
  end
518
443
 
519
- context "when mixed: true" do
444
+ context "with child having explicit namespaces" do
520
445
  let(:xml) do
521
- <<~XML
522
- <schemaLocationOrdered xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
523
- xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd">
524
- <schemaLocationOrdered xmlns:xsi="http://another-instance"
525
- xsi:schemaLocation="http://www.opengis.net/gml/3.7">
526
- Some text inside paragraph
527
- </schemaLocationOrdered>
528
- </schemaLocationOrdered>
446
+ <<~XML.strip
447
+ <pn:WithChildExplicitNamespaceNil xmlns:pn="http://parent-namespace" xmlns:cn="http://child-namespace">
448
+ <pn:DefaultNamespace>default namespace text</pn:DefaultNamespace>
449
+ <cn:WithNamespace>explicit namespace text</cn:WithNamespace>
450
+ <WithoutNamespace>without namespace text</WithoutNamespace>
451
+ </pn:WithChildExplicitNamespaceNil>
529
452
  XML
530
453
  end
531
454
 
532
- it "contain schemaLocation attributes" do
533
- expect(XmlMapping::SchemaLocationOrdered.from_xml(xml).to_xml).to be_equivalent_to(xml)
455
+ let(:parsed) do
456
+ XmlMapping::WithChildExplicitNamespace.from_xml(xml)
534
457
  end
535
- end
536
- end
537
458
 
538
- context "with multiple schemaLocations" do
539
- let(:xml) do
540
- <<~XML
541
- <p xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
542
- xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd">
543
- <p xmlns:xsi="http://another-instance"
544
- xsi:schemaLocation="http://www.opengis.net/gml/3.7 http://schemas.opengis.net/gml/3.7.1/gml.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd">
545
- Some text inside paragraph
546
- </p>
547
- </p>
548
- XML
549
- end
550
-
551
- it "parses and serializes multiple schemaLocation attributes" do
552
- parsed = Paragraph.from_xml(xml)
553
- expect(parsed.schema_location.size).to eq(2)
554
- expect(parsed.schema_location[0].namespace).to eq("http://www.opengis.net/gml/3.2")
555
- expect(parsed.schema_location[0].location).to eq("http://schemas.opengis.net/gml/3.2.1/gml.xsd")
556
- expect(parsed.schema_location[1].namespace).to eq("http://www.w3.org/1999/xlink")
557
- expect(parsed.schema_location[1].location).to eq("http://www.w3.org/1999/xlink.xsd")
558
-
559
- serialized = parsed.to_xml
560
- expect(serialized).to be_equivalent_to(xml)
561
- expect(serialized).to include('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
562
- expect(serialized).to include('xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"')
563
- end
459
+ it "reads element with default namespace" do
460
+ expect(parsed.with_default_namespace).to eq("default namespace text")
461
+ end
564
462
 
565
- it "handles nested elements with different schemaLocations" do
566
- parsed = Paragraph.from_xml(xml)
567
- nested_p = parsed.paragraph
463
+ it "reads element with explicit namespace" do
464
+ expect(parsed.with_namespace).to eq("explicit namespace text")
465
+ end
568
466
 
569
- expect(nested_p).to be_a(Paragraph)
570
- expect(nested_p.schema_location.size).to eq(2)
571
- expect(nested_p.schema_location[0].namespace).to eq("http://www.opengis.net/gml/3.7")
572
- expect(nested_p.schema_location[0].location).to eq("http://schemas.opengis.net/gml/3.7.1/gml.xsd")
573
- expect(nested_p.schema_location[1].namespace).to eq("http://www.isotc211.org/2005/gmd")
574
- expect(nested_p.schema_location[1].location).to eq("http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd")
467
+ it "reads element without namespace" do
468
+ expect(parsed.without_namespace).to eq("without namespace text")
469
+ end
575
470
 
576
- serialized = parsed.to_xml
577
- expect(serialized).to include('xmlns:xsi="http://another-instance"')
578
- expect(serialized).to include('xsi:schemaLocation="http://www.opengis.net/gml/3.7 http://schemas.opengis.net/gml/3.7.1/gml.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd"')
471
+ it "round-trips xml with child explicit namespace" do
472
+ expect(parsed.to_xml).to be_equivalent_to(xml)
473
+ end
579
474
  end
580
475
 
581
- it "creates XML with multiple schemaLocations" do
582
- paragraph = Paragraph.new(
583
- schema_location: Lutaml::Model::SchemaLocation.new(
584
- schema_location: {
585
- "http://www.opengis.net/gml/3.2" => "http://schemas.opengis.net/gml/3.2.1/gml.xsd",
586
- "http://www.w3.org/1999/xlink" => "http://www.w3.org/1999/xlink.xsd",
587
- },
588
- prefix: "xsi",
589
- ),
590
- paragraph: Paragraph.new(
591
- schema_location: Lutaml::Model::SchemaLocation.new(
592
- schema_location: {
593
- "http://www.opengis.net/gml/3.7" => "http://schemas.opengis.net/gml/3.7.1/gml.xsd",
594
- "http://www.isotc211.org/2005/gmd" => "http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd",
595
- },
596
- prefix: "xsi",
597
- namespace: "http://another-instance",
598
- ),
599
- text: ["Some text inside paragraph"],
600
- ),
601
- )
476
+ context "with default namespace" do
477
+ before do
478
+ mapping.root("ceramic")
479
+ mapping.namespace("https://example.com/ceramic/1.2")
480
+ mapping.map_element("type", to: :type)
481
+ mapping.map_element("color", to: :color, delegate: :glaze)
482
+ mapping.map_element("finish", to: :finish, delegate: :glaze)
483
+ end
602
484
 
603
- serialized = paragraph.to_xml
604
- expect(serialized).to be_equivalent_to(xml)
605
- end
606
- end
485
+ it "sets the default namespace for the root element" do
486
+ expect(mapping.namespace_uri).to eq("https://example.com/ceramic/1.2")
487
+ expect(mapping.namespace_prefix).to be_nil
488
+ end
607
489
 
608
- context "with raw mapping" do
609
- let(:input_xml) do
610
- <<~XML
611
- <person>
612
- <name>John Doe</name>
613
- <address>
614
- <street>
615
- <a>N</a>
616
- <p>adf</p>
617
- </street>
618
- <city><a>M</a></city>
619
- </address>
620
- </person>
621
- XML
490
+ it "maps elements correctly" do
491
+ expect(mapping.elements.size).to eq(3)
492
+ expect(mapping.elements[0].name).to eq("type")
493
+ expect(mapping.elements[1].delegate).to eq(:glaze)
494
+ end
622
495
  end
623
496
 
624
- let(:expected_street) do
625
- if Lutaml::Model::Config.xml_adapter == Lutaml::Model::XmlAdapter::OxAdapter
626
- "<a>N</a>\n<p>adf</p>\n"
627
- else
628
- "\n <a>N</a>\n <p>adf</p>\n "
497
+ context "with prefixed namespace" do
498
+ before do
499
+ mapping.root("ceramic")
500
+ mapping.namespace("https://example.com/ceramic/1.2", "cera")
501
+ mapping.map_element("type", to: :type)
502
+ mapping.map_element("color", to: :color, delegate: :glaze)
503
+ mapping.map_element("finish", to: :finish, delegate: :glaze)
629
504
  end
630
- end
631
505
 
632
- let(:model) { XmlMapping::Person.from_xml(input_xml) }
506
+ it "sets the namespace with prefix for the root element" do
507
+ expect(mapping.namespace_uri).to eq("https://example.com/ceramic/1.2")
508
+ expect(mapping.namespace_prefix).to eq("cera")
509
+ end
633
510
 
634
- it "expect to contain raw xml" do
635
- expect(model.address.street).to eq(expected_street)
636
- expect(model.address.city.strip).to eq("<a>M</a>")
511
+ it "maps elements correctly" do
512
+ expect(mapping.elements.size).to eq(3)
513
+ expect(mapping.elements[0].name).to eq("type")
514
+ expect(mapping.elements[1].delegate).to eq(:glaze)
515
+ end
637
516
  end
638
- end
639
517
 
640
- context "with content mapping" do
641
- let(:xml_data) { "<i>my text <b>bold</b> is in italics</i>" }
642
- let(:italic) { Italic.from_xml(xml_data) }
518
+ context "with element-level namespace" do
519
+ before do
520
+ mapping.root("ceramic")
521
+ mapping.map_element(
522
+ "type",
523
+ to: :type,
524
+ namespace: "https://example.com/ceramic/1.2",
525
+ prefix: "cera",
526
+ )
527
+ mapping.map_element("color", to: :color, delegate: :glaze)
528
+ mapping.map_element("finish", to: :finish, delegate: :glaze)
529
+ end
643
530
 
644
- it "parses the textual content of an XML element" do
645
- expect(italic.text).to eq(["my text ", " is in italics"])
531
+ it "sets the namespace for individual elements" do
532
+ expect(mapping.elements.size).to eq(3)
533
+ expect(mapping.elements[0].namespace).to eq("https://example.com/ceramic/1.2")
534
+ expect(mapping.elements[0].prefix).to eq("cera")
535
+ expect(mapping.elements[1].delegate).to eq(:glaze)
536
+ end
646
537
  end
647
- end
648
538
 
649
- context "with p object" do
650
- describe "convert from xml containing p tag" do
651
- let(:xml_data) { "<p>my text for paragraph</p>" }
652
- let(:paragraph) { Paragraph.from_xml(xml_data) }
539
+ context "with attribute-level namespace" do
540
+ before do
541
+ mapping.root("ceramic")
542
+ mapping.map_attribute(
543
+ "date",
544
+ to: :date,
545
+ namespace: "https://example.com/ceramic/1.2",
546
+ prefix: "cera",
547
+ )
548
+ mapping.map_element("type", to: :type)
549
+ mapping.map_element("color", to: :color, delegate: :glaze)
550
+ mapping.map_element("finish", to: :finish, delegate: :glaze)
551
+ end
653
552
 
654
- it "parses the textual content of an XML element" do
655
- expect(paragraph.text).to eq("my text for paragraph")
553
+ it "sets the namespace for individual attributes" do
554
+ expect(mapping.attributes.size).to eq(1)
555
+ expect(mapping.attributes[0].namespace).to eq("https://example.com/ceramic/1.2")
556
+ expect(mapping.attributes[0].prefix).to eq("cera")
656
557
  end
657
558
  end
658
559
 
659
- describe "generate xml with p tag" do
660
- let(:paragraph) { Paragraph.new(text: "my text for paragraph") }
661
- let(:expected_xml) { "<p>my text for paragraph</p>" }
662
-
663
- it "converts to xml correctly" do
664
- expect(paragraph.to_xml).to eq(expected_xml)
560
+ context "with nil element-level namespace" do
561
+ let(:expected_xml) do
562
+ <<~XML
563
+ <xmi:ChildNamespaceNil xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:new="http://www.omg.org/spec/XMI/20161001">
564
+ <xmi:ElementDefaultNamespace>Default namespace</xmi:ElementDefaultNamespace>
565
+ <ElementNilNamespace>No namespace</ElementNilNamespace>
566
+ <new:ElementNewNamespace>New namespace</new:ElementNewNamespace>
567
+ </xmi:ChildNamespaceNil>
568
+ XML
665
569
  end
666
- end
667
- end
668
570
 
669
- describe "#deep_dup" do
670
- let(:orig_mappings) do
671
- XmlMapping::ToBeDuplicated.mappings_for(:xml)
672
- end
571
+ let(:model) do
572
+ XmlMapping::ChildNamespaceNil.new(
573
+ {
574
+ element_default_namespace: "Default namespace",
575
+ element_nil_namespace: "No namespace",
576
+ element_new_namespace: "New namespace",
577
+ },
578
+ )
579
+ end
673
580
 
674
- let(:dup_mappings) do
675
- orig_mappings.deep_dup
581
+ it "expect to apply correct namespaces" do
582
+ expect(model.to_xml).to be_equivalent_to(expected_xml)
583
+ end
676
584
  end
677
585
 
678
- it "duplicates root_element" do
679
- orig_root = orig_mappings.root_element
680
- dup_root = dup_mappings.root_element
586
+ context "with schemaLocation" do
587
+ context "when mixed: false" do
588
+ let(:xml) do
589
+ <<~XML
590
+ <p xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
591
+ xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd">
592
+ <p xmlns:xsi="http://another-instance"
593
+ xsi:schemaLocation="http://www.opengis.net/gml/3.7">
594
+ Some text inside paragraph
595
+ </p>
596
+ </p>
597
+ XML
598
+ end
681
599
 
682
- expect(orig_root).to eq(dup_root)
683
- expect(orig_root.object_id).not_to eq(dup_root.object_id)
684
- end
600
+ it "contain schemaLocation attributes" do
601
+ expect(Paragraph.from_xml(xml).to_xml).to be_equivalent_to(xml)
602
+ end
603
+ end
685
604
 
686
- it "duplicates namespace_uri" do
687
- orig_namespace_uri = orig_mappings.namespace_uri
688
- dup_namespace_uri = dup_mappings.namespace_uri
605
+ context "when mixed: true" do
606
+ let(:xml) do
607
+ <<~XML
608
+ <schemaLocationOrdered xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
609
+ xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd">
610
+ <schemaLocationOrdered xmlns:xsi="http://another-instance"
611
+ xsi:schemaLocation="http://www.opengis.net/gml/3.7">
612
+ Some text inside paragraph
613
+ </schemaLocationOrdered>
614
+ </schemaLocationOrdered>
615
+ XML
616
+ end
689
617
 
690
- expect(orig_namespace_uri).to eq(dup_namespace_uri)
691
- expect(orig_namespace_uri.object_id).not_to eq(dup_namespace_uri.object_id)
618
+ it "contain schemaLocation attributes" do
619
+ expect(XmlMapping::SchemaLocationOrdered.from_xml(xml).to_xml).to be_equivalent_to(xml)
620
+ end
621
+ end
692
622
  end
693
623
 
694
- it "duplicates namespace_prefix" do
695
- orig_namespace_prefix = orig_mappings.namespace_prefix
696
- dup_namespace_prefix = dup_mappings.namespace_prefix
624
+ context "with multiple schemaLocations" do
625
+ let(:xml) do
626
+ <<~XML
627
+ <p xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
628
+ xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd">
629
+ <p xmlns:xsi="http://another-instance"
630
+ xsi:schemaLocation="http://www.opengis.net/gml/3.7 http://schemas.opengis.net/gml/3.7.1/gml.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd">
631
+ Some text inside paragraph
632
+ </p>
633
+ </p>
634
+ XML
635
+ end
697
636
 
698
- expect(orig_namespace_prefix).to eq(dup_namespace_prefix)
699
- expect(orig_namespace_prefix.object_id).not_to eq(dup_namespace_prefix.object_id)
700
- end
637
+ it "parses and serializes multiple schemaLocation attributes" do
638
+ parsed = Paragraph.from_xml(xml)
639
+ expect(parsed.schema_location.size).to eq(2)
640
+ expect(parsed.schema_location[0].namespace).to eq("http://www.opengis.net/gml/3.2")
641
+ expect(parsed.schema_location[0].location).to eq("http://schemas.opengis.net/gml/3.2.1/gml.xsd")
642
+ expect(parsed.schema_location[1].namespace).to eq("http://www.w3.org/1999/xlink")
643
+ expect(parsed.schema_location[1].location).to eq("http://www.w3.org/1999/xlink.xsd")
644
+
645
+ serialized = parsed.to_xml
646
+ expect(serialized).to be_equivalent_to(xml)
647
+ expect(serialized).to include('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
648
+ expect(serialized).to include('xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"')
649
+ end
701
650
 
702
- context "when duplicating mapping" do
703
- let(:orig_mapping) { orig_mappings.mappings[0] }
704
- let(:dup_mapping) { dup_mappings.mappings[0] }
651
+ it "handles nested elements with different schemaLocations" do
652
+ parsed = Paragraph.from_xml(xml)
653
+ nested_p = parsed.paragraph
705
654
 
706
- it "duplicates custom_methods" do
707
- orig_custom_methods = orig_mapping.custom_methods
708
- dup_custom_methods = dup_mapping.custom_methods
655
+ expect(nested_p).to be_a(Paragraph)
656
+ expect(nested_p.schema_location.size).to eq(2)
657
+ expect(nested_p.schema_location[0].namespace).to eq("http://www.opengis.net/gml/3.7")
658
+ expect(nested_p.schema_location[0].location).to eq("http://schemas.opengis.net/gml/3.7.1/gml.xsd")
659
+ expect(nested_p.schema_location[1].namespace).to eq("http://www.isotc211.org/2005/gmd")
660
+ expect(nested_p.schema_location[1].location).to eq("http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd")
709
661
 
710
- expect(orig_custom_methods).to eq(dup_custom_methods)
711
- expect(orig_custom_methods.object_id).not_to eq(dup_custom_methods.object_id)
662
+ serialized = parsed.to_xml
663
+ expect(serialized).to include('xmlns:xsi="http://another-instance"')
664
+ expect(serialized).to include('xsi:schemaLocation="http://www.opengis.net/gml/3.7 http://schemas.opengis.net/gml/3.7.1/gml.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd"')
712
665
  end
713
666
 
714
- it "duplicates default_namespace" do
715
- orig_default_namespace = orig_mapping.default_namespace
716
- dup_default_namespace = dup_mapping.default_namespace
667
+ it "creates XML with multiple schemaLocations" do
668
+ paragraph = Paragraph.new(
669
+ schema_location: Lutaml::Model::SchemaLocation.new(
670
+ schema_location: {
671
+ "http://www.opengis.net/gml/3.2" => "http://schemas.opengis.net/gml/3.2.1/gml.xsd",
672
+ "http://www.w3.org/1999/xlink" => "http://www.w3.org/1999/xlink.xsd",
673
+ },
674
+ prefix: "xsi",
675
+ ),
676
+ paragraph: Paragraph.new(
677
+ schema_location: Lutaml::Model::SchemaLocation.new(
678
+ schema_location: {
679
+ "http://www.opengis.net/gml/3.7" => "http://schemas.opengis.net/gml/3.7.1/gml.xsd",
680
+ "http://www.isotc211.org/2005/gmd" => "http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd",
681
+ },
682
+ prefix: "xsi",
683
+ namespace: "http://another-instance",
684
+ ),
685
+ text: ["Some text inside paragraph"],
686
+ ),
687
+ )
717
688
 
718
- expect(orig_default_namespace).to eq(dup_default_namespace)
719
- expect(orig_default_namespace.object_id).not_to eq(dup_default_namespace.object_id)
689
+ serialized = paragraph.to_xml
690
+ expect(serialized).to be_equivalent_to(xml)
720
691
  end
692
+ end
721
693
 
722
- it "duplicates delegate" do
723
- # `delegate` is symbol which are constant so object_id will be same
724
- expect(orig_mapping.delegate).to eq(dup_mapping.delegate)
694
+ context "with raw mapping" do
695
+ let(:input_xml) do
696
+ <<~XML
697
+ <person>
698
+ <name>John Doe</name>
699
+ <address>
700
+ <street>
701
+ <a>N</a>
702
+ <p>adf</p>
703
+ </street>
704
+ <city><a>M</a></city>
705
+ </address>
706
+ </person>
707
+ XML
725
708
  end
726
709
 
727
- it "duplicates mixed_content" do
728
- # boolean value is constant so object_id will be same
729
- expect(orig_mapping.mixed_content).to eq(dup_mapping.mixed_content)
710
+ let(:expected_street) do
711
+ if Lutaml::Model::Config.xml_adapter == Lutaml::Model::XmlAdapter::OxAdapter
712
+ "<a>N</a>\n<p>adf</p>\n"
713
+ else
714
+ "\n <a>N</a>\n <p>adf</p>\n "
715
+ end
730
716
  end
731
717
 
732
- it "duplicates name" do
733
- orig_name = orig_mapping.name
734
- dup_name = dup_mapping.name
718
+ let(:model) { XmlMapping::Person.from_xml(input_xml) }
735
719
 
736
- expect(orig_name).to eq(dup_name)
737
- expect(orig_name.object_id).not_to eq(dup_name.object_id)
720
+ it "expect to contain raw xml" do
721
+ expect(model.address.street).to eq(expected_street)
722
+ expect(model.address.city.strip).to eq("<a>M</a>")
738
723
  end
724
+ end
739
725
 
740
- it "duplicates namespace" do
741
- orig_namespace = orig_mapping.namespace
742
- dup_namespace = dup_mapping.namespace
726
+ context "with content mapping" do
727
+ let(:xml_data) { "<i>my text <b>bold</b> is in italics</i>" }
728
+ let(:italic) { Italic.from_xml(xml_data) }
743
729
 
744
- expect(orig_namespace).to eq(dup_namespace)
745
- expect(orig_namespace.object_id).not_to eq(dup_namespace.object_id)
730
+ it "parses the textual content of an XML element" do
731
+ expect(italic.text).to eq(["my text ", " is in italics"])
746
732
  end
733
+ end
747
734
 
748
- it "duplicates namespace_set" do
749
- # boolean value is constant so object_id will be same
750
- expect(orig_mapping.namespace_set?).to eq(dup_mapping.namespace_set?)
735
+ context "with p object" do
736
+ describe "convert from xml containing p tag" do
737
+ let(:xml_data) { "<p>my text for paragraph</p>" }
738
+ let(:paragraph) { Paragraph.from_xml(xml_data) }
739
+
740
+ it "parses the textual content of an XML element" do
741
+ expect(paragraph.text).to eq("my text for paragraph")
742
+ end
751
743
  end
752
744
 
753
- it "duplicates prefix" do
754
- orig_prefix = orig_mapping.prefix
755
- dup_prefix = dup_mapping.prefix
745
+ describe "generate xml with p tag" do
746
+ let(:paragraph) { Paragraph.new(text: "my text for paragraph") }
747
+ let(:expected_xml) { "<p>my text for paragraph</p>" }
756
748
 
757
- expect(orig_prefix).to eq(dup_prefix)
758
- expect(orig_prefix.object_id).not_to eq(dup_prefix.object_id)
749
+ it "converts to xml correctly" do
750
+ expect(paragraph.to_xml.chomp).to eq(expected_xml)
751
+ end
759
752
  end
753
+ end
760
754
 
761
- it "duplicates prefix_set" do
762
- # boolean value is constant so object_id will be same
763
- expect(orig_mapping.prefix_set?).to eq(dup_mapping.prefix_set?)
755
+ describe "#deep_dup" do
756
+ let(:orig_mappings) do
757
+ XmlMapping::ToBeDuplicated.mappings_for(:xml)
764
758
  end
765
759
 
766
- it "duplicates render_nil" do
767
- # boolean value is constant so object_id will be same
768
- expect(orig_mapping.render_nil?).to eq(dup_mapping.render_nil?)
760
+ let(:dup_mappings) do
761
+ orig_mappings.deep_dup
769
762
  end
770
763
 
771
- it "duplicates to" do
772
- # `to` is symbol which are constant so object_id will be same
773
- expect(orig_mapping.to).to eq(dup_mapping.to)
764
+ it "duplicates root_element" do
765
+ orig_root = orig_mappings.root_element
766
+ dup_root = dup_mappings.root_element
767
+
768
+ expect(orig_root).to eq(dup_root)
769
+ expect(orig_root.object_id).not_to eq(dup_root.object_id)
774
770
  end
775
- end
776
- end
777
771
 
778
- describe "#map_all" do
779
- context "when map_all is defined before any other mapping" do
780
- let(:error_message) { "no other mappings are allowed with map_all" }
772
+ it "duplicates namespace_uri" do
773
+ orig_namespace_uri = orig_mappings.namespace_uri
774
+ dup_namespace_uri = dup_mappings.namespace_uri
781
775
 
782
- it "raise error when for map_element with map_all" do
783
- expect do
784
- XmlMapping::WithMapAll.xml do
785
- map_element "ele", to: :ele
786
- end
787
- end.to raise_error(StandardError, error_message)
776
+ expect(orig_namespace_uri).to eq(dup_namespace_uri)
777
+ expect(orig_namespace_uri.object_id).not_to eq(dup_namespace_uri.object_id)
788
778
  end
789
779
 
790
- it "raise error when for map_attribute with map_all" do
791
- expect do
792
- XmlMapping::WithMapAll.xml do
793
- map_attribute "attr", to: :attr
794
- end
795
- end.to raise_error(StandardError, error_message)
780
+ it "duplicates namespace_prefix" do
781
+ orig_namespace_prefix = orig_mappings.namespace_prefix
782
+ dup_namespace_prefix = dup_mappings.namespace_prefix
783
+
784
+ expect(orig_namespace_prefix).to eq(dup_namespace_prefix)
785
+ expect(orig_namespace_prefix.object_id).not_to eq(dup_namespace_prefix.object_id)
796
786
  end
797
787
 
798
- it "raise error when for map_content with map_all" do
799
- expect do
800
- XmlMapping::WithMapAll.xml do
801
- map_content to: :text
802
- end
803
- end.to raise_error(StandardError, error_message)
788
+ context "when duplicating mapping" do
789
+ let(:orig_mapping) { orig_mappings.mappings[0] }
790
+ let(:dup_mapping) { dup_mappings.mappings[0] }
791
+
792
+ it "duplicates custom_methods" do
793
+ orig_custom_methods = orig_mapping.custom_methods
794
+ dup_custom_methods = dup_mapping.custom_methods
795
+
796
+ expect(orig_custom_methods).to eq(dup_custom_methods)
797
+ expect(orig_custom_methods.object_id).not_to eq(dup_custom_methods.object_id)
798
+ end
799
+
800
+ it "duplicates default_namespace" do
801
+ orig_default_namespace = orig_mapping.default_namespace
802
+ dup_default_namespace = dup_mapping.default_namespace
803
+
804
+ expect(orig_default_namespace).to eq(dup_default_namespace)
805
+ expect(orig_default_namespace.object_id).not_to eq(dup_default_namespace.object_id)
806
+ end
807
+
808
+ it "duplicates delegate" do
809
+ # `delegate` is symbol which are constant so object_id will be same
810
+ expect(orig_mapping.delegate).to eq(dup_mapping.delegate)
811
+ end
812
+
813
+ it "duplicates mixed_content" do
814
+ # boolean value is constant so object_id will be same
815
+ expect(orig_mapping.mixed_content).to eq(dup_mapping.mixed_content)
816
+ end
817
+
818
+ it "duplicates name" do
819
+ orig_name = orig_mapping.name
820
+ dup_name = dup_mapping.name
821
+
822
+ expect(orig_name).to eq(dup_name)
823
+ expect(orig_name.object_id).not_to eq(dup_name.object_id)
824
+ end
825
+
826
+ it "duplicates namespace" do
827
+ orig_namespace = orig_mapping.namespace
828
+ dup_namespace = dup_mapping.namespace
829
+
830
+ expect(orig_namespace).to eq(dup_namespace)
831
+ expect(orig_namespace.object_id).not_to eq(dup_namespace.object_id)
832
+ end
833
+
834
+ it "duplicates namespace_set" do
835
+ # boolean value is constant so object_id will be same
836
+ expect(orig_mapping.namespace_set?).to eq(dup_mapping.namespace_set?)
837
+ end
838
+
839
+ it "duplicates prefix" do
840
+ orig_prefix = orig_mapping.prefix
841
+ dup_prefix = dup_mapping.prefix
842
+
843
+ expect(orig_prefix).to eq(dup_prefix)
844
+ expect(orig_prefix.object_id).not_to eq(dup_prefix.object_id)
845
+ end
846
+
847
+ it "duplicates prefix_set" do
848
+ # boolean value is constant so object_id will be same
849
+ expect(orig_mapping.prefix_set?).to eq(dup_mapping.prefix_set?)
850
+ end
851
+
852
+ it "duplicates render_nil" do
853
+ # boolean value is constant so object_id will be same
854
+ expect(orig_mapping.render_nil?).to eq(dup_mapping.render_nil?)
855
+ end
856
+
857
+ it "duplicates to" do
858
+ # `to` is symbol which are constant so object_id will be same
859
+ expect(orig_mapping.to).to eq(dup_mapping.to)
860
+ end
804
861
  end
805
862
  end
806
863
 
807
- context "when map_all is defined after other mappings" do
808
- let(:error_message) { "map_all is not allowed with other mappings" }
809
-
810
- it "raise error when for map_element with map_all" do
811
- expect do
812
- XmlMapping::WithoutMapAll.xml do
813
- map_all to: :all_content
814
- end
815
- end.to raise_error(StandardError, error_message)
864
+ describe "#map_all" do
865
+ context "when map_all is defined before any other mapping" do
866
+ it "raise error when for map_element with map_all" do
867
+ expect do
868
+ XmlMapping::WithMapAll.xml do
869
+ map_element "ele", to: :ele
870
+ end
871
+ end.to raise_error(
872
+ StandardError,
873
+ "map_element is not allowed, only map_attribute is allowed with map_all",
874
+ )
875
+ end
876
+
877
+ it "raise error when for map_content with map_all" do
878
+ expect do
879
+ XmlMapping::WithMapAll.xml do
880
+ map_content to: :text
881
+ end
882
+ end.to raise_error(
883
+ StandardError,
884
+ "map_content is not allowed, only map_attribute is allowed with map_all",
885
+ )
886
+ end
887
+
888
+ it "does not raise error for map_attribute with map_all" do
889
+ expect do
890
+ XmlMapping::WithMapAll.xml do
891
+ map_attribute "attr", to: :attr
892
+ end
893
+ end.not_to raise_error
894
+ end
816
895
  end
817
- end
818
896
 
819
- it "maps all the content including tags" do
820
- inner_xml = "Str<sub>2</sub>text<sup>1</sup>123"
821
- xml = "<WithMapAll>#{inner_xml}</WithMapAll>"
897
+ context "when map_all is defined after other mappings" do
898
+ let(:error_message) { "map_all is not allowed with other mappings" }
822
899
 
823
- parsed = XmlMapping::WithMapAll.from_xml(xml)
900
+ it "raise error when for map_element with map_all" do
901
+ expect do
902
+ XmlMapping::WithoutMapAll.xml do
903
+ map_all to: :all_content
904
+ end
905
+ end.to raise_error(StandardError, error_message)
906
+ end
907
+ end
824
908
 
825
- expect(parsed.all_content).to eq(inner_xml)
826
- end
909
+ context "with custom methods" do
910
+ let(:inner_xml) do
911
+ "Str<sub>2</sub>text<sup>1</sup>123"
912
+ end
827
913
 
828
- it "round-trips xml" do
829
- xml = "<WithMapAll>Str<sub>2</sub>text<sup>1</sup>123</WithMapAll>"
830
- expected_xml = "<WithMapAll>Str&lt;sub&gt;2&lt;/sub&gt;text&lt;sup&gt;1&lt;/sup&gt;123</WithMapAll>"
914
+ let(:xml) do
915
+ "<MapAllWithCustomMethod>#{inner_xml}</MapAllWithCustomMethod>"
916
+ end
831
917
 
832
- expect(XmlMapping::WithMapAll.from_xml(xml).to_xml).to eq(expected_xml)
833
- end
918
+ let(:parsed) do
919
+ XmlMapping::MapAllWithCustomMethod.from_xml(xml)
920
+ end
834
921
 
835
- context "when nested content has map_all" do
836
- let(:description) do
837
- <<~DESCRIPTION
838
- I'm a <b>web developer</b> with <strong>years</strong> of
839
- <i>experience</i> in many programing languages.
840
- DESCRIPTION
841
- end
922
+ it "uses custom method when parsing XML" do
923
+ expect(parsed.all_content).to eq("<div>#{inner_xml}</div>")
924
+ end
842
925
 
843
- let(:expected_description) do
844
- <<~DESCRIPTION
845
- I'm a &lt;b&gt;web developer&lt;/b&gt; with &lt;strong&gt;years&lt;/strong&gt; of
846
- &lt;i&gt;experience&lt;/i&gt; in many programing languages.
847
- DESCRIPTION
926
+ it "generates correct XML" do
927
+ expect(parsed.to_xml.chomp).to be_equivalent_to(xml)
928
+ end
848
929
  end
849
930
 
850
- let(:xml) do
851
- <<~XML
852
- <WithNestedMapAll age="23">
853
- <name>John Doe</name>
854
- <description>
855
- #{description}
856
- </description>
857
- </WithNestedMapAll>
858
- XML
859
- end
931
+ it "maps all the content including tags" do
932
+ inner_xml = "Str<sub>2</sub>text<sup>1</sup>123"
933
+ xml = "<WithMapAll>#{inner_xml}</WithMapAll>"
860
934
 
861
- let(:expected_xml) do
862
- <<~XML
863
- <WithNestedMapAll age="23">
864
- <name>John Doe</name>
865
- <description>
866
- #{expected_description}
867
- </description>
868
- </WithNestedMapAll>
869
- XML
870
- end
935
+ parsed = XmlMapping::WithMapAll.from_xml(xml)
871
936
 
872
- let(:parsed) do
873
- XmlMapping::WithNestedMapAll.from_xml(xml)
937
+ expect(parsed.all_content).to eq(inner_xml)
874
938
  end
875
939
 
876
- it "maps description correctly" do
877
- expect(parsed.description.all_content.strip).to eq(description.strip)
878
- end
940
+ it "round-trips xml" do
941
+ xml = "<WithMapAll>Str<sub>2</sub>text<sup>1</sup>123</WithMapAll>"
879
942
 
880
- it "maps name correctly" do
881
- expect(parsed.name).to eq("John Doe")
943
+ expect(XmlMapping::WithMapAll.from_xml(xml).to_xml.chomp).to eq(xml)
882
944
  end
883
945
 
884
- it "maps age correctly" do
885
- expect(parsed.age).to eq(23)
946
+ context "when nested content has map_all" do
947
+ let(:description) do
948
+ <<~DESCRIPTION
949
+ I'm a <b>web developer</b> with <strong>years</strong> of <i>experience</i> in many programing languages.
950
+ DESCRIPTION
951
+ end
952
+
953
+ let(:expected_description) do
954
+ <<~DESCRIPTION
955
+ I'm a <b>web developer</b> with <strong>years</strong> of <i>experience</i> in many programing languages.
956
+ DESCRIPTION
957
+ end
958
+
959
+ let(:xml) do
960
+ <<~XML
961
+ <WithNestedMapAll age="23">
962
+ <name>John Doe</name>
963
+ <description>
964
+ #{description}
965
+ </description>
966
+ </WithNestedMapAll>
967
+ XML
968
+ end
969
+
970
+ let(:expected_xml) do
971
+ <<~XML
972
+ <WithNestedMapAll age="23">
973
+ <name>John Doe</name>
974
+ <description>
975
+ #{expected_description}
976
+ </description>
977
+ </WithNestedMapAll>
978
+ XML
979
+ end
980
+
981
+ let(:parsed) do
982
+ XmlMapping::WithNestedMapAll.from_xml(xml)
983
+ end
984
+
985
+ it "maps description correctly" do
986
+ expect(parsed.description.all_content.strip).to eq(description.strip)
987
+ end
988
+
989
+ it "maps name correctly" do
990
+ expect(parsed.name).to eq("John Doe")
991
+ end
992
+
993
+ it "maps age correctly" do
994
+ expect(parsed.age).to eq(23)
995
+ end
996
+
997
+ it "round-trips xml" do
998
+ expect(parsed.to_xml).to be_equivalent_to(expected_xml)
999
+ end
886
1000
  end
887
1001
 
888
- it "round-trips xml" do
889
- expect(parsed.to_xml).to be_equivalent_to(expected_xml)
1002
+ context "when special char used in content with map all" do
1003
+ let(:xml) do
1004
+ <<~XML
1005
+ <SpecialCharContentWithMapAll>
1006
+ B <p>R&#x0026;C</p>
1007
+ C <p>J&#8212;C</p>
1008
+ O <p>A &amp; B </p>
1009
+ F <p>Z &#x00A9; </p>
1010
+ </SpecialCharContentWithMapAll>
1011
+ XML
1012
+ end
1013
+
1014
+ let(:expected_nokogiri_xml) do
1015
+ <<~XML.strip
1016
+ <SpecialCharContentWithMapAll>
1017
+ B <p>R&amp;C</p>
1018
+ C <p>J—C</p>
1019
+ O <p>A &amp; B </p>
1020
+ F <p>Z © </p>
1021
+ </SpecialCharContentWithMapAll>
1022
+ XML
1023
+ end
1024
+
1025
+ let(:expected_ox_xml) do
1026
+ "<SpecialCharContentWithMapAll> " \
1027
+ "B <p>R&amp;C</p> " \
1028
+ "C <p>J—C</p> " \
1029
+ "O <p>A &amp; B </p> " \
1030
+ "F <p>Z © </p>" \
1031
+ "</SpecialCharContentWithMapAll>\n"
1032
+ end
1033
+
1034
+ it "round-trips xml" do
1035
+ expected_xml = if adapter_class == Lutaml::Model::XmlAdapter::NokogiriAdapter
1036
+ expected_nokogiri_xml
1037
+ else
1038
+ expected_ox_xml
1039
+ end
1040
+
1041
+ expect(XmlMapping::SpecialCharContentWithMapAll.from_xml(xml).to_xml).to eq(expected_xml)
1042
+ end
890
1043
  end
891
- end
892
-
893
- context "when special char used in content with map all" do
894
- it "round-trips xml" do
895
- xml = <<~XML
896
- <SpecialCharContentWithMapAll>
897
- B <p>R&#x0026;C</p>
898
- C <p>J&#8212;C</p>
899
- O <p>A &amp; B </p>
900
- F <p>Z &#x00A9; </p>
901
- </SpecialCharContentWithMapAll>
902
- XML
903
1044
 
904
- expected_xml = <<~XML.strip
905
- <SpecialCharContentWithMapAll>
906
- B &lt;p&gt;R&amp;amp;C&lt;/p&gt;
907
- C &lt;p&gt;J&amp;#x2014;C&lt;/p&gt;
908
- O &lt;p&gt;A &amp;amp; B &lt;/p&gt;
909
- F &lt;p&gt;Z &amp;#xA9; &lt;/p&gt;
910
- </SpecialCharContentWithMapAll>
911
- XML
912
-
913
- expect(XmlMapping::SpecialCharContentWithMapAll.from_xml(xml).to_xml).to eq(expected_xml)
1045
+ context "when mixed content is true and child is content_mapping" do
1046
+ let(:xml) do
1047
+ <<~XML
1048
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1049
+ <xsd:documentation>asdf</xsd:documentation>
1050
+ </xsd:schema>
1051
+ XML
1052
+ end
1053
+
1054
+ it "round-trips xml" do
1055
+ expect(XmlMapping::Schema.from_xml(xml).to_xml).to be_equivalent_to(xml)
1056
+ end
914
1057
  end
915
1058
  end
1059
+ end
916
1060
 
917
- context "when mixed content is true and child is content_mapping" do
918
- let(:xml) do
919
- <<~XML
920
- <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
921
- <xsd:documentation>asdf</xsd:documentation>
922
- </xsd:schema>
923
- XML
924
- end
1061
+ describe Lutaml::Model::XmlAdapter::NokogiriAdapter do
1062
+ it_behaves_like "having XML Mappings", described_class
1063
+ end
925
1064
 
926
- it "round-trips xml" do
927
- expect(XmlMapping::Schema.from_xml(xml).to_xml).to be_equivalent_to(xml)
928
- end
929
- end
1065
+ describe Lutaml::Model::XmlAdapter::OxAdapter do
1066
+ it_behaves_like "having XML Mappings", described_class
1067
+ end
1068
+
1069
+ describe Lutaml::Model::XmlAdapter::OgaAdapter, skip: "Not implemented yet" do
1070
+ it_behaves_like "having XML Mappings", described_class
930
1071
  end
931
1072
  end