qti 0.9.12 → 0.9.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ecb7ff4bd1d4f7dc9238fb727d9d6d111a8534ee
4
- data.tar.gz: e63c12313dc8ced9fb35262dedce19d670f0ed7b
3
+ metadata.gz: a8a20f28fe6f8aeded9fd3282dccc970983a3234
4
+ data.tar.gz: 054ff6d10ef0da8fbde0e8b583ed40eb9f49b2e6
5
5
  SHA512:
6
- metadata.gz: 808c41b55051f1a7b4501a18385a5e56c9d06019899f5eeb77c333129e61f3ae1247862ee7676d77a38e7d052004433eab6657e541533a31f049cf6a568d05d3
7
- data.tar.gz: 9432df6fdde51711156dc520027ec524ac890028876ff1c6661a334a78c662031400a965f94760daf4de8dc44caf65373d792e9dc7487a741f5087934509184d
6
+ metadata.gz: f0ba4fa3e613ee9bcf93afd69f02ce855688f1849e5613cfd224a706cc6f556b99fac43048b2cf6769bd66dcee03a9cf8db31615edae3a3d8c0c51b82d4b982b
7
+ data.tar.gz: 5df6efce6e7f3d33b1934752075c251bd9c43aafce275ada3c5f177cf858f2e587bff5223aef40b0d29d03ecc1872262453cac2b90f45d098314b2fed6db7124
@@ -74,7 +74,7 @@ module Qti
74
74
  nodes.each do |node|
75
75
  # convert all #160 space to regular #32 whitespace
76
76
  # latex parser won't work for #160 space
77
- text = node.text.gsub(/\u00a0/, ' ')
77
+ text = node.text.tr("\u00a0", ' ')
78
78
  latex_string = " \\(#{text}\\) "
79
79
  node.replace(latex_string)
80
80
  end
@@ -10,8 +10,8 @@ module Qti
10
10
  end
11
11
 
12
12
  def qti_1_href
13
- test_path = xmlns_resource("[@type='imsqti_xmlv1p2']/@href") ||
14
- xmlns_resource("[@type='imsqti_xmlv1p2']/xmlns:file/@href")
13
+ test_path = xmlns_resource('[@type="imsqti_xmlv1p2"]/@href') ||
14
+ xmlns_resource('[@type="imsqti_xmlv1p2"]/xmlns:file/@href')
15
15
  return unless test_path
16
16
  Qti::V1::Models::Assessment.from_path!(
17
17
  remap_href_path(test_path), @package_root
@@ -19,8 +19,8 @@ module Qti
19
19
  end
20
20
 
21
21
  def qti_2_x_href
22
- test_path = xmlns_resource("[@type='imsqti_test_xmlv2p1']/@href") ||
23
- xmlns_resource("[@type='imsqti_test_xmlv2p2']/@href")
22
+ test_path = xmlns_resource('[@type="imsqti_test_xmlv2p1"]/@href') ||
23
+ xmlns_resource('[@type="imsqti_test_xmlv2p2"]/@href')
24
24
  return unless test_path
25
25
  Qti::V2::Models::AssessmentTest.from_path!(
26
26
  remap_href_path(test_path), @package_root
@@ -29,8 +29,8 @@ module Qti
29
29
 
30
30
  def qti_2_non_assessment_href
31
31
  Qti::V2::Models::NonAssessmentTest.from_path!(@path, @package_root) if
32
- xmlns_resource_count("[@type='imsqti_item_xmlv2p1']/@href") > 0 ||
33
- xmlns_resource_count("[@type='imsqti_item_xmlv2p2']/@href") > 0
32
+ xmlns_resource_count('[@type="imsqti_item_xmlv2p1"]/@href').positive? ||
33
+ xmlns_resource_count('[@type="imsqti_item_xmlv2p2"]/@href').positive?
34
34
  end
35
35
 
36
36
  def unknown_type
@@ -1,4 +1,4 @@
1
- require "active_support/core_ext/hash/except"
1
+ require 'active_support/core_ext/hash/except'
2
2
  # Populate the subclasses
3
3
  Dir["#{__dir__}/interactions/*.rb"].each { |f| load f }
4
4
 
@@ -8,8 +8,8 @@ module Qti
8
8
  module Interactions
9
9
  # This one finds the correct parsing model based on the provided xml node
10
10
  def self.interaction_model(node, parent)
11
- ordered_classes = [ FormulaInteraction, NumericInteraction ]
12
- ordered_classes.each do | interaction_class |
11
+ ordered_classes = [CanvasMultipleDropdownInteraction, FormulaInteraction, NumericInteraction]
12
+ ordered_classes.each do |interaction_class|
13
13
  match = interaction_class.matches(node, parent)
14
14
  return match if match
15
15
  end
@@ -0,0 +1,49 @@
1
+ module Qti
2
+ module V1
3
+ module Models
4
+ module Interactions
5
+ class BaseFillBlankInteraction < BaseInteraction
6
+ CANVAS_REGEX = /(\[.+?\])/
7
+
8
+ def canvas_stem_items(item_prompt)
9
+ item_prompt.split(CANVAS_REGEX).map.with_index do |stem_item, index|
10
+ if stem_item.match CANVAS_REGEX
11
+ stem_blank(index, canvas_blank_id(stem_item))
12
+ else
13
+ stem_text(index, stem_item)
14
+ end
15
+ end
16
+ end
17
+
18
+ def stem_blank(index, value)
19
+ {
20
+ id: "stem_#{index}",
21
+ position: index + 1,
22
+ type: 'blank',
23
+ blank_id: value
24
+ }
25
+ end
26
+
27
+ def stem_text(index, value)
28
+ {
29
+ id: "stem_#{index}",
30
+ position: index + 1,
31
+ type: 'text',
32
+ value: value
33
+ }
34
+ end
35
+
36
+ def canvas_blank_id(stem_item)
37
+ blank_id = nil
38
+ node.xpath('.//xmlns:response_lid').children.map do |response_lid_node|
39
+ if stem_item.include?(response_lid_node.text)
40
+ blank_id = response_lid_node.parent.attributes['ident']&.value
41
+ end
42
+ end
43
+ blank_id
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -12,7 +12,7 @@ module Qti
12
12
  def self.canvas_multiple_fib?(node)
13
13
  matches = node.xpath('.//xmlns:response_lid')
14
14
  return false if matches.count <= 1
15
- node.at_xpath('.//xmlns:fieldentry').text == "fill_in_multiple_blanks_question"
15
+ node.at_xpath('.//xmlns:fieldentry').text == 'fill_in_multiple_blanks_question'
16
16
  end
17
17
 
18
18
  def initialize(node, parent)
@@ -0,0 +1,84 @@
1
+ module Qti
2
+ module V1
3
+ module Models
4
+ module Interactions
5
+ class CanvasMultipleDropdownInteraction < BaseFillBlankInteraction
6
+ # This will know if a class matches
7
+ def self.matches(node, parent)
8
+ field_entry = node.xpath('.//xmlns:fieldentry')[0]
9
+ return false unless field_entry&.text == 'multiple_dropdowns_question'
10
+ new(node, parent)
11
+ end
12
+
13
+ def stem_items
14
+ canvas_stem_items(node.at_xpath('.//xmlns:presentation/xmlns:material/xmlns:mattext').text)
15
+ end
16
+
17
+ def blanks
18
+ @blanks = node.xpath('.//xmlns:response_lid').map do |resp|
19
+ index = 0
20
+ {
21
+ id: resp[:ident],
22
+ choices:
23
+ resp.xpath('.//xmlns:response_label').map do |bnode|
24
+ blank_choice(bnode, index += 1)
25
+ end
26
+ }
27
+ end
28
+ end
29
+
30
+ def scoring_data_structs
31
+ answers.map do |answer|
32
+ ScoringData.new(
33
+ {
34
+ id: answer[:entry_id],
35
+ position: position_for_entry(answer[:entry_id]),
36
+ item_body: answer[:blank_text]
37
+ },
38
+ rcardinality,
39
+ id: answer[:value]
40
+ )
41
+ end
42
+ end
43
+
44
+ def text_for_entry(entry_id)
45
+ blanks
46
+ @blank_choices[entry_id][:item_body]
47
+ end
48
+
49
+ def position_for_entry(entry_id)
50
+ blanks
51
+ @blank_choices[entry_id][:position]
52
+ end
53
+
54
+ def answers
55
+ @node.xpath('.//xmlns:respcondition/xmlns:setvar[@varname="SCORE"]').map do |points|
56
+ entry = points.at_xpath('preceding-sibling::xmlns:conditionvar/xmlns:varequal')
57
+ {
58
+ value: entry[:respident],
59
+ entry_id: entry.text,
60
+ blank_text: text_for_entry(entry.text),
61
+ action: points[:action],
62
+ point_value: points.text
63
+ }
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def blank_choice(bnode, index)
70
+ bnode_id = bnode[:ident]
71
+ choice = {
72
+ id: bnode_id,
73
+ position: index + 1,
74
+ item_body: bnode.at_xpath('.//xmlns:mattext').text
75
+ }
76
+ @blank_choices ||= {}
77
+ @blank_choices[bnode_id] = choice
78
+ choice
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -2,19 +2,19 @@ module Qti
2
2
  module V1
3
3
  module Models
4
4
  module Interactions
5
- class FillBlankInteraction < BaseInteraction
6
- CANVAS_REGEX = /(\[.+?\])/.freeze
5
+ class FillBlankInteraction < BaseFillBlankInteraction
6
+ CANVAS_REGEX = /(\[.+?\])/
7
7
 
8
8
  # This will know if a class matches
9
9
  def self.matches(node, parent)
10
10
  return false if node.at_xpath('.//xmlns:other').present?
11
11
  match = if BaseInteraction.canvas_multiple_fib?(node)
12
- node.at_xpath('.//xmlns:response_lid')
13
- else
14
- node.at_xpath('.//xmlns:render_fib')
15
- end
12
+ node.at_xpath('.//xmlns:response_lid')
13
+ else
14
+ node.at_xpath('.//xmlns:render_fib')
15
+ end
16
16
  return false if match.blank? ||
17
- match.attributes['fibtype']&.value == 'Decimal'
17
+ match.attributes['fibtype']&.value == 'Decimal'
18
18
  new(node, parent)
19
19
  end
20
20
 
@@ -24,59 +24,19 @@ module Qti
24
24
 
25
25
  def stem_items
26
26
  if canvas_multiple_fib?
27
- canvas_stem_items
27
+ canvas_stem_items(node.at_xpath('.//xmlns:mattext').text)
28
28
  else
29
29
  qti_stem_items
30
30
  end
31
31
  end
32
32
 
33
- def canvas_stem_items
34
- @response_lid_nodes = node.xpath('.//xmlns:response_lid')
35
- item_prompt = node.at_xpath('.//xmlns:mattext').text
36
- item_prompt_words = item_prompt.split(CANVAS_REGEX)
37
- item_prompt_words.map.with_index do |stem_item, index|
38
- if stem_item.match CANVAS_REGEX
39
- @response_lid_nodes.children.map do |response_lid_node|
40
- if stem_item.include?(response_lid_node.text)
41
- @blank_id = response_lid_node.parent.attributes['ident']&.value
42
- end
43
- end
44
-
45
- {
46
- id: "stem_#{index}",
47
- position: index + 1,
48
- type: 'blank',
49
- blank_id: @blank_id
50
- }
51
- else
52
- {
53
- id: "stem_#{index}",
54
- position: index + 1,
55
- type: 'text',
56
- value: stem_item
57
- }
58
- end
59
- end
60
- end
61
-
62
-
63
33
  def qti_stem_items
64
34
  stem_item_nodes = node.xpath('.//xmlns:presentation').children
65
35
  stem_item_nodes.map.with_index do |stem_item, index|
66
36
  if stem_item.xpath('./xmlns:render_fib').present?
67
- {
68
- id: "stem_#{index}",
69
- position: index + 1,
70
- type: 'blank',
71
- blank_id: stem_item.attributes['ident'].value
72
- }
37
+ stem_blank(index, stem_item.attributes['ident'].value)
73
38
  else
74
- {
75
- id: "stem_#{index}",
76
- position: index + 1,
77
- type: 'text',
78
- value: stem_item.children.text
79
- }
39
+ stem_text(index, stem_item.children.text)
80
40
  end
81
41
  end
82
42
  end
@@ -116,9 +76,9 @@ module Qti
116
76
  ScoringData.new(
117
77
  value_node.content,
118
78
  rcardinality,
119
- id: value_node.attributes['respident']&.value || value_node.attributes['ident']&.value,
120
- case: value_node.attributes['case']&.value || 'no',
121
- parent_identifier: value_node.parent.parent.attributes['ident']&.value,
79
+ id: scoring_data_id(value_node),
80
+ case: scoring_data_case(value_node),
81
+ parent_identifier: value_node.parent.parent.attributes['ident']&.value
122
82
  )
123
83
  end
124
84
  end
@@ -137,6 +97,14 @@ module Qti
137
97
  @node.xpath('.//xmlns:varequal')
138
98
  end
139
99
  end
100
+
101
+ def scoring_data_id(node)
102
+ node.attributes['respident']&.value || node.attributes['ident']&.value
103
+ end
104
+
105
+ def scoring_data_case(node)
106
+ node.attributes['case']&.value || 'no'
107
+ end
140
108
  end
141
109
  end
142
110
  end
@@ -15,7 +15,7 @@ module Qti
15
15
  ScoringData.new(
16
16
  answer[:output],
17
17
  rcardinality,
18
- {id: answer[:id]}
18
+ id: answer[:id]
19
19
  )
20
20
  end
21
21
  end
@@ -46,10 +46,10 @@ module Qti
46
46
  end
47
47
 
48
48
  def margin_of_error
49
- if answer_tolerance.ends_with? "%"
50
- return {margin: answer_tolerance[0..-2], margin_type:'percent'}
49
+ if answer_tolerance.ends_with? '%'
50
+ return { margin: answer_tolerance[0..-2], margin_type: 'percent' }
51
51
  end
52
- {margin: answer_tolerance, margin_type:'absolute'}
52
+ { margin: answer_tolerance, margin_type: 'absolute' }
53
53
  end
54
54
 
55
55
  def formula_decimal_places
@@ -57,9 +57,7 @@ module Qti
57
57
  end
58
58
 
59
59
  def formulas
60
- node.xpath('.//xmlns:formula').map do |fnode|
61
- fnode.text
62
- end
60
+ node.xpath('.//xmlns:formula').map(&:text)
63
61
  end
64
62
 
65
63
  private
@@ -0,0 +1,34 @@
1
+ module Qti
2
+ module V1
3
+ module Models
4
+ module Interactions
5
+ class UploadInteraction < BaseInteraction
6
+ # This will know if a class matches
7
+ def self.matches(node, parent)
8
+ meta_node = node.at_xpath(
9
+ './/xmlns:qtimetadatafield[./xmlns:fieldlabel/text()="question_type"]'
10
+ )
11
+ return false unless meta_node.present?
12
+ type_node = meta_node.at_xpath('.//xmlns:fieldentry')
13
+ return false unless type_node&.text() == 'file_upload_question'
14
+ new(node, parent)
15
+ end
16
+
17
+ def item_body
18
+ @item_body ||= begin
19
+ node = @node.dup
20
+ presentation = node.at_xpath('.//xmlns:presentation')
21
+ mattext = presentation.at_xpath('.//xmlns:mattext')
22
+ inner_content = return_inner_content!(mattext)
23
+ sanitize_content!(inner_content)
24
+ end
25
+ end
26
+
27
+ def scoring_data_structs
28
+ { value: '' }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/qti/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Qti
2
- VERSION = '0.9.12'.freeze
2
+ VERSION = '0.9.13'.freeze
3
3
  end
@@ -0,0 +1,167 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <questestinterop xmlns="http://www.imsglobal.org/xsd/ims_qtiasiv1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd">
3
+ <assessment ident="ie797010092a6c1798006e216ba4c9c90" title="Multiple Drop Down">
4
+ <qtimetadata>
5
+ <qtimetadatafield>
6
+ <fieldlabel>cc_maxattempts</fieldlabel>
7
+ <fieldentry>1</fieldentry>
8
+ </qtimetadatafield>
9
+ </qtimetadata>
10
+ <section ident="root_section">
11
+ <item ident="id9d8b63d85a03f2987646622805b61cf" title="Question">
12
+ <itemmetadata>
13
+ <qtimetadata>
14
+ <qtimetadatafield>
15
+ <fieldlabel>question_type</fieldlabel>
16
+ <fieldentry>multiple_dropdowns_question</fieldentry>
17
+ </qtimetadatafield>
18
+ <qtimetadatafield>
19
+ <fieldlabel>points_possible</fieldlabel>
20
+ <fieldentry>1.0</fieldentry>
21
+ </qtimetadatafield>
22
+ <qtimetadatafield>
23
+ <fieldlabel>assessment_question_identifierref</fieldlabel>
24
+ <fieldentry>i7ad7f9841cc58f0a1392816b78aaa878</fieldentry>
25
+ </qtimetadatafield>
26
+ </qtimetadata>
27
+ </itemmetadata>
28
+ <presentation>
29
+ <material>
30
+ <mattext texttype="text/html">&lt;div&gt;&lt;p&gt;Roses are [color1], violets are [color2].&lt;/p&gt;&lt;/div&gt;</mattext>
31
+ </material>
32
+ <response_lid ident="response_color1">
33
+ <material>
34
+ <mattext>color1</mattext>
35
+ </material>
36
+ <render_choice>
37
+ <response_label ident="6548">
38
+ <material>
39
+ <mattext texttype="text/plain">red</mattext>
40
+ </material>
41
+ </response_label>
42
+ <response_label ident="5550">
43
+ <material>
44
+ <mattext texttype="text/plain">plaid</mattext>
45
+ </material>
46
+ </response_label>
47
+ </render_choice>
48
+ </response_lid>
49
+ <response_lid ident="response_color2">
50
+ <material>
51
+ <mattext>color2</mattext>
52
+ </material>
53
+ <render_choice>
54
+ <response_label ident="6951">
55
+ <material>
56
+ <mattext texttype="text/plain">blue</mattext>
57
+ </material>
58
+ </response_label>
59
+ <response_label ident="4500">
60
+ <material>
61
+ <mattext texttype="text/plain">paisely</mattext>
62
+ </material>
63
+ </response_label>
64
+ </render_choice>
65
+ </response_lid>
66
+ </presentation>
67
+ <resprocessing>
68
+ <outcomes>
69
+ <decvar maxvalue="100" minvalue="0" varname="SCORE" vartype="Decimal"/>
70
+ </outcomes>
71
+ <respcondition continue="Yes">
72
+ <conditionvar>
73
+ <other/>
74
+ </conditionvar>
75
+ <displayfeedback feedbacktype="Response" linkrefid="general_fb"/>
76
+ </respcondition>
77
+ <respcondition continue="Yes">
78
+ <conditionvar>
79
+ <varequal respident="response_color1">6548</varequal>
80
+ </conditionvar>
81
+ <displayfeedback feedbacktype="Response" linkrefid="6548_fb"/>
82
+ </respcondition>
83
+ <respcondition continue="Yes">
84
+ <conditionvar>
85
+ <varequal respident="response_color1">5550</varequal>
86
+ </conditionvar>
87
+ <displayfeedback feedbacktype="Response" linkrefid="5550_fb"/>
88
+ </respcondition>
89
+ <respcondition continue="Yes">
90
+ <conditionvar>
91
+ <varequal respident="response_color2">6951</varequal>
92
+ </conditionvar>
93
+ <displayfeedback feedbacktype="Response" linkrefid="6951_fb"/>
94
+ </respcondition>
95
+ <respcondition continue="Yes">
96
+ <conditionvar>
97
+ <varequal respident="response_color2">4500</varequal>
98
+ </conditionvar>
99
+ <displayfeedback feedbacktype="Response" linkrefid="4500_fb"/>
100
+ </respcondition>
101
+ <respcondition>
102
+ <conditionvar>
103
+ <varequal respident="response_color1">6548</varequal>
104
+ </conditionvar>
105
+ <setvar varname="SCORE" action="Add">50.00</setvar>
106
+ </respcondition>
107
+ <respcondition>
108
+ <conditionvar>
109
+ <varequal respident="response_color2">6951</varequal>
110
+ </conditionvar>
111
+ <setvar varname="SCORE" action="Add">50.00</setvar>
112
+ </respcondition>
113
+ </resprocessing>
114
+ <itemfeedback ident="general_fb">
115
+ <flow_mat>
116
+ <material>
117
+ <mattext texttype="text/html">&lt;p&gt;Roses come in many colors, violets probably do too.&lt;/p&gt;
118
+ &lt;p&gt;Never the less, the correct answers were &lt;strong&gt;red&lt;/strong&gt; and &lt;strong&gt;blue&lt;/strong&gt;.&lt;/p&gt;</mattext>
119
+ </material>
120
+ </flow_mat>
121
+ </itemfeedback>
122
+ <itemfeedback ident="correct_fb">
123
+ <flow_mat>
124
+ <material>
125
+ <mattext texttype="text/html">&lt;p&gt;Completing the poem, is left to you.&lt;/p&gt;</mattext>
126
+ </material>
127
+ </flow_mat>
128
+ </itemfeedback>
129
+ <itemfeedback ident="general_incorrect_fb">
130
+ <flow_mat>
131
+ <material>
132
+ <mattext texttype="text/html">&lt;p&gt;Those aren't colors, you meant &lt;strong&gt;red&lt;/strong&gt; and &lt;strong&gt;blue&lt;/strong&gt;.&lt;/p&gt;</mattext>
133
+ </material>
134
+ </flow_mat>
135
+ </itemfeedback>
136
+ <itemfeedback ident="6548_fb">
137
+ <flow_mat>
138
+ <material>
139
+ <mattext texttype="text/html">&lt;p&gt;Yes! &lt;strong&gt;Red&lt;/strong&gt;.&lt;/p&gt;</mattext>
140
+ </material>
141
+ </flow_mat>
142
+ </itemfeedback>
143
+ <itemfeedback ident="5550_fb">
144
+ <flow_mat>
145
+ <material>
146
+ <mattext texttype="text/html">&lt;p&gt;I'm pretty sure you meant &lt;strong&gt;red.&lt;/strong&gt;&lt;/p&gt;</mattext>
147
+ </material>
148
+ </flow_mat>
149
+ </itemfeedback>
150
+ <itemfeedback ident="6951_fb">
151
+ <flow_mat>
152
+ <material>
153
+ <mattext texttype="text/html">&lt;p&gt;Yes, &lt;strong&gt;blue&lt;/strong&gt;!&lt;/p&gt;</mattext>
154
+ </material>
155
+ </flow_mat>
156
+ </itemfeedback>
157
+ <itemfeedback ident="4500_fb">
158
+ <flow_mat>
159
+ <material>
160
+ <mattext texttype="text/html">&lt;p&gt;Did you also chose plaid? You wanted to &lt;strong&gt;blue&lt;/strong&gt;.&lt;/p&gt;</mattext>
161
+ </material>
162
+ </flow_mat>
163
+ </itemfeedback>
164
+ </item>
165
+ </section>
166
+ </assessment>
167
+ </questestinterop>
@@ -0,0 +1,167 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <questestinterop xmlns="http://www.imsglobal.org/xsd/ims_qtiasiv1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd">
3
+ <assessment ident="ie797010092a6c1798006e216ba4c9c90" title="Multiple Drop Down">
4
+ <qtimetadata>
5
+ <qtimetadatafield>
6
+ <fieldlabel>cc_maxattempts</fieldlabel>
7
+ <fieldentry>1</fieldentry>
8
+ </qtimetadatafield>
9
+ </qtimetadata>
10
+ <section ident="root_section">
11
+ <item ident="id9d8b63d85a03f2987646622805b61cf" title="Question">
12
+ <itemmetadata>
13
+ <qtimetadata>
14
+ <qtimetadatafield>
15
+ <fieldlabel>question_type</fieldlabel>
16
+ <fieldentry>multiple_dropdowns_question</fieldentry>
17
+ </qtimetadatafield>
18
+ <qtimetadatafield>
19
+ <fieldlabel>points_possible</fieldlabel>
20
+ <fieldentry>1.0</fieldentry>
21
+ </qtimetadatafield>
22
+ <qtimetadatafield>
23
+ <fieldlabel>assessment_question_identifierref</fieldlabel>
24
+ <fieldentry>i7ad7f9841cc58f0a1392816b78aaa878</fieldentry>
25
+ </qtimetadatafield>
26
+ </qtimetadata>
27
+ </itemmetadata>
28
+ <presentation>
29
+ <material>
30
+ <mattext texttype="text/html">&lt;div&gt;&lt;p&gt;Roses are [color1], violets are [color2].&lt;/p&gt;&lt;/div&gt;</mattext>
31
+ </material>
32
+ <response_lid ident="response_color1">
33
+ <material>
34
+ <mattext>color1</mattext>
35
+ </material>
36
+ <render_choice>
37
+ <response_label ident="6548">
38
+ <material>
39
+ <mattext texttype="text/plain">red</mattext>
40
+ </material>
41
+ </response_label>
42
+ <response_label ident="5550">
43
+ <material>
44
+ <mattext texttype="text/plain">plaid</mattext>
45
+ </material>
46
+ </response_label>
47
+ </render_choice>
48
+ </response_lid>
49
+ <response_lid ident="response_color2">
50
+ <material>
51
+ <mattext>color2</mattext>
52
+ </material>
53
+ <render_choice>
54
+ <response_label ident="6951">
55
+ <material>
56
+ <mattext texttype="text/plain">blue</mattext>
57
+ </material>
58
+ </response_label>
59
+ <response_label ident="4500">
60
+ <material>
61
+ <mattext texttype="text/plain">paisely</mattext>
62
+ </material>
63
+ </response_label>
64
+ </render_choice>
65
+ </response_lid>
66
+ </presentation>
67
+ <resprocessing>
68
+ <outcomes>
69
+ <decvar maxvalue="100" minvalue="0" varname="SCORE" vartype="Decimal"/>
70
+ </outcomes>
71
+ <respcondition continue="Yes">
72
+ <conditionvar>
73
+ <other/>
74
+ </conditionvar>
75
+ <displayfeedback feedbacktype="Response" linkrefid="general_fb"/>
76
+ </respcondition>
77
+ <respcondition continue="Yes">
78
+ <conditionvar>
79
+ <varequal respident="response_color1">6548</varequal>
80
+ </conditionvar>
81
+ <displayfeedback feedbacktype="Response" linkrefid="6548_fb"/>
82
+ </respcondition>
83
+ <respcondition continue="Yes">
84
+ <conditionvar>
85
+ <varequal respident="response_color1">5550</varequal>
86
+ </conditionvar>
87
+ <displayfeedback feedbacktype="Response" linkrefid="5550_fb"/>
88
+ </respcondition>
89
+ <respcondition continue="Yes">
90
+ <conditionvar>
91
+ <varequal respident="response_color2">6951</varequal>
92
+ </conditionvar>
93
+ <displayfeedback feedbacktype="Response" linkrefid="6951_fb"/>
94
+ </respcondition>
95
+ <respcondition continue="Yes">
96
+ <conditionvar>
97
+ <varequal respident="response_color2">4500</varequal>
98
+ </conditionvar>
99
+ <displayfeedback feedbacktype="Response" linkrefid="4500_fb"/>
100
+ </respcondition>
101
+ <respcondition>
102
+ <conditionvar>
103
+ <varequal respident="response_color1">6548</varequal>
104
+ </conditionvar>
105
+ <setvar varname="SCORE" action="Add">50.00</setvar>
106
+ </respcondition>
107
+ <respcondition>
108
+ <conditionvar>
109
+ <varequal respident="response_color2">6951</varequal>
110
+ </conditionvar>
111
+ <setvar varname="SCORE" action="Add">50.00</setvar>
112
+ </respcondition>
113
+ </resprocessing>
114
+ <itemfeedback ident="general_fb">
115
+ <flow_mat>
116
+ <material>
117
+ <mattext texttype="text/html">&lt;p&gt;Roses come in many colors, violets probably do too.&lt;/p&gt;
118
+ &lt;p&gt;Never the less, the correct answers were &lt;strong&gt;red&lt;/strong&gt; and &lt;strong&gt;blue&lt;/strong&gt;.&lt;/p&gt;</mattext>
119
+ </material>
120
+ </flow_mat>
121
+ </itemfeedback>
122
+ <itemfeedback ident="correct_fb">
123
+ <flow_mat>
124
+ <material>
125
+ <mattext texttype="text/html">&lt;p&gt;Completing the poem, is left to you.&lt;/p&gt;</mattext>
126
+ </material>
127
+ </flow_mat>
128
+ </itemfeedback>
129
+ <itemfeedback ident="general_incorrect_fb">
130
+ <flow_mat>
131
+ <material>
132
+ <mattext texttype="text/html">&lt;p&gt;Those aren't colors, you meant &lt;strong&gt;red&lt;/strong&gt; and &lt;strong&gt;blue&lt;/strong&gt;.&lt;/p&gt;</mattext>
133
+ </material>
134
+ </flow_mat>
135
+ </itemfeedback>
136
+ <itemfeedback ident="6548_fb">
137
+ <flow_mat>
138
+ <material>
139
+ <mattext texttype="text/html">&lt;p&gt;Yes! &lt;strong&gt;Red&lt;/strong&gt;.&lt;/p&gt;</mattext>
140
+ </material>
141
+ </flow_mat>
142
+ </itemfeedback>
143
+ <itemfeedback ident="5550_fb">
144
+ <flow_mat>
145
+ <material>
146
+ <mattext texttype="text/html">&lt;p&gt;I'm pretty sure you meant &lt;strong&gt;red.&lt;/strong&gt;&lt;/p&gt;</mattext>
147
+ </material>
148
+ </flow_mat>
149
+ </itemfeedback>
150
+ <itemfeedback ident="6951_fb">
151
+ <flow_mat>
152
+ <material>
153
+ <mattext texttype="text/html">&lt;p&gt;Yes, &lt;strong&gt;blue&lt;/strong&gt;!&lt;/p&gt;</mattext>
154
+ </material>
155
+ </flow_mat>
156
+ </itemfeedback>
157
+ <itemfeedback ident="4500_fb">
158
+ <flow_mat>
159
+ <material>
160
+ <mattext texttype="text/html">&lt;p&gt;Did you also chose plaid? You wanted to &lt;strong&gt;blue&lt;/strong&gt;.&lt;/p&gt;</mattext>
161
+ </material>
162
+ </flow_mat>
163
+ </itemfeedback>
164
+ </item>
165
+ </section>
166
+ </assessment>
167
+ </questestinterop>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <questestinterop xmlns="http://www.imsglobal.org/xsd/ims_qtiasiv1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd">
3
+ <qtimetadata>
4
+ <qtimetadatafield>
5
+ <fieldlabel>cc_maxattempts</fieldlabel>
6
+ <fieldentry>1</fieldentry>
7
+ </qtimetadatafield>
8
+ </qtimetadata>
9
+ <section ident="root_section">
10
+ <item ident="i53d46f6a4edbfcefd662489e9f2a970a" title="Question">
11
+ <itemmetadata>
12
+ <qtimetadata>
13
+ <qtimetadatafield>
14
+ <fieldlabel>question_type</fieldlabel>
15
+ <fieldentry>file_upload_question</fieldentry>
16
+ </qtimetadatafield>
17
+ <qtimetadatafield>
18
+ <fieldlabel>points_possible</fieldlabel>
19
+ <fieldentry>1.0</fieldentry>
20
+ </qtimetadatafield>
21
+ <qtimetadatafield>
22
+ <fieldlabel>assessment_question_identifierref</fieldlabel>
23
+ <fieldentry>i2b5557c31dcad5441b956ebb83d06915</fieldentry>
24
+ </qtimetadatafield>
25
+ </qtimetadata>
26
+ </itemmetadata>
27
+ <presentation>
28
+ <material>
29
+ <mattext texttype="text/html">Upload a file that is a CSV</mattext>
30
+ </material>
31
+ </presentation>
32
+ </item>
33
+ </section>
34
+ </questestinterop>
@@ -1,7 +1,10 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- qti (0.9.12)
4
+ mathml2latex (0.1.2)
5
+ activesupport (>= 4.2.9, < 5.2)
6
+ nokogiri (>= 1.6.8)
7
+ qti (0.9.13)
5
8
  actionview (>= 4.2.0)
6
9
  activesupport (>= 4.2.9, < 5.2)
7
10
  dry-struct (~> 0.2.1)
@@ -67,9 +70,6 @@ GEM
67
70
  loofah (2.2.2)
68
71
  crass (~> 1.0.2)
69
72
  nokogiri (>= 1.5.9)
70
- mathml2latex (0.1.1)
71
- activesupport (>= 4.2.9, < 5.2)
72
- nokogiri (~> 1.8)
73
73
  method_source (0.9.0)
74
74
  mini_portile2 (2.3.0)
75
75
  minitest (5.11.3)
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::V1::Models::Interactions::CanvasMultipleDropdownInteraction do
4
+ let(:fixtures_path) { File.join('spec', 'fixtures', 'items_1.2') }
5
+ let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
6
+ let(:assessment_item_refs) { test_object.assessment_items }
7
+ let(:loaded_class) { described_class.new(assessment_item_refs.first, test_object) }
8
+
9
+ shared_examples_for 'shuffled?' do
10
+ it 'returns shuffle setting' do
11
+ expect(loaded_class.shuffled?).to eq shuffle_value
12
+ end
13
+ end
14
+
15
+ shared_examples_for 'blanks' do
16
+ it 'returns the blanks' do
17
+ expect(loaded_class.blanks).to eq(expected_blanks)
18
+ end
19
+ end
20
+
21
+ shared_examples_for 'answers' do
22
+ it 'returns the answers' do
23
+ expect(loaded_class.answers.count).to eq answer_count
24
+ expect(loaded_class.answers).to eq(expected_answers)
25
+ end
26
+ end
27
+
28
+ shared_examples_for 'stem_items' do
29
+ it 'returns the stem_items' do
30
+ expect(loaded_class.stem_items).to eq(expected_stem_items)
31
+ end
32
+ end
33
+
34
+ shared_examples_for 'scoring_data_structs' do
35
+ it 'returns the scoring_data_structs' do
36
+ expect(loaded_class.scoring_data_structs.map(&:id)).to eq(scoring_data_ids)
37
+ expect(loaded_class.scoring_data_structs.map(&:values)).to eq(scoring_data_values)
38
+ end
39
+ end
40
+
41
+ context 'canvas_multiple_dropdowns.xml' do
42
+ let(:file_path) { File.join(fixtures_path, 'canvas_multiple_dropdowns.xml') }
43
+ let(:shuffle_value) { false }
44
+ let(:answer_count) { 2 }
45
+ let(:scoring_data_ids) { %w[response_color1 response_color2] }
46
+ let(:scoring_data_values) do
47
+ [
48
+ { id: '6548', position: 2, item_body: 'red' },
49
+ { id: '6951', position: 2, item_body: 'blue' }
50
+ ]
51
+ end
52
+ let(:expected_blanks) do
53
+ [
54
+ {
55
+ id: 'response_color1',
56
+ choices:
57
+ [
58
+ { id: '6548', position: 2, item_body: 'red' },
59
+ { id: '5550', position: 3, item_body: 'plaid' }
60
+ ]
61
+ },
62
+ {
63
+ id: 'response_color2',
64
+ choices:
65
+ [
66
+ { id: '6951', position: 2, item_body: 'blue' },
67
+ { id: '4500', position: 3, item_body: 'paisely' }
68
+ ]
69
+ }
70
+ ]
71
+ end
72
+ let(:expected_stem_items) do
73
+ [
74
+ { id: 'stem_0', position: 1, type: 'text', value: '<div><p>Roses are ' },
75
+ { id: 'stem_1', position: 2, type: 'blank', blank_id: 'response_color1' },
76
+ { id: 'stem_2', position: 3, type: 'text', value: ', violets are ' },
77
+ { id: 'stem_3', position: 4, type: 'blank', blank_id: 'response_color2' },
78
+ { id: 'stem_4', position: 5, type: 'text', value: '.</p></div>' }
79
+ ]
80
+ end
81
+ let('expected_answers') do
82
+ [
83
+ {
84
+ value: 'response_color1',
85
+ entry_id: '6548',
86
+ blank_text: 'red',
87
+ action: 'Add',
88
+ point_value: '50.00'
89
+ },
90
+ {
91
+ value: 'response_color2',
92
+ entry_id: '6951',
93
+ blank_text: 'blue',
94
+ action: 'Add',
95
+ point_value: '50.00'
96
+ }
97
+ ]
98
+ end
99
+
100
+ include_examples 'shuffled?'
101
+ include_examples 'answers'
102
+ include_examples 'blanks'
103
+ include_examples 'stem_items'
104
+ include_examples 'scoring_data_structs'
105
+ end
106
+ end
@@ -45,11 +45,11 @@ describe Qti::V1::Models::Interactions::FillBlankInteraction do
45
45
  let(:scoring_data_values) { %w[Illinois illinois] }
46
46
  let(:scoring_data_case) { %w[no no] }
47
47
  let(:answer_count) { 2 }
48
- let(:expected_blanks) {[{ id: 'response1' }]}
48
+ let(:expected_blanks) { [{ id: 'response1' }] }
49
49
  let(:expected_stem_items) do
50
50
  [
51
- {:id=>"stem_0", :position=>1, :type=>"text", :value=>"<div><p>Chicago is in what state?</p></div>"},
52
- {:id=>"stem_1", :position=>2, :type=>"blank", :blank_id=>"response1"}
51
+ { id: 'stem_0', position: 1, type: 'text', value: '<div><p>Chicago is in what state?</p></div>' },
52
+ { id: 'stem_1', position: 2, type: 'blank', blank_id: 'response1' }
53
53
  ]
54
54
  end
55
55
 
@@ -70,14 +70,14 @@ describe Qti::V1::Models::Interactions::FillBlankInteraction do
70
70
  let(:scoring_data_values) { %w[red Red blue Blue] }
71
71
  let(:scoring_data_case) { %w[no no no no] }
72
72
  let(:answer_count) { 4 }
73
- let(:expected_blanks) {[{id: '9799'}, {id: '5231'}, {id: '5939'}, {id: '6364'}]}
73
+ let(:expected_blanks) { [{ id: '9799' }, { id: '5231' }, { id: '5939' }, { id: '6364' }] }
74
74
  let(:expected_stem_items) do
75
75
  [
76
76
  { id: 'stem_0', position: 1, type: 'text', value: '<div><p><span>Roses are ' },
77
77
  { id: 'stem_1', position: 2, type: 'blank', blank_id: 'response_color1' },
78
78
  { id: 'stem_2', position: 3, type: 'text', value: ', violets are ' },
79
79
  { id: 'stem_3', position: 4, type: 'blank', blank_id: 'response_color2' },
80
- { id: "stem_4", position: 5, type: "text", value: "</span></p></div>"}
80
+ { id: 'stem_4', position: 5, type: 'text', value: '</span></p></div>' }
81
81
  ]
82
82
  end
83
83
 
@@ -99,7 +99,7 @@ describe Qti::V1::Models::Interactions::FillBlankInteraction do
99
99
  let(:scoring_data_values) { %w[Winter Summer York] }
100
100
  let(:scoring_data_case) { %w[Yes Yes Yes] }
101
101
  let(:answer_count) { 3 }
102
- let(:expected_blanks) {[{ id: 'FIB01' }, { id: 'FIB02' }, { id: 'FIB03' }]}
102
+ let(:expected_blanks) { [{ id: 'FIB01' }, { id: 'FIB02' }, { id: 'FIB03' }] }
103
103
  let(:expected_stem_items) do
104
104
  [
105
105
  { id: 'stem_0', position: 1, type: 'text', value: 'Fill-in-the blanks in this text from Richard III: ' },
@@ -45,9 +45,9 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
45
45
  let(:formula_decimal_places) { '0' }
46
46
  let(:formula_formulas) { ['x'] }
47
47
 
48
- let(:item_title) {'<div><p>What number is [x]</p></div>'}
48
+ let(:item_title) { '<div><p>What number is [x]</p></div>' }
49
49
 
50
- let(:variables) { [ { name: 'x', min: '1.0', max: '10.0', precision: '0' } ] }
50
+ let(:variables) { [{ name: 'x', min: '1.0', max: '10.0', precision: '0' }] }
51
51
 
52
52
  include_examples 'scoring_data_structs'
53
53
  include_examples 'reading_formulas'
@@ -65,10 +65,12 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
65
65
  let(:formula_decimal_places) { '0' }
66
66
  let(:formula_formulas) { ['x+y'] }
67
67
 
68
- let(:item_title) {'<div><p>[x] + [y]</p></div>'}
68
+ let(:item_title) { '<div><p>[x] + [y]</p></div>' }
69
69
 
70
- let(:variables) { [ { name: 'x', min: '1.0', max: '10.0', precision: '0' },
71
- { name: 'y', min: '1.0', max: '10.0', precision: '0' } ] }
70
+ let(:variables) do
71
+ [{ name: 'x', min: '1.0', max: '10.0', precision: '0' },
72
+ { name: 'y', min: '1.0', max: '10.0', precision: '0' }]
73
+ end
72
74
 
73
75
  include_examples 'scoring_data_structs'
74
76
  include_examples 'answer_tolerance'
@@ -86,12 +88,14 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
86
88
  let(:formula_decimal_places) { '2' }
87
89
  let(:formula_formulas) { ['x=n*x', 'y=m*y', 'x+y'] }
88
90
 
89
- let(:item_title) {'<div><p>[n][x] + [m][y]</p></div>'}
91
+ let(:item_title) { '<div><p>[n][x] + [m][y]</p></div>' }
90
92
 
91
- let(:variables) { [ { name: 'y', min: '1.0', max: '10.0', precision: '2' },
92
- { name: 'x', min: '1.0', max: '10.0', precision: '2' },
93
- { name: 'n', min: '1.0', max: '10.0', precision: '2' },
94
- { name: 'm', min: '1.0', max: '10.0', precision: '2' } ] }
93
+ let(:variables) do
94
+ [{ name: 'y', min: '1.0', max: '10.0', precision: '2' },
95
+ { name: 'x', min: '1.0', max: '10.0', precision: '2' },
96
+ { name: 'n', min: '1.0', max: '10.0', precision: '2' },
97
+ { name: 'm', min: '1.0', max: '10.0', precision: '2' }]
98
+ end
95
99
 
96
100
  include_examples 'scoring_data_structs'
97
101
  include_examples 'answer_tolerance'
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::V1::Models::Interactions::UploadInteraction do
4
+ let(:fixtures_path) { File.join('spec', 'fixtures', 'items_1.2') }
5
+ let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
6
+ let(:assessment_item_refs) { test_object.assessment_items }
7
+ let(:loaded_class) { described_class.new(assessment_item_refs.first, test_object) }
8
+
9
+ context 'upload.xml' do
10
+ let(:file_path) { File.join(fixtures_path, 'upload.xml') }
11
+ let(:cardinality) { 'Single' }
12
+
13
+ it 'returns loads the correct cardinality' do
14
+ expect(loaded_class.send(:rcardinality)).to eq(cardinality)
15
+ end
16
+
17
+ context '#item_body' do
18
+ let(:loaded_class) { described_class.new(assessment_item_refs.first, test_object) }
19
+ it 'returns right title' do
20
+ expect(loaded_class.item_body).to eq 'Upload a file that is a CSV'
21
+ end
22
+ end
23
+
24
+ describe '#scoring_data_structs' do
25
+ it 'grabs scoring data value for matching questions' do
26
+ expect(loaded_class.scoring_data_structs).to eq(
27
+ value: ''
28
+ )
29
+ end
30
+ end
31
+ end
32
+ end
@@ -71,18 +71,14 @@ describe Qti::V1::Models::Numerics::Precision do
71
71
 
72
72
  context '#significant_digits' do
73
73
  it 'returns correct number for leading zeros' do
74
- expect(described_class.significant_digits('0.0000123')).
75
- to eq(3)
74
+ expect(described_class.significant_digits('0.0000123')).to eq(3)
76
75
  end
77
76
  it 'returns correct number for trailing zeros' do
78
- expect(described_class.significant_digits('0.0000123000')).
79
- to eq(3)
77
+ expect(described_class.significant_digits('0.0000123000')).to eq(3)
80
78
  end
81
79
  it 'returns correct number for zeros in the middle' do
82
- expect(described_class.significant_digits('0.000012003')).
83
- to eq(5)
84
- expect(described_class.significant_digits('15.000012003')).
85
- to eq(11)
80
+ expect(described_class.significant_digits('0.000012003')).to eq(5)
81
+ expect(described_class.significant_digits('15.000012003')).to eq(11)
86
82
  end
87
83
  end
88
84
  end
@@ -86,7 +86,9 @@ describe Qti::V2::Models::AssessmentItem do
86
86
 
87
87
  # it 'removes the passage from the item_body' do
88
88
  # item = test_object.create_assessment_item(item_ref)
89
+ # rubocop:disable AsciiComments
89
90
  # expect(item.item_body).not_to include '¡El equipo de hockey te necesita!'
91
+ # rubocop:enable AsciiComments
90
92
  # end
91
93
  # end
92
94
  end
@@ -86,7 +86,9 @@ describe Qti::V2::Models::AssessmentTest do
86
86
  # 'passages', '0cfd5cf7-2c91-4b35-a57a-9f5d1709f68f.html'
87
87
  # )
88
88
  # stimulus = loaded_class.create_stimulus(stimulus_path)
89
+ # rubocop:disable AsciiComments
89
90
  # expect(stimulus.title).to eq '¡El equipo de hockey te necesita!'
91
+ # rubocop:enable AsciiComments
90
92
  # end
91
93
  # end
92
94
  end
@@ -2,8 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  fixtures_path = File.join('spec', 'fixtures')
4
4
 
5
-
6
-
7
5
  describe Qti::V2::Models::NonAssessmentTest do
8
6
  shared_examples_for 'loading_a_non-assessment' do
9
7
  it 'loads an Non-AssessmentTest XML file' do
@@ -13,13 +13,17 @@
13
13
  # end
14
14
 
15
15
  # it 'has the title' do
16
+ # rubocop:disable AsciiComments
16
17
  # expect(loaded_class.title).to eq '¡El equipo de hockey te necesita!'
18
+ # rubocop:enable AsciiComments
17
19
  # end
18
20
 
19
21
  # it 'has sanitized item_body' do
20
22
  # expect(loaded_class.body).to include '<div'
21
23
  # expect(loaded_class.body).to include 'Listen to the audio passage.'
24
+ # rubocop:disable AsciiComments
22
25
  # expect(loaded_class.body).to include '¡'
26
+ # rubocop:enable AsciiComments
23
27
  # end
24
28
 
25
29
  # it 'has the identifier used to identify it in manifest file' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.12
4
+ version: 0.9.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hannah Bottalla
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-04-04 00:00:00.000000000 Z
12
+ date: 2018-04-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -296,7 +296,9 @@ files:
296
296
  - lib/qti/v1/models/choices/fill_blank_choice.rb
297
297
  - lib/qti/v1/models/choices/logical_identifier_choice.rb
298
298
  - lib/qti/v1/models/interactions.rb
299
+ - lib/qti/v1/models/interactions/base_fill_blank_interaction.rb
299
300
  - lib/qti/v1/models/interactions/base_interaction.rb
301
+ - lib/qti/v1/models/interactions/canvas_multiple_dropdown.rb
300
302
  - lib/qti/v1/models/interactions/choice_interaction.rb
301
303
  - lib/qti/v1/models/interactions/fill_blank_interaction.rb
302
304
  - lib/qti/v1/models/interactions/formula_interaction.rb
@@ -304,6 +306,7 @@ files:
304
306
  - lib/qti/v1/models/interactions/numeric_interaction.rb
305
307
  - lib/qti/v1/models/interactions/ordering_interaction.rb
306
308
  - lib/qti/v1/models/interactions/string_interaction.rb
309
+ - lib/qti/v1/models/interactions/upload_interaction.rb
307
310
  - lib/qti/v1/models/numerics/exact_match.rb
308
311
  - lib/qti/v1/models/numerics/margin_error.rb
309
312
  - lib/qti/v1/models/numerics/precision.rb
@@ -333,6 +336,8 @@ files:
333
336
  - lib/qti/v2/models/scoring_data.rb
334
337
  - lib/qti/v2/models/stimulus_item.rb
335
338
  - lib/qti/version.rb
339
+ - spec/fixtures/items_1.2/canvas_multiple_dropdown.xml
340
+ - spec/fixtures/items_1.2/canvas_multiple_dropdowns.xml
336
341
  - spec/fixtures/items_1.2/canvas_multiple_fib.xml
337
342
  - spec/fixtures/items_1.2/choice.xml
338
343
  - spec/fixtures/items_1.2/essay.xml
@@ -352,6 +357,7 @@ files:
352
357
  - spec/fixtures/items_1.2/ordering.xml
353
358
  - spec/fixtures/items_1.2/single_fib.xml
354
359
  - spec/fixtures/items_1.2/true_false.xml
360
+ - spec/fixtures/items_1.2/upload.xml
355
361
  - spec/fixtures/items_2.1/Example02-feedbackInline.xml
356
362
  - spec/fixtures/items_2.1/categorization.xml
357
363
  - spec/fixtures/items_2.1/choice.xml
@@ -570,6 +576,7 @@ files:
570
576
  - spec/lib/qti/v1/models/choices/fill_blank_choice_spec.rb
571
577
  - spec/lib/qti/v1/models/choices/logical_identifier_choice_spec.rb
572
578
  - spec/lib/qti/v1/models/interactions/base_interaction_spec.rb
579
+ - spec/lib/qti/v1/models/interactions/canvas_multiple_dropdown_spec.rb
573
580
  - spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb
574
581
  - spec/lib/qti/v1/models/interactions/fill_blank_interaction_spec.rb
575
582
  - spec/lib/qti/v1/models/interactions/formula_interaction_spec.rb
@@ -577,6 +584,7 @@ files:
577
584
  - spec/lib/qti/v1/models/interactions/numeric_interaction_spec.rb
578
585
  - spec/lib/qti/v1/models/interactions/ordering_interaction_spec.rb
579
586
  - spec/lib/qti/v1/models/interactions/string_interaction_spec.rb
587
+ - spec/lib/qti/v1/models/interactions/upload_interaction_spec.rb
580
588
  - spec/lib/qti/v1/models/numerics/exact_match_spec.rb
581
589
  - spec/lib/qti/v1/models/numerics/margin_error_spec.rb
582
590
  - spec/lib/qti/v1/models/numerics/precision_spec.rb
@@ -626,6 +634,8 @@ signing_key:
626
634
  specification_version: 4
627
635
  summary: QTI 1.2 and 2.1 import and export models
628
636
  test_files:
637
+ - spec/fixtures/items_1.2/canvas_multiple_dropdown.xml
638
+ - spec/fixtures/items_1.2/canvas_multiple_dropdowns.xml
629
639
  - spec/fixtures/items_1.2/canvas_multiple_fib.xml
630
640
  - spec/fixtures/items_1.2/choice.xml
631
641
  - spec/fixtures/items_1.2/essay.xml
@@ -645,6 +655,7 @@ test_files:
645
655
  - spec/fixtures/items_1.2/ordering.xml
646
656
  - spec/fixtures/items_1.2/single_fib.xml
647
657
  - spec/fixtures/items_1.2/true_false.xml
658
+ - spec/fixtures/items_1.2/upload.xml
648
659
  - spec/fixtures/items_2.1/Example02-feedbackInline.xml
649
660
  - spec/fixtures/items_2.1/categorization.xml
650
661
  - spec/fixtures/items_2.1/choice.xml
@@ -863,6 +874,7 @@ test_files:
863
874
  - spec/lib/qti/v1/models/choices/fill_blank_choice_spec.rb
864
875
  - spec/lib/qti/v1/models/choices/logical_identifier_choice_spec.rb
865
876
  - spec/lib/qti/v1/models/interactions/base_interaction_spec.rb
877
+ - spec/lib/qti/v1/models/interactions/canvas_multiple_dropdown_spec.rb
866
878
  - spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb
867
879
  - spec/lib/qti/v1/models/interactions/fill_blank_interaction_spec.rb
868
880
  - spec/lib/qti/v1/models/interactions/formula_interaction_spec.rb
@@ -870,6 +882,7 @@ test_files:
870
882
  - spec/lib/qti/v1/models/interactions/numeric_interaction_spec.rb
871
883
  - spec/lib/qti/v1/models/interactions/ordering_interaction_spec.rb
872
884
  - spec/lib/qti/v1/models/interactions/string_interaction_spec.rb
885
+ - spec/lib/qti/v1/models/interactions/upload_interaction_spec.rb
873
886
  - spec/lib/qti/v1/models/numerics/exact_match_spec.rb
874
887
  - spec/lib/qti/v1/models/numerics/margin_error_spec.rb
875
888
  - spec/lib/qti/v1/models/numerics/precision_spec.rb