hqmf2js 1.2.1 → 1.3.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.
- checksums.yaml +15 -0
- data/.travis.yml +2 -5
- data/Gemfile +6 -4
- data/Gemfile.lock +83 -86
- data/Rakefile +9 -5
- data/app/assets/javascripts/hqmf_util.js.coffee +98 -23
- data/app/assets/javascripts/logging_utils.js.coffee +25 -16
- data/app/assets/javascripts/patient_api_extension.js.coffee +85 -0
- data/app/assets/javascripts/specifics.js.coffee +60 -14
- data/hqmf2js.gemspec +8 -8
- data/lib/assets/javascripts/libraries/map_reduce_utils.js +130 -0
- data/lib/generator/characteristic.js.erb +28 -17
- data/lib/generator/codes_to_json.rb +5 -5
- data/lib/generator/data_criteria.js.erb +5 -5
- data/lib/generator/execution.rb +144 -0
- data/lib/generator/js.rb +46 -21
- data/lib/generator/observation_criteria.js.erb +1 -1
- data/lib/generator/patient_data.js.erb +22 -19
- data/lib/generator/population_criteria.js.erb +6 -1
- data/lib/generator/precondition.js.erb +5 -7
- data/lib/hqmf2js.rb +1 -0
- data/test/fixtures/codes/codes.json +54 -0
- data/test/fixtures/json/0495.json +1014 -0
- data/test/fixtures/json/59New.json +148 -0
- data/test/fixtures/json/data_criteria/specific_occurrence.json +27 -0
- data/test/fixtures/json/data_criteria/temporals_with_anynonnull.json +27 -0
- data/test/fixtures/patients/larry_vanderman.json +4 -4
- data/test/simplecov.rb +19 -0
- data/test/test_helper.rb +1 -1
- data/test/unit/cmd_test.rb +92 -0
- data/test/unit/codes_to_json_test.rb +32 -0
- data/test/unit/erb_context_test.rb +64 -0
- data/test/unit/hqmf_from_json_javascript_test.rb +37 -2
- data/test/unit/hqmf_javascript_test.rb +18 -0
- data/test/unit/js_object_test.rb +27 -0
- data/test/unit/library_function_test.rb +22 -21
- data/test/unit/specifics_test.rb +7 -2
- metadata +16 -121
- data/lib/tasks/cover_me.rake +0 -8
data/lib/generator/js.rb
CHANGED
@@ -166,8 +166,12 @@ module HQMF2JS
|
|
166
166
|
def initialize(doc)
|
167
167
|
@doc = doc
|
168
168
|
end
|
169
|
+
|
170
|
+
def self.map_reduce_utils
|
171
|
+
File.read(File.expand_path(File.join('..', '..', "assets",'javascripts','libraries','map_reduce_utils.js'), __FILE__))
|
172
|
+
end
|
169
173
|
|
170
|
-
def to_js(population_index=0, codes=nil)
|
174
|
+
def to_js(population_index=0, codes=nil, force_sources=nil)
|
171
175
|
population_index ||= 0
|
172
176
|
population = @doc.populations[population_index]
|
173
177
|
|
@@ -177,14 +181,23 @@ module HQMF2JS
|
|
177
181
|
oid_dictionary = "<%= oid_dictionary %>"
|
178
182
|
end
|
179
183
|
|
184
|
+
sub_ids = ('a'..'zz').to_a
|
185
|
+
sub_id = @doc.populations.size > 1 ? "'#{sub_ids[population_index]}'" : "null";
|
186
|
+
|
187
|
+
|
180
188
|
"
|
181
189
|
// #########################
|
182
190
|
// ##### DATA ELEMENTS #####
|
183
191
|
// #########################
|
184
192
|
|
193
|
+
hqmfjs.nqf_id = '#{@doc.id}';
|
194
|
+
hqmfjs.hqmf_id = '#{@doc.hqmf_id}';
|
195
|
+
hqmfjs.sub_id = #{sub_id};
|
196
|
+
if (typeof(test_id) == 'undefined') hqmfjs.test_id = null;
|
197
|
+
|
185
198
|
OidDictionary = #{oid_dictionary};
|
186
199
|
|
187
|
-
#{js_for_data_criteria()}
|
200
|
+
#{js_for_data_criteria(force_sources)}
|
188
201
|
|
189
202
|
// #########################
|
190
203
|
// ##### MEASURE LOGIC #####
|
@@ -193,7 +206,7 @@ module HQMF2JS
|
|
193
206
|
#{js_initialize_specifics(@doc.source_data_criteria)}
|
194
207
|
|
195
208
|
// INITIAL PATIENT POPULATION
|
196
|
-
#{js_for(population[HQMF::PopulationCriteria::IPP], HQMF::PopulationCriteria::IPP
|
209
|
+
#{js_for(population[HQMF::PopulationCriteria::IPP], HQMF::PopulationCriteria::IPP)}
|
197
210
|
// DENOMINATOR
|
198
211
|
#{js_for(population[HQMF::PopulationCriteria::DENOM], HQMF::PopulationCriteria::DENOM, true)}
|
199
212
|
// NUMERATOR
|
@@ -236,29 +249,34 @@ module HQMF2JS
|
|
236
249
|
end
|
237
250
|
|
238
251
|
# Generate JS for a HQMF2::DataCriteria
|
239
|
-
def js_for_data_criteria
|
240
|
-
HQMF2JS::Generator.render_template('data_criteria', {'all_criteria' => @doc.specific_occurrence_source_data_criteria.concat(@doc.all_data_criteria), 'measure_period' => @doc.measure_period})
|
252
|
+
def js_for_data_criteria(force_sources=nil)
|
253
|
+
HQMF2JS::Generator.render_template('data_criteria', {'all_criteria' => @doc.specific_occurrence_source_data_criteria(force_sources).concat(@doc.all_data_criteria), 'measure_period' => @doc.measure_period})
|
241
254
|
end
|
242
255
|
|
243
|
-
def self.library_functions(check_crosswalk=false)
|
256
|
+
def self.library_functions(check_crosswalk=false, include_underscore=true)
|
244
257
|
ctx = Sprockets::Environment.new(File.expand_path("../../..", __FILE__))
|
245
258
|
Tilt::CoffeeScriptTemplate.default_bare = true
|
246
259
|
ctx.append_path "app/assets/javascripts"
|
247
260
|
|
248
|
-
libraries = [
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
261
|
+
libraries = []
|
262
|
+
|
263
|
+
if include_underscore
|
264
|
+
libraries += ["// #########################\n// ###### Underscore.js #######\n// #######################\n",
|
265
|
+
ctx.find_asset('underscore').to_s]
|
266
|
+
end
|
267
|
+
|
268
|
+
libraries += ["// #########################\n// ###### PATIENT API #######\n// #########################\n",
|
269
|
+
HqueryPatientApi::Generator.patient_api_javascript.to_s,
|
270
|
+
"// #########################\n// ## SPECIFIC OCCURRENCES ##\n// #########################\n",
|
271
|
+
ctx.find_asset('specifics').to_s,
|
272
|
+
"// #########################\n// ### LIBRARY FUNCTIONS ####\n// #########################\n",
|
273
|
+
ctx.find_asset('hqmf_util').to_s,
|
274
|
+
"// #########################\n// ### PATIENT EXTENSION ####\n// #########################\n",
|
275
|
+
ctx.find_asset('patient_api_extension').to_s,
|
276
|
+
"// #########################\n// ## CUSTOM CALCULATIONS ###\n// #########################\n",
|
277
|
+
ctx.find_asset('custom_calculations').to_s,
|
278
|
+
"// #########################\n// ##### LOGGING UTILS ######\n// #########################\n",
|
279
|
+
ctx.find_asset('logging_utils').to_s]
|
262
280
|
|
263
281
|
# check for code set crosswalks
|
264
282
|
if (check_crosswalk)
|
@@ -270,6 +288,13 @@ module HQMF2JS
|
|
270
288
|
|
271
289
|
end
|
272
290
|
|
291
|
+
# Allow crosswalk functionality to be loaded separately from main JS libraries
|
292
|
+
def self.crosswalk_functions
|
293
|
+
ctx = Sprockets::Environment.new(File.expand_path("../../..", __FILE__))
|
294
|
+
Tilt::CoffeeScriptTemplate.default_bare = true
|
295
|
+
ctx.append_path "app/assets/javascripts"
|
296
|
+
ctx.find_asset('crosswalk').to_s
|
297
|
+
end
|
273
298
|
end
|
274
299
|
|
275
300
|
# Simple class to issue monotonically increasing integer identifiers
|
@@ -293,4 +318,4 @@ module HQMF2JS
|
|
293
318
|
include Singleton
|
294
319
|
end
|
295
320
|
end
|
296
|
-
end
|
321
|
+
end
|
@@ -1,22 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
<%-
|
6
|
-
|
7
|
-
<%-
|
8
|
-
<%-
|
9
|
-
events = events.withNegation(<%= "getCodes(\"#{criteria.negation_code_list_id}\")" if criteria.negation_code_list_id %>);
|
10
|
-
<%- else -%>
|
11
|
-
events = events.withoutNegation();
|
12
|
-
<%- end -%>
|
13
|
-
var codes = <%= js_for_code_list(criteria) %>;
|
14
|
-
var start = null;
|
15
|
-
var end = null;
|
1
|
+
<%- eventType = patient_api_method(criteria) -%>
|
2
|
+
<%- valueSetId = criteria.code_list_id -%>
|
3
|
+
<%- valueSet = criteria.inline_code_list ? js_for_code_list(criteria) : nil -%>
|
4
|
+
<%- negationValueSetId = criteria.negation_code_list_id -%>
|
5
|
+
<%- statuses = criteria.status ? "[\"#{criteria.status}\"]" : nil -%>
|
6
|
+
<%- includeEventsWithoutStatus = criteria.hard_status ? false : true -%>
|
7
|
+
<%- start = nil -%>
|
8
|
+
<%- stop = nil -%>
|
16
9
|
<%- if criteria.effective_time -%>
|
17
10
|
<%- startExp = js_for_value(criteria.effective_time.low) -%>
|
18
|
-
start =
|
19
|
-
<%-
|
20
|
-
|
11
|
+
<%- start = startExp+'.asDate()' if startExp != 'null' -%>
|
12
|
+
<%- stopExp = js_for_value(criteria.effective_time.high) -%>
|
13
|
+
<%- stop = stopExp+'.asDate()' if stopExp != 'null' -%>
|
21
14
|
<%- end -%>
|
22
|
-
|
15
|
+
var eventCriteria = {"type": "<%= eventType %>"<%- -%>
|
16
|
+
<%= ", \"statuses\": #{statuses}" if statuses %> <%- -%>
|
17
|
+
<%= ", \"includeEventsWithoutStatus\": #{includeEventsWithoutStatus}" if includeEventsWithoutStatus %> <%- -%>
|
18
|
+
<%= ", \"negated\": #{criteria.negation}" if criteria.negation %> <%- -%>
|
19
|
+
<%= ", \"negationValueSetId\": \"#{negationValueSetId}\"" if criteria.negation && negationValueSetId %> <%- -%>
|
20
|
+
<%= ", \"valueSetId\": \"#{valueSetId}\"" if valueSetId %> <%- -%>
|
21
|
+
<%= ", \"valueSet\": #{valueSet}" if valueSet %> <%- -%>
|
22
|
+
<%= ", \"start\": #{start}" if start %> <%- -%>
|
23
|
+
<%= ", \"stop\": #{stop}" if stop %> <%- -%>
|
24
|
+
<%= ", \"specificOccurrence\": \"#{criteria.source_data_criteria}\"" if criteria.specific_occurrence %>};
|
25
|
+
var events = patient.getEvents(eventCriteria);
|
@@ -1,4 +1,9 @@
|
|
1
1
|
hqmfjs.<%= type %> = function(patient, initialSpecificContext) {
|
2
|
-
|
2
|
+
population_criteria_fn = <%= js_for_precondition(criteria, 0, true) -%>;
|
3
|
+
if (typeof(population_criteria_fn) == 'function') {
|
4
|
+
return population_criteria_fn();
|
5
|
+
} else {
|
6
|
+
return population_criteria_fn;
|
7
|
+
}
|
3
8
|
};
|
4
9
|
|
@@ -1,16 +1,14 @@
|
|
1
1
|
<%- if precondition.conjunction? -%>
|
2
2
|
<%- if indent>0 -%>
|
3
|
-
<%= "\n#{' '*(indent+1)}#{conjunction_code_for(precondition)}('#{precondition.id}'," -%>
|
3
|
+
<%= "\n#{' '*(indent+1)}#{conjunction_code_for(precondition)}('#{precondition.id}', patient, initialSpecificContext," -%>
|
4
4
|
<%- else -%>
|
5
|
-
<%= "#{conjunction_code_for(precondition)}('#{precondition.id}'," -%>
|
5
|
+
<%= "#{conjunction_code_for(precondition)}('#{precondition.id}', patient, initialSpecificContext," -%>
|
6
6
|
<%- end -%>
|
7
7
|
<%- precondition.preconditions.each_with_index do |child, index| -%>
|
8
|
-
<%= "#{
|
8
|
+
<%= "#{js_for_precondition(child, indent+1, context)}" -%>
|
9
9
|
<%= "," if index < precondition.preconditions.length-1 -%>
|
10
10
|
<%- end -%>
|
11
11
|
<%= "\n#{' '*(indent+1)})" -%>
|
12
|
-
<%-
|
13
|
-
<%= " hqmfjs.#{js_name(precondition.reference)}
|
14
|
-
<%- else -%>
|
15
|
-
<%= "\n#{' '*(indent+1)}hqmfjs.#{js_name(precondition.reference)}(patient)" -%>
|
12
|
+
<%- else # !precondition.conjunction? -%>
|
13
|
+
<%= " hqmfjs.#{js_name(precondition.reference)}" -%>
|
16
14
|
<%- end -%>
|
data/lib/hqmf2js.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
[{
|
2
|
+
"concepts": [
|
3
|
+
{
|
4
|
+
"code": "123A",
|
5
|
+
"code_system_name": "SNOMED-CT"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"code": "124B",
|
9
|
+
"code_system_name": "SNOMED-CT"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"code": "125C",
|
13
|
+
"code_system_name": "CPT"
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"code": "126D",
|
17
|
+
"code_system_name": "CPT"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"code": "127E",
|
21
|
+
"code_system_name": "CPT"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"display_name": "ABD-XYZ",
|
25
|
+
"oid": "1.2.3.4.6",
|
26
|
+
"version": "20130614"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"concepts": [
|
30
|
+
{
|
31
|
+
"code": "123",
|
32
|
+
"code_system_name": "SNOMED-CT"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"code": "124",
|
36
|
+
"code_system_name": "SNOMED-CT"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"code": "125",
|
40
|
+
"code_system_name": "SNOMED-CT"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"code": "126",
|
44
|
+
"code_system_name": "ICD-9-CM"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"code": "127",
|
48
|
+
"code_system_name": "ICD-9-CM"
|
49
|
+
}
|
50
|
+
],
|
51
|
+
"display_name": "ABC-XYZ",
|
52
|
+
"oid": "1.2.3.4.5",
|
53
|
+
"version": "20130614"
|
54
|
+
}]
|