qti 0.0.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.
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