qti 1.0.3 → 1.0.4

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.
data/lib/qti/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Qti
2
- VERSION = '1.0.3'.freeze
2
+ VERSION = '1.0.4'.freeze
3
3
  end
@@ -0,0 +1,20 @@
1
+ module Qti
2
+ module XPathHelpers
3
+ def xpath_resource(type = '')
4
+ "//xmlns:resources/xmlns:resource#{type}"
5
+ end
6
+
7
+ def xpath_endswith(tag, tail)
8
+ "substring(#{tag}, string-length(#{tag}) - string-length('#{tail}') + 1) = '#{tail}'"
9
+ end
10
+
11
+ def rtype_predicate(ver, rsc_type)
12
+ # XPath 2.0 supports ends-with, which is what substring is doing here.
13
+ # It also support regex matching with matches.
14
+ # We only have XPath 1.0 available.
15
+ cc_match = "starts-with(@type, '#{ver}') and " + xpath_endswith('@type', rsc_type)
16
+ qti_match = "@type='#{ver}'"
17
+ "#{qti_match} or (#{cc_match})"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,85 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- QTI Template -->
3
+ <manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:imsmd="http://ltsc.ieee.org/xsd/LOM">
4
+ <resources>
5
+ <resource identifier="i-taxonpath-identifier" type="imsqti_item_xmlv2p1" href="fourofour">
6
+ <metadata>
7
+ <imsmd:lom>
8
+ <imsmd:classification>
9
+ <imsmd:taxonPath>
10
+ <imsmd:source>
11
+ <imsmd:string>Blank Entry</imsmd:string>
12
+ </imsmd:source>
13
+ <imsmd:taxon>
14
+ <imsmd:entry>
15
+ <imsmd:string/>
16
+ </imsmd:entry>
17
+ </imsmd:taxon>
18
+ </imsmd:taxonPath>
19
+ <imsmd:taxonPath>
20
+ <imsmd:source>
21
+ <imsmd:string>Single Entry</imsmd:string>
22
+ </imsmd:source>
23
+ <imsmd:taxon>
24
+ <imsmd:entry>
25
+ <imsmd:string>Data</imsmd:string>
26
+ </imsmd:entry>
27
+ </imsmd:taxon>
28
+ </imsmd:taxonPath>
29
+ <imsmd:taxonPath>
30
+ <imsmd:source>
31
+ <imsmd:string>Nested Entry</imsmd:string>
32
+ </imsmd:source>
33
+ <imsmd:taxon>
34
+ <imsmd:entry>
35
+ <imsmd:string>Level 1</imsmd:string>
36
+ </imsmd:entry>
37
+ <imsmd:taxon>
38
+ <imsmd:entry>
39
+ <imsmd:string>Level 2</imsmd:string>
40
+ </imsmd:entry>
41
+ <imsmd:taxon>
42
+ <imsmd:entry>
43
+ <imsmd:string>Level 3</imsmd:string>
44
+ </imsmd:entry>
45
+ </imsmd:taxon>
46
+ </imsmd:taxon>
47
+ </imsmd:taxon>
48
+ </imsmd:taxonPath>
49
+ <imsmd:taxonPath>
50
+ <imsmd:source>
51
+ <imsmd:string>String Type</imsmd:string>
52
+ </imsmd:source>
53
+ <imsmd:taxon>
54
+ <imsmd:entry>
55
+ <imsmd:langstring>langstring</imsmd:langstring>
56
+ </imsmd:entry>
57
+ <imsmd:taxon>
58
+ <imsmd:entry>
59
+ <imsmd:string>string</imsmd:string>
60
+ </imsmd:entry>
61
+ </imsmd:taxon>
62
+ </imsmd:taxon>
63
+ </imsmd:taxonPath>
64
+ <imsmd:taxonPath>
65
+ <imsmd:source>
66
+ <imsmd:string>Language Entry</imsmd:string>
67
+ </imsmd:source>
68
+ <imsmd:taxon>
69
+ <imsmd:entry>
70
+ <imsmd:langstring xml:lang="en">English</imsmd:langstring>
71
+ <imsmd:langstring>Default</imsmd:langstring>
72
+ <imsmd:langstring lang="ja">Japanese</imsmd:langstring>
73
+ <imsmd:langstring language="hu">Hungarian</imsmd:langstring>
74
+ <imsmd:string lang="de">Deutsch</imsmd:string>
75
+ <imsmd:string xml:lang="fr">French</imsmd:string>
76
+ <imsmd:string language="hr">Croatian</imsmd:string>
77
+ </imsmd:entry>
78
+ </imsmd:taxon>
79
+ </imsmd:taxonPath>
80
+ </imsmd:classification>
81
+ </imsmd:lom>
82
+ </metadata>
83
+ </resource>
84
+ </resources>
85
+ </manifest>
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ fixtures_path = File.join('spec', 'fixtures')
4
+
5
+ describe Qti::Models::Manifest do
6
+ shared_examples 'metadata with empty or no taxonpaths' do
7
+ it 'will have metadata attached' do
8
+ expect(testobject.metadata).not_to eq(nil)
9
+ end
10
+
11
+ it 'will not contain any taxonpaths' do
12
+ expect(testobject.metadata.taxonpaths).to eq(nil)
13
+ end
14
+ end
15
+
16
+ describe 'v1 assessment_tests' do
17
+ qti1_files = ['test_qti_1.2', 'test_qti_1.2_canvas']
18
+ qti1_files.each do |qfile|
19
+ let(:file) { File.join(fixtures_path, qfile, 'imsmanifest.xml') }
20
+ let(:testobject) { described_class.from_path!(file).assessment_test }
21
+
22
+ include_examples 'metadata with empty or no taxonpaths'
23
+ end
24
+ end
25
+
26
+ describe 'v2 assessment_tests' do
27
+ qti2_files = ['test_qti_2.1', 'test_qti_2.2']
28
+ qti2_files.each do |qfile|
29
+ let(:file) { File.join(fixtures_path, qfile, 'imsmanifest.xml') }
30
+ let(:testobject) { described_class.from_path!(file).assessment_test }
31
+
32
+ include_examples 'metadata with empty or no taxonpaths'
33
+ end
34
+ end
35
+
36
+ describe 'canvas cartridge' do
37
+ let(:file) { File.join(fixtures_path, 'canvas_cartridge/imsmanifest.xml') }
38
+ let(:testobject) { described_class.from_path!(file).assessment_test }
39
+
40
+ include_examples 'metadata with empty or no taxonpaths'
41
+ end
42
+
43
+ describe 'v2 non assessment' do
44
+ let(:file) { File.join(fixtures_path, 'no_assessment_xml/imsmanifest.xml') }
45
+ let(:assessment_test) { described_class.from_path!(file).assessment_test }
46
+ let(:testobject) { assessment_test.assessment_items.first[:resource] }
47
+
48
+ include_examples 'metadata with empty or no taxonpaths'
49
+ end
50
+
51
+ describe 'v2 assessment with taxonpaths' do
52
+ let(:file) { File.join(fixtures_path, 'test_qti_2.1_taxonpath/imsmanifest.xml') }
53
+ let(:assessment_test) { described_class.from_path!(file).assessment_test }
54
+ let(:testobject) { assessment_test.assessment_items.last[:resource] }
55
+
56
+ it 'will have metadata' do
57
+ expect(testobject.metadata).not_to eq(nil)
58
+ end
59
+
60
+ it 'will contain taxonpaths' do
61
+ expect(testobject.metadata.taxonpaths.count).to eq(5)
62
+ end
63
+
64
+ describe 'taxonpath instances' do
65
+ let(:taxonpath) { testobject.metadata.taxonpaths }
66
+
67
+ it 'accepts sources with empty taxons' do
68
+ expect(taxonpath['Blank Entry']['default']).to eq([''])
69
+ end
70
+
71
+ it 'accepts sources with a single entry' do
72
+ expect(taxonpath['Single Entry']['default']).to eq(['Data'])
73
+ end
74
+
75
+ it 'accepts sources with nested entries' do
76
+ expect(taxonpath['Nested Entry']['default']).to eq(['Level 1', 'Level 2', 'Level 3'])
77
+ end
78
+
79
+ it 'is agnostic about string and langstring' do
80
+ expect(taxonpath['String Type']['default']).to eq(%w[langstring string])
81
+ end
82
+
83
+ it 'allows for multiple languages in entries' do
84
+ expect(taxonpath['Language Entry']['default']).to eq(['Default'])
85
+ expect(taxonpath['Language Entry']['en']).to eq(['English'])
86
+ expect(taxonpath['Language Entry']['de']).to eq(['Deutsch'])
87
+ expect(taxonpath['Language Entry']['fr']).to eq(['French'])
88
+ expect(taxonpath['Language Entry']['ja']).to eq(['Japanese'])
89
+ expect(taxonpath['Language Entry']['hr']).to eq(['Croatian'])
90
+ expect(taxonpath['Language Entry']['hu']).to eq(['Hungarian'])
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ fixtures_path = File.join('spec', 'fixtures')
4
+
5
+ describe Qti::Models::Manifest do
6
+ manifest_files = ['test_qti_1.2', 'test_qti_1.2_canvas', 'test_qti_2.1', 'test_qti_2.2']
7
+ manifest_files.each do |mfile|
8
+ file = File.join(fixtures_path, mfile, 'imsmanifest.xml')
9
+ context "File: #{file}" do
10
+ it 'parses the manifest file without error' do
11
+ expect { described_class.from_path!(file) }.not_to raise_error
12
+ end
13
+ end
14
+ end
15
+
16
+ it 'v1 assessment_tests have a resource attached' do
17
+ qti1_files = ['test_qti_1.2', 'test_qti_1.2_canvas']
18
+ qti1_files.each do |qfile|
19
+ file = File.join(fixtures_path, qfile, 'imsmanifest.xml')
20
+ assessment_test = described_class.from_path!(file).assessment_test
21
+ expect(assessment_test.resource).not_to eq(nil)
22
+ end
23
+ end
24
+
25
+ it 'v2 assessment_tests have a resource attached' do
26
+ qti2_files = ['test_qti_2.1', 'test_qti_2.2']
27
+ qti2_files.each do |qfile|
28
+ file = File.join(fixtures_path, qfile, 'imsmanifest.xml')
29
+ assessment_test = described_class.from_path!(file).assessment_test
30
+ expect(assessment_test.resource).not_to eq(nil)
31
+ end
32
+ end
33
+
34
+ it 'canvas cartridge have canvas metadata attached to the resource' do
35
+ file = File.join(fixtures_path, 'canvas_cartridge/imsmanifest.xml')
36
+ assessment_test = described_class.from_path!(file).assessment_test
37
+ expect(assessment_test.resource).not_to eq(nil)
38
+ expect(assessment_test.resource.canvas_metadata).not_to eq(nil)
39
+ end
40
+
41
+ describe 'v2 non assessment' do
42
+ file = File.join(fixtures_path, 'no_assessment_xml/imsmanifest.xml')
43
+ assessment_test = described_class.from_path!(file).assessment_test
44
+
45
+ it 'will not have a resource attached' do
46
+ expect(assessment_test.resource).to eq(nil)
47
+ end
48
+
49
+ it 'the assessment_items will have resources attached' do
50
+ expect(assessment_test.assessment_items.first[:resource]).not_to eq(nil)
51
+ end
52
+ end
53
+ end
@@ -19,7 +19,7 @@ describe Qti::V2::Models::AssessmentTest do
19
19
 
20
20
  it 'gets dependency file refs' do
21
21
  refs = loaded_class.assessment_items
22
- expect(refs.all? { |ref| File.extname(ref) == '.xml' })
22
+ expect(refs.all? { |ref| File.extname(ref[:path]) == '.xml' })
23
23
  end
24
24
 
25
25
  it 'loads up some testParts' do
@@ -56,7 +56,7 @@ describe Qti::V2::Models::AssessmentTest do
56
56
 
57
57
  it 'gets dependency file refs' do
58
58
  refs = loaded_class.assessment_items
59
- expect(refs.all? { |ref| File.extname(ref) == '.xml' })
59
+ expect(refs.all? { |ref| File.extname(ref[:path]) == '.xml' })
60
60
  end
61
61
  end
62
62
  end
data/spec/lib/qti_spec.rb CHANGED
@@ -65,7 +65,7 @@ describe Qti::Importer do
65
65
  it 'sets the path and package root properly' do
66
66
  ref = importer.assessment_item_refs.first
67
67
  item = importer.create_assessment_item(ref)
68
- expect(item.path).to eq ref
68
+ expect(item.path).to eq ref[:path]
69
69
  expect(item.package_root).to eq file_path + '/'
70
70
  expect(item.manifest).not_to be_nil
71
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qti
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hannah Bottalla
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-09-19 00:00:00.000000000 Z
12
+ date: 2018-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -291,6 +291,8 @@ files:
291
291
  - lib/qti/models/assessment_meta.rb
292
292
  - lib/qti/models/base.rb
293
293
  - lib/qti/models/manifest.rb
294
+ - lib/qti/models/metadata.rb
295
+ - lib/qti/models/resource.rb
294
296
  - lib/qti/sanitizer.rb
295
297
  - lib/qti/v1/models/assessment.rb
296
298
  - lib/qti/v1/models/assessment_item.rb
@@ -340,6 +342,7 @@ files:
340
342
  - lib/qti/v2/models/scoring_data.rb
341
343
  - lib/qti/v2/models/stimulus_item.rb
342
344
  - lib/qti/version.rb
345
+ - lib/qti/xpath_helpers.rb
343
346
  - spec/fixtures/all_canvas_simple_1.2.xml
344
347
  - spec/fixtures/canvas_cartridge/course_settings/assignment_groups.xml
345
348
  - spec/fixtures/canvas_cartridge/course_settings/canvas_export.txt
@@ -528,6 +531,7 @@ files:
528
531
  - spec/fixtures/test_qti_2.1/Items/Item_VE_IP_05/qtiv2p1_EntryTest_VE_IP_05.xml
529
532
  - spec/fixtures/test_qti_2.1/Tests/Test_VE_TP_06/qtiv2p1_EntryTest_VE_TP_06.xml
530
533
  - spec/fixtures/test_qti_2.1/imsmanifest.xml
534
+ - spec/fixtures/test_qti_2.1_taxonpath/imsmanifest.xml
531
535
  - spec/fixtures/test_qti_2.2.zip
532
536
  - spec/fixtures/test_qti_2.2/assessment.xml
533
537
  - spec/fixtures/test_qti_2.2/essay/essay.xml
@@ -597,17 +601,16 @@ files:
597
601
  - spec/fixtures/tests/tests/rtest26.xml
598
602
  - spec/fixtures/tests/tests/rtest27.xml
599
603
  - spec/fixtures/unsupported_version/imsmanifest.xml
600
- - spec/gemfiles/nokogiri-1.6.gemfile.lock
601
- - spec/gemfiles/nokogiri-1.8.gemfile.lock
602
604
  - spec/gemfiles/rails-5.0.gemfile
603
605
  - spec/gemfiles/rails-5.1.gemfile
604
606
  - spec/gemfiles/rails-5.2.gemfile
605
- - spec/gemfiles/rails-5.2.gemfile.lock
606
607
  - spec/lib/qti/assessment_item_exporter_spec.rb
607
608
  - spec/lib/qti/exporter_spec.rb
608
609
  - spec/lib/qti/models/assessment_meta_spec.rb
609
610
  - spec/lib/qti/models/base_spec.rb
610
611
  - spec/lib/qti/models/manifest_spec.rb
612
+ - spec/lib/qti/models/metadata_spec.rb
613
+ - spec/lib/qti/models/resource_spec.rb
611
614
  - spec/lib/qti/v1/models/assessment_item_spec.rb
612
615
  - spec/lib/qti/v1/models/assessment_spec.rb
613
616
  - spec/lib/qti/v1/models/choices/fill_blank_choice_spec.rb
@@ -668,7 +671,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
668
671
  version: '0'
669
672
  requirements: []
670
673
  rubyforge_project:
671
- rubygems_version: 2.6.13
674
+ rubygems_version: 2.6.14
672
675
  signing_key:
673
676
  specification_version: 4
674
677
  summary: QTI 1.2 and 2.1 import and export models
@@ -861,6 +864,7 @@ test_files:
861
864
  - spec/fixtures/test_qti_2.1/Items/Item_VE_IP_05/qtiv2p1_EntryTest_VE_IP_05.xml
862
865
  - spec/fixtures/test_qti_2.1/Tests/Test_VE_TP_06/qtiv2p1_EntryTest_VE_TP_06.xml
863
866
  - spec/fixtures/test_qti_2.1/imsmanifest.xml
867
+ - spec/fixtures/test_qti_2.1_taxonpath/imsmanifest.xml
864
868
  - spec/fixtures/test_qti_2.2.zip
865
869
  - spec/fixtures/test_qti_2.2/assessment.xml
866
870
  - spec/fixtures/test_qti_2.2/essay/essay.xml
@@ -930,17 +934,16 @@ test_files:
930
934
  - spec/fixtures/tests/tests/rtest26.xml
931
935
  - spec/fixtures/tests/tests/rtest27.xml
932
936
  - spec/fixtures/unsupported_version/imsmanifest.xml
933
- - spec/gemfiles/nokogiri-1.6.gemfile.lock
934
- - spec/gemfiles/nokogiri-1.8.gemfile.lock
935
937
  - spec/gemfiles/rails-5.0.gemfile
936
938
  - spec/gemfiles/rails-5.1.gemfile
937
939
  - spec/gemfiles/rails-5.2.gemfile
938
- - spec/gemfiles/rails-5.2.gemfile.lock
939
940
  - spec/lib/qti/assessment_item_exporter_spec.rb
940
941
  - spec/lib/qti/exporter_spec.rb
941
942
  - spec/lib/qti/models/assessment_meta_spec.rb
942
943
  - spec/lib/qti/models/base_spec.rb
943
944
  - spec/lib/qti/models/manifest_spec.rb
945
+ - spec/lib/qti/models/metadata_spec.rb
946
+ - spec/lib/qti/models/resource_spec.rb
944
947
  - spec/lib/qti/v1/models/assessment_item_spec.rb
945
948
  - spec/lib/qti/v1/models/assessment_spec.rb
946
949
  - spec/lib/qti/v1/models/choices/fill_blank_choice_spec.rb
@@ -1,149 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- mathml2latex (0.1.1)
5
- activesupport (>= 4.2.9, < 5.2)
6
- nokogiri (>= 1.6.8)
7
- qti (0.9.12)
8
- actionview (>= 4.2.0)
9
- activesupport (>= 4.2.9, < 5.2)
10
- dry-struct (~> 0.2.1)
11
- dry-types (~> 0.12.0)
12
- mathml2latex (>= 0.1.0)
13
- nokogiri (>= 1.6.8, < 1.9)
14
- rubyzip (~> 1.2)
15
- sanitize (>= 4.2.0, < 5.0)
16
-
17
- GEM
18
- remote: https://rubygems.org/
19
- specs:
20
- actionview (5.1.5)
21
- activesupport (= 5.1.5)
22
- builder (~> 3.1)
23
- erubi (~> 1.4)
24
- rails-dom-testing (~> 2.0)
25
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
26
- activesupport (5.1.5)
27
- concurrent-ruby (~> 1.0, >= 1.0.2)
28
- i18n (~> 0.7)
29
- minitest (~> 5.1)
30
- tzinfo (~> 1.1)
31
- ast (2.4.0)
32
- builder (3.2.3)
33
- byebug (9.1.0)
34
- coderay (1.1.2)
35
- concurrent-ruby (1.0.5)
36
- crass (1.0.3)
37
- diff-lcs (1.3)
38
- docile (1.3.0)
39
- dry-configurable (0.7.0)
40
- concurrent-ruby (~> 1.0)
41
- dry-container (0.6.0)
42
- concurrent-ruby (~> 1.0)
43
- dry-configurable (~> 0.1, >= 0.1.3)
44
- dry-core (0.4.5)
45
- concurrent-ruby (~> 1.0)
46
- dry-equalizer (0.2.0)
47
- dry-logic (0.4.2)
48
- dry-container (~> 0.2, >= 0.2.6)
49
- dry-core (~> 0.2)
50
- dry-equalizer (~> 0.2)
51
- dry-struct (0.2.1)
52
- dry-configurable (~> 0.1)
53
- dry-equalizer (~> 0.2)
54
- dry-types (~> 0.9, >= 0.9.0)
55
- ice_nine (~> 0.11)
56
- dry-types (0.12.2)
57
- concurrent-ruby (~> 1.0)
58
- dry-configurable (~> 0.1)
59
- dry-container (~> 0.3)
60
- dry-core (~> 0.2, >= 0.2.1)
61
- dry-equalizer (~> 0.2)
62
- dry-logic (~> 0.4, >= 0.4.2)
63
- inflecto (~> 0.0.0, >= 0.0.2)
64
- erubi (1.7.1)
65
- i18n (0.9.5)
66
- concurrent-ruby (~> 1.0)
67
- ice_nine (0.11.2)
68
- inflecto (0.0.2)
69
- json (2.1.0)
70
- loofah (2.2.2)
71
- crass (~> 1.0.2)
72
- nokogiri (>= 1.5.9)
73
- method_source (0.9.0)
74
- mini_portile2 (2.1.0)
75
- minitest (5.11.3)
76
- nokogiri (1.6.8.1)
77
- mini_portile2 (~> 2.1.0)
78
- nokogumbo (1.5.0)
79
- nokogiri
80
- parallel (1.12.1)
81
- parser (2.5.0.5)
82
- ast (~> 2.4.0)
83
- powerpack (0.1.1)
84
- pry (0.11.3)
85
- coderay (~> 1.1.0)
86
- method_source (~> 0.9.0)
87
- rails-dom-testing (2.0.3)
88
- activesupport (>= 4.2.0)
89
- nokogiri (>= 1.6)
90
- rails-html-sanitizer (1.0.4)
91
- loofah (~> 2.2, >= 2.2.2)
92
- rainbow (2.2.2)
93
- rake
94
- rake (0.9.6)
95
- rspec (3.7.0)
96
- rspec-core (~> 3.7.0)
97
- rspec-expectations (~> 3.7.0)
98
- rspec-mocks (~> 3.7.0)
99
- rspec-core (3.7.1)
100
- rspec-support (~> 3.7.0)
101
- rspec-expectations (3.7.0)
102
- diff-lcs (>= 1.2.0, < 2.0)
103
- rspec-support (~> 3.7.0)
104
- rspec-mocks (3.7.0)
105
- diff-lcs (>= 1.2.0, < 2.0)
106
- rspec-support (~> 3.7.0)
107
- rspec-support (3.7.1)
108
- rubocop (0.50.0)
109
- parallel (~> 1.10)
110
- parser (>= 2.3.3.1, < 3.0)
111
- powerpack (~> 0.1)
112
- rainbow (>= 2.2.2, < 3.0)
113
- ruby-progressbar (~> 1.7)
114
- unicode-display_width (~> 1.0, >= 1.0.1)
115
- ruby-progressbar (1.9.0)
116
- rubyzip (1.2.1)
117
- sanitize (4.6.4)
118
- crass (~> 1.0.2)
119
- nokogiri (>= 1.4.4)
120
- nokogumbo (~> 1.4)
121
- simplecov (0.16.1)
122
- docile (~> 1.1)
123
- json (>= 1.8, < 3)
124
- simplecov-html (~> 0.10.0)
125
- simplecov-html (0.10.2)
126
- thread_safe (0.3.6)
127
- tzinfo (1.2.5)
128
- thread_safe (~> 0.1)
129
- unicode-display_width (1.3.0)
130
- wwtd (1.3.0)
131
-
132
- PLATFORMS
133
- ruby
134
-
135
- DEPENDENCIES
136
- bundler (~> 1.15)
137
- byebug (~> 9.0)
138
- nokogiri (~> 1.6.8)
139
- pry (~> 0)
140
- qti!
141
- rake (~> 0)
142
- rspec (~> 3.6)
143
- rspec-mocks (~> 3.6)
144
- rubocop (~> 0.50.0)
145
- simplecov (~> 0)
146
- wwtd (~> 1.3)
147
-
148
- BUNDLED WITH
149
- 1.16.1