inferno_core 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ require_relative 'attributes'
2
+ require_relative '../exceptions'
3
+
4
+ module Inferno
5
+ module Entities
6
+ # This class represents an Input for a runnable.
7
+ class Input
8
+ ATTRIBUTES = [
9
+ :name,
10
+ :title,
11
+ :description,
12
+ :type,
13
+ :default,
14
+ :optional,
15
+ :options,
16
+ :locked
17
+ ].freeze
18
+ include Entities::Attributes
19
+
20
+ # These attributes require special handling when merging input
21
+ # definitions.
22
+ UNINHERITABLE_ATTRIBUTES = [
23
+ # Locking an input only has meaning at the level it is locked.
24
+ # Consider:
25
+ # - ParentGroup
26
+ # - Group 1, input :a
27
+ # - Group 2, input :a, locked: true
28
+ # The input 'a' should be only be locked when running Group 2 in
29
+ # isolation. It should not be locked when running Group 1 or the
30
+ # ParentGroup.
31
+ :locked,
32
+ # Input type is sometimes only a UI concern (e.g. text vs. textarea), so
33
+ # it is common to not redeclare the type everywhere it's used and needs
34
+ # special handling to avoid clobbering the type with the default (text)
35
+ # type.
36
+ :type
37
+ ].freeze
38
+
39
+ # These are the attributes that can be directly copied when merging a
40
+ # runnable's input with the input of one of its children.
41
+ INHERITABLE_ATTRIBUTES = (ATTRIBUTES - UNINHERITABLE_ATTRIBUTES).freeze
42
+
43
+ # These are the attributes that can be directly copied when merging a
44
+ # runnable's input with an input configuration.
45
+ MERGEABLE_ATTRIBUTES = (ATTRIBUTES - [:type]).freeze
46
+
47
+ def initialize(**params)
48
+ bad_params = params.keys - ATTRIBUTES
49
+
50
+ raise Exceptions::UnknownAttributeException.new(bad_params, self.class) if bad_params.present?
51
+
52
+ params
53
+ .compact
54
+ .each { |key, value| send("#{key}=", value) }
55
+
56
+ self.name = name.to_s if params[:name].present?
57
+ end
58
+
59
+ # @private
60
+ # Merge this input with an input belonging to a child. Fields defined on
61
+ # this input take precedence over those defined on the child input.
62
+ def merge_with_child(child_input)
63
+ return self if child_input.nil?
64
+
65
+ INHERITABLE_ATTRIBUTES.each do |attribute|
66
+ merge_attribute(attribute, primary_source: self, secondary_source: child_input)
67
+ end
68
+
69
+ self.type = child_input.type if child_input.present? && child_input.type != 'text'
70
+
71
+ self
72
+ end
73
+
74
+ # @private
75
+ # Merge this input with an input from a configuration. Fields defined in
76
+ # the configuration take precedence over those defined on this input.
77
+ def merge(other_input)
78
+ return self if other_input.nil?
79
+
80
+ MERGEABLE_ATTRIBUTES.each do |attribute|
81
+ merge_attribute(attribute, primary_source: other_input, secondary_source: self)
82
+ end
83
+
84
+ self.type = other_input.type if other_input.type.present? && other_input.type != 'text'
85
+
86
+ self
87
+ end
88
+
89
+ # @private
90
+ # Merge an individual attribute. If the primary source contains the
91
+ # attribute, that value will be used. Otherwise the value from the
92
+ # secondary source will be used.
93
+ # @param attribute [Symbol]
94
+ # @param primary_source [Input]
95
+ # @param secondary_source [Input]
96
+ def merge_attribute(attribute, primary_source:, secondary_source:)
97
+ value = primary_source.send(attribute)
98
+ value = secondary_source.send(attribute) if value.nil?
99
+
100
+ return if value.nil?
101
+
102
+ send("#{attribute}=", value)
103
+ end
104
+
105
+ def to_hash
106
+ ATTRIBUTES.each_with_object({}) do |attribute, hash|
107
+ value = send(attribute)
108
+ next if value.nil?
109
+
110
+ hash[attribute] = value
111
+ end
112
+ end
113
+
114
+ def ==(other)
115
+ return false unless other.is_a? Input
116
+
117
+ ATTRIBUTES.all? { |attribute| send(attribute) == other.send(attribute) }
118
+ end
119
+ end
120
+ end
121
+ end
@@ -60,7 +60,7 @@ module Inferno
60
60
  end
61
61
 
62
62
  def optional?
63
- runnable.optional?
63
+ runnable.nil? || runnable.optional?
64
64
  end
65
65
 
66
66
  def required?
@@ -122,16 +122,16 @@ module Inferno
122
122
  #
123
123
  # @param name [Symbol] name of the input
124
124
  # @param other_names [Symbol] array of symbols if specifying multiple inputs
125
- # @param input_definition [Hash] options for input such as type, description, or title
126
- # @option input_definition [String] :title Human readable title for input
127
- # @option input_definition [String] :description Description for the input
128
- # @option input_definition [String] :type 'text' | 'textarea'
125
+ # @param input_params [Hash] options for input such as type, description, or title
126
+ # @option input_params [String] :title Human readable title for input
127
+ # @option input_params [String] :description Description for the input
128
+ # @option input_params [String] :type 'text' | 'textarea'
129
129
  # @return [void]
130
130
  # @example
131
131
  # input :patientid, title: 'Patient ID', description: 'The ID of the patient being searched for'
132
132
  # @example
133
133
  # input :textarea, title: 'Textarea Input Example', type: 'textarea'
134
- def input(name, *other_names, **input_definition)
134
+ def input(name, *other_names, **input_params)
135
135
  super
136
136
 
137
137
  if other_names.present?
@@ -0,0 +1,59 @@
1
+ require 'json'
2
+
3
+ # Extension to FHIR::Model. Prepending this into FHIR::Model (done below)
4
+ # allows us to call super() on initialize when we overriding it,
5
+ # while also defining new methods and attributes
6
+ module InfernoFHIRModelExtensions
7
+ attr_accessor :source_hash, :source_text
8
+
9
+ def initialize(hash = {})
10
+ super(hash)
11
+ @source_hash = hash
12
+ end
13
+
14
+ def source_contents
15
+ @source_text || JSON.generate(@source_hash)
16
+ end
17
+ end
18
+
19
+ module FHIR
20
+ class Model
21
+ prepend ::InfernoFHIRModelExtensions
22
+ end
23
+ end
24
+
25
+ # Extension to FHIR::Json. Prepending this into FHIR::Json (done below)
26
+ # allows us to call super() on from_json
27
+ module InfernoJson
28
+ def from_json(json)
29
+ resource = super(json)
30
+ resource.source_text = json
31
+ resource
32
+ end
33
+ end
34
+
35
+ # Extension to FHIR::Xml. Prepending this into FHIR::Xml (done below)
36
+ # allows us to call super() on from_xml
37
+ module InfernoXml
38
+ def from_xml(xml)
39
+ resource = super(xml)
40
+ resource.source_text = xml
41
+ resource
42
+ end
43
+ end
44
+
45
+ module FHIR
46
+ module Json
47
+ class << self
48
+ prepend InfernoJson
49
+ end
50
+ end
51
+ end
52
+
53
+ module FHIR
54
+ module Xml
55
+ class << self
56
+ prepend InfernoXml
57
+ end
58
+ end
59
+ end