diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..17e5a705 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: FHIR Model Tests + +on: + workflow_dispatch: + push: + branches: + - 'master' + pull_request: + +permissions: + contents: read + +jobs: + build: + if: github.repository == 'incendilabs/fhir_models' + name: FHIR ${{ matrix.fhir-version }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - fhir-version: R4 + suite: r4 + - fhir-version: R4B + suite: r4b + - fhir-version: R5 + suite: r5 + + steps: + - name: Checkout fhir_models + uses: actions/checkout@v7 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.9' + + - name: Install test dependencies + run: | + gem install --no-document \ + bcp47:0.3.3 \ + date_time_precision:0.8.1 \ + mime-types:3.7.0 \ + nokogiri:1.19.4 \ + nokogiri-diff:0.3.0 \ + pry:0.15.2 \ + simplecov:0.22.0 \ + test-unit:3.7.7 + + - name: Run FHIR ${{ matrix.fhir-version }} test suite + run: ruby -Ilib -Itest test/run_version_suite.rb ${{ matrix.suite }} diff --git a/lib/fhir_models/bootstrap/model.rb b/lib/fhir_models/bootstrap/model.rb index 36227c79..f69bf31e 100644 --- a/lib/fhir_models/bootstrap/model.rb +++ b/lib/fhir_models/bootstrap/model.rb @@ -33,8 +33,8 @@ def ==(other) def method_missing(method, *_args, &_block) if defined?(self.class::MULTIPLE_TYPES) && self.class::MULTIPLE_TYPES[method.to_s] self.class::MULTIPLE_TYPES[method.to_s].each do |type| - type[0] = type[0].upcase - value = send("#{method}#{type}".to_sym) + type_name = type[0].upcase + type[1..] + value = send("#{method}#{type_name}".to_sym) return value unless value.nil? end return nil diff --git a/spec/lib/fhir_models/bootstrap/model_spec.rb b/spec/lib/fhir_models/bootstrap/model_spec.rb index d70c1198..1c29b09d 100644 --- a/spec/lib/fhir_models/bootstrap/model_spec.rb +++ b/spec/lib/fhir_models/bootstrap/model_spec.rb @@ -96,4 +96,12 @@ expect(range.low.value).to equal(18) end end + + describe '#method_missing' do + it 'resolves polymorphic fields without mutating type metadata' do + observation = FHIR::Observation.new(valueQuantity: { value: 1 }) + + expect(observation.value).to be_a(FHIR::Quantity) + end + end end diff --git a/test/run_version_suite.rb b/test/run_version_suite.rb new file mode 100644 index 00000000..4af0277e --- /dev/null +++ b/test/run_version_suite.rb @@ -0,0 +1,34 @@ +VERSION_SUITES = { + 'r4' => lambda { + Dir['test/unit/**/*_test.rb'].reject do |file| + File.basename(file).match?(/\A(?:r4b|r5)_/) + end + }, + 'r4b' => lambda { + %w[ + test/unit/r4b_models_test.rb + test/unit/r4b_definitions_test.rb + test/unit/r4b_xml_schema_validation_test.rb + ] + }, + 'r5' => lambda { + %w[ + test/unit/r5_models_test.rb + test/unit/r5_definitions_test.rb + test/unit/r5_xml_schema_validation_test.rb + test/acceptance/r5_serialization_acceptance_test.rb + test/acceptance/r5_runtime_definitions_acceptance_test.rb + test/acceptance/cross_version_model_isolation_test.rb + ] + } +}.freeze + +version = ARGV.fetch(0) do + abort "Usage: ruby -Ilib -Itest #{__FILE__} <#{VERSION_SUITES.keys.join('|')}>" +end.downcase + +suite = VERSION_SUITES[version] +abort "Unsupported FHIR version: #{version}" unless suite + +ARGV.clear +suite.call.sort.each { |file| require File.expand_path(file) }