Module: Qti::V1::Models::Interactions

Defined in:
lib/qti/v1/models/interactions.rb,
lib/qti/v1/models/interactions/base_interaction.rb,
lib/qti/v1/models/interactions/match_interaction.rb,
lib/qti/v1/models/interactions/choice_interaction.rb,
lib/qti/v1/models/interactions/string_interaction.rb,
lib/qti/v1/models/interactions/upload_interaction.rb,
lib/qti/v1/models/interactions/formula_interaction.rb,
lib/qti/v1/models/interactions/numeric_interaction.rb,
lib/qti/v1/models/interactions/hot_spot_interaction.rb,
lib/qti/v1/models/interactions/ordering_interaction.rb,
lib/qti/v1/models/interactions/fill_blank_interaction.rb,
lib/qti/v1/models/interactions/canvas_multiple_dropdown.rb,
lib/qti/v1/models/interactions/categorization_interaction.rb,
lib/qti/v1/models/interactions/base_fill_blank_interaction.rb

Defined Under Namespace

Classes: BaseFillBlankInteraction, BaseInteraction, CanvasMultipleDropdownInteraction, CategorizationInteraction, ChoiceInteraction, FillBlankInteraction, FormulaInteraction, HotSpotInteraction, MatchInteraction, NumericInteraction, OrderingInteraction, StringInteraction, UploadInteraction

Constant Summary collapse

ALL_CLASSES =
constants.map { |c| const_get(c) }.freeze
ORDERED_CLASSES =
[CanvasMultipleDropdownInteraction, FormulaInteraction, NumericInteraction].freeze
FALLBACK_CLASSES =
[StringInteraction].freeze
IDENTIFIED_CLASSES =
{
  'multiple_choice_question' => ChoiceInteraction,
  'true_false_question' => ChoiceInteraction,
  'short_answer_question' => FillBlankInteraction,
  'fill_in_multiple_blanks_question' => FillBlankInteraction,
  'multiple_answers_question' => ChoiceInteraction,
  'multiple_dropdowns_question' => CanvasMultipleDropdownInteraction,
  'matching_question' => MatchInteraction,
  'numerical_question' => NumericInteraction,
  'calculated_question' => FormulaInteraction,
  'essay_question ' => StringInteraction,
  'file_upload_question' => UploadInteraction,
  'hot_spot_question' => HotSpotInteraction,
  'categorization_question' => CategorizationInteraction
  # "text_only_question" => StimulusNoQuestion
}.freeze

Class Method Summary collapse

Class Method Details

.get_match(node, parent, classlist) ⇒ Object



54
55
56
57
58
# File 'lib/qti/v1/models/interactions.rb', line 54

def self.get_match(node, parent, classlist)
  classlist.each do |interaction_class|
    return true if interaction_class.match(node, parent)
  end
end

.get_matches(node, parent, classlist) ⇒ Object



60
61
62
63
64
65
# File 'lib/qti/v1/models/interactions.rb', line 60

def self.get_matches(node, parent, classlist)
  classlist.each_with_object([]) do |interaction_class, result|
    match = interaction_class.matches(node, parent)
    result << match if match
  end
end

.interaction_model(node, parent) ⇒ Object

This one finds the correct parsing model based on the provided xml node



27
28
29
# File 'lib/qti/v1/models/interactions.rb', line 27

def self.interaction_model(node, parent)
  matched_class(node, parent) || searched_class(node, parent)
end

.matched_class(node, parent) ⇒ Object



44
45
46
# File 'lib/qti/v1/models/interactions.rb', line 44

def self.matched_class(node, parent)
  IDENTIFIED_CLASSES[question_type(node)]&.new(node, parent)
end

.question_type(node) ⇒ Object



48
49
50
51
52
# File 'lib/qti/v1/models/interactions.rb', line 48

def self.question_type(node)
  path = './/xmlns:qtimetadatafield/xmlns:fieldlabel' \
    '[text()="question_type"]/../xmlns:fieldentry'
  node.at_xpath(path)&.text
end

.searched_class(node, parent) ⇒ Object

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/qti/v1/models/interactions.rb', line 31

def self.searched_class(node, parent)
  matches = Interactions.get_matches(node, parent, ORDERED_CLASSES)
  return matches.first unless matches.empty?

  subclasses = ALL_CLASSES - ORDERED_CLASSES - FALLBACK_CLASSES

  matches = Interactions.get_matches(node, parent, subclasses)
  matches = Interactions.get_matches(node, parent, FALLBACK_CLASSES) if matches.empty?

  raise UnsupportedSchema, "Multiple Types (#{matches.map(&:class)})" if matches.size != 1
  matches.first
end