hqmf2js 1.0.1 → 1.1.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.
- data/Gemfile +5 -10
- data/Gemfile.lock +70 -68
- data/app/assets/javascripts/custom_calculations.js.coffee +72 -0
- data/app/assets/javascripts/hqmf_util.js.coffee +97 -46
- data/app/assets/javascripts/logging_utils.js.coffee +0 -11
- data/app/assets/javascripts/specifics.js.coffee +211 -185
- data/app/assets/javascripts/underscore.js +1200 -0
- data/hqmf2js.gemspec +5 -5
- data/lib/generator/characteristic.js.erb +3 -3
- data/lib/generator/converter.rb +5 -5
- data/lib/generator/data_criteria.js.erb +8 -8
- data/lib/generator/js.rb +25 -5
- data/test/fixtures/codes/codes.xml +6 -0
- data/test/fixtures/patients/larry_vanderman.json +11 -1
- data/test/test_helper.rb +2 -3
- data/test/unit/codes_to_json_test.rb +1 -1
- data/test/unit/custom_calculations_test.rb +74 -0
- data/test/unit/hqmf_from_json_javascript_test.rb +9 -9
- data/test/unit/hqmf_javascript_test.rb +36 -14
- data/test/unit/library_function_test.rb +29 -11
- data/test/unit/specifics_test.rb +200 -82
- metadata +13 -9
- data/test/fixtures/patient_api.js +0 -2823
data/hqmf2js.gemspec
CHANGED
@@ -6,14 +6,14 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.description = "A library for converting HQMF files to executable JavaScript suitable for use with the hQuery Gateway"
|
7
7
|
s.email = "hquery-talk@googlegroups.com"
|
8
8
|
s.homepage = "http://github.com/hquery/hqmf2js"
|
9
|
-
s.authors = ["Marc Hadley"]
|
10
|
-
s.version = '1.0
|
9
|
+
s.authors = ["Marc Hadley", "Andre Quina", "Andy Gregorowicz"]
|
10
|
+
s.version = '1.1.0'
|
11
11
|
|
12
|
-
s.add_dependency 'nokogiri', '~> 1.5.
|
12
|
+
s.add_dependency 'nokogiri', '~> 1.5.5'
|
13
13
|
s.add_dependency 'tilt', '~> 1.3.3'
|
14
14
|
s.add_dependency 'coffee-script', '~> 2.2.0'
|
15
|
-
s.add_dependency 'sprockets', '~> 2.
|
16
|
-
s.add_development_dependency "awesome_print", "~> 0
|
15
|
+
s.add_dependency 'sprockets', '~> 2.2.2'
|
16
|
+
s.add_development_dependency "awesome_print", "~> 1.1.0"
|
17
17
|
|
18
18
|
s.files = s.files = `git ls-files`.split("\n")
|
19
19
|
end
|
@@ -6,14 +6,14 @@ var events = [value];
|
|
6
6
|
events = <%= temporal_reference.type %>(events, hqmfjs.<%= temporal_reference.reference.id %>(patient)<%= ", #{js_for_bounds(temporal_reference.range)}" if temporal_reference.range %>);
|
7
7
|
<%- end -%>
|
8
8
|
<%- end -%>
|
9
|
-
events.specificContext=
|
9
|
+
events.specificContext=hqmf.SpecificsManager.identity();
|
10
10
|
return events;
|
11
11
|
<%- elsif criteria.property == :expired or criteria.property == :clinicalTrialParticipant -%>
|
12
12
|
matching = matchingValue(value, 'true');
|
13
|
-
matching.specificContext=
|
13
|
+
matching.specificContext=hqmf.SpecificsManager.identity();
|
14
14
|
return matching
|
15
15
|
<%- else -%>
|
16
16
|
matching = matchingValue(value, <%= js_for_bounds(criteria.value) %>);
|
17
|
-
matching.specificContext=
|
17
|
+
matching.specificContext=hqmf.SpecificsManager.identity();
|
18
18
|
return matching;
|
19
19
|
<%- end -%>
|
data/lib/generator/converter.rb
CHANGED
@@ -25,17 +25,17 @@ module HQMF2JS
|
|
25
25
|
# Pretty stock map/reduce functions that call out to our converted HQMF code stored in the functions variable
|
26
26
|
map = "function map(patient) {
|
27
27
|
var ipp = hqmfjs.IPP(patient);
|
28
|
-
if (
|
28
|
+
if (hqmf.SpecificsManager.validate(ipp)) {
|
29
29
|
emit('ipp', 1);
|
30
|
-
if (
|
30
|
+
if (hqmf.SpecificsManager.validate(hqmfjs.DENEX(patient), ipp)) {
|
31
31
|
emit('denex', 1);
|
32
32
|
} else {
|
33
33
|
var denom = hqmfjs.DENOM(patient);
|
34
|
-
if (
|
35
|
-
if (
|
34
|
+
if (hqmf.SpecificsManager.validate(denom, ipp)) {
|
35
|
+
if (hqmf.SpecificsManager.validate(hqmfjs.NUMER(patient), denom, ipp)) {
|
36
36
|
emit('denom', 1);
|
37
37
|
emit('numer', 1);
|
38
|
-
} else if (
|
38
|
+
} else if (hqmf.SpecificsManager.validate(hqmfjs.DENEXCEP(patient), denom, ipp)) {
|
39
39
|
emit('excep', 1);
|
40
40
|
} else {
|
41
41
|
emit('denom', 1);
|
@@ -19,20 +19,20 @@ hqmfjs.<%= js_name(criteria) %> = function(patient) {
|
|
19
19
|
events = filterEventsByValue(events, <%= js_for_bounds(criteria.value) %>);
|
20
20
|
<%- end -%>
|
21
21
|
<%- if criteria.field_values.present?
|
22
|
-
criteria.field_values.keys.each do |field|
|
23
|
-
|
24
|
-
|
25
|
-
<%-
|
26
|
-
end -%>
|
22
|
+
criteria.field_values.keys.each do |field| -%>
|
23
|
+
events = <%= field_library_method(field) %>(events, "<%= field_method(field) %>", <%= js_for_bounds(criteria.field_values[field]) %>);
|
24
|
+
<%- end -%>
|
25
|
+
<%- end -%>
|
27
26
|
<%- if criteria.temporal_references and criteria.temporal_references.length > 0 -%>
|
28
27
|
<%- criteria.temporal_references.each do |temporal_reference| -%>
|
29
|
-
events = <%= temporal_reference.type %>(events, hqmfjs.<%= temporal_reference.reference.id %>(patient)<%= ", #{js_for_bounds(temporal_reference.range)}" if temporal_reference.range %>);
|
28
|
+
if (events.length > 0) events = <%= temporal_reference.type %>(events, hqmfjs.<%= temporal_reference.reference.id %>(patient)<%= ", #{js_for_bounds(temporal_reference.range)}" if temporal_reference.range %>);
|
29
|
+
else events.specificContext=hqmf.SpecificsManager.empty();
|
30
30
|
<%- end -%>
|
31
31
|
<%- else -%>
|
32
32
|
<%- if criteria.specific_occurrence -%>
|
33
|
-
events.specificContext=new
|
33
|
+
events.specificContext=new hqmf.SpecificOccurrence(Row.buildForDataCriteria(events.specific_occurrence, events))
|
34
34
|
<%- else -%>
|
35
|
-
events.specificContext=
|
35
|
+
events.specificContext=hqmf.SpecificsManager.identity()
|
36
36
|
<%- end -%>
|
37
37
|
<%- end -%>
|
38
38
|
<%- if criteria.subset_operators -%>
|
data/lib/generator/js.rb
CHANGED
@@ -46,6 +46,17 @@ module HQMF2JS
|
|
46
46
|
HQMF::DataCriteria::FIELDS[field_name][:coded_entry_method].to_s.camelize(:lower)
|
47
47
|
end
|
48
48
|
|
49
|
+
def field_library_method(field_name)
|
50
|
+
field_type = HQMF::DataCriteria::FIELDS[field_name][:field_type]
|
51
|
+
if field_type == :value
|
52
|
+
'filterEventsByField'
|
53
|
+
elsif field_type == :timestamp
|
54
|
+
'adjustBoundsForField'
|
55
|
+
elsif field_type == :nested_timestamp
|
56
|
+
'denormalizeEventsByLocation'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
49
60
|
def js_for_value(value)
|
50
61
|
if value
|
51
62
|
if value.respond_to?(:derived?) && value.derived?
|
@@ -119,6 +130,8 @@ module HQMF2JS
|
|
119
130
|
def js_for_code_list(criteria)
|
120
131
|
if criteria.inline_code_list
|
121
132
|
criteria.inline_code_list.to_json
|
133
|
+
elsif criteria.code_list_id.nil?
|
134
|
+
"null"
|
122
135
|
else
|
123
136
|
"getCodes(\"#{criteria.code_list_id}\")"
|
124
137
|
end
|
@@ -187,6 +200,8 @@ module HQMF2JS
|
|
187
200
|
#{js_for(population[HQMF::PopulationCriteria::NUMER], HQMF::PopulationCriteria::NUMER)}
|
188
201
|
#{js_for(population[HQMF::PopulationCriteria::DENEX], HQMF::PopulationCriteria::DENEX)}
|
189
202
|
#{js_for(population[HQMF::PopulationCriteria::DENEXCEP], HQMF::PopulationCriteria::DENEXCEP)}
|
203
|
+
// CV
|
204
|
+
#{js_for(population[HQMF::PopulationCriteria::MSRPOPL], HQMF::PopulationCriteria::MSRPOPL)}
|
190
205
|
"
|
191
206
|
end
|
192
207
|
|
@@ -200,7 +215,7 @@ module HQMF2JS
|
|
200
215
|
json_list = specific_occurrences.map {|occurrence| occurrence.to_json}
|
201
216
|
specifics_list = json_list.join(',')
|
202
217
|
specifics_list = ",#{specifics_list}" unless specifics_list.empty?
|
203
|
-
"hqmfjs.initializeSpecifics = function(patient_api, hqmfjs) {
|
218
|
+
"hqmfjs.initializeSpecifics = function(patient_api, hqmfjs) { hqmf.SpecificsManager.initialize(patient_api,hqmfjs#{specifics_list}) }"
|
204
219
|
end
|
205
220
|
|
206
221
|
# Generate JS for a HQMF2::PopulationCriteria
|
@@ -225,16 +240,21 @@ module HQMF2JS
|
|
225
240
|
Tilt::CoffeeScriptTemplate.default_bare = true
|
226
241
|
ctx.append_path "app/assets/javascripts"
|
227
242
|
|
228
|
-
["// #########################\n// ######
|
243
|
+
["// #########################\n// ###### Underscore.js #######\n// #######################\n",
|
244
|
+
ctx.find_asset('underscore').to_s,
|
245
|
+
"// #########################\n// ###### PATIENT API #######\n// #########################\n",
|
229
246
|
HqueryPatientApi::Generator.patient_api_javascript.to_s,
|
247
|
+
"// #########################\n// ## SPECIFIC OCCURRENCES ##\n// #########################\n",
|
248
|
+
ctx.find_asset('specifics').to_s,
|
230
249
|
"// #########################\n// ### LIBRARY FUNCTIONS ####\n// #########################\n",
|
231
250
|
ctx.find_asset('hqmf_util').to_s,
|
232
251
|
"// #########################\n// ### PATIENT EXTENSION ####\n// #########################\n",
|
233
252
|
ctx.find_asset('patient_api_extension').to_s,
|
253
|
+
"// #########################\n// ## CUSTOM CALCULATIONS ###\n// #########################\n",
|
254
|
+
ctx.find_asset('custom_calculations').to_s,
|
234
255
|
"// #########################\n// ##### LOGGING UTILS ######\n// #########################\n",
|
235
|
-
ctx.find_asset('logging_utils').to_s
|
236
|
-
|
237
|
-
ctx.find_asset('specifics').to_s].join("\n")
|
256
|
+
ctx.find_asset('logging_utils').to_s].join("\n")
|
257
|
+
|
238
258
|
end
|
239
259
|
|
240
260
|
end
|
@@ -6,6 +6,12 @@
|
|
6
6
|
codeSystemVersion="3"/>
|
7
7
|
</ConceptList>
|
8
8
|
</ValueSet>
|
9
|
+
<ValueSet id="2.16.840.1.113883.3.464.1.1142" displayName="diabetes">
|
10
|
+
<ConceptList xml:lang="en-US">
|
11
|
+
<Concept code="E10.36" codeSystemName="ICD-10-CM" displayName="Type 1 diabetes mellitus with diabetic cataract" codeSystemVersion="06/2009"/>
|
12
|
+
</ConceptList>
|
13
|
+
</ValueSet>
|
14
|
+
|
9
15
|
<ValueSet id="2.16.840.1.113883.3.464.1.37" displayName="diabetes">
|
10
16
|
<ConceptList xml:lang="en-US">
|
11
17
|
<Concept code="E10.36" codeSystemName="ICD-10-CM"
|
@@ -100,7 +100,16 @@
|
|
100
100
|
"V70.0"
|
101
101
|
]
|
102
102
|
},
|
103
|
-
"description": "Encounter Outpatient",
|
103
|
+
"description": "Encounter Outpatient",
|
104
|
+
"facility": {
|
105
|
+
"name": "Outpatient Clinic",
|
106
|
+
"start_time": 1290166000,
|
107
|
+
"end_time": 1291166000,
|
108
|
+
"code": {
|
109
|
+
"code": "bar",
|
110
|
+
"codeSystem": "SNOMED-CT"
|
111
|
+
}
|
112
|
+
},
|
104
113
|
"end_time": 1291266000
|
105
114
|
},
|
106
115
|
{
|
@@ -201,6 +210,7 @@
|
|
201
210
|
},
|
202
211
|
"description": "Foot Exam",
|
203
212
|
"time": 1291266000,
|
213
|
+
"incisionTime": 1112587200,
|
204
214
|
"values": [
|
205
215
|
{
|
206
216
|
"scalar": "Normal",
|
data/test/test_helper.rb
CHANGED
@@ -32,7 +32,6 @@ def get_js_context(javascript)
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def initialize_javascript_context(hqmf_utils, codes_json, converted_hqmf)
|
35
|
-
patient_api = File.open('test/fixtures/patient_api.js').read
|
36
35
|
fixture_json = File.read('test/fixtures/patients/larry_vanderman.json')
|
37
36
|
initialize_patient = 'var numeratorPatient = new hQuery.Patient(larry);'
|
38
37
|
|
@@ -41,13 +40,13 @@ def initialize_javascript_context(hqmf_utils, codes_json, converted_hqmf)
|
|
41
40
|
else
|
42
41
|
@context = V8::Context.new
|
43
42
|
end
|
44
|
-
@context.eval("
|
43
|
+
@context.eval("
|
45
44
|
#{hqmf_utils}
|
46
45
|
var OidDictionary = #{codes_json};
|
47
46
|
#{converted_hqmf}
|
48
47
|
var larry = #{fixture_json};
|
49
48
|
#{initialize_patient}")
|
50
|
-
@context.eval("
|
49
|
+
@context.eval("hqmf.SpecificsManager.initialize()")
|
51
50
|
end
|
52
51
|
|
53
52
|
def compile_coffee_script
|
@@ -14,7 +14,7 @@ class CodesToJsonTest < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
@context = get_js_context("var dictionary = #{codes_json}")
|
16
16
|
|
17
|
-
@context.eval("dictionary").entries.length.must_equal
|
17
|
+
@context.eval("dictionary").entries.length.must_equal 19
|
18
18
|
@context.eval("dictionary['2.16.840.1.113883.3.464.1.42']").entries.first[0].must_equal "CPT"
|
19
19
|
@context.eval("dictionary['2.16.840.1.113883.3.464.1.42']").entries.first[1].length.must_equal 19
|
20
20
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require 'hquery-patient-api'
|
3
|
+
|
4
|
+
class CustomCalculationsTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@context = get_js_context(HQMF2JS::Generator::JS.library_functions)
|
8
|
+
test_initialize_js =
|
9
|
+
"
|
10
|
+
inr1 = new hQuery.CodedEntry({time:#{Time.gm(2010,1,5).to_i}, values:[{scalar:'2.8'}]})
|
11
|
+
inr2 = new hQuery.CodedEntry({time:#{Time.gm(2010,1,18).to_i}, values:[{scalar:'3.5'}]})
|
12
|
+
inr3 = new hQuery.CodedEntry({time:#{Time.gm(2010,2,2).to_i}, values:[{scalar:'3.4'}]})
|
13
|
+
inr4 = new hQuery.CodedEntry({time:#{Time.gm(2010,2,15).to_i}, values:[{scalar:'3.9'}]})
|
14
|
+
inr5 = new hQuery.CodedEntry({time:#{Time.gm(2010,3,10).to_i}, values:[{scalar:'1.7'}]})
|
15
|
+
inr6 = new hQuery.CodedEntry({time:#{Time.gm(2010,3,24).to_i}, values:[{scalar:'2.3'}]})
|
16
|
+
inr7 = new hQuery.CodedEntry({time:#{Time.gm(2010,4,12).to_i}, values:[{scalar:'2.4'}]})
|
17
|
+
inr8 = new hQuery.CodedEntry({time:#{Time.gm(2010,5,13).to_i}, values:[{scalar:'3.2'}]})
|
18
|
+
inr9 = new hQuery.CodedEntry({time:#{Time.gm(2010,5,27).to_i}, values:[{scalar:'3.5'}]})
|
19
|
+
inr10 = new hQuery.CodedEntry({time:#{Time.gm(2010,6,10).to_i}, values:[{scalar:'3.5'}]})
|
20
|
+
inr11 = new hQuery.CodedEntry({time:#{Time.gm(2010,6,24).to_i}, values:[{scalar:'3.4'}]})
|
21
|
+
inr12 = new hQuery.CodedEntry({time:#{Time.gm(2010,7,8).to_i}, values:[{scalar:'2.1'}]})
|
22
|
+
inr13 = new hQuery.CodedEntry({time:#{Time.gm(2010,7,22).to_i}, values:[{scalar:'2.6'}]})
|
23
|
+
|
24
|
+
list = new hqmf.CustomCalc.PercentTTREntries([inr1,inr2,inr3,inr4,inr5,inr6,inr7,inr8,inr9,inr10,inr11,inr12,inr13])
|
25
|
+
|
26
|
+
inr_b1 = new hQuery.CodedEntry({time:#{Time.gm(2010,4,1).to_i}, values:[{scalar:'2.2'}]})
|
27
|
+
inr_b2 = new hQuery.CodedEntry({time:#{Time.gm(2010,5,7).to_i}, values:[{scalar:'2.0'}]})
|
28
|
+
inr_b3 = new hQuery.CodedEntry({time:#{Time.gm(2010,6,4).to_i}, values:[{scalar:'2.7'}]})
|
29
|
+
inr_b4 = new hQuery.CodedEntry({time:#{Time.gm(2010,7,10).to_i}, values:[{scalar:'2.2'}]})
|
30
|
+
inr_b5 = new hQuery.CodedEntry({time:#{Time.gm(2010,8,12).to_i}, values:[{scalar:'2.3'}]})
|
31
|
+
inr_b6 = new hQuery.CodedEntry({time:#{Time.gm(2010,9,11).to_i}, values:[{scalar:'2.8'}]})
|
32
|
+
inr_b7 = new hQuery.CodedEntry({time:#{Time.gm(2010,10,9).to_i}, values:[{scalar:'2.8'}]})
|
33
|
+
inr_b8 = new hQuery.CodedEntry({time:#{Time.gm(2010,10,17).to_i}, values:[{scalar:'2.1'}]})
|
34
|
+
inr_b9 = new hQuery.CodedEntry({time:#{Time.gm(2010,10,31).to_i}, values:[{scalar:'1.8'}]})
|
35
|
+
|
36
|
+
list2 = new hqmf.CustomCalc.PercentTTREntries([inr_b1,inr_b2,inr_b3,inr_b4,inr_b5,inr_b6,inr_b7,inr_b8,inr_b9])
|
37
|
+
"
|
38
|
+
@context.eval(test_initialize_js)
|
39
|
+
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def test_inr_results
|
45
|
+
@context.eval("typeof(hqmf.CustomCalc.PercentTTREntries) === 'function'").must_equal true
|
46
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr1,inr2) - 3.714285714285717) < .001")
|
47
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr2,inr3)) == 0 ")
|
48
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr3,inr4)) == 0")
|
49
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr4,inr5) - 10.45454545) < .001")
|
50
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr5,inr6) - 7) < .001")
|
51
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr6,inr7) - 19) < .001")
|
52
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr7,inr8) - 23.25) < .001")
|
53
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr8,inr9)) == 0")
|
54
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr9,inr10)) == 0")
|
55
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr10,inr11)) == 0")
|
56
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr11,inr12) - 9.692307692) < .001")
|
57
|
+
assert @context.eval("Math.abs(list.calculateDaysInRange(inr12,inr13) - 14) < .001")
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_total_number_of_days
|
62
|
+
@context.eval("list.totalNumberOfDays()").must_equal 198
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_calculate_ttr
|
66
|
+
assert @context.eval("Math.abs(list.calculateTTR() - 87.11113886) < .001")
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_calculate_percent_ttr
|
70
|
+
assert @context.eval("Math.abs(list.calculatePercentTTR() - 43.99552468) < .001")
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
@@ -33,17 +33,17 @@ class HqmfFromJsonJavascriptTest < Test::Unit::TestCase
|
|
33
33
|
def test_converted_hqmf
|
34
34
|
# Unspecified time bounds should be nil
|
35
35
|
assert_equal nil, @context.eval("numeratorPatient.encounters()[0].asIVL_TS().low.asDate()")
|
36
|
-
assert_equal 2010, @context.eval("numeratorPatient.encounters()[0].asIVL_TS().high.asDate().
|
36
|
+
assert_equal 2010, @context.eval("numeratorPatient.encounters()[0].asIVL_TS().high.asDate().getUTCFullYear()")
|
37
37
|
|
38
38
|
# Measure variables
|
39
|
-
assert_equal 2011, @context.eval("MeasurePeriod.low.asDate().
|
40
|
-
assert_equal 0, @context.eval("MeasurePeriod.low.asDate().
|
41
|
-
assert_equal 2011, @context.eval("MeasurePeriod.high.asDate().
|
42
|
-
assert_equal 11, @context.eval("MeasurePeriod.high.asDate().
|
43
|
-
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().
|
44
|
-
assert_equal 0, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().
|
45
|
-
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().
|
46
|
-
assert_equal 11, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().
|
39
|
+
assert_equal 2011, @context.eval("MeasurePeriod.low.asDate().getUTCFullYear()")
|
40
|
+
assert_equal 0, @context.eval("MeasurePeriod.low.asDate().getUTCMonth()")
|
41
|
+
assert_equal 2011, @context.eval("MeasurePeriod.high.asDate().getUTCFullYear()")
|
42
|
+
assert_equal 11, @context.eval("MeasurePeriod.high.asDate().getUTCMonth()")
|
43
|
+
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().getUTCFullYear()")
|
44
|
+
assert_equal 0, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().getUTCMonth()")
|
45
|
+
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().getUTCFullYear()")
|
46
|
+
assert_equal 11, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().getUTCMonth()")
|
47
47
|
|
48
48
|
# Age functions - Fixture is 37.1
|
49
49
|
assert @context.eval("hqmfjs.ageBetween17and64(numeratorPatient).isTrue()")
|
@@ -8,8 +8,6 @@ class HqmfJavascriptTest < Test::Unit::TestCase
|
|
8
8
|
doc = HQMF::Parser.parse(hqmf_contents, HQMF::Parser::HQMF_VERSION_2)
|
9
9
|
|
10
10
|
codes_file_path = File.expand_path("../../fixtures/codes/codes.xml", __FILE__)
|
11
|
-
# This patient is identified from Cypress as in the denominator and numerator for NQF59
|
12
|
-
numerator_patient_json = File.read('test/fixtures/patients/larry_vanderman.json')
|
13
11
|
|
14
12
|
# First compile the CoffeeScript that enables our converted HQMF JavaScript
|
15
13
|
hqmf_utils = compile_coffee_script
|
@@ -46,10 +44,8 @@ class HqmfJavascriptTest < Test::Unit::TestCase
|
|
46
44
|
def test_to_js_method
|
47
45
|
value = @converter.to_js(0,@codes_hash)
|
48
46
|
local_context = V8::Context.new
|
49
|
-
patient_api = File.open('test/fixtures/patient_api.js').read
|
50
47
|
hqmf_utils = HQMF2JS::Generator::JS.library_functions
|
51
|
-
local_context.eval("#{
|
52
|
-
#{hqmf_utils}
|
48
|
+
local_context.eval("#{hqmf_utils}
|
53
49
|
#{value}")
|
54
50
|
|
55
51
|
local_context.eval('typeof hqmfjs != undefined').must_equal true
|
@@ -62,17 +58,17 @@ class HqmfJavascriptTest < Test::Unit::TestCase
|
|
62
58
|
def test_converted_hqmf
|
63
59
|
# Unspecified time bounds should be nil
|
64
60
|
assert_equal nil, @context.eval("numeratorPatient.encounters()[0].asIVL_TS().low.asDate()")
|
65
|
-
assert_equal 2010, @context.eval("numeratorPatient.encounters()[0].asIVL_TS().high.asDate().
|
61
|
+
assert_equal 2010, @context.eval("numeratorPatient.encounters()[0].asIVL_TS().high.asDate().getUTCFullYear()")
|
66
62
|
|
67
63
|
# Measure variables
|
68
|
-
assert_equal 2011, @context.eval("MeasurePeriod.low.asDate().
|
69
|
-
assert_equal 0, @context.eval("MeasurePeriod.low.asDate().
|
70
|
-
assert_equal 2011, @context.eval("MeasurePeriod.high.asDate().
|
71
|
-
assert_equal 11, @context.eval("MeasurePeriod.high.asDate().
|
72
|
-
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().
|
73
|
-
assert_equal 0, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().
|
74
|
-
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().
|
75
|
-
assert_equal 11, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().
|
64
|
+
assert_equal 2011, @context.eval("MeasurePeriod.low.asDate().getUTCFullYear()")
|
65
|
+
assert_equal 0, @context.eval("MeasurePeriod.low.asDate().getUTCMonth()")
|
66
|
+
assert_equal 2011, @context.eval("MeasurePeriod.high.asDate().getUTCFullYear()")
|
67
|
+
assert_equal 11, @context.eval("MeasurePeriod.high.asDate().getUTCMonth()")
|
68
|
+
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().getUTCFullYear()")
|
69
|
+
assert_equal 0, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().getUTCMonth()")
|
70
|
+
assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().getUTCFullYear()")
|
71
|
+
assert_equal 11, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().getUTCMonth()")
|
76
72
|
|
77
73
|
# Age functions - Fixture is 37.1
|
78
74
|
assert @context.eval("hqmfjs.ageBetween17and64(numeratorPatient).isTrue()")
|
@@ -142,6 +138,32 @@ class HqmfJavascriptTest < Test::Unit::TestCase
|
|
142
138
|
# getCode
|
143
139
|
assert_equal 1, @context.eval('getCodes("2.16.840.1.113883.3.464.1.14")').count
|
144
140
|
assert_equal "00110", @context.eval('getCodes("2.16.840.1.113883.3.464.1.14")["HL7"][0]')
|
141
|
+
|
142
|
+
# adjustBoundsForField
|
143
|
+
@context.eval('var procedures = numeratorPatient.procedures()')
|
144
|
+
assert_equal 7, @context.eval('procedures.length')
|
145
|
+
assert_equal 2010, @context.eval('procedures[0].timeStamp().getFullYear()')
|
146
|
+
assert_equal true, @context.eval('procedures[0].includesCodeFrom({"SNOMED-CT": ["401191002"]})')
|
147
|
+
@context.eval('var updatedProcedures = adjustBoundsForField(procedures, "incisionTime")')
|
148
|
+
assert_equal 1, @context.eval('updatedProcedures.length')
|
149
|
+
assert_equal 2005, @context.eval('updatedProcedures[0].timeStamp().getFullYear()')
|
150
|
+
assert_equal true, @context.eval('updatedProcedures[0].includesCodeFrom({"SNOMED-CT": ["401191002"]})')
|
151
|
+
|
152
|
+
# denormalizeEventsByLocation
|
153
|
+
@context.eval('var normalizedEncounters = denormalizeEventsByLocation(numeratorPatient.encounters(), "facilityArrival")')
|
154
|
+
assert_equal 1, @context.eval('normalizedEncounters.length')
|
155
|
+
assert_equal 10, @context.eval('normalizedEncounters[0].startDate().getUTCMonth()')
|
156
|
+
assert_equal 19, @context.eval('normalizedEncounters[0].startDate().getUTCDate()')
|
157
|
+
assert_equal 10, @context.eval('normalizedEncounters[0].endDate().getUTCMonth()')
|
158
|
+
assert_equal 19, @context.eval('normalizedEncounters[0].endDate().getUTCDate()')
|
159
|
+
assert_equal 'bar', @context.eval('normalizedEncounters[0].facility().code()')
|
160
|
+
assert_equal 'SNOMED-CT', @context.eval('normalizedEncounters[0].facility().codeSystemName()')
|
161
|
+
@context.eval('normalizedEncounters = denormalizeEventsByLocation(numeratorPatient.encounters(), "facilityDeparture")')
|
162
|
+
assert_equal 1, @context.eval('normalizedEncounters.length')
|
163
|
+
assert_equal 11, @context.eval('normalizedEncounters[0].startDate().getUTCMonth()')
|
164
|
+
assert_equal 1, @context.eval('normalizedEncounters[0].startDate().getUTCDate()')
|
165
|
+
assert_equal 11, @context.eval('normalizedEncounters[0].endDate().getUTCMonth()')
|
166
|
+
assert_equal 1, @context.eval('normalizedEncounters[0].endDate().getUTCDate()')
|
145
167
|
end
|
146
168
|
|
147
169
|
def test_map_reduce_generation
|
@@ -5,7 +5,7 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
5
5
|
|
6
6
|
def setup
|
7
7
|
@context = get_js_context(HQMF2JS::Generator::JS.library_functions)
|
8
|
-
@context.eval("
|
8
|
+
@context.eval("hqmf.SpecificsManager.initialize()")
|
9
9
|
end
|
10
10
|
|
11
11
|
|
@@ -85,15 +85,15 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
85
85
|
ts = 'new TS("20110101")'
|
86
86
|
ts2 = 'new TS("20100101")'
|
87
87
|
ts3 = 'new TS("20120101")'
|
88
|
-
assert_equal 2011, @context.eval("#{ts}.asDate().
|
89
|
-
assert_equal 0, @context.eval("#{ts}.asDate().
|
90
|
-
assert_equal 1, @context.eval("#{ts}.asDate().
|
91
|
-
assert_equal 2012, @context.eval("#{ts}.add(new PQ(1, 'a')).asDate().
|
92
|
-
assert_equal 2, @context.eval("#{ts}.add(new PQ(1, 'd')).asDate().
|
93
|
-
assert_equal 8, @context.eval("#{ts}.add(new PQ(1, 'wk')).asDate().
|
94
|
-
assert_equal 1, @context.eval("#{ts}.add(new PQ(1, 'h')).asDate().
|
95
|
-
assert_equal 5, @context.eval("#{ts}.add(new PQ(5, 'min')).asDate().
|
96
|
-
assert_equal 11, @context.eval("#{ts}.add(new PQ(-1, 'mo')).asDate().
|
88
|
+
assert_equal 2011, @context.eval("#{ts}.asDate().getUTCFullYear()")
|
89
|
+
assert_equal 0, @context.eval("#{ts}.asDate().getUTCMonth()")
|
90
|
+
assert_equal 1, @context.eval("#{ts}.asDate().getUTCDate()")
|
91
|
+
assert_equal 2012, @context.eval("#{ts}.add(new PQ(1, 'a')).asDate().getUTCFullYear()")
|
92
|
+
assert_equal 2, @context.eval("#{ts}.add(new PQ(1, 'd')).asDate().getUTCDate()")
|
93
|
+
assert_equal 8, @context.eval("#{ts}.add(new PQ(1, 'wk')).asDate().getUTCDate()")
|
94
|
+
assert_equal 1, @context.eval("#{ts}.add(new PQ(1, 'h')).asDate().getUTCHours()")
|
95
|
+
assert_equal 5, @context.eval("#{ts}.add(new PQ(5, 'min')).asDate().getUTCMinutes()")
|
96
|
+
assert_equal 11, @context.eval("#{ts}.add(new PQ(-1, 'mo')).asDate().getUTCMonth()")
|
97
97
|
assert @context.eval("#{ts2}.before(#{ts})")
|
98
98
|
assert @context.eval("#{ts3}.after(#{ts})")
|
99
99
|
assert !@context.eval("#{ts}.before(#{ts2})")
|
@@ -260,7 +260,7 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
260
260
|
ivl1 = 'new IVL_TS(new TS("20120310"), new TS("20120320"))'
|
261
261
|
ivl2 = 'new IVL_TS(new TS("20120312"), new TS("20120320"))'
|
262
262
|
assert @context.eval("#{ivl2}.DURING(#{ivl1})")
|
263
|
-
assert_equal 2010, @context.eval('getIVL(new Date(2010,1,1)).low.asDate().
|
263
|
+
assert_equal 2010, @context.eval('getIVL(new Date(Date.UTC(2010,1,1))).low.asDate().getUTCFullYear()')
|
264
264
|
end
|
265
265
|
|
266
266
|
def test_any_non_null
|
@@ -336,6 +336,7 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
336
336
|
# Events and bounds for temporal operators
|
337
337
|
@context.eval('var events1 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120105"), new TS("20120105"));}}]')
|
338
338
|
@context.eval('var events2 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120102"), new TS("20120105"));}}]')
|
339
|
+
@context.eval('var events3 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120105203030"), new TS("20120105203030"));}}]')
|
339
340
|
@context.eval('var bound1 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120105"), new TS("20120105"));}}]')
|
340
341
|
@context.eval('var bound2 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120107"), new TS("20120107"));}}]')
|
341
342
|
@context.eval('var bound3 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120103"), new TS("20120107"));}}]')
|
@@ -344,8 +345,11 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
344
345
|
@context.eval('var nullStartBound = new IVL_TS(new TS("20120105"), new TS("20120105"));')
|
345
346
|
@context.eval('nullStartBound.low.date = null;')
|
346
347
|
@context.eval('var bound6 = {"asIVL_TS": function() {return nullStartBound;}}')
|
348
|
+
@context.eval('var bound7 = [{"asIVL_TS": function() {return new IVL_TS(new TS("20120105193030"), new TS("20120105193030"));}}]')
|
347
349
|
@context.eval('var range1 = new IVL_PQ(null, new PQ(1, "d"))')
|
348
350
|
@context.eval('var range2 = new IVL_PQ(new PQ(1, "d"), null)')
|
351
|
+
@context.eval('var range3 = new IVL_PQ(new PQ(0, "d"), null)')
|
352
|
+
@context.eval('var range4 = new IVL_PQ(null, new PQ(3, "d"))')
|
349
353
|
|
350
354
|
# DURING
|
351
355
|
assert_equal 1, @context.eval('DURING(events1, bound1)').count
|
@@ -408,6 +412,7 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
408
412
|
assert_equal 0, @context.eval('SBS(events2, bound1, range1)').count
|
409
413
|
assert_equal 1, @context.eval('SBS(events2, bound1)').count
|
410
414
|
assert_equal 1, @context.eval('SBS(events2, bound1, range2)').count
|
415
|
+
assert_equal 0, @context.eval('SBS(events3, bound7, range3)').count
|
411
416
|
|
412
417
|
# SAS
|
413
418
|
assert_equal 0, @context.eval('SAS(events1, bound1)').count
|
@@ -470,6 +475,19 @@ class LibraryFunctionTest < Test::Unit::TestCase
|
|
470
475
|
# CONCURRENT
|
471
476
|
assert_equal 1, @context.eval('CONCURRENT(events1, bound1)').count
|
472
477
|
assert_equal 0, @context.eval('CONCURRENT(events1, bound2)').count
|
478
|
+
|
479
|
+
#DATEDIFF
|
480
|
+
@context.eval('var diffEvent1 = {"asIVL_TS": function() {return new IVL_TS(new TS("20120105"), new TS("20120105"));}, "timeStamp": function() {return new Date(Date.UTC(2012, 1, 5, 0, 0));}}')
|
481
|
+
@context.eval('var diffEvent2 = {"asIVL_TS": function() {return new IVL_TS(new TS("20120107"), new TS("20120107"));}, "timeStamp": function() {return new Date(Date.UTC(2012, 1, 7, 0, 0));}}')
|
482
|
+
@context.eval('var diffEvent3 = {"asIVL_TS": function() {return new IVL_TS(new TS("20120111"), new TS("20120111"));}, "timeStamp": function() {return new Date(Date.UTC(2012, 1, 11, 0, 0));}}')
|
483
|
+
|
484
|
+
assert_equal true, @context.eval('DATEDIFF([diffEvent1,diffEvent2],range4).isTrue()')
|
485
|
+
assert_equal true, @context.eval('DATEDIFF([diffEvent2,diffEvent1],range4).isTrue()')
|
486
|
+
assert_equal true, @context.eval('DATEDIFF([diffEvent1,diffEvent1],range4).isTrue()')
|
487
|
+
|
488
|
+
# false test
|
489
|
+
|
490
|
+
|
473
491
|
end
|
474
492
|
|
475
493
|
def test_ordinal_operators
|