hssc_surveyor 1.4.1.pre
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/.gitignore +28 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +198 -0
- data/Gemfile +5 -0
- data/Gemfile.rails_version +19 -0
- data/MIT-LICENSE +20 -0
- data/README.md +186 -0
- data/Rakefile +105 -0
- data/app/controllers/surveyor_controller.rb +6 -0
- data/app/helpers/results_helper.rb +20 -0
- data/app/helpers/survey_form_builder.rb +37 -0
- data/app/helpers/surveyor_helper.rb +3 -0
- data/app/inputs/quiet_input.rb +5 -0
- data/app/inputs/surveyor_check_boxes_input.rb +35 -0
- data/app/inputs/surveyor_radio_input.rb +18 -0
- data/app/models/answer.rb +4 -0
- data/app/models/dependency.rb +4 -0
- data/app/models/dependency_condition.rb +4 -0
- data/app/models/question.rb +4 -0
- data/app/models/question_group.rb +5 -0
- data/app/models/response.rb +5 -0
- data/app/models/response_set.rb +4 -0
- data/app/models/survey.rb +4 -0
- data/app/models/survey_section.rb +5 -0
- data/app/models/survey_section_sweeper.rb +15 -0
- data/app/models/survey_translation.rb +5 -0
- data/app/models/validation.rb +4 -0
- data/app/models/validation_condition.rb +4 -0
- data/app/views/layouts/results.html.erb +13 -0
- data/app/views/layouts/surveyor_default.html.erb +12 -0
- data/app/views/partials/_answer.html.haml +25 -0
- data/app/views/partials/_dependents.html.haml +5 -0
- data/app/views/partials/_question.html.haml +41 -0
- data/app/views/partials/_question_group.html.haml +44 -0
- data/app/views/partials/_section.html.haml +12 -0
- data/app/views/partials/_section_menu.html.haml +12 -0
- data/app/views/surveyor/edit.html.haml +24 -0
- data/app/views/surveyor/export.json.rabl +85 -0
- data/app/views/surveyor/new.html.haml +24 -0
- data/app/views/surveyor/show.html.haml +74 -0
- data/app/views/surveyor/show.json.rabl +15 -0
- data/ci-exec.sh +56 -0
- data/config/routes.rb +8 -0
- data/cucumber.yml +10 -0
- data/doc/REPRESENTATIONS.md +34 -0
- data/doc/api_id_schema.json +7 -0
- data/doc/question types.png +0 -0
- data/doc/response_set_schema.json +54 -0
- data/doc/surveyor question combinations.png +0 -0
- data/doc/surveyor reject or delete decision matrix.png +0 -0
- data/doc/surveyor_models.png +0 -0
- data/doc/surveyor_models2.png +0 -0
- data/doc/surveyor_timestamp_schema.json +9 -0
- data/features/ajax_submissions.feature +140 -0
- data/features/export_to_json.feature +344 -0
- data/features/internationalization.feature +121 -0
- data/features/no_duplicates.feature +110 -0
- data/features/show_survey.feature +71 -0
- data/features/step_definitions/parser_steps.rb +145 -0
- data/features/step_definitions/surveyor_steps.rb +325 -0
- data/features/step_definitions/ui_steps.rb +25 -0
- data/features/step_definitions/web_steps.rb +225 -0
- data/features/support/REDCapDemoDatabase_DataDictionary.csv +127 -0
- data/features/support/database_cleaner.rb +16 -0
- data/features/support/env.rb +56 -0
- data/features/support/hooks.rb +4 -0
- data/features/support/paths.rb +39 -0
- data/features/support/redcap_new_headers.csv +1 -0
- data/features/support/redcap_siblings.csv +1 -0
- data/features/support/redcap_whitespace.csv +1 -0
- data/features/support/selectors.rb +39 -0
- data/features/support/simultaneous_ajax.rb +101 -0
- data/features/support/single_quit_selenium_driver.rb +23 -0
- data/features/support/slow_updates.rb +18 -0
- data/features/surveyor.feature +895 -0
- data/features/surveyor_dependencies.feature +476 -0
- data/features/surveyor_parser.feature +504 -0
- data/features/z_redcap_parser.feature +62 -0
- data/lib/assets/images/surveyor/next.gif +0 -0
- data/lib/assets/images/surveyor/prev.gif +0 -0
- data/lib/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/lib/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/assets/images/ui-icons_222222_256x240.png +0 -0
- data/lib/assets/images/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/assets/images/ui-icons_454545_256x240.png +0 -0
- data/lib/assets/images/ui-icons_888888_256x240.png +0 -0
- data/lib/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/assets/javascripts/surveyor/jquery-1.9.0.js +9555 -0
- data/lib/assets/javascripts/surveyor/jquery-ui-1.10.0.custom.js +14850 -0
- data/lib/assets/javascripts/surveyor/jquery-ui-timepicker-addon.js +1919 -0
- data/lib/assets/javascripts/surveyor/jquery.maskedinput.js +338 -0
- data/lib/assets/javascripts/surveyor/jquery.selectToUISlider.js +240 -0
- data/lib/assets/javascripts/surveyor/jquery.surveyor.js +156 -0
- data/lib/assets/stylesheets/surveyor/jquery-ui-1.10.0.custom.css +1174 -0
- data/lib/assets/stylesheets/surveyor/jquery-ui-timepicker-addon.css +11 -0
- data/lib/assets/stylesheets/surveyor/reset.css +48 -0
- data/lib/assets/stylesheets/surveyor/results.css +125 -0
- data/lib/assets/stylesheets/surveyor/ui.slider.extras.css +110 -0
- data/lib/assets/stylesheets/surveyor.sass +132 -0
- data/lib/generators/surveyor/custom_generator.rb +18 -0
- data/lib/generators/surveyor/install_generator.rb +102 -0
- data/lib/generators/surveyor/templates/app/assets/javascripts/surveyor_all.js +6 -0
- data/lib/generators/surveyor/templates/app/assets/stylesheets/surveyor_all.css +9 -0
- data/lib/generators/surveyor/templates/app/controllers/surveyor_controller.rb +40 -0
- data/lib/generators/surveyor/templates/app/views/layouts/surveyor_custom.html.erb +13 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_en.yml +19 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_es.yml +19 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_he.yml +19 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_ko.yml +19 -0
- data/lib/generators/surveyor/templates/db/migrate/add_api_id_to_question_groups.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_api_ids.rb +14 -0
- data/lib/generators/surveyor/templates/db/migrate/add_api_ids_to_response_sets_and_responses.rb +12 -0
- data/lib/generators/surveyor/templates/db/migrate/add_attachment_to_response.rb +5 -0
- data/lib/generators/surveyor/templates/db/migrate/add_correct_answer_id_to_questions.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_default_value_to_answers.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_display_order_to_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_display_type_to_answers.rb +14 -0
- data/lib/generators/surveyor/templates/db/migrate/add_index_to_response_sets.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_index_to_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_input_mask_attributes_to_answer.rb +12 -0
- data/lib/generators/surveyor/templates/db/migrate/add_section_id_to_responses.rb +12 -0
- data/lib/generators/surveyor/templates/db/migrate/add_unique_index_on_access_code_and_version_in_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_unique_indicies.rb +18 -0
- data/lib/generators/surveyor/templates/db/migrate/add_version_to_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/api_ids_must_be_unique.rb +23 -0
- data/lib/generators/surveyor/templates/db/migrate/create_answers.rb +38 -0
- data/lib/generators/surveyor/templates/db/migrate/create_dependencies.rb +23 -0
- data/lib/generators/surveyor/templates/db/migrate/create_dependency_conditions.rb +30 -0
- data/lib/generators/surveyor/templates/db/migrate/create_question_groups.rb +28 -0
- data/lib/generators/surveyor/templates/db/migrate/create_questions.rb +37 -0
- data/lib/generators/surveyor/templates/db/migrate/create_response_sets.rb +23 -0
- data/lib/generators/surveyor/templates/db/migrate/create_responses.rb +34 -0
- data/lib/generators/surveyor/templates/db/migrate/create_survey_sections.rb +30 -0
- data/lib/generators/surveyor/templates/db/migrate/create_survey_translations.rb +19 -0
- data/lib/generators/surveyor/templates/db/migrate/create_surveys.rb +32 -0
- data/lib/generators/surveyor/templates/db/migrate/create_validation_conditions.rb +33 -0
- data/lib/generators/surveyor/templates/db/migrate/create_validations.rb +21 -0
- data/lib/generators/surveyor/templates/db/migrate/drop_unique_index_on_access_code_in_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/update_blank_api_ids_on_question_group.rb +22 -0
- data/lib/generators/surveyor/templates/db/migrate/update_blank_versions_on_surveys.rb +13 -0
- data/lib/generators/surveyor/templates/surveys/EXTENDING_SURVEYOR.md +52 -0
- data/lib/generators/surveyor/templates/surveys/MODIFYING_SURVEYOR.md +91 -0
- data/lib/generators/surveyor/templates/surveys/date_survey.rb +16 -0
- data/lib/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +284 -0
- data/lib/generators/surveyor/templates/surveys/languages.rb +14 -0
- data/lib/generators/surveyor/templates/surveys/quiz.rb +11 -0
- data/lib/generators/surveyor/templates/surveys/translations/languages.es.yml +18 -0
- data/lib/generators/surveyor/templates/surveys/translations/languages.he.yml +18 -0
- data/lib/generators/surveyor/templates/surveys/translations/languages.ko.yml +18 -0
- data/lib/generators/surveyor/templates/vendor/assets/stylesheets/custom.sass +5 -0
- data/lib/surveyor/acts_as_response.rb +17 -0
- data/lib/surveyor/common.rb +59 -0
- data/lib/surveyor/engine.rb +10 -0
- data/lib/surveyor/helpers/asset_pipeline.rb +13 -0
- data/lib/surveyor/helpers/formtastic_custom_input.rb +13 -0
- data/lib/surveyor/helpers/surveyor_helper_methods.rb +103 -0
- data/lib/surveyor/models/answer_methods.rb +86 -0
- data/lib/surveyor/models/dependency_condition_methods.rb +72 -0
- data/lib/surveyor/models/dependency_methods.rb +60 -0
- data/lib/surveyor/models/question_group_methods.rb +61 -0
- data/lib/surveyor/models/question_methods.rb +115 -0
- data/lib/surveyor/models/response_methods.rb +132 -0
- data/lib/surveyor/models/response_set_methods.rb +196 -0
- data/lib/surveyor/models/survey_methods.rb +103 -0
- data/lib/surveyor/models/survey_section_methods.rb +56 -0
- data/lib/surveyor/models/survey_translation_methods.rb +33 -0
- data/lib/surveyor/models/validation_condition_methods.rb +56 -0
- data/lib/surveyor/models/validation_methods.rb +48 -0
- data/lib/surveyor/mustache_context.rb +11 -0
- data/lib/surveyor/parser.rb +428 -0
- data/lib/surveyor/redcap_parser.rb +289 -0
- data/lib/surveyor/surveyor_controller_methods.rb +237 -0
- data/lib/surveyor/unparser.rb +147 -0
- data/lib/surveyor/version.rb +3 -0
- data/lib/surveyor.rb +13 -0
- data/lib/tasks/surveyor_tasks.rake +88 -0
- data/rails/init.rb +1 -0
- data/spec/controllers/surveyor_controller_spec.rb +307 -0
- data/spec/factories.rb +161 -0
- data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
- data/spec/helpers/surveyor_helper_spec.rb +118 -0
- data/spec/lib/benchmark_spec.rb +22 -0
- data/spec/lib/chinese_survey.rb +14 -0
- data/spec/lib/common_spec.rb +34 -0
- data/spec/lib/parser_spec.rb +204 -0
- data/spec/lib/rake_kitchen_sink.rb +40 -0
- data/spec/lib/redcap_parser_spec.rb +75 -0
- data/spec/lib/tasks_spec.rake +26 -0
- data/spec/lib/unparser_spec.rb +126 -0
- data/spec/models/answer_spec.rb +175 -0
- data/spec/models/dependency_condition_spec.rb +439 -0
- data/spec/models/dependency_spec.rb +101 -0
- data/spec/models/question_group_spec.rb +93 -0
- data/spec/models/question_spec.rb +207 -0
- data/spec/models/response_set_spec.rb +477 -0
- data/spec/models/response_spec.rb +218 -0
- data/spec/models/survey_section_spec.rb +85 -0
- data/spec/models/survey_spec.rb +191 -0
- data/spec/models/validation_condition_spec.rb +113 -0
- data/spec/models/validation_spec.rb +74 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +56 -0
- data/stacktests.sh +65 -0
- data/surveyor.gemspec +45 -0
- metadata +657 -0
@@ -0,0 +1,504 @@
|
|
1
|
+
Feature: Survey parser
|
2
|
+
As a developer
|
3
|
+
I want to write out the survey in the DSL
|
4
|
+
So that I can give it to survey participants
|
5
|
+
|
6
|
+
Scenario: Parsing basic questions
|
7
|
+
Given I parse
|
8
|
+
"""
|
9
|
+
survey "Simple survey" do
|
10
|
+
section_basic "Basic questions" do
|
11
|
+
label "These questions are examples of the basic supported input types"
|
12
|
+
|
13
|
+
question_1 "What is your favorite color?", :pick => :one
|
14
|
+
answer "red"
|
15
|
+
answer "blue"
|
16
|
+
answer "green"
|
17
|
+
answer :other
|
18
|
+
|
19
|
+
q_2b "Choose the colors you don't like", :pick => :any
|
20
|
+
a_1 "orange", :display_order => 1
|
21
|
+
a_2 "purple", :display_order => 2
|
22
|
+
a_3 "brown", :display_order => 0
|
23
|
+
a :omit
|
24
|
+
end
|
25
|
+
section_second "Second section" do
|
26
|
+
end
|
27
|
+
end
|
28
|
+
survey "Second survey" do
|
29
|
+
end
|
30
|
+
"""
|
31
|
+
Then there should be 2 surveys with:
|
32
|
+
| title | display_order |
|
33
|
+
| Simple survey | 0 |
|
34
|
+
| Second survey | 1 |
|
35
|
+
And there should be 2 sections with:
|
36
|
+
| title | display_order | reference_identifier |
|
37
|
+
| Basic questions | 0 | basic |
|
38
|
+
| Second section | 1 | second |
|
39
|
+
And there should be 3 questions with:
|
40
|
+
| reference_identifier | text | pick | display_type | display_order |
|
41
|
+
| nil | These questions are examples of the basic supported input types | none | label | 0 |
|
42
|
+
| 1 | What is your favorite color? | one | default | 1 |
|
43
|
+
| 2b | Choose the colors you don't like | any | default | 2 |
|
44
|
+
And there should be 8 answers with:
|
45
|
+
| reference_identifier | text | response_class | display_order |
|
46
|
+
| nil | red | answer | 0 |
|
47
|
+
| nil | blue | answer | 1 |
|
48
|
+
| nil | green | answer | 2 |
|
49
|
+
| nil | Other | answer | 3 |
|
50
|
+
| 1 | orange | answer | 1 |
|
51
|
+
| 2 | purple | answer | 2 |
|
52
|
+
| 3 | brown | answer | 0 |
|
53
|
+
| nil | Omit | answer | 3 |
|
54
|
+
|
55
|
+
Scenario: Parsing more complex questions
|
56
|
+
Given I parse
|
57
|
+
"""
|
58
|
+
survey "Complex survey" do
|
59
|
+
section "Complicated questions" do
|
60
|
+
grid_feel "Tell us how you feel today" do
|
61
|
+
a "-2"
|
62
|
+
a "-1"
|
63
|
+
a "0"
|
64
|
+
a "1"
|
65
|
+
a "2"
|
66
|
+
q "down|up" , :pick => :one
|
67
|
+
q "sad|happy", :pick => :one
|
68
|
+
q "limp|perky", :pick => :one
|
69
|
+
end
|
70
|
+
|
71
|
+
q "Choose your favorite utensils and enter frequency of use (daily, weekly, monthly, etc...)", :pick => :any
|
72
|
+
a "spoon", :string
|
73
|
+
a "fork", :string
|
74
|
+
a "knife", :string
|
75
|
+
a :other, :string
|
76
|
+
|
77
|
+
repeater_cars "Tell us about the cars you own" do
|
78
|
+
q "Make", :pick => :one, :display_type => :dropdown
|
79
|
+
a "Toyota"
|
80
|
+
a "Ford"
|
81
|
+
a "GMChevy"
|
82
|
+
a "Ferrari"
|
83
|
+
a "Tesla"
|
84
|
+
a "Honda"
|
85
|
+
a "Other weak brand"
|
86
|
+
q "Model"
|
87
|
+
a :string
|
88
|
+
q "Year"
|
89
|
+
a :string
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
"""
|
94
|
+
Then there should be 1 survey with:
|
95
|
+
| title |
|
96
|
+
| Complex survey |
|
97
|
+
And there should be 2 question groups with:
|
98
|
+
| text | display_type | reference_identifier |
|
99
|
+
| Tell us how you feel today | grid | feel |
|
100
|
+
| Tell us about the cars you own | repeater | cars |
|
101
|
+
And there should be 7 questions with:
|
102
|
+
| text | pick | display_type |
|
103
|
+
| Make | one | dropdown |
|
104
|
+
And there should be 28 answers with:
|
105
|
+
| text | response_class |
|
106
|
+
| -2 | answer |
|
107
|
+
| Other | string |
|
108
|
+
|
109
|
+
Scenario: Parsing dependencies and validations
|
110
|
+
Given I parse
|
111
|
+
"""
|
112
|
+
survey "Dependency and validation survey" do
|
113
|
+
section "Conditionals" do
|
114
|
+
q_montypython3 "What... is your name? (e.g. It is 'Arthur', King of the Britons)"
|
115
|
+
a_1 :string
|
116
|
+
|
117
|
+
q_montypython4 "What... is your quest? (e.g. To seek the Holy Grail)"
|
118
|
+
a_1 :string
|
119
|
+
dependency :rule => "A"
|
120
|
+
condition_A :q_montypython3, "==", {:string_value => "It is 'Arthur', King of the Britons", :answer_reference => "1"}
|
121
|
+
|
122
|
+
q "How many pets do you own?"
|
123
|
+
a :integer
|
124
|
+
validation :rule => "A"
|
125
|
+
condition_A ">=", :integer_value => 0
|
126
|
+
|
127
|
+
q "What is your address?", :custom_class => 'address'
|
128
|
+
a :text, :custom_class => 'mapper'
|
129
|
+
validation :rule => "AC"
|
130
|
+
vcondition_AC "=~", :regexp => /[0-9a-zA-z\. #]/
|
131
|
+
|
132
|
+
q_2 "Which colors do you loathe?", :pick => :any
|
133
|
+
a_1 "red"
|
134
|
+
a_2 "blue"
|
135
|
+
a_3 "green"
|
136
|
+
a_4 "yellow"
|
137
|
+
|
138
|
+
q_2a "Please explain why you hate so many colors?"
|
139
|
+
a_1 "explanation", :text
|
140
|
+
dependency :rule => "Z"
|
141
|
+
condition_Z :q_2, "count>2"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
"""
|
145
|
+
Then there should be 1 survey with:
|
146
|
+
| title |
|
147
|
+
| Dependency and validation survey |
|
148
|
+
And there should be 6 questions with:
|
149
|
+
| text | pick | display_type | custom_class |
|
150
|
+
| What... is your name? (e.g. It is 'Arthur', King of the Britons) | none | default | nil |
|
151
|
+
| What is your address? | none | default | address |
|
152
|
+
And there should be 2 dependency with:
|
153
|
+
| rule |
|
154
|
+
| A |
|
155
|
+
| Z |
|
156
|
+
And there should be 2 resolved dependency_condition with:
|
157
|
+
| rule_key |
|
158
|
+
| A |
|
159
|
+
| Z |
|
160
|
+
And there should be 2 validations with:
|
161
|
+
| rule |
|
162
|
+
| A |
|
163
|
+
| AC |
|
164
|
+
And there should be 2 validation_conditions with:
|
165
|
+
| rule_key | integer_value |
|
166
|
+
| A | 0 |
|
167
|
+
|
168
|
+
Scenario: Parsing other dependencies and validations
|
169
|
+
Given I parse
|
170
|
+
"""
|
171
|
+
survey "dependency test" do
|
172
|
+
section "section 1" do
|
173
|
+
|
174
|
+
q_copd_sh_1 "Have you ever smoked cigarettes?",:pick=>:one,:help_text=>"NO means less than 20 packs of cigarettes or 12 oz. of tobacco in a lifetime or less than 1 cigarette a day for 1 year."
|
175
|
+
a_1 "Yes"
|
176
|
+
a_2 "No"
|
177
|
+
|
178
|
+
q_copd_sh_1a "How old were you when you first started smoking cigarettes?", :help_text=>"age in years"
|
179
|
+
a :integer
|
180
|
+
dependency :rule => "A"
|
181
|
+
condition_A :q_copd_sh_1, "==", :a_1
|
182
|
+
|
183
|
+
q_copd_sh_1b "Do you currently smoke cigarettes?",:pick=>:one, :help_text=>"as of 1 month ago"
|
184
|
+
a_1 "Yes"
|
185
|
+
a_2 "No"
|
186
|
+
dependency :rule => "B"
|
187
|
+
condition_B :q_copd_sh_1, "==", :a_1
|
188
|
+
|
189
|
+
q_copd_sh_1c "On the average of the entire time you smoked, how many cigarettes did you smoke per day?"
|
190
|
+
a :integer
|
191
|
+
dependency :rule => "C"
|
192
|
+
condition_C :q_copd_sh_1, "==", :a_1
|
193
|
+
|
194
|
+
q_copd_sh_1bb "How many cigarettes do you smoke per day now?"
|
195
|
+
a_2 "integer"
|
196
|
+
dependency :rule => "D"
|
197
|
+
condition_D :q_copd_sh_1b, "==", :a_1
|
198
|
+
|
199
|
+
|
200
|
+
q_copd_sh_1ba "How old were you when you stopped?"
|
201
|
+
a "Years", :integer
|
202
|
+
dependency :rule => "E"
|
203
|
+
condition_E :q_copd_sh_1b, "==", :a_2
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
207
|
+
"""
|
208
|
+
Then there should be 5 dependencies
|
209
|
+
And question "copd_sh_1a" should have a dependency with rule "A"
|
210
|
+
And question "copd_sh_1ba" should have a dependency with rule "E"
|
211
|
+
|
212
|
+
Scenario: Parsing dependencies on questions inside of a group
|
213
|
+
Given I parse
|
214
|
+
"""
|
215
|
+
survey "Phone Screen Questions" do
|
216
|
+
section "Phone Screen" do
|
217
|
+
q_diabetes "Diabetes", :pick => :one
|
218
|
+
a_yes "Yes"
|
219
|
+
a_no "No"
|
220
|
+
|
221
|
+
q_high_blood_preassure "High blood pressure?", :pick => :one
|
222
|
+
a_yes "Yes"
|
223
|
+
a_no "No"
|
224
|
+
|
225
|
+
group do
|
226
|
+
dependency :rule => "A"
|
227
|
+
condition_A :q_diabetes, "==", :a_yes
|
228
|
+
label "It looks like you are not eligible for this specific study at the time"
|
229
|
+
end
|
230
|
+
|
231
|
+
group "Eligible" do
|
232
|
+
dependency :rule => "A"
|
233
|
+
condition_A :q_diabetes, "==", :a_no
|
234
|
+
|
235
|
+
label "You're Eligible!"
|
236
|
+
|
237
|
+
label "You need medical clearance"
|
238
|
+
dependency :rule => "A"
|
239
|
+
condition_A :q_high_blood_preassure, "==", :a_yes
|
240
|
+
|
241
|
+
label "You don't need medical clearance"
|
242
|
+
dependency :rule => "A"
|
243
|
+
condition_A :q_high_blood_preassure, "==", :a_no
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
"""
|
248
|
+
Then there should be 4 dependencies
|
249
|
+
And 2 dependencies should depend on questions
|
250
|
+
And 2 dependencies should depend on question groups
|
251
|
+
|
252
|
+
Scenario: Parsing dependencies with "a"
|
253
|
+
Given I parse
|
254
|
+
"""
|
255
|
+
survey "Dependencies with 'a'" do
|
256
|
+
section "First" do
|
257
|
+
q_data_collection "Disease data collection", :pick => :one
|
258
|
+
a_via_chart_review "Via chart review"
|
259
|
+
a_via_patient_interview "Via patient interview/questionnaire"
|
260
|
+
|
261
|
+
q_myocardial_infaction "Myocardinal Infarction", :pick => :one
|
262
|
+
dependency :rule => "A"
|
263
|
+
condition_A :q_data_collection, "==", :a_via_chart_review
|
264
|
+
a_yes "Yes"
|
265
|
+
a_no "No"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
"""
|
269
|
+
And there should be 1 dependency with:
|
270
|
+
| rule |
|
271
|
+
| A |
|
272
|
+
And there should be 1 resolved dependency_condition with:
|
273
|
+
| rule_key |
|
274
|
+
| A |
|
275
|
+
|
276
|
+
Scenario: Parsing dependencies with "q"
|
277
|
+
Given I parse
|
278
|
+
"""
|
279
|
+
survey "Dependencies with 'q'" do
|
280
|
+
section "First" do
|
281
|
+
q_rawq_collection "Your rockin rawq collection", :pick => :one
|
282
|
+
a_rawqs "Rawqs"
|
283
|
+
a_doesnt_rawq "Doesn't rawq"
|
284
|
+
|
285
|
+
q_do_you_rawq "Do you rawq with your rockin rawq collection?", :pick => :one
|
286
|
+
dependency :rule => "A"
|
287
|
+
condition_A :q_rawq_collection, "==", :a_rawqs
|
288
|
+
a_yes "Yes"
|
289
|
+
a_no "No"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
"""
|
293
|
+
And there should be 1 dependency with:
|
294
|
+
| rule |
|
295
|
+
| A |
|
296
|
+
And there should be 1 resolved dependency_condition with:
|
297
|
+
| rule_key |
|
298
|
+
| A |
|
299
|
+
|
300
|
+
@quiz
|
301
|
+
Scenario: Parsing a quiz
|
302
|
+
Given I parse
|
303
|
+
"""
|
304
|
+
survey "Quiz time" do
|
305
|
+
section "First" do
|
306
|
+
q_the_answer "What is the 'Answer to the Ultimate Question of Life, The Universe, and Everything'", :correct => "adams"
|
307
|
+
a_pi "3.14"
|
308
|
+
a_zero "0"
|
309
|
+
a_adams "42"
|
310
|
+
end
|
311
|
+
end
|
312
|
+
"""
|
313
|
+
Then the question "the_answer" should have correct answer "adams"
|
314
|
+
|
315
|
+
@quiz
|
316
|
+
Scenario: Parsing a quiz for #365
|
317
|
+
Given I parse
|
318
|
+
"""
|
319
|
+
survey "Arithmetic" do
|
320
|
+
section "Addtion" do
|
321
|
+
q_1 "What is one plus one?", :pick => :one, :correct => "2"
|
322
|
+
a_1 "1"
|
323
|
+
a_2 "2"
|
324
|
+
a_3 "3"
|
325
|
+
a_4 "4"
|
326
|
+
|
327
|
+
q_2 "What is five plus one?", :pick => :one, :correct => "6"
|
328
|
+
a_5 "five"
|
329
|
+
a_6 "six"
|
330
|
+
a_7 "seven"
|
331
|
+
a_8 "eight"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
"""
|
335
|
+
Then the question "1" should have correct answer "2"
|
336
|
+
Then the question "2" should have correct answer "6"
|
337
|
+
|
338
|
+
Scenario: Parsing typos in blocks
|
339
|
+
Given the survey
|
340
|
+
"""
|
341
|
+
survey "Basics" do
|
342
|
+
sectionals "Typo" do
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
"""
|
347
|
+
Then the parser should fail with "\"sectionals\" is not a surveyor method."
|
348
|
+
|
349
|
+
Scenario: Parsing bad references
|
350
|
+
Given the survey
|
351
|
+
"""
|
352
|
+
survey "Refs" do
|
353
|
+
section "Bad" do
|
354
|
+
q_watch "Do you watch football?", :pick => :one
|
355
|
+
a_1 "Yes"
|
356
|
+
a_2 "No"
|
357
|
+
|
358
|
+
q "Do you like the replacement refs?", :pick => :one
|
359
|
+
dependency :rule => "A or B"
|
360
|
+
condition_A :q_1, "==", :a_1
|
361
|
+
condition_B :q_watch, "==", :b_1
|
362
|
+
a "Yes"
|
363
|
+
a "No"
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
"""
|
368
|
+
Then the parser should fail with "Bad references: q_1; q_1, a_1; q_watch, a_b_1"
|
369
|
+
|
370
|
+
Scenario: Parsing repeated references
|
371
|
+
Given the survey
|
372
|
+
"""
|
373
|
+
survey "Refs" do
|
374
|
+
section "Bad" do
|
375
|
+
q_watch "Do you watch football?", :pick => :one
|
376
|
+
a_1 "Yes"
|
377
|
+
a_1 "No"
|
378
|
+
|
379
|
+
q_watch "Do you watch baseball?", :pick => :one
|
380
|
+
a_yes "Yes"
|
381
|
+
a_no "No"
|
382
|
+
|
383
|
+
q "Do you like the replacement refs?", :pick => :one
|
384
|
+
dependency :rule => "A or B"
|
385
|
+
condition_A :q_watch, "==", :a_1
|
386
|
+
a "Yes"
|
387
|
+
a "No"
|
388
|
+
end
|
389
|
+
end
|
390
|
+
"""
|
391
|
+
Then the parser should fail with "Duplicate references: q_watch, a_1; q_watch"
|
392
|
+
|
393
|
+
Scenario: Parsing with Rails validation errors
|
394
|
+
Given the survey
|
395
|
+
"""
|
396
|
+
survey do
|
397
|
+
section "Usage" do
|
398
|
+
q_PLACED_BAG_1 "Is the bag placed?", :pick => :one
|
399
|
+
a_1 "Yes"
|
400
|
+
a_2 "No"
|
401
|
+
a_3 "Refused"
|
402
|
+
end
|
403
|
+
end
|
404
|
+
"""
|
405
|
+
Then the parser should fail with "Survey not saved: Title can't be blank"
|
406
|
+
|
407
|
+
Scenario: Parsing bad shortcuts
|
408
|
+
Given the survey
|
409
|
+
"""
|
410
|
+
survey "shortcuts" do
|
411
|
+
section "Bad" do
|
412
|
+
quack "Do you like ducks?", :pick => :one
|
413
|
+
a_1 "Yes"
|
414
|
+
a_1 "No"
|
415
|
+
end
|
416
|
+
end
|
417
|
+
"""
|
418
|
+
Then the parser should fail with "\"quack\" is not a surveyor method."
|
419
|
+
|
420
|
+
Scenario: Clearing grid answers
|
421
|
+
Given I parse
|
422
|
+
"""
|
423
|
+
survey "Grids" do
|
424
|
+
section "Leaking" do
|
425
|
+
grid "How would you rate the following?" do
|
426
|
+
a "bad"
|
427
|
+
a "neutral"
|
428
|
+
a "good"
|
429
|
+
q "steak" , :pick => :one
|
430
|
+
q "chicken", :pick => :one
|
431
|
+
q "fish", :pick => :one
|
432
|
+
end
|
433
|
+
grid "How do you feel about the following?" do
|
434
|
+
a "sad"
|
435
|
+
a "indifferent"
|
436
|
+
a "happy"
|
437
|
+
q "births" , :pick => :one
|
438
|
+
q "weddings", :pick => :one
|
439
|
+
q "funerals", :pick => :one
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
"""
|
444
|
+
Then there should be 18 answers with:
|
445
|
+
| text | display_order |
|
446
|
+
| bad | 0 |
|
447
|
+
| neutral | 1 |
|
448
|
+
| good | 2 |
|
449
|
+
| sad | 0 |
|
450
|
+
| indifferent | 1 |
|
451
|
+
| happy | 2 |
|
452
|
+
|
453
|
+
Scenario: Parsing mandatory questions
|
454
|
+
Given I parse
|
455
|
+
"""
|
456
|
+
survey "Chores", :default_mandatory => true do
|
457
|
+
section "Morning" do
|
458
|
+
q "Did you take out the trash", :pick => :one
|
459
|
+
a "Yes"
|
460
|
+
a "No"
|
461
|
+
|
462
|
+
q "Did you do the laundry", :pick => :one
|
463
|
+
a "Yes"
|
464
|
+
a "No"
|
465
|
+
|
466
|
+
q "Optional comments", :is_mandatory => false
|
467
|
+
a :string
|
468
|
+
end
|
469
|
+
end
|
470
|
+
"""
|
471
|
+
And there should be 3 questions with:
|
472
|
+
| text | is_mandatory |
|
473
|
+
| Did you take out the trash | true |
|
474
|
+
| Did you do the laundry | true |
|
475
|
+
| Optional comments | false |
|
476
|
+
|
477
|
+
@javascript
|
478
|
+
Scenario: Parsing dependencies with "question_" and "answer_" syntax
|
479
|
+
Given I parse
|
480
|
+
"""
|
481
|
+
survey "Days" do
|
482
|
+
section "Fridays" do
|
483
|
+
q_is_it_friday "Is it Friday?", :pick => :one
|
484
|
+
a_yes "Yes"
|
485
|
+
a_no "No"
|
486
|
+
|
487
|
+
label "woot!"
|
488
|
+
dependency :rule => "A"
|
489
|
+
condition_A :question_is_it_friday, "==", :answer_yes
|
490
|
+
end
|
491
|
+
end
|
492
|
+
"""
|
493
|
+
Then there should be 1 dependency with:
|
494
|
+
| rule |
|
495
|
+
| A |
|
496
|
+
And there should be 1 resolved dependency_condition with:
|
497
|
+
| rule_key |
|
498
|
+
| A |
|
499
|
+
When I go to the surveys page
|
500
|
+
And I start the "Days" survey
|
501
|
+
Then the question "woot!" should be hidden
|
502
|
+
And I choose "Yes"
|
503
|
+
Then the question "woot!" should be triggered
|
504
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# The redcap parser feature should run last. If it runs in between other features that use the surveyor parser,
|
2
|
+
# it causes the DependencyCondition before_save :resolve_references hook to stop running, causing hard to trace failures.
|
3
|
+
Feature: Survey import from REDCap
|
4
|
+
As a developer
|
5
|
+
I want to write out the survey in the DSL
|
6
|
+
So that I can give it to survey participants
|
7
|
+
|
8
|
+
Scenario: Basic questions from REDCap
|
9
|
+
Given I parse redcap file "REDCapDemoDatabase_DataDictionary.csv"
|
10
|
+
Then there should be 1 survey with:
|
11
|
+
||
|
12
|
+
And there should be 143 questions with:
|
13
|
+
||
|
14
|
+
And there should be 233 answers with:
|
15
|
+
||
|
16
|
+
And there should be 3 resolved dependency_conditions with:
|
17
|
+
| rule_key | operator | question_reference | answer_reference |
|
18
|
+
| A | == | sex | 0 |
|
19
|
+
| A | == | sex | 0 |
|
20
|
+
| B | == | given_birth | 1 |
|
21
|
+
And there should be 2 dependencies with:
|
22
|
+
| rule |
|
23
|
+
| A |
|
24
|
+
| A and B |
|
25
|
+
Scenario: Question level dependencies from REDCap
|
26
|
+
Given I parse redcap file "redcap_siblings.csv"
|
27
|
+
Then there should be 1 survey with:
|
28
|
+
||
|
29
|
+
And there should be 2 questions with:
|
30
|
+
||
|
31
|
+
And there should be 2 answers with:
|
32
|
+
||
|
33
|
+
And there should be 1 resolved dependency_conditions with:
|
34
|
+
| rule_key |
|
35
|
+
| A |
|
36
|
+
And there should be 1 dependencies with:
|
37
|
+
| rule |
|
38
|
+
| A |
|
39
|
+
Scenario: with different headers from REDCap
|
40
|
+
Given I parse redcap file "redcap_new_headers.csv"
|
41
|
+
Then there should be 1 survey with:
|
42
|
+
||
|
43
|
+
And there should be 1 questions with:
|
44
|
+
||
|
45
|
+
And there should be 2 answers with:
|
46
|
+
||
|
47
|
+
|
48
|
+
Scenario: with different whitespace from REDCap
|
49
|
+
Given I parse redcap file "redcap_whitespace.csv"
|
50
|
+
Then there should be 1 survey with:
|
51
|
+
||
|
52
|
+
And there should be 2 questions with:
|
53
|
+
||
|
54
|
+
And there should be 7 answers with:
|
55
|
+
| reference_identifier | text |
|
56
|
+
| 1 | Lexapro |
|
57
|
+
| 2 | Celexa |
|
58
|
+
| 3 | Prozac |
|
59
|
+
| 4 | Paxil |
|
60
|
+
| 5 | Zoloft |
|
61
|
+
| 0 | No |
|
62
|
+
| 1 | Yes |
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|