surveyor 0.19.3 → 0.19.4
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 +12 -0
- data/README.md +8 -3
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/app/views/partials/_question.html.haml +1 -1
- data/features/redcap_parser.feature +14 -0
- data/features/step_definitions/surveyor_steps.rb +15 -1
- data/features/step_definitions/web_steps.rb +10 -0
- data/features/support/redcap_siblings.csv +1 -0
- data/features/surveyor.feature +55 -0
- data/generators/surveyor/surveyor_generator.rb +1 -1
- data/generators/surveyor/templates/assets/stylesheets/sass/surveyor.sass +1 -1
- data/generators/surveyor/templates/migrate/add_api_ids.rb +13 -0
- data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +22 -0
- data/lib/surveyor/models/answer_methods.rb +1 -0
- data/lib/surveyor/models/question_methods.rb +1 -0
- data/lib/surveyor/models/response_methods.rb +12 -0
- data/lib/surveyor/models/response_set_methods.rb +17 -1
- data/lib/surveyor/models/survey_methods.rb +1 -0
- data/lib/surveyor/redcap_parser.rb +9 -1
- data/lib/surveyor/surveyor_controller_methods.rb +2 -1
- data/lib/surveyor/unparser.rb +3 -3
- data/spec/models/answer_spec.rb +4 -0
- data/spec/models/question_spec.rb +4 -0
- data/spec/models/response_set_spec.rb +18 -1
- data/spec/models/response_spec.rb +18 -0
- data/spec/models/survey_spec.rb +4 -0
- data/surveyor.gemspec +7 -2
- data/testbed/Gemfile +1 -0
- metadata +22 -6
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
0.19.4
|
2
|
+
|
3
|
+
* add api ids
|
4
|
+
* Saving response set completion time when a survey is finished.
|
5
|
+
* Fixed pick one and pick any not saving when an answer of type string exists within the options.
|
6
|
+
* Fixed problem with dropdowns inside of repeaters appearing as radio buttons.
|
7
|
+
* Updated method to get unanswered dependencies within ResultSet to also return question groups.
|
8
|
+
* Added a conditional question group to the kitchen sink survey.
|
9
|
+
* add support for question reference syntax in redcap parser. closes #124
|
10
|
+
* adding checkbox grid to kitchen sink
|
11
|
+
* hide labels on checkbox grids too. closes #121. thanks jdzak
|
12
|
+
|
1
13
|
0.19.3
|
2
14
|
|
3
15
|
* add authenticity token into ajax requests. closes #120
|
data/README.md
CHANGED
@@ -95,9 +95,14 @@ and read surveys/EXTENDING\_SURVEYOR
|
|
95
95
|
|
96
96
|
# Requirements
|
97
97
|
|
98
|
-
Surveyor depends on
|
99
|
-
|
100
|
-
|
98
|
+
Surveyor depends on:
|
99
|
+
|
100
|
+
* Ruby (1.8.7 - 1.9.1)
|
101
|
+
* Rails 2.3
|
102
|
+
* HAML/SASS
|
103
|
+
* formtastic
|
104
|
+
* fastercsv for csv exports
|
105
|
+
* UUID
|
101
106
|
|
102
107
|
To work on the code fork this github project. Run:
|
103
108
|
|
data/Rakefile
CHANGED
@@ -12,6 +12,7 @@ begin
|
|
12
12
|
gem.add_dependency 'haml'
|
13
13
|
gem.add_dependency 'fastercsv'
|
14
14
|
gem.add_dependency 'formtastic'
|
15
|
+
gem.add_dependency 'uuid'
|
15
16
|
gem.add_development_dependency "yard", ">= 0"
|
16
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
18
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.19.
|
1
|
+
0.19.4
|
@@ -5,7 +5,7 @@
|
|
5
5
|
%span.help= q.help_text
|
6
6
|
- case renderer
|
7
7
|
- when :image, :label
|
8
|
-
- when :dropdown, :inline_dropdown, :slider
|
8
|
+
- when :dropdown, :inline_dropdown, :slider, :repeater_dropdown
|
9
9
|
- r = response_for(@response_set, q, nil, rg)
|
10
10
|
- i = response_idx
|
11
11
|
- f.semantic_fields_for i, r do |ff|
|
@@ -17,3 +17,17 @@ Feature: Survey creation
|
|
17
17
|
| rule |
|
18
18
|
| A |
|
19
19
|
| A and B |
|
20
|
+
Scenario: question level dependencies
|
21
|
+
Given I parse redcap file "redcap_siblings.csv"
|
22
|
+
Then there should be 1 survey with:
|
23
|
+
||
|
24
|
+
And there should be 2 questions with:
|
25
|
+
||
|
26
|
+
And there should be 2 answers with:
|
27
|
+
||
|
28
|
+
And there should be 1 resolved dependency_conditions with:
|
29
|
+
| rule_key |
|
30
|
+
| A |
|
31
|
+
And there should be 1 dependencies with:
|
32
|
+
| rule |
|
33
|
+
| A |
|
@@ -4,7 +4,7 @@ When /^I start the "([^"]*)" survey$/ do |name|
|
|
4
4
|
click_button "Take it"
|
5
5
|
end
|
6
6
|
|
7
|
-
Then /^there should be (\d+) response set with (\d+) responses with:$/ do |rs_num, r_num, table|
|
7
|
+
Then /^there should be (\d+) response set with (\d+) responses? with:$/ do |rs_num, r_num, table|
|
8
8
|
ResponseSet.count.should == rs_num.to_i
|
9
9
|
Response.count.should == r_num.to_i
|
10
10
|
table.hashes.each do |hash|
|
@@ -36,3 +36,17 @@ end
|
|
36
36
|
Then /^the element "([^"]*)" should have the class "([^"]*)"$/ do |selector, css_class|
|
37
37
|
response.should have_selector(selector, :class => css_class)
|
38
38
|
end
|
39
|
+
|
40
|
+
Then /^the survey should be complete$/ do
|
41
|
+
ResponseSet.first.should be_complete
|
42
|
+
end
|
43
|
+
|
44
|
+
Then /^a dropdown should exist with the options "([^"]*)"$/ do |options_text|
|
45
|
+
response.should have_selector('select')
|
46
|
+
options = options_text.split(',').collect(&:strip)
|
47
|
+
within "select" do |select|
|
48
|
+
options.each do |o|
|
49
|
+
select o
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -33,13 +33,23 @@ When /^(?:|I )follow "([^"]*)" within "([^"]*)"$/ do |link, parent|
|
|
33
33
|
end
|
34
34
|
|
35
35
|
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
36
|
+
field = resolve_regexp(field)
|
36
37
|
fill_in(field, :with => value)
|
37
38
|
end
|
38
39
|
|
39
40
|
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
|
41
|
+
field = resolve_regexp(field)
|
40
42
|
fill_in(field, :with => value)
|
41
43
|
end
|
42
44
|
|
45
|
+
def resolve_regexp(expr)
|
46
|
+
if expr =~ /\/.*\//
|
47
|
+
Regexp.new(expr[1..-2])
|
48
|
+
else
|
49
|
+
expr
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
43
53
|
# Use this to fill in an entire form with data from a table. Example:
|
44
54
|
#
|
45
55
|
# When I fill in the following:
|
@@ -0,0 +1 @@
|
|
1
|
+
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?
|
data/features/surveyor.feature
CHANGED
@@ -57,6 +57,7 @@ Feature: Survey creation
|
|
57
57
|
Then there should be 1 response set with 1 responses with:
|
58
58
|
| string_value |
|
59
59
|
| beef |
|
60
|
+
Then the survey should be complete
|
60
61
|
|
61
62
|
When I start the "Favorites" survey
|
62
63
|
And I fill in "food" with "chicken"
|
@@ -97,5 +98,59 @@ Feature: Survey creation
|
|
97
98
|
Then the element "input[type='text']:first" should have the class "my_custom_class"
|
98
99
|
# Then the element "input[type='text']:last" should not contain the class attribute
|
99
100
|
|
101
|
+
Scenario: A pick one question with an option for other
|
102
|
+
Given the survey
|
103
|
+
"""
|
104
|
+
survey "Favorites" do
|
105
|
+
section "Foods" do
|
106
|
+
q "What is the best meat?", :pick => :one
|
107
|
+
a "bacon"
|
108
|
+
a "chicken"
|
109
|
+
a "beef"
|
110
|
+
a "other", :string
|
111
|
+
end
|
112
|
+
end
|
113
|
+
"""
|
114
|
+
When I start the "Favorites" survey
|
115
|
+
Then I choose "bacon"
|
116
|
+
And I press "Click here to finish"
|
117
|
+
Then there should be 1 response set with 1 response with:
|
118
|
+
| bacon |
|
119
|
+
|
120
|
+
Scenario: Repeater with a dropdown
|
121
|
+
Given the survey
|
122
|
+
"""
|
123
|
+
survey "Movies" do
|
124
|
+
section "Preferences" do
|
125
|
+
repeater "What are you favorite genres?" do
|
126
|
+
q "Make", :pick => :one, :display_type => :dropdown
|
127
|
+
a "Action"
|
128
|
+
a "Comedy"
|
129
|
+
a "Mystery"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
"""
|
134
|
+
When I start the "Movies" survey
|
135
|
+
Then a dropdown should exist with the options "Action, Comedy, Mystery"
|
100
136
|
|
137
|
+
Scenario: A pick one question with an option for other
|
138
|
+
Given the survey
|
139
|
+
"""
|
140
|
+
survey "Favorites" do
|
141
|
+
section "Foods" do
|
142
|
+
q "What is the best meat?", :pick => :one
|
143
|
+
a "bacon"
|
144
|
+
a "chicken"
|
145
|
+
a "beef"
|
146
|
+
a "other", :string
|
147
|
+
end
|
148
|
+
end
|
149
|
+
"""
|
150
|
+
When I start the "Favorites" survey
|
151
|
+
Then I choose "other"
|
152
|
+
And I fill in "/.*string_value.*/" with "shrimp"
|
153
|
+
And I press "Click here to finish"
|
154
|
+
Then there should be 1 response set with 1 response with:
|
155
|
+
| shrimp |
|
101
156
|
|
@@ -28,7 +28,7 @@ class SurveyorGenerator < Rails::Generator::Base
|
|
28
28
|
"add_display_order_to_surveys", "add_correct_answer_id_to_questions",
|
29
29
|
"add_index_to_response_sets", "add_index_to_surveys",
|
30
30
|
"add_unique_indicies", "add_section_id_to_responses",
|
31
|
-
"add_default_value_to_answers"].each_with_index do |model, i|
|
31
|
+
"add_default_value_to_answers", "add_api_ids"].each_with_index do |model, i|
|
32
32
|
unless (prev_migrations = Dir.glob("db/migrate/[0-9]*_*.rb").grep(/[0-9]+_#{model}.rb$/)).empty?
|
33
33
|
prev_migration_timestamp = prev_migrations[0].match(/([0-9]+)_#{model}.rb$/)[1]
|
34
34
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AddApiIds < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :surveys, :api_id, :string
|
4
|
+
add_column :questions, :api_id, :string
|
5
|
+
add_column :answers, :api_id, :string
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.down
|
9
|
+
remove_column :surveys, :api_id
|
10
|
+
remove_column :questions, :api_id
|
11
|
+
remove_column :answers, :api_id
|
12
|
+
end
|
13
|
+
end
|
@@ -181,6 +181,22 @@ survey "Kitchen Sink survey" do
|
|
181
181
|
q "limp|perky", :pick => :one
|
182
182
|
end
|
183
183
|
|
184
|
+
grid "For each of the car types checked, what type of options would you prefer?" do
|
185
|
+
a "Leather seats"
|
186
|
+
a "Shiny rims"
|
187
|
+
a "Subwoofer"
|
188
|
+
a "Sunroof"
|
189
|
+
a "Turbocharger"
|
190
|
+
q "SUV", :pick => :any
|
191
|
+
q "Sedan", :pick => :any
|
192
|
+
q "Coupe", :pick => :any
|
193
|
+
q "Convertible", :pick => :any
|
194
|
+
q "Minivan", :pick => :any
|
195
|
+
q "Crossover", :pick => :any
|
196
|
+
q "Wagon", :pick => :any
|
197
|
+
q "Other", :pick => :any
|
198
|
+
end
|
199
|
+
|
184
200
|
q "Please rank the following foods based on how much you like them"
|
185
201
|
a "|pizza", :integer
|
186
202
|
a "|salad", :integer
|
@@ -195,8 +211,14 @@ survey "Kitchen Sink survey" do
|
|
195
211
|
a "knife", :string
|
196
212
|
a :other, :string
|
197
213
|
|
214
|
+
q_car "Do you own a car?", :pick => :one
|
215
|
+
a_y "Yes"
|
216
|
+
a_n "No"
|
217
|
+
|
198
218
|
# Repeaters allow multiple responses to a question or set of questions
|
199
219
|
repeater "Tell us about the cars you own" do
|
220
|
+
dependency :rule => "A"
|
221
|
+
condition_A :q_car, "==", :a_y
|
200
222
|
q "Make", :pick => :one, :display_type => :dropdown
|
201
223
|
a "Toyota"
|
202
224
|
a "Ford"
|
@@ -14,6 +14,18 @@ module Surveyor
|
|
14
14
|
@@validations_already_included = true
|
15
15
|
end
|
16
16
|
base.send :include, Surveyor::ActsAsResponse # includes "as" instance method
|
17
|
+
|
18
|
+
# Class methods
|
19
|
+
base.instance_eval do
|
20
|
+
def applicable_attributes(attrs)
|
21
|
+
result = HashWithIndifferentAccess.new(attrs)
|
22
|
+
if result[:string_value] && Answer.exists?(result[:answer_id])
|
23
|
+
answer = Answer.find(result[:answer_id])
|
24
|
+
result.delete(:string_value) unless answer.response_class && answer.response_class.to_sym == :string
|
25
|
+
end
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
17
29
|
end
|
18
30
|
|
19
31
|
# Instance Methods
|
@@ -26,6 +26,7 @@ module Surveyor
|
|
26
26
|
def reject_or_destroy_blanks(hash_of_hashes)
|
27
27
|
result = {}
|
28
28
|
(hash_of_hashes || {}).each_pair do |k, hash|
|
29
|
+
hash = Response.applicable_attributes(hash)
|
29
30
|
if has_blank_value?(hash)
|
30
31
|
result.merge!({k => hash.merge("_destroy" => "true")}) if hash.has_key?("id")
|
31
32
|
else
|
@@ -74,6 +75,10 @@ module Surveyor
|
|
74
75
|
def complete!
|
75
76
|
self.completed_at = Time.now
|
76
77
|
end
|
78
|
+
|
79
|
+
def complete?
|
80
|
+
!completed_at.nil?
|
81
|
+
end
|
77
82
|
|
78
83
|
def correct?
|
79
84
|
responses.all?(&:correct?)
|
@@ -103,6 +108,9 @@ module Surveyor
|
|
103
108
|
def is_unanswered?(question)
|
104
109
|
self.responses.detect{|r| r.question_id == question.id}.nil?
|
105
110
|
end
|
111
|
+
def is_group_unanswered?(group)
|
112
|
+
group.questions.any?{|question| is_unanswered?(question)}
|
113
|
+
end
|
106
114
|
|
107
115
|
# Returns the number of response groups (count of group responses enterted) for this question group
|
108
116
|
def count_group_responses(questions)
|
@@ -110,7 +118,15 @@ module Surveyor
|
|
110
118
|
end
|
111
119
|
|
112
120
|
def unanswered_dependencies
|
113
|
-
|
121
|
+
unanswered_question_dependencies + unanswered_question_group_dependencies
|
122
|
+
end
|
123
|
+
|
124
|
+
def unanswered_question_dependencies
|
125
|
+
dependencies.select{|d| d.is_met?(self) and d.question and self.is_unanswered?(d.question)}.map(&:question)
|
126
|
+
end
|
127
|
+
|
128
|
+
def unanswered_question_group_dependencies
|
129
|
+
dependencies.select{|d| d.is_met?(self) and d.question_group and self.is_group_unanswered?(d.question_group)}.map(&:question_group)
|
114
130
|
end
|
115
131
|
|
116
132
|
def all_dependencies(question_ids = nil)
|
@@ -81,6 +81,10 @@ class Question < ActiveRecord::Base
|
|
81
81
|
:pick => pick_from_field_type(r[:field_type]),
|
82
82
|
:display_type => display_type_from_field_type(r[:field_type])
|
83
83
|
})
|
84
|
+
unless context[:question].reference_identifier.blank?
|
85
|
+
context[:lookup] ||= []
|
86
|
+
context[:lookup] << [context[:question].reference_identifier, nil, context[:question]]
|
87
|
+
end
|
84
88
|
print "question_#{context[:question].reference_identifier} "
|
85
89
|
end
|
86
90
|
def self.pick_from_field_type(ft)
|
@@ -152,7 +156,11 @@ class DependencyCondition < ActiveRecord::Base
|
|
152
156
|
def resolve_references
|
153
157
|
return unless lookup_reference
|
154
158
|
print "resolve(#{question_reference},#{answer_reference})"
|
155
|
-
if row = lookup_reference.find{|r| r[0] == question_reference and r[1] ==
|
159
|
+
if answer_reference.blank? and (row = lookup_reference.find{|r| r[0] == question_reference and r[1] == nil}) and row[2].answers.size == 1
|
160
|
+
print "...found "
|
161
|
+
self.question = row[2]
|
162
|
+
self.answer = self.question.answers.first
|
163
|
+
elsif row = lookup_reference.find{|r| r[0] == question_reference and r[1] == answer_reference}
|
156
164
|
print "...found "
|
157
165
|
self.answer = row[2]
|
158
166
|
self.question = self.answer.question
|
@@ -63,7 +63,8 @@ module Surveyor
|
|
63
63
|
saved = false
|
64
64
|
ActiveRecord::Base.transaction do
|
65
65
|
saved = @response_set.update_attributes(:responses_attributes => ResponseSet.reject_or_destroy_blanks(params[:r]))
|
66
|
-
|
66
|
+
@response_set.complete! if saved && params[:finish]
|
67
|
+
saved &= @response_set.save
|
67
68
|
end
|
68
69
|
return redirect_with_message(surveyor_finish, :notice, t('surveyor.completed_survey')) if saved && params[:finish]
|
69
70
|
|
data/lib/surveyor/unparser.rb
CHANGED
@@ -14,7 +14,7 @@ class Survey < ActiveRecord::Base
|
|
14
14
|
# block
|
15
15
|
|
16
16
|
def unparse(dsl)
|
17
|
-
attrs = (self.attributes.diff Survey.new(:title => title).attributes).delete_if{|k,v| %w(created_at updated_at inactive_at id title access_code).include? k}.symbolize_keys!
|
17
|
+
attrs = (self.attributes.diff Survey.new(:title => title).attributes).delete_if{|k,v| %w(created_at updated_at inactive_at id title access_code api_id).include? k}.symbolize_keys!
|
18
18
|
dsl << "survey \"#{title}\""
|
19
19
|
dsl << (attrs.blank? ? " do\n" : ", #{attrs.inspect.gsub(/\{|\}/, "")} do\n")
|
20
20
|
sections.each{|section| section.unparse(dsl)}
|
@@ -62,7 +62,7 @@ class Question < ActiveRecord::Base
|
|
62
62
|
# nonblock
|
63
63
|
|
64
64
|
def unparse(dsl)
|
65
|
-
attrs = (self.attributes.diff Question.new(:text => text).attributes).delete_if{|k,v| %w(created_at updated_at reference_identifier id survey_section_id question_group_id).include?(k) or (k == "display_type" && v == "label")}.symbolize_keys!
|
65
|
+
attrs = (self.attributes.diff Question.new(:text => text).attributes).delete_if{|k,v| %w(created_at updated_at reference_identifier id survey_section_id question_group_id api_id).include?(k) or (k == "display_type" && v == "label")}.symbolize_keys!
|
66
66
|
dsl << (solo? ? "\n" : " ")
|
67
67
|
if display_type == "label"
|
68
68
|
dsl << " label"
|
@@ -105,7 +105,7 @@ class Answer < ActiveRecord::Base
|
|
105
105
|
# nonblock
|
106
106
|
|
107
107
|
def unparse(dsl)
|
108
|
-
attrs = (self.attributes.diff Answer.new(:text => text).attributes).delete_if{|k,v| %w(created_at updated_at reference_identifier response_class id question_id).include? k}.symbolize_keys!
|
108
|
+
attrs = (self.attributes.diff Answer.new(:text => text).attributes).delete_if{|k,v| %w(created_at updated_at reference_identifier response_class id question_id api_id).include? k}.symbolize_keys!
|
109
109
|
attrs.delete(:is_exclusive) if text == "Omit" && is_exclusive == true
|
110
110
|
attrs.merge!({:is_exclusive => false}) if text == "Omit" && is_exclusive == false
|
111
111
|
dsl << " " if question.part_of_group?
|
data/spec/models/answer_spec.rb
CHANGED
@@ -38,6 +38,10 @@ describe Question, "when creating a new question" do
|
|
38
38
|
@question.split_text(:pre).should == "before"
|
39
39
|
@question.split_text(:post).should == "after|extra"
|
40
40
|
end
|
41
|
+
|
42
|
+
it "should have an api_id" do
|
43
|
+
@question.api_id.length.should == 36
|
44
|
+
end
|
41
45
|
end
|
42
46
|
|
43
47
|
describe Question, "that has answers" do
|
@@ -18,6 +18,7 @@ describe ResponseSet do
|
|
18
18
|
@response_set.complete!
|
19
19
|
@response_set.completed_at.should_not be_nil
|
20
20
|
@response_set.completed_at.is_a?(Time).should be_true
|
21
|
+
@response_set.should be_complete
|
21
22
|
end
|
22
23
|
|
23
24
|
it "does not allow completion through mass assignment" do
|
@@ -138,7 +139,23 @@ describe ResponseSet, "with dependencies" do
|
|
138
139
|
it "should list answered and unanswered dependencies to show inline (javascript turned on)" do
|
139
140
|
@response_set.all_dependencies[:show].should == ["q_#{@what_flavor.id}", "q_#{@what_bakery.id}"]
|
140
141
|
end
|
141
|
-
|
142
|
+
it "should list group as dependency" do
|
143
|
+
# Question Group
|
144
|
+
crust_group = Factory(:question_group, :text => "Favorite Crusts")
|
145
|
+
|
146
|
+
# Question
|
147
|
+
what_crust = Factory(:question, :text => "What is your favorite curst type?", :survey_section => @section)
|
148
|
+
crust_group.questions << what_crust
|
149
|
+
|
150
|
+
# Answers
|
151
|
+
what_crust.answers << Factory(:answer, :response_class => :string, :question_id => what_crust.id)
|
152
|
+
|
153
|
+
# Dependency
|
154
|
+
crust_group_dep = Factory(:dependency, :rule => "C", :question_group_id => crust_group.id, :question => nil)
|
155
|
+
Factory(:dependency_condition, :rule_key => "C", :question_id => @do_you_like_pie.id, :operator => "==", :answer_id => @do_you_like_pie.answers.first.id, :dependency_id => crust_group_dep.id)
|
156
|
+
|
157
|
+
@response_set.unanswered_dependencies.should == [@what_bakery, crust_group]
|
158
|
+
end
|
142
159
|
end
|
143
160
|
describe ResponseSet, "as a quiz" do
|
144
161
|
before(:each) do
|
@@ -74,3 +74,21 @@ describe Response, "when saving a response" do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
end
|
77
|
+
|
78
|
+
describe Response, "applicable_attributes" do
|
79
|
+
before(:each) do
|
80
|
+
@who = Factory(:question, :text => "Who rules?")
|
81
|
+
@odoyle = Factory(:answer, :text => "Odoyle", :response_class => "answer")
|
82
|
+
@other = Factory(:answer, :text => "Other", :response_class => "string")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have string_value if response_type is string" do
|
86
|
+
good = {"question_id" => @who.id, "answer_id" => @other.id, "string_value" => "Frank"}
|
87
|
+
Response.applicable_attributes(good).should == good
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not have string_value if response_type is answer" do
|
91
|
+
bad = {"question_id"=>@who.id, "answer_id"=>@odoyle.id, "string_value"=>"Frank"}
|
92
|
+
Response.applicable_attributes(bad).should == {"question_id" => @who.id, "answer_id"=> @odoyle.id}
|
93
|
+
end
|
94
|
+
end
|
data/spec/models/survey_spec.rb
CHANGED
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.4"
|
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-
|
12
|
+
s.date = %q{2011-05-18}
|
13
13
|
s.email = %q{yoon@northwestern.edu}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.md"
|
@@ -60,6 +60,7 @@ Gem::Specification.new do |s|
|
|
60
60
|
"features/support/REDCapDemoDatabase_DataDictionary.csv",
|
61
61
|
"features/support/env.rb",
|
62
62
|
"features/support/paths.rb",
|
63
|
+
"features/support/redcap_siblings.csv",
|
63
64
|
"features/surveyor.feature",
|
64
65
|
"features/surveyor_parser.feature",
|
65
66
|
"generators/extend_surveyor/extend_surveyor_generator.rb",
|
@@ -79,6 +80,7 @@ Gem::Specification.new do |s|
|
|
79
80
|
"generators/surveyor/templates/locales/surveyor_en.yml",
|
80
81
|
"generators/surveyor/templates/locales/surveyor_es.yml",
|
81
82
|
"generators/surveyor/templates/locales/surveyor_he.yml",
|
83
|
+
"generators/surveyor/templates/migrate/add_api_ids.rb",
|
82
84
|
"generators/surveyor/templates/migrate/add_correct_answer_id_to_questions.rb",
|
83
85
|
"generators/surveyor/templates/migrate/add_default_value_to_answers.rb",
|
84
86
|
"generators/surveyor/templates/migrate/add_display_order_to_surveys.rb",
|
@@ -182,17 +184,20 @@ Gem::Specification.new do |s|
|
|
182
184
|
s.add_runtime_dependency(%q<haml>, [">= 0"])
|
183
185
|
s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
|
184
186
|
s.add_runtime_dependency(%q<formtastic>, [">= 0"])
|
187
|
+
s.add_runtime_dependency(%q<uuid>, [">= 0"])
|
185
188
|
s.add_development_dependency(%q<yard>, [">= 0"])
|
186
189
|
else
|
187
190
|
s.add_dependency(%q<haml>, [">= 0"])
|
188
191
|
s.add_dependency(%q<fastercsv>, [">= 0"])
|
189
192
|
s.add_dependency(%q<formtastic>, [">= 0"])
|
193
|
+
s.add_dependency(%q<uuid>, [">= 0"])
|
190
194
|
s.add_dependency(%q<yard>, [">= 0"])
|
191
195
|
end
|
192
196
|
else
|
193
197
|
s.add_dependency(%q<haml>, [">= 0"])
|
194
198
|
s.add_dependency(%q<fastercsv>, [">= 0"])
|
195
199
|
s.add_dependency(%q<formtastic>, [">= 0"])
|
200
|
+
s.add_dependency(%q<uuid>, [">= 0"])
|
196
201
|
s.add_dependency(%q<yard>, [">= 0"])
|
197
202
|
end
|
198
203
|
end
|
data/testbed/Gemfile
CHANGED
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: 91
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 19
|
9
|
-
-
|
10
|
-
version: 0.19.
|
9
|
+
- 4
|
10
|
+
version: 0.19.4
|
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-
|
19
|
+
date: 2011-05-18 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -62,7 +62,7 @@ dependencies:
|
|
62
62
|
type: :runtime
|
63
63
|
version_requirements: *id003
|
64
64
|
- !ruby/object:Gem::Dependency
|
65
|
-
name:
|
65
|
+
name: uuid
|
66
66
|
prerelease: false
|
67
67
|
requirement: &id004 !ruby/object:Gem::Requirement
|
68
68
|
none: false
|
@@ -73,8 +73,22 @@ dependencies:
|
|
73
73
|
segments:
|
74
74
|
- 0
|
75
75
|
version: "0"
|
76
|
-
type: :
|
76
|
+
type: :runtime
|
77
77
|
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: yard
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
type: :development
|
91
|
+
version_requirements: *id005
|
78
92
|
description:
|
79
93
|
email: yoon@northwestern.edu
|
80
94
|
executables: []
|
@@ -129,6 +143,7 @@ files:
|
|
129
143
|
- features/support/REDCapDemoDatabase_DataDictionary.csv
|
130
144
|
- features/support/env.rb
|
131
145
|
- features/support/paths.rb
|
146
|
+
- features/support/redcap_siblings.csv
|
132
147
|
- features/surveyor.feature
|
133
148
|
- features/surveyor_parser.feature
|
134
149
|
- generators/extend_surveyor/extend_surveyor_generator.rb
|
@@ -148,6 +163,7 @@ files:
|
|
148
163
|
- generators/surveyor/templates/locales/surveyor_en.yml
|
149
164
|
- generators/surveyor/templates/locales/surveyor_es.yml
|
150
165
|
- generators/surveyor/templates/locales/surveyor_he.yml
|
166
|
+
- generators/surveyor/templates/migrate/add_api_ids.rb
|
151
167
|
- generators/surveyor/templates/migrate/add_correct_answer_id_to_questions.rb
|
152
168
|
- generators/surveyor/templates/migrate/add_default_value_to_answers.rb
|
153
169
|
- generators/surveyor/templates/migrate/add_display_order_to_surveys.rb
|