Class: Inferno::CLI::Session::SessionCompare::ComparedTestResult

Inherits:
Object
  • Object
show all
Defined in:
lib/inferno/apps/cli/session/session_compare.rb

Constant Summary collapse

MESSAGE_TYPE_ORDER =
{ 'error' => 0, 'warning' => 1, 'info' => 2 }.freeze
UNKNOWN_MESSAGE_TYPE_ORDER =
99

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, expected_result, actual_result, options, short_id_map = {}) ⇒ ComparedTestResult

Returns a new instance of ComparedTestResult.



188
189
190
191
192
193
194
195
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 188

def initialize(id, expected_result, actual_result, options, short_id_map = {})
  @id = id
  @expected_result = expected_result
  @actual_result = actual_result
  @options = options
  @short_id_map = short_id_map
  @same = same_results?
end

Instance Attribute Details

#actual_resultObject (readonly)

Returns the value of attribute actual_result.



186
187
188
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 186

def actual_result
  @actual_result
end

#expected_resultObject (readonly)

Returns the value of attribute expected_result.



186
187
188
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 186

def expected_result
  @expected_result
end

#idObject (readonly)

Returns the value of attribute id.



186
187
188
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 186

def id
  @id
end

#optionsObject (readonly)

Returns the value of attribute options.



186
187
188
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 186

def options
  @options
end

#short_id_mapObject (readonly)

Returns the value of attribute short_id_map.



186
187
188
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 186

def short_id_map
  @short_id_map
end

Instance Method Details

#build_message_comparisonsObject



272
273
274
275
276
277
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 272

def build_message_comparisons
  expected_msgs = sorted_messages(expected_result)
  actual_msgs = sorted_messages(actual_result)
  max_length = [expected_msgs.size, actual_msgs.size].max
  (0...max_length).map { |i| messages_match?(expected_msgs[i], actual_msgs[i]) }
end

#comparison_csv_rowObject



344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 344

def comparison_csv_row
  row = [id, short_id, type, different_result?, expected_result&.dig('result'), actual_result&.dig('result')]
  if options[:compare_result_message]
    row << different_result_message?
    row << normalize_string(expected_result&.dig('result_message'))
    row << normalize_string(actual_result&.dig('result_message'))
  end
  if options[:compare_messages]
    row << different_messages?
    row << format_messages_for_csv(expected_result)
    row << format_messages_for_csv(actual_result)
  end
  row
end

#different_messages?Boolean

Returns:

  • (Boolean)


315
316
317
318
319
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 315

def different_messages?
  return false unless type == 'Compared'

  !same_messages?
end

#different_result?Boolean

Returns:

  • (Boolean)


305
306
307
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 305

def different_result?
  !same_result?
end

#different_result_message?Boolean

Returns:

  • (Boolean)


309
310
311
312
313
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 309

def different_result_message?
  return false unless type == 'Compared'

  normalize_string(expected_result['result_message']) != normalize_string(actual_result['result_message'])
end

#format_messages_for_csv(results) ⇒ Object



369
370
371
372
373
374
375
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 369

def format_messages_for_csv(results)
  return '' unless results&.dig('messages').present?

  sorted_messages(results).each_with_index.map do |message, index|
    message_text_for_csv(message, index)
  end.join("\n")
end

#message_comparisonsObject



265
266
267
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 265

def message_comparisons
  @message_comparisons ||= build_message_comparisons
end

#message_text_for_csv(message, index) ⇒ Object



377
378
379
380
381
382
383
384
385
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 377

def message_text_for_csv(message, index)
  prefix = message_comparisons[index] ? '- ' : '! '
  text = normalize_string(message['message'].to_s)
    .gsub("\r\n", '\n')
    .gsub("\n", '\n')
    .gsub("\r", '\r')
    .gsub("\t", '\t')
  "#{prefix}(#{message['type']}) \"#{text}\""
end

#messages_match?(expected_message, actual_message) ⇒ Boolean

Returns:

  • (Boolean)


285
286
287
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 285

def messages_match?(expected_message, actual_message)
  expected_message.present? && actual_message.present? && same_message?(expected_message, actual_message)
end

#normalize_string(str) ⇒ Object



234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 234

def normalize_string(str)
  return str unless str.present?

  Array(options[:normalized_strings]).reduce(str) do |s, entry|
    parse_normalize_entry(entry).reduce(s) do |s2, (pattern, replacement)|
      if pattern.is_a?(Regexp)
        s2.gsub(pattern, replacement)
      else
        s2.gsub(pattern, replacement).gsub(CGI.escape(pattern), replacement)
      end
    end
  end
end

#normalizing?Boolean

Returns:

  • (Boolean)


248
249
250
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 248

def normalizing?
  options[:normalized_strings].present?
end

#optional_to_h_fieldsObject



331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 331

def optional_to_h_fields
  fields = {}
  if options[:compare_result_message]
    fields[:expected_result_message] = expected_result&.dig('result_message')
    fields[:actual_result_message] = actual_result&.dig('result_message')
  end
  if options[:compare_messages]
    fields[:expected_messages] = expected_result&.dig('messages')
    fields[:actual_messages] = actual_result&.dig('messages')
  end
  fields
end

#parse_normalize_entry(entry) ⇒ Object

Parses a normalize entry into an array of [pattern, replacement] pairs. Entries may be:

- A plain string: literal match, replacement defaults to '<NORMALIZED>'
- A "/pattern/[flags]" string: compiled to Regexp, replacement defaults to '<NORMALIZED>'
- A hash with 'pattern' or 'patterns' and optional 'replacement' keys (from YAML):
    pattern: '/code_challenge=[A-Za-z0-9+\/=_-]{20,}/'
    replacement: '<CODE_CHALLENGE>'
  Or multiple patterns sharing one replacement:
    patterns:
      - '/code_challenge=[A-Za-z0-9+\/=_-]{20,}/'
      - '/code_verifier=[A-Za-z0-9+\/=_-]{20,}/'
    replacement: '<PKCE_VALUE>'


213
214
215
216
217
218
219
220
221
222
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 213

def parse_normalize_entry(entry)
  if entry.is_a?(Hash)
    replacement = entry.fetch('replacement', '<NORMALIZED>')
    Array(entry['patterns'] || entry['pattern']).map do |pattern|
      [parse_pattern_string(pattern.to_s), replacement]
    end
  else
    [[parse_pattern_string(entry.to_s), '<NORMALIZED>']]
  end
end

#parse_pattern_string(str) ⇒ Object



224
225
226
227
228
229
230
231
232
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 224

def parse_pattern_string(str)
  return str unless (parsed_regex = str.match(%r{\A/(.+)/([imx]*)\z}m))

  flags = 0
  flags |= Regexp::IGNORECASE if parsed_regex[2].include?('i')
  flags |= Regexp::MULTILINE  if parsed_regex[2].include?('m')
  flags |= Regexp::EXTENDED   if parsed_regex[2].include?('x')
  Regexp.new(parsed_regex[1], flags)
end

#same_message?(expected_message, actual_message) ⇒ Boolean

Returns:

  • (Boolean)


296
297
298
299
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 296

def same_message?(expected_message, actual_message)
  expected_message['type'] == actual_message['type'] &&
    normalize_string(expected_message['message']) == normalize_string(actual_message['message'])
end

#same_messages?Boolean

Returns:

  • (Boolean)


289
290
291
292
293
294
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 289

def same_messages?
  return false unless expected_result['messages']&.size == actual_result['messages']&.size
  return true unless expected_result['messages'].present?

  message_comparisons.all?
end

#same_result?Boolean

Returns:

  • (Boolean)


301
302
303
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 301

def same_result?
  @same
end

#same_results?Boolean

Returns:

  • (Boolean)


252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 252

def same_results?
  return false unless type == 'Compared'
  return false unless expected_result['result'] == actual_result['result']

  if options[:compare_result_message] &&
     normalize_string(expected_result['result_message']) != normalize_string(actual_result['result_message'])
    return false
  end
  return false if options[:compare_messages] && !same_messages?

  true
end

#short_idObject



197
198
199
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 197

def short_id
  short_id_map[id]
end

#sorted_messages(result) ⇒ Object



279
280
281
282
283
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 279

def sorted_messages(result)
  Array(result&.dig('messages')).sort_by do |m|
    [MESSAGE_TYPE_ORDER.fetch(m['type'].to_s, UNKNOWN_MESSAGE_TYPE_ORDER), m['message'].to_s]
  end
end

#to_hObject



321
322
323
324
325
326
327
328
329
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 321

def to_h
  {
    id: id,
    type: type,
    matched: same_result?,
    expected_result: expected_result&.dig('result'),
    actual_result: actual_result&.dig('result')
  }.merge(optional_to_h_fields)
end

#typeObject



359
360
361
362
363
364
365
366
367
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 359

def type
  if expected_result.nil?
    'Additional'
  elsif actual_result.nil?
    'Missing'
  else
    'Compared'
  end
end