conceptql 0.0.1

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 (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/CHANGELOG.md +17 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +28 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +108 -0
  8. data/Rakefile +1 -0
  9. data/bin/conceptql +5 -0
  10. data/conceptql.gemspec +30 -0
  11. data/doc/ConceptQL Specification (alpha).pdf +0 -0
  12. data/doc/diagram_0.png +0 -0
  13. data/doc/spec.md +1208 -0
  14. data/lib/conceptql/behaviors/dottable.rb +71 -0
  15. data/lib/conceptql/cli.rb +135 -0
  16. data/lib/conceptql/date_adjuster.rb +45 -0
  17. data/lib/conceptql/graph.rb +49 -0
  18. data/lib/conceptql/graph_nodifier.rb +123 -0
  19. data/lib/conceptql/logger.rb +10 -0
  20. data/lib/conceptql/nodes/after.rb +12 -0
  21. data/lib/conceptql/nodes/before.rb +11 -0
  22. data/lib/conceptql/nodes/binary_operator_node.rb +41 -0
  23. data/lib/conceptql/nodes/casting_node.rb +75 -0
  24. data/lib/conceptql/nodes/complement.rb +16 -0
  25. data/lib/conceptql/nodes/concept.rb +38 -0
  26. data/lib/conceptql/nodes/condition_type.rb +63 -0
  27. data/lib/conceptql/nodes/cpt.rb +20 -0
  28. data/lib/conceptql/nodes/date_range.rb +39 -0
  29. data/lib/conceptql/nodes/death.rb +19 -0
  30. data/lib/conceptql/nodes/during.rb +16 -0
  31. data/lib/conceptql/nodes/except.rb +11 -0
  32. data/lib/conceptql/nodes/first.rb +24 -0
  33. data/lib/conceptql/nodes/from.rb +15 -0
  34. data/lib/conceptql/nodes/gender.rb +27 -0
  35. data/lib/conceptql/nodes/hcpcs.rb +20 -0
  36. data/lib/conceptql/nodes/icd10.rb +23 -0
  37. data/lib/conceptql/nodes/icd9.rb +23 -0
  38. data/lib/conceptql/nodes/icd9_procedure.rb +20 -0
  39. data/lib/conceptql/nodes/intersect.rb +29 -0
  40. data/lib/conceptql/nodes/last.rb +24 -0
  41. data/lib/conceptql/nodes/loinc.rb +20 -0
  42. data/lib/conceptql/nodes/node.rb +71 -0
  43. data/lib/conceptql/nodes/occurrence.rb +47 -0
  44. data/lib/conceptql/nodes/pass_thru.rb +11 -0
  45. data/lib/conceptql/nodes/person.rb +25 -0
  46. data/lib/conceptql/nodes/person_filter.rb +12 -0
  47. data/lib/conceptql/nodes/place_of_service_code.rb +23 -0
  48. data/lib/conceptql/nodes/procedure_occurrence.rb +21 -0
  49. data/lib/conceptql/nodes/race.rb +23 -0
  50. data/lib/conceptql/nodes/rxnorm.rb +20 -0
  51. data/lib/conceptql/nodes/snomed.rb +19 -0
  52. data/lib/conceptql/nodes/source_vocabulary_node.rb +54 -0
  53. data/lib/conceptql/nodes/standard_vocabulary_node.rb +43 -0
  54. data/lib/conceptql/nodes/started_by.rb +16 -0
  55. data/lib/conceptql/nodes/temporal_node.rb +25 -0
  56. data/lib/conceptql/nodes/time_window.rb +54 -0
  57. data/lib/conceptql/nodes/union.rb +15 -0
  58. data/lib/conceptql/nodes/visit.rb +11 -0
  59. data/lib/conceptql/nodes/visit_occurrence.rb +26 -0
  60. data/lib/conceptql/nodifier.rb +9 -0
  61. data/lib/conceptql/query.rb +39 -0
  62. data/lib/conceptql/tree.rb +36 -0
  63. data/lib/conceptql/version.rb +3 -0
  64. data/lib/conceptql/view_maker.rb +56 -0
  65. data/lib/conceptql.rb +7 -0
  66. data/spec/conceptql/behaviors/dottable_spec.rb +111 -0
  67. data/spec/conceptql/date_adjuster_spec.rb +68 -0
  68. data/spec/conceptql/nodes/after_spec.rb +18 -0
  69. data/spec/conceptql/nodes/before_spec.rb +18 -0
  70. data/spec/conceptql/nodes/casting_node_spec.rb +73 -0
  71. data/spec/conceptql/nodes/complement_spec.rb +15 -0
  72. data/spec/conceptql/nodes/concept_spec.rb +34 -0
  73. data/spec/conceptql/nodes/condition_type_spec.rb +113 -0
  74. data/spec/conceptql/nodes/cpt_spec.rb +31 -0
  75. data/spec/conceptql/nodes/date_range_spec.rb +35 -0
  76. data/spec/conceptql/nodes/death_spec.rb +12 -0
  77. data/spec/conceptql/nodes/during_spec.rb +32 -0
  78. data/spec/conceptql/nodes/except_spec.rb +18 -0
  79. data/spec/conceptql/nodes/first_spec.rb +37 -0
  80. data/spec/conceptql/nodes/from_spec.rb +15 -0
  81. data/spec/conceptql/nodes/gender_spec.rb +29 -0
  82. data/spec/conceptql/nodes/hcpcs_spec.rb +31 -0
  83. data/spec/conceptql/nodes/icd10_spec.rb +36 -0
  84. data/spec/conceptql/nodes/icd9_procedure_spec.rb +31 -0
  85. data/spec/conceptql/nodes/icd9_spec.rb +36 -0
  86. data/spec/conceptql/nodes/intersect_spec.rb +33 -0
  87. data/spec/conceptql/nodes/last_spec.rb +38 -0
  88. data/spec/conceptql/nodes/loinc_spec.rb +31 -0
  89. data/spec/conceptql/nodes/occurrence_spec.rb +89 -0
  90. data/spec/conceptql/nodes/person_filter_spec.rb +18 -0
  91. data/spec/conceptql/nodes/person_spec.rb +12 -0
  92. data/spec/conceptql/nodes/place_of_service_code_spec.rb +26 -0
  93. data/spec/conceptql/nodes/procedure_occurrence_spec.rb +12 -0
  94. data/spec/conceptql/nodes/query_double.rb +19 -0
  95. data/spec/conceptql/nodes/race_spec.rb +23 -0
  96. data/spec/conceptql/nodes/rxnorm_spec.rb +31 -0
  97. data/spec/conceptql/nodes/snomed_spec.rb +31 -0
  98. data/spec/conceptql/nodes/source_vocabulary_node_spec.rb +37 -0
  99. data/spec/conceptql/nodes/standard_vocabulary_node_spec.rb +40 -0
  100. data/spec/conceptql/nodes/started_by_spec.rb +25 -0
  101. data/spec/conceptql/nodes/temporal_node_spec.rb +57 -0
  102. data/spec/conceptql/nodes/time_window_spec.rb +66 -0
  103. data/spec/conceptql/nodes/union_spec.rb +25 -0
  104. data/spec/conceptql/nodes/visit_occurrence_spec.rb +12 -0
  105. data/spec/conceptql/query_spec.rb +20 -0
  106. data/spec/conceptql/tree_spec.rb +54 -0
  107. data/spec/doubles/stream_for_casting_double.rb +9 -0
  108. data/spec/doubles/stream_for_occurrence_double.rb +21 -0
  109. data/spec/doubles/stream_for_temporal_double.rb +6 -0
  110. data/spec/spec_helper.rb +74 -0
  111. metadata +327 -0
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/concept'
3
+
4
+ describe ConceptQL::Nodes::Concept do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Concept.new.must_behave_like(:evaluator)
7
+ end
8
+
9
+ class ConceptDouble < ConceptQL::Nodes::Concept
10
+ def arguments
11
+ [1]
12
+ end
13
+
14
+ def set_statement(value)
15
+ # Do Nothing
16
+ end
17
+
18
+ def stream
19
+ @stream ||= Minitest::Mock.new
20
+ end
21
+ end
22
+
23
+ describe '#query' do
24
+ it 'evaluates child' do
25
+ cd = ConceptDouble.new(1)
26
+ cd.stream.expect :evaluate, nil, [:db]
27
+ cd.query(:db)
28
+ cd.stream.verify
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/condition_type'
3
+
4
+ describe ConceptQL::Nodes::ConditionType do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::ConditionType.new.must_behave_like(:evaluator)
7
+ end
8
+
9
+ describe '#query' do
10
+ it 'works for inpatient_detail_primary' do
11
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000183))"
12
+ ConceptQL::Nodes::ConditionType.new(:inpatient_detail_primary).query(Sequel.mock).sql.must_equal correct_query
13
+ end
14
+
15
+ it 'works for inpatient_detail_1' do
16
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000184))"
17
+ ConceptQL::Nodes::ConditionType.new(:inpatient_detail_1).query(Sequel.mock).sql.must_equal correct_query
18
+ end
19
+
20
+ it 'works for inpatient_detail_2' do
21
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000185))"
22
+ ConceptQL::Nodes::ConditionType.new(:inpatient_detail_2).query(Sequel.mock).sql.must_equal correct_query
23
+ end
24
+
25
+ it 'works for inpatient_header_primary' do
26
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000199))"
27
+ ConceptQL::Nodes::ConditionType.new(:inpatient_header_primary).query(Sequel.mock).sql.must_equal correct_query
28
+ end
29
+
30
+ it 'works for inpatient_header_1' do
31
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000200))"
32
+ ConceptQL::Nodes::ConditionType.new(:inpatient_header_1).query(Sequel.mock).sql.must_equal correct_query
33
+ end
34
+
35
+ it 'works for outpatient_detail_1' do
36
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000215))"
37
+ ConceptQL::Nodes::ConditionType.new(:outpatient_detail_1).query(Sequel.mock).sql.must_equal correct_query
38
+ end
39
+
40
+ it 'works for outpatient_header_1' do
41
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000230))"
42
+ ConceptQL::Nodes::ConditionType.new(:outpatient_header_1).query(Sequel.mock).sql.must_equal correct_query
43
+ end
44
+
45
+ it 'works for ehr_problem_list' do
46
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000245))"
47
+ ConceptQL::Nodes::ConditionType.new(:ehr_problem_list).query(Sequel.mock).sql.must_equal correct_query
48
+ end
49
+
50
+ it 'works for condition_era_0_day_window' do
51
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000246))"
52
+ ConceptQL::Nodes::ConditionType.new(:condition_era_0_day_window).query(Sequel.mock).sql.must_equal correct_query
53
+ end
54
+
55
+ it 'works for condition_era_30_day_window' do
56
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000247))"
57
+ ConceptQL::Nodes::ConditionType.new(:condition_era_30_day_window).query(Sequel.mock).sql.must_equal correct_query
58
+ end
59
+
60
+ describe 'with multiple arguments' do
61
+ it 'works for inpatient_detail_1' do
62
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000184, 38000185))"
63
+ ConceptQL::Nodes::ConditionType.new(:inpatient_detail_1, :inpatient_detail_2).query(Sequel.mock).sql.must_equal correct_query
64
+ end
65
+ end
66
+
67
+ describe 'with arguments as strings' do
68
+ it 'works for inpatient_detail_1' do
69
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000184, 38000185))"
70
+ ConceptQL::Nodes::ConditionType.new('inpatient_detail_1', 'inpatient_detail_2').query(Sequel.mock).sql.must_equal correct_query
71
+ end
72
+ end
73
+
74
+ describe 'as category' do
75
+ it 'works for inpatient_detail' do
76
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000183, 38000184, 38000185, 38000186, 38000187, 38000188, 38000189, 38000190, 38000191, 38000192, 38000193, 38000194, 38000195, 38000196, 38000197, 38000198))"
77
+ ConceptQL::Nodes::ConditionType.new('inpatient_detail').query(Sequel.mock).sql.must_equal correct_query
78
+ end
79
+
80
+ it 'works for inpatient_header' do
81
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000199, 38000200, 38000201, 38000202, 38000203, 38000204, 38000205, 38000206, 38000207, 38000208, 38000209, 38000210, 38000211, 38000212, 38000213, 38000214))"
82
+ ConceptQL::Nodes::ConditionType.new('inpatient_header').query(Sequel.mock).sql.must_equal correct_query
83
+ end
84
+
85
+ it 'works for inpatient' do
86
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000183, 38000184, 38000185, 38000186, 38000187, 38000188, 38000189, 38000190, 38000191, 38000192, 38000193, 38000194, 38000195, 38000196, 38000197, 38000198, 38000199, 38000200, 38000201, 38000202, 38000203, 38000204, 38000205, 38000206, 38000207, 38000208, 38000209, 38000210, 38000211, 38000212, 38000213, 38000214))"
87
+ ConceptQL::Nodes::ConditionType.new('inpatient').query(Sequel.mock).sql.must_equal correct_query
88
+ end
89
+
90
+ it 'works for outpatient_detail' do
91
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000215, 38000216, 38000217, 38000218, 38000219, 38000220, 38000221, 38000222, 38000223, 38000224, 38000225, 38000226, 38000227, 38000228, 38000229))"
92
+ ConceptQL::Nodes::ConditionType.new('outpatient_detail').query(Sequel.mock).sql.must_equal correct_query
93
+ end
94
+
95
+ it 'works for outpatient_header' do
96
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000230, 38000231, 38000232, 38000233, 38000234, 38000235, 38000236, 38000237, 38000238, 38000239, 38000240, 38000241, 38000242, 38000243, 38000244))"
97
+ ConceptQL::Nodes::ConditionType.new('outpatient_header').query(Sequel.mock).sql.must_equal correct_query
98
+ end
99
+
100
+ it 'works for outpatient' do
101
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000215, 38000216, 38000217, 38000218, 38000219, 38000220, 38000221, 38000222, 38000223, 38000224, 38000225, 38000226, 38000227, 38000228, 38000229, 38000230, 38000231, 38000232, 38000233, 38000234, 38000235, 38000236, 38000237, 38000238, 38000239, 38000240, 38000241, 38000242, 38000243, 38000244))"
102
+ ConceptQL::Nodes::ConditionType.new('outpatient').query(Sequel.mock).sql.must_equal correct_query
103
+ end
104
+
105
+ it 'works for condition_era' do
106
+ correct_query = "SELECT * FROM condition_occurrence_with_dates WHERE (condition_type_concept_id IN (38000246, 38000247))"
107
+ ConceptQL::Nodes::ConditionType.new('condition_era').query(Sequel.mock).sql.must_equal correct_query
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/cpt'
3
+
4
+ describe ConceptQL::Nodes::Cpt do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Cpt.new.must_behave_like(:standard_vocabulary_node)
7
+ end
8
+
9
+ subject do
10
+ ConceptQL::Nodes::Cpt.new
11
+ end
12
+
13
+ describe '#table' do
14
+ it 'should be procedure_occurrence' do
15
+ subject.table.must_equal :procedure_occurrence
16
+ end
17
+ end
18
+
19
+ describe '#concept_column' do
20
+ it 'should be procedure_concept_id' do
21
+ subject.concept_column.must_equal :procedure_concept_id
22
+ end
23
+ end
24
+
25
+ describe '#vocabulary_id' do
26
+ it 'should be 4' do
27
+ subject.vocabulary_id.must_equal 4
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/date_range'
3
+
4
+ describe ConceptQL::Nodes::DateRange do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::DateRange.new.must_behave_like(:evaluator)
7
+ end
8
+
9
+ describe '#types' do
10
+ it 'should be [:date]' do
11
+ ConceptQL::Nodes::DateRange.new(start: '2004-12-13', end: '2010-03-20').types.must_equal([:person])
12
+ end
13
+ end
14
+
15
+ describe '#query' do
16
+ it 'should be dates specified assigned to all persons' do
17
+ ConceptQL::Nodes::DateRange.new(start: '2004-12-13', end: '2010-03-20').query(Sequel.mock).sql.must_equal("SELECT * FROM (SELECT *, CAST('2004-12-13' AS date) AS start_date, CAST('2010-03-20' AS date) AS end_date FROM person) AS t1")
18
+ end
19
+
20
+ it 'should handle strings for option keys' do
21
+ ConceptQL::Nodes::DateRange.new('start' => '2004-12-13', 'end' => '2010-03-20').query(Sequel.mock).sql.must_equal("SELECT * FROM (SELECT *, CAST('2004-12-13' AS date) AS start_date, CAST('2010-03-20' AS date) AS end_date FROM person) AS t1")
22
+ end
23
+
24
+ it 'handles START as day before first recorded visit_occurrence' do
25
+ ConceptQL::Nodes::DateRange.new(start: 'START', end: '2010-03-20').query(Sequel.mock).sql.must_equal("SELECT * FROM (SELECT *, CAST((SELECT min(start_date) FROM visit_occurrence_with_dates) AS date) AS start_date, CAST('2010-03-20' AS date) AS end_date FROM person) AS t1")
26
+ end
27
+
28
+ it 'handles END as 2010-12-31' do
29
+ ConceptQL::Nodes::DateRange.new(start: '2004-12-13', end: 'END').query(Sequel.mock).sql.must_equal("SELECT * FROM (SELECT *, CAST('2004-12-13' AS date) AS start_date, CAST((SELECT max(end_date) FROM visit_occurrence_with_dates) AS date) AS end_date FROM person) AS t1")
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/death'
3
+ require_double('stream_for_casting')
4
+
5
+ describe ConceptQL::Nodes::CastingNode do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::Death.new.must_behave_like(:casting_node)
8
+ end
9
+ end
10
+
11
+
12
+
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/during'
3
+ require_double('stream_for_temporal')
4
+
5
+ describe ConceptQL::Nodes::During do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::During.new.must_behave_like(:temporal_node)
8
+ end
9
+
10
+ describe 'when not inclusive' do
11
+ subject do
12
+ ConceptQL::Nodes::During.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new)
13
+ end
14
+
15
+ it 'should use proper where clause' do
16
+ subject.query(Sequel.mock).sql.must_match 'l.end_date <= r.end_date'
17
+ subject.query(Sequel.mock).sql.must_match 'r.start_date <= l.start_date'
18
+ end
19
+ end
20
+
21
+ describe 'when inclusive' do
22
+ subject do
23
+ ConceptQL::Nodes::During.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new, inclusive: true)
24
+ end
25
+
26
+ it 'should use proper where clause' do
27
+ subject.query(Sequel.mock).sql.must_match '(r.start_date <= l.end_date) AND (l.end_date <= r.end_date)'
28
+ subject.query(Sequel.mock).sql.must_match '(r.start_date <= l.start_date) AND (l.start_date <= r.end_date)'
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/except'
3
+ require_relative 'query_double'
4
+
5
+ describe ConceptQL::Nodes::Except do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::Except.new.must_behave_like(:evaluator)
8
+ end
9
+
10
+ describe '#query' do
11
+ it 'uses right stream as argument to EXCEPT against left stream' do
12
+ double1 = QueryDouble.new(1)
13
+ double2 = QueryDouble.new(2)
14
+ double1.must_behave_like(:evaluator)
15
+ ConceptQL::Nodes::Except.new(left: double1, right: double2).query(Sequel.mock).sql.must_equal "SELECT * FROM (SELECT * FROM table1 EXCEPT SELECT * FROM table2) AS t1"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/first'
3
+ require_double('stream_for_occurrence')
4
+
5
+ describe ConceptQL::Nodes::First do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::First.new.must_behave_like(:evaluator)
8
+ end
9
+
10
+ it 'should have occurrence pegged at 1' do
11
+ ConceptQL::Nodes::First.new.occurrence.must_equal(1)
12
+ end
13
+
14
+ describe 'occurrence set to 1' do
15
+ subject do
16
+ ConceptQL::Nodes::First.new(StreamForOccurrenceDouble.new).query(Sequel.mock).sql
17
+ end
18
+
19
+ it 'should order by ascending start_date' do
20
+ subject.must_match 'ORDER BY start_date ASC'
21
+ end
22
+
23
+ it 'should partition by person_id' do
24
+ subject.must_match 'PARTITION BY person_id'
25
+ end
26
+
27
+ it 'should assign a row number' do
28
+ subject.must_match 'row_number()'
29
+ end
30
+
31
+ it 'should find the all rows with rn = 1' do
32
+ subject.must_match 'rn = 1'
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/from'
3
+ require_relative 'query_double'
4
+
5
+ describe ConceptQL::Nodes::From do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::From.new.must_behave_like(:evaluator)
8
+ end
9
+
10
+ describe '#query' do
11
+ it 'works for single criteria' do
12
+ ConceptQL::Nodes::From.new(:table1).query(Sequel.mock).sql.must_equal "SELECT * FROM table1"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/gender'
3
+
4
+ describe ConceptQL::Nodes::Gender do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Gender.new.must_behave_like(:evaluator)
7
+ end
8
+
9
+ describe '#query' do
10
+ it 'works for male/MALE/Male/M/m' do
11
+ correct_query = "SELECT * FROM person_with_dates WHERE (gender_concept_id IN (8507))"
12
+ ConceptQL::Nodes::Gender.new('male').query(Sequel.mock).sql.must_equal correct_query
13
+ ConceptQL::Nodes::Gender.new('Male').query(Sequel.mock).sql.must_equal correct_query
14
+ ConceptQL::Nodes::Gender.new('MALE').query(Sequel.mock).sql.must_equal correct_query
15
+ ConceptQL::Nodes::Gender.new('M').query(Sequel.mock).sql.must_equal correct_query
16
+ ConceptQL::Nodes::Gender.new('m').query(Sequel.mock).sql.must_equal correct_query
17
+ end
18
+
19
+ it 'works for Female/FEMALE/female/F/f' do
20
+ correct_query = "SELECT * FROM person_with_dates WHERE (gender_concept_id IN (8532))"
21
+ ConceptQL::Nodes::Gender.new('female').query(Sequel.mock).sql.must_equal correct_query
22
+ ConceptQL::Nodes::Gender.new('Female').query(Sequel.mock).sql.must_equal correct_query
23
+ ConceptQL::Nodes::Gender.new('FEMALE').query(Sequel.mock).sql.must_equal correct_query
24
+ ConceptQL::Nodes::Gender.new('F').query(Sequel.mock).sql.must_equal correct_query
25
+ ConceptQL::Nodes::Gender.new('f').query(Sequel.mock).sql.must_equal correct_query
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/hcpcs'
3
+
4
+ describe ConceptQL::Nodes::Hcpcs do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Hcpcs.new.must_behave_like(:standard_vocabulary_node)
7
+ end
8
+
9
+ subject do
10
+ ConceptQL::Nodes::Hcpcs.new
11
+ end
12
+
13
+ describe '#table' do
14
+ it 'should be procedure_occurrence' do
15
+ subject.table.must_equal :procedure_occurrence
16
+ end
17
+ end
18
+
19
+ describe '#concept_column' do
20
+ it 'should be procedure_concept_id' do
21
+ subject.concept_column.must_equal :procedure_concept_id
22
+ end
23
+ end
24
+
25
+ describe '#vocabulary_id' do
26
+ it 'should be 5' do
27
+ subject.vocabulary_id.must_equal 5
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/icd10'
3
+
4
+ describe ConceptQL::Nodes::Icd10 do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Icd10.new.must_behave_like(:source_vocabulary_node)
7
+ end
8
+
9
+ subject do
10
+ ConceptQL::Nodes::Icd10.new
11
+ end
12
+
13
+ describe '#table' do
14
+ it 'should be condition_occurrence' do
15
+ subject.table.must_equal :condition_occurrence
16
+ end
17
+ end
18
+
19
+ describe '#concept_column' do
20
+ it 'should be condition_concept_id' do
21
+ subject.concept_column.must_equal :condition_concept_id
22
+ end
23
+ end
24
+
25
+ describe '#source_column' do
26
+ it 'should be condition_source_valuej' do
27
+ subject.source_column.must_equal :condition_source_value
28
+ end
29
+ end
30
+
31
+ describe '#vocabulary_id' do
32
+ it 'should be 34' do
33
+ subject.vocabulary_id.must_equal 34
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/icd9_procedure'
3
+
4
+ describe ConceptQL::Nodes::Icd9Procedure do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Icd9Procedure.new.must_behave_like(:standard_vocabulary_node)
7
+ end
8
+
9
+ subject do
10
+ ConceptQL::Nodes::Icd9Procedure.new
11
+ end
12
+
13
+ describe '#table' do
14
+ it 'should be procedure_occurrence' do
15
+ subject.table.must_equal :procedure_occurrence
16
+ end
17
+ end
18
+
19
+ describe '#concept_column' do
20
+ it 'should be procedure_concept_id' do
21
+ subject.concept_column.must_equal :procedure_concept_id
22
+ end
23
+ end
24
+
25
+ describe '#vocabulary_id' do
26
+ it 'should be 3' do
27
+ subject.vocabulary_id.must_equal 3
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/icd9'
3
+
4
+ describe ConceptQL::Nodes::Icd9 do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Icd9.new.must_behave_like(:source_vocabulary_node)
7
+ end
8
+
9
+ subject do
10
+ ConceptQL::Nodes::Icd9.new
11
+ end
12
+
13
+ describe '#table' do
14
+ it 'should be condition_occurrence' do
15
+ subject.table.must_equal :condition_occurrence
16
+ end
17
+ end
18
+
19
+ describe '#concept_column' do
20
+ it 'should be condition_concept_id' do
21
+ subject.concept_column.must_equal :condition_concept_id
22
+ end
23
+ end
24
+
25
+ describe '#source_column' do
26
+ it 'should be condition_source_valuej' do
27
+ subject.source_column.must_equal :condition_source_value
28
+ end
29
+ end
30
+
31
+ describe '#vocabulary_id' do
32
+ it 'should be 2' do
33
+ subject.vocabulary_id.must_equal 2
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/intersect'
3
+ require_relative 'query_double'
4
+
5
+ describe ConceptQL::Nodes::Intersect do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::Intersect.new.must_behave_like(:evaluator)
8
+ end
9
+
10
+ describe '#query' do
11
+ it 'works for multiple criteria of same type' do
12
+ double1 = QueryDouble.new(1)
13
+ double2 = QueryDouble.new(2)
14
+ double3 = QueryDouble.new(3)
15
+ double1.must_behave_like(:evaluator)
16
+ ConceptQL::Nodes::Intersect.new(double1, double2, double3).query(Sequel.mock).sql.must_equal "SELECT * FROM (SELECT * FROM (SELECT * FROM table1 INTERSECT ALL SELECT * FROM table2) AS t1 INTERSECT ALL SELECT * FROM table3) AS t1"
17
+ end
18
+
19
+ it 'works for multiple criteria of different type' do
20
+ double1 = QueryDouble.new(1)
21
+ double2 = QueryDouble.new(2, :person)
22
+ double3 = QueryDouble.new(3)
23
+ double1.must_behave_like(:evaluator)
24
+ ConceptQL::Nodes::Intersect.new(double1, double2, double3).query(Sequel.mock).sql.must_equal "SELECT * FROM (SELECT * FROM (SELECT * FROM table1 INTERSECT ALL SELECT * FROM table3) AS t1 UNION ALL SELECT * FROM table2) AS t1"
25
+ end
26
+
27
+ it 'works for single criteria' do
28
+ double1 = QueryDouble.new(1)
29
+ double1.must_behave_like(:evaluator)
30
+ ConceptQL::Nodes::Intersect.new(double1).query(Sequel.mock).sql.must_equal "SELECT * FROM table1"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/last'
3
+ require_double('stream_for_occurrence')
4
+
5
+ describe ConceptQL::Nodes::Last do
6
+ it 'behaves itself' do
7
+ ConceptQL::Nodes::Last.new.must_behave_like(:evaluator)
8
+ end
9
+
10
+ it 'should have occurrence pegged at -1' do
11
+ ConceptQL::Nodes::Last.new.occurrence.must_equal(-1)
12
+ end
13
+
14
+ describe 'occurrence set to -1' do
15
+ subject do
16
+ ConceptQL::Nodes::Last.new(StreamForOccurrenceDouble.new).query(Sequel.mock).sql
17
+ end
18
+
19
+
20
+ it 'should order by descending start_date' do
21
+ subject.must_match 'ORDER BY start_date DESC'
22
+ end
23
+
24
+ it 'should partition by person_id' do
25
+ subject.must_match 'PARTITION BY person_id'
26
+ end
27
+
28
+ it 'should assign a row number' do
29
+ subject.must_match 'row_number()'
30
+ end
31
+
32
+ it 'should find the all rows with rn = 1' do
33
+ subject.must_match 'rn = 1'
34
+ end
35
+ end
36
+ end
37
+
38
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'conceptql/nodes/loinc'
3
+
4
+ describe ConceptQL::Nodes::Loinc do
5
+ it 'behaves itself' do
6
+ ConceptQL::Nodes::Loinc.new.must_behave_like(:standard_vocabulary_node)
7
+ end
8
+
9
+ subject do
10
+ ConceptQL::Nodes::Loinc.new
11
+ end
12
+
13
+ describe '#table' do
14
+ it 'should be observation' do
15
+ subject.table.must_equal :observation
16
+ end
17
+ end
18
+
19
+ describe '#concept_column' do
20
+ it 'should be procedure_concept_id' do
21
+ subject.concept_column.must_equal :observation_concept_id
22
+ end
23
+ end
24
+
25
+ describe '#vocabulary_id' do
26
+ it 'should be 6' do
27
+ subject.vocabulary_id.must_equal 6
28
+ end
29
+ end
30
+ end
31
+