csv2qti_lumen 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4fb0fcb4afce967be7d76513dff0643f95746063
4
+ data.tar.gz: 63f48522bb42995a5643fea43efce88c3e0dd07e
5
+ SHA512:
6
+ metadata.gz: ac655316943ea8f2ebda1b036eb8b2ef44dda0e7abf0c20af20b593ecdfb9d77bee48b999460e0f4abaccdcb45d68985966ba740b5b1816ffcdafcf8a1298075
7
+ data.tar.gz: 48ee7604e9f594e7eb95691fa6efb288b840906dff650ad90313ba2b47eeed83aaf341a09e3ebfce3e5417e1809182b4cddd8a8068fca1155d370cf05438badb
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in csv2qti.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Lumen Learning
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Csv2qti
2
+
3
+ Converts a specifically-formatted CSV into QTI.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'csv2qti'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install csv2qti
20
+
21
+ ## Usage
22
+
23
+
24
+ ## Contributing
25
+
26
+ 1. Fork it ( https://github.com/lumenlearning/csv2qti/fork )
27
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
28
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
29
+ 4. Push to the branch (`git push origin my-new-feature`)
30
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push "lib"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
data/bin/csv2qti ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'csv2qti'
4
+
5
+ if ARGV.empty?
6
+ puts "To use do: csv2qti path_to_csv.csv"
7
+ else
8
+ puts ARGV[0]
9
+ course = Csv2qti::process_file(ARGV[0])
10
+ course.generate_cc(ARGV[1])
11
+ end
data/csv2qti.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'csv2qti/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "csv2qti_lumen"
8
+ spec.version = Csv2qti::VERSION
9
+ spec.authors = ["Bracken Mosbacker"]
10
+ spec.email = ["bracken@lumenlearning.com"]
11
+ spec.summary = %q{Converts a specifically-formatted CSV into QTI.}
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_runtime_dependency "canvas_cc"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest"
25
+ end
@@ -0,0 +1,38 @@
1
+ require 'tmpdir'
2
+
3
+ module Csv2qti
4
+ class Course
5
+ attr_reader :title, :file_path, :primary_outcomes
6
+
7
+ def initialize(title, file_path)
8
+ @title = title
9
+ @file_path = file_path
10
+ @primary_outcomes = []
11
+ end
12
+
13
+ def add_primary_outcome(row)
14
+ @primary_outcomes << Outcome.new(row)
15
+ @primary_outcomes.last
16
+ end
17
+
18
+ def generate_cc(filename=nil)
19
+ filename ||= @title
20
+ course = CanvasCc::CanvasCC::Models::Course.new
21
+ course.title = @title
22
+ course.identifier = rand(1000).to_s
23
+
24
+ @primary_outcomes.each do |po|
25
+ course.assessments << po.generate_assessment
26
+ end
27
+
28
+ dir = Dir.mktmpdir
29
+ file = CanvasCc::CanvasCC::CartridgeCreator.new(course).create(dir)
30
+
31
+ FileUtils.mv(file, "./#{filename.downcase.gsub(' ', '_')}.zip")
32
+ end
33
+
34
+ def to_s
35
+ @primary_outcomes.inject("#{title}\nOutcomes:") { |s, o| s + "\n" + o.to_s }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,63 @@
1
+ module Csv2qti
2
+ class Outcome
3
+ attr_reader :title, :number, :enabling_outcomes, :description, :license, :questions, :guid
4
+
5
+ def initialize(row, parent_outcome=nil)
6
+ @number = row[0]
7
+ @title = row[1]
8
+ @description = row[2]
9
+ @guid = row[3]
10
+ @license = row[5]
11
+ @parent_outcome = parent_outcome
12
+ @enabling_outcomes = []
13
+ @questions = []
14
+ end
15
+
16
+ def add_enabling_outcome(row)
17
+ @enabling_outcomes << Outcome.new(row, self)
18
+ @enabling_outcomes.last
19
+ end
20
+
21
+ def add_question(row)
22
+ @questions << Question.generate(row)
23
+ end
24
+
25
+ def is_primary_outcome?
26
+ !! @parent_outcome
27
+ end
28
+
29
+ def generate_assessment
30
+ assessment = CanvasCc::CanvasCC::Models::Assessment.new
31
+ assessment.identifier = rand(10000).to_s
32
+ assessment.items = []
33
+ assessment.title = @title
34
+ add_questions(assessment)
35
+
36
+ @enabling_outcomes.each do |eo|
37
+ g = CanvasCc::CanvasCC::Models::QuestionGroup.new
38
+ g.title = eo.title
39
+ g.identifier = rand(10000).to_s
40
+ g.selection_number = 1
41
+ g.points_per_item = 1
42
+ eo.add_questions(g)
43
+ assessment.items << g
44
+ end
45
+
46
+ assessment
47
+ end
48
+
49
+ def add_questions(group)
50
+ @questions.each do |q|
51
+ q.add_to_group(group)
52
+ end
53
+ end
54
+
55
+ def to_s
56
+ if is_primary_outcome?
57
+ "#{number}: #{title} - #{description} - #{guid} - #{license} - #{questions.count} questions"
58
+ else
59
+ "#{number}: #{title} - #{description} - #{guid} - #{license} - #{enabling_outcomes.count} enabling outcomes"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,81 @@
1
+ module Csv2qti
2
+ class Question
3
+ TYPE = 7
4
+ STEM = 8
5
+ CORRECT = 9
6
+ DISTRACTOR_1 = 10
7
+ DISTRACTOR_2 = 11
8
+ LICENSE = 12
9
+
10
+ def self.generate(row)
11
+ type = row[TYPE] || ''
12
+ case type.downcase
13
+ when ''
14
+ raise Csv2qti::QuestionParseError, "Thought this row would be a question but its not."
15
+ when 'mc'
16
+ MultipleChoice.new(row)
17
+ when 'mmc'
18
+ MultipleSelect.new(row)
19
+ when 'category'
20
+ raise Csv2qti::QuestionParseError, "unsupported question type: #{row[TYPE]}"
21
+ when 'matching'
22
+ Matching.new(row)
23
+ when 'process'
24
+ raise Csv2qti::QuestionParseError, "unsupported question type: #{row[TYPE]}"
25
+ else
26
+ raise Csv2qti::QuestionParseError, "unknown question type: #{row[TYPE]}"
27
+ end
28
+ end
29
+
30
+ attr_reader :stem, :license
31
+
32
+ def initialize(row)
33
+ @stem = process_stem(row[STEM])
34
+ @license = row[LICENSE]
35
+ end
36
+
37
+ # converts image references to html
38
+ # images look like this in the original value:
39
+ # (image: https://s3-us-west-2.amazonaws.com/textimgs/Biology/FormativeAssessment+/Bio_C3_LO2.png)
40
+ def process_stem(val)
41
+ val.gsub(/\(image: ([^\)]*)\)/, %{<img src="\\1" />})
42
+ end
43
+
44
+ def process_distractors(row)
45
+ [row[DISTRACTOR_1], row[DISTRACTOR_2]]
46
+ end
47
+
48
+ def generate_cc_question
49
+ nil
50
+ end
51
+
52
+ def add_to_assessment(assessment)
53
+ if q = generate_cc_question
54
+ assessment.items << q
55
+ end
56
+ end
57
+
58
+ def add_to_group(assessment)
59
+ if q = generate_cc_question
60
+ assessment.questions << q
61
+ end
62
+ end
63
+
64
+ def to_qti
65
+ ''
66
+ end
67
+
68
+ def type
69
+ "unknown"
70
+ end
71
+
72
+ def to_s
73
+ type
74
+ end
75
+
76
+ end
77
+ end
78
+
79
+ require 'csv2qti/question_types/multiple_choice'
80
+ require 'csv2qti/question_types/multiple_select'
81
+ require 'csv2qti/question_types/matching'
@@ -0,0 +1,47 @@
1
+ module Csv2qti
2
+ class Matching < Question
3
+
4
+ attr_reader :distractors, :answers
5
+
6
+ def initialize(row)
7
+ super(row)
8
+ @answers = process_answers(row[CORRECT])
9
+ end
10
+
11
+ # parse out the matching answers that look like this:
12
+ # "A—Alpha Carbon\nB—Amino Group\nC—Carboxyl Group\nD—Hydrogen Atom\nE—R Group"
13
+ def process_answers(val)
14
+ val.split("\n").map{|m|m.split("—")}
15
+ end
16
+
17
+ def type
18
+ 'MATCHING'
19
+ end
20
+
21
+ def generate_cc_question
22
+ question = CanvasCc::CanvasCC::Models::Question.create('matching_question')
23
+ question.identifier = rand(10000)
24
+ question.material = stem
25
+ #question.distractors = %w(distractor1 distractor2)
26
+ question.matches = @answers.map {|a| make_answer(a)}
27
+
28
+ question
29
+ end
30
+
31
+ def to_qti
32
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
33
+ CanvasCc::CanvasCC::MatchingQuestionWriter.write_question(node, generate_cc_question)
34
+ end.doc.to_xml
35
+ end
36
+
37
+ private
38
+
39
+ def make_answer(match)
40
+ {:id => rand(10000).to_s,
41
+ :question_text => match.first,
42
+ :question_text_format => '1',
43
+ :answer_text => match.last}
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ module Csv2qti
2
+ class MultipleChoice < Question
3
+
4
+ attr_reader :distractors, :answer
5
+
6
+ def initialize(row)
7
+ super(row)
8
+ @distractors = process_distractors(row)
9
+ @answer = row[CORRECT]
10
+ end
11
+
12
+ def type
13
+ 'MULTIPLE_CHOICE'
14
+ end
15
+
16
+ def generate_cc_question
17
+ question = CanvasCc::CanvasCC::Models::Question.create('multiple_choice_question')
18
+ question.material = stem
19
+ question.identifier = rand(10000)
20
+ question.answers = @distractors.map {|d| make_answer(d)} << make_answer(@answer, true)
21
+
22
+ question
23
+ end
24
+
25
+ def to_qti
26
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
27
+ CanvasCc::CanvasCC::MultipleChoiceQuestionWriter.write_question(node, generate_cc_question)
28
+ end.doc.to_xml
29
+ end
30
+
31
+ private
32
+
33
+ def make_answer(text, correct=false)
34
+ answer = CanvasCc::CanvasCC::Models::Answer.new
35
+ answer.id = rand(10000)
36
+ answer.fraction = correct ? 1.0 : 0.0
37
+ answer.answer_text = text
38
+ answer
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ module Csv2qti
2
+ class MultipleSelect < Question
3
+
4
+ attr_reader :distractors, :answers
5
+
6
+ def initialize(row)
7
+ super(row)
8
+ @distractors = process_distractors(row)
9
+ @answers = process_answers(row[CORRECT])
10
+ end
11
+
12
+ # parse out the multiple answers that look like this:
13
+ # "*Helper\n*chains\n*Lower energies"
14
+ def process_answers(val)
15
+ val.split("\n").map { |a| a.gsub(/\A\*/, '') }
16
+ end
17
+
18
+ def type
19
+ 'MULTIPLE_SELECT'
20
+ end
21
+
22
+ def generate_cc_question
23
+ question = CanvasCc::CanvasCC::Models::Question.create('multiple_answers_question')
24
+ question.material = stem
25
+ question.identifier = rand(10000)
26
+ question.answers = @answers.map { |a| make_answer(a, true) } + @distractors.map { |d| make_answer(d) }
27
+ question
28
+ end
29
+
30
+ def to_qti
31
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
32
+ CanvasCc::CanvasCC::MultipleAnswersQuestionWriter.write_question(node, generate_cc_question)
33
+ end.doc.to_xml
34
+ end
35
+
36
+ private
37
+
38
+ def make_answer(text, correct=false)
39
+ answer = CanvasCc::CanvasCC::Models::Answer.new
40
+ answer.id = rand(10000)
41
+ answer.fraction = correct ? 1.0 : 0.0
42
+ answer.answer_text = text
43
+ answer
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module Csv2qti
2
+ VERSION = "0.0.1"
3
+ end
data/lib/csv2qti.rb ADDED
@@ -0,0 +1,75 @@
1
+ require "csv2qti/version"
2
+ require 'csv'
3
+ require 'pp'
4
+ require 'canvas_cc'
5
+ require 'fileutils'
6
+
7
+ module Csv2qti
8
+
9
+ class Csv2qtiError < StandardError
10
+ end
11
+
12
+ class QuestionParseError < Csv2qtiError
13
+ end
14
+
15
+ def self.process_dir(path='.')
16
+
17
+ end
18
+
19
+ def self.process_file(path)
20
+ course = nil
21
+ current_primary = nil
22
+ current_enabling = nil
23
+
24
+ CSV.foreach(path, skip_blanks: true) do |row|
25
+ begin
26
+ if $INPUT_LINE_NUMBER == 1
27
+ raise Csv2qtiError, "Course title not in first cell" unless row[0]
28
+ course = Course.new(row[0], path)
29
+ next
30
+ end
31
+
32
+ if row[1] == 'Title'
33
+ # new Primary outcome
34
+ current_primary = nil
35
+ current_enabling = nil
36
+ elsif row[0]
37
+ # new outcome row
38
+ current_enabling = nil
39
+ if current_primary
40
+ # New enabling outcome
41
+ current_enabling = current_primary.add_enabling_outcome(row)
42
+ # there is usually a question there too
43
+ current_enabling.add_question(row)
44
+ else
45
+ # New primary Outcome
46
+ current_primary = course.add_primary_outcome(row)
47
+ end
48
+ elsif current_enabling
49
+ current_enabling.add_question(row)
50
+ elsif row[2] == "Enabling Learning Outcome"
51
+ # Header row for the enabling outcomes
52
+ # If the CSVs aren't consistent we may need to use this
53
+ else
54
+ puts "what is row #{$INPUT_LINE_NUMBER}?"
55
+ puts row
56
+ end
57
+ rescue QuestionParseError => e
58
+ puts "line #{$INPUT_LINE_NUMBER + 1}: Problem parsing question: #{$!.message} (just Skipping)"
59
+ rescue Csv2qtiError => e
60
+ puts "line #{$INPUT_LINE_NUMBER + 1}: Error: #{$!.message}"
61
+ raise e
62
+ rescue
63
+ puts "line #{$INPUT_LINE_NUMBER + 1}: Unknown Error for this data:"
64
+ puts row
65
+ raise $!
66
+ end
67
+ end
68
+
69
+ course
70
+ end
71
+ end
72
+
73
+ require 'csv2qti/course'
74
+ require 'csv2qti/outcome'
75
+ require 'csv2qti/question'
@@ -0,0 +1,15 @@
1
+ module QuestionFixtures
2
+ MC = [nil, nil, nil, nil, "OLI: Intro to Biology, module 30, p182-183", "CC BY-NC-SA ", nil,
3
+ "mc", "Human eye color is a ____ trait.", "polygenic", "epistatic", "epigenetic.", "CC", nil]
4
+
5
+ IMAGE = ["8.2", "Genetics and Disease", "Explain the conventions...", "a0db89e6-9afe-4864-ac7b-29843833595e", "Genetics and Disease Outline", "CC BY", "4/10/2015",
6
+ "mc", "Given the punnett square below, choose the right answer? (image: https://example.com/Bio_C8_LO2.jpg)", "Half", "All will have red eyes", "All will have white eyes.", nil, nil]
7
+
8
+ MS = [nil, nil, nil, nil, nil, nil, nil,
9
+ "mmc", "Select the answers that help define enzymes.", "*Helper\n*chains\n*Lower energies",
10
+ "force a reaction", "Increase energy", nil, "edited"]
11
+
12
+ MATCHING = [nil, nil, nil, nil, "Proteins (Part I)", "CC BY", "4/14/2015",
13
+ "matching", "Match the letters to the molecular components.",
14
+ "A—Alpha Carbon\nB—Amino Group\nC—Carboxyl Group\nD—Hydrogen Atom\nE—R Group", nil, nil, nil, nil]
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ require 'csv2qti'
4
+ require_relative 'fixtures/quiz_questions'
5
+
6
+ describe Csv2qti::Matching do
7
+
8
+ subject { Csv2qti::Matching.new(QuestionFixtures::MATCHING) }
9
+
10
+ it "pulls out the matches" do
11
+ subject.answers.must_equal [["A", "Alpha Carbon"],
12
+ ["B", "Amino Group"],
13
+ ["C", "Carboxyl Group"],
14
+ ["D", "Hydrogen Atom"],
15
+ ["E", "R Group"]]
16
+ end
17
+
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ require 'csv2qti'
4
+ require_relative 'fixtures/quiz_questions'
5
+
6
+ describe Csv2qti::MultipleChoice do
7
+
8
+ subject { Csv2qti::MultipleChoice.new(QuestionFixtures::MC) }
9
+
10
+ it "pulls out the stem" do
11
+ subject.stem.must_equal "Human eye color is a ____ trait."
12
+ end
13
+
14
+ it "pulls out the answer" do
15
+ subject.answer.must_equal "polygenic"
16
+ end
17
+
18
+ it "pulls out the distractors" do
19
+ subject.distractors.must_equal ["epistatic", "epigenetic."]
20
+ end
21
+
22
+ end
@@ -0,0 +1,18 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ require 'csv2qti'
4
+ require_relative 'fixtures/quiz_questions'
5
+
6
+ describe Csv2qti::MultipleSelect do
7
+
8
+ subject { Csv2qti::MultipleSelect.new(QuestionFixtures::MS) }
9
+
10
+ it "pulls out the answers" do
11
+ subject.answers.must_equal ['Helper', 'chains', 'Lower energies']
12
+ end
13
+
14
+ it "pulls out the distractors" do
15
+ subject.distractors.must_equal ["force a reaction", "Increase energy"]
16
+ end
17
+
18
+ end
@@ -0,0 +1,30 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ require 'csv2qti'
4
+ require_relative 'fixtures/quiz_questions'
5
+
6
+ describe Csv2qti::Outcome do
7
+
8
+ subject { Csv2qti::Outcome.new(QuestionFixtures::IMAGE) }
9
+
10
+ it "pulls out number" do
11
+ subject.number.must_equal '8.2'
12
+ end
13
+
14
+ it "pulls out the title" do
15
+ subject.title.must_equal "Genetics and Disease"
16
+ end
17
+
18
+ it "pulls out the description" do
19
+ subject.description.must_equal "Explain the conventions..."
20
+ end
21
+
22
+ it "pulls out the license" do
23
+ subject.license.must_equal "CC BY"
24
+ end
25
+
26
+ it "pulls out the GUID" do
27
+ subject.guid.must_equal "a0db89e6-9afe-4864-ac7b-29843833595e"
28
+ end
29
+
30
+ end
@@ -0,0 +1,23 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ require 'csv2qti'
4
+ require_relative 'fixtures/quiz_questions'
5
+
6
+ describe Csv2qti::MultipleChoice do
7
+
8
+ subject { Csv2qti::Question.new(QuestionFixtures::MC) }
9
+
10
+ it "pulls out the stem" do
11
+ subject.stem.must_equal "Human eye color is a ____ trait."
12
+ end
13
+
14
+ it "pulls out the license" do
15
+ subject.license.must_equal "CC"
16
+ end
17
+
18
+ it "converts image text" do
19
+ q = Csv2qti::Question.new(QuestionFixtures::IMAGE)
20
+ q.stem.must_equal %{Given the punnett square below, choose the right answer? <img src="https://example.com/Bio_C8_LO2.jpg" />}
21
+ end
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv2qti_lumen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bracken Mosbacker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: canvas_cc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - bracken@lumenlearning.com
72
+ executables:
73
+ - csv2qti
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/csv2qti
83
+ - csv2qti.gemspec
84
+ - lib/csv2qti.rb
85
+ - lib/csv2qti/course.rb
86
+ - lib/csv2qti/outcome.rb
87
+ - lib/csv2qti/question.rb
88
+ - lib/csv2qti/question_types/matching.rb
89
+ - lib/csv2qti/question_types/multiple_choice.rb
90
+ - lib/csv2qti/question_types/multiple_select.rb
91
+ - lib/csv2qti/version.rb
92
+ - test/fixtures/quiz_questions.rb
93
+ - test/matching_test.rb
94
+ - test/multiple_choice_test.rb
95
+ - test/multiple_select_test.rb
96
+ - test/outcome_test.rb
97
+ - test/question_test.rb
98
+ homepage: ''
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.4.6
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Converts a specifically-formatted CSV into QTI.
122
+ test_files:
123
+ - test/fixtures/quiz_questions.rb
124
+ - test/matching_test.rb
125
+ - test/multiple_choice_test.rb
126
+ - test/multiple_select_test.rb
127
+ - test/outcome_test.rb
128
+ - test/question_test.rb