surveyor 0.18.1 → 0.18.2
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 +6 -0
- data/VERSION +1 -1
- data/features/redcap.feature +1 -1
- data/lib/surveyor/models/survey_methods.rb +1 -1
- data/lib/surveyor/parser.rb +6 -3
- data/lib/surveyor/redcap_parser.rb +13 -4
- data/spec/lib/parser_spec.rb +3 -1
- data/spec/lib/redcap_parser_spec.rb +5 -0
- data/spec/models/answer_spec.rb +6 -1
- data/spec/models/dependency_spec.rb +9 -1
- data/spec/models/question_spec.rb +10 -1
- data/spec/models/survey_section_spec.rb +6 -0
- data/spec/models/survey_spec.rb +5 -1
- data/spec/models/validation_spec.rb +9 -0
- data/surveyor.gemspec +2 -2
- metadata +4 -4
data/CHANGELOG
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.18.
|
1
|
+
0.18.2
|
data/features/redcap.feature
CHANGED
@@ -3,7 +3,7 @@ module Surveyor
|
|
3
3
|
module SurveyMethods
|
4
4
|
def self.included(base)
|
5
5
|
# Associations
|
6
|
-
base.send :has_many, :sections, :class_name => "SurveySection", :order => 'display_order'
|
6
|
+
base.send :has_many, :sections, :class_name => "SurveySection", :order => 'display_order', :dependent => :destroy
|
7
7
|
base.send :has_many, :sections_with_questions, :include => :questions, :class_name => "SurveySection", :order => 'display_order'
|
8
8
|
base.send :has_many, :response_sets
|
9
9
|
|
data/lib/surveyor/parser.rb
CHANGED
@@ -7,7 +7,7 @@ module Surveyor
|
|
7
7
|
# Class methods
|
8
8
|
def self.parse(str)
|
9
9
|
puts
|
10
|
-
Surveyor::Parser.new.
|
10
|
+
Surveyor::Parser.new.parse(str)
|
11
11
|
puts
|
12
12
|
end
|
13
13
|
|
@@ -15,7 +15,10 @@ module Surveyor
|
|
15
15
|
def initialize
|
16
16
|
self.context = {}
|
17
17
|
end
|
18
|
-
|
18
|
+
def parse(str)
|
19
|
+
instance_eval(str)
|
20
|
+
return context[:survey]
|
21
|
+
end
|
19
22
|
# This method_missing does all the heavy lifting for the DSL
|
20
23
|
def method_missing(missing_method, *args, &block)
|
21
24
|
method_name, reference_identifier = missing_method.to_s.split("_", 2)
|
@@ -37,7 +40,7 @@ module Surveyor
|
|
37
40
|
puts
|
38
41
|
print context[type.to_sym].save ? "saved. " : " not saved! #{context[type.to_sym].errors.each_full{|x| x }.join(", ")} "
|
39
42
|
end
|
40
|
-
context[type.to_sym].clear(context)
|
43
|
+
context[type.to_sym].clear(context) unless type == 'survey'
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -39,6 +39,7 @@ module Surveyor
|
|
39
39
|
puts = "Oops. Not a valid CSV file."
|
40
40
|
# ensure
|
41
41
|
end
|
42
|
+
return context[:survey]
|
42
43
|
end
|
43
44
|
def missing_columns(r)
|
44
45
|
required_columns - r.headers.map(&:to_s)
|
@@ -162,6 +163,14 @@ class DependencyCondition < ActiveRecord::Base
|
|
162
163
|
end
|
163
164
|
class Answer < ActiveRecord::Base
|
164
165
|
def self.build_and_set(context, r)
|
166
|
+
case r[:field_type]
|
167
|
+
when "text"
|
168
|
+
context[:answer] = context[:question].answers.build(:response_class => "string", :text => "Text")
|
169
|
+
when "notes"
|
170
|
+
context[:answer] = context[:question].answers.build(:response_class => "text", :text => "Notes")
|
171
|
+
when "file"
|
172
|
+
puts "\n!!! skipping answer: file"
|
173
|
+
end
|
165
174
|
r[:choices_or_calculations].to_s.split("|").each do |pair|
|
166
175
|
aref, atext = pair.strip.split(", ")
|
167
176
|
if aref.blank? or atext.blank?
|
@@ -198,24 +207,24 @@ class Validation < ActiveRecord::Base
|
|
198
207
|
when "email"
|
199
208
|
context[:question].answers.each do |a|
|
200
209
|
context[:validation] = a.validations.build(:rule => "A")
|
201
|
-
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :
|
210
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp => "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$")
|
202
211
|
end
|
203
212
|
when "integer"
|
204
213
|
context[:question].display_type = :integer if context[:question].display_type == :string
|
205
214
|
context[:question].answers.each do |a|
|
206
215
|
context[:validation] = a.validations.build(:rule => "A")
|
207
|
-
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :
|
216
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp => "\d+")
|
208
217
|
end
|
209
218
|
when "number"
|
210
219
|
context[:question].display_type = :float if context[:question].display_type == :string
|
211
220
|
context[:question].answers.each do |a|
|
212
221
|
context[:validation] = a.validations.build(:rule => "A")
|
213
|
-
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :
|
222
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp => "^\d*(,\d{3})*(\.\d*)?$")
|
214
223
|
end
|
215
224
|
when "phone"
|
216
225
|
context[:question].answers.each do |a|
|
217
226
|
context[:validation] = a.validations.build(:rule => "A")
|
218
|
-
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :
|
227
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp => "\d{3}.*\d{4}")
|
219
228
|
end
|
220
229
|
end
|
221
230
|
end
|
data/spec/lib/parser_spec.rb
CHANGED
@@ -25,6 +25,8 @@ describe Surveyor::Parser do
|
|
25
25
|
it "should identify models that take blocks" do
|
26
26
|
@parser.send(:block_models).should == %w(survey survey_section question_group)
|
27
27
|
end
|
28
|
-
|
28
|
+
it "should return a survey object" do
|
29
|
+
Surveyor::Parser.new.parse("survey 'hi' do\n end").is_a?(Survey).should be_true
|
30
|
+
end
|
29
31
|
|
30
32
|
end
|
@@ -45,4 +45,9 @@ describe Surveyor::RedcapParser do
|
|
45
45
|
Dependency.decompose_component('[initial_119(2)] = "1"').should == {:question_reference => 'initial_119', :operator => '==', :answer_reference => '2'}
|
46
46
|
Dependency.decompose_component('[f1_q15] >= 21').should == {:question_reference => 'f1_q15', :operator => '>=', :integer_value => '21'}
|
47
47
|
end
|
48
|
+
it "should return a survey object" do
|
49
|
+
x = %("Variable / Field Name","Form Name","Field Units","Section Header","Field Type","Field Label","Choices OR Calculations","Field Note","Text Validation Type","Text Validation Min","Text Validation Max",Identifier?,"Branching Logic (Show field only if...)","Required Field?"\nstudy_id,demographics,,,text,"Study ID",,,,,,,,)
|
50
|
+
Surveyor::RedcapParser.new.parse(x, "redcaptest").is_a?(Survey).should be_true
|
51
|
+
end
|
52
|
+
|
48
53
|
end
|
data/spec/models/answer_spec.rb
CHANGED
@@ -26,5 +26,10 @@ describe Answer, "when creating a new answer" do
|
|
26
26
|
@answer.response_class = "B"
|
27
27
|
@answer.renderer.should == :a_b
|
28
28
|
end
|
29
|
-
|
29
|
+
it "should delete validation when it is deleted" do
|
30
|
+
v_id = Factory(:validation, :answer => @answer).id
|
31
|
+
@answer.destroy
|
32
|
+
Validation.find_by_id(v_id).should be_nil
|
33
|
+
end
|
34
|
+
|
30
35
|
end
|
@@ -77,5 +77,13 @@ describe Dependency, "when evaluating dependency conditions of a question in a r
|
|
77
77
|
@dep3.conditions_hash(@response_set).should == {:A => true, :B => false}
|
78
78
|
@dep4.conditions_hash(@response_set).should == {:A => true, :B => false, :C => true}
|
79
79
|
end
|
80
|
-
|
81
80
|
end
|
81
|
+
describe Dependency, "with conditions" do
|
82
|
+
@dependency = Dependency.new(:rule => "A and B and C", :question_id => 1)
|
83
|
+
Factory(:dependency_condition, :dependency => @dependency, :rule_key => "A")
|
84
|
+
Factory(:dependency_condition, :dependency => @dependency, :rule_key => "B")
|
85
|
+
Factory(:dependency_condition, :dependency => @dependency, :rule_key => "C")
|
86
|
+
dc_ids = @dependency.dependency_conditions.map(&:id)
|
87
|
+
@dependency.destroy
|
88
|
+
dc_ids.each{|id| DependencyCondition.find_by_id(id).should == nil}
|
89
|
+
end
|
@@ -45,7 +45,11 @@ describe Question, "that has answers" do
|
|
45
45
|
it "should retrieve those answers in display_order" do
|
46
46
|
@question.answers.map(&:display_order).should == [1,2,3]
|
47
47
|
end
|
48
|
-
|
48
|
+
it "should delete answers when it is deleted" do
|
49
|
+
answer_ids = @question.answers.map(&:id)
|
50
|
+
@question.destroy
|
51
|
+
answer_ids.each{|id| Answer.find_by_id(id).should be_nil}
|
52
|
+
end
|
49
53
|
end
|
50
54
|
|
51
55
|
describe Question, "when interacting with an instance" do
|
@@ -81,5 +85,10 @@ describe Question, "with dependencies" do
|
|
81
85
|
@question.stub!(:dependency).and_return(@dependency)
|
82
86
|
@question.triggered?(@rs).should == true
|
83
87
|
end
|
88
|
+
it "should delete dependency when it is deleted" do
|
89
|
+
dep_id = Factory(:dependency, :question => @question).id
|
90
|
+
@question.destroy
|
91
|
+
Dependency.find_by_id(dep_id).should be_nil
|
92
|
+
end
|
84
93
|
|
85
94
|
end
|
@@ -30,4 +30,10 @@ describe SurveySection, "with questions" do
|
|
30
30
|
@survey_section.questions.should have(3).questions
|
31
31
|
@survey_section.questions.should == [@q2,@q3,@q1]
|
32
32
|
end
|
33
|
+
it "should delete questions when it is deleted" do
|
34
|
+
question_ids = @survey_section.questions.map(&:id)
|
35
|
+
@survey_section.destroy
|
36
|
+
question_ids.each{|id| Question.find_by_id(id).should be_nil}
|
37
|
+
end
|
38
|
+
|
33
39
|
end
|
data/spec/models/survey_spec.rb
CHANGED
@@ -45,7 +45,11 @@ describe Survey, "that has sections" do
|
|
45
45
|
@survey.sections_with_questions.map(&:questions).flatten.should have(4).questions
|
46
46
|
@survey.sections_with_questions.map(&:questions).flatten.should == [@q4,@q1,@q3,@q2]
|
47
47
|
end
|
48
|
-
|
48
|
+
it "should delete survey sections when it is deleted" do
|
49
|
+
section_ids = @survey.sections.map(&:id)
|
50
|
+
@survey.destroy
|
51
|
+
section_ids.each{|id| SurveySection.find_by_id(id).should be_nil}
|
52
|
+
end
|
49
53
|
end
|
50
54
|
|
51
55
|
# Methods
|
@@ -58,3 +58,12 @@ describe Validation, "reporting its status" do
|
|
58
58
|
|
59
59
|
end
|
60
60
|
end
|
61
|
+
describe Validation, "with conditions" do
|
62
|
+
@validation = Factory(:validation)
|
63
|
+
Factory(:validation_condition, :validation => @validation, :rule_key => "A")
|
64
|
+
Factory(:validation_condition, :validation => @validation, :rule_key => "B")
|
65
|
+
Factory(:validation_condition, :validation => @validation, :rule_key => "C")
|
66
|
+
v_ids = @validation.validation_conditions.map(&:id)
|
67
|
+
@validation.destroy
|
68
|
+
v_ids.each{|id| DependencyCondition.find_by_id(id).should == nil}
|
69
|
+
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.18.
|
8
|
+
s.version = "0.18.2"
|
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-01-
|
12
|
+
s.date = %q{2011-01-20}
|
13
13
|
s.email = %q{yoon@northwestern.edu}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.md"
|
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: 83
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 18
|
9
|
-
-
|
10
|
-
version: 0.18.
|
9
|
+
- 2
|
10
|
+
version: 0.18.2
|
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-01-
|
19
|
+
date: 2011-01-20 00:00:00 -06:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|