qti 0.9.14 → 0.9.15
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.rb +1 -0
- data/lib/qti/v1/models/assessment.rb +17 -4
- data/lib/qti/v1/models/assessment_item.rb +4 -0
- data/lib/qti/v1/models/base.rb +2 -1
- data/lib/qti/v1/models/interactions/base_interaction.rb +36 -0
- data/lib/qti/v1/models/interactions/choice_interaction.rb +9 -0
- data/lib/qti/v1/models/interactions/fill_blank_interaction.rb +1 -1
- data/lib/qti/v1/models/interactions/match_interaction.rb +3 -1
- data/lib/qti/v1/models/interactions/numeric_interaction.rb +1 -1
- data/lib/qti/v1/models/interactions/string_interaction.rb +3 -2
- data/lib/qti/v1/models/stimulus_item.rb +33 -0
- data/lib/qti/v2/models/assessment_item.rb +4 -0
- data/lib/qti/v2/models/interactions/base_interaction.rb +2 -0
- data/lib/qti/version.rb +1 -1
- data/spec/fixtures/all_canvas_simple_1.2.xml +1676 -0
- data/spec/fixtures/feedback_quiz_1.2.xml +246 -0
- data/spec/fixtures/items_1.2/matching_feedback.xml +370 -0
- data/spec/fixtures/items_1.2/text.no.question.xml +36 -0
- data/spec/lib/qti/v1/models/assessment_item_spec.rb +11 -0
- data/spec/lib/qti/v1/models/assessment_spec.rb +187 -13
- data/spec/lib/qti/v1/models/interactions/base_interaction_spec.rb +56 -0
- data/spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb +12 -0
- data/spec/lib/qti/v1/models/interactions/match_interaction_spec.rb +67 -23
- data/spec/lib/qti/v1/models/stimulus_item_spec.rb +55 -0
- metadata +14 -7
- data/spec/gemfiles/nokogiri-1.6.gemfile.lock +0 -149
- data/spec/gemfiles/nokogiri-1.8.gemfile.lock +0 -149
@@ -0,0 +1,36 @@
|
|
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="i1e5e0d6fba7342e63ae43afe9863070d" title="Quiz.text">
|
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="i5dae6b32741a0962b55c06c35e49ffb8" title="Question1">
|
12
|
+
<itemmetadata>
|
13
|
+
<qtimetadata>
|
14
|
+
<qtimetadatafield>
|
15
|
+
<fieldlabel>question_type</fieldlabel>
|
16
|
+
<fieldentry>text_only_question</fieldentry>
|
17
|
+
</qtimetadatafield>
|
18
|
+
<qtimetadatafield>
|
19
|
+
<fieldlabel>points_possible</fieldlabel>
|
20
|
+
<fieldentry>0</fieldentry>
|
21
|
+
</qtimetadatafield>
|
22
|
+
<qtimetadatafield>
|
23
|
+
<fieldlabel>assessment_question_identifierref</fieldlabel>
|
24
|
+
<fieldentry>if47b767d37e06559ff801f2d253307ba</fieldentry>
|
25
|
+
</qtimetadatafield>
|
26
|
+
</qtimetadata>
|
27
|
+
</itemmetadata>
|
28
|
+
<presentation>
|
29
|
+
<material>
|
30
|
+
<mattext texttype="text/html"><div><p>asfdfas asdvadsfsdav a . aasvdafa</p></div></mattext>
|
31
|
+
</material>
|
32
|
+
</presentation>
|
33
|
+
</item>
|
34
|
+
</section>
|
35
|
+
</assessment>
|
36
|
+
</questestinterop>
|
@@ -1,6 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Qti::V1::Models::AssessmentItem do
|
4
|
+
context 'multiple_fib' do
|
5
|
+
let(:file_path) { File.join('spec', 'fixtures', 'items_1.2', 'single_fib.xml') }
|
6
|
+
let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
|
7
|
+
let(:assessment_item_refs) { test_object.assessment_items }
|
8
|
+
let(:loaded_class) { described_class.new(assessment_item_refs) }
|
9
|
+
|
10
|
+
it 'has sanitized item_body' do
|
11
|
+
expect(loaded_class.item_body).to include '<div'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
context 'quiz.xml' do
|
5
16
|
let(:file_path) { File.join('spec', 'fixtures', 'items_1.2', 'true_false.xml') }
|
6
17
|
let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
|
@@ -1,22 +1,174 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
fixtures_path = File.join('spec', 'fixtures')
|
4
|
-
|
5
3
|
describe Qti::V1::Models::Assessment do
|
6
|
-
|
7
|
-
|
4
|
+
describe 'interaction item' do
|
5
|
+
let(:fixtures_path) { File.join('spec', 'fixtures') }
|
6
|
+
shared_examples_for 'basic quiz fields' do
|
7
|
+
it 'loads an AssessmentXML file' do
|
8
|
+
expect do
|
9
|
+
described_class.from_path!(path)
|
10
|
+
end.to_not raise_error
|
11
|
+
end
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
describe '#title' do
|
14
|
+
context '<assessmentTest> has a title property' do
|
15
|
+
it 'has the title' do
|
16
|
+
expect(loaded_class.title).to eq(expected_title)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'it has the correct number of items' do
|
21
|
+
expect(loaded_class.assessment_items.count).to eq(expected_item_count)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
shared_examples_for 'verify quiz items' do
|
27
|
+
it 'has the correct item data' do
|
28
|
+
loaded_class.assessment_items.zip(expected_item_data).each do |node, cmp|
|
29
|
+
item = Qti::V1::Models::AssessmentItem.new(node)
|
30
|
+
expect(item.interaction_model.class).to eq(cmp[:interaction_class])
|
31
|
+
expect(item.title).to eq(cmp[:title])
|
32
|
+
expect(item.feedback).to eq(cmp[:feedback])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'reference qti 1.2 quiz' do
|
38
|
+
let(:path) { File.join(fixtures_path, 'test_qti_1.2', 'quiz.xml') }
|
39
|
+
let(:loaded_class) { described_class.from_path!(path) }
|
40
|
+
let(:expected_title) { '1.2 Import Quiz' }
|
41
|
+
let(:expected_item_count) { 5 }
|
42
|
+
|
43
|
+
include_examples('basic quiz fields')
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'quiz with feedback samples' do
|
47
|
+
let(:path) { File.join(fixtures_path, 'feedback_quiz_1.2.xml') }
|
48
|
+
let(:loaded_class) { described_class.from_path!(path) }
|
49
|
+
let(:expected_title) { 'I Can Haz Feedback' }
|
50
|
+
let(:expected_item_count) { 3 }
|
51
|
+
let(:expected_item_data) do
|
52
|
+
[
|
53
|
+
{
|
54
|
+
interaction_class: Qti::V1::Models::Interactions::StringInteraction,
|
55
|
+
title: 'Question',
|
56
|
+
feedback: { neutral: '<p>General Feedback</p>' }
|
57
|
+
},
|
58
|
+
{
|
59
|
+
interaction_class: Qti::V1::Models::Interactions::ChoiceInteraction,
|
60
|
+
title: 'Question',
|
61
|
+
feedback: { neutral: '<p>Neutral</p>', correct: '<p>Correct</p>', incorrect: '<p>Incorrect</p>' }
|
62
|
+
},
|
63
|
+
{
|
64
|
+
interaction_class: Qti::V1::Models::Interactions::ChoiceInteraction,
|
65
|
+
title: 'Question',
|
66
|
+
feedback: {}
|
67
|
+
}
|
68
|
+
]
|
69
|
+
end
|
14
70
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
71
|
+
include_examples('basic quiz fields')
|
72
|
+
include_examples('verify quiz items')
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'reference qti 1.2 quiz' do
|
76
|
+
let(:path) { File.join(fixtures_path, 'all_canvas_simple_1.2.xml') }
|
77
|
+
let(:loaded_class) { described_class.from_path!(path) }
|
78
|
+
let(:expected_title) { 'Every Canvas Interaction' }
|
79
|
+
let(:expected_item_count) { 10 }
|
80
|
+
let(:expected_item_data) do
|
81
|
+
[
|
82
|
+
{
|
83
|
+
interaction_class: Qti::V1::Models::Interactions::ChoiceInteraction,
|
84
|
+
title: 'Question 1',
|
85
|
+
feedback: {
|
86
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
87
|
+
correct: '<p>Item Feedback, Correct</p>',
|
88
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
89
|
+
}
|
90
|
+
},
|
91
|
+
{
|
92
|
+
interaction_class: Qti::V1::Models::Interactions::ChoiceInteraction,
|
93
|
+
title: 'Question 2',
|
94
|
+
feedback: {
|
95
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
96
|
+
correct: '<p>Item Feedback, Correct</p>',
|
97
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
98
|
+
}
|
99
|
+
},
|
100
|
+
{
|
101
|
+
interaction_class: Qti::V1::Models::Interactions::FillBlankInteraction,
|
102
|
+
title: 'Question 3',
|
103
|
+
feedback: {
|
104
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
105
|
+
correct: '<p>Item Feedback, Correct</p>',
|
106
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
107
|
+
}
|
108
|
+
},
|
109
|
+
{
|
110
|
+
interaction_class: Qti::V1::Models::Interactions::FillBlankInteraction,
|
111
|
+
title: 'Question 4',
|
112
|
+
feedback: {
|
113
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
114
|
+
correct: '<p>Item Feedback, Correct</p>',
|
115
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
116
|
+
}
|
117
|
+
},
|
118
|
+
{
|
119
|
+
interaction_class: Qti::V1::Models::Interactions::ChoiceInteraction,
|
120
|
+
title: 'Question 5',
|
121
|
+
feedback: {
|
122
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
123
|
+
correct: '<p>Item Feedback, Correct</p>',
|
124
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
125
|
+
}
|
126
|
+
},
|
127
|
+
{
|
128
|
+
interaction_class: Qti::V1::Models::Interactions::CanvasMultipleDropdownInteraction,
|
129
|
+
title: 'Question 6',
|
130
|
+
feedback: {
|
131
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
132
|
+
correct: '<p>Item Feedback, Correct</p>',
|
133
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
134
|
+
}
|
135
|
+
},
|
136
|
+
{
|
137
|
+
interaction_class: Qti::V1::Models::Interactions::MatchInteraction,
|
138
|
+
title: 'Question 7',
|
139
|
+
feedback: {
|
140
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
141
|
+
correct: '<p>Item Feedback, Correct</p>',
|
142
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
143
|
+
}
|
144
|
+
},
|
145
|
+
{
|
146
|
+
interaction_class: Qti::V1::Models::Interactions::NumericInteraction,
|
147
|
+
title: 'Question 8',
|
148
|
+
feedback: {
|
149
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
150
|
+
correct: '<p>Item Feedback, Correct</p>',
|
151
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
152
|
+
}
|
153
|
+
},
|
154
|
+
{
|
155
|
+
interaction_class: Qti::V1::Models::Interactions::FormulaInteraction,
|
156
|
+
title: 'Question 9',
|
157
|
+
feedback: {
|
158
|
+
neutral: '<p>Item Feedback, Neutral</p>',
|
159
|
+
correct: '<p>Item Feedback, Correct</p>',
|
160
|
+
incorrect: '<p>Item Feedback, Incorrect</p>'
|
161
|
+
}
|
162
|
+
},
|
163
|
+
{
|
164
|
+
interaction_class: Qti::V1::Models::Interactions::StringInteraction,
|
165
|
+
title: 'Question 10',
|
166
|
+
feedback: { neutral: '<p>Item Feedback, Neutral</p>' }
|
167
|
+
}
|
168
|
+
]
|
19
169
|
end
|
170
|
+
include_examples('basic quiz fields')
|
171
|
+
include_examples('verify quiz items')
|
20
172
|
end
|
21
173
|
|
22
174
|
context '<assessmentTest> has no title property' do
|
@@ -34,4 +186,26 @@ describe Qti::V1::Models::Assessment do
|
|
34
186
|
end
|
35
187
|
end
|
36
188
|
end
|
189
|
+
|
190
|
+
describe 'stimulus (text-no-question) item' do
|
191
|
+
let(:fixtures_path) { File.join('spec', 'fixtures', 'items_1.2') }
|
192
|
+
let(:test_object) { described_class.from_path!(file_path) }
|
193
|
+
let(:assessment_item_refs) { test_object.assessment_items }
|
194
|
+
let(:assessment_item_ref) { assessment_item_refs.first }
|
195
|
+
let(:file_path) { File.join(fixtures_path, 'text.no.question.xml') }
|
196
|
+
|
197
|
+
it 'methods behave as expected' do
|
198
|
+
expect(
|
199
|
+
test_object.create_assessment_item(assessment_item_ref)
|
200
|
+
).to eq(nil)
|
201
|
+
|
202
|
+
expect(
|
203
|
+
test_object.stimulus_ref(assessment_item_ref)
|
204
|
+
).to eq(assessment_item_ref)
|
205
|
+
|
206
|
+
expect(
|
207
|
+
test_object.create_stimulus(assessment_item_ref).class
|
208
|
+
).to be(Qti::V1::Models::StimulusItem)
|
209
|
+
end
|
210
|
+
end
|
37
211
|
end
|
@@ -18,4 +18,60 @@ describe Qti::V1::Models::Interactions::BaseInteraction do
|
|
18
18
|
interaction = described_class.new(node, assessment)
|
19
19
|
expect(interaction.rcardinality).to eq 'Single'
|
20
20
|
end
|
21
|
+
|
22
|
+
let(:fixtures_path) { File.join('spec', 'fixtures', 'items_1.2') }
|
23
|
+
let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
|
24
|
+
let(:assessment_item_refs) { test_object.assessment_items }
|
25
|
+
let(:loaded_class) { described_class.new(assessment_item_refs.first, test_object) }
|
26
|
+
|
27
|
+
shared_examples_for 'item_level_feedback' do
|
28
|
+
it 'returns the correct item-level feedback' do
|
29
|
+
expect(loaded_class.canvas_item_feedback[:neutral]).to eq(general_fb)
|
30
|
+
expect(loaded_class.canvas_item_feedback[:correct]).to eq(correct_fb)
|
31
|
+
expect(loaded_class.canvas_item_feedback[:incorrect]).to eq(incorrect_fb)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
shared_examples_for 'answer_feedback' do
|
36
|
+
it 'returns the correct answer feedback' do
|
37
|
+
expect(loaded_class.answer_feedback).to eq(answer_fb)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'canvas_multiple_dropdown.xml' do
|
42
|
+
let(:file_path) { File.join(fixtures_path, 'canvas_multiple_dropdown.xml') }
|
43
|
+
let(:general_fb) do
|
44
|
+
"<p>Roses come in many colors, violets probably do too.</p>\n<p>Never the less, " \
|
45
|
+
'the correct answers were <strong>red</strong> and <strong>blue</strong>.</p>'
|
46
|
+
end
|
47
|
+
let(:correct_fb) { '<p>Completing the poem, is left to you.</p>' }
|
48
|
+
let(:incorrect_fb) { '<p>Those aren\'t colors, you meant <strong>red</strong> and <strong>blue</strong>.</p>' }
|
49
|
+
|
50
|
+
let(:answer_fb) do
|
51
|
+
[
|
52
|
+
{ response_id: 'response_color1', response_value: '6548',
|
53
|
+
texttype: 'text/html', feedback: '<p>Yes! <strong>Red</strong>.</p>' },
|
54
|
+
{ response_id: 'response_color1', response_value: '5550',
|
55
|
+
texttype: 'text/html', feedback: "<p>I'm pretty sure you meant <strong>red.</strong></p>" },
|
56
|
+
{ response_id: 'response_color2', response_value: '6951',
|
57
|
+
texttype: 'text/html', feedback: '<p>Yes, <strong>blue</strong>!</p>' },
|
58
|
+
{ response_id: 'response_color2', response_value: '4500',
|
59
|
+
texttype: 'text/html', feedback: '<p>Did you also chose plaid? You wanted to <strong>blue</strong>.</p>' }
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
include_examples('item_level_feedback')
|
64
|
+
include_examples('answer_feedback')
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'canvas_multiple_fib.xml' do
|
68
|
+
let(:file_path) { File.join(fixtures_path, 'canvas_multiple_fib.xml') }
|
69
|
+
let(:general_fb) { nil }
|
70
|
+
let(:correct_fb) { nil }
|
71
|
+
let(:incorrect_fb) { nil }
|
72
|
+
let(:answer_fb) { nil }
|
73
|
+
|
74
|
+
include_examples('item_level_feedback')
|
75
|
+
include_examples('answer_feedback')
|
76
|
+
end
|
21
77
|
end
|
@@ -20,22 +20,32 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
shared_examples_for 'meta_type' do
|
24
|
+
it 'returns interaction type from canvas meta data' do
|
25
|
+
expect(loaded_class.meta_type).to eq meta_type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
23
29
|
context 'multiple_choice.xml' do
|
24
30
|
let(:file_path) { File.join(fixtures_path, 'multiple_choice.xml') }
|
25
31
|
let(:shuffle_value) { false }
|
26
32
|
let(:answer_choices_count) { 5 }
|
33
|
+
let(:meta_type) { nil }
|
27
34
|
|
28
35
|
include_examples 'shuffled?'
|
29
36
|
include_examples 'answers'
|
37
|
+
include_examples 'meta_type'
|
30
38
|
end
|
31
39
|
|
32
40
|
context 'true_false.xml' do
|
33
41
|
let(:file_path) { File.join(fixtures_path, 'true_false.xml') }
|
34
42
|
let(:shuffle_value) { true }
|
35
43
|
let(:answer_choices_count) { 2 }
|
44
|
+
let(:meta_type) { nil }
|
36
45
|
|
37
46
|
include_examples 'shuffled?'
|
38
47
|
include_examples 'answers'
|
48
|
+
include_examples 'meta_type'
|
39
49
|
end
|
40
50
|
|
41
51
|
context 'multiple_answer.xml' do
|
@@ -49,8 +59,10 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
49
59
|
let(:file_path) { File.join(fixtures_path, 'multiple_answer_canvas.xml') }
|
50
60
|
let(:shuffle_value) { false }
|
51
61
|
let(:answer_choices_count) { 4 }
|
62
|
+
let(:meta_type) { 'multiple_answers_question' }
|
52
63
|
|
53
64
|
include_examples 'shuffled?'
|
65
|
+
include_examples 'meta_type'
|
54
66
|
end
|
55
67
|
|
56
68
|
context 'multiple respconditions with empty setvars' do
|
@@ -1,44 +1,88 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Qti::V1::Models::Interactions::MatchInteraction do
|
4
|
-
let(:
|
4
|
+
let(:path) { File.join('spec', 'fixtures', 'items_1.2') }
|
5
5
|
let(:assessment) { Qti::V1::Models::Assessment.from_path!(file) }
|
6
6
|
let(:item) { assessment.assessment_items.first }
|
7
|
-
subject { described_class.new(item, assessment) }
|
7
|
+
let(:subject) { described_class.new(item, assessment) }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
shared_examples_for 'common features' do
|
10
|
+
describe '.matches' do
|
11
|
+
it 'matches the item in file' do
|
12
|
+
expect(described_class.matches(item, assessment)).to be_truthy
|
13
|
+
end
|
14
|
+
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"Uses a beam of electrons. Can provide details of cells' internal structure.",
|
17
|
-
'A distractor answer.']
|
18
|
-
)
|
16
|
+
it 'returns shuffle setting' do
|
17
|
+
expect(subject.shuffled?).to eq false
|
18
|
+
end
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
it '
|
23
|
-
expect(
|
21
|
+
shared_examples_for 'questions and answers' do
|
22
|
+
it 'returns the answers' do
|
23
|
+
expect(subject.answers.map(&:item_body)).to eq(expected_answers)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns the questions' do
|
27
|
+
expect(subject.questions).to eq(expected_questions)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
|
31
|
+
shared_examples_for '#scoring_data_structs' do
|
28
32
|
it 'grabs scoring data value for matching questions' do
|
29
|
-
expect(subject.scoring_data_structs.first.values).to eq(
|
33
|
+
expect(subject.scoring_data_structs.first.values).to eq(expected_scoring_data)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'matching.xml' do
|
38
|
+
let(:file) { File.join(path, 'matching.xml') }
|
39
|
+
let(:expected_answers) do
|
40
|
+
[
|
41
|
+
'Magnify up to about 400 times. Sometimes requires colored staining of cells.',
|
42
|
+
"Uses a beam of electrons. Can provide details of cells' internal structure.",
|
43
|
+
'A distractor answer.'
|
44
|
+
]
|
45
|
+
end
|
46
|
+
let(:expected_questions) do
|
47
|
+
[
|
48
|
+
{ id: 'question_1', itemBody: 'Light Microscope' },
|
49
|
+
{ id: 'question_2', itemBody: 'Electron Microscopes' }
|
50
|
+
]
|
51
|
+
end
|
52
|
+
let(:expected_scoring_data) do
|
53
|
+
{
|
30
54
|
'question_1' => 'Magnify up to about 400 times. Sometimes requires colored staining of cells.',
|
31
55
|
'question_2' => "Uses a beam of electrons. Can provide details of cells' internal structure."
|
32
|
-
|
56
|
+
}
|
33
57
|
end
|
58
|
+
|
59
|
+
include_examples('common features')
|
60
|
+
include_examples('questions and answers')
|
61
|
+
include_examples('#scoring_data_structs')
|
34
62
|
end
|
35
63
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
64
|
+
context 'matching_feedback.xml' do
|
65
|
+
let(:file) { File.join(path, 'matching_feedback.xml') }
|
66
|
+
let(:expected_answers) { '1,2,,C,D,E,F,3,4,5,6'.split(',') }
|
67
|
+
let(:expected_questions) do
|
68
|
+
[
|
69
|
+
{ id: 'response_6831', itemBody: 'A' },
|
70
|
+
{ id: 'response_6259', itemBody: 'B' },
|
71
|
+
{ id: 'response_743', itemBody: '' },
|
72
|
+
{ id: 'response_1943', itemBody: '' }
|
73
|
+
]
|
74
|
+
end
|
75
|
+
let(:expected_scoring_data) do
|
76
|
+
{
|
77
|
+
'response_6831' => '1',
|
78
|
+
'response_6259' => '2',
|
79
|
+
'response_743' => '',
|
80
|
+
'response_1943' => ''
|
81
|
+
}
|
42
82
|
end
|
83
|
+
|
84
|
+
include_examples('common features')
|
85
|
+
include_examples('questions and answers')
|
86
|
+
include_examples('#scoring_data_structs')
|
43
87
|
end
|
44
88
|
end
|