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.
Files changed (39) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +2 -5
  3. data/Gemfile +6 -4
  4. data/Gemfile.lock +83 -86
  5. data/Rakefile +9 -5
  6. data/app/assets/javascripts/hqmf_util.js.coffee +98 -23
  7. data/app/assets/javascripts/logging_utils.js.coffee +25 -16
  8. data/app/assets/javascripts/patient_api_extension.js.coffee +85 -0
  9. data/app/assets/javascripts/specifics.js.coffee +60 -14
  10. data/hqmf2js.gemspec +8 -8
  11. data/lib/assets/javascripts/libraries/map_reduce_utils.js +130 -0
  12. data/lib/generator/characteristic.js.erb +28 -17
  13. data/lib/generator/codes_to_json.rb +5 -5
  14. data/lib/generator/data_criteria.js.erb +5 -5
  15. data/lib/generator/execution.rb +144 -0
  16. data/lib/generator/js.rb +46 -21
  17. data/lib/generator/observation_criteria.js.erb +1 -1
  18. data/lib/generator/patient_data.js.erb +22 -19
  19. data/lib/generator/population_criteria.js.erb +6 -1
  20. data/lib/generator/precondition.js.erb +5 -7
  21. data/lib/hqmf2js.rb +1 -0
  22. data/test/fixtures/codes/codes.json +54 -0
  23. data/test/fixtures/json/0495.json +1014 -0
  24. data/test/fixtures/json/59New.json +148 -0
  25. data/test/fixtures/json/data_criteria/specific_occurrence.json +27 -0
  26. data/test/fixtures/json/data_criteria/temporals_with_anynonnull.json +27 -0
  27. data/test/fixtures/patients/larry_vanderman.json +4 -4
  28. data/test/simplecov.rb +19 -0
  29. data/test/test_helper.rb +1 -1
  30. data/test/unit/cmd_test.rb +92 -0
  31. data/test/unit/codes_to_json_test.rb +32 -0
  32. data/test/unit/erb_context_test.rb +64 -0
  33. data/test/unit/hqmf_from_json_javascript_test.rb +37 -2
  34. data/test/unit/hqmf_javascript_test.rb +18 -0
  35. data/test/unit/js_object_test.rb +27 -0
  36. data/test/unit/library_function_test.rb +22 -21
  37. data/test/unit/specifics_test.rb +7 -2
  38. metadata +16 -121
  39. data/lib/tasks/cover_me.rake +0 -8
@@ -552,6 +552,154 @@
552
552
  ]
553
553
  }
554
554
  },
555
+ "dead4MonthsBeforeMeasurePeriod": {
556
+ "title": "Deceased",
557
+ "description": "Patient Characteristic Expired: Deceased",
558
+ "standard_category": "individual_characteristic",
559
+ "qds_data_type": "individual_characteristic",
560
+ "code_list_id": "2.16.840.1.113883.3.67.1.101.11.721",
561
+ "property": "expired",
562
+ "type": "characteristic",
563
+ "definition": "patient_characteristic_expired",
564
+ "hard_status": false,
565
+ "negation": false,
566
+ "source_data_criteria": "PatientCharacteristicExpiredDeceased",
567
+ "inline_code_list": {
568
+ "SNOMED-CT": [
569
+ "18632008",
570
+ "371828006"
571
+ ]
572
+ },
573
+ "temporal_references": [
574
+ {
575
+ "type": "SBS",
576
+ "reference": "MeasurePeriod",
577
+ "range": {
578
+ "type": "IVL_PQ",
579
+ "low": {
580
+ "type": "PQ",
581
+ "unit": "mo",
582
+ "value": "4",
583
+ "inclusive?": true,
584
+ "derived?": false
585
+ }
586
+ }
587
+ }
588
+ ]
589
+ },
590
+ "dead3MonthsBeforeMeasurePeriod": {
591
+ "title": "Deceased",
592
+ "description": "Patient Characteristic Expired: Deceased",
593
+ "standard_category": "individual_characteristic",
594
+ "qds_data_type": "individual_characteristic",
595
+ "code_list_id": "2.16.840.1.113883.3.67.1.101.11.721",
596
+ "property": "expired",
597
+ "type": "characteristic",
598
+ "definition": "patient_characteristic_expired",
599
+ "hard_status": false,
600
+ "negation": false,
601
+ "source_data_criteria": "PatientCharacteristicExpiredDeceased",
602
+ "inline_code_list": {
603
+ "SNOMED-CT": [
604
+ "18632008",
605
+ "371828006"
606
+ ]
607
+ },
608
+ "temporal_references": [
609
+ {
610
+ "type": "SBS",
611
+ "reference": "MeasurePeriod",
612
+ "range": {
613
+ "type": "IVL_PQ",
614
+ "low": {
615
+ "type": "PQ",
616
+ "unit": "mo",
617
+ "value": "3",
618
+ "inclusive?": true,
619
+ "derived?": false
620
+ }
621
+ }
622
+ }
623
+ ]
624
+ },
625
+
626
+ "dead3MonthsAfterMeasurePeriod": {
627
+ "title": "Deceased",
628
+ "description": "Patient Characteristic Expired: Deceased",
629
+ "standard_category": "individual_characteristic",
630
+ "qds_data_type": "individual_characteristic",
631
+ "code_list_id": "2.16.840.1.113883.3.67.1.101.11.721",
632
+ "property": "expired",
633
+ "type": "characteristic",
634
+ "definition": "patient_characteristic_expired",
635
+ "hard_status": false,
636
+ "negation": false,
637
+ "source_data_criteria": "PatientCharacteristicExpiredDeceased",
638
+ "inline_code_list": {
639
+ "SNOMED-CT": [
640
+ "18632008",
641
+ "371828006"
642
+ ]
643
+ },
644
+ "temporal_references": [
645
+ {
646
+ "type": "SAS",
647
+ "reference": "MeasurePeriod",
648
+ "range": {
649
+ "type": "IVL_PQ",
650
+ "low": {
651
+ "type": "PQ",
652
+ "unit": "mo",
653
+ "value": "3",
654
+ "inclusive?": true,
655
+ "derived?": false
656
+ }
657
+ }
658
+ }
659
+ ]
660
+ },
661
+ "deadBetween5and6MonthsDuringMeasurePeriod": {
662
+ "title": "Deceased",
663
+ "description": "Patient Characteristic Expired: Deceased",
664
+ "standard_category": "individual_characteristic",
665
+ "qds_data_type": "individual_characteristic",
666
+ "code_list_id": "2.16.840.1.113883.3.67.1.101.11.721",
667
+ "property": "expired",
668
+ "type": "characteristic",
669
+ "definition": "patient_characteristic_expired",
670
+ "hard_status": false,
671
+ "negation": false,
672
+ "source_data_criteria": "PatientCharacteristicExpiredDeceased",
673
+ "inline_code_list": {
674
+ "SNOMED-CT": [
675
+ "18632008",
676
+ "371828006"
677
+ ]
678
+ },
679
+ "temporal_references": [
680
+ {
681
+ "type": "SAS",
682
+ "reference": "MeasurePeriod",
683
+ "range": {
684
+ "type": "IVL_PQ",
685
+ "low": {
686
+ "type": "PQ",
687
+ "unit": "mo",
688
+ "value": "5",
689
+ "inclusive?": true,
690
+ "derived?": false
691
+ },
692
+ "high": {
693
+ "type": "PQ",
694
+ "unit": "mo",
695
+ "value": "6",
696
+ "inclusive?": true,
697
+ "derived?": false
698
+ }
699
+ }
700
+ }
701
+ ]
702
+ },
555
703
  "genderMale": {
556
704
  "title": "Gender",
557
705
  "standard_category": "individual_characteristic",
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "Inpatient Encounter",
3
+ "description": "Encounter, Performed: Inpatient Encounter",
4
+ "standard_category": "encounter",
5
+ "qds_data_type": "encounter",
6
+ "code_list_id": "2.16.840.1.113883.3.117.1.7.1.23",
7
+ "type": "encounters",
8
+ "definition": "encounter",
9
+ "status": "performed",
10
+ "hard_status": false,
11
+ "negation": false,
12
+ "specific_occurrence": "A",
13
+ "specific_occurrence_const": "ENCOUNTER_PERFORMED_INPATIENT_ENCOUNTER",
14
+ "source_data_criteria": "OccurrenceAInpatientEncounter1",
15
+ "field_values": {
16
+ "LENGTH_OF_STAY": {
17
+ "type": "IVL_PQ",
18
+ "high": {
19
+ "type": "PQ",
20
+ "unit": "d",
21
+ "value": "120",
22
+ "inclusive?": true,
23
+ "derived?": false
24
+ }
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "Inpatient Encounter",
3
+ "description": "Encounter, Performed: Inpatient Encounter",
4
+ "standard_category": "encounter",
5
+ "qds_data_type": "encounter",
6
+ "code_list_id": "2.16.840.1.113883.3.117.1.7.1.23",
7
+ "type": "encounters",
8
+ "definition": "encounter",
9
+ "status": "performed",
10
+ "hard_status": false,
11
+ "negation": false,
12
+ "specific_occurrence": "A",
13
+ "specific_occurrence_const": "ENCOUNTER_PERFORMED_INPATIENT_ENCOUNTER",
14
+ "source_data_criteria": "OccurrenceAInpatientEncounter11",
15
+ "field_values": {
16
+ "DISCHARGE_DATETIME": {
17
+ "type": "ANYNonNull"
18
+ }
19
+ },
20
+ "temporal_references": [
21
+ {
22
+ "type": "SBE",
23
+ "reference": "MeasurePeriod",
24
+ "title": "MeasurePeriod"
25
+ }
26
+ ]
27
+ }
@@ -159,10 +159,10 @@
159
159
  },
160
160
  "description": "Insulin",
161
161
  "time": 1278475200,
162
- "cumulativeMedicationDuration" : {
163
- "scalar": 6,
164
- "unit": "d"
165
- }
162
+ "administrationTiming" : {"period": {"unit": "h", "value": 8 }},
163
+ "fulfillmentHistory": [
164
+ {"dispenseDate": 1278475200, "quantityDispensed" : {"value" :"15"}}
165
+ ]
166
166
  },
167
167
  {
168
168
  "codes": {
data/test/simplecov.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'simplecov'
2
+ SimpleCov.command_name 'Unit Tests'
3
+ SimpleCov.start do
4
+ add_filter "test/"
5
+ add_filter "vendor/"
6
+ add_group "Generator", "lib/generator"
7
+ add_group "Engine", "lib/hquery"
8
+ end
9
+
10
+ class SimpleCov::Formatter::QualityFormatter
11
+ def format(result)
12
+ SimpleCov::Formatter::HTMLFormatter.new.format(result)
13
+ File.open("coverage/covered_percent", "w") do |f|
14
+ f.puts result.source_files.covered_percent.to_f
15
+ end
16
+ end
17
+ end
18
+
19
+ SimpleCov.formatter = SimpleCov::Formatter::QualityFormatter
data/test/test_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'cover_me'
1
+ require_relative "./simplecov"
2
2
  require 'test/unit'
3
3
  require 'turn'
4
4
 
@@ -0,0 +1,92 @@
1
+ require_relative '../test_helper'
2
+ require 'hquery-patient-api'
3
+
4
+ class CmdTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @context = get_js_context(HQMF2JS::Generator::JS.library_functions)
8
+ end
9
+
10
+ def test_does_per_day
11
+ #administrative timeing in days
12
+ assert_equal (1/3.0),@context.eval("new hQuery.AdministrationTiming({'period' : {'unit': 'd' , 'value': 3 }}).dosesPerDay()"), "Administrative Timing every 3 days should == 1/3"
13
+ assert_equal 3,@context.eval("new hQuery.AdministrationTiming({'period' : {'unit': 'h' , 'value': 8 }}).dosesPerDay()"), "Administrative Timing every 8 hours should == 3 doses"
14
+ assert_equal (24.0/5),@context.eval("new hQuery.AdministrationTiming({'period' : {'unit': 'h' , 'value': 5 }}).dosesPerDay()"), "Administrative Timing every 5 hours should == 3 doses"
15
+ assert_equal (24.0/30),@context.eval("new hQuery.AdministrationTiming({'period' : {'unit': 'h' , 'value': 30 }}).dosesPerDay()"), "Administrative Timing every 30 hours should == 24/30 doses"
16
+ end
17
+
18
+ def test_days_in_range
19
+
20
+ @context.eval("var range = new IVL_TS(new TS('20100101'), new TS('20101231'))")
21
+ @context.eval("var perDay = 3;")
22
+ scs = @context.eval(%{var scs = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2010,01,01).to_i} , "quantityDispensed" : {"value" :"30"}}) })
23
+ during = @context.eval(%{var during = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2010,02,02).to_i} , "quantityDispensed" : {"value" :"30"}})})
24
+ sbs = @context.eval(%{ var sbs = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2009,12,25).to_i} , "quantityDispensed" : {"value" :"30"}}) })
25
+ sae = @context.eval(%{ var sae = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2011,01,01).to_i} , "quantityDispensed" :{"value" :"30"}}) })
26
+ eae = @context.eval(%{ var eae = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2010,12,25).to_i} , "quantityDispensed" : {"value" :"30"}}) })
27
+ ebs = @context.eval(%{ var ebs = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2009,02,02).to_i} , "quantityDispensed" : {"value" :"30"}}) })
28
+ ece = @context.eval(%{ var ece = new hQuery.Fulfillment({"dispenseDate": #{Time.utc(2010,12,21).to_i} , "quantityDispensed" : {"value" :"30"}}) })
29
+
30
+ assert_equal 10 , @context.eval("during.daysInRange(range, perDay)"), "Should be 10 days during"
31
+ assert_equal 10 , @context.eval("scs.daysInRange(range, perDay)"), "Should be 10 days starting concurrent with the start range"
32
+ assert_equal 3, @context.eval("sbs.daysInRange(range, perDay)"), "Should be 4 days overlap for starting before the start of the range"
33
+ assert_equal 0, @context.eval("sae.daysInRange(range, perDay)"), "Should be 0 days starting after end"
34
+ assert_equal 6, @context.eval("eae.daysInRange(range, perDay)"), "Should be 6 days overlap ending after the end of date range"
35
+ assert_equal 0, @context.eval("ebs.daysInRange(range, perDay)"), "Should be 0 days overlap ending before the start of the date range"
36
+ assert_equal 10, @context.eval("ece.daysInRange(range, perDay)"), "Should be 10 days when ending concurrent with the end"
37
+
38
+ @context.eval("var perDay = 1/3;") #every 3 days
39
+
40
+ assert_equal 90 , @context.eval("during.daysInRange(range, perDay)"), "Should be 10 days during"
41
+ assert_equal 90 , @context.eval("scs.daysInRange(range, perDay)"), "Should be 10 days starting concurrent with the start range"
42
+ assert_equal 90-7, @context.eval("sbs.daysInRange(range, perDay)"), "Should be 4 days overlap for starting before the start of the range"
43
+ assert_equal 0, @context.eval("sae.daysInRange(range, perDay)"), "Should be 0 days starting after end"
44
+ assert_equal 6, @context.eval("eae.daysInRange(range, perDay)"), "Should be 6 days overlap starting after the end of date range"
45
+ assert_equal 0, @context.eval("ebs.daysInRange(range, perDay)"), "Should be 0 days overlap ending before the start of the date range"
46
+ assert_equal 10, @context.eval("ece.daysInRange(range, perDay)"), "Should be 10 days when ending concurrent with the end"
47
+
48
+ @context.eval("range = new IVL_TS(null, new TS('20101231'))")
49
+ assert_equal 90, @context.eval("during.daysInRange(range, perDay)"), "Should be 90 when not supplied a start date"
50
+
51
+ @context.eval("range = new IVL_TS(new TS('20100301'), null)")
52
+ assert_equal 63, @context.eval("during.daysInRange(range, perDay)"), "Should be 90 when not supplied an end date date"
53
+
54
+ end
55
+
56
+ def test_cumulativeMedicationDuration
57
+ medication1 = %{
58
+ {
59
+ "administrationTiming" :{'period' : {'unit': 'h' , 'value': 8 }},
60
+ "fulfillmentHistory": [
61
+ {"dispenseDate": #{Time.utc(2010,01,01).to_i} , "quantityDispensed" : {"value" :"30"}}
62
+ ]
63
+ }
64
+ }
65
+
66
+ medication2 = %{
67
+ {
68
+ "administrationTiming" :{'period' : {'unit': 'h' , 'value': 8 }},
69
+ "fulfillmentHistory": [
70
+ {"dispenseDate": #{Time.utc(2010,01,01).to_i} , "quantityDispensed" : {"value" :"30"}},
71
+ {"dispenseDate": #{Time.utc(2010,10,01).to_i} , "quantityDispensed" : {"value" :"90"}}
72
+ ]
73
+ }
74
+ }
75
+
76
+ no_history = %{
77
+ {
78
+ "administrationTiming" :{'period' : {'unit': 'h' , 'value': 8 }},
79
+ "fulfillmentHistory": []
80
+ }
81
+ }
82
+ @context.eval("var med = new hQuery.Medication(#{medication1})")
83
+ @context.eval("var med2 = new hQuery.Medication(#{medication2})")
84
+ @context.eval("var no_meds = new hQuery.Medication(#{no_history})")
85
+ @context.eval("var range = new IVL_TS(new TS('20100101'), new TS('20101231'))")
86
+ assert_equal 10, @context.eval("med.cumulativeMedicationDuration(range)"), "CMD should be 10"
87
+ assert_equal 40, @context.eval("med2.cumulativeMedicationDuration(range)"), "CMD should be 10"
88
+ assert_equal 0, @context.eval("no_meds.cumulativeMedicationDuration(range)"), "CMD should be 10"
89
+ end
90
+
91
+
92
+ end
@@ -20,5 +20,37 @@ class CodesToJsonTest < Test::Unit::TestCase
20
20
 
21
21
  end
22
22
 
23
+ def test_codes_to_json
24
+ value_sets = JSON.parse(File.read(File.join('test','fixtures','codes','codes.json'))).map {|vs| HealthDataStandards::SVS::ValueSet.new(vs)}
25
+ oid_map = HQMF2JS::Generator::CodesToJson.from_value_sets(value_sets)
26
+
27
+ oid_map.keys.sort.must_equal ["1.2.3.4.5","1.2.3.4.6"]
28
+ oid_map["1.2.3.4.5"].keys.sort.must_equal ["ICD-9-CM","SNOMED-CT"]
29
+ oid_map["1.2.3.4.5"]["ICD-9-CM"].sort.must_equal ["126", "127"]
30
+ oid_map["1.2.3.4.5"]["SNOMED-CT"].sort.must_equal ["123", "124", "125"]
31
+ oid_map["1.2.3.4.6"].keys.sort.must_equal ["CPT","SNOMED-CT"]
32
+ oid_map["1.2.3.4.6"]["CPT"].sort.must_equal ["125C", "126D", "127E"]
33
+ oid_map["1.2.3.4.6"]["SNOMED-CT"].sort.must_equal ["123A", "124B"]
34
+
35
+ # def self.from_value_sets(value_sets)
36
+ # # make sure we have a string keyed hash
37
+ # value_sets = JSON.parse(value_sets.to_json)
38
+ # translation = {}
39
+ # value_sets.each do |value_set|
40
+ # code_sets = {}
41
+ # value_set["concepts"].each do |code_set|
42
+ # code_sets[code_set["code_system_name"]] ||= []
43
+ # code_sets[code_set["code_system_name"]].concat(code_set["code"].to_a)
44
+ # end
45
+
46
+ # translation[value_set["oid"]] = code_sets
47
+ # end
48
+
49
+ # translation
50
+ # end
51
+
52
+
53
+ end
54
+
23
55
 
24
56
  end
@@ -0,0 +1,64 @@
1
+ require_relative '../test_helper'
2
+
3
+ class ErbContextTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_data_criteria_js
9
+
10
+ context = HQMF2JS::Generator::ErbContext.new({})
11
+
12
+ criteria = HQMF::DataCriteria.from_json(nil, JSON.parse(File.read(File.join('test','fixtures','json','data_criteria','temporals_with_anynonnull.json'))))
13
+
14
+ get_codes = context.js_for_code_list(criteria)
15
+ get_codes.must_equal "getCodes(\"2.16.840.1.113883.3.117.1.7.1.23\")"
16
+ criteria.instance_variable_set(:@code_list_id, nil)
17
+ get_codes = context.js_for_code_list(criteria)
18
+ get_codes.must_equal "null"
19
+
20
+ date_bound = context.js_for_date_bound(criteria)
21
+ date_bound.must_equal "MeasurePeriod.high.asDate()"
22
+
23
+ criteria.temporal_references[0].instance_variable_set(:@type,"FOO")
24
+ exception = assert_raise RuntimeError do
25
+ context.js_for_date_bound(criteria)
26
+ end
27
+ exception.message.must_equal "do not know how to get a date for this type"
28
+ end
29
+
30
+ def test_value_js
31
+ context = HQMF2JS::Generator::ErbContext.new({})
32
+ value = HQMF::Value.from_json({"type" => "ANYNonNull"})
33
+ result = context.js_for_value(value)
34
+ result.must_equal "new ANYNonNull()"
35
+
36
+
37
+ value = HQMF::Value.from_json({"type"=>"SCALAR", "unit"=>"mm[Hg]", "value"=>"90", "inclusive?"=>false, "derived?"=>false } )
38
+ result = context.js_for_value(value)
39
+ result.must_equal "new SCALAR(90, \"mm[Hg]\", false)"
40
+
41
+ value = HQMF::Value.from_json({"type"=>"SCALAR", "unit"=>nil, "value"=>"90", "inclusive?"=>true, "derived?"=>false } )
42
+ result = context.js_for_value(value)
43
+ result.must_equal "new SCALAR(\"90\", null, true)"
44
+
45
+ value = HQMF::Value.from_json({"type"=>"SCALAR", "unit"=>nil, "value"=>"90", "inclusive?"=>nil, "derived?"=>false } )
46
+ value.instance_variable_set(:@inclusive, nil)
47
+ result = context.js_for_value(value)
48
+ result.must_equal "new SCALAR(\"90\")"
49
+
50
+ end
51
+
52
+ def test_field_library_method
53
+ context = HQMF2JS::Generator::ErbContext.new({})
54
+ result = context.field_library_method('ADMISSION_DATETIME')
55
+ result.must_equal "adjustBoundsForField"
56
+
57
+ context = HQMF2JS::Generator::ErbContext.new({})
58
+ result = context.field_library_method('FACILITY_LOCATION_ARRIVAL_DATETIME')
59
+ result.must_equal "denormalizeEventsByLocation"
60
+ end
61
+
62
+
63
+
64
+ end
@@ -44,7 +44,7 @@ class HqmfFromJsonJavascriptTest < Test::Unit::TestCase
44
44
  assert_equal 0, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().low.asDate().getUTCMonth()")
45
45
  assert_equal 2011, @context.eval("hqmfjs.MeasurePeriod()[0].asIVL_TS().high.asDate().getUTCFullYear()")
46
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()")
50
50
  assert @context.eval("hqmfjs.ageBetween30and39(numeratorPatient).isTrue()")
@@ -53,6 +53,42 @@ class HqmfFromJsonJavascriptTest < Test::Unit::TestCase
53
53
  assert !@context.eval("hqmfjs.ageBetween40and49(numeratorPatient).isTrue()")
54
54
  assert !@context.eval("hqmfjs.ageBetween50and59(numeratorPatient).isTrue()")
55
55
  assert !@context.eval("hqmfjs.ageBetween60and64(numeratorPatient).isTrue()")
56
+
57
+
58
+ # record does not have a death date so false
59
+ assert !@context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
60
+ assert !@context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
61
+ assert !@context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
62
+
63
+ @context.eval("numeratorPatient.json['deathdate']=#{Time.utc(2010,11).to_i}")
64
+ assert !@context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
65
+ assert !@context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
66
+ assert !@context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
67
+
68
+ @context.eval("numeratorPatient.json['deathdate']=#{Time.utc(2010,10).to_i}")
69
+ assert @context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
70
+ assert !@context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
71
+ assert !@context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
72
+
73
+ @context.eval("numeratorPatient.json['deathdate']=#{Time.utc(2011,2).to_i}")
74
+ assert !@context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
75
+ assert !@context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
76
+ assert !@context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
77
+
78
+ @context.eval("numeratorPatient.json['deathdate']=#{Time.utc(2011,4).to_i}")
79
+ assert !@context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
80
+ assert @context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
81
+ assert !@context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
82
+
83
+ @context.eval("numeratorPatient.json['deathdate']=#{Time.utc(2011,6).to_i}")
84
+ assert !@context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
85
+ assert @context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
86
+ assert @context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
87
+
88
+ @context.eval("numeratorPatient.json['deathdate']=#{Time.utc(2011,9).to_i}")
89
+ assert !@context.eval("hqmfjs.dead3MonthsBeforeMeasurePeriod(numeratorPatient).isTrue()")
90
+ assert @context.eval("hqmfjs.dead3MonthsAfterMeasurePeriod(numeratorPatient).isTrue()")
91
+ assert !@context.eval("hqmfjs.deadBetween5and6MonthsDuringMeasurePeriod(numeratorPatient).isTrue()")
56
92
 
57
93
  # Birthdate function
58
94
  assert_equal 1, @context.eval("hqmfjs.birthdateThirtyYearsBeforeMeasurementPeriod(numeratorPatient)").count
@@ -80,7 +116,6 @@ class HqmfFromJsonJavascriptTest < Test::Unit::TestCase
80
116
 
81
117
  # Results
82
118
  assert_equal 2, @context.eval("hqmfjs.HbA1C(numeratorPatient).length")
83
-
84
119
  # Medications
85
120
  assert_equal 1, @context.eval("hqmfjs.DiabetesMedAdministered(numeratorPatient).length")
86
121
  assert_equal 1, @context.eval("hqmfjs.DiabetesMedAdministeredFor7Days(numeratorPatient).length")
@@ -1,4 +1,5 @@
1
1
  require_relative '../test_helper'
2
+ require 'hquery-patient-api'
2
3
 
3
4
  class HqmfJavascriptTest < Test::Unit::TestCase
4
5
  def setup
@@ -54,6 +55,11 @@ class HqmfJavascriptTest < Test::Unit::TestCase
54
55
  local_context.eval('typeof hqmfjs.NUMER != undefined').must_equal true
55
56
  local_context.eval('typeof hqmfjs.DENOM != undefined').must_equal true
56
57
  end
58
+
59
+ def test_to_js_method_without_codes
60
+ value = @converter.to_js(0,nil)
61
+ assert !value.match(/<%= oid_dictionary %>/).nil?
62
+ end
57
63
 
58
64
  def test_converted_hqmf
59
65
  # Unspecified time bounds should be nil
@@ -129,6 +135,18 @@ class HqmfJavascriptTest < Test::Unit::TestCase
129
135
  assert_equal 1, @context.eval("hqmfjs.allDiabetes(numeratorPatient).length")
130
136
  end
131
137
 
138
+ def test_cached_access
139
+ eventCriteria = '{"type": "results", "statuses": [], "includeEventsWithoutStatus": true, "negated": false, "valueSet": getCodes("2.16.840.1.113883.3.464.1.72")}'
140
+ assert_equal 3, @context.eval("numeratorPatient.getEvents(#{eventCriteria}).length")
141
+ end
142
+
143
+ def test_measure_with_observ
144
+ measure = HQMF::Document.from_json(JSON.parse(File.read(File.join('test','fixtures','json','0495.json'))))
145
+ c = HQMF2JS::Generator::JS.new(measure)
146
+ result = c.js_for('OBSERV',HQMF::PopulationCriteria::OBSERV)
147
+ assert !result.match(/hqmfjs.OBSERV = function/).nil?
148
+ end
149
+
132
150
  def test_converted_utils
133
151
  # Filter events by value - HbA1C as an example
134
152
  events = 'numeratorPatient.results().match(getCodes("2.16.840.1.113883.3.464.1.72"))'
@@ -0,0 +1,27 @@
1
+ require_relative '../test_helper'
2
+ require 'hquery-patient-api'
3
+
4
+ class JSObjectTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ end
8
+
9
+ def test_library_functions_with_crosswalk
10
+ result = HQMF2JS::Generator::JS.library_functions(true)
11
+ assert !result.match(/CROSSWALK EXTENSION/).nil?
12
+ assert !result.match(/CrosswalkManager/).nil?
13
+ end
14
+
15
+ def test_js_initialize_specifics
16
+ js = HQMF2JS::Generator::JS.new nil
17
+ criteria = HQMF::DataCriteria.from_json(nil, JSON.parse(File.read(File.join('test','fixtures','json','data_criteria','specific_occurrence.json'))))
18
+ expected = "hqmfjs.initializeSpecifics = function(patient_api, hqmfjs) { hqmf.SpecificsManager.initialize(patient_api,hqmfjs,{\"id\":\"\",\"type\":\"ENCOUNTER_PERFORMED_INPATIENT_ENCOUNTER\",\"function\":\"OccurrenceAInpatientEncounter1\"}) }"
19
+ result = js.js_initialize_specifics([criteria])
20
+ result.must_equal expected
21
+ end
22
+
23
+ def test_to_js_without_codes
24
+ end
25
+
26
+
27
+ end
@@ -17,31 +17,31 @@ class LibraryFunctionTest < Test::Unit::TestCase
17
17
  end
18
18
 
19
19
  def test_all_true
20
- @context.eval('allTrue(1,new Boolean(false),new Boolean(false),new Boolean(false)).isTrue()').must_equal false
21
- @context.eval('allTrue(1,new Boolean(false),new Boolean(true),new Boolean(false)).isTrue()').must_equal false
22
- @context.eval('allTrue(1,new Boolean(true),new Boolean(true),new Boolean(true)).isTrue()').must_equal true
23
- @context.eval('allTrue(1).isTrue()').must_equal false
20
+ @context.eval('allTrue(1,null,null,new Boolean(false),new Boolean(false),new Boolean(false))().isTrue()').must_equal false
21
+ @context.eval('allTrue(1,null,null,new Boolean(false),new Boolean(true),new Boolean(false))().isTrue()').must_equal false
22
+ @context.eval('allTrue(1,null,null,new Boolean(true),new Boolean(true),new Boolean(true))().isTrue()').must_equal true
23
+ @context.eval('allTrue(1,null,null)().isTrue()').must_equal false
24
24
  end
25
25
 
26
26
  def test_at_least_one_true
27
- @context.eval('atLeastOneTrue(1,new Boolean(true),new Boolean(false),new Boolean(false)).isTrue()').must_equal true
28
- @context.eval('atLeastOneTrue(1,new Boolean(true),new Boolean(true),new Boolean(true)).isTrue()').must_equal true
29
- @context.eval('atLeastOneTrue(1,new Boolean(false),new Boolean(false),new Boolean(false)).isTrue()').must_equal false
30
- @context.eval('atLeastOneTrue(1).isTrue()').must_equal false
27
+ @context.eval('atLeastOneTrue(1,null,null,new Boolean(true),new Boolean(false),new Boolean(false))().isTrue()').must_equal true
28
+ @context.eval('atLeastOneTrue(1,null,null,new Boolean(true),new Boolean(true),new Boolean(true))().isTrue()').must_equal true
29
+ @context.eval('atLeastOneTrue(1,null,null,new Boolean(false),new Boolean(false),new Boolean(false))().isTrue()').must_equal false
30
+ @context.eval('atLeastOneTrue(1,null,null)().isTrue()').must_equal false
31
31
  end
32
32
 
33
33
  def test_all_false
34
- @context.eval('allFalse(1,new Boolean(false),new Boolean(false),new Boolean(false)).isTrue()').must_equal true
35
- @context.eval('allFalse(1,new Boolean(false),new Boolean(true),new Boolean(false)).isTrue()').must_equal false
36
- @context.eval('allFalse(1,new Boolean(true),new Boolean(true),new Boolean(true)).isTrue()').must_equal false
37
- @context.eval('allFalse(1).isTrue()').must_equal false
34
+ @context.eval('allFalse(1,null,null,new Boolean(false),new Boolean(false),new Boolean(false))().isTrue()').must_equal true
35
+ @context.eval('allFalse(1,null,null,new Boolean(false),new Boolean(true),new Boolean(false))().isTrue()').must_equal false
36
+ @context.eval('allFalse(1,null,null,new Boolean(true),new Boolean(true),new Boolean(true))().isTrue()').must_equal false
37
+ @context.eval('allFalse(1,null,null)().isTrue()').must_equal false
38
38
  end
39
39
 
40
40
  def test_at_least_one_false
41
- @context.eval('atLeastOneFalse(1,new Boolean(true),new Boolean(false),new Boolean(false)).isTrue()').must_equal true
42
- @context.eval('atLeastOneFalse(1,new Boolean(true),new Boolean(true),new Boolean(true)).isTrue()').must_equal false
43
- @context.eval('atLeastOneFalse(1,new Boolean(false),new Boolean(false),new Boolean(false)).isTrue()').must_equal true
44
- @context.eval('atLeastOneFalse(1).isTrue()').must_equal false
41
+ @context.eval('atLeastOneFalse(1,null,null,new Boolean(true),new Boolean(false),new Boolean(false))().isTrue()').must_equal true
42
+ @context.eval('atLeastOneFalse(1,null,null,new Boolean(true),new Boolean(true),new Boolean(true))().isTrue()').must_equal false
43
+ @context.eval('atLeastOneFalse(1,null,null,new Boolean(false),new Boolean(false),new Boolean(false))().isTrue()').must_equal true
44
+ @context.eval('atLeastOneFalse(1,null,null)().isTrue()').must_equal false
45
45
  end
46
46
 
47
47
  def test_patient_extensions
@@ -53,6 +53,7 @@ class LibraryFunctionTest < Test::Unit::TestCase
53
53
  @context.eval('typeof hQuery.Patient.prototype.activeDiagnoses').must_equal "function"
54
54
  @context.eval('typeof hQuery.Patient.prototype.inactiveDiagnoses').must_equal "function"
55
55
  @context.eval('typeof hQuery.Patient.prototype.resolvedDiagnoses').must_equal "function"
56
+ @context.eval('typeof hQuery.Patient.prototype.getEvents').must_equal "function"
56
57
  end
57
58
 
58
59
  def test_code_list
@@ -500,11 +501,11 @@ class LibraryFunctionTest < Test::Unit::TestCase
500
501
 
501
502
  def test_ordinal_operators
502
503
  # Ordinal operators
503
- ts20100101 = '{"timeStamp": function() {return new Date(2010,0,1);}}'
504
- ts20100201 = '{"timeStamp": function() {return new Date(2010,1,1);}}'
505
- ts20100301 = '{"timeStamp": function() {return new Date(2010,2,1);}}'
506
- ts20100401 = '{"timeStamp": function() {return new Date(2010,3,1);}}'
507
- ts20100501 = '{"timeStamp": function() {return new Date(2010,4,1);}}'
504
+ ts20100101 = '{"timeStamp": function() {return new Date(2010,0,1);}, "asIVL_TS": function() {return new IVL_TS(new TS("20100101"), new TS("20100101"));}}'
505
+ ts20100201 = '{"timeStamp": function() {return new Date(2010,1,1);}, "asIVL_TS": function() {return new IVL_TS(new TS("20100201"), new TS("20100201"));}}'
506
+ ts20100301 = '{"timeStamp": function() {return new Date(2010,2,1);}, "asIVL_TS": function() {return new IVL_TS(new TS("20100301"), new TS("20100301"));}}'
507
+ ts20100401 = '{"timeStamp": function() {return new Date(2010,3,1);}, "asIVL_TS": function() {return new IVL_TS(new TS("20100401"), new TS("20100401"));}}'
508
+ ts20100501 = '{"timeStamp": function() {return new Date(2010,4,1);}, "asIVL_TS": function() {return new IVL_TS(new TS("20100501"), new TS("20100501"));}}'
508
509
  events0 = "[]"
509
510
  events1 = "[#{ts20100101}]"
510
511
  events2 = "[#{ts20100101},#{ts20100201}]"