qti 1.0.7 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/qti/v1/models/interactions.rb +1 -1
- data/lib/qti/v1/models/interactions/base_interaction.rb +13 -2
- data/lib/qti/v1/models/interactions/choice_interaction.rb +8 -0
- data/lib/qti/v1/models/interactions/fill_blank_interaction.rb +2 -2
- data/lib/qti/version.rb +1 -1
- data/spec/fixtures/items_1.2/canvas_multiple_fib_as_single.xml +49 -0
- data/spec/lib/qti/v1/models/interactions/fill_blank_interaction_spec.rb +59 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e53f243da494ee925b59209d0dd07bb4a2cabe94
|
4
|
+
data.tar.gz: 824890bebce7299bf5d4acfb11a8499354452965
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60fb5c2db7b83bc57183d633f95d1929aa6601975eb796c87f5e9a84ca378d68f645468c4d280717ae715030e699cce580037c5f6f572e6aa846a9407489537f
|
7
|
+
data.tar.gz: 8879e659c17e6e7cc0c4400eacabcc594b2964dca2ce45175a84b320ce92c2621d99277b3a755b11a3a7d09a1fcda1544d67c9fdbc374b21b066a38763d07b9b
|
@@ -19,7 +19,7 @@ module Qti
|
|
19
19
|
matches = Interactions.get_matches(node, parent, subclasses)
|
20
20
|
matches = Interactions.get_matches(node, parent, FALLBACK_CLASSES) if matches.empty?
|
21
21
|
|
22
|
-
raise UnsupportedSchema if matches.size != 1
|
22
|
+
raise UnsupportedSchema, "Multiple Types (#{matches.map(&:class)})" if matches.size != 1
|
23
23
|
matches.first
|
24
24
|
end
|
25
25
|
|
@@ -11,8 +11,19 @@ module Qti
|
|
11
11
|
|
12
12
|
def self.canvas_multiple_fib?(node)
|
13
13
|
matches = node.xpath('.//xmlns:response_lid')
|
14
|
-
return false if matches.count
|
15
|
-
node
|
14
|
+
return false if matches.count < 1
|
15
|
+
question_type(node) == 'fill_in_multiple_blanks_question'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.question_type(node)
|
19
|
+
path = './/xmlns:qtimetadatafield/xmlns:fieldlabel' \
|
20
|
+
'[text()="question_type"]/../xmlns:fieldentry'
|
21
|
+
node.at_xpath(path)&.text
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.maybe_question_type(node, qtype)
|
25
|
+
question_type = self.question_type(node)
|
26
|
+
!question_type || question_type == qtype
|
16
27
|
end
|
17
28
|
|
18
29
|
def initialize(node, parent)
|
@@ -5,6 +5,7 @@ module Qti
|
|
5
5
|
class ChoiceInteraction < BaseInteraction
|
6
6
|
# This will know if a class matches
|
7
7
|
def self.matches(node, parent)
|
8
|
+
return false unless maybe_choice_type(node)
|
8
9
|
matches = node.xpath('.//xmlns:response_lid')
|
9
10
|
return false if matches.count > 1 || matches.empty?
|
10
11
|
rcardinality = matches.first.attributes['rcardinality']&.value || 'Single'
|
@@ -12,6 +13,13 @@ module Qti
|
|
12
13
|
new(node, parent)
|
13
14
|
end
|
14
15
|
|
16
|
+
def self.maybe_choice_type(node)
|
17
|
+
question_type = self.question_type(node)
|
18
|
+
return true unless question_type
|
19
|
+
valid_types = %w[multiple_choice_question multiple_answers_question true_false_question]
|
20
|
+
valid_types.include?(question_type)
|
21
|
+
end
|
22
|
+
|
15
23
|
def answers
|
16
24
|
@answers ||= answer_nodes.map do |node|
|
17
25
|
V1::Models::Choices::LogicalIdentifierChoice.new(node, self)
|
@@ -27,7 +27,7 @@ module Qti
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def canvas_multiple_fib?
|
30
|
-
BaseInteraction.canvas_multiple_fib?(@node)
|
30
|
+
@canvas_multiple_fib ||= BaseInteraction.canvas_multiple_fib?(@node)
|
31
31
|
end
|
32
32
|
|
33
33
|
def stem_items
|
@@ -50,7 +50,7 @@ module Qti
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def single_fill_in_blank?
|
53
|
-
blanks.count == 1
|
53
|
+
!canvas_multiple_fib? && blanks.count == 1
|
54
54
|
end
|
55
55
|
|
56
56
|
def blanks
|
data/lib/qti/version.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
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
|
+
<item ident="i244ba14e56b64f3df2a0fc8becc49966" title="Question">
|
4
|
+
<itemmetadata>
|
5
|
+
<qtimetadata>
|
6
|
+
<qtimetadatafield>
|
7
|
+
<fieldlabel>question_type</fieldlabel>
|
8
|
+
<fieldentry>fill_in_multiple_blanks_question</fieldentry>
|
9
|
+
</qtimetadatafield>
|
10
|
+
<qtimetadatafield>
|
11
|
+
<fieldlabel>points_possible</fieldlabel>
|
12
|
+
<fieldentry>1.0</fieldentry>
|
13
|
+
</qtimetadatafield>
|
14
|
+
<qtimetadatafield>
|
15
|
+
<fieldlabel>assessment_question_identifierref</fieldlabel>
|
16
|
+
<fieldentry>i66da2dd13053deb08f20ed05ac1c74c8</fieldentry>
|
17
|
+
</qtimetadatafield>
|
18
|
+
</qtimetadata>
|
19
|
+
</itemmetadata>
|
20
|
+
<presentation>
|
21
|
+
<material>
|
22
|
+
<mattext texttype="text/html"><div><p>Bird, bird, bird, bird is the [word]</p></div></mattext>
|
23
|
+
</material>
|
24
|
+
<response_lid ident="response_word">
|
25
|
+
<material>
|
26
|
+
<mattext>word</mattext>
|
27
|
+
</material>
|
28
|
+
<render_choice>
|
29
|
+
<response_label ident="3537">
|
30
|
+
<material>
|
31
|
+
<mattext texttype="text/plain">word</mattext>
|
32
|
+
</material>
|
33
|
+
</response_label>
|
34
|
+
</render_choice>
|
35
|
+
</response_lid>
|
36
|
+
</presentation>
|
37
|
+
<resprocessing>
|
38
|
+
<outcomes>
|
39
|
+
<decvar maxvalue="100" minvalue="0" varname="SCORE" vartype="Decimal"/>
|
40
|
+
</outcomes>
|
41
|
+
<respcondition>
|
42
|
+
<conditionvar>
|
43
|
+
<varequal respident="response_word">3537</varequal>
|
44
|
+
</conditionvar>
|
45
|
+
<setvar varname="SCORE" action="Add">100.00</setvar>
|
46
|
+
</respcondition>
|
47
|
+
</resprocessing>
|
48
|
+
</item>
|
49
|
+
</questestinterop>
|
@@ -154,4 +154,63 @@ describe Qti::V1::Models::Interactions::FillBlankInteraction do
|
|
154
154
|
expect(subject.scoring_data_structs.first.case).to eq 'no'
|
155
155
|
end
|
156
156
|
end
|
157
|
+
|
158
|
+
context 'fib_str.xml' do
|
159
|
+
let(:file_path) { File.join(fixtures_path, 'fib_str.xml') }
|
160
|
+
let(:shuffle_value) { false }
|
161
|
+
let(:scoring_data_ids) { %w[FIB01 FIB02 FIB03] }
|
162
|
+
let(:scoring_data_values) { %w[Winter Summer York] }
|
163
|
+
let(:scoring_data_case) { %w[Yes Yes Yes] }
|
164
|
+
let(:answer_count) { 3 }
|
165
|
+
let(:expected_blanks) { [{ id: 'FIB01' }, { id: 'FIB02' }, { id: 'FIB03' }] }
|
166
|
+
let(:expected_stem_items) do
|
167
|
+
[
|
168
|
+
{ id: 'stem_0', position: 1, type: 'text', value: 'Fill-in-the blanks in this text from Richard III: ' },
|
169
|
+
{ id: 'stem_1', position: 2, type: 'text', value: 'Now is the ' },
|
170
|
+
{ id: 'stem_2', position: 3, type: 'blank', blank_id: 'FIB01' },
|
171
|
+
{ id: 'stem_3', position: 4, type: 'text', value: ' of our discontent made glorious ' },
|
172
|
+
{ id: 'stem_4', position: 5, type: 'blank', blank_id: 'FIB02' },
|
173
|
+
{ id: 'stem_5', position: 6, type: 'text', value: ' by these sons of ' },
|
174
|
+
{ id: 'stem_6', position: 7, type: 'blank', blank_id: 'FIB03' }
|
175
|
+
]
|
176
|
+
end
|
177
|
+
|
178
|
+
include_examples 'shuffled?'
|
179
|
+
include_examples 'answers'
|
180
|
+
include_examples 'scoring_data_structs'
|
181
|
+
include_examples 'blanks'
|
182
|
+
include_examples 'stem_items'
|
183
|
+
|
184
|
+
it 'returns false for #single_fill_in_blank?' do
|
185
|
+
expect(loaded_class.single_fill_in_blank?).to eq false
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'canvas multiple fill in the blank questions with a single blank' do
|
190
|
+
let(:file_path) { File.join(fixtures_path, 'canvas_multiple_fib_as_single.xml') }
|
191
|
+
let(:shuffle_value) { false }
|
192
|
+
let(:scoring_data_ids) { %w[3537] }
|
193
|
+
let(:scoring_data_values) { %w[word] }
|
194
|
+
let(:scoring_data_case) { %w[no] }
|
195
|
+
let(:answer_count) { 1 }
|
196
|
+
let(:expected_blanks) { [{ id: '3537' }] }
|
197
|
+
let(:expected_stem_items) do
|
198
|
+
[
|
199
|
+
{ id: 'stem_0', position: 1, type: 'text', value: '<div><p>Bird, bird, bird, bird is the ' },
|
200
|
+
{ id: 'stem_1', position: 2, type: 'blank', blank_id: 'response_word' },
|
201
|
+
{ id: 'stem_2', position: 3, type: 'text', value: '</p></div>' }
|
202
|
+
]
|
203
|
+
end
|
204
|
+
|
205
|
+
include_examples 'shuffled?'
|
206
|
+
include_examples 'answers'
|
207
|
+
include_examples 'scoring_data_structs'
|
208
|
+
include_examples 'blanks'
|
209
|
+
include_examples 'stem_items'
|
210
|
+
|
211
|
+
it 'returns false for #single_fill_in_blank?' do
|
212
|
+
puts "LOADED CLASS: #{loaded_class}"
|
213
|
+
expect(loaded_class.single_fill_in_blank?).to eq false
|
214
|
+
end
|
215
|
+
end
|
157
216
|
end
|
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: 1.0.
|
4
|
+
version: 1.0.8
|
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-
|
12
|
+
date: 2018-12-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -358,6 +358,7 @@ files:
|
|
358
358
|
- spec/fixtures/items_1.2/canvas_multiple_dropdown.xml
|
359
359
|
- spec/fixtures/items_1.2/canvas_multiple_dropdowns.xml
|
360
360
|
- spec/fixtures/items_1.2/canvas_multiple_fib.xml
|
361
|
+
- spec/fixtures/items_1.2/canvas_multiple_fib_as_single.xml
|
361
362
|
- spec/fixtures/items_1.2/choice.xml
|
362
363
|
- spec/fixtures/items_1.2/essay.xml
|
363
364
|
- spec/fixtures/items_1.2/fib.xml
|
@@ -691,6 +692,7 @@ test_files:
|
|
691
692
|
- spec/fixtures/items_1.2/canvas_multiple_dropdown.xml
|
692
693
|
- spec/fixtures/items_1.2/canvas_multiple_dropdowns.xml
|
693
694
|
- spec/fixtures/items_1.2/canvas_multiple_fib.xml
|
695
|
+
- spec/fixtures/items_1.2/canvas_multiple_fib_as_single.xml
|
694
696
|
- spec/fixtures/items_1.2/choice.xml
|
695
697
|
- spec/fixtures/items_1.2/essay.xml
|
696
698
|
- spec/fixtures/items_1.2/fib.xml
|