hqmf2js 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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}]"