Commit 182f2953 authored by Zac Wood's avatar Zac Wood

Added simple tests, refactored data loading

parent baf8caf8
......@@ -15,6 +15,5 @@ class Section < ApplicationRecord
validates :start_date, presence: true
validates :end_date, presence: true
validates :days, presence: true
validates :start_time, presence: true
validates :end_time, presence: true
validates :course_id, presence: true
end
require 'rubyXL'
# Provides utilities for loading schedules from GMU's excel files.
class ExcelLoader
def initialize(file_path)
workbook = RubyXL::Parser.parse(file_path)
@rows = workbook[0]
@rows = @rows.drop(16) # the first 16 rows are junk data, so remove them
@semester = Semester.create! season: 'Fall', year: '2018'
@current_course = nil
end
# Loads all data from the Excel file into the database.
def load_data
@rows.each do |row|
if (course = configure_course?(row)) # If this row contained a course, save it
course.save!
@current_course = course
end
configure_section?(row)&.save! # If this row contained a section, save it
end
end
private
# Prints the failure, deletes all data added during loading, and raises the failure error.
def fail(error)
p error.message
p error.backtrace
delete_all_records
raise error
end
# Deletes all records from the database.
def delete_all_records
Semester.delete_all
Course.delete_all
Section.delete_all
end
def configure_course?(row)
course_name = row&.cells[1]&.value
course = nil
# Ensure the course name is valid
if course_name && !course_name.empty? && course_name != 'Total'
# Split the name into its two components, i.e. "CS 112" => ["CS", "112"]
name_components = course_name.split(' ')
# Try to save the new course
course = Course.new
course.subject = name_components[0]
course.course_number = name_components[1]
course.semester = @semester
end
return course
end
def configure_section?(row)
# Get all the info out of the current row
section_name = row&.cells[2]&.value
crn = row&.cells[6]&.value
schedule_type = row&.cells[8]&.value
section_title = row&.cells[11]&.value
instructor = row&.cells[16]&.value
start_date = row&.cells[18]&.value
end_date = row&.cells[21]&.value
days = row&.cells[22]&.value
times = row&.cells[23]&.value
location = row&.cells[25]&.value
# TODO: Add campus, notes, and size limit fields
section = nil
# If there is no valid section name, just continue to the next row
unless !section_name || section_name&.empty? || section_name == 'Total'
# Create the new section
section = Section.new
# Add all fields to the section
section.name = section_name
section.course = @current_course
section.crn = crn
section.section_type = schedule_type
section.title = section_title
section.instructor = instructor
section.start_date = start_date
section.end_date = end_date
section.days = days
# The time field in the spreadsheet uses the format "start_time - end_time" i.e. "12:00 PM - 1:15 PM".
# So, split the times string by the - character
time_strs = times.split('-')
section.start_time = time_strs[0].strip
section.end_time = time_strs[1].strip
section.location = location
# Save the section to the database
end
return section
end
end
......@@ -5,98 +5,14 @@
#
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
# Character.create(name: 'Luke', movie: movies.first)
require 'rubyXL'
# Open the data file...this takes a while
workbook = RubyXL::Parser.parse('db/data/allsections.xlsx')
rows = workbook[0]
puts 'Done parsing!'
# The first 16 rows are not actual data, so remove them
rows = rows.drop(16)
# Keep track of the course each section is for
current_course = nil
# Create the Semester object that all courses will belong to
semester = Semester.create season: "Fall", year: "2018"
semester.save
# Loop through all the rows in the date
rows.each do | row |
# Get all the info out of the current row
course_name = row&.cells[1]&.value
section_name = row&.cells[2]&.value
crn = row&.cells[6]&.value
schedule_type = row&.cells[8]&.value
section_title = row&.cells[11]&.value
instructor = row&.cells[16]&.value
start_date = row&.cells[18]&.value
end_date = row&.cells[21]&.value
days = row&.cells[22]&.value
times = row&.cells[23]&.value
location = row&.cells[25]&.value
# Ensure the course name is valid
if course_name && !course_name.empty? && course_name != 'Total'
# Split the name into its two components, i.e. "CS 112" => ["CS", "112"]
name_components = course_name.split(' ')
# Create and save the course, and set it to be the current_course
current_course = Course.create subject: name_components[0], course_number: name_components[1], semester: semester
current_course.save
puts "Created course named: #{current_course.subject} #{current_course.course_number}"
end
# If there is no valid section name, just continue to the next row
if !section_name || section_name&.empty? || section_name == 'Total'
next
else
# Create the new section
section = Section.new
# Add all fields to the section, ensuring each is valid
section.name = section_name
section.course = current_course
if crn
section.crn = crn
end
if schedule_type
section.section_type = schedule_type
end
if section_title
section.title = section_title
end
if instructor
section.instructor = instructor
end
if start_date
section.start_date = start_date
end
if end_date
section.end_date = end_date
end
if days
section.days = days
end
if times
# The time field in the spreadsheet uses the format "start_time - end_time" i.e. "12:00 PM - 1:15 PM".
# So, split the times string by the - character
time_strs = times.split('-')
section.start_time = time_strs[0].strip
section.end_date = time_strs[1].strip
end
if location
section.location = location
end
# Save the section to the database
section.save
puts "Created section for named #{section.name}"
end
require_relative 'excel_loader'
if Rails.env == 'test'
loader = ExcelLoader.new 'db/data/testdata.xlsx'
loader.load_data
else
loader = ExcelLoader.new 'db/data/allsections.xlsx'
loader.load_data
end
......@@ -3,7 +3,6 @@ require 'test_helper'
class SectionsControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get url_for controller: 'sections', action: 'index', course_id: 1
# get 'api/'
assert_response :success
end
end
require 'test_helper'
class CourseTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test 'fails with improper data' do
assert_raise do
Course.create! course_number: nil, subject: nil, semester_id: nil
end
end
test 'creates with proper data' do
Course.create! course_number: '112', subject: 'CS', semester_id: 1
end
end
require 'test_helper'
load 'db/excel_loader.rb'
class ExcelLoaderTest < ActiveSupport::TestCase
NUMBER_ADDED_BY_FIXTURES = 2
test 'loads data correctly' do
loader = ExcelLoader.new 'db/data/testdata.xlsx'
loader.load_data
assert(Semester.count > NUMBER_ADDED_BY_FIXTURES, 'No semester loaded')
assert(Course.count > NUMBER_ADDED_BY_FIXTURES, 'No courses loaded')
assert(Section.count > NUMBER_ADDED_BY_FIXTURES, 'No sections loaded')
end
end
require 'test_helper'
class SectionTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test 'fails with improper data' do
assert_raise do
Section.create! name: nil, crn: nil, title: nil, start_date: nil, end_date: nil, days: nil
end
end
test 'succeeds with proper data' do
Section.create! name: 'Test section', crn: '12345', title: 'Test title', start_date: Date.today, end_date: Date.today, days: 'MWF', course_id: 1
end
end
require 'test_helper'
class SemesterTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test "create fails with no data" do
assert_raise do
Semester.create!(season: nil, year: nil)
end
end
test 'create successful' do
Semester.create!(season: 'Test', year: 'Test')
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment