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.
Files changed (212) hide show
  1. data/.gitignore +28 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +198 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.rails_version +19 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +186 -0
  8. data/Rakefile +105 -0
  9. data/app/controllers/surveyor_controller.rb +6 -0
  10. data/app/helpers/results_helper.rb +20 -0
  11. data/app/helpers/survey_form_builder.rb +37 -0
  12. data/app/helpers/surveyor_helper.rb +3 -0
  13. data/app/inputs/quiet_input.rb +5 -0
  14. data/app/inputs/surveyor_check_boxes_input.rb +35 -0
  15. data/app/inputs/surveyor_radio_input.rb +18 -0
  16. data/app/models/answer.rb +4 -0
  17. data/app/models/dependency.rb +4 -0
  18. data/app/models/dependency_condition.rb +4 -0
  19. data/app/models/question.rb +4 -0
  20. data/app/models/question_group.rb +5 -0
  21. data/app/models/response.rb +5 -0
  22. data/app/models/response_set.rb +4 -0
  23. data/app/models/survey.rb +4 -0
  24. data/app/models/survey_section.rb +5 -0
  25. data/app/models/survey_section_sweeper.rb +15 -0
  26. data/app/models/survey_translation.rb +5 -0
  27. data/app/models/validation.rb +4 -0
  28. data/app/models/validation_condition.rb +4 -0
  29. data/app/views/layouts/results.html.erb +13 -0
  30. data/app/views/layouts/surveyor_default.html.erb +12 -0
  31. data/app/views/partials/_answer.html.haml +25 -0
  32. data/app/views/partials/_dependents.html.haml +5 -0
  33. data/app/views/partials/_question.html.haml +41 -0
  34. data/app/views/partials/_question_group.html.haml +44 -0
  35. data/app/views/partials/_section.html.haml +12 -0
  36. data/app/views/partials/_section_menu.html.haml +12 -0
  37. data/app/views/surveyor/edit.html.haml +24 -0
  38. data/app/views/surveyor/export.json.rabl +85 -0
  39. data/app/views/surveyor/new.html.haml +24 -0
  40. data/app/views/surveyor/show.html.haml +74 -0
  41. data/app/views/surveyor/show.json.rabl +15 -0
  42. data/ci-exec.sh +56 -0
  43. data/config/routes.rb +8 -0
  44. data/cucumber.yml +10 -0
  45. data/doc/REPRESENTATIONS.md +34 -0
  46. data/doc/api_id_schema.json +7 -0
  47. data/doc/question types.png +0 -0
  48. data/doc/response_set_schema.json +54 -0
  49. data/doc/surveyor question combinations.png +0 -0
  50. data/doc/surveyor reject or delete decision matrix.png +0 -0
  51. data/doc/surveyor_models.png +0 -0
  52. data/doc/surveyor_models2.png +0 -0
  53. data/doc/surveyor_timestamp_schema.json +9 -0
  54. data/features/ajax_submissions.feature +140 -0
  55. data/features/export_to_json.feature +344 -0
  56. data/features/internationalization.feature +121 -0
  57. data/features/no_duplicates.feature +110 -0
  58. data/features/show_survey.feature +71 -0
  59. data/features/step_definitions/parser_steps.rb +145 -0
  60. data/features/step_definitions/surveyor_steps.rb +325 -0
  61. data/features/step_definitions/ui_steps.rb +25 -0
  62. data/features/step_definitions/web_steps.rb +225 -0
  63. data/features/support/REDCapDemoDatabase_DataDictionary.csv +127 -0
  64. data/features/support/database_cleaner.rb +16 -0
  65. data/features/support/env.rb +56 -0
  66. data/features/support/hooks.rb +4 -0
  67. data/features/support/paths.rb +39 -0
  68. data/features/support/redcap_new_headers.csv +1 -0
  69. data/features/support/redcap_siblings.csv +1 -0
  70. data/features/support/redcap_whitespace.csv +1 -0
  71. data/features/support/selectors.rb +39 -0
  72. data/features/support/simultaneous_ajax.rb +101 -0
  73. data/features/support/single_quit_selenium_driver.rb +23 -0
  74. data/features/support/slow_updates.rb +18 -0
  75. data/features/surveyor.feature +895 -0
  76. data/features/surveyor_dependencies.feature +476 -0
  77. data/features/surveyor_parser.feature +504 -0
  78. data/features/z_redcap_parser.feature +62 -0
  79. data/lib/assets/images/surveyor/next.gif +0 -0
  80. data/lib/assets/images/surveyor/prev.gif +0 -0
  81. data/lib/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  82. data/lib/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  83. data/lib/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  84. data/lib/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  85. data/lib/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  86. data/lib/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  87. data/lib/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  88. data/lib/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  89. data/lib/assets/images/ui-icons_222222_256x240.png +0 -0
  90. data/lib/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  91. data/lib/assets/images/ui-icons_454545_256x240.png +0 -0
  92. data/lib/assets/images/ui-icons_888888_256x240.png +0 -0
  93. data/lib/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
  94. data/lib/assets/javascripts/surveyor/jquery-1.9.0.js +9555 -0
  95. data/lib/assets/javascripts/surveyor/jquery-ui-1.10.0.custom.js +14850 -0
  96. data/lib/assets/javascripts/surveyor/jquery-ui-timepicker-addon.js +1919 -0
  97. data/lib/assets/javascripts/surveyor/jquery.maskedinput.js +338 -0
  98. data/lib/assets/javascripts/surveyor/jquery.selectToUISlider.js +240 -0
  99. data/lib/assets/javascripts/surveyor/jquery.surveyor.js +156 -0
  100. data/lib/assets/stylesheets/surveyor/jquery-ui-1.10.0.custom.css +1174 -0
  101. data/lib/assets/stylesheets/surveyor/jquery-ui-timepicker-addon.css +11 -0
  102. data/lib/assets/stylesheets/surveyor/reset.css +48 -0
  103. data/lib/assets/stylesheets/surveyor/results.css +125 -0
  104. data/lib/assets/stylesheets/surveyor/ui.slider.extras.css +110 -0
  105. data/lib/assets/stylesheets/surveyor.sass +132 -0
  106. data/lib/generators/surveyor/custom_generator.rb +18 -0
  107. data/lib/generators/surveyor/install_generator.rb +102 -0
  108. data/lib/generators/surveyor/templates/app/assets/javascripts/surveyor_all.js +6 -0
  109. data/lib/generators/surveyor/templates/app/assets/stylesheets/surveyor_all.css +9 -0
  110. data/lib/generators/surveyor/templates/app/controllers/surveyor_controller.rb +40 -0
  111. data/lib/generators/surveyor/templates/app/views/layouts/surveyor_custom.html.erb +13 -0
  112. data/lib/generators/surveyor/templates/config/locales/surveyor_en.yml +19 -0
  113. data/lib/generators/surveyor/templates/config/locales/surveyor_es.yml +19 -0
  114. data/lib/generators/surveyor/templates/config/locales/surveyor_he.yml +19 -0
  115. data/lib/generators/surveyor/templates/config/locales/surveyor_ko.yml +19 -0
  116. data/lib/generators/surveyor/templates/db/migrate/add_api_id_to_question_groups.rb +10 -0
  117. data/lib/generators/surveyor/templates/db/migrate/add_api_ids.rb +14 -0
  118. data/lib/generators/surveyor/templates/db/migrate/add_api_ids_to_response_sets_and_responses.rb +12 -0
  119. data/lib/generators/surveyor/templates/db/migrate/add_attachment_to_response.rb +5 -0
  120. data/lib/generators/surveyor/templates/db/migrate/add_correct_answer_id_to_questions.rb +10 -0
  121. data/lib/generators/surveyor/templates/db/migrate/add_default_value_to_answers.rb +10 -0
  122. data/lib/generators/surveyor/templates/db/migrate/add_display_order_to_surveys.rb +10 -0
  123. data/lib/generators/surveyor/templates/db/migrate/add_display_type_to_answers.rb +14 -0
  124. data/lib/generators/surveyor/templates/db/migrate/add_index_to_response_sets.rb +10 -0
  125. data/lib/generators/surveyor/templates/db/migrate/add_index_to_surveys.rb +10 -0
  126. data/lib/generators/surveyor/templates/db/migrate/add_input_mask_attributes_to_answer.rb +12 -0
  127. data/lib/generators/surveyor/templates/db/migrate/add_section_id_to_responses.rb +12 -0
  128. data/lib/generators/surveyor/templates/db/migrate/add_unique_index_on_access_code_and_version_in_surveys.rb +10 -0
  129. data/lib/generators/surveyor/templates/db/migrate/add_unique_indicies.rb +18 -0
  130. data/lib/generators/surveyor/templates/db/migrate/add_version_to_surveys.rb +10 -0
  131. data/lib/generators/surveyor/templates/db/migrate/api_ids_must_be_unique.rb +23 -0
  132. data/lib/generators/surveyor/templates/db/migrate/create_answers.rb +38 -0
  133. data/lib/generators/surveyor/templates/db/migrate/create_dependencies.rb +23 -0
  134. data/lib/generators/surveyor/templates/db/migrate/create_dependency_conditions.rb +30 -0
  135. data/lib/generators/surveyor/templates/db/migrate/create_question_groups.rb +28 -0
  136. data/lib/generators/surveyor/templates/db/migrate/create_questions.rb +37 -0
  137. data/lib/generators/surveyor/templates/db/migrate/create_response_sets.rb +23 -0
  138. data/lib/generators/surveyor/templates/db/migrate/create_responses.rb +34 -0
  139. data/lib/generators/surveyor/templates/db/migrate/create_survey_sections.rb +30 -0
  140. data/lib/generators/surveyor/templates/db/migrate/create_survey_translations.rb +19 -0
  141. data/lib/generators/surveyor/templates/db/migrate/create_surveys.rb +32 -0
  142. data/lib/generators/surveyor/templates/db/migrate/create_validation_conditions.rb +33 -0
  143. data/lib/generators/surveyor/templates/db/migrate/create_validations.rb +21 -0
  144. data/lib/generators/surveyor/templates/db/migrate/drop_unique_index_on_access_code_in_surveys.rb +10 -0
  145. data/lib/generators/surveyor/templates/db/migrate/update_blank_api_ids_on_question_group.rb +22 -0
  146. data/lib/generators/surveyor/templates/db/migrate/update_blank_versions_on_surveys.rb +13 -0
  147. data/lib/generators/surveyor/templates/surveys/EXTENDING_SURVEYOR.md +52 -0
  148. data/lib/generators/surveyor/templates/surveys/MODIFYING_SURVEYOR.md +91 -0
  149. data/lib/generators/surveyor/templates/surveys/date_survey.rb +16 -0
  150. data/lib/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +284 -0
  151. data/lib/generators/surveyor/templates/surveys/languages.rb +14 -0
  152. data/lib/generators/surveyor/templates/surveys/quiz.rb +11 -0
  153. data/lib/generators/surveyor/templates/surveys/translations/languages.es.yml +18 -0
  154. data/lib/generators/surveyor/templates/surveys/translations/languages.he.yml +18 -0
  155. data/lib/generators/surveyor/templates/surveys/translations/languages.ko.yml +18 -0
  156. data/lib/generators/surveyor/templates/vendor/assets/stylesheets/custom.sass +5 -0
  157. data/lib/surveyor/acts_as_response.rb +17 -0
  158. data/lib/surveyor/common.rb +59 -0
  159. data/lib/surveyor/engine.rb +10 -0
  160. data/lib/surveyor/helpers/asset_pipeline.rb +13 -0
  161. data/lib/surveyor/helpers/formtastic_custom_input.rb +13 -0
  162. data/lib/surveyor/helpers/surveyor_helper_methods.rb +103 -0
  163. data/lib/surveyor/models/answer_methods.rb +86 -0
  164. data/lib/surveyor/models/dependency_condition_methods.rb +72 -0
  165. data/lib/surveyor/models/dependency_methods.rb +60 -0
  166. data/lib/surveyor/models/question_group_methods.rb +61 -0
  167. data/lib/surveyor/models/question_methods.rb +115 -0
  168. data/lib/surveyor/models/response_methods.rb +132 -0
  169. data/lib/surveyor/models/response_set_methods.rb +196 -0
  170. data/lib/surveyor/models/survey_methods.rb +103 -0
  171. data/lib/surveyor/models/survey_section_methods.rb +56 -0
  172. data/lib/surveyor/models/survey_translation_methods.rb +33 -0
  173. data/lib/surveyor/models/validation_condition_methods.rb +56 -0
  174. data/lib/surveyor/models/validation_methods.rb +48 -0
  175. data/lib/surveyor/mustache_context.rb +11 -0
  176. data/lib/surveyor/parser.rb +428 -0
  177. data/lib/surveyor/redcap_parser.rb +289 -0
  178. data/lib/surveyor/surveyor_controller_methods.rb +237 -0
  179. data/lib/surveyor/unparser.rb +147 -0
  180. data/lib/surveyor/version.rb +3 -0
  181. data/lib/surveyor.rb +13 -0
  182. data/lib/tasks/surveyor_tasks.rake +88 -0
  183. data/rails/init.rb +1 -0
  184. data/spec/controllers/surveyor_controller_spec.rb +307 -0
  185. data/spec/factories.rb +161 -0
  186. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  187. data/spec/helpers/surveyor_helper_spec.rb +118 -0
  188. data/spec/lib/benchmark_spec.rb +22 -0
  189. data/spec/lib/chinese_survey.rb +14 -0
  190. data/spec/lib/common_spec.rb +34 -0
  191. data/spec/lib/parser_spec.rb +204 -0
  192. data/spec/lib/rake_kitchen_sink.rb +40 -0
  193. data/spec/lib/redcap_parser_spec.rb +75 -0
  194. data/spec/lib/tasks_spec.rake +26 -0
  195. data/spec/lib/unparser_spec.rb +126 -0
  196. data/spec/models/answer_spec.rb +175 -0
  197. data/spec/models/dependency_condition_spec.rb +439 -0
  198. data/spec/models/dependency_spec.rb +101 -0
  199. data/spec/models/question_group_spec.rb +93 -0
  200. data/spec/models/question_spec.rb +207 -0
  201. data/spec/models/response_set_spec.rb +477 -0
  202. data/spec/models/response_spec.rb +218 -0
  203. data/spec/models/survey_section_spec.rb +85 -0
  204. data/spec/models/survey_spec.rb +191 -0
  205. data/spec/models/validation_condition_spec.rb +113 -0
  206. data/spec/models/validation_spec.rb +74 -0
  207. data/spec/rcov.opts +2 -0
  208. data/spec/spec.opts +4 -0
  209. data/spec/spec_helper.rb +56 -0
  210. data/stacktests.sh +65 -0
  211. data/surveyor.gemspec +45 -0
  212. metadata +657 -0
data/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ Gemfile.lock
21
+ reports
22
+ chromedriver.log
23
+
24
+ ## PROJECT::SPECIFIC
25
+ testbed
26
+ surveys/fixtures/*.yml
27
+ .rvmrc
28
+ .sass-cache/**/*.sassc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color -fn
data/CHANGELOG.md ADDED
@@ -0,0 +1,198 @@
1
+ History for Surveyor
2
+ ====================
3
+
4
+ 1.4.1
5
+ -----
6
+
7
+ ### Fixes
8
+
9
+ - Handle `nil` in `ResponseMethods#date_value=` and `ResponseMethods#time_value`.
10
+ (#450)
11
+ - Handle `nil` datetime values in `ResponseMethods#to_formatted_s`. (#459)
12
+
13
+ ### Dependencies
14
+
15
+ - Removing support for Ruby 1.8.7. Applications requiring Ruby 1.8.7 should use Surveyor v1.4.0
16
+
17
+ 1.4.0
18
+ -----
19
+ ### Features
20
+
21
+ - Routes are namespaced (e.g. `surveyor.available_surveys_path`) and may be mounted at a different root (e.g. `mount Surveyor::Engine, :at => '/instruments'`) (#398, #421)
22
+ - Surveyor::Parser.parse_file takes an options[:filename] parameter, used to locate translations (#429)
23
+ - Surveyor::Parser allows translations to be specified inline using a hash (#429)
24
+ - require locale of survey when translations are present (#426)
25
+ - locale selection in survey UI (#427)
26
+
27
+ ### Fixes
28
+
29
+ - Remove default order on Response. (#423)
30
+ - Bug fix for RedCap Parser for DependencyConditions. thanks @ariel-perez-birchbox
31
+ - Make Surveyor::Parser accept Answer#reference_identifier via underscore or hash syntax (#439)
32
+ - Fix show action and have it use new translation view methods (#438, #442) thanks @alanjcfs
33
+ - Fix times showing in UTC when time zone is specified in Rails (#435)
34
+
35
+ ### Dependencies
36
+
37
+ - Removing support for Rails 3.0. Applications requiring Rails 3.0 should use Surveyor v1.3.0
38
+
39
+ 1.3.0
40
+ -----
41
+
42
+ ### Features
43
+
44
+ - Upgrade to jQuery UI 1.10.0, jQuery 1.9.0, jQueryUI timepicker addons 1.2, and remove jQuery tools (#409)
45
+ - Upgrade reset css
46
+ - Added surveyor_translations table to support YAML-based localizations of surveys. (#420)
47
+ - Add extension point for pre-JSON-export survey modifications (#416)
48
+ - Add input mask for text entry fields (#415)
49
+
50
+ ### Fixes
51
+
52
+ - Export null when datetime response has null datetime value
53
+ - Move the help text to be after the answer text (#401)
54
+ - Fix response serialization for date pick one answers (#400)
55
+ - Remove ordering default scope on survey section methods (#417, #290)
56
+ - Answers of labels should not be shown, within or without groups (#304)
57
+ - Inline group questions should display inline (#303)
58
+ - Evaluate all submitted questions for depdencies (#396)
59
+ - Pick one answers with dates should display their dates correctly (#378)
60
+
61
+ ### Infrastructure
62
+
63
+ - Added stacktests.sh shell script for testing different stacks
64
+
65
+ 1.2.0
66
+ -----
67
+
68
+ ### Features
69
+
70
+ - Allow rendering of simple hash contexts with Mustache (#296)
71
+ - Allow configuration of question numbering (#136)
72
+ - Allow references to question_ and answer_ in dependency conditions (#345)
73
+
74
+ ### Fixes
75
+
76
+ - Surveyor will never require 'fastercsv' on Ruby 1.9. (#381)
77
+ - Add question_groups/question/answer/reference_identifier to JSON
78
+ serialization for Survey. (#390)
79
+ - Evaluate dependencies even when the last response is removed (#362, #215)
80
+ - Add answer help text (#373)
81
+ - SurveyorController#export now renders 404 when surveys are not found (#391)
82
+
83
+ 1.1.0
84
+ -----
85
+
86
+ ### Features
87
+
88
+ - Breaking change: Question#is_mandatory => false by default. For those who found it useful to have
89
+ all questions mandatory, the parser accepts `:default_mandatory => true` as an argument to the survey.
90
+
91
+ ### Fixes
92
+
93
+ - fixing and documenting count operators on dependency conditions
94
+
95
+ ### Infrastructure
96
+
97
+ - basic spec for the surveyor task
98
+
99
+ 1.0.1
100
+ ------
101
+
102
+ ### Features
103
+
104
+ - Question#display_type == "hidden" and QuestionGroup#display_type == "hidden"
105
+ now exclude the question or question group from the DOM. These display types are
106
+ used to inject data (responses) into surveys. Note, custom_class => "hidden" doesn't
107
+ have any effect until a custom css rule is created by the end user. (#197)
108
+
109
+ - more readable parser and more strict parser method aliases (#278)
110
+
111
+ ### Fixes
112
+
113
+ - Replaced deprecated ActiveRecord::Errors#each_full with ActiveRecord::Errors#full_messages. (#363)
114
+
115
+ - fixing dependency condition evaluation where #Response.*_value is nil. (#297)
116
+
117
+ - fixing grid answers leak, introduced in 5baa7ac3. thanks @jsurrett (#375, #377)
118
+
119
+ 1.0.0
120
+ ------
121
+
122
+ ### Features
123
+
124
+ - Official support for Rails 3.2, including declaring of all mass-assignable
125
+ attributes with `attr_accessible`.
126
+
127
+ - Breaking change: Surveys are now explicitly versioned. If you loaded a survey
128
+ when another survey with the same title/access code had already been loaded,
129
+ Surveyor would previously have appended a serial number to the title. As of
130
+ this version, Surveyor keeps the serial number in a separate `survey_version`
131
+ field. (#262)
132
+
133
+ - Add encoding comments for generated files. (#329)
134
+
135
+ - Asset pipeline support for Rails 3.1+. Rails 3.0 is still supported.
136
+ (#307, #314, #315)
137
+
138
+ - Upgrade to Formtastic 2.1. (#227)
139
+
140
+ - `:pick => :one` and `:pick => :any` questions may now have date, time,
141
+ datetime, integer, or float values, in addition to the already-supported
142
+ string values. (#207)
143
+
144
+ - Added Survey#as_json, ResponseSet#as_json. (#291)
145
+
146
+ - Changed defaults for and interpretation of for Survey#active_at and
147
+ Survey#inactive_at. (#258)
148
+
149
+ - JSON export representation of DateTimes is 2010-04-08T10:30+00:00 and Dates is
150
+ 2010-04-08 and Times is 10:30. (#355)
151
+
152
+ - JSON representation of Response includes response_group. (#349)
153
+
154
+ - Use Object#extend to inject SuryeyorParser and SurveyorRedcapParser methods into
155
+ instances of models instead of reopening classes. Move responsibility for keeping
156
+ track of and reporting duplicate and bad references from the models to the parsers.
157
+ Upgrade SurveyorRedcapParser to trace only when rake --trace is specified. (#341)
158
+
159
+ - export Question#data_export_identifier, Answer#data_export_identifier,
160
+ Answer#reference_identifier in survey JSON export. (#368)
161
+
162
+ ### Fixes
163
+
164
+ - Ensure response set is available to `render_context` (#320)
165
+
166
+ - Hide dependent rows of grids. (#343)
167
+
168
+ - Dependency condition with '!=' now returns true if there is no response. (#337)
169
+
170
+ - Properly handle multiple "exclusive" checkboxes in a single question. (#336)
171
+
172
+ - Correct storing of "correct" answers when parsing a survey. (#326)
173
+
174
+ - Restore "slider" renderer. (#230)
175
+
176
+ - Ensure that duplicate responses cannot be created by parallel AJAX requests.
177
+ (#328)
178
+
179
+ - Create default identifiers in before_create, not in the initializer. (#369)
180
+
181
+ - Eliminate unnecessary (and incorrect) access code uniqueness checks.
182
+ Use SecureRandom for generating access codes. (#370)
183
+
184
+ - Use json_spec for testing JSON responses, instead of
185
+ Surveyor::Common#deep_compare_excluding_wildcards. (#350)
186
+
187
+ - Parser now sets Question#correct_answer_id correctly. The association is changed from
188
+ Question :has_one correct_answer => Question :belongs_to correct_answer. (#365)
189
+
190
+ ### Infrastructure
191
+
192
+ - Enabled Selenium-backed cucumber features in CI. (#333)
193
+
194
+ - Added `testbed:surveys` task to load all sample surveys in the testbed.
195
+
196
+ - Begin formal changelog.
197
+
198
+ - Change test infra so that tx behavior can be tested. (#360)
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://www.rubygems.org'
2
+
3
+ gemspec
4
+
5
+ eval(File.read File.expand_path('../Gemfile.rails_version', __FILE__))
@@ -0,0 +1,19 @@
1
+ # For testing against different releases of Rails. This is in a
2
+ # separate fragment so that it can be sourced from the test
3
+ # application's Gemfile in addition to the main development Gemfile.
4
+ if ENV['RAILS_VERSION']
5
+ case ENV['RAILS_VERSION']
6
+ when /3.0$/
7
+ gem 'rails', '~> 3.0.15'
8
+ when /3.1$/
9
+ gem 'rails', '~> 3.1.0'
10
+ # A JS runtime is required for Rails 3.1+
11
+ gem 'therubyracer', '~> 0.10.2'
12
+ when /3.2$/
13
+ gem 'rails', '~> 3.2.0'
14
+ # A JS runtime is required for Rails 3.1+
15
+ gem 'therubyracer', '~> 0.10.2'
16
+ else
17
+ fail "Unknown Rails version #{ENV['RAILS_VERSION']}"
18
+ end
19
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2010 Brian Chamberlain and Mark Yoon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,186 @@
1
+ ## What's different in this version
2
+
3
+ * Ability to attach files
4
+ * Fix to question/group numbering
5
+
6
+ ## Why surveyor?
7
+
8
+ Surveyor is a developer tool to deliver surveys in Rails applications.
9
+ Surveys are written in the surveyor DSL (Domain Specific
10
+ Language). A DSL makes it significantly easier to import long surveys
11
+ (one of the motivations for building surveyor was copy/paste fatigue).
12
+ It enables non-programmers to write out, edit, and review surveys.
13
+
14
+ If your Rails app needs to asks users questions as part of a survey, quiz,
15
+ or questionnaire then you should consider using surveyor. This gem was
16
+ designed to deliver clinical research surveys to large populations,
17
+ but it can be used for any type of survey.
18
+
19
+ Surveyor is a Rails engine distributed as a ruby gem, meaning it is
20
+ straightforward to override or extend its behaviors in your Rails app
21
+ without maintaining a fork.
22
+
23
+ ## Requirements
24
+
25
+ Surveyor works with:
26
+
27
+ * Ruby 1.9.2, and 1.9.3
28
+ * Rails 3.1-3.2
29
+
30
+ In keeping with the Rails team maintenance [policy] we no longer support Rails 3.0 (stick with v1.3.0 if you need Rails 3.0) or Ruby 1.8.7 (stick with v1.4.0 if you need Ruby 1.8.7).
31
+
32
+ Some key dependencies are:
33
+
34
+ * HAML
35
+ * Sass
36
+ * Formtastic
37
+
38
+ A more exhaustive list can be found in the [gemspec][].
39
+
40
+ [gemspec]: https://github.com/NUBIC/surveyor/blob/master/surveyor.gemspec
41
+ [policy]: http://weblog.rubyonrails.org/2013/2/24/maintenance-policy-for-ruby-on-rails/
42
+
43
+ ## Install
44
+
45
+ Add surveyor to your Gemfile:
46
+
47
+ gem "surveyor"
48
+
49
+ Bundle, install, and migrate:
50
+
51
+ bundle install
52
+ script/rails generate surveyor:install
53
+ bundle exec rake db:migrate
54
+
55
+ Parse the "kitchen sink" survey ([kitchen sink](http://en.wiktionary.org/wiki/everything_but_the_kitchen_sink) means almost everything)
56
+
57
+ bundle exec rake surveyor FILE=surveys/kitchen_sink_survey.rb
58
+
59
+ Start up your app, visit `/surveys`, compare what you see to [kitchen\_sink\_survey.rb][kitchensink] and try responding to the survey.
60
+
61
+ [kitchensink]: http://github.com/NUBIC/surveyor/blob/master/lib/generators/surveyor/templates/surveys/kitchen_sink_survey.rb
62
+
63
+ ## Customize surveyor
64
+
65
+ Surveyor's controller, helper, models, and views may be overridden by classes in your `app` folder. To generate a sample custom controller and layout run:
66
+
67
+ script/rails generate surveyor:custom
68
+
69
+ and read the instructions generated in [`surveys/EXTENDING_SURVEYOR.MD`][extending]
70
+
71
+ [extending]: https://github.com/NUBIC/surveyor/blob/master/lib/generators/surveyor/templates/surveys/EXTENDING_SURVEYOR.md
72
+
73
+ ## Upgrade surveyor
74
+
75
+ To get the latest version of surveyor, bundle, install and migrate:
76
+
77
+ bundle update surveyor
78
+ script/rails generate surveyor:install
79
+ bundle exec rake db:migrate
80
+
81
+ and review the [changelog][] for changes that may affect your customizations.
82
+
83
+ [changelog]: https://github.com/NUBIC/surveyor/blob/master/CHANGELOG.md
84
+
85
+ ## What surveyor does and doesn't do
86
+
87
+ ### Does do
88
+ * use a DSL to parse large surveys without hours of copy/paste into a gui builder
89
+ * support complex, rule-based dependencies (skip-logic)
90
+ * JSON export of both surveys and response sets
91
+ * allow customization of all models, views, and controller, as well as helpers and routes
92
+ * follow semantic versioning
93
+ * exclusive checkboxes - a checkbox that when checked, unchecks all the others
94
+
95
+ ### Doesn't do
96
+ * Enforce mandatory questions... yet (although it does have some[1] methods[2] on ResponseSet to support that)
97
+ * Dependencies within repeaters... yet [#235](http://github.com/NUBIC/surveyor/issues/235)
98
+ * Validations within the UI... yet [#34](http://github.com/NUBIC/surveyor/issues/34), although it does have model support and database representations
99
+ * GUI creating, editing, deleting and administration of surveys... yet [#414](http://github.com/NUBIC/surveyor/issues/414)
100
+ * Consistently support HTML tags in title, text, help_text attributes. We intend to move to markdown support [#413](http://github.com/NUBIC/surveyor/issues/413) so that same survey definition can be used with [nu_surveyor](http://github.com/NUBIC/nu_surveyor).
101
+
102
+ [1]: http://github.com/NUBIC/surveyor/blob/master/lib/surveyor/models/response_set_methods.rb#L94
103
+ [2]: http://github.com/NUBIC/surveyor/blob/master/lib/surveyor/models/response_set_methods.rb#L97
104
+
105
+
106
+ ## Users of spork
107
+
108
+ There is [an issue with spork and custom inputs in formatstic (#851)][851]. A workaround (thanks rmm5t!):
109
+
110
+ Spork.prefork do
111
+ # ...
112
+ surveyor_path = Gem.loaded_specs['surveyor'].full_gem_path
113
+ Dir["#{surveyor_path}/app/inputs/*_input.rb"].each { |f| require File.basename(f) }
114
+ # ...
115
+ end
116
+
117
+ [851]: https://github.com/justinfrench/formtastic/issues/851
118
+
119
+ ## Follow master
120
+
121
+ If you are following pre-release versions of surveyor using a `:git`
122
+ source in your Gemfile, be particularly careful about reviewing migrations after
123
+ updating surveyor and re-running the generator. We will never change a migration
124
+ between two released versions of surveyor. However, we may on rare occasions
125
+ change a migration which has been merged into master. When this happens, you'll
126
+ need to assess the differences and decide on an appropriate course of action for
127
+ your app. If you aren't sure what this means, we do not recommend that you deploy an app
128
+ that's locked to surveyor master into production.
129
+
130
+ ## Support
131
+
132
+ For general discussion (e.g., "how do I do this?"), please send a message to the
133
+ [surveyor-dev][] group. This group is moderated to keep out spam; don't be
134
+ surprised if your message isn't posted immediately.
135
+
136
+ For reproducible bugs, please file an issue on the [GitHub issue tracker][issues].
137
+ Please include a minimal test case (a detailed description of
138
+ how to trigger the bug in a clean rails application). If you aren't sure how to
139
+ isolate the bug, send a message to [surveyor-dev][] with what you know and we'll
140
+ try to help.
141
+
142
+ For build status see our [continuous integration page][ci].
143
+
144
+ Take a look at our [screencast][] (a bit dated now).
145
+
146
+ [surveyor-dev]: https://groups.google.com/group/surveyor-dev
147
+ [issues]: https://github.com/NUBIC/surveyor/issues
148
+ [ci]:https://public-ci.nubic.northwestern.edu/job/surveyor/
149
+ [screencast]:http://vimeo.com/7051279
150
+
151
+ ## Contribute, test
152
+
153
+ To work on the code, fork this github project. Install [bundler][] if
154
+ you don't have it, then bundle, generate the app in `testbed`, and run the specs and features
155
+
156
+ $ bundle update
157
+ $ bundle exec rake testbed
158
+ $ bundle exec rake spec
159
+ $ bundle exec rake cucumber
160
+
161
+ [bundler]: http://gembundler.com/
162
+
163
+ ## Selenium
164
+
165
+ Some of surveyor's integration tests use Selenium WebDriver and Capybara. The
166
+ WebDriver-based tests default to running in Chrome due to an unfortunate
167
+ [Firefox bug][FF566671]. For them to run, you'll either need:
168
+
169
+ * Chrome and [chromedriver][] installed, or
170
+ * to switch to use Firefox instead
171
+
172
+ To use Firefox instead of Chrome, invoke one or more features with
173
+ `SELENIUM_BROWSER` set in the environment:
174
+
175
+ $ SELENIUM_BROWSER=firefox bundle exec rake cucumber
176
+ $ SELENIUM_BROWSER=firefox bundle exec cucumber features/ajax_submissions.feature
177
+
178
+ Note that when running features in Firefox, you must allow the WebDriver-driven
179
+ Firefox to retain focus, otherwise some tests will fail.
180
+
181
+ [FF566671]: https://bugzilla.mozilla.org/show_bug.cgi?id=566671
182
+ [chromedriver]: http://code.google.com/p/selenium/wiki/ChromeDriver
183
+
184
+ Copyright (c) 2008-2013 Brian Chamberlain and Mark Yoon, released under the [MIT license][mit]
185
+
186
+ [mit]: https://github.com/NUBIC/surveyor/blob/master/MIT-LICENSE
data/Rakefile ADDED
@@ -0,0 +1,105 @@
1
+ $LOAD_PATH << File.expand_path('../lib', __FILE__)
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'cucumber/rake/task'
6
+ require 'ci/reporter/rake/rspec'
7
+
8
+ ###### RSPEC
9
+
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
13
+ spec.rcov = true
14
+ end
15
+
16
+ task :default => :spec
17
+
18
+ ###### CUCUMBER
19
+
20
+ namespace :cucumber do
21
+ Cucumber::Rake::Task.new(:ok, 'Run features that should pass') do |t|
22
+ t.profile = 'default'
23
+ end
24
+
25
+ Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
26
+ t.profile = 'wip'
27
+ end
28
+
29
+ desc 'Run all features'
30
+ task :all => [:ok, :wip]
31
+ end
32
+ desc 'Alias for cucumber:ok'
33
+ task :cucumber => 'cucumber:ok'
34
+
35
+ ###### TESTBED
36
+
37
+ desc 'Set up the rails app that the specs and features use'
38
+ task :testbed => 'testbed:rebuild'
39
+
40
+ namespace :testbed do
41
+ desc 'Generate a minimal surveyor-using rails app'
42
+ task :generate do
43
+ Tempfile.open('surveyor_Rakefile') do |f|
44
+ f.write("application \"config.time_zone='Rome'\"");f.flush
45
+ sh "bundle exec rails new testbed --skip-bundle -m #{f.path}" # don't run bundle install until the Gemfile modifications
46
+ end
47
+ chdir('testbed') do
48
+ gem_file_contents = File.read('Gemfile')
49
+ gem_file_contents.sub!(/^(gem 'rails'.*)$/, %Q{# \\1\nplugin_root = File.expand_path('../..', __FILE__)\neval(File.read File.join(plugin_root, 'Gemfile.rails_version'))\ngem 'surveyor', :path => plugin_root})
50
+ File.open('Gemfile', 'w'){|f| f.write(gem_file_contents) }
51
+
52
+ Bundler.with_clean_env do
53
+ sh 'bundle install' # run bundle install after Gemfile modifications
54
+ end
55
+ end
56
+ end
57
+
58
+ desc 'Prepare the databases for the testbed'
59
+ task :migrate do
60
+ chdir('testbed') do
61
+ Bundler.with_clean_env do
62
+ sh 'bundle exec rails generate surveyor:install'
63
+ sh 'bundle exec rake db:migrate db:test:prepare'
64
+ end
65
+ end
66
+ end
67
+
68
+ desc 'Remove the testbed entirely'
69
+ task :remove do
70
+ rm_rf 'testbed'
71
+ end
72
+
73
+ task :rebuild => [:remove, :generate, :migrate]
74
+
75
+ desc 'Load all the sample surveys into the testbed instance'
76
+ task :surveys do
77
+ cd('testbed') do
78
+ Dir[File.join('surveys', '*.rb')].each do |fn|
79
+ puts "Installing #{fn} into the testbed"
80
+ system("rake surveyor FILE='#{fn}'")
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ ###### CI
87
+
88
+ namespace :ci do
89
+ task :all => ['rake:testbed', :spec, :cucumber, 'cucumber:wip']
90
+
91
+ task :env do
92
+ ENV['CI_REPORTS'] = 'reports/spec-xml'
93
+ ENV['SPEC_OPTS'] = "#{ENV['SPEC_OPTS']} --format nested"
94
+ end
95
+
96
+ Cucumber::Rake::Task.new(:cucumber, 'Run features using the CI profile') do |t|
97
+ t.profile = 'ci'
98
+ end
99
+
100
+ Cucumber::Rake::Task.new('cucumber:wip', 'Run WIP features using the CI profile') do |t|
101
+ t.profile = 'ci_wip'
102
+ end
103
+
104
+ task :spec => [:env, 'ci:setup:rspecbase', 'rake:spec']
105
+ end
@@ -0,0 +1,6 @@
1
+ # Surveyor Controller allows a user to take a survey. It is semi-RESTful since it does not have a concrete representation model.
2
+ # The "resource" is a survey attempt/session populating a response set.
3
+ class SurveyorController < ApplicationController
4
+ unloadable
5
+ include Surveyor::SurveyorControllerMethods
6
+ end
@@ -0,0 +1,20 @@
1
+ module ResultsHelper
2
+ def display_response(r_set,question)
3
+ sets = r_set.responses.select{|r| r.question.display_order == question.display_order}
4
+ if sets.size == 0
5
+ return "-"
6
+ elsif sets.size == 1
7
+ return (sets.first.string_value || sets.first.text_value || show_answer(sets.first))
8
+ else
9
+ txt = ""
10
+ sets.each do |set|
11
+ txt << show_answer(set) + "<br/>"
12
+ end
13
+ return txt
14
+ end
15
+ end
16
+
17
+ def show_answer(set)
18
+ set.answer.text
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ class SurveyFormBuilder < ActionView::Helpers::FormBuilder
2
+ def survey_check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
3
+ fields = @template.survey_check_box(@object_name, method, options.merge(:object => @object), checked_value, unchecked_value)
4
+ fields[1]
5
+ end
6
+ end
7
+
8
+ module ActionView
9
+ module Helpers
10
+ module FormHelper
11
+ def survey_check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
12
+ if (Rails::VERSION::STRING.to_f > 2.1)
13
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_survey_check_box_tag(options, checked_value, unchecked_value)
14
+ else
15
+ InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_survey_check_box_tag(options, checked_value, unchecked_value)
16
+ end
17
+ end
18
+ end
19
+
20
+ class InstanceTag
21
+ def to_survey_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
22
+ options = options.stringify_keys
23
+ options["type"] = "checkbox"
24
+ options["value"] = checked_value
25
+ if options.has_key?("checked")
26
+ cv = options.delete "checked"
27
+ checked = cv == true || cv == "checked"
28
+ else
29
+ checked = self.class.check_box_checked?(value(object), checked_value)
30
+ end
31
+ options["checked"] = "checked" if checked
32
+ add_default_name_and_id(options)
33
+ [tag("input", "name" => options["name"], "type" => "hidden", "value" => unchecked_value), tag("input", options)]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module SurveyorHelper
2
+ include Surveyor::Helpers::SurveyorHelperMethods
3
+ end
@@ -0,0 +1,5 @@
1
+ class QuietInput < Formtastic::Inputs::HiddenInput
2
+ def to_html
3
+ super
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ class SurveyorCheckBoxesInput < Formtastic::Inputs::CheckBoxesInput
2
+ include Surveyor::Helpers::FormtasticCustomInput
3
+ def to_html
4
+ super
5
+ end
6
+ def choice_html(choice)
7
+ output = ""
8
+ output << template.content_tag(:label,
9
+ hidden_fields? ?
10
+ check_box_with_hidden_input(choice) :
11
+ check_box_without_hidden_input(choice) <<
12
+ choice_label(choice),
13
+ label_html_options.merge(:for => choice_input_dom_id(choice), :class => nil)
14
+ )
15
+ output << builder.text_field(:response_other, input_html_options_with(choice, :response_other)) if options[:response_class] == "other_and_string"
16
+ output << builder.text_field(response_class_to_method(options[:response_class]), input_html_options_with(choice, options[:response_class])) if %w(date datetime time float integer string other_and_string).include? options[:response_class]
17
+ output << builder.text_area(:text_value, input_html_options_with(choice, :text_value)) if options[:response_class] == "text"
18
+ output.html_safe
19
+ end
20
+ def checked?(value)
21
+ selected_values.include?(value.to_s)
22
+ end
23
+ def disabled?(value)
24
+ disabled_values.include?(value) || input_html_options[:disabled] == true
25
+ end
26
+ def make_selected_values
27
+ if object.respond_to?(method)
28
+ selected_items = [object.send(method)].compact.flatten.map(&:to_s)
29
+
30
+ [*selected_items.map { |o| send_or_call_or_object(value_method, o) }].compact
31
+ else
32
+ []
33
+ end
34
+ end
35
+ end