expressir 2.4.44-arm-linux → 2.4.45-arm-linux

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: 593a8089c2331653710b2ca51e3789d501cdaf9369be044bea4bd416d92d133f
4
- data.tar.gz: 703e76c30dba9a5451a8a0f3ad323a3fb9ce2a580c0ce4d13be00fa1a4dce7eb
3
+ metadata.gz: e09c5c927c878e232059b301e116b126589dd35e4ab72bbce563577a9d82b576
4
+ data.tar.gz: f16d568d6767b6ecb2648717108278b7012bd8f367b6bcc9e081d26b8d484457
5
5
  SHA512:
6
- metadata.gz: f6c71a721e0a7e00ce7e6fe1e72e6fdcb2af58f3bc73ac73ab676b9fa734bbf06dd1f87a2c319b4a3a07d1ed0640c6a6d0bc9df8162c24dc355bf04f19d7b9e8
7
- data.tar.gz: 1a8bc4fb4ecfed9b8e223d818499a101a7011e87ff135aa4599f45a30894b31ca9170c8e8162c8650cd0400a90b125a6eaea69645b8d94a0bc7a6001348108da
6
+ metadata.gz: 82bc5464f43c819eede4751832c8947d5a22a36f8466aec0a2db0170d7115ea7af7c17214e01b961b0bc63d318cdea82626b687ae3a3f40e497f69488e231f4e
7
+ data.tar.gz: f6361a1d666f0fbff3964f35917fa2a44c1b07e5b26ac717778f69f12c94f552d5c72d411280ccbab148176ea08d1ee29ed9dcf3863a2ac9f8a7a465a9c8e79c
@@ -0,0 +1,61 @@
1
+ # Floor guard: every released expressir must LOAD under the OLDEST
2
+ # lutaml-model its own gemspec admits. v2.4.4/v2.4.5 shipped `map ...,
3
+ # serialize: false` while declaring `lutaml-model ~> 0.8.0` — the
4
+ # keyword first exists in 0.8.43 — so any bundle resolving that pair
5
+ # died at class-load time (issue #566). This job pins lutaml-model to
6
+ # the exact gemspec floor and loads the model classes against it.
7
+ name: gemspec-floor
8
+
9
+ on:
10
+ push:
11
+ branches: [ master, main ]
12
+ pull_request:
13
+
14
+ jobs:
15
+ floor:
16
+ runs-on: ubuntu-latest
17
+ name: lutaml-model at the gemspec floor
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: '3.3'
24
+
25
+ - name: Extract the lutaml-model floor from the gemspec
26
+ id: floor
27
+ run: |
28
+ floor=$(ruby -e '
29
+ spec = Gem::Specification.load(Dir["*.gemspec"].first)
30
+ dep = spec.dependencies.find { |d| d.name == "lutaml-model" }
31
+ candidates = dep.requirement.requirements
32
+ .select { |op, _| [">=", "~>"].include?(op) }
33
+ .map { |_, v| v.version }
34
+ abort "no lutaml-model floor in the gemspec" if candidates.empty?
35
+ puts candidates.min
36
+ ')
37
+ echo "floor=$floor" >> "$GITHUB_OUTPUT"
38
+ echo "lutaml-model floor: $floor"
39
+
40
+ - name: Pin lutaml-model exactly at the floor
41
+ run: |
42
+ cat >> Gemfile <<'GEMFILE'
43
+
44
+ gem "lutaml-model", "= ${{ steps.floor.outputs.floor }}"
45
+ GEMFILE
46
+ bundle install
47
+
48
+ - name: Load the model classes under the floor
49
+ run: |
50
+ bundle exec ruby -e '
51
+ require "lutaml/model"
52
+ resolved = Gem.loaded_specs["lutaml-model"].version.to_s
53
+ abort "resolved #{resolved}, expected ${{ steps.floor.outputs.floor }}" unless resolved == "${{ steps.floor.outputs.floor }}"
54
+ require "expressir"
55
+ require "expressir/model/model_element"
56
+ require "expressir/model"
57
+ puts "model classes load under lutaml-model #{resolved}"
58
+ '
59
+
60
+ - name: Model specs under the floor
61
+ run: bundle exec rspec spec/expressir/model
@@ -465,9 +465,11 @@ module Expressir
465
465
  elsif entity_class == "Expressir::Model::Declarations::Type" && type_subtype_skips.any?
466
466
  entity_subtype = get_type_subtype(entity)
467
467
  type_subtype_skips.include?(entity_subtype)
468
- # Check FUNCTION:INNER exclusions
469
- elsif entity_class == "Expressir::Model::Declarations::Function" && function_subtype_skips.include?("INNER")
470
- inner_function?(entity)
468
+ # Check FUNCTION:INNER exclusions — the whole inner-function
469
+ # subtree is excluded, its parameters and nested declarations
470
+ # included, not only the function entity itself
471
+ elsif function_subtype_skips.include?("INNER") && within_inner_function?(entity)
472
+ true
471
473
  else
472
474
  false
473
475
  end
@@ -506,5 +508,19 @@ module Expressir
506
508
  parent.is_a?(Expressir::Model::Declarations::Rule) ||
507
509
  parent.is_a?(Expressir::Model::Declarations::Procedure)
508
510
  end
511
+
512
+ # Check if an entity is an inner function or a declaration belonging to one
513
+ # (its parameters, nested types, nested functions, ...)
514
+ # @param entity [Expressir::Model::ModelElement] The entity to check
515
+ # @return [Boolean] True if the entity or any of its ancestors is an inner function
516
+ def self.within_inner_function?(entity)
517
+ current = entity
518
+ while current
519
+ return true if current.is_a?(Model::Declarations::Function) && inner_function?(current)
520
+
521
+ current = current.respond_to?(:parent) ? current.parent : nil
522
+ end
523
+ false
524
+ end
509
525
  end
510
526
  end
@@ -372,6 +372,16 @@ module Expressir
372
372
  # 7.6.3: one accessor element per mapped attribute; OPTIONAL
373
373
  # attributes are minOccurs="0"; aggregates carry their
374
374
  # occurrence bounds.
375
+ #
376
+ # Entity-typed accessors carry the REF form (exp:Entity —
377
+ # content-free, the ref/href IDREF attributes): a P21
378
+ # entity-valued position holds a reference (#N), never inline
379
+ # content, and the full validated form stays on the GLOBAL
380
+ # entity element (substitutionGroup exp:Entity). Typing the
381
+ # accessor with the entity's own complexType demanded that
382
+ # content inside by-reference occurrences — `<Widget ref="id2"/>`
383
+ # could not validate (#565, exposed by leptris 1.9.383 fixing
384
+ # the empty-instance bypass #1860).
375
385
  def accessor_node(doc, schema, prefix, attribute, inline, config = nil,
376
386
  scope = nil)
377
387
  type = attribute.type
@@ -383,11 +393,14 @@ module Expressir
383
393
  node.set_attributes("minOccurs" => "0") if optional
384
394
  case kind
385
395
  when :entity
386
- target = entity_id_of(schema, type)
387
- node.set_attributes("type" => "#{prefix}:#{mapped(target, config, :entity)}")
396
+ # exp:Entity is abstract — an element cannot use it as its
397
+ # type directly (libxml2 rejects the schema); the concrete
398
+ # ref form is an anonymous empty extension carrying the
399
+ # base's ref/href attributes.
400
+ node.add_child(ref_form_node(doc, inline, prefix))
388
401
  when :entity_aggregate
389
402
  node.add_child(aggregate_content_node(doc, schema, prefix, type,
390
- config))
403
+ config, inline: inline))
391
404
  when :aggregate
392
405
  node.add_child(inline_list_node(doc, schema, type, inline))
393
406
  when :select
@@ -415,24 +428,41 @@ module Expressir
415
428
  # Aggregates of entity base: the accessor wraps unqualified
416
429
  # component elements typed by the component entity (9.2.6.1
417
430
  # worked example shape).
418
- def aggregate_content_node(doc, schema, prefix, aggregate, config = nil)
431
+ def aggregate_content_node(doc, schema, prefix, aggregate, config = nil,
432
+ inline: false)
419
433
  base = aggregate.base_type
420
434
  target = entity_id_of(schema, base)
421
435
  name = mapped(target, config, :entity)
422
436
  content = doc.create_element("xs:complexType")
423
437
  sequence = doc.create_element("xs:sequence")
424
438
  component = doc.create_element("xs:element")
439
+ # Aggregate members hold REFERENCES to entity instances
440
+ # (P21 #N ids), so the component element carries the
441
+ # content-free ref form (exp:Entity) — the full validated
442
+ # form stays on the global entity element (#565).
425
443
  component.set_attributes(
426
444
  "name" => name,
427
- "type" => "#{prefix}:#{name}",
428
445
  "minOccurs" => "0",
429
446
  "maxOccurs" => "unbounded",
430
447
  )
448
+ component.add_child(ref_form_node(doc, inline, prefix))
431
449
  sequence.add_child(component)
432
450
  content.add_child(sequence)
433
451
  content
434
452
  end
435
453
 
454
+ # The concrete ref form: an anonymous empty extension of
455
+ # exp:Entity — content-free, carrying the base's ref/href
456
+ # attributes. Entity-valued positions in a P21 instance hold
457
+ # references (#N ids), never inline content (#565).
458
+ def ref_form_node(doc, inline, prefix)
459
+ content = doc.create_element("xs:complexContent")
460
+ extension = doc.create_element("xs:extension")
461
+ extension.set_attributes("base" => exp_name("Entity", inline, prefix))
462
+ content.add_child(extension)
463
+ content
464
+ end
465
+
436
466
  # 7.8: the context-schema specific uos element — in the
437
467
  # exp:uos substitution group, extending the exp:uos carrier,
438
468
  # with a repeating choice over the exp:Entity substitution
@@ -3,6 +3,6 @@ module Expressir
3
3
  # autoload it (Ruby autoload only works for module/class constants, not
4
4
  # for string constants like `Expressir::VERSION`).
5
5
  module Version
6
- VERSION = "2.4.44".freeze
6
+ VERSION = "2.4.45".freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressir
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.44
4
+ version: 2.4.45
5
5
  platform: arm-linux
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-26 00:00:00.000000000 Z
11
+ date: 2026-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -227,6 +227,7 @@ files:
227
227
  - ".github/workflows/codeql.yml"
228
228
  - ".github/workflows/conformance.yml"
229
229
  - ".github/workflows/docs.yml"
230
+ - ".github/workflows/gemspec-floor.yml"
230
231
  - ".github/workflows/links.yml"
231
232
  - ".github/workflows/native-gems.yml"
232
233
  - ".github/workflows/performance-release.yml"