qti 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1aabd1fcd54402b41afeebc7bc69be6c86390a52
4
- data.tar.gz: c2bed919eed81aeba3b0cb8f753c79f5d0f68be6
3
+ metadata.gz: b0b2571404f88af47659de553891bc760d1ee13f
4
+ data.tar.gz: 8e68acc2256a603807a42b04ad34277e92f92225
5
5
  SHA512:
6
- metadata.gz: afeb012f7304d7952fe6f615eb8ddc74ab202f18ea9dcf012a3180d7b5ddbdd73c034eea72887c77382b49cc33d2bd558b6bfc209faa44d4d0fcf4ac2a7c16a6
7
- data.tar.gz: 2ebe901bb7779a0cd972b54ad7108f59847361e47ae6c8964ba96dd10a707686174cfc719adf0ded99d0e5324a733442fee69b9a1a0ac91c4c1a4ca8123345ed
6
+ metadata.gz: 9f939252ce6df39c30b75757648bb5350397a8e8e1f81584f906b15ab00578e48f8ddfea4bbba47e53c5a8862a796137ee65dd17a29ec64f3f942d0b50789821
7
+ data.tar.gz: 6c068d7a32c9d741e3f2f9f7a5f18541b6d4ece8f774409989aca382e57d4aa3c68dd57c0522698bb0fe7086e6ede024b8db3bd7aa2c67173b0474f5e4687dfc
@@ -15,6 +15,10 @@ module Qti
15
15
  @node.attributes['ident']&.value
16
16
  end
17
17
 
18
+ def parent_identifier
19
+ @parent_identifier ||= @node.parent.parent.attributes['ident']&.value
20
+ end
21
+
18
22
  def item_body
19
23
  @item_body ||= begin
20
24
  node = @node.dup
@@ -9,6 +9,12 @@ module Qti
9
9
  false
10
10
  end
11
11
 
12
+ def self.canvas_multiple_fib?(node)
13
+ matches = node.xpath('.//xmlns:response_lid')
14
+ return false if matches.count <= 1
15
+ node.at_xpath('.//xmlns:fieldentry').text == "fill_in_multiple_blanks_question"
16
+ end
17
+
12
18
  def initialize(node, parent)
13
19
  @node = node
14
20
  copy_paths_from_item(parent)
@@ -3,16 +3,64 @@ module Qti
3
3
  module Models
4
4
  module Interactions
5
5
  class FillBlankInteraction < BaseInteraction
6
+ CANVAS_REGEX = /(\[.+?\])/.freeze
7
+
6
8
  # This will know if a class matches
7
9
  def self.matches(node, parent)
8
- return false if node.xpath('.//xmlns:other').present?
9
- matches = node.xpath('.//xmlns:render_fib')
10
- return false if matches.empty? ||
11
- matches.first.attributes['fibtype']&.value == 'Decimal'
10
+ return false if node.at_xpath('.//xmlns:other').present?
11
+ match = if BaseInteraction.canvas_multiple_fib?(node)
12
+ node.at_xpath('.//xmlns:response_lid')
13
+ else
14
+ node.at_xpath('.//xmlns:render_fib')
15
+ end
16
+ return false if match.blank? ||
17
+ match.attributes['fibtype']&.value == 'Decimal'
12
18
  new(node, parent)
13
19
  end
14
20
 
21
+ def canvas_multiple_fib?
22
+ BaseInteraction.canvas_multiple_fib?(@node)
23
+ end
24
+
15
25
  def stem_items
26
+ if canvas_multiple_fib?
27
+ canvas_stem_items
28
+ else
29
+ qti_stem_items
30
+ end
31
+ end
32
+
33
+ def canvas_stem_items
34
+ @response_lid_nodes = node.xpath('.//xmlns:response_lid')
35
+ item_prompt = node.at_xpath('.//xmlns:mattext').text
36
+ item_prompt_words = item_prompt.split(CANVAS_REGEX)
37
+ item_prompt_words.map.with_index do |stem_item, index|
38
+ if stem_item.match CANVAS_REGEX
39
+ @response_lid_nodes.children.map do |response_lid_node|
40
+ if stem_item.include?(response_lid_node.text)
41
+ @blank_id = response_lid_node.parent.attributes['ident']&.value
42
+ end
43
+ end
44
+
45
+ {
46
+ id: "stem_#{index}",
47
+ position: index + 1,
48
+ type: 'blank',
49
+ blank_id: @blank_id
50
+ }
51
+ else
52
+ {
53
+ id: "stem_#{index}",
54
+ position: index + 1,
55
+ type: 'text',
56
+ value: stem_item
57
+ }
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ def qti_stem_items
16
64
  stem_item_nodes = node.xpath('.//xmlns:presentation').children
17
65
  stem_item_nodes.map.with_index do |stem_item, index|
18
66
  if stem_item.xpath('./xmlns:render_fib').present?
@@ -38,8 +86,22 @@ module Qti
38
86
  end
39
87
 
40
88
  def blanks
89
+ if node.at_xpath('.//xmlns:render_choice').present?
90
+ canvas_blanks
91
+ else
92
+ qti_standard_blanks
93
+ end
94
+ end
95
+
96
+ def canvas_blanks
97
+ node.xpath('.//xmlns:response_label').map do |blank|
98
+ { id: blank.attributes['ident']&.value }
99
+ end
100
+ end
101
+
102
+ def qti_standard_blanks
41
103
  node.xpath('.//xmlns:response_str').map do |blank|
42
- { id: blank.attributes['ident'].value }
104
+ { id: blank.attributes['ident']&.value }
43
105
  end
44
106
  end
45
107
 
@@ -54,8 +116,9 @@ module Qti
54
116
  ScoringData.new(
55
117
  value_node.content,
56
118
  rcardinality,
57
- id: value_node.attributes['respident']&.value,
58
- case: value_node.attributes['case']&.value || 'no'
119
+ id: value_node.attributes['respident']&.value || value_node.attributes['ident']&.value,
120
+ case: value_node.attributes['case']&.value || 'no',
121
+ parent_identifier: value_node.parent.parent.attributes['ident']&.value,
59
122
  )
60
123
  end
61
124
  end
@@ -68,7 +131,11 @@ module Qti
68
131
  end
69
132
 
70
133
  def answer_nodes
71
- @node.xpath('.//xmlns:varequal')
134
+ if canvas_multiple_fib?
135
+ @node.xpath('.//xmlns:response_label')
136
+ else
137
+ @node.xpath('.//xmlns:varequal')
138
+ end
72
139
  end
73
140
  end
74
141
  end
@@ -4,6 +4,7 @@ module Qti
4
4
  module Interactions
5
5
  class MatchInteraction < BaseInteraction
6
6
  def self.matches(node, parent)
7
+ return false if canvas_multiple_fib?(node)
7
8
  matches = node.xpath('.//xmlns:response_lid')
8
9
  return false if matches.count <= 1
9
10
  new(node, parent)
@@ -1,9 +1,9 @@
1
1
  module Qti
2
2
  module V1
3
3
  module Models
4
- ScoringData = Struct.new(:values, :rcardinality, :id, :case) do
4
+ ScoringData = Struct.new(:values, :rcardinality, :id, :case, :parent_identifier) do
5
5
  def initialize(values, rcardinality, options = {})
6
- super(values, rcardinality, options[:id], options[:case])
6
+ super(values, rcardinality, options[:id], options[:case], options[:parent_identifier])
7
7
  end
8
8
  end
9
9
  end
@@ -1,3 +1,3 @@
1
1
  module Qti
2
- VERSION = '0.9.7'.freeze
2
+ VERSION = '0.9.8'.freeze
3
3
  end
@@ -0,0 +1,77 @@
1
+ <?xml version="1.0" encoding="ISO-8859-1"?>
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
+ <item ident="i54cc67bc8ce2e7d19edd187803a28f7d" title="Fill in Multiple Blanks">
4
+ <itemmetadata>
5
+ <qtimetadata>
6
+ <qtimetadatafield>
7
+ <fieldlabel>question_type</fieldlabel>
8
+ <fieldentry>fill_in_multiple_blanks_question</fieldentry>
9
+ </qtimetadatafield>
10
+ <qtimetadatafield>
11
+ <fieldlabel>points_possible</fieldlabel>
12
+ <fieldentry>1.0</fieldentry>
13
+ </qtimetadatafield>
14
+ <qtimetadatafield>
15
+ <fieldlabel>assessment_question_identifierref</fieldlabel>
16
+ <fieldentry>i110040ca4c30b713a4a98bcf21907ff7</fieldentry>
17
+ </qtimetadatafield>
18
+ </qtimetadata>
19
+ </itemmetadata>
20
+ <presentation>
21
+ <material>
22
+ <mattext texttype="text/html">&lt;div&gt;&lt;p&gt;&lt;span&gt;Roses are [color1], violets are [color2]&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;</mattext>
23
+ </material>
24
+ <response_lid ident="response_color1">
25
+ <material>
26
+ <mattext>color1</mattext>
27
+ </material>
28
+ <render_choice>
29
+ <response_label ident="9799">
30
+ <material>
31
+ <mattext texttype="text/plain">red</mattext>
32
+ </material>
33
+ </response_label>
34
+ <response_label ident="5231">
35
+ <material>
36
+ <mattext texttype="text/plain">Red</mattext>
37
+ </material>
38
+ </response_label>
39
+ </render_choice>
40
+ </response_lid>
41
+ <response_lid ident="response_color2">
42
+ <material>
43
+ <mattext>color2</mattext>
44
+ </material>
45
+ <render_choice>
46
+ <response_label ident="5939">
47
+ <material>
48
+ <mattext texttype="text/plain">blue</mattext>
49
+ </material>
50
+ </response_label>
51
+ <response_label ident="6364">
52
+ <material>
53
+ <mattext texttype="text/plain">Blue</mattext>
54
+ </material>
55
+ </response_label>
56
+ </render_choice>
57
+ </response_lid>
58
+ </presentation>
59
+ <resprocessing>
60
+ <outcomes>
61
+ <decvar maxvalue="100" minvalue="0" varname="SCORE" vartype="Decimal"/>
62
+ </outcomes>
63
+ <respcondition>
64
+ <conditionvar>
65
+ <varequal respident="response_color1">9799</varequal>
66
+ </conditionvar>
67
+ <setvar varname="SCORE" action="Add">50.00</setvar>
68
+ </respcondition>
69
+ <respcondition>
70
+ <conditionvar>
71
+ <varequal respident="response_color2">5939</varequal>
72
+ </conditionvar>
73
+ <setvar varname="SCORE" action="Add">50.00</setvar>
74
+ </respcondition>
75
+ </resprocessing>
76
+ </item>
77
+ </questestinterop>
@@ -0,0 +1,127 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ qti (0.9.3)
5
+ activesupport (>= 4.2.9, < 5.2)
6
+ dry-struct (~> 0.2.1)
7
+ dry-types (~> 0.12.0)
8
+ nokogiri (>= 1.6.8, < 1.9)
9
+ rubyzip (~> 1.2)
10
+ sanitize (>= 4.2.0, < 5.0)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ activesupport (5.1.4)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (~> 0.7)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ ast (2.3.0)
21
+ byebug (9.1.0)
22
+ coderay (1.1.2)
23
+ concurrent-ruby (1.0.5)
24
+ crass (1.0.2)
25
+ diff-lcs (1.3)
26
+ docile (1.1.5)
27
+ dry-configurable (0.7.0)
28
+ concurrent-ruby (~> 1.0)
29
+ dry-container (0.6.0)
30
+ concurrent-ruby (~> 1.0)
31
+ dry-configurable (~> 0.1, >= 0.1.3)
32
+ dry-core (0.3.4)
33
+ concurrent-ruby (~> 1.0)
34
+ dry-equalizer (0.2.0)
35
+ dry-logic (0.4.2)
36
+ dry-container (~> 0.2, >= 0.2.6)
37
+ dry-core (~> 0.2)
38
+ dry-equalizer (~> 0.2)
39
+ dry-struct (0.2.1)
40
+ dry-configurable (~> 0.1)
41
+ dry-equalizer (~> 0.2)
42
+ dry-types (~> 0.9, >= 0.9.0)
43
+ ice_nine (~> 0.11)
44
+ dry-types (0.12.0)
45
+ concurrent-ruby (~> 1.0)
46
+ dry-configurable (~> 0.1)
47
+ dry-container (~> 0.3)
48
+ dry-core (~> 0.2, >= 0.2.1)
49
+ dry-equalizer (~> 0.2)
50
+ dry-logic (~> 0.4, >= 0.4.2)
51
+ inflecto (~> 0.0.0, >= 0.0.2)
52
+ i18n (0.8.6)
53
+ ice_nine (0.11.2)
54
+ inflecto (0.0.2)
55
+ json (2.1.0)
56
+ method_source (0.9.0)
57
+ mini_portile2 (2.1.0)
58
+ minitest (5.10.3)
59
+ nokogiri (1.6.8.1)
60
+ mini_portile2 (~> 2.1.0)
61
+ nokogumbo (1.4.13)
62
+ nokogiri
63
+ parallel (1.12.0)
64
+ parser (2.4.0.0)
65
+ ast (~> 2.2)
66
+ powerpack (0.1.1)
67
+ pry (0.11.1)
68
+ coderay (~> 1.1.0)
69
+ method_source (~> 0.9.0)
70
+ rainbow (2.2.2)
71
+ rake
72
+ rake (0.9.6)
73
+ rspec (3.6.0)
74
+ rspec-core (~> 3.6.0)
75
+ rspec-expectations (~> 3.6.0)
76
+ rspec-mocks (~> 3.6.0)
77
+ rspec-core (3.6.0)
78
+ rspec-support (~> 3.6.0)
79
+ rspec-expectations (3.6.0)
80
+ diff-lcs (>= 1.2.0, < 2.0)
81
+ rspec-support (~> 3.6.0)
82
+ rspec-mocks (3.6.0)
83
+ diff-lcs (>= 1.2.0, < 2.0)
84
+ rspec-support (~> 3.6.0)
85
+ rspec-support (3.6.0)
86
+ rubocop (0.50.0)
87
+ parallel (~> 1.10)
88
+ parser (>= 2.3.3.1, < 3.0)
89
+ powerpack (~> 0.1)
90
+ rainbow (>= 2.2.2, < 3.0)
91
+ ruby-progressbar (~> 1.7)
92
+ unicode-display_width (~> 1.0, >= 1.0.1)
93
+ ruby-progressbar (1.8.3)
94
+ rubyzip (1.2.1)
95
+ sanitize (4.5.0)
96
+ crass (~> 1.0.2)
97
+ nokogiri (>= 1.4.4)
98
+ nokogumbo (~> 1.4.1)
99
+ simplecov (0.15.1)
100
+ docile (~> 1.1.0)
101
+ json (>= 1.8, < 3)
102
+ simplecov-html (~> 0.10.0)
103
+ simplecov-html (0.10.2)
104
+ thread_safe (0.3.6)
105
+ tzinfo (1.2.3)
106
+ thread_safe (~> 0.1)
107
+ unicode-display_width (1.3.0)
108
+ wwtd (1.3.0)
109
+
110
+ PLATFORMS
111
+ ruby
112
+
113
+ DEPENDENCIES
114
+ bundler (~> 1.15)
115
+ byebug (~> 9.0)
116
+ nokogiri (~> 1.6.8)
117
+ pry (~> 0)
118
+ qti!
119
+ rake (~> 0)
120
+ rspec (~> 3.6)
121
+ rspec-mocks (~> 3.6)
122
+ rubocop (~> 0.50.0)
123
+ simplecov (~> 0)
124
+ wwtd (~> 1.3)
125
+
126
+ BUNDLED WITH
127
+ 1.15.4
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- qti (0.9.7)
4
+ qti (0.9.8)
5
5
  activesupport (>= 4.2.9, < 5.2)
6
6
  dry-struct (~> 0.2.1)
7
7
  dry-types (~> 0.12.0)
@@ -61,29 +61,29 @@ GEM
61
61
  mini_portile2 (~> 2.3.0)
62
62
  nokogumbo (1.4.13)
63
63
  nokogiri
64
- parallel (1.12.1)
65
- parser (2.4.0.2)
66
- ast (~> 2.3)
64
+ parallel (1.12.0)
65
+ parser (2.4.0.0)
66
+ ast (~> 2.2)
67
67
  powerpack (0.1.1)
68
- pry (0.11.3)
68
+ pry (0.11.1)
69
69
  coderay (~> 1.1.0)
70
70
  method_source (~> 0.9.0)
71
71
  rainbow (2.2.2)
72
72
  rake
73
73
  rake (0.9.6)
74
- rspec (3.7.0)
75
- rspec-core (~> 3.7.0)
76
- rspec-expectations (~> 3.7.0)
77
- rspec-mocks (~> 3.7.0)
78
- rspec-core (3.7.0)
79
- rspec-support (~> 3.7.0)
80
- rspec-expectations (3.7.0)
74
+ rspec (3.6.0)
75
+ rspec-core (~> 3.6.0)
76
+ rspec-expectations (~> 3.6.0)
77
+ rspec-mocks (~> 3.6.0)
78
+ rspec-core (3.6.0)
79
+ rspec-support (~> 3.6.0)
80
+ rspec-expectations (3.6.0)
81
81
  diff-lcs (>= 1.2.0, < 2.0)
82
- rspec-support (~> 3.7.0)
83
- rspec-mocks (3.7.0)
82
+ rspec-support (~> 3.6.0)
83
+ rspec-mocks (3.6.0)
84
84
  diff-lcs (>= 1.2.0, < 2.0)
85
- rspec-support (~> 3.7.0)
86
- rspec-support (3.7.0)
85
+ rspec-support (~> 3.6.0)
86
+ rspec-support (3.6.0)
87
87
  rubocop (0.50.0)
88
88
  parallel (~> 1.10)
89
89
  parser (>= 2.3.3.1, < 3.0)
@@ -91,7 +91,7 @@ GEM
91
91
  rainbow (>= 2.2.2, < 3.0)
92
92
  ruby-progressbar (~> 1.7)
93
93
  unicode-display_width (~> 1.0, >= 1.0.1)
94
- ruby-progressbar (1.9.0)
94
+ ruby-progressbar (1.8.3)
95
95
  rubyzip (1.2.1)
96
96
  sanitize (4.5.0)
97
97
  crass (~> 1.0.2)
@@ -125,4 +125,4 @@ DEPENDENCIES
125
125
  wwtd (~> 1.3)
126
126
 
127
127
  BUNDLED WITH
128
- 1.16.0
128
+ 1.15.4