qti 2.22.0 → 2.22.2
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 +4 -4
- data/lib/qti/v1/models/interactions/choice_interaction.rb +8 -1
- data/lib/qti/v1/models/interactions/fill_blank_interaction.rb +3 -3
- data/lib/qti/v1/models/interactions/match_interaction.rb +8 -0
- data/lib/qti/version.rb +1 -1
- data/spec/fixtures/items_1.2/choice.xml +4 -0
- data/spec/fixtures/items_1.2/matching.xml +20 -0
- data/spec/fixtures/items_1.2/multiple_answer.xml +20 -0
- data/spec/fixtures/items_1.2/nq_multiple_fib_answer_types.xml +26 -3
- data/spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb +12 -0
- data/spec/lib/qti/v1/models/interactions/fill_blank_interaction_spec.rb +37 -8
- data/spec/lib/qti/v1/models/interactions/match_interaction_spec.rb +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 741703a8337d31961ab9ce07b394f6c9bb3484d2672f79f13a75ccd56234ad8e
|
4
|
+
data.tar.gz: 534f9d8da9a9e427cefb09765856fe7308e1d23c7710329358751cab3f48a713
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc88bd3ff406a0283589bcdb992506fe6994fa7cdae1a26422c3f24edd15a7c4a4041e6915c96d7e2a9cbc0a2ea8289e103df8baa2e2ccffe893b3ed9cbac7ee
|
7
|
+
data.tar.gz: 3a2cf6f3599f66f1e8ca178af12e1115d267bcccbdf1145401f127e923aa5d6bd35976885f892ff4f576de7291a366d7044bbc48d8b70f53b807f2a369f59275
|
@@ -44,6 +44,13 @@ module Qti
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
def scoring_algorithm
|
48
|
+
scoring_algorithm_path = './/xmlns:qtimetadatafield/xmlns:fieldlabel' \
|
49
|
+
'[text()="scoring_algorithm"]/../xmlns:fieldentry'
|
50
|
+
|
51
|
+
node.at_xpath(scoring_algorithm_path)&.text
|
52
|
+
end
|
53
|
+
|
47
54
|
private
|
48
55
|
|
49
56
|
def answer_nodes
|
@@ -72,8 +79,8 @@ module Qti
|
|
72
79
|
scoring_options: scoring_options)
|
73
80
|
end
|
74
81
|
end
|
75
|
-
# rubocop:enable Metrics/AbcSize
|
76
82
|
|
83
|
+
# rubocop:enable Metrics/AbcSize
|
77
84
|
def setvar_nodes(choice_nodes)
|
78
85
|
choice_nodes.select do |choice_node|
|
79
86
|
choice_node.at_xpath('.//xmlns:setvar')&.content&.to_f&.positive?
|
@@ -112,17 +112,17 @@ module Qti
|
|
112
112
|
def wordbank_choices
|
113
113
|
return unless wordbank_answer_present?
|
114
114
|
|
115
|
-
choices =
|
115
|
+
choices = Set.new
|
116
116
|
|
117
117
|
wordbank_answers = all_wordbank_answers.map do |node|
|
118
118
|
V1::Models::Choices::FillBlankChoice.new(node, self)
|
119
119
|
end
|
120
120
|
|
121
121
|
wordbank_answers.each do |wordbank_answer|
|
122
|
-
choices.
|
122
|
+
choices.add({ id: wordbank_answer.identifier, item_body: wordbank_answer.item_body })
|
123
123
|
end
|
124
124
|
|
125
|
-
choices
|
125
|
+
choices.to_a
|
126
126
|
end
|
127
127
|
|
128
128
|
def correct_answer_map
|
@@ -35,6 +35,13 @@ module Qti
|
|
35
35
|
all.reject { |v| correct.include? v }
|
36
36
|
end
|
37
37
|
|
38
|
+
def scoring_algorithm
|
39
|
+
scoring_algorithm_path = './/xmlns:qtimetadatafield/xmlns:fieldlabel' \
|
40
|
+
'[text()="scoring_algorithm"]/../xmlns:fieldentry'
|
41
|
+
|
42
|
+
node.at_xpath(scoring_algorithm_path)&.text
|
43
|
+
end
|
44
|
+
|
38
45
|
private
|
39
46
|
|
40
47
|
def parse_scoring_data
|
@@ -43,6 +50,7 @@ module Qti
|
|
43
50
|
matches = node.xpath(path).map do |node|
|
44
51
|
[node.attributes['respident'].value, answers_map[node.content]]
|
45
52
|
end
|
53
|
+
|
46
54
|
[Models::ScoringData.new(Hash[matches], rcardinality)]
|
47
55
|
end
|
48
56
|
|
data/lib/qti/version.rb
CHANGED
@@ -220,6 +220,10 @@
|
|
220
220
|
<fieldentry>i50a52b1e8b3e61e8e4f56b30182a3f6f</fieldentry>
|
221
221
|
</qtimetadatafield>
|
222
222
|
</qtimetadata>
|
223
|
+
<qtimetadatafield>
|
224
|
+
<fieldlabel>scoring_algorithm</fieldlabel>
|
225
|
+
<fieldentry>AllOrNothing</fieldentry>
|
226
|
+
</qtimetadatafield>
|
223
227
|
</itemmetadata>
|
224
228
|
<presentation>
|
225
229
|
<material>
|
@@ -70,5 +70,25 @@
|
|
70
70
|
<setvar varname="SCORE" action="Add">50.00</setvar>
|
71
71
|
</respcondition>
|
72
72
|
</resprocessing>
|
73
|
+
<itemmetadata>
|
74
|
+
<qtimetadata>
|
75
|
+
<qtimetadatafield>
|
76
|
+
<fieldlabel>question_type</fieldlabel>
|
77
|
+
<fieldentry>multiple_answers_question</fieldentry>
|
78
|
+
</qtimetadatafield>
|
79
|
+
<qtimetadatafield>
|
80
|
+
<fieldlabel>points_possible</fieldlabel>
|
81
|
+
<fieldentry>1.0</fieldentry>
|
82
|
+
</qtimetadatafield>
|
83
|
+
<qtimetadatafield>
|
84
|
+
<fieldlabel>assessment_question_identifierref</fieldlabel>
|
85
|
+
<fieldentry>i50a52b1e8b3e61e8e4f56b30182a3f6f</fieldentry>
|
86
|
+
</qtimetadatafield>
|
87
|
+
</qtimetadata>
|
88
|
+
<qtimetadatafield>
|
89
|
+
<fieldlabel>scoring_algorithm</fieldlabel>
|
90
|
+
<fieldentry>AllOrNothing</fieldentry>
|
91
|
+
</qtimetadatafield>
|
92
|
+
</itemmetadata>
|
73
93
|
</item>
|
74
94
|
</questestinterop>
|
@@ -94,6 +94,26 @@
|
|
94
94
|
<setvar varname="que_score" action="Add">25.00</setvar>
|
95
95
|
</respcondition>
|
96
96
|
</resprocessing>
|
97
|
+
<itemmetadata>
|
98
|
+
<qtimetadata>
|
99
|
+
<qtimetadatafield>
|
100
|
+
<fieldlabel>question_type</fieldlabel>
|
101
|
+
<fieldentry>multiple_answers_question</fieldentry>
|
102
|
+
</qtimetadatafield>
|
103
|
+
<qtimetadatafield>
|
104
|
+
<fieldlabel>points_possible</fieldlabel>
|
105
|
+
<fieldentry>1.0</fieldentry>
|
106
|
+
</qtimetadatafield>
|
107
|
+
<qtimetadatafield>
|
108
|
+
<fieldlabel>assessment_question_identifierref</fieldlabel>
|
109
|
+
<fieldentry>i50a52b1e8b3e61e8e4f56b30182a3f6f</fieldentry>
|
110
|
+
</qtimetadatafield>
|
111
|
+
</qtimetadata>
|
112
|
+
<qtimetadatafield>
|
113
|
+
<fieldlabel>scoring_algorithm</fieldlabel>
|
114
|
+
<fieldentry>AllOrNothing</fieldentry>
|
115
|
+
</qtimetadatafield>
|
116
|
+
</itemmetadata>
|
97
117
|
</item>
|
98
118
|
</section>
|
99
119
|
</assessment>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
</itemmetadata>
|
24
24
|
<presentation>
|
25
25
|
<material>
|
26
|
-
<mattext texttype="text/html"><p>Roses are [a20629ed-0c0b-4959-b565-a80c0f199602] and [ab37a945-ebad-4787-a356-
|
26
|
+
<mattext texttype="text/html"><p>Roses are [a20629ed-0c0b-4959-b565-a80c0f199602], [ab37a945-ebad-4787-a356-66c3c91efcc6], and [ab37a945-ebad-4787-a356-66c3c91efcc7].</p></mattext>
|
27
27
|
</material>
|
28
28
|
<response_lid ident="response_a20629ed-0c0b-4959-b565-a80c0f199602">
|
29
29
|
<material>
|
@@ -64,6 +64,23 @@
|
|
64
64
|
</response_label>
|
65
65
|
</render_choice>
|
66
66
|
</response_lid>
|
67
|
+
<response_lid ident="response_ab37a945-ebad-4787-a356-66c3c91efcc7">
|
68
|
+
<material>
|
69
|
+
<mattext>brown</mattext>
|
70
|
+
</material>
|
71
|
+
<render_choice>
|
72
|
+
<response_label ident="cd11d826-906d-4dc4-b78d-d66516eb94ce" scoring_algorithm='TextEquivalence' answer_type='wordbank' allow_reuse='true'>
|
73
|
+
<material>
|
74
|
+
<mattext texttype="text/plain">brown</mattext>
|
75
|
+
</material>
|
76
|
+
</response_label>
|
77
|
+
<response_label ident="bae0bd4f-2327-4a3e-b29f-199e1e279e91" scoring_algorithm='TextEquivalence' answer_type='wordbank' allow_reuse='true'>
|
78
|
+
<material>
|
79
|
+
<mattext texttype="text/plain">white</mattext>
|
80
|
+
</material>
|
81
|
+
</response_label>
|
82
|
+
</render_choice>
|
83
|
+
</response_lid>
|
67
84
|
</presentation>
|
68
85
|
<resprocessing>
|
69
86
|
<outcomes>
|
@@ -73,13 +90,19 @@
|
|
73
90
|
<conditionvar>
|
74
91
|
<varequal respident="response_a20629ed-0c0b-4959-b565-a80c0f199602">378646a8-b823-4e5b-beb8-19ca63f1f355</varequal>
|
75
92
|
</conditionvar>
|
76
|
-
<setvar action="Add" varname="SCORE">
|
93
|
+
<setvar action="Add" varname="SCORE">33.33</setvar>
|
77
94
|
</respcondition>
|
78
95
|
<respcondition>
|
79
96
|
<conditionvar>
|
80
97
|
<varequal respident="response_ab37a945-ebad-4787-a356-66c3c91efcc6">bae0bd4f-2327-4a3e-b29f-199e1e279e91</varequal>
|
81
98
|
</conditionvar>
|
82
|
-
<setvar action="Add" varname="SCORE">
|
99
|
+
<setvar action="Add" varname="SCORE">33.33</setvar>
|
100
|
+
</respcondition>
|
101
|
+
<respcondition>
|
102
|
+
<conditionvar>
|
103
|
+
<varequal respident="response_ab37a945-ebad-4787-a356-66c3c91efcc7">cd11d826-906d-4dc4-b78d-d66516eb94ce</varequal>
|
104
|
+
</conditionvar>
|
105
|
+
<setvar action="Add" varname="SCORE">33.33</setvar>
|
83
106
|
</respcondition>
|
84
107
|
</resprocessing>
|
85
108
|
</item>
|
@@ -41,6 +41,10 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
41
41
|
include_examples 'locked_choices'
|
42
42
|
include_examples 'answers'
|
43
43
|
include_examples 'meta_type'
|
44
|
+
|
45
|
+
it 'does not have any scoring algorithm' do
|
46
|
+
expect(loaded_class.scoring_algorithm).to eq nil
|
47
|
+
end
|
44
48
|
end
|
45
49
|
|
46
50
|
context 'true_false.xml' do
|
@@ -61,6 +65,10 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
61
65
|
let(:shuffle_value) { false }
|
62
66
|
let(:locked_choices_value) { [] }
|
63
67
|
|
68
|
+
it 'has the correct scoring algorithm' do
|
69
|
+
expect(loaded_class.scoring_algorithm).to eq 'AllOrNothing'
|
70
|
+
end
|
71
|
+
|
64
72
|
include_examples 'shuffled?'
|
65
73
|
include_examples 'locked_choices'
|
66
74
|
end
|
@@ -75,6 +83,10 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
75
83
|
include_examples 'shuffled?'
|
76
84
|
include_examples 'locked_choices'
|
77
85
|
include_examples 'meta_type'
|
86
|
+
|
87
|
+
it 'does not have any scoring algorithm' do
|
88
|
+
expect(loaded_class.scoring_algorithm).to eq nil
|
89
|
+
end
|
78
90
|
end
|
79
91
|
|
80
92
|
context 'multiple respconditions with empty setvars' do
|
@@ -319,20 +319,43 @@ describe Qti::V1::Models::Interactions::FillBlankInteraction do
|
|
319
319
|
c9400bfb-78ea-45b6-b5a5-e3311f6d5ed0
|
320
320
|
76350749-49ac-4094-966b-c4e1f12d54bc
|
321
321
|
cd11d826-906d-4dc4-b78d-d66516eb94ce
|
322
|
+
bae0bd4f-2327-4a3e-b29f-199e1e279e91
|
323
|
+
cd11d826-906d-4dc4-b78d-d66516eb94ce
|
322
324
|
bae0bd4f-2327-4a3e-b29f-199e1e279e91]
|
323
325
|
end
|
324
|
-
let(:scoring_data_values) { %w[black violet grey brown white] }
|
325
|
-
let(:scoring_data_case) { %w[no no no no no] }
|
326
|
-
let(:scoring_data_algorithm)
|
327
|
-
|
328
|
-
|
326
|
+
let(:scoring_data_values) { %w[black violet grey brown white brown white] }
|
327
|
+
let(:scoring_data_case) { %w[no no no no no no no] }
|
328
|
+
let(:scoring_data_algorithm) do
|
329
|
+
%w[
|
330
|
+
Equivalence
|
331
|
+
Equivalence
|
332
|
+
Equivalence
|
333
|
+
TextEquivalence
|
334
|
+
TextEquivalence
|
335
|
+
TextEquivalence
|
336
|
+
TextEquivalence
|
337
|
+
]
|
338
|
+
end
|
339
|
+
let(:scoring_data_answer_type) { %w[dropdown dropdown dropdown wordbank wordbank wordbank wordbank] }
|
340
|
+
let(:scoring_data_options) do
|
341
|
+
[
|
342
|
+
{},
|
343
|
+
{},
|
344
|
+
{},
|
345
|
+
{ 'allow_reuse' => 'true' },
|
346
|
+
{ 'allow_reuse' => 'true' },
|
347
|
+
{ 'allow_reuse' => 'true' },
|
348
|
+
{ 'allow_reuse' => 'true' }
|
349
|
+
]
|
350
|
+
end
|
329
351
|
let(:wordbank_choices) do
|
330
352
|
[{ id: 'cd11d826-906d-4dc4-b78d-d66516eb94ce', item_body: 'brown' },
|
331
353
|
{ id: 'bae0bd4f-2327-4a3e-b29f-199e1e279e91', item_body: 'white' }]
|
332
354
|
end
|
333
355
|
let(:correct_answer_map) do
|
334
356
|
{ 'response_a20629ed-0c0b-4959-b565-a80c0f199602' => '378646a8-b823-4e5b-beb8-19ca63f1f355',
|
335
|
-
'response_ab37a945-ebad-4787-a356-66c3c91efcc6' => 'bae0bd4f-2327-4a3e-b29f-199e1e279e91'
|
357
|
+
'response_ab37a945-ebad-4787-a356-66c3c91efcc6' => 'bae0bd4f-2327-4a3e-b29f-199e1e279e91',
|
358
|
+
'response_ab37a945-ebad-4787-a356-66c3c91efcc7' => 'cd11d826-906d-4dc4-b78d-d66516eb94ce' }
|
336
359
|
end
|
337
360
|
let(:expected_stem_items) do
|
338
361
|
[{ id: 'stem_0', position: 1, type: 'text', value: '<p>Roses are ' },
|
@@ -341,13 +364,19 @@ describe Qti::V1::Models::Interactions::FillBlankInteraction do
|
|
341
364
|
id: 'stem_1',
|
342
365
|
position: 2,
|
343
366
|
type: 'blank' },
|
344
|
-
{ id: 'stem_2', position: 3, type: 'text', value: '
|
367
|
+
{ id: 'stem_2', position: 3, type: 'text', value: ', ' },
|
345
368
|
{ blank_id: 'response_ab37a945-ebad-4787-a356-66c3c91efcc6',
|
346
369
|
blank_name: 'white',
|
347
370
|
id: 'stem_3',
|
348
371
|
position: 4,
|
349
372
|
type: 'blank' },
|
350
|
-
{ id: 'stem_4', position: 5, type: 'text', value: '
|
373
|
+
{ id: 'stem_4', position: 5, type: 'text', value: ', and ' },
|
374
|
+
{ blank_id: 'response_ab37a945-ebad-4787-a356-66c3c91efcc7',
|
375
|
+
blank_name: 'brown',
|
376
|
+
id: 'stem_5',
|
377
|
+
position: 6,
|
378
|
+
type: 'blank' },
|
379
|
+
{ id: 'stem_6', position: 7, type: 'text', value: '.</p>' }]
|
351
380
|
end
|
352
381
|
|
353
382
|
include_examples 'scoring_data_structs'
|
@@ -59,6 +59,10 @@ describe Qti::V1::Models::Interactions::MatchInteraction do
|
|
59
59
|
end
|
60
60
|
let(:expected_distractors) { ['A distractor answer.'] }
|
61
61
|
|
62
|
+
it 'has the correct scoring algorithm' do
|
63
|
+
expect(subject.scoring_algorithm).to eq 'AllOrNothing'
|
64
|
+
end
|
65
|
+
|
62
66
|
include_examples('common features')
|
63
67
|
include_examples('questions and answers')
|
64
68
|
include_examples('#scoring_data_structs')
|
@@ -88,5 +92,9 @@ describe Qti::V1::Models::Interactions::MatchInteraction do
|
|
88
92
|
include_examples('common features')
|
89
93
|
include_examples('questions and answers')
|
90
94
|
include_examples('#scoring_data_structs')
|
95
|
+
|
96
|
+
it 'does not have any scoring algorithm' do
|
97
|
+
expect(subject.scoring_algorithm).to eq nil
|
98
|
+
end
|
91
99
|
end
|
92
100
|
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: 2.22.
|
4
|
+
version: 2.22.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Diaz
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2023-08-
|
15
|
+
date: 2023-08-31 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: actionview
|