Quiz Stats - Normalize input

Ensure all input hashes are using symbol keys.

Closes CNVS-13158

TEST PLAN
---- ----

Code changes. Test plan is similar to
https://gerrit.instructure.com/#/c/35096/

Change-Id: Ie1db45e2a5875e410a758c0b2f14594345212b5d
Reviewed-on: https://gerrit.instructure.com/35098
Reviewed-by: Derek DeVries <ddevries@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Caleb Guanzon <cguanzon@instructure.com>
Product-Review: Ahmad Amireh <ahmad@instructure.com>
This commit is contained in:
Ahmad Amireh 2014-05-17 17:44:07 +03:00
parent 457e55d6a2
commit d7a23ea23d
4 changed files with 137 additions and 0 deletions

View File

@ -360,6 +360,10 @@ class Quizzes::QuizStatistics::StudentAnalysis < Quizzes::QuizStatistics::Report
# "multiple_responses"=>false}],
def stats_for_question(question, responses)
if CQS.can_analyze?(question)
# the gem expects all hash keys to be symbols:
question = CQS::Util.deep_symbolize_keys(question)
responses = responses.map(&CQS::Util.method(:deep_symbolize_keys))
analysis = CQS.analyze(question, responses)
return question.to_hash.merge(analysis).with_indifferent_access

View File

@ -1,5 +1,6 @@
module CanvasQuizStatistics
require 'canvas_quiz_statistics/version'
require 'canvas_quiz_statistics/util'
require 'canvas_quiz_statistics/analyzers'
def self.can_analyze?(question_data)

View File

@ -0,0 +1,39 @@
#
# Copyright (C) 2014 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module CanvasQuizStatistics
module Util
# Converts a hash to use symbol keys.
#
# Works on nested hashes, and hashes inside of arrays.
def self.deep_symbolize_keys(input)
return input unless input.is_a?(Hash)
input.inject({}) do |result, (key, value)|
new_key = key.is_a?(String) ? key.to_sym : key
new_value = case value
when Hash then deep_symbolize_keys(value)
when Array then value.map(&method(:deep_symbolize_keys))
else value
end
result[new_key] = new_value
result
end
end
end
end

View File

@ -0,0 +1,93 @@
require 'spec_helper'
describe CanvasQuizStatistics::Util do
Util = CanvasQuizStatistics::Util
describe '#deep_symbolize_keys' do
it 'does nothing on anything but a Hash' do
Util.deep_symbolize_keys(5).should == 5
Util.deep_symbolize_keys([]).should == []
Util.deep_symbolize_keys(nil).should == nil
end
it 'should symbolize top-level keys' do
Util.deep_symbolize_keys({ 'a' => 'b', c: 'd' }).should == {
a: 'b',
c: 'd'
}
end
it 'should symbolize keys of nested hashes' do
Util.deep_symbolize_keys({
'e' => {
'f' => 'g',
h: 'i'
}
}).should == {
e: {
f: 'g',
h: 'i'
}
}
end
it 'should symbolize keys of hashes inside arrays' do
Util.deep_symbolize_keys({
'e' => [{
'f' => 'g',
h: 'i'
}]
}).should == {
e: [{
f: 'g',
h: 'i'
}]
}
end
it 'should symbolize all sorts of things' do
Util.deep_symbolize_keys({
item1: 'value1',
"item2" => 'value2',
hash: {
item3: 'value3',
"item4" => 'value4'
},
'array' => [{
"item5" => 'value5',
item6: 'value6'
}]
}).should == {
item1: 'value1',
item2: 'value2',
hash: {
item3: 'value3',
item4: 'value4'
},
array: [{
item5: 'value5',
item6: 'value6'
}]
}
end
it 'should work with numbers for keys' do
Util.deep_symbolize_keys({
"1" => "first",
"2" => "second"
}).should == {
:"1" => "first",
:"2" => "second"
}
end
it 'should skip nils and items that cant be symbolized' do
Util.deep_symbolize_keys({ nil => 'foo' }).should == { nil => 'foo' }
end
it 'should only munge hashes' do
Util.deep_symbolize_keys([]).should == []
Util.deep_symbolize_keys([{ 'foo' => 'bar' }]).should == [{ 'foo' => 'bar' }]
end
end
end