inferno_core 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)}}}]);