inferno_core 0.5.3 → 0.6.0

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.
@@ -0,0 +1,9 @@
1
+ require_relative 'in_memory_repository'
2
+
3
+ module Inferno
4
+ module Repositories
5
+ # Repository that deals with persistence for the `IG` entity.
6
+ class IGs < InMemoryRepository
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Inferno
2
+ # @private
3
+ module RouteStorage
4
+ def routes
5
+ @routes ||= []
6
+ end
7
+ end
8
+
9
+ extend RouteStorage
10
+ end
@@ -7,11 +7,13 @@ module Inferno
7
7
  FACTORY_PATH = File.expand_path('../../spec/factories', __dir__).freeze
8
8
  REQUEST_HELPER_PATH = File.expand_path('../../spec/request_helper', __dir__).freeze
9
9
  RUNNABLE_HELPER_PATH = File.expand_path('../../spec/runnable_helper', __dir__).freeze
10
+ TEST_KIT_SPEC = File.expand_path('../../spec/shared/test_kit_examples', __dir__).freeze
10
11
 
11
12
  def self.require_helpers
12
13
  require FACTORY_BOT_SUPPORT_PATH
13
14
  require RUNNABLE_HELPER_PATH
14
15
  require REQUEST_HELPER_PATH
16
+ require TEST_KIT_SPEC
15
17
  end
16
18
  end
17
19
  end
@@ -14,7 +14,7 @@ module Inferno
14
14
  File.join(ig_path, suffix ? "package_#{suffix}.tgz" : 'package.tgz')
15
15
  end
16
16
 
17
- def load_ig(ig_input, idx = nil, thor_config = { verbose: true })
17
+ def load_ig(ig_input, idx = nil, thor_config = { verbose: true }, output_path = nil)
18
18
  case ig_input
19
19
  when FHIR_PACKAGE_NAME_REG_EX
20
20
  uri = ig_registry_url(ig_input)
@@ -25,12 +25,12 @@ module Inferno
25
25
  else
26
26
  raise StandardError, <<~FAILED_TO_LOAD
27
27
  Could not find implementation guide: #{ig_input}
28
- Put its package.tgz file directly in #{ig_path}
29
28
  FAILED_TO_LOAD
30
29
  end
31
30
 
31
+ destination = output_path || ig_file(idx)
32
32
  # use Thor's get to support CLI options config
33
- get(uri, ig_file(idx), thor_config)
33
+ get(uri, destination, thor_config)
34
34
  uri
35
35
  end
36
36
 
@@ -1,4 +1,4 @@
1
1
  module Inferno
2
2
  # Standard patterns for gem versions: https://guides.rubygems.org/patterns/
3
- VERSION = '0.5.3'.freeze
3
+ VERSION = '0.6.0'.freeze
4
4
  end
data/lib/inferno.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  module Inferno
2
- def self.routes
3
- @routes ||= []
4
- end
5
2
  end
6
3
 
7
4
  require_relative 'inferno/config/application'
@@ -14,3 +11,4 @@ require_relative 'inferno/spec_support'
14
11
  require_relative 'inferno/test_runner'
15
12
  require_relative 'inferno/version'
16
13
  require_relative 'inferno/utils/static_assets'
14
+ require_relative 'inferno/route_storage'
@@ -0,0 +1,13 @@
1
+ module ExtractTGZHelper
2
+ def extract_tgz(fixture)
3
+ filename = File.basename(fixture, '.tgz')
4
+ target_dir = Dir.mktmpdir(filename)
5
+ system "mkdir -p #{target_dir}"
6
+ system "tar -xzf #{fixture} --directory #{target_dir}"
7
+ target_dir
8
+ end
9
+
10
+ def cleanup(target_dir)
11
+ FileUtils.remove_entry(target_dir)
12
+ end
13
+ end
@@ -0,0 +1,133 @@
1
+ RSpec.shared_examples 'platform_deployable_test_kit' do
2
+ let(:test_kit_location) do
3
+ Object.const_source_location(described_class.name).first
4
+ end
5
+ let(:test_kit_gem) do
6
+ Bundler.definition.specs.find { |gem| test_kit_location.start_with? gem.full_gem_path }
7
+ end
8
+ let(:base_path) do
9
+ test_kit_gem.full_gem_path
10
+ end
11
+ let(:test_kit) do
12
+ described_class.const_get('Metadata')
13
+ rescue NameError
14
+ skip 'TestKit must be defined first'
15
+ end
16
+ let(:suites) do
17
+ test_kit.suite_ids.map { |id| Inferno::Repositories::TestSuites.new.find(id) }
18
+ end
19
+
20
+ describe 'TestKit' do
21
+ it 'defines test kit in the Metadata class' do
22
+ error_message =
23
+ "Define #{described_class.name}::Metadata at " \
24
+ "lib/#{described_class.name.underscore}/metadata.rb and require it in " \
25
+ "lib/#{described_class.name.underscore}.rb\n"
26
+
27
+ expect { described_class.const_get('Metadata') }.to_not raise_error(NameError), error_message
28
+
29
+ expect(described_class.const_get('Metadata') < Inferno::Entities::TestKit).to be(true)
30
+ end
31
+
32
+ it 'defines all required fields' do
33
+ required_fields = [
34
+ :id,
35
+ :title,
36
+ :description,
37
+ :suite_ids,
38
+ :version,
39
+ :maturity
40
+ ]
41
+
42
+ required_fields.each do |field_name|
43
+ expect(test_kit.send(field_name)).to be_present
44
+ end
45
+ end
46
+
47
+ it 'has a description with a <!-- break -->' do
48
+ error_message =
49
+ 'The test kit description must begin with one paragraph followed by "<!-- ' \
50
+ 'break -->". The portion of the description above the break is displayed ' \
51
+ "on the test kit listing page.\n"
52
+
53
+ expect(test_kit.description).to include('<!-- break -->'), error_message
54
+ end
55
+
56
+ it 'has a maturity of "Low", "Medium", or "High"' do
57
+ expect(['Low', 'Medium', 'High']).to include(test_kit.maturity) # rubocop:disable RSpec/ExpectActual
58
+ end
59
+
60
+ it 'uses the correct ruby version in its Dockerfile' do
61
+ dockerfile_path = File.join(base_path, 'Dockerfile')
62
+ dockerfile_contents = File.read(dockerfile_path)
63
+
64
+ expect(dockerfile_contents.lines.first.chomp).to eq('FROM ruby:3.3.6')
65
+ end
66
+ end
67
+
68
+ describe 'suites' do
69
+ it 'relies on the test kit version rather than defining the version in the suites' do
70
+ suite_paths = suites.map { |suite| Object.const_source_location(suite.name).first }
71
+ suite_contents = suite_paths.map { |path| File.read(path) }
72
+
73
+ suite_contents.each_with_index do |suite, i|
74
+ error_message =
75
+ "Suite at #{suite_paths[i]} should not explicitly declare a version, as " \
76
+ 'its version can now be determined by the version of its Test Kit.' \
77
+ "Remove the `version` method call in the suite definition.\n"
78
+
79
+ expect(suite).to_not match(/^\s+version(\s|\()\S+\)?/), error_message
80
+ end
81
+ end
82
+
83
+ it 'contains standard links' do
84
+ suites.each do |suite|
85
+ link_labels = suite.links.map { |link| link[:label] }
86
+
87
+ expected_labels = ['Report Issue', 'Open Source', 'Download']
88
+
89
+ error_message =
90
+ "Include the standard 'Report Issue', 'Open Source', and 'Download links in " \
91
+ 'each suite.\n'
92
+ expect(link_labels).to match_array(expected_labels), error_message
93
+ end
94
+ end
95
+ end
96
+
97
+ describe 'presets' do
98
+ it 'includes presets in the gem' do
99
+ presets = Dir[
100
+ File.join(base_path, 'config', 'presets', '*.json'),
101
+ File.join(base_path, 'config', 'presets', '*.json.erb')
102
+ ].map { |file_path| file_path.delete_prefix "#{Dir.pwd}/" }
103
+
104
+ missing_presets = presets - test_kit_gem.files
105
+
106
+ error_message =
107
+ "The following presets are not included in the gem: #{missing_presets.join(', ')}\n" \
108
+ "Ensure that config/presets is included in spec.files in #{test_kit_gem.name}.gemspec"
109
+
110
+ expect(missing_presets).to be_empty, error_message
111
+ end
112
+ end
113
+
114
+ describe 'gemspec' do
115
+ it 'uses git to determine files to include in the gem' do
116
+ gemspec_contents = File.read(File.join(base_path, "#{test_kit_gem.name}.gemspec"))
117
+
118
+ error_message =
119
+ 'Use git to determine which files to include in the gem. In ' \
120
+ "#{test_kit_gem.name}.gemspec, use: " \
121
+ "spec.files = `[ -d .git ] && git ls-files -z lib config/presets LICENSE`.split(\"\\x0\")\n"
122
+
123
+ expect(gemspec_contents).to include('[ -d .git ] && git ls-files'), error_message
124
+ end
125
+
126
+ it 'includes the inferno test kit metadata tag' do
127
+ error_message =
128
+ %(Add "spec.metadata['inferno_test_kit'] = 'true'" to #{test_kit_gem.name}.gemspec)
129
+
130
+ expect(test_kit_gem.metadata['inferno_test_kit']).to eq('true'), error_message
131
+ end
132
+ end
133
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inferno_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen MacVicar
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-12-17 00:00:00.000000000 Z
13
+ date: 2025-01-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -412,6 +412,7 @@ files:
412
412
  - lib/inferno/apps/cli/templates/.env.test
413
413
  - lib/inferno/apps/cli/templates/.gitignore
414
414
  - lib/inferno/apps/cli/templates/.rspec
415
+ - lib/inferno/apps/cli/templates/.rubocop.yml
415
416
  - lib/inferno/apps/cli/templates/.ruby-version
416
417
  - lib/inferno/apps/cli/templates/.tool-versions
417
418
  - lib/inferno/apps/cli/templates/Dockerfile.tt
@@ -534,6 +535,7 @@ files:
534
535
  - lib/inferno/entities/entity.rb
535
536
  - lib/inferno/entities/has_runnable.rb
536
537
  - lib/inferno/entities/header.rb
538
+ - lib/inferno/entities/ig.rb
537
539
  - lib/inferno/entities/input.rb
538
540
  - lib/inferno/entities/message.rb
539
541
  - lib/inferno/entities/preset.rb
@@ -557,8 +559,6 @@ files:
557
559
  - lib/inferno/jobs/invoke_validator_session.rb
558
560
  - lib/inferno/jobs/resume_test_run.rb
559
561
  - lib/inferno/public/0e0b993fd6ff351f435ff1c2938daf2d.png
560
- - lib/inferno/public/175.bundle.js
561
- - lib/inferno/public/217.bundle.js
562
562
  - lib/inferno/public/237.bundle.js
563
563
  - lib/inferno/public/a5cd39450ab0336db73c5e57228b649d.png
564
564
  - lib/inferno/public/assets.json
@@ -568,6 +568,7 @@ files:
568
568
  - lib/inferno/public/logo192.png
569
569
  - lib/inferno/repositories.rb
570
570
  - lib/inferno/repositories/headers.rb
571
+ - lib/inferno/repositories/igs.rb
571
572
  - lib/inferno/repositories/in_memory_repository.rb
572
573
  - lib/inferno/repositories/messages.rb
573
574
  - lib/inferno/repositories/presets.rb
@@ -586,6 +587,7 @@ files:
586
587
  - lib/inferno/repositories/validator_sessions.rb
587
588
  - lib/inferno/result_collection.rb
588
589
  - lib/inferno/result_summarizer.rb
590
+ - lib/inferno/route_storage.rb
589
591
  - lib/inferno/spec_support.rb
590
592
  - lib/inferno/test_runner.rb
591
593
  - lib/inferno/utils/ig_downloader.rb
@@ -599,6 +601,7 @@ files:
599
601
  - lib/inferno/utils/static_assets.rb
600
602
  - lib/inferno/utils/verify_runnable.rb
601
603
  - lib/inferno/version.rb
604
+ - spec/extract_tgz_helper.rb
602
605
  - spec/factories/header.rb
603
606
  - spec/factories/message.rb
604
607
  - spec/factories/request.rb
@@ -613,6 +616,7 @@ files:
613
616
  - spec/request_helper.rb
614
617
  - spec/runnable_context.rb
615
618
  - spec/runnable_helper.rb
619
+ - spec/shared/test_kit_examples.rb
616
620
  - spec/spec_helper.rb
617
621
  - spec/support/factory_bot.rb
618
622
  homepage: https://github.com/inferno-framework/inferno-core
@@ -631,14 +635,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
631
635
  requirements:
632
636
  - - "~>"
633
637
  - !ruby/object:Gem::Version
634
- version: 3.1.2
638
+ version: 3.3.6
635
639
  required_rubygems_version: !ruby/object:Gem::Requirement
636
640
  requirements:
637
641
  - - ">="
638
642
  - !ruby/object:Gem::Version
639
643
  version: '0'
640
644
  requirements: []
641
- rubygems_version: 3.3.7
645
+ rubygems_version: 3.5.22
642
646
  signing_key:
643
647
  specification_version: 4
644
648
  summary: Inferno Core is an open source tool for testing data exchanges enabled by
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[175],{9175:(t,e,n)=>{n.r(e),n.d(e,{getCLS:()=>d,getFCP:()=>m,getFID:()=>v,getLCP:()=>h,getTTFB:()=>S});var i,a,r=function(t){return{name:t,value:arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1,delta:0,entries:[],id:"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),isFinal:!1}},o=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},s=!1,u=!1,c=function(t){s=!t.persisted},p=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];u||(addEventListener("pagehide",c),addEventListener("beforeunload",(function(){})),u=!0),addEventListener("visibilitychange",(function(e){var n=e.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:n,isUnloading:s})}),{capture:!0,once:e})},l=function(t,e,n,i){var a;return function(){n&&e.isFinal&&n.disconnect(),e.value>=0&&(i||e.isFinal||"hidden"===document.visibilityState)&&(e.delta=e.value-(a||0),(e.delta||e.isFinal||void 0===a)&&(t(e),a=e.value))}},d=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=r("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},s=o("layout-shift",a);s&&(e=l(t,i,s,n),p((function(t){var n=t.isUnloading;s.takeRecords().map(a),n&&(i.isFinal=!0),e()})))},f=function(){return void 0===i&&(i="hidden"===document.visibilityState?0:1/0,p((function(t){var e=t.timeStamp;return i=e}),!0)),{get timeStamp(){return i}}},m=function(t){var e,n=r("FCP"),i=f(),a=o("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(n.value=t.startTime,n.isFinal=!0,n.entries.push(t),e())}));a&&(e=l(t,n,a))},v=function(t){var e=r("FID"),n=f(),i=function(t){t.startTime<n.timeStamp&&(e.value=t.processingStart-t.startTime,e.entries.push(t),e.isFinal=!0,s())},a=o("first-input",i),s=l(t,e,a);a?p((function(){a.takeRecords().map(i),a.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<n.timeStamp&&(e.value=t,e.isFinal=!0,e.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],s())}))},g=function(){return a||(a=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(e){addEventListener(e,t,{once:!0,passive:!0,capture:!0})}))}))),a},h=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=r("LCP"),a=f(),s=function(t){var n=t.startTime;n<a.timeStamp?(i.value=n,i.entries.push(t)):i.isFinal=!0,e()},u=o("largest-contentful-paint",s);if(u){e=l(t,i,u,n);var c=function(){i.isFinal||(u.takeRecords().map(s),i.isFinal=!0,e())};g().then(c),p(c,!0)}},S=function(t){var e,n=r("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],n.isFinal=!0,t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[217],{3217:(t,e,n)=>{n.r(e),n.d(e,{getCLS:()=>d,getFCP:()=>m,getFID:()=>v,getLCP:()=>h,getTTFB:()=>S});var i,a,r=function(t){return{name:t,value:arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1,delta:0,entries:[],id:"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),isFinal:!1}},o=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},s=!1,u=!1,c=function(t){s=!t.persisted},p=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];u||(addEventListener("pagehide",c),addEventListener("beforeunload",(function(){})),u=!0),addEventListener("visibilitychange",(function(e){var n=e.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:n,isUnloading:s})}),{capture:!0,once:e})},l=function(t,e,n,i){var a;return function(){n&&e.isFinal&&n.disconnect(),e.value>=0&&(i||e.isFinal||"hidden"===document.visibilityState)&&(e.delta=e.value-(a||0),(e.delta||e.isFinal||void 0===a)&&(t(e),a=e.value))}},d=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=r("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},s=o("layout-shift",a);s&&(e=l(t,i,s,n),p((function(t){var n=t.isUnloading;s.takeRecords().map(a),n&&(i.isFinal=!0),e()})))},f=function(){return void 0===i&&(i="hidden"===document.visibilityState?0:1/0,p((function(t){var e=t.timeStamp;return i=e}),!0)),{get timeStamp(){return i}}},m=function(t){var e,n=r("FCP"),i=f(),a=o("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(n.value=t.startTime,n.isFinal=!0,n.entries.push(t),e())}));a&&(e=l(t,n,a))},v=function(t){var e=r("FID"),n=f(),i=function(t){t.startTime<n.timeStamp&&(e.value=t.processingStart-t.startTime,e.entries.push(t),e.isFinal=!0,s())},a=o("first-input",i),s=l(t,e,a);a?p((function(){a.takeRecords().map(i),a.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<n.timeStamp&&(e.value=t,e.isFinal=!0,e.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],s())}))},g=function(){return a||(a=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(e){addEventListener(e,t,{once:!0,passive:!0,capture:!0})}))}))),a},h=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=r("LCP"),a=f(),s=function(t){var n=t.startTime;n<a.timeStamp?(i.value=n,i.entries.push(t)):i.isFinal=!0,e()},u=o("largest-contentful-paint",s);if(u){e=l(t,i,u,n);var c=function(){i.isFinal||(u.takeRecords().map(s),i.isFinal=!0,e())};g().then(c),p(c,!0)}},S=function(t){var e,n=r("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],n.isFinal=!0,t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)}}}]);