surveyor 0.19.6 → 0.19.7
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/CHANGELOG +11 -0
- data/README.md +4 -3
- data/VERSION +1 -1
- data/app/views/partials/_question.html.haml +1 -1
- data/doc/surveyor_models.png +0 -0
- data/doc/surveyor_models2.png +0 -0
- data/lib/surveyor/common.rb +3 -3
- data/lib/surveyor/models/dependency_condition_methods.rb +1 -0
- data/lib/surveyor/models/response_set_methods.rb +7 -3
- data/lib/surveyor/models/survey_methods.rb +3 -2
- data/lib/surveyor/redcap_parser.rb +5 -3
- data/spec/models/dependency_condition_spec.rb +22 -1
- data/spec/models/response_set_spec.rb +11 -2
- data/spec/models/survey_spec.rb +15 -8
- data/surveyor.gemspec +4 -2
- metadata +6 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
0.19.7
|
2
|
+
|
3
|
+
* fix accidentally allowing through blank pick => any answers
|
4
|
+
* rewrote a test to reflect re-saving a survey via an admin controller
|
5
|
+
* stop survey titles from appending '1' to itself when calling update attributes
|
6
|
+
* fix response saving and dependencies on pick one/many with string. closes #158
|
7
|
+
* changed fastercsv to csv for ruby 1.9. closes #111
|
8
|
+
* changed .to_s to .join for ruby 1.9
|
9
|
+
* Merge pull request #137 from keviniano/master
|
10
|
+
* surveyor models
|
11
|
+
|
1
12
|
0.19.6
|
2
13
|
|
3
14
|
* fix parsing of group questions with dependencies. closes #160
|
data/README.md
CHANGED
@@ -97,11 +97,12 @@ and read surveys/EXTENDING\_SURVEYOR
|
|
97
97
|
|
98
98
|
Surveyor depends on:
|
99
99
|
|
100
|
-
* Ruby (1.8.7 - 1.9.
|
100
|
+
* Ruby (1.8.7 - 1.9.2)
|
101
101
|
* Rails 2.3
|
102
|
-
* HAML
|
102
|
+
* HAML
|
103
|
+
* SASS
|
104
|
+
* fastercsv (or CSV for ruby 1.9) for csv exports
|
103
105
|
* formtastic
|
104
|
-
* fastercsv for csv exports
|
105
106
|
* UUID
|
106
107
|
|
107
108
|
To work on the code fork this github project. Run:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.19.
|
1
|
+
0.19.7
|
@@ -1,7 +1,7 @@
|
|
1
1
|
-# TODO: js for slider
|
2
2
|
- rg ||= nil
|
3
3
|
- renderer = q.renderer(g ||= nil)
|
4
|
-
- f.inputs q_text(q), :id => rg ? "q_#{q.id}_#{rg
|
4
|
+
- f.inputs q_text(q), :id => rg ? "q_#{q.id}_#{rg}" : "q_#{q.id}", :class => "q_#{renderer} #{q.css_class(@response_set)}" do
|
5
5
|
%span.help= q.help_text
|
6
6
|
- case renderer
|
7
7
|
- when :image, :label
|
Binary file
|
Binary file
|
data/lib/surveyor/common.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Surveyor
|
2
2
|
class Common
|
3
|
-
RAND_CHARS = [('a'..'z'), ('A'..'Z'), (0..9)].map{|r| r.to_a}.flatten.
|
3
|
+
RAND_CHARS = [('a'..'z'), ('A'..'Z'), (0..9)].map{|r| r.to_a}.flatten.join
|
4
4
|
OPERATORS = %w(== != < > <= >= =~)
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def make_tiny_code(len = 10)
|
8
8
|
if RUBY_VERSION < "1.8.7"
|
9
|
-
(1..len).to_a.map{|i| RAND_CHARS[rand(RAND_CHARS.size), 1] }.
|
9
|
+
(1..len).to_a.map{|i| RAND_CHARS[rand(RAND_CHARS.size), 1] }.join
|
10
10
|
else
|
11
|
-
len.times.map{|i| RAND_CHARS[rand(RAND_CHARS.size), 1] }.
|
11
|
+
len.times.map{|i| RAND_CHARS[rand(RAND_CHARS.size), 1] }.join
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fastercsv'
|
2
|
+
require 'csv'
|
1
3
|
module Surveyor
|
2
4
|
module Models
|
3
5
|
module ResponseSetMethods
|
@@ -36,7 +38,9 @@ module Surveyor
|
|
36
38
|
result
|
37
39
|
end
|
38
40
|
def has_blank_value?(hash)
|
39
|
-
hash["answer_id"].blank?
|
41
|
+
return true if hash["answer_id"].blank?
|
42
|
+
return false if (q = Question.find_by_id(hash["question_id"])) and q.pick == "one"
|
43
|
+
hash.any?{|k,v| v.is_a?(Array) ? v.all?{|x| x.to_s.blank?} : v.to_s.blank?}
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
@@ -63,8 +67,8 @@ module Surveyor
|
|
63
67
|
qcols = Question.content_columns.map(&:name) - %w(created_at updated_at)
|
64
68
|
acols = Answer.content_columns.map(&:name) - %w(created_at updated_at)
|
65
69
|
rcols = Response.content_columns.map(&:name)
|
66
|
-
|
67
|
-
|
70
|
+
csvlib = CSV.const_defined?(:Reader) ? FasterCSV : CSV
|
71
|
+
result = csvlib.generate do |csv|
|
68
72
|
csv << (access_code ? ["response set access code"] : []) + qcols.map{|qcol| "question.#{qcol}"} + acols.map{|acol| "answer.#{acol}"} + rcols.map{|rcol| "response.#{rcol}"} if print_header
|
69
73
|
responses.each do |response|
|
70
74
|
csv << (access_code ? [self.access_code] : []) + qcols.map{|qcol| response.question.send(qcol)} + acols.map{|acol| response.answer.send(acol)} + rcols.map{|rcol| response.send(rcol)}
|
@@ -42,6 +42,7 @@ module Surveyor
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def title=(value)
|
45
|
+
return if value == self.title
|
45
46
|
adjusted_value = value
|
46
47
|
while Survey.find_by_access_code(Survey.to_normalized_string(adjusted_value))
|
47
48
|
i ||= 0
|
@@ -49,7 +50,7 @@ module Surveyor
|
|
49
50
|
adjusted_value = "#{value} #{i.to_s}"
|
50
51
|
end
|
51
52
|
self.access_code = Survey.to_normalized_string(adjusted_value)
|
52
|
-
super(adjusted_value)
|
53
|
+
super(adjusted_value)
|
53
54
|
# self.access_code = Survey.to_normalized_string(value)
|
54
55
|
# super
|
55
56
|
end
|
@@ -76,4 +77,4 @@ module Surveyor
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
end
|
79
|
-
end
|
80
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
%w(survey survey_section question_group question dependency dependency_condition answer validation validation_condition).each {|model| require model }
|
2
|
-
require 'fastercsv'
|
3
2
|
require 'active_support' # for humanize
|
3
|
+
require 'fastercsv'
|
4
|
+
require 'csv'
|
4
5
|
module Surveyor
|
5
6
|
class RedcapParser
|
6
7
|
# Attributes
|
@@ -19,8 +20,9 @@ module Surveyor
|
|
19
20
|
self.context = {}
|
20
21
|
end
|
21
22
|
def parse(str, filename)
|
23
|
+
csvlib = CSV.const_defined?(:Reader) ? FasterCSV : CSV
|
22
24
|
begin
|
23
|
-
|
25
|
+
csvlib.parse(str, :headers => :first_row, :return_headers => true, :header_converters => :symbol) do |r|
|
24
26
|
if r.header_row? # header row
|
25
27
|
return puts "Missing headers: #{missing_columns(r).inspect}\n\n" unless missing_columns(r).blank?
|
26
28
|
context[:survey] = Survey.new(:title => filename)
|
@@ -35,7 +37,7 @@ module Surveyor
|
|
35
37
|
end
|
36
38
|
print context[:survey].save ? "saved. " : " not saved! #{context[:survey].errors.each_full{|x| x }.join(", ")} "
|
37
39
|
# print context[:survey].sections.map(&:questions).flatten.map(&:answers).flatten.map{|x| x.errors.each_full{|y| y}.join}.join
|
38
|
-
rescue
|
40
|
+
rescue csvlib::MalformedCSVError
|
39
41
|
puts = "Oops. Not a valid CSV file."
|
40
42
|
# ensure
|
41
43
|
end
|
@@ -339,7 +339,28 @@ describe DependencyCondition do
|
|
339
339
|
@dep_c.is_met?([@response]).should be_true
|
340
340
|
end
|
341
341
|
end
|
342
|
-
|
342
|
+
|
343
|
+
describe "when evaluating a pick one/many with response_class e.g. string" do
|
344
|
+
it "should compare answer ids when the string_value is nil" do
|
345
|
+
a = Factory(:answer, :response_class => "string")
|
346
|
+
dc = Factory(:dependency_condition, :question_id => a.question.id, :answer_id => a.id, :operator => "==")
|
347
|
+
r = Factory(:response, :question_id => a.question.id, :answer_id => a.id, :string_value => "")
|
348
|
+
r.should_receive(:as).with("answer").and_return(a.id)
|
349
|
+
dc.is_met?([r]).should be_true
|
350
|
+
end
|
351
|
+
it "should compare strings when the string_value is not nil, even if it is blank" do
|
352
|
+
a = Factory(:answer, :response_class => "string")
|
353
|
+
dc = Factory(:dependency_condition, :question_id => a.question.id, :answer_id => a.id, :operator => "==", :string_value => "foo")
|
354
|
+
r = Factory(:response, :question_id => a.question.id, :answer_id => a.id, :string_value => "foo")
|
355
|
+
r.should_receive(:as).with("string").and_return("foo")
|
356
|
+
dc.is_met?([r]).should be_true
|
357
|
+
|
358
|
+
dc2 = Factory(:dependency_condition, :question_id => a.question.id, :answer_id => a.id, :operator => "==", :string_value => "")
|
359
|
+
r2 = Factory(:response, :question_id => a.question.id, :answer_id => a.id, :string_value => "")
|
360
|
+
r2.should_receive(:as).with("string").and_return("")
|
361
|
+
dc2.is_met?([r2]).should be_true
|
362
|
+
end
|
363
|
+
end
|
343
364
|
describe "when given responses whether the dependency is satisfied using 'count'" do
|
344
365
|
before(:each) do
|
345
366
|
@dep_c = DependencyCondition.new(:answer_id => nil,
|
@@ -90,7 +90,7 @@ describe ResponseSet do
|
|
90
90
|
"28" => {"question_id" => "16", "answer_id" => "", "string_value" => "foo"}, # new radio with string value, blank
|
91
91
|
"29" => {"question_id" => "17", "answer_id" => "261", "string_value" => "bar"}, # new radio with string value, selected
|
92
92
|
"30" => {"id" => "110", "question_id" => "18", "answer_id" => "271", "string_value" => "moo"}, # existing radio with string value, changed
|
93
|
-
"31" => {"id" => "111", "question_id" => "19", "answer_id" => "281", "string_value" => "mar"}
|
93
|
+
"31" => {"id" => "111", "question_id" => "19", "answer_id" => "281", "string_value" => "mar"} # existing radio with string value, unchanged
|
94
94
|
}
|
95
95
|
ResponseSet.reject_or_destroy_blanks(hash_of_hashes).should == {
|
96
96
|
# "11" => {"question_id" => "1", "answer_id" => [""]}, # new checkbox, blank
|
@@ -113,7 +113,16 @@ describe ResponseSet do
|
|
113
113
|
# "28" => {"question_id" => "16", "answer_id" => "", "string_value" => "foo"}, # new radio with string value, blank
|
114
114
|
"29" => {"question_id" => "17", "answer_id" => "261", "string_value" => "bar"}, # new radio with string value, selected
|
115
115
|
"30" => {"id" => "110", "question_id" => "18", "answer_id" => "271", "string_value" => "moo"}, # existing radio with string value, changed
|
116
|
-
"31" => {"id" => "111", "question_id" => "19", "answer_id" => "281", "string_value" => "mar"}
|
116
|
+
"31" => {"id" => "111", "question_id" => "19", "answer_id" => "281", "string_value" => "mar"} # existing radio with string value, unchanged
|
117
|
+
}
|
118
|
+
end
|
119
|
+
it "should clean up radio and string responses_attributes before passing to nested_attributes" do
|
120
|
+
@qone = Factory(:question, :pick => "one")
|
121
|
+
hash_of_hashes = {
|
122
|
+
"32" => {"question_id" => @qone.id, "answer_id" => "291", "string_value" => ""} # new radio with blank string value, selected
|
123
|
+
}
|
124
|
+
ResponseSet.reject_or_destroy_blanks(hash_of_hashes).should == {
|
125
|
+
"32" => {"question_id" => @qone.id, "answer_id" => "291", "string_value" => ""} # new radio with blank string value, selected
|
117
126
|
}
|
118
127
|
end
|
119
128
|
it "should remove responses" do
|
data/spec/models/survey_spec.rb
CHANGED
@@ -5,12 +5,12 @@ describe Survey, "when saving a new one" do
|
|
5
5
|
before(:each) do
|
6
6
|
@survey = Factory(:survey, :title => "Foo")
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
it "should be invalid without a title" do
|
10
10
|
@survey.title = nil
|
11
11
|
@survey.should have(1).error_on(:title)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "should adjust the title to save unique titles" do
|
15
15
|
original = Survey.new(:title => "Foo")
|
16
16
|
original.save.should be_true
|
@@ -21,7 +21,14 @@ describe Survey, "when saving a new one" do
|
|
21
21
|
bandwagoneer.save.should be_true
|
22
22
|
bandwagoneer.title.should == "Foo 2"
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
|
+
it "should not adjust the title when updating itself" do
|
26
|
+
original = Factory(:survey, :title => "Foo")
|
27
|
+
original.save.should be_true
|
28
|
+
original.update_attributes(:title => "Foo")
|
29
|
+
original.title.should == "Foo"
|
30
|
+
end
|
31
|
+
|
25
32
|
it "should have an api_id" do
|
26
33
|
@survey.api_id.length.should == 36
|
27
34
|
end
|
@@ -44,7 +51,7 @@ describe Survey, "that has sections" do
|
|
44
51
|
@survey.sections.should have(3).sections
|
45
52
|
@survey.sections.should == [@s3, @s1, @s2]
|
46
53
|
end
|
47
|
-
|
54
|
+
|
48
55
|
it "should return survey_sections_with_questions in display order" do
|
49
56
|
@survey.sections_with_questions.map(&:questions).flatten.should have(4).questions
|
50
57
|
@survey.sections_with_questions.map(&:questions).flatten.should == [@q4,@q1,@q3,@q2]
|
@@ -72,19 +79,19 @@ describe Survey do
|
|
72
79
|
@survey.active?.should be_true
|
73
80
|
@survey.inactive_at.should be_nil
|
74
81
|
end
|
75
|
-
|
82
|
+
|
76
83
|
it "should be able to deactivate as of a certain date/time" do
|
77
84
|
@survey.active_at = 2.days.ago
|
78
85
|
@survey.inactive_at = 3.days.ago
|
79
86
|
@survey.active?.should be_false
|
80
87
|
@survey.active_at.should be_nil
|
81
88
|
end
|
82
|
-
|
89
|
+
|
83
90
|
it "should activate and deactivate" do
|
84
91
|
@survey.activate!
|
85
92
|
@survey.active?.should be_true
|
86
93
|
@survey.deactivate!
|
87
94
|
@survey.active?.should be_false
|
88
95
|
end
|
89
|
-
|
90
|
-
end
|
96
|
+
|
97
|
+
end
|
data/surveyor.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{surveyor}
|
8
|
-
s.version = "0.19.
|
8
|
+
s.version = "0.19.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Chamberlain", "Mark Yoon"]
|
12
|
-
s.date = %q{2011-06-
|
12
|
+
s.date = %q{2011-06-23}
|
13
13
|
s.email = %q{yoon@northwestern.edu}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.md"
|
@@ -52,6 +52,8 @@ Gem::Specification.new do |s|
|
|
52
52
|
"app/views/surveyor/show.html.haml",
|
53
53
|
"ci-env.sh",
|
54
54
|
"config/routes.rb",
|
55
|
+
"doc/surveyor_models.png",
|
56
|
+
"doc/surveyor_models2.png",
|
55
57
|
"features/redcap_parser.feature",
|
56
58
|
"features/step_definitions/parser_steps.rb",
|
57
59
|
"features/step_definitions/surveyor_steps.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surveyor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 93
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 19
|
9
|
-
-
|
10
|
-
version: 0.19.
|
9
|
+
- 7
|
10
|
+
version: 0.19.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Chamberlain
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-06-
|
19
|
+
date: 2011-06-23 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -149,6 +149,8 @@ files:
|
|
149
149
|
- app/views/surveyor/show.html.haml
|
150
150
|
- ci-env.sh
|
151
151
|
- config/routes.rb
|
152
|
+
- doc/surveyor_models.png
|
153
|
+
- doc/surveyor_models2.png
|
152
154
|
- features/redcap_parser.feature
|
153
155
|
- features/step_definitions/parser_steps.rb
|
154
156
|
- features/step_definitions/surveyor_steps.rb
|