qti 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +28 -0
  3. data/Rakefile +1 -0
  4. data/lib/qti.rb +62 -0
  5. data/lib/qti/models/base.rb +80 -0
  6. data/lib/qti/models/manifest.rb +20 -0
  7. data/lib/qti/v1/models/assessment.rb +17 -0
  8. data/lib/qti/v1/models/assessment_item.rb +59 -0
  9. data/lib/qti/v1/models/base.rb +13 -0
  10. data/lib/qti/v1/models/choices/logical_identifier_choice.rb +26 -0
  11. data/lib/qti/v1/models/interactions/logical_identifier_interaction.rb +32 -0
  12. data/lib/qti/v2/models/assessment_item.rb +62 -0
  13. data/lib/qti/v2/models/assessment_test.rb +32 -0
  14. data/lib/qti/v2/models/base.rb +70 -0
  15. data/lib/qti/v2/models/choices/simple_choice.rb +28 -0
  16. data/lib/qti/v2/models/interactions.rb +25 -0
  17. data/lib/qti/v2/models/interactions/choice_interaction.rb +50 -0
  18. data/spec/fixtures/items_1.2/multiple_answer.xml +105 -0
  19. data/spec/fixtures/items_1.2/multiple_choice.xml +83 -0
  20. data/spec/fixtures/items_1.2/true_false.xml +50 -0
  21. data/spec/fixtures/items_2.1/Example01-modalFeedback.xml +79 -0
  22. data/spec/fixtures/items_2.1/Example02-feedbackInline.xml +67 -0
  23. data/spec/fixtures/items_2.1/Example03-feedbackBlock-solution-random.xml +223 -0
  24. data/spec/fixtures/items_2.1/Example03-feedbackBlock-solution.xml +238 -0
  25. data/spec/fixtures/items_2.1/Example04-feedbackBlock-templateBlock.xml +582 -0
  26. data/spec/fixtures/items_2.1/Example05-feedbackBlock-adaptive.xml +397 -0
  27. data/spec/fixtures/items_2.1/adaptive.xml +286 -0
  28. data/spec/fixtures/items_2.1/adaptive_template.xml +350 -0
  29. data/spec/fixtures/items_2.1/associate.xml +33 -0
  30. data/spec/fixtures/items_2.1/audio-video.xml +46 -0
  31. data/spec/fixtures/items_2.1/choice.xml +31 -0
  32. data/spec/fixtures/items_2.1/choice_aria.xml +42 -0
  33. data/spec/fixtures/items_2.1/choice_fixed.xml +33 -0
  34. data/spec/fixtures/items_2.1/choice_multiple.xml +31 -0
  35. data/spec/fixtures/items_2.1/choice_multiple_chocolade.xml +74 -0
  36. data/spec/fixtures/items_2.1/choice_multiple_rtl.xml +33 -0
  37. data/spec/fixtures/items_2.1/choice_ruby.xml +39 -0
  38. data/spec/fixtures/items_2.1/choice_t_f.xml +30 -0
  39. data/spec/fixtures/items_2.1/choice_true_false.xml +30 -0
  40. data/spec/fixtures/items_2.1/data-attributes.xml +61 -0
  41. data/spec/fixtures/items_2.1/drawing.xml +16 -0
  42. data/spec/fixtures/items_2.1/essay.xml +14 -0
  43. data/spec/fixtures/items_2.1/extended_text.xml +24 -0
  44. data/spec/fixtures/items_2.1/extended_text_rubric.xml +36 -0
  45. data/spec/fixtures/items_2.1/feedback_adaptive.xml +142 -0
  46. data/spec/fixtures/items_2.1/figures.xml +32 -0
  47. data/spec/fixtures/items_2.1/gap_match.xml +33 -0
  48. data/spec/fixtures/items_2.1/graphic_associate.xml +36 -0
  49. data/spec/fixtures/items_2.1/graphic_gap_match.xml +54 -0
  50. data/spec/fixtures/items_2.1/graphic_gap_match_text.xml +50 -0
  51. data/spec/fixtures/items_2.1/graphic_order.xml +32 -0
  52. data/spec/fixtures/items_2.1/hint.xml +85 -0
  53. data/spec/fixtures/items_2.1/hotspot.xml +26 -0
  54. data/spec/fixtures/items_2.1/hottext.xml +33 -0
  55. data/spec/fixtures/items_2.1/images/CBG.png +0 -0
  56. data/spec/fixtures/items_2.1/images/EBG.png +0 -0
  57. data/spec/fixtures/items_2.1/images/EDI.png +0 -0
  58. data/spec/fixtures/items_2.1/images/GLA.png +0 -0
  59. data/spec/fixtures/items_2.1/images/MAN.png +0 -0
  60. data/spec/fixtures/items_2.1/images/MCH.png +0 -0
  61. data/spec/fixtures/items_2.1/images/airport.png +0 -0
  62. data/spec/fixtures/items_2.1/images/blueStar.png +0 -0
  63. data/spec/fixtures/items_2.1/images/blue_door.png +0 -0
  64. data/spec/fixtures/items_2.1/images/bus.png +0 -0
  65. data/spec/fixtures/items_2.1/images/castle.png +0 -0
  66. data/spec/fixtures/items_2.1/images/greenTriangle.png +0 -0
  67. data/spec/fixtures/items_2.1/images/green_door.png +0 -0
  68. data/spec/fixtures/items_2.1/images/house.png +0 -0
  69. data/spec/fixtures/items_2.1/images/open_car.png +0 -0
  70. data/spec/fixtures/items_2.1/images/open_goat.png +0 -0
  71. data/spec/fixtures/items_2.1/images/plane.png +0 -0
  72. data/spec/fixtures/items_2.1/images/postcard.eps +3581 -0
  73. data/spec/fixtures/items_2.1/images/postcard.png +0 -0
  74. data/spec/fixtures/items_2.1/images/rectangle.svg +1 -0
  75. data/spec/fixtures/items_2.1/images/redCircle.png +0 -0
  76. data/spec/fixtures/items_2.1/images/red_door.png +0 -0
  77. data/spec/fixtures/items_2.1/images/sign.png +0 -0
  78. data/spec/fixtures/items_2.1/images/survey.jpg +0 -0
  79. data/spec/fixtures/items_2.1/images/train.png +0 -0
  80. data/spec/fixtures/items_2.1/images/uk.png +0 -0
  81. data/spec/fixtures/items_2.1/images/ukair.png +0 -0
  82. data/spec/fixtures/items_2.1/images/ukairtags.png +0 -0
  83. data/spec/fixtures/items_2.1/imsmanifest.xml +227 -0
  84. data/spec/fixtures/items_2.1/inline_choice.xml +26 -0
  85. data/spec/fixtures/items_2.1/inline_choice_math.xml +68 -0
  86. data/spec/fixtures/items_2.1/likert.xml +21 -0
  87. data/spec/fixtures/items_2.1/match.xml +41 -0
  88. data/spec/fixtures/items_2.1/math.xml +35 -0
  89. data/spec/fixtures/items_2.1/mc_calc3.xml +164 -0
  90. data/spec/fixtures/items_2.1/mc_calc5.xml +211 -0
  91. data/spec/fixtures/items_2.1/mc_stat2.xml +219 -0
  92. data/spec/fixtures/items_2.1/media_coords.xml +33 -0
  93. data/spec/fixtures/items_2.1/multi-input.xml +271 -0
  94. data/spec/fixtures/items_2.1/nested_object.xml +26 -0
  95. data/spec/fixtures/items_2.1/order.xml +25 -0
  96. data/spec/fixtures/items_2.1/order_partial_scoring.xml +55 -0
  97. data/spec/fixtures/items_2.1/order_rtl.xml +27 -0
  98. data/spec/fixtures/items_2.1/orkney1.xml +34 -0
  99. data/spec/fixtures/items_2.1/orkney2.xml +34 -0
  100. data/spec/fixtures/items_2.1/position_object.xml +34 -0
  101. data/spec/fixtures/items_2.1/select_point.xml +23 -0
  102. data/spec/fixtures/items_2.1/shared/orkney.css +1 -0
  103. data/spec/fixtures/items_2.1/shared/orkney.html +20 -0
  104. data/spec/fixtures/items_2.1/slider.xml +35 -0
  105. data/spec/fixtures/items_2.1/svg.xml +28 -0
  106. data/spec/fixtures/items_2.1/template.xml +88 -0
  107. data/spec/fixtures/items_2.1/template_image.xml +74 -0
  108. data/spec/fixtures/items_2.1/text_entry.xml +27 -0
  109. data/spec/fixtures/items_2.1/upload.xml +18 -0
  110. data/spec/fixtures/items_2.1/upload_composite.xml +24 -0
  111. data/spec/fixtures/test_qti_1.2.zip +0 -0
  112. data/spec/fixtures/test_qti_1.2/contact info.png +0 -0
  113. data/spec/fixtures/test_qti_1.2/exam1/my_files/org0/images/image.png +0 -0
  114. data/spec/fixtures/test_qti_1.2/exam1/my_files/org1/images/image.png +0 -0
  115. data/spec/fixtures/test_qti_1.2/image.png +0 -0
  116. data/spec/fixtures/test_qti_1.2/imsmanifest.xml +37 -0
  117. data/spec/fixtures/test_qti_1.2/quiz.xml +216 -0
  118. data/spec/fixtures/test_qti_2.1.zip +0 -0
  119. data/spec/fixtures/test_qti_2.1/assessment.xml +77 -0
  120. data/spec/fixtures/test_qti_2.1/imsmanifest.xml +211 -0
  121. data/spec/fixtures/test_qti_2.1/mathassess.xsd +54 -0
  122. data/spec/fixtures/test_qti_2.1/multiple-answer/multiple-answer.xml +31 -0
  123. data/spec/fixtures/test_qti_2.1/multiple-choice/multiple-choice.xml +31 -0
  124. data/spec/fixtures/test_qti_2.1/text-entry/text-entry.xml +330 -0
  125. data/spec/fixtures/test_qti_2.1/true-false/true-false.xml +55 -0
  126. data/spec/fixtures/tests/feedbackTest/assessment.xml +252 -0
  127. data/spec/fixtures/tests/feedbackTest/id-38d47747fb30/Example02-feedbackInline.xml +51 -0
  128. data/spec/fixtures/tests/feedbackTest/id-5e216df10030/Example03-feedbackBlock-solution.xml +199 -0
  129. data/spec/fixtures/tests/feedbackTest/id-9c33d141576e/Example05-feedbackBlock-adaptive.xml +330 -0
  130. data/spec/fixtures/tests/feedbackTest/id-aaa0bbf5da1d/Example03-feedbackBlock-solution-random.xml +223 -0
  131. data/spec/fixtures/tests/feedbackTest/id-d599169403d2/Example04-feedbackBlock-templateBlock.xml +534 -0
  132. data/spec/fixtures/tests/feedbackTest/id-fa3ee5852723/Example01-modalFeedback.xml +55 -0
  133. data/spec/fixtures/tests/feedbackTest/imsmanifest.xml +239 -0
  134. data/spec/fixtures/tests/interactionmix_saxony_v3/Choicemultiple_2014410822.xml +110 -0
  135. data/spec/fixtures/tests/interactionmix_saxony_v3/Choicemultiple_871212949.xml +208 -0
  136. data/spec/fixtures/tests/interactionmix_saxony_v3/Choicesingle_853928446.xml +159 -0
  137. data/spec/fixtures/tests/interactionmix_saxony_v3/Choicetruefalse_176040516.xml +98 -0
  138. data/spec/fixtures/tests/interactionmix_saxony_v3/Hotspot_278940407.xml +109 -0
  139. data/spec/fixtures/tests/interactionmix_saxony_v3/Hottext_801974120.xml +106 -0
  140. data/spec/fixtures/tests/interactionmix_saxony_v3/InteractionMixSachsen_1901710679.xml +54 -0
  141. data/spec/fixtures/tests/interactionmix_saxony_v3/Matchmultiple_1038910213.xml +139 -0
  142. data/spec/fixtures/tests/interactionmix_saxony_v3/Matchsingle_143114773.xml +133 -0
  143. data/spec/fixtures/tests/interactionmix_saxony_v3/Order_913967682.xml +117 -0
  144. data/spec/fixtures/tests/interactionmix_saxony_v3/TextEntry_883368511.xml +114 -0
  145. data/spec/fixtures/tests/interactionmix_saxony_v3/TextEntrynumeric_2040297025.xml +154 -0
  146. data/spec/fixtures/tests/interactionmix_saxony_v3/TextEntrynumeric_770468849.xml +124 -0
  147. data/spec/fixtures/tests/interactionmix_saxony_v3/TextEntrysubset_806481421.xml +227 -0
  148. data/spec/fixtures/tests/interactionmix_saxony_v3/imsmanifest.xml +278 -0
  149. data/spec/fixtures/tests/interactionmix_saxony_v3/media/03c5e2f774db49598deb3ac7d05b53f9.jpg +0 -0
  150. data/spec/fixtures/tests/interactionmix_saxony_v3/media/0563e67fb1bb48ad882e0a5abf2a2686.jpg +0 -0
  151. data/spec/fixtures/tests/interactionmix_saxony_v3/media/2f44366716474a5d8e2a2e32346cbc05.jpg +0 -0
  152. data/spec/fixtures/tests/interactionmix_saxony_v3/media/71a299b50b5e4b1492f8ee51ce25be7d.jpg +0 -0
  153. data/spec/fixtures/tests/interactionmix_saxony_v3/media/a439b702d5034ca38f6df26a12835db3.jpg +0 -0
  154. data/spec/fixtures/tests/interactionmix_saxony_v3/media/b660fc9f268c4ef688d8606116c70160.jpg +0 -0
  155. data/spec/fixtures/tests/interactionmix_saxony_v3/media/c2f541343b9b4bfdba9fc90c7a18403e.jpg +0 -0
  156. data/spec/fixtures/tests/interactionmix_saxony_v3/media/e18b5a2eb8104d0994a182ee0176a05c.jpg +0 -0
  157. data/spec/fixtures/tests/interactionmix_saxony_v3/media/f88c5aa2c6724a388fdbadc7133eb757.jpg +0 -0
  158. data/spec/fixtures/tests/interactionmix_saxony_v3/media/ffe337505ef74334a0cecb33310f99c1.jpg +0 -0
  159. data/spec/fixtures/tests/tests/complete.xml +33 -0
  160. data/spec/fixtures/tests/tests/report.xml +70 -0
  161. data/spec/fixtures/tests/tests/rtest01-fragment.xml +12 -0
  162. data/spec/fixtures/tests/tests/rtest01-set01.xml +17 -0
  163. data/spec/fixtures/tests/tests/rtest01-set02.xml +17 -0
  164. data/spec/fixtures/tests/tests/rtest01-set03.xml +17 -0
  165. data/spec/fixtures/tests/tests/rtest01.xml +16 -0
  166. data/spec/fixtures/tests/tests/rtest02.xml +48 -0
  167. data/spec/fixtures/tests/tests/rtest03.xml +38 -0
  168. data/spec/fixtures/tests/tests/rtest04.xml +50 -0
  169. data/spec/fixtures/tests/tests/rtest06.xml +34 -0
  170. data/spec/fixtures/tests/tests/rtest08.xml +38 -0
  171. data/spec/fixtures/tests/tests/rtest09.xml +33 -0
  172. data/spec/fixtures/tests/tests/rtest10.xml +48 -0
  173. data/spec/fixtures/tests/tests/rtest12.xml +38 -0
  174. data/spec/fixtures/tests/tests/rtest13.xml +62 -0
  175. data/spec/fixtures/tests/tests/rtest22.xml +41 -0
  176. data/spec/fixtures/tests/tests/rtest24.xml +37 -0
  177. data/spec/fixtures/tests/tests/rtest25.xml +62 -0
  178. data/spec/fixtures/tests/tests/rtest26.xml +38 -0
  179. data/spec/fixtures/tests/tests/rtest27.xml +46 -0
  180. data/spec/qti/models/base_spec.rb +71 -0
  181. data/spec/qti/models/manifest_spec.rb +19 -0
  182. data/spec/qti/v1/models/assessment_item_spec.rb +49 -0
  183. data/spec/qti/v1/models/assessment_spec.rb +18 -0
  184. data/spec/qti/v1/models/choices/logical_identifier_choice_spec.rb +23 -0
  185. data/spec/qti/v1/models/interactions/logical_identifier_interaction_spec.rb +20 -0
  186. data/spec/qti/v2/models/assessment_item_spec.rb +67 -0
  187. data/spec/qti/v2/models/assessment_test_spec.rb +60 -0
  188. data/spec/qti/v2/models/choices/simple_choice_spec.rb +22 -0
  189. data/spec/qti/v2/models/interactions/choice_interaction_spec.rb +27 -0
  190. data/spec/qti_spec.rb +38 -0
  191. data/spec/spec_helper.rb +10 -0
  192. metadata +506 -0
@@ -0,0 +1,37 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p2 http://www.imsglobal.org/xsd/qti/qtiv2p2/imsqti_v2p2.xsd"
5
+ identifier="RTEST-24" title="Randomizing the Order of Items and Sections">
6
+ <testPart navigationMode="nonlinear" submissionMode="simultaneous" identifier="RTEST-24-A">
7
+ <assessmentSection identifier="sectionA" title="Section A" visible="true">
8
+ <ordering shuffle="true"/>
9
+ <rubricBlock view="candidate">
10
+ <p>Instructions for Section A</p>
11
+ </rubricBlock>
12
+ <assessmentItemRef identifier="item034" href="item034.xml" fixed="true"/>
13
+ <assessmentItemRef identifier="item160" href="item160.xml"/>
14
+ <assessmentItemRef identifier="item063" href="item063.xml"/>
15
+ </assessmentSection>
16
+ <assessmentSection identifier="sectionB" title="Section B" visible="true">
17
+ <ordering shuffle="true"/>
18
+ <rubricBlock view="candidate">
19
+ <p>Instructions for Section B</p>
20
+ </rubricBlock>
21
+ <assessmentItemRef identifier="item434" href="item434.xml"/>
22
+ <assessmentItemRef identifier="item065" href="item065.xml"/>
23
+ <assessmentItemRef identifier="item365" href="item365.xml"/>
24
+ <assessmentSection identifier="sectionB1" title="Section B1" visible="false"
25
+ keepTogether="true">
26
+ <ordering shuffle="false"/>
27
+ <rubricBlock view="candidate">
28
+ <p>More instructions to cover these items only, displayed in addition to the
29
+ general instructions for section B.</p>
30
+ </rubricBlock>
31
+ <assessmentItemRef identifier="item347" href="item347.xml"/>
32
+ <assessmentItemRef identifier="item653" href="item653.xml"/>
33
+ </assessmentSection>
34
+ <assessmentItemRef identifier="item656" href="item656.xml"/>
35
+ </assessmentSection>
36
+ </testPart>
37
+ </assessmentTest>
@@ -0,0 +1,62 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p2 http://www.imsglobal.org/xsd/qti/qtiv2p2/imsqti_v2p2.xsd"
5
+ identifier="RTEST-25" title="Basic Statistics as Outcomes">
6
+ <outcomeDeclaration identifier="NCORRECTA" cardinality="single" baseType="integer"/>
7
+ <outcomeDeclaration identifier="NCORRECTB" cardinality="single" baseType="integer"/>
8
+ <outcomeDeclaration identifier="NINCORRECT" cardinality="single" baseType="integer"/>
9
+ <outcomeDeclaration identifier="NRESPONSED" cardinality="single" baseType="integer"/>
10
+ <outcomeDeclaration identifier="NPRESENTED" cardinality="single" baseType="integer"/>
11
+ <outcomeDeclaration identifier="NSELECTED" cardinality="single" baseType="integer"/>
12
+ <outcomeDeclaration identifier="PERCENT_CORRECT" cardinality="single" baseType="float"/>
13
+ <testPart navigationMode="nonlinear" submissionMode="simultaneous" identifier="RTEST-25-A">
14
+ <assessmentSection identifier="sectionA" title="Section A" visible="true">
15
+ <rubricBlock view="candidate">
16
+ <p>Instructions for Section A</p>
17
+ </rubricBlock>
18
+ <assessmentItemRef identifier="item034" href="item034.xml"/>
19
+ <assessmentItemRef identifier="item160" href="item160.xml"/>
20
+ <assessmentItemRef identifier="item063" href="item063.xml"/>
21
+ </assessmentSection>
22
+ <assessmentSection identifier="sectionB" title="Section B" visible="true">
23
+ <selection select="2"/>
24
+ <rubricBlock view="candidate">
25
+ <p>Instructions for Section B</p>
26
+ </rubricBlock>
27
+ <assessmentItemRef identifier="item434" href="item434.xml"/>
28
+ <assessmentItemRef identifier="item065" href="item065.xml"/>
29
+ <assessmentItemRef identifier="item365" href="item365.xml"/>
30
+ <assessmentItemRef identifier="item656" href="item656.xml"/>
31
+ </assessmentSection>
32
+ </testPart>
33
+ <outcomeProcessing>
34
+ <setOutcomeValue identifier="NCORRECTA">
35
+ <numberCorrect sectionIdentifier="sectionA"/>
36
+ </setOutcomeValue>
37
+ <setOutcomeValue identifier="NCORRECTB">
38
+ <numberCorrect sectionIdentifier="sectionB"/>
39
+ </setOutcomeValue>
40
+ <setOutcomeValue identifier="NINCORRECT">
41
+ <numberIncorrect/>
42
+ </setOutcomeValue>
43
+ <setOutcomeValue identifier="NRESPONSED">
44
+ <numberResponded/>
45
+ </setOutcomeValue>
46
+ <setOutcomeValue identifier="NPRESENTED">
47
+ <numberPresented/>
48
+ </setOutcomeValue>
49
+ <setOutcomeValue identifier="NSELECTED">
50
+ <numberSelected/>
51
+ </setOutcomeValue>
52
+ <setOutcomeValue identifier="PERCENT_CORRECT">
53
+ <product>
54
+ <baseValue baseType="float">100.0</baseValue>
55
+ <divide>
56
+ <numberCorrect/>
57
+ <numberSelected/>
58
+ </divide>
59
+ </product>
60
+ </setOutcomeValue>
61
+ </outcomeProcessing>
62
+ </assessmentTest>
@@ -0,0 +1,38 @@
1
+ <assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2"
2
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p2 http://www.imsglobal.org/xsd/qti/qtiv2p2/imsqti_v2p2.xsd"
4
+ identifier="RTEST-26" title="Mapping item outcomes prior to aggregation">
5
+ <!-- Support for mapping of item outcomes prior to aggregation -->
6
+ <outcomeDeclaration baseType="float" cardinality="single" identifier="SCORE">
7
+ <defaultValue>
8
+ <value>0</value>
9
+ </defaultValue>
10
+ </outcomeDeclaration>
11
+ <testPart navigationMode="nonlinear" submissionMode="simultaneous" identifier="RTEST-26-A">
12
+ <assessmentSection identifier="sectionA" title="Section A" visible="true">
13
+ <rubricBlock view="candidate">
14
+ <p>Instructions for Section A</p>
15
+ </rubricBlock>
16
+ <assessmentItemRef identifier="item034" href="item034.xml">
17
+ <variableMapping sourceIdentifier="NOTA" targetIdentifier="SCORE"/>
18
+ </assessmentItemRef>
19
+ <assessmentItemRef identifier="item160" href="item160.xml"/>
20
+ <assessmentItemRef identifier="item063" href="item063.xml"/>
21
+ </assessmentSection>
22
+ <assessmentSection identifier="sectionB" title="Section B" visible="true">
23
+ <rubricBlock view="candidate">
24
+ <p>Instructions for Section B</p>
25
+ </rubricBlock>
26
+ <assessmentItemRef identifier="item434" href="item434.xml"/>
27
+ <assessmentItemRef identifier="item065" href="ïtem065.xml"/>
28
+ <assessmentItemRef identifier="item365" href="item365.xml"/>
29
+ </assessmentSection>
30
+ </testPart>
31
+ <outcomeProcessing>
32
+ <setOutcomeValue identifier="SCORE">
33
+ <sum>
34
+ <testVariables variableIdentifier="SCORE"/>
35
+ </sum>
36
+ </setOutcomeValue>
37
+ </outcomeProcessing>
38
+ </assessmentTest>
@@ -0,0 +1,46 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p2 http://www.imsglobal.org/xsd/qti/qtiv2p2/imsqti_v2p2.xsd"
5
+ identifier="RTEST-27" title="Generalized Processing of Item Outcomes">
6
+ <outcomeDeclaration identifier="SCORE365" cardinality="single" baseType="integer"/>
7
+ <outcomeDeclaration identifier="SCOREA" cardinality="single" baseType="integer"/>
8
+ <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="float"/>
9
+ <testPart navigationMode="nonlinear" submissionMode="simultaneous" identifier="RTEST-27-A">
10
+ <assessmentSection identifier="sectionA" title="Section A" visible="true">
11
+ <rubricBlock view="candidate">
12
+ <p>Instructions for Section A</p>
13
+ </rubricBlock>
14
+ <assessmentItemRef identifier="item034" href="item034.xml"/>
15
+ <assessmentItemRef identifier="item160" href="item160.xml"/>
16
+ <assessmentItemRef identifier="item063" href="item063.xml"/>
17
+ </assessmentSection>
18
+ <assessmentSection identifier="sectionB" title="Section B" visible="true">
19
+ <rubricBlock view="candidate">
20
+ <p>Instructions for Section B</p>
21
+ </rubricBlock>
22
+ <assessmentItemRef identifier="item434" href="item434.xml"/>
23
+ <assessmentItemRef identifier="item065" href="item065.xml"/>
24
+ <assessmentItemRef identifier="item365" href="item365.xml"/>
25
+ <assessmentItemRef identifier="item656" href="item656.xml"/>
26
+ </assessmentSection>
27
+ </testPart>
28
+ <outcomeProcessing>
29
+ <!-- just a single item score -->
30
+ <setOutcomeValue identifier="SCORE365">
31
+ <variable identifier="item365.SCORE"/>
32
+ </setOutcomeValue>
33
+ <!-- all the scores in section A -->
34
+ <setOutcomeValue identifier="SCOREA">
35
+ <sum>
36
+ <testVariables sectionIdentifier="SectionA" variableIdentifier="SCORE"/>
37
+ </sum>
38
+ </setOutcomeValue>
39
+ <!-- all the scores in the test -->
40
+ <setOutcomeValue identifier="SCORE">
41
+ <sum>
42
+ <testVariables variableIdentifier="SCORE"/>
43
+ </sum>
44
+ </setOutcomeValue>
45
+ </outcomeProcessing>
46
+ </assessmentTest>
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::Models::Base do
4
+ let(:loaded_class) do
5
+ path = File.join('spec', 'fixtures', 'test_qti_2.1', 'assessment.xml')
6
+ described_class.from_path!(path)
7
+ end
8
+
9
+ context 'specified as single content node matching helpers' do
10
+ let(:content_stub) { Struct.new(:content, :thing) }
11
+
12
+ # "assessmentItemRef" should match 4 nodes, and therefore raise for these helpers
13
+ let(:bad_xpath) { '//xmlns:assessmentItemRef' }
14
+ let(:bad_css_path) { 'assessmentItemRef' }
15
+
16
+ let(:xpath) { '//xmlns:assessmentTest' }
17
+ let(:css_path) { 'assessmentTest' }
18
+
19
+ describe '#xpath_with_single_check' do
20
+ it 'raises if node count is more than 1' do
21
+ expect do
22
+ loaded_class.xpath_with_single_check(bad_xpath)
23
+ end.to raise_error
24
+ end
25
+
26
+ it 'doesn\'t raise with a single node count' do
27
+ expect do
28
+ loaded_class.xpath_with_single_check(xpath)
29
+ end.not_to raise_error
30
+ end
31
+ end
32
+
33
+ describe '#css_with_single_check' do
34
+ it 'raises if node count is more than 1' do
35
+ expect do
36
+ loaded_class.css_with_single_check(bad_css_path)
37
+ end.to raise_error
38
+ end
39
+
40
+ it 'doesn\'t raise with a single node count' do
41
+ expect do
42
+ loaded_class.css_with_single_check(css_path)
43
+ end.not_to raise_error
44
+ end
45
+ end
46
+
47
+ describe '#remap_href_path' do
48
+ let(:href) { 'hi.xml' }
49
+ let(:base_path) { 'hello/bob.xml' }
50
+ let(:remapped_path) { File.join(File.dirname(base_path), href) }
51
+ let(:subject) { loaded_class.remap_href_path(href, base_path) }
52
+
53
+ it 'passes the original path if it exists' do
54
+ allow(File).to receive(:exist?).with(href).and_return(true)
55
+ expect(subject).to eq href
56
+ end
57
+
58
+ it 'passes the original path when the remapped path doesn\'t exist' do
59
+ allow(File).to receive(:exist?).with(href).and_return(false)
60
+ allow(File).to receive(:exist?).with(remapped_path).and_return(false)
61
+ expect(subject).to eq href
62
+ end
63
+
64
+ it 'passes the remapped path if it exists' do
65
+ allow(File).to receive(:exist?).with(href).and_return(false)
66
+ allow(File).to receive(:exist?).with(remapped_path).and_return(true)
67
+ expect(subject).to eq remapped_path
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ fixtures_path = File.join('spec', 'fixtures')
4
+
5
+ describe Qti::Models::Manifest do
6
+ manifest_files = Dir.glob(File.join(fixtures_path, '**', 'imsmanifest.xml'))
7
+ manifest_files.each do |file|
8
+ context "File: #{file}" do
9
+ it 'parses the manifest file without error' do
10
+ expect { described_class.from_path!(file) }.not_to raise_error
11
+ end
12
+
13
+ it 'returns a path to the xml test reference if it exists' do
14
+ href = described_class.from_path!(file).assessment_test_href
15
+ expect(File.extname(href)).to eq '.xml' if href
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::V1::Models::AssessmentItem do
4
+ context 'quiz.xml' do
5
+ let(:file_path) { File.join('spec', 'fixtures', 'items_1.2', 'true_false.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 'loads an AssessmentItem ref' do
11
+ expect do
12
+ described_class.new(assessment_item_ref)
13
+ end.to_not raise_error(Qti::ParseError)
14
+ end
15
+
16
+ it 'has the title' do
17
+ expect(loaded_class.title).to eq 'Grading - specific - 3 pt score'
18
+ end
19
+
20
+ it 'has sanitized item_body' do
21
+ expect(loaded_class.item_body).to include '<img'
22
+ expect(loaded_class.item_body).to include 'If I get a 3, I must have done something wrong.'
23
+ end
24
+
25
+ it 'grabs the points possible' do
26
+ expect(loaded_class.points_possible).to eq '0'
27
+ end
28
+
29
+ it 'grabs the rcardinality and scoring data value' do
30
+ struct = loaded_class.send(:scoring_data_structs)
31
+ expect(struct.first.values).to eq 'QUE_1005_A1'
32
+ expect(struct.first.rcardinality).to eq 'Single'
33
+ end
34
+
35
+ it 'has the identifier used to identify it in manifest/test files' do
36
+ expect(loaded_class.identifier).to eq 'QUE_1003'
37
+ end
38
+
39
+ it 'loads the interaction_model without erroring' do
40
+ expect { loaded_class.interaction_model }.not_to raise_error
41
+ end
42
+
43
+ it 'loads the correct interaction model' do
44
+ expect(loaded_class.interaction_model).to be_an_instance_of(
45
+ Qti::V1::Models::Interactions::LogicalIdentifierInteraction
46
+ )
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ fixtures_path = File.join('spec', 'fixtures')
4
+
5
+ describe Qti::V1::Models::Assessment do
6
+ let(:path) { File.join(fixtures_path, 'test_qti_1.2', 'quiz.xml') }
7
+ let(:loaded_class) { described_class.from_path!(path) }
8
+
9
+ it 'loads an AssessmentXML file' do
10
+ expect do
11
+ described_class.from_path!(path)
12
+ end.to_not raise_error
13
+ end
14
+
15
+ it 'has the title' do
16
+ expect(loaded_class.title).to eq '1.2 Import Quiz'
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::V1::Models::Choices::LogicalIdentifierChoice do
4
+ context 'quiz.xml' do
5
+ let(:fixtures_path) { File.join('spec', 'fixtures') }
6
+ let(:file_path) { File.join(fixtures_path, 'test_qti_1.2', 'quiz.xml') }
7
+ let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
8
+ let(:nodes) { test_object.assessment_items }
9
+ let(:choices) { nodes.map { |node| described_class.new(node) } }
10
+
11
+ it 'returns the right identifier' do
12
+ expect(choices.map(&:identifier)).to eq %w(QUE_1003 QUE_1007 QUE_1022)
13
+ end
14
+
15
+ it 'returns the item body text' do
16
+ expect(choices.map(&:item_body).map(&:empty?).any?).to eq false
17
+ end
18
+
19
+ it 'removes inline feedback elements from item_body' do
20
+ expect(choices.map(&:item_body).map { |text| text.include? 'correct' }.any?).to eq false
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::V1::Models::Interactions::LogicalIdentifierInteraction do
4
+ context 'quiz.xml' do
5
+ let(:fixtures_path) { File.join('spec', 'fixtures') }
6
+ let(:file_path) { File.join(fixtures_path, 'test_qti_1.2', 'quiz.xml') }
7
+ let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
8
+ let(:assessment_item_refs) { test_object.assessment_items }
9
+ let(:loaded_class) { described_class.new(assessment_item_refs.first) }
10
+
11
+ it 'returns shuffle setting' do
12
+ expect(loaded_class.shuffled?).to eq true
13
+ end
14
+
15
+ it 'returns the answers' do
16
+ expect(loaded_class.answers.count).to eq 2
17
+ expect(loaded_class.answers.first).to be_an_instance_of(Qti::V1::Models::Choices::LogicalIdentifierChoice)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Qti::V2::Models::AssessmentItem do
4
+ context 'choice.xml' do
5
+ let(:fixtures_path) { File.join('spec', 'fixtures') }
6
+ let(:file_path) { File.join(fixtures_path, 'items_2.1', 'choice.xml') }
7
+ let(:loaded_class) { described_class.from_path!(file_path) }
8
+
9
+ it 'loads an AssessmentItem XML file' do
10
+ expect do
11
+ described_class.from_path!(file_path)
12
+ end.to_not raise_error(Qti::ParseError)
13
+ end
14
+
15
+ it 'has the title' do
16
+ expect(loaded_class.title).to eq 'Unattended Luggage'
17
+ end
18
+
19
+ it 'has sanitized item_body' do
20
+ expect(loaded_class.item_body).to include '<img'
21
+ expect(loaded_class.item_body).to include '<p'
22
+ expect(loaded_class.item_body).to include 'Look at the text in the picture.'
23
+ end
24
+
25
+ it 'falls back onto nil points possible value' do
26
+ expect(loaded_class.points_possible).to eq nil
27
+ end
28
+
29
+ it 'grabs the type and scoring data value' do
30
+ struct = loaded_class.send(:scoring_data_structs)
31
+ expect(struct.first.values).to eq 'ChoiceA'
32
+ expect(struct.first.type).to eq 'identifier'
33
+ end
34
+
35
+ it 'has the identifier used to identify it in manifest/test files' do
36
+ expect(loaded_class.identifier).to eq 'choice'
37
+ end
38
+
39
+ it 'loads the interaction_model without erroring' do
40
+ expect { loaded_class.interaction_model }.not_to raise_error
41
+ end
42
+
43
+ it 'loads the correct interaction model' do
44
+ expect(loaded_class.interaction_model).to be_an_instance_of(Qti::V2::Models::Interactions::ChoiceInteraction)
45
+ end
46
+ end
47
+
48
+ context 'all test files' do
49
+ test_files = Dir.glob(File.join('spec', 'fixtures', 'items_2.1', '*.xml'))
50
+ test_files.each do |file|
51
+ next if file.include? 'imsmanifest.xml'
52
+ context File.basename(file) do
53
+ let(:loaded_class) { described_class.from_path!(file) }
54
+
55
+ it 'loads an AssessmentItem XML file' do
56
+ expect do
57
+ described_class.from_path!(file)
58
+ end.to_not raise_error
59
+ end
60
+
61
+ it 'has a title' do
62
+ expect(loaded_class.title).to be_a String
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end