Module: IpaTestKit::DateSearchValidation

Included in:
SearchTest
Defined in:
lib/ipa_test_kit/date_search_validation.rb

Instance Method Summary collapse

Instance Method Details

#fhir_date_comparer(search_range, target_range, comparator) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ipa_test_kit/date_search_validation.rb', line 39

def fhir_date_comparer(search_range, target_range, comparator)
  # Implicitly, a missing lower boundary is "less than" any actual date. A missing upper boundary is "greater than" any actual date.
  case comparator
  when 'eq' # the range of the search value fully contains the range of the target value
    !target_range[:start].nil? && !target_range[:end].nil? && search_range[:start] <= target_range[:start] && search_range[:end] >= target_range[:end]
  when 'ne' # the range of the search value does not fully contain the range of the target value
    target_range[:start].nil? || target_range[:end].nil? || search_range[:start] > target_range[:start] || search_range[:end] < target_range[:end]
  when 'gt' #  the range above the search value intersects (i.e. overlaps) with the range of the target value
    target_range[:end].nil? || search_range[:end] < target_range[:end]
  when 'lt' # the range below the search value intersects (i.e. overlaps) with the range of the target value
    target_range[:start].nil? || search_range[:start] > target_range[:start]
  when 'ge'
    fhir_date_comparer(search_range, target_range, 'gt') || fhir_date_comparer(search_range, target_range, 'eq')
  when 'le'
    fhir_date_comparer(search_range, target_range, 'lt') || fhir_date_comparer(search_range, target_range, 'eq')
  when 'sa' # the range above the search value contains the range of the target value
    !target_range[:start].nil? && search_range[:end] < target_range[:start]
  when 'eb' # the range below the search value contains the range of the target value
    !target_range[:end].nil? && search_range[:start] > target_range[:end]
  when 'ap' # the range of the search value overlaps with the range of the target value
    if target_range[:start].nil? || target_range[:end].nil?
      (target_range[:start].nil? && search_range[:start] < target_range[:end]) ||
        (target_range[:end].nil? && search_range[:end] > target_range[:start])
    else
      (search_range[:start] >= target_range[:start] && search_range[:start] <= target_range[:end]) ||
        (search_range[:end] >= target_range[:start] && search_range[:end] <= target_range[:end])
    end
  end
end

#get_fhir_datetime_range(datetime) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/ipa_test_kit/date_search_validation.rb', line 5

def get_fhir_datetime_range(datetime)
  range = { start: DateTime.xmlschema(datetime), end: nil }
  range[:end] =
    if /^\d{4}$/.match?(datetime) # YYYY
      range[:start].next_year - 1.seconds
    elsif /^\d{4}-\d{2}$/.match?(datetime) # YYYY-MM
      range[:start].next_month - 1.seconds
    elsif /^\d{4}-\d{2}-\d{2}$/.match?(datetime) # YYYY-MM-DD
      range[:start].next_day - 1.seconds
    else # YYYY-MM-DDThh:mm:ss+zz:zz
      range[:start]
    end
  range
end

#get_fhir_period_range(period) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/ipa_test_kit/date_search_validation.rb', line 20

def get_fhir_period_range(period)
  range = { start: nil, end: nil }
  range[:start] = DateTime.xmlschema(period.start) unless period.start.nil?
  return range if period.end.nil?

  period_end_beginning = DateTime.xmlschema(period.end)
  range[:end] =
    if /^\d{4}$/.match?(period.end) # YYYY
      period_end_beginning.next_year - 1.seconds
    elsif /^\d{4}-\d{2}$/.match?(period.end) # YYYY-MM
      period_end_beginning.next_month - 1.seconds
    elsif /^\d{4}-\d{2}-\d{2}$/.match?(period.end) # YYYY-MM-DD
      period_end_beginning.next_day - 1.seconds
    else # YYYY-MM-DDThh:mm:ss+zz:zz
      period_end_beginning
    end
  range
end

#validate_date_search(search_value, target_value) ⇒ Object



69
70
71
72
73
74
75
# File 'lib/ipa_test_kit/date_search_validation.rb', line 69

def validate_date_search(search_value, target_value)
  if target_value.instance_of? FHIR::Period
    validate_period_search(search_value, target_value)
  else
    validate_datetime_search(search_value, target_value)
  end
end

#validate_datetime_search(search_value, target_value) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/ipa_test_kit/date_search_validation.rb', line 77

def validate_datetime_search(search_value, target_value)
  comparator = search_value[0..1]
  if ['eq', 'ge', 'gt', 'le', 'lt', 'ne', 'sa', 'eb', 'ap'].include? comparator
    search_value = search_value[2..-1]
  else
    comparator = 'eq'
  end
  search_range = get_fhir_datetime_range(search_value)
  target_range = get_fhir_datetime_range(target_value)
  fhir_date_comparer(search_range, target_range, comparator)
end

#validate_period_search(search_value, target_value) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ipa_test_kit/date_search_validation.rb', line 89

def validate_period_search(search_value, target_value)
  comparator = search_value[0..1]
  if ['eq', 'ge', 'gt', 'le', 'lt', 'ne', 'sa', 'eb', 'ap'].include? comparator
    search_value = search_value[2..-1]
  else
    comparator = 'eq'
  end
  search_range = get_fhir_datetime_range(search_value)
  target_range = get_fhir_period_range(target_value)
  fhir_date_comparer(search_range, target_range, comparator)
end