qti 2.22.0 → 2.22.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69db54c55235becbc279f304dfb4627e3edb22a7467ab9ce311bab29b97ab09d
4
- data.tar.gz: 762bbfa69e290cff6ba71f5c1a3202594537b5c8a8cac09e7549def491fa258a
3
+ metadata.gz: 741703a8337d31961ab9ce07b394f6c9bb3484d2672f79f13a75ccd56234ad8e
4
+ data.tar.gz: 534f9d8da9a9e427cefb09765856fe7308e1d23c7710329358751cab3f48a713
5
5
  SHA512:
6
- metadata.gz: 1eba7a1b6f972af2eb7698cb0dd025931f2dfff52965922b01fd0d9987b5a7cb6900978dbb22830cd6928ff98ce893c362aee94bcd8218987328bf7691dabb73
7
- data.tar.gz: bac1972140ef8df38a1a1b521d6b729911fa2a7daa7ae7cd9cc762e2f927667296fc0b563dc210bc46c578f4bc2b791137155829d39216952e0cab8f1b8366fe
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.push({ id: wordbank_answer.identifier, item_body: wordbank_answer.item_body })
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
@@ -1,3 +1,3 @@
1
1
  module Qti
2
- VERSION = '2.22.0'.freeze
2
+ VERSION = '2.22.2'.freeze
3
3
  end
@@ -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">&lt;p&gt;Roses are [a20629ed-0c0b-4959-b565-a80c0f199602] and [ab37a945-ebad-4787-a356-66c3c91efcc6].&lt;/p&gt;</mattext>
26
+ <mattext texttype="text/html">&lt;p&gt;Roses are [a20629ed-0c0b-4959-b565-a80c0f199602], [ab37a945-ebad-4787-a356-66c3c91efcc6], and [ab37a945-ebad-4787-a356-66c3c91efcc7].&lt;/p&gt;</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">50.00</setvar>
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">50.00</setvar>
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) { %w[Equivalence Equivalence Equivalence TextEquivalence TextEquivalence] }
327
- let(:scoring_data_answer_type) { %w[dropdown dropdown dropdown wordbank wordbank] }
328
- let(:scoring_data_options) { [{}, {}, {}, { 'allow_reuse' => 'true' }, { 'allow_reuse' => 'true' }] }
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: ' and ' },
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: '.</p>' }]
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.0
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 00:00:00.000000000 Z
15
+ date: 2023-08-31 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: actionview