qti 2.17.0 → 2.18.1
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/assessment_item.rb +21 -0
- data/lib/qti/v1/models/interactions/base_interaction.rb +10 -0
- data/lib/qti/version.rb +1 -1
- data/spec/fixtures/items_1.2/true_false.xml +1 -1
- data/spec/fixtures/items_1.2/true_false_with_calculator.xml +90 -0
- data/spec/lib/qti/v1/models/assessment_item_spec.rb +20 -0
- data/spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb +14 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 336700103b4d3c146a3a14e388d0cc03b568aa7561401ffabede5cab0881559d
|
4
|
+
data.tar.gz: 29a3213732a5377ba14d133c06a5e545c3f16c25e1e19200d9f4dd98e1b98792
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e31d581b78da6e468e3a8c5d188310585981b42c2a581f66d9938861c2fcdc701f86d8cbc99c13f3eaf6977e191237deb9904d50bd83159e6b780ffd89005846
|
7
|
+
data.tar.gz: 3ad4b4496777d9df2ef092ae2a9c9cbd7d19808c4939bbfdd63fdc1710faa85aeee2296c2209c8642fd15d9bf9ae417f5618f4858e13e4296075aaac65631c35
|
@@ -84,6 +84,27 @@ module Qti
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
def calculator_type
|
88
|
+
@calculator_type ||= begin
|
89
|
+
if calculator_type_metadata?
|
90
|
+
calculator_type_metadata_label = qti_metadata_children.children.find do |node|
|
91
|
+
node.text == 'calculator_type'
|
92
|
+
end
|
93
|
+
calculator_type_metadata_label.next.text
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def calculator_type_metadata?
|
99
|
+
if @doc.at_xpath('.//xmlns:qtimetadata').present?
|
100
|
+
qti_metadata_children.children.find do |node|
|
101
|
+
node.text == 'calculator_type'
|
102
|
+
end.present?
|
103
|
+
else
|
104
|
+
false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
87
108
|
def decvar_maxvalue
|
88
109
|
@doc.at_xpath('.//xmlns:decvar/@maxvalue')&.value&.to_i ||
|
89
110
|
@doc.at_xpath('.//xmlns:decvar/@defaultval')&.value&.to_i || 0
|
@@ -40,6 +40,16 @@ module Qti
|
|
40
40
|
@node.at_xpath('.//xmlns:render_choice/@shuffle')&.value.try(:downcase) == 'yes'
|
41
41
|
end
|
42
42
|
|
43
|
+
def locked_choices
|
44
|
+
return [] unless shuffled?
|
45
|
+
|
46
|
+
@node.xpath('.//xmlns:response_label').filter_map.with_index do |answer_node, index|
|
47
|
+
is_locked = answer_node.attributes['lock']&.value&.downcase == 'yes'
|
48
|
+
|
49
|
+
is_locked ? index : nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
43
53
|
def scoring_data_structs
|
44
54
|
raise NotImplementedError
|
45
55
|
end
|
data/lib/qti/version.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
</material>
|
22
22
|
<response_lid ident="QUE_1004_RL" rcardinality="Single" rtiming="No">
|
23
23
|
<render_choice shuffle="Yes">
|
24
|
-
<response_label ident="QUE_1005_A1">
|
24
|
+
<response_label ident="QUE_1005_A1" lock="Yes">
|
25
25
|
<material>
|
26
26
|
<mattext texttype="text/html"><![CDATA[True]]></mattext>
|
27
27
|
</material>
|
@@ -0,0 +1,90 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
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 title="1.2 Import Quiz" ident="A1001">
|
4
|
+
<section title="Main" ident="S1002">
|
5
|
+
<item title="Grading - specific - 3 pt score" ident="QUE_1003">
|
6
|
+
<itemmetadata>
|
7
|
+
<qtimetadata>
|
8
|
+
<qtimetadatafield>
|
9
|
+
<fieldlabel>question_type</fieldlabel>
|
10
|
+
<fieldentry>true_false_question</fieldentry>
|
11
|
+
</qtimetadatafield>
|
12
|
+
<qtimetadatafield>
|
13
|
+
<fieldlabel>assessment_question_identifierref</fieldlabel>
|
14
|
+
<fieldentry>iff205c7405d3b36bdca9b75b51198932</fieldentry>
|
15
|
+
</qtimetadatafield>
|
16
|
+
<qtimetadatafield>
|
17
|
+
<fieldlabel>calculator_type</fieldlabel>
|
18
|
+
<fieldentry>basic</fieldentry>
|
19
|
+
</qtimetadatafield>
|
20
|
+
</qtimetadata>
|
21
|
+
</itemmetadata>
|
22
|
+
<presentation>
|
23
|
+
<material>
|
24
|
+
<mattext texttype="text/html"><![CDATA[If I get a 3, I must have done something wrong. <img data-equation-content="sample equation" script="alert('bad')" align="bottom" alt="image.png" src="org0/images/image.png" border="0"/> <img script="alert('bad')" align="bottom" alt="image.png" src="org0/images/image.png" border="0"/>]]></mattext>
|
25
|
+
</material>
|
26
|
+
<response_lid ident="QUE_1004_RL" rcardinality="Single" rtiming="No">
|
27
|
+
<render_choice shuffle="Yes">
|
28
|
+
<response_label ident="QUE_1005_A1">
|
29
|
+
<material>
|
30
|
+
<mattext texttype="text/html"><![CDATA[True]]></mattext>
|
31
|
+
</material>
|
32
|
+
</response_label>
|
33
|
+
<response_label ident="QUE_1006_A2">
|
34
|
+
<material>
|
35
|
+
<mattext texttype="text/html"><![CDATA[False]]></mattext>
|
36
|
+
</material>
|
37
|
+
</response_label>
|
38
|
+
</render_choice>
|
39
|
+
</response_lid>
|
40
|
+
</presentation>
|
41
|
+
<resprocessing>
|
42
|
+
<outcomes>
|
43
|
+
<decvar vartype="Decimal" defaultval="0" varname="que_score"/>
|
44
|
+
</outcomes>
|
45
|
+
<respcondition>
|
46
|
+
<conditionvar>
|
47
|
+
<varequal respident="QUE_1004_RL">QUE_1005_A1</varequal>
|
48
|
+
</conditionvar>
|
49
|
+
<setvar varname="que_score" action="Add">0</setvar>
|
50
|
+
</respcondition>
|
51
|
+
<respcondition>
|
52
|
+
<conditionvar>
|
53
|
+
<varequal respident="QUE_1004_RL">QUE_1006_A2</varequal>
|
54
|
+
</conditionvar>
|
55
|
+
<setvar varname="que_score" action="Set">10.00</setvar>
|
56
|
+
<displayfeedback feedbacktype="Response" linkrefid="fb_QUE_1006_A2"/>
|
57
|
+
</respcondition>
|
58
|
+
</resprocessing>
|
59
|
+
<itemfeedback ident="general_fb">
|
60
|
+
<flow_mat>
|
61
|
+
<material>
|
62
|
+
<mattext texttype="text/html"><p>Neutral</p><img script="alert('bad')" alt="image.png" src="org0/images/image.png"/></mattext>
|
63
|
+
</material>
|
64
|
+
</flow_mat>
|
65
|
+
</itemfeedback>
|
66
|
+
<itemfeedback ident="correct_fb">
|
67
|
+
<flow_mat>
|
68
|
+
<material>
|
69
|
+
<mattext texttype="text/html"><p>Correct</p><img script="alert('bad')" alt="image.png" src="org0/images/image.png"/></mattext>
|
70
|
+
</material>
|
71
|
+
</flow_mat>
|
72
|
+
</itemfeedback>
|
73
|
+
<itemfeedback ident="general_incorrect_fb">
|
74
|
+
<flow_mat>
|
75
|
+
<material>
|
76
|
+
<mattext texttype="text/html"><p>Incorrect</p><img script="alert('bad')" alt="image.png" src="org0/images/image.png"/></mattext>
|
77
|
+
</material>
|
78
|
+
</flow_mat>
|
79
|
+
</itemfeedback>
|
80
|
+
<itemfeedback ident="fb_QUE_1006_A2">
|
81
|
+
<flow_mat>
|
82
|
+
<material>
|
83
|
+
<mattext texttype="text/html"><p>Answer was Correct</p><img script="alert('bad')" alt="image.png" src="org0/images/image.png"/></mattext>
|
84
|
+
</material>
|
85
|
+
</flow_mat>
|
86
|
+
</itemfeedback>
|
87
|
+
</item>
|
88
|
+
</section>
|
89
|
+
</assessment>
|
90
|
+
</questestinterop>
|
@@ -115,6 +115,26 @@ describe Qti::V1::Models::AssessmentItem do
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
describe '#calculator_type' do
|
119
|
+
let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
|
120
|
+
let(:assessment_item_refs) { test_object.assessment_items }
|
121
|
+
let(:loaded_class) { described_class.new(assessment_item_refs) }
|
122
|
+
|
123
|
+
context 'when it does not contain calculator_type metadata' do
|
124
|
+
let(:file_path) { File.join('spec', 'fixtures', 'items_1.2', 'true_false.xml') }
|
125
|
+
it 'returns nil' do
|
126
|
+
expect(loaded_class.calculator_type).to be_nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when it contains calculator_type metadata' do
|
131
|
+
let(:file_path) { File.join('spec', 'fixtures', 'items_1.2', 'true_false_with_calculator.xml') }
|
132
|
+
it 'returns the calculator_type value' do
|
133
|
+
expect(loaded_class.calculator_type).to eq 'basic'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
118
138
|
describe '#scoring_data_structs' do
|
119
139
|
it 'grabs the rcardinality and scoring data value' do
|
120
140
|
struct = loaded_class.send(:scoring_data_structs)
|
@@ -10,6 +10,12 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
shared_examples_for 'locked_choices' do
|
14
|
+
it 'returns locked choices setting' do
|
15
|
+
expect(loaded_class.locked_choices).to eq locked_choices_value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
13
19
|
shared_examples_for 'answers' do
|
14
20
|
it 'returns the answers' do
|
15
21
|
expect(loaded_class.answers.count).to eq answer_choices_count
|
@@ -27,10 +33,12 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
27
33
|
context 'multiple_choice.xml' do
|
28
34
|
let(:file_path) { File.join(fixtures_path, 'multiple_choice.xml') }
|
29
35
|
let(:shuffle_value) { false }
|
36
|
+
let(:locked_choices_value) { [] }
|
30
37
|
let(:answer_choices_count) { 5 }
|
31
38
|
let(:meta_type) { nil }
|
32
39
|
|
33
40
|
include_examples 'shuffled?'
|
41
|
+
include_examples 'locked_choices'
|
34
42
|
include_examples 'answers'
|
35
43
|
include_examples 'meta_type'
|
36
44
|
end
|
@@ -38,10 +46,12 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
38
46
|
context 'true_false.xml' do
|
39
47
|
let(:file_path) { File.join(fixtures_path, 'true_false.xml') }
|
40
48
|
let(:shuffle_value) { true }
|
49
|
+
let(:locked_choices_value) { [0] }
|
41
50
|
let(:answer_choices_count) { 2 }
|
42
51
|
let(:meta_type) { 'true_false_question' }
|
43
52
|
|
44
53
|
include_examples 'shuffled?'
|
54
|
+
include_examples 'locked_choices'
|
45
55
|
include_examples 'answers'
|
46
56
|
include_examples 'meta_type'
|
47
57
|
end
|
@@ -49,17 +59,21 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
49
59
|
context 'multiple_answer.xml' do
|
50
60
|
let(:file_path) { File.join(fixtures_path, 'multiple_answer.xml') }
|
51
61
|
let(:shuffle_value) { false }
|
62
|
+
let(:locked_choices_value) { [] }
|
52
63
|
|
53
64
|
include_examples 'shuffled?'
|
65
|
+
include_examples 'locked_choices'
|
54
66
|
end
|
55
67
|
|
56
68
|
context 'multiple_answer_canvas.xml' do
|
57
69
|
let(:file_path) { File.join(fixtures_path, 'multiple_answer_canvas.xml') }
|
58
70
|
let(:shuffle_value) { false }
|
71
|
+
let(:locked_choices_value) { [] }
|
59
72
|
let(:answer_choices_count) { 4 }
|
60
73
|
let(:meta_type) { 'multiple_answers_question' }
|
61
74
|
|
62
75
|
include_examples 'shuffled?'
|
76
|
+
include_examples 'locked_choices'
|
63
77
|
include_examples 'meta_type'
|
64
78
|
end
|
65
79
|
|
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.
|
4
|
+
version: 2.18.1
|
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-07-
|
15
|
+
date: 2023-07-21 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: actionview
|
@@ -428,6 +428,7 @@ files:
|
|
428
428
|
- spec/fixtures/items_1.2/stimulus_with_child_item.xml
|
429
429
|
- spec/fixtures/items_1.2/text.no.question.xml
|
430
430
|
- spec/fixtures/items_1.2/true_false.xml
|
431
|
+
- spec/fixtures/items_1.2/true_false_with_calculator.xml
|
431
432
|
- spec/fixtures/items_1.2/upload.xml
|
432
433
|
- spec/fixtures/items_2.1/Example02-feedbackInline.xml
|
433
434
|
- spec/fixtures/items_2.1/categorization.xml
|
@@ -795,6 +796,7 @@ test_files:
|
|
795
796
|
- spec/fixtures/items_1.2/stimulus_with_child_item.xml
|
796
797
|
- spec/fixtures/items_1.2/text.no.question.xml
|
797
798
|
- spec/fixtures/items_1.2/true_false.xml
|
799
|
+
- spec/fixtures/items_1.2/true_false_with_calculator.xml
|
798
800
|
- spec/fixtures/items_1.2/upload.xml
|
799
801
|
- spec/fixtures/items_2.1/Example02-feedbackInline.xml
|
800
802
|
- spec/fixtures/items_2.1/categorization.xml
|