hqmf2js 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|