qti 0.9.0 → 0.9.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.
- checksums.yaml +4 -4
- data/lib/null_logger.rb +2 -4
- data/lib/qti/models/base.rb +8 -10
- data/lib/qti/models/manifest.rb +4 -8
- data/lib/qti/v1/models/assessment.rb +4 -4
- data/lib/qti/v1/models/assessment_item.rb +2 -2
- data/lib/qti/v1/models/choices/fill_blank_choice.rb +1 -1
- data/lib/qti/v1/models/interactions/base_interaction.rb +1 -1
- data/lib/qti/v1/models/interactions/choice_interaction.rb +1 -1
- data/lib/qti/v1/models/interactions/fill_blank_interaction.rb +6 -7
- data/lib/qti/v1/models/interactions/ordering_interaction.rb +1 -1
- data/lib/qti/v1/models/scoring_data.rb +1 -1
- data/lib/qti/v2/models/assessment_item.rb +1 -1
- data/lib/qti/v2/models/assessment_test.rb +3 -3
- data/lib/qti/v2/models/base.rb +6 -6
- data/lib/qti/v2/models/choices/simple_choice.rb +1 -1
- data/lib/qti/v2/models/interactions/base_interaction.rb +1 -1
- data/lib/qti/v2/models/interactions/categorization_interaction.rb +1 -1
- data/lib/qti/v2/models/interactions/gap_match_interaction.rb +8 -12
- data/lib/qti/v2/models/interactions/match_interaction.rb +2 -2
- data/lib/qti/v2/models/non_assessment_test.rb +2 -2
- data/lib/qti/v2/models/scoring_data.rb +1 -1
- data/lib/qti/v2/models/stimulus_item.rb +0 -1
- data/lib/qti/version.rb +1 -1
- data/spec/gemfiles/nokogiri-1.6.gemfile.lock +126 -0
- data/spec/gemfiles/nokogiri-1.8.gemfile.lock +126 -0
- data/spec/gemfiles/rails-4.2.gemfile.lock +203 -0
- data/spec/gemfiles/rails-5.0.gemfile.lock +209 -0
- data/spec/gemfiles/rails-5.1.gemfile.lock +209 -0
- data/spec/gemfiles/sanitize-4.2.gemfile.lock +126 -0
- data/spec/gemfiles/sanitize-4.5.gemfile.lock +126 -0
- data/spec/lib/qti/models/base_spec.rb +10 -10
- data/spec/lib/qti/models/manifest_spec.rb +0 -1
- data/spec/lib/qti/v1/models/assessment_spec.rb +7 -8
- data/spec/lib/qti/v1/models/choices/fill_blank_choice_spec.rb +1 -1
- data/spec/lib/qti/v1/models/choices/logical_identifier_choice_spec.rb +1 -1
- data/spec/lib/qti/v1/models/interactions/fill_blank_interaction_spec.rb +15 -13
- data/spec/lib/qti/v1/models/interactions/ordering_interaction_spec.rb +1 -1
- data/spec/lib/qti/v2/models/assessment_item_spec.rb +3 -3
- data/spec/lib/qti/v2/models/assessment_test_spec.rb +6 -7
- data/spec/lib/qti/v2/models/choices/gap_match_choice_spec.rb +1 -1
- data/spec/lib/qti/v2/models/choices/simple_associable_choice_spec.rb +8 -8
- data/spec/lib/qti/v2/models/choices/simple_choice_spec.rb +1 -1
- data/spec/lib/qti/v2/models/interactions/categorization_interaction_spec.rb +3 -3
- data/spec/lib/qti/v2/models/interactions/gap_match_interaction_spec.rb +24 -23
- data/spec/lib/qti/v2/models/interactions/ordering_interaction_spec.rb +1 -1
- data/spec/lib/qti/v2/models/interactions/short_text_interaction_spec.rb +1 -1
- data/spec/lib/qti/v2/models/non_assessment_test_spec.rb +1 -1
- data/spec/lib/qti/v2/models/object_element_spec.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 202d9ba3ef99c4e0df030cf13a8e25f4e19441c2
|
4
|
+
data.tar.gz: 077f7118e61d94d1d7796494e481355e0b399833
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6119e426a2f6c4b91cfb84ac7da7ca78317490439c0ace3ec067fc65ffa1b8b929979dfa76a4cb648b9d44781e5cb55d38490c89151ab1e66581c9315c8b88ff
|
7
|
+
data.tar.gz: 76f7caf87c7c9efd299b770d2adfcfa5737991dbaa3b2ee450616d0ae987bac40bd2a362932769f462006e80a11b40b4cb00c249cf48b1565c70fa50b71d559e
|
data/lib/null_logger.rb
CHANGED
data/lib/qti/models/base.rb
CHANGED
@@ -113,7 +113,7 @@ module Qti
|
|
113
113
|
case node[:type]
|
114
114
|
when /^image\//
|
115
115
|
return replace_with_image(node, node[:data])
|
116
|
-
when
|
116
|
+
when 'text/html'
|
117
117
|
return replace_with_html(node, path)
|
118
118
|
end
|
119
119
|
end
|
@@ -127,15 +127,13 @@ module Qti
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def replace_with_html(node, path)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
node.unlink
|
138
|
-
end
|
130
|
+
content = File.read(path)
|
131
|
+
html_content = Sanitize.fragment(content, sanitize_config(import_objects: false))
|
132
|
+
node.name = 'div'
|
133
|
+
node.add_child(Nokogiri::HTML.fragment(html_content))
|
134
|
+
rescue StandardError => e
|
135
|
+
warn "failed to import html object #{path}: #{e.message}"
|
136
|
+
node.unlink
|
139
137
|
end
|
140
138
|
end
|
141
139
|
end
|
data/lib/qti/models/manifest.rb
CHANGED
@@ -3,29 +3,25 @@ require 'qti/v1/models/base'
|
|
3
3
|
module Qti
|
4
4
|
module Models
|
5
5
|
class Manifest < Qti::Models::Base
|
6
|
-
|
7
6
|
def assessment_test
|
8
7
|
qti_2_x_href || qti_1_href || qti_2_non_assessment_href || unknown_type
|
9
8
|
end
|
10
9
|
|
11
10
|
def qti_1_href
|
12
11
|
test_path = xpath_with_single_check("//xmlns:resources/xmlns:resource[@type='imsqti_xmlv1p2']/@href")&.content ||
|
13
|
-
|
12
|
+
xpath_with_single_check("//xmlns:resources/xmlns:resource[@type='imsqti_xmlv1p2']/xmlns:file/@href")&.content
|
14
13
|
Qti::V1::Models::Assessment.from_path!(remap_href_path(test_path), @package_root) if test_path
|
15
14
|
end
|
16
15
|
|
17
16
|
def qti_2_x_href
|
18
17
|
test_path = xpath_with_single_check("//xmlns:resources/xmlns:resource[@type='imsqti_test_xmlv2p1']/@href")&.content ||
|
19
|
-
|
18
|
+
xpath_with_single_check("//xmlns:resources/xmlns:resource[@type='imsqti_test_xmlv2p2']/@href")&.content
|
20
19
|
Qti::V2::Models::AssessmentTest.from_path!(remap_href_path(test_path), @package_root) if test_path
|
21
20
|
end
|
22
21
|
|
23
22
|
def qti_2_non_assessment_href
|
24
|
-
|
25
|
-
|
26
|
-
# use imsmanifest.xml as the assessment XML if there is no assessment xml
|
27
|
-
Qti::V2::Models::NonAssessmentTest.from_path!(@path, @package_root)
|
28
|
-
end
|
23
|
+
item_path = @doc.at_xpath("//xmlns:resources/xmlns:resource[@type='imsqti_item_xmlv2p1']/@href")&.content
|
24
|
+
Qti::V2::Models::NonAssessmentTest.from_path!(@path, @package_root) if item_path
|
29
25
|
end
|
30
26
|
|
31
27
|
def unknown_type
|
@@ -16,12 +16,12 @@ module Qti
|
|
16
16
|
Qti::V1::Models::AssessmentItem.new(assessment_item, @package_root)
|
17
17
|
end
|
18
18
|
|
19
|
-
def stimulus_ref(
|
20
|
-
|
19
|
+
def stimulus_ref(_ref)
|
20
|
+
nil
|
21
21
|
end
|
22
22
|
|
23
|
-
def create_stimulus(
|
24
|
-
raise
|
23
|
+
def create_stimulus(_stimulus)
|
24
|
+
raise 'Stimulus type not supported for QTI version'
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -36,7 +36,7 @@ module Qti
|
|
36
36
|
|
37
37
|
def has_points_possible_qti_metadata?
|
38
38
|
if @doc.at_xpath('.//xmlns:qtimetadata').present?
|
39
|
-
points_possible_label = qti_metadata_children.children.find {|node| node.text ==
|
39
|
+
points_possible_label = qti_metadata_children.children.find { |node| node.text == 'points_possible' }
|
40
40
|
points_possible_label.present?
|
41
41
|
else
|
42
42
|
false
|
@@ -46,7 +46,7 @@ module Qti
|
|
46
46
|
def points_possible
|
47
47
|
@points_possible ||= begin
|
48
48
|
if has_points_possible_qti_metadata?
|
49
|
-
points_possible_label = qti_metadata_children.children.find {|node| node.text ==
|
49
|
+
points_possible_label = qti_metadata_children.children.find { |node| node.text == 'points_possible' }
|
50
50
|
points_possible_node = points_possible_label.next.text
|
51
51
|
else
|
52
52
|
decvar_maxvalue
|
@@ -6,7 +6,7 @@ module Qti
|
|
6
6
|
# This will know if a class matches
|
7
7
|
def self.matches(node, parent)
|
8
8
|
matches = node.xpath('.//xmlns:response_lid')
|
9
|
-
return false if matches.count > 1
|
9
|
+
return false if matches.count > 1 || matches.empty?
|
10
10
|
rcardinality = matches.first.attributes['rcardinality']&.value || 'Single'
|
11
11
|
return false if rcardinality == 'Ordered'
|
12
12
|
new(node, parent)
|
@@ -45,22 +45,21 @@ module Qti
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def scoring_data_structs
|
48
|
-
answer_nodes.map
|
48
|
+
answer_nodes.map do |value_node|
|
49
|
+
ScoringData.new(
|
49
50
|
value_node.content,
|
50
51
|
rcardinality,
|
51
|
-
|
52
|
-
|
53
|
-
case: value_node.attributes['case']&.value || 'no'
|
54
|
-
}
|
52
|
+
id: value_node.attributes['respident']&.value,
|
53
|
+
case: value_node.attributes['case']&.value || 'no'
|
55
54
|
)
|
56
|
-
|
55
|
+
end
|
57
56
|
end
|
58
57
|
|
59
58
|
private
|
60
59
|
|
61
60
|
def rcardinality
|
62
61
|
@rcardinality ||= @node.at_xpath('.//xmlns:response_str/@rcardinality')&.value ||
|
63
|
-
|
62
|
+
@node.at_xpath('.//xmlns:response_num/@rcardinality')&.value
|
64
63
|
end
|
65
64
|
|
66
65
|
def answer_nodes
|
@@ -6,7 +6,7 @@ module Qti
|
|
6
6
|
# This will know if a class matches
|
7
7
|
def self.matches(node, parent)
|
8
8
|
matches = node.xpath('.//xmlns:response_lid')
|
9
|
-
return false if matches.count > 1
|
9
|
+
return false if matches.count > 1 || matches.empty?
|
10
10
|
rcardinality = matches.first.attributes['rcardinality']&.value || 'Single'
|
11
11
|
return false if rcardinality != 'Ordered'
|
12
12
|
new(node, parent)
|
@@ -2,7 +2,7 @@ module Qti
|
|
2
2
|
module V1
|
3
3
|
module Models
|
4
4
|
ScoringData = Struct.new(:values, :rcardinality, :id, :case) do
|
5
|
-
def initialize(values, rcardinality, options={})
|
5
|
+
def initialize(values, rcardinality, options = {})
|
6
6
|
super(values, rcardinality, options[:id], options[:case])
|
7
7
|
end
|
8
8
|
end
|
@@ -35,7 +35,7 @@ module Qti
|
|
35
35
|
def points_possible
|
36
36
|
@points_possible ||= begin
|
37
37
|
xpath_with_single_check("//xmlns:outcomeDeclaration[@identifier='SCORE']/@normalMaximum")&.content ||
|
38
|
-
|
38
|
+
xpath_with_single_check("//xmlns:outcomeDeclaration[@identifier='MAXSCORE']//xmlns:value")&.content
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -5,7 +5,7 @@ module Qti
|
|
5
5
|
module Models
|
6
6
|
class AssessmentTest < Qti::V2::Models::Base
|
7
7
|
def title
|
8
|
-
@title ||= xpath_with_single_check('//xmlns:assessmentTest/@title')&.content || File.basename(@path,
|
8
|
+
@title ||= xpath_with_single_check('//xmlns:assessmentTest/@title')&.content || File.basename(@path, '.xml')
|
9
9
|
end
|
10
10
|
|
11
11
|
def assessment_items
|
@@ -29,8 +29,8 @@ module Qti
|
|
29
29
|
Qti::V2::Models::AssessmentItem.from_path!(assessment_item_ref, @package_root)
|
30
30
|
end
|
31
31
|
|
32
|
-
def stimulus_ref(
|
33
|
-
|
32
|
+
def stimulus_ref(_ref)
|
33
|
+
nil
|
34
34
|
end
|
35
35
|
|
36
36
|
def create_stimulus(stimulus_ref)
|
data/lib/qti/v2/models/base.rb
CHANGED
@@ -4,7 +4,7 @@ module Qti
|
|
4
4
|
module V2
|
5
5
|
module Models
|
6
6
|
class Base < Qti::Models::Base
|
7
|
-
BODY_ELEMENTS_CSS = %w
|
7
|
+
BODY_ELEMENTS_CSS = %w[
|
8
8
|
atomicBlock
|
9
9
|
atomicInline
|
10
10
|
caption
|
@@ -33,9 +33,9 @@ module Qti
|
|
33
33
|
tr
|
34
34
|
ul
|
35
35
|
infoControl
|
36
|
-
|
36
|
+
].join(',').freeze
|
37
37
|
|
38
|
-
INTERACTION_ELEMENTS_CSS = %w
|
38
|
+
INTERACTION_ELEMENTS_CSS = %w[
|
39
39
|
blockInteraction
|
40
40
|
customInteraction
|
41
41
|
inlineInteraction
|
@@ -55,11 +55,11 @@ module Qti
|
|
55
55
|
orderInteraction
|
56
56
|
sliderInteraction
|
57
57
|
uploadInteraction
|
58
|
-
|
58
|
+
].join(',').freeze
|
59
59
|
|
60
|
-
CHOICE_ELEMENTS_CSS = %w
|
60
|
+
CHOICE_ELEMENTS_CSS = %w[
|
61
61
|
simpleChoice
|
62
|
-
|
62
|
+
].join(',').freeze
|
63
63
|
|
64
64
|
def qti_version
|
65
65
|
2
|
@@ -16,7 +16,7 @@ module Qti
|
|
16
16
|
def self.use_match_interaction_implementation?(node)
|
17
17
|
MatchItemTagProcessors::MatchInteractionTagProcessor.match_interaction_tag?(node) &&
|
18
18
|
MatchItemTagProcessors::MatchInteractionTagProcessor.number_of_questions_per_answer(node)
|
19
|
-
|
19
|
+
.any? { |n| n != 1 }
|
20
20
|
end
|
21
21
|
|
22
22
|
def scoring_data_structs
|
@@ -20,9 +20,7 @@ module Qti
|
|
20
20
|
gap_node.children.filter('gapText').each(&:remove)
|
21
21
|
|
22
22
|
gap_node.children.each do |child|
|
23
|
-
if child.inner_text.strip.empty?
|
24
|
-
child.remove
|
25
|
-
end
|
23
|
+
child.remove if child.inner_text.strip.empty?
|
26
24
|
end
|
27
25
|
|
28
26
|
gap_node
|
@@ -68,7 +66,7 @@ module Qti
|
|
68
66
|
else
|
69
67
|
{
|
70
68
|
type: 'text',
|
71
|
-
value: stem_item.text.empty? ?
|
69
|
+
value: stem_item.text.empty? ? ' ' : stem_item.text
|
72
70
|
}
|
73
71
|
end
|
74
72
|
end
|
@@ -90,20 +88,18 @@ module Qti
|
|
90
88
|
question_response_pairs = node.xpath('.//xmlns:correctResponse//xmlns:value').map do |value|
|
91
89
|
value.content.split
|
92
90
|
end
|
93
|
-
question_response_pairs.map!
|
91
|
+
question_response_pairs.map!(&:reverse)
|
94
92
|
question_response_id_mapping = Hash[question_response_pairs]
|
95
|
-
answer_nodes.map
|
93
|
+
answer_nodes.map do |value_node|
|
96
94
|
node_id = value_node.attributes['identifier']&.value
|
97
|
-
answer_choice = choices.find{ |choice| choice.attributes['identifier']&.value == question_response_id_mapping[node_id] }
|
95
|
+
answer_choice = choices.find { |choice| choice.attributes['identifier']&.value == question_response_id_mapping[node_id] }
|
98
96
|
ScoringData.new(
|
99
97
|
answer_choice.content,
|
100
98
|
'directedPair',
|
101
|
-
|
102
|
-
|
103
|
-
case: false
|
104
|
-
}
|
99
|
+
id: node_id,
|
100
|
+
case: false
|
105
101
|
)
|
106
|
-
|
102
|
+
end
|
107
103
|
end
|
108
104
|
|
109
105
|
def choices
|
@@ -36,13 +36,13 @@ module Qti
|
|
36
36
|
def self.use_associate_interaction_implementation?(node)
|
37
37
|
MatchItemTagProcessors::AssociateInteractionTagProcessor.associate_interaction_tag?(node) &&
|
38
38
|
MatchItemTagProcessors::AssociateInteractionTagProcessor.number_of_questions_per_answer(node)
|
39
|
-
|
39
|
+
.all? { |n| n == 1 }
|
40
40
|
end
|
41
41
|
|
42
42
|
def self.use_match_interaction_implementation?(node)
|
43
43
|
MatchItemTagProcessors::MatchInteractionTagProcessor.match_interaction_tag?(node) &&
|
44
44
|
MatchItemTagProcessors::MatchInteractionTagProcessor.number_of_questions_per_answer(node)
|
45
|
-
|
45
|
+
.all? { |n| n == 1 }
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -16,11 +16,11 @@ module Qti
|
|
16
16
|
def stimulus_ref(assessment_item_ref)
|
17
17
|
ref = assessment_item_ref.sub(@package_root, '')
|
18
18
|
dependencies = @doc.xpath("//xmlns:resource[@href='#{ref}']/xmlns:dependency/@identifierref")
|
19
|
-
return unless dependencies
|
19
|
+
return unless dependencies&.count == 1
|
20
20
|
href = xpath_with_single_check("//xmlns:resource[@identifier='#{dependencies.first}']/@href")
|
21
21
|
remap_href_path(href)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
|
-
end
|
26
|
+
end
|
@@ -2,7 +2,7 @@ module Qti
|
|
2
2
|
module V2
|
3
3
|
module Models
|
4
4
|
ScoringData = Struct.new(:values, :type, :id, :case, :question_id, :questions_ids) do
|
5
|
-
def initialize(values, type, options={})
|
5
|
+
def initialize(values, type, options = {})
|
6
6
|
super(values, type, options[:id], options[:case], options[:question_id], options[:questions_ids])
|
7
7
|
end
|
8
8
|
end
|
data/lib/qti/version.rb
CHANGED
@@ -0,0 +1,126 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../..
|
3
|
+
specs:
|
4
|
+
qti (0.9.1)
|
5
|
+
activesupport (>= 4.2.9, < 5.2)
|
6
|
+
dry-struct (~> 0.2.1)
|
7
|
+
nokogiri (>= 1.6.8, < 1.9)
|
8
|
+
rubyzip (~> 1.2)
|
9
|
+
sanitize (>= 4.2.0, < 5.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
activesupport (5.1.4)
|
15
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
16
|
+
i18n (~> 0.7)
|
17
|
+
minitest (~> 5.1)
|
18
|
+
tzinfo (~> 1.1)
|
19
|
+
ast (2.3.0)
|
20
|
+
byebug (9.1.0)
|
21
|
+
coderay (1.1.2)
|
22
|
+
concurrent-ruby (1.0.5)
|
23
|
+
crass (1.0.2)
|
24
|
+
diff-lcs (1.3)
|
25
|
+
docile (1.1.5)
|
26
|
+
dry-configurable (0.7.0)
|
27
|
+
concurrent-ruby (~> 1.0)
|
28
|
+
dry-container (0.6.0)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
dry-configurable (~> 0.1, >= 0.1.3)
|
31
|
+
dry-core (0.3.3)
|
32
|
+
concurrent-ruby (~> 1.0)
|
33
|
+
dry-equalizer (0.2.0)
|
34
|
+
dry-logic (0.4.2)
|
35
|
+
dry-container (~> 0.2, >= 0.2.6)
|
36
|
+
dry-core (~> 0.2)
|
37
|
+
dry-equalizer (~> 0.2)
|
38
|
+
dry-struct (0.2.1)
|
39
|
+
dry-configurable (~> 0.1)
|
40
|
+
dry-equalizer (~> 0.2)
|
41
|
+
dry-types (~> 0.9, >= 0.9.0)
|
42
|
+
ice_nine (~> 0.11)
|
43
|
+
dry-types (0.12.0)
|
44
|
+
concurrent-ruby (~> 1.0)
|
45
|
+
dry-configurable (~> 0.1)
|
46
|
+
dry-container (~> 0.3)
|
47
|
+
dry-core (~> 0.2, >= 0.2.1)
|
48
|
+
dry-equalizer (~> 0.2)
|
49
|
+
dry-logic (~> 0.4, >= 0.4.2)
|
50
|
+
inflecto (~> 0.0.0, >= 0.0.2)
|
51
|
+
i18n (0.8.6)
|
52
|
+
ice_nine (0.11.2)
|
53
|
+
inflecto (0.0.2)
|
54
|
+
json (2.1.0)
|
55
|
+
method_source (0.9.0)
|
56
|
+
mini_portile2 (2.1.0)
|
57
|
+
minitest (5.10.3)
|
58
|
+
nokogiri (1.6.8.1)
|
59
|
+
mini_portile2 (~> 2.1.0)
|
60
|
+
nokogumbo (1.4.13)
|
61
|
+
nokogiri
|
62
|
+
parallel (1.12.0)
|
63
|
+
parser (2.4.0.0)
|
64
|
+
ast (~> 2.2)
|
65
|
+
powerpack (0.1.1)
|
66
|
+
pry (0.11.1)
|
67
|
+
coderay (~> 1.1.0)
|
68
|
+
method_source (~> 0.9.0)
|
69
|
+
rainbow (2.2.2)
|
70
|
+
rake
|
71
|
+
rake (0.9.6)
|
72
|
+
rspec (3.6.0)
|
73
|
+
rspec-core (~> 3.6.0)
|
74
|
+
rspec-expectations (~> 3.6.0)
|
75
|
+
rspec-mocks (~> 3.6.0)
|
76
|
+
rspec-core (3.6.0)
|
77
|
+
rspec-support (~> 3.6.0)
|
78
|
+
rspec-expectations (3.6.0)
|
79
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
80
|
+
rspec-support (~> 3.6.0)
|
81
|
+
rspec-mocks (3.6.0)
|
82
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
83
|
+
rspec-support (~> 3.6.0)
|
84
|
+
rspec-support (3.6.0)
|
85
|
+
rubocop (0.50.0)
|
86
|
+
parallel (~> 1.10)
|
87
|
+
parser (>= 2.3.3.1, < 3.0)
|
88
|
+
powerpack (~> 0.1)
|
89
|
+
rainbow (>= 2.2.2, < 3.0)
|
90
|
+
ruby-progressbar (~> 1.7)
|
91
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
92
|
+
ruby-progressbar (1.8.3)
|
93
|
+
rubyzip (1.2.1)
|
94
|
+
sanitize (4.5.0)
|
95
|
+
crass (~> 1.0.2)
|
96
|
+
nokogiri (>= 1.4.4)
|
97
|
+
nokogumbo (~> 1.4.1)
|
98
|
+
simplecov (0.15.1)
|
99
|
+
docile (~> 1.1.0)
|
100
|
+
json (>= 1.8, < 3)
|
101
|
+
simplecov-html (~> 0.10.0)
|
102
|
+
simplecov-html (0.10.2)
|
103
|
+
thread_safe (0.3.6)
|
104
|
+
tzinfo (1.2.3)
|
105
|
+
thread_safe (~> 0.1)
|
106
|
+
unicode-display_width (1.3.0)
|
107
|
+
wwtd (1.3.0)
|
108
|
+
|
109
|
+
PLATFORMS
|
110
|
+
ruby
|
111
|
+
|
112
|
+
DEPENDENCIES
|
113
|
+
bundler (~> 1.15)
|
114
|
+
byebug (~> 9.0)
|
115
|
+
nokogiri (~> 1.6.8)
|
116
|
+
pry (~> 0)
|
117
|
+
qti!
|
118
|
+
rake (~> 0)
|
119
|
+
rspec (~> 3.6)
|
120
|
+
rspec-mocks (~> 3.6)
|
121
|
+
rubocop (~> 0.50.0)
|
122
|
+
simplecov (~> 0)
|
123
|
+
wwtd (~> 1.3)
|
124
|
+
|
125
|
+
BUNDLED WITH
|
126
|
+
1.15.4
|