qti 1.0.11 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/qti.rb +72 -19
  4. data/lib/qti/content_packaging.rb +0 -8
  5. data/lib/qti/models/assessment_meta.rb +0 -2
  6. data/lib/qti/models/base.rb +0 -5
  7. data/lib/qti/models/manifest.rb +1 -7
  8. data/lib/qti/models/metadata.rb +0 -7
  9. data/lib/qti/models/resource.rb +4 -10
  10. data/lib/qti/sanitizer.rb +0 -4
  11. data/lib/qti/v1/models/assessment.rb +1 -3
  12. data/lib/qti/v1/models/assessment_item.rb +0 -3
  13. data/lib/qti/v1/models/base.rb +0 -2
  14. data/lib/qti/v1/models/choices/fill_blank_choice.rb +0 -2
  15. data/lib/qti/v1/models/choices/logical_identifier_choice.rb +0 -2
  16. data/lib/qti/v1/models/interactions.rb +0 -4
  17. data/lib/qti/v1/models/interactions/base_fill_blank_interaction.rb +1 -1
  18. data/lib/qti/v1/models/interactions/formula_interaction.rb +2 -4
  19. data/lib/qti/v1/models/interactions/match_interaction.rb +2 -2
  20. data/lib/qti/v1/models/numerics/exact_match.rb +0 -2
  21. data/lib/qti/v1/models/numerics/margin_error.rb +0 -2
  22. data/lib/qti/v1/models/numerics/precision.rb +1 -3
  23. data/lib/qti/v1/models/numerics/within_range.rb +0 -2
  24. data/lib/qti/v1/models/question_group.rb +0 -3
  25. data/lib/qti/v2/models/assessment_item.rb +0 -3
  26. data/lib/qti/v2/models/assessment_test.rb +2 -5
  27. data/lib/qti/v2/models/base.rb +0 -2
  28. data/lib/qti/v2/models/choices/gap_match_choice.rb +0 -2
  29. data/lib/qti/v2/models/choices/simple_associable_choice.rb +0 -2
  30. data/lib/qti/v2/models/choices/simple_choice.rb +0 -2
  31. data/lib/qti/v2/models/interactions.rb +0 -3
  32. data/lib/qti/v2/models/interactions/ordering_interaction.rb +0 -2
  33. data/lib/qti/v2/models/non_assessment_test.rb +2 -4
  34. data/lib/qti/version.rb +1 -1
  35. data/spec/gemfiles/nokogiri-1.6.gemfile.lock +149 -0
  36. data/spec/gemfiles/nokogiri-1.8.gemfile.lock +149 -0
  37. data/spec/gemfiles/rails-5.2.gemfile.lock +222 -0
  38. data/spec/gemfiles/{rails-5.0.gemfile → rails-6.0.gemfile} +1 -1
  39. data/spec/lib/qti/assessment_item_exporter_spec.rb +17 -21
  40. data/spec/lib/qti/exporter_spec.rb +73 -81
  41. data/spec/lib/qti/models/assessment_meta_spec.rb +0 -2
  42. data/spec/lib/qti/models/base_spec.rb +20 -15
  43. data/spec/lib/qti/models/manifest_spec.rb +0 -2
  44. data/spec/lib/qti/models/metadata_spec.rb +0 -2
  45. data/spec/lib/qti/models/resource_spec.rb +0 -2
  46. data/spec/lib/qti/v1/models/assessment_item_spec.rb +9 -13
  47. data/spec/lib/qti/v1/models/assessment_spec.rb +3 -6
  48. data/spec/lib/qti/v1/models/choices/fill_blank_choice_spec.rb +0 -2
  49. data/spec/lib/qti/v1/models/choices/logical_identifier_choice_spec.rb +0 -2
  50. data/spec/lib/qti/v1/models/interactions/base_interaction_spec.rb +1 -3
  51. data/spec/lib/qti/v1/models/interactions/canvas_multiple_dropdown_spec.rb +0 -2
  52. data/spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb +0 -2
  53. data/spec/lib/qti/v1/models/interactions/fill_blank_interaction_spec.rb +0 -2
  54. data/spec/lib/qti/v1/models/interactions/formula_interaction_spec.rb +0 -2
  55. data/spec/lib/qti/v1/models/interactions/match_interaction_spec.rb +0 -2
  56. data/spec/lib/qti/v1/models/interactions/numeric_interaction_spec.rb +0 -2
  57. data/spec/lib/qti/v1/models/interactions/ordering_interaction_spec.rb +0 -2
  58. data/spec/lib/qti/v1/models/interactions/string_interaction_spec.rb +0 -2
  59. data/spec/lib/qti/v1/models/interactions/upload_interaction_spec.rb +0 -2
  60. data/spec/lib/qti/v1/models/interactions_spec.rb +0 -2
  61. data/spec/lib/qti/v1/models/numerics/exact_match_spec.rb +0 -2
  62. data/spec/lib/qti/v1/models/numerics/margin_error_spec.rb +0 -2
  63. data/spec/lib/qti/v1/models/numerics/precision_spec.rb +0 -2
  64. data/spec/lib/qti/v1/models/numerics/scoring_base_spec.rb +0 -2
  65. data/spec/lib/qti/v1/models/numerics/scoring_node_spec.rb +0 -2
  66. data/spec/lib/qti/v1/models/numerics/within_range_spec.rb +0 -2
  67. data/spec/lib/qti/v1/models/question_group_spec.rb +0 -2
  68. data/spec/lib/qti/v1/models/stimulus_item_spec.rb +0 -2
  69. data/spec/lib/qti/v2/models/assessment_item_spec.rb +0 -2
  70. data/spec/lib/qti/v2/models/assessment_test_spec.rb +1 -4
  71. data/spec/lib/qti/v2/models/choices/gap_match_choice_spec.rb +0 -2
  72. data/spec/lib/qti/v2/models/choices/simple_associable_choice_spec.rb +0 -2
  73. data/spec/lib/qti/v2/models/choices/simple_choice_spec.rb +0 -2
  74. data/spec/lib/qti/v2/models/interactions/categorization_interaction_spec.rb +0 -2
  75. data/spec/lib/qti/v2/models/interactions/choice_interaction_spec.rb +0 -2
  76. data/spec/lib/qti/v2/models/interactions/extended_text_interaction_spec.rb +0 -2
  77. data/spec/lib/qti/v2/models/interactions/gap_match_interaction_spec.rb +0 -2
  78. data/spec/lib/qti/v2/models/interactions/match_interaction_spec.rb +0 -2
  79. data/spec/lib/qti/v2/models/interactions/ordering_interaction_spec.rb +0 -2
  80. data/spec/lib/qti/v2/models/interactions/short_text_interaction_spec.rb +0 -2
  81. data/spec/lib/qti/v2/models/non_assessment_test_spec.rb +0 -2
  82. data/spec/lib/qti/v2/models/object_element_spec.rb +0 -2
  83. data/spec/lib/qti/v2/models/stimulus_item_spec.rb +0 -2
  84. data/spec/lib/qti_spec.rb +0 -2
  85. data/spec/spec_helper.rb +5 -7
  86. data/spec/support/custom_matchers.rb +0 -2
  87. metadata +70 -70
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '0369a1eaf87bdecfae0f4c08e738088d1c065ee3'
4
- data.tar.gz: 7d9672b8b3e612cd0458730e17abd25a23458763
3
+ metadata.gz: e4aee322bc3949281194bb63959f4ef4bf084d03
4
+ data.tar.gz: 782d6a831b7ec7c309781592924d1b683e6e2407
5
5
  SHA512:
6
- metadata.gz: 387299550290124d9825e0195ea6f3ba4b3bc2137d7caf75ac94908584daaf2c5b59155ae9394d47c4849dcbc1d82aeb86825c90a9932b1ce9447bb55291aeab
7
- data.tar.gz: 74f0d0de3c9e519c899e84ffadfabd0df9fde95078da77b6114273dcbed97aad1751603739aa1d27b557eef4550d1abf25fea6d7e6ea5aadd21a8dcd694fcdaa
6
+ metadata.gz: ba7ecb2c6765ed021d6ff31d90918b9dc7ce52f8ba62d107e69f52fbd896939417e7d016401bdecdc5f55bf28bfb146b1c424c7dc2819ec7331b83622107ace8
7
+ data.tar.gz: 0edb24529f59bf862e4687aa09d0a3c6e5f703c9ef4f947947de92e5dcedde7fddf8b887607b5489ba00c8755fc79638f2cc7b4d5f2b3c59e92f4f99e5233986
data/README.md CHANGED
@@ -81,7 +81,7 @@ Individual spec runs can be started like so:
81
81
 
82
82
  ```bash
83
83
  docker-compose run --rm app /bin/bash -l -c \
84
- "BUNDLE_GEMFILE=spec/gemfiles/rails-5.2.gemfile rvm-exec 2.5 rspec"
84
+ "BUNDLE_GEMFILE=spec/gemfiles/rails-6.0.gemfile rvm-exec 2.5 rspec"
85
85
  ```
86
86
 
87
87
  If you'd like to mount your git checkout within the docker container running
data/lib/qti.rb CHANGED
@@ -1,4 +1,16 @@
1
+ require 'action_view'
2
+ require 'active_support/core_ext/array/access'
3
+ require 'active_support/core_ext/string'
4
+ require 'active_support/core_ext/hash/except'
5
+ require 'active_support/core_ext/module/delegation'
6
+ require 'dry-struct'
1
7
  require 'find'
8
+ require 'mathml2latex'
9
+ require 'nokogiri'
10
+ require 'pathname'
11
+ require 'sanitize'
12
+ require 'uri'
13
+ require 'zip'
2
14
 
3
15
  module Qti
4
16
  class Importer
@@ -57,22 +69,60 @@ module Qti
57
69
  end
58
70
  end
59
71
 
60
- require 'active_support/core_ext/string'
61
- require 'active_support/core_ext/module/delegation'
72
+ # The load order of all of these is important.
73
+
74
+ require 'null_logger'
75
+
76
+ require 'qti/version'
77
+
78
+ require 'qti/assessment_item_exporter'
79
+ require 'qti/content_packaging'
80
+ require 'qti/exporter'
81
+ require 'qti/sanitizer'
82
+ require 'qti/xpath_helpers'
83
+
84
+ require 'qti/content_packaging/simple_choice'
85
+ require 'qti/content_packaging/choice_interaction'
86
+ require 'qti/content_packaging/assessment_item'
87
+ require 'qti/content_packaging/outcome_declaration'
88
+ require 'qti/content_packaging/assessment_test'
62
89
 
63
- require 'qti/models/manifest'
64
90
  require 'qti/models/base'
91
+ require 'qti/models/assessment_meta'
65
92
 
66
93
  require 'qti/v1/models/base'
67
- require 'qti/v1/models/interactions/base_interaction'
68
- require 'qti/v1/models/interactions/base_fill_blank_interaction'
69
- require 'qti/v1/models/interactions/choice_interaction'
70
-
71
94
  require 'qti/v1/models/assessment'
95
+
96
+ require 'qti/v2/models/base'
97
+ require 'qti/v2/models/assessment_test'
98
+
99
+ require 'qti/models/metadata'
100
+ require 'qti/models/resource'
101
+ require 'qti/models/manifest'
102
+
72
103
  require 'qti/v1/models/assessment_item'
73
104
  require 'qti/v1/models/choices/logical_identifier_choice'
74
105
  require 'qti/v1/models/choices/fill_blank_choice'
75
106
  require 'qti/v1/models/scoring_data'
107
+ require 'qti/v1/models/stimulus_item'
108
+ require 'qti/v1/models/question_group'
109
+
110
+ require 'qti/v1/models/interactions/base_interaction'
111
+ require 'qti/v1/models/interactions/choice_interaction'
112
+
113
+ require 'qti/v1/models/interactions/base_fill_blank_interaction'
114
+ require 'qti/v1/models/interactions/canvas_multiple_dropdown'
115
+ require 'qti/v1/models/interactions/fill_blank_interaction'
116
+ require 'qti/v1/models/interactions/formula_interaction'
117
+ require 'qti/v1/models/interactions/match_interaction'
118
+ require 'qti/v1/models/interactions/numeric_interaction'
119
+ require 'qti/v1/models/interactions/ordering_interaction'
120
+ require 'qti/v1/models/interactions/string_interaction'
121
+ require 'qti/v1/models/interactions/upload_interaction'
122
+
123
+ require 'qti/v1/models/interactions'
124
+
125
+ require 'qti/v1/models/numerics/scoring_base'
76
126
 
77
127
  require 'qti/v1/models/numerics/exact_match'
78
128
  require 'qti/v1/models/numerics/margin_error'
@@ -80,23 +130,26 @@ require 'qti/v1/models/numerics/precision'
80
130
  require 'qti/v1/models/numerics/scoring_data'
81
131
  require 'qti/v1/models/numerics/scoring_node'
82
132
  require 'qti/v1/models/numerics/within_range'
83
- require 'qti/v1/models/stimulus_item'
84
- require 'qti/v1/models/question_group'
85
133
 
86
- require 'qti/v2/models/base'
87
- require 'qti/v2/models/choices/simple_choice'
88
- require 'qti/v2/models/choices/simple_associable_choice'
89
- require 'qti/v2/models/choices/gap_match_choice'
90
134
  require 'qti/v2/models/assessment_item'
91
135
  require 'qti/v2/models/stimulus_item'
92
- require 'qti/v2/models/assessment_test'
136
+ require 'qti/v2/models/interactions'
93
137
  require 'qti/v2/models/non_assessment_test'
94
138
  require 'qti/v2/models/scoring_data'
95
139
 
96
- require 'zip'
97
- require 'qti/exporter'
140
+ require 'qti/v2/models/interactions/base_interaction'
98
141
 
99
- require 'qti/content_packaging'
100
- require 'qti/assessment_item_exporter'
142
+ require 'qti/v2/models/interactions/categorization_interaction'
143
+ require 'qti/v2/models/interactions/choice_interaction'
144
+ require 'qti/v2/models/interactions/extended_text_interaction'
145
+ require 'qti/v2/models/interactions/gap_match_interaction'
146
+ require 'qti/v2/models/interactions/match_interaction'
147
+ require 'qti/v2/models/interactions/ordering_interaction'
148
+ require 'qti/v2/models/interactions/short_text_interaction'
101
149
 
102
- require 'null_logger'
150
+ require 'qti/v2/models/interactions/match_item_tag_processors/associate_interaction_tag_processor'
151
+ require 'qti/v2/models/interactions/match_item_tag_processors/match_interaction_tag_processor'
152
+
153
+ require 'qti/v2/models/choices/simple_choice'
154
+ require 'qti/v2/models/choices/simple_associable_choice'
155
+ require 'qti/v2/models/choices/gap_match_choice'
@@ -1,5 +1,3 @@
1
- require 'dry-struct'
2
-
3
1
  module Qti
4
2
  module ContentPackaging
5
3
  module Types
@@ -7,9 +5,3 @@ module Qti
7
5
  end
8
6
  end
9
7
  end
10
-
11
- require 'qti/content_packaging/outcome_declaration'
12
- require 'qti/content_packaging/simple_choice'
13
- require 'qti/content_packaging/choice_interaction'
14
- require 'qti/content_packaging/assessment_item'
15
- require 'qti/content_packaging/assessment_test'
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/base'
2
-
3
1
  module Qti
4
2
  module Models
5
3
  class AssessmentMeta < Qti::Models::Base
@@ -1,8 +1,3 @@
1
- require 'nokogiri'
2
- require 'pathname'
3
- require 'mathml2latex'
4
- require 'qti/sanitizer'
5
-
6
1
  module Qti
7
2
  class ParseError < StandardError; end
8
3
  class SpecificationViolation < StandardError; end
@@ -1,15 +1,9 @@
1
- require 'qti/v1/models/base'
2
- require 'qti/models/assessment_meta'
3
- require 'qti/v1/models/assessment'
4
- require 'qti/v2/models/assessment_test'
5
- require 'qti/v2/models/non_assessment_test'
6
- require 'qti/models/resource'
7
-
8
1
  module Qti
9
2
  module Models
10
3
  class Manifest < Qti::Models::Base
11
4
  include Qti::Models::ResourceGroup
12
5
  include Qti::XPathHelpers
6
+
13
7
  def assessment_test(resource_id = nil)
14
8
  resource_id ||= assessment_identifiers.first
15
9
  test = assessment_from_identifier(resource_id)
@@ -52,12 +52,5 @@ module Qti
52
52
  taxon(node.xpath('imsmd:taxon')&.first, path)
53
53
  end
54
54
  end
55
-
56
- module MetaDataBase
57
- delegate :taxonpath, to: :@meta_data, allow_nil: true
58
- def metadata_from_node!(node)
59
- @meta_data ||= MetaData.new(node)
60
- end
61
- end
62
55
  end
63
56
  end
@@ -1,16 +1,10 @@
1
- require 'qti/v1/models/base'
2
- require 'qti/models/assessment_meta'
3
- require 'qti/v1/models/assessment'
4
- require 'qti/v2/models/assessment_test'
5
- require 'qti/v2/models/non_assessment_test'
6
- require 'qti/xpath_helpers'
7
- require 'qti/models/metadata'
8
-
9
1
  module Qti
10
2
  module Models
11
3
  class Resource < Qti::Models::Base
12
- include Qti::Models::MetaDataBase
13
4
  include Qti::XPathHelpers
5
+
6
+ delegate :taxonpath, to: :@metadata, allow_nil: true
7
+
14
8
  def initialize(node, parent)
15
9
  @node = node
16
10
  @parent = parent
@@ -24,7 +18,7 @@ module Qti
24
18
  end
25
19
 
26
20
  def metadata
27
- @metadata = metadata_from_node!(@node)
21
+ @metadata ||= MetaData.new(@node)
28
22
  end
29
23
 
30
24
  def canvas_metadata
@@ -1,7 +1,3 @@
1
- require 'nokogiri'
2
- require 'sanitize'
3
- require 'uri'
4
-
5
1
  module Qti
6
2
  class Sanitizer
7
3
  ELEMENTS_REMAP = {
@@ -1,11 +1,9 @@
1
- require 'qti/v1/models/base'
2
- require 'qti/models/assessment_meta'
3
-
4
1
  module Qti
5
2
  module V1
6
3
  module Models
7
4
  class Assessment < Qti::V1::Models::Base
8
5
  include Qti::Models::AssessmentMetaBase
6
+
9
7
  GROUP_ID = 'xmlns:section/xmlns:selection_ordering'.freeze
10
8
 
11
9
  def title
@@ -1,6 +1,3 @@
1
- require 'qti/v1/models/base'
2
- require 'qti/v1/models/interactions'
3
-
4
1
  module Qti
5
2
  module V1
6
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/models/base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -1,7 +1,3 @@
1
- require 'active_support/core_ext/hash/except'
2
- # Populate the subclasses
3
- Dir["#{__dir__}/interactions/*.rb"].each { |f| load f }
4
-
5
1
  module Qti
6
2
  module V1
7
3
  module Models
@@ -3,7 +3,7 @@ module Qti
3
3
  module Models
4
4
  module Interactions
5
5
  class BaseFillBlankInteraction < BaseInteraction
6
- CANVAS_REGEX ||= /(\[.+?\])/
6
+ CANVAS_REGEX ||= /(\[.+?\])/.freeze
7
7
 
8
8
  def canvas_stem_items(item_prompt)
9
9
  item_prompt.split(CANVAS_REGEX).map.with_index do |stem_item, index|
@@ -37,13 +37,11 @@ module Qti
37
37
  end
38
38
 
39
39
  def answer_tolerance
40
- @answer_tolernance ||= @node.at_xpath('.//xmlns:answer_tolerance').text
40
+ @answer_tolerance ||= @node.at_xpath('.//xmlns:answer_tolerance').text
41
41
  end
42
42
 
43
43
  def margin_of_error
44
- if answer_tolerance.ends_with? '%'
45
- return { margin: answer_tolerance[0..-2], margin_type: 'percent' }
46
- end
44
+ return { margin: answer_tolerance[0..-2], margin_type: 'percent' } if answer_tolerance.ends_with? '%'
47
45
  { margin: answer_tolerance, margin_type: 'absolute' }
48
46
  end
49
47
 
@@ -26,7 +26,7 @@ module Qti
26
26
  end
27
27
 
28
28
  def scoring_data_structs
29
- @scoring_data ||= parse_scoring_data
29
+ @scoring_data_structs ||= parse_scoring_data
30
30
  end
31
31
 
32
32
  def distractors
@@ -38,7 +38,7 @@ module Qti
38
38
  private
39
39
 
40
40
  def parse_scoring_data
41
- # This preserves the original behavior while not breaking on itemfeedback
41
+ # This preserves the original behavior while not breaking on item feedback
42
42
  path = './/xmlns:respcondition/xmlns:setvar/../xmlns:conditionvar/xmlns:varequal'
43
43
  matches = node.xpath(path).map do |node|
44
44
  [node.attributes['respident'].value, answers_map[node.content]]
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/numerics/scoring_base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/numerics/scoring_base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/numerics/scoring_base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -55,7 +53,7 @@ module Qti
55
53
  end
56
54
  # this is not exactly significant digits
57
55
  # trailing zeros are ignored
58
- # because gt_node and lte_ndoe don't expect trailing zeros
56
+ # because gt_node and lte_node don't expect trailing zeros
59
57
  sig
60
58
  end
61
59
  end
@@ -1,5 +1,3 @@
1
- require 'qti/v1/models/numerics/scoring_base'
2
-
3
1
  module Qti
4
2
  module V1
5
3
  module Models
@@ -1,6 +1,3 @@
1
- require 'qti/v1/models/base'
2
- require 'qti/v1/models/interactions'
3
-
4
1
  module Qti
5
2
  module V1
6
3
  module Models
@@ -1,6 +1,3 @@
1
- require 'qti/v2/models/base'
2
- require 'qti/v2/models/interactions'
3
-
4
1
  module Qti
5
2
  module V2
6
3
  module Models
@@ -1,20 +1,17 @@
1
- require 'qti/v2/models/base'
2
- require 'qti/models/assessment_meta'
3
- require 'qti/xpath_helpers'
4
-
5
1
  module Qti
6
2
  module V2
7
3
  module Models
8
4
  class AssessmentTest < Qti::V2::Models::Base
9
5
  include Qti::Models::AssessmentMetaBase
10
6
  include Qti::XPathHelpers
7
+
11
8
  def title
12
9
  @title ||= xpath_with_single_check('//xmlns:assessmentTest/@title')&.content || File.basename(@path, '.xml')
13
10
  end
14
11
 
15
12
  def assessment_items
16
13
  # Return the xml files we should be parsing
17
- @assessment_item_reference_hrefs ||= begin
14
+ @assessment_items ||= begin
18
15
  @doc.xpath('//xmlns:assessmentItemRef/@href').map(&:content).map do |href|
19
16
  { path: remap_href_path(href), resource: self }
20
17
  end
@@ -1,5 +1,3 @@
1
- require 'qti/models/base'
2
-
3
1
  module Qti
4
2
  module V2
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v2/models/base'
2
-
3
1
  module Qti
4
2
  module V2
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v2/models/base'
2
-
3
1
  module Qti
4
2
  module V2
5
3
  module Models
@@ -1,5 +1,3 @@
1
- require 'qti/v2/models/base'
2
-
3
1
  module Qti
4
2
  module V2
5
3
  module Models