surveyor_gui 0.0.3

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 (283) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +44 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +21 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +159 -0
  8. data/Rakefile +66 -0
  9. data/app/controllers/answers_controller.rb +3 -0
  10. data/app/controllers/application_controller.rb +3 -0
  11. data/app/controllers/dependencys_controller.rb +286 -0
  12. data/app/controllers/question_groups_controller.rb +84 -0
  13. data/app/controllers/questions_controller.rb +187 -0
  14. data/app/controllers/survey_sections_controller.rb +80 -0
  15. data/app/controllers/surveyforms_controller.rb +4 -0
  16. data/app/controllers/surveyor_controller.rb +89 -0
  17. data/app/controllers/surveyor_gui/reports_controller.rb +339 -0
  18. data/app/controllers/surveyor_gui/responses_controller.rb +39 -0
  19. data/app/controllers/surveyor_gui/survey_controller.rb +16 -0
  20. data/app/facades/report_formatter.rb +44 -0
  21. data/app/facades/report_preview_wrapper.rb +11 -0
  22. data/app/facades/report_response_generator.rb +147 -0
  23. data/app/helpers/application_helper.rb +2 -0
  24. data/app/helpers/dependency_helper.rb +5 -0
  25. data/app/helpers/question_helper.rb +22 -0
  26. data/app/helpers/surveyform_helper.rb +179 -0
  27. data/app/helpers/surveyor_gui/report_helper.rb +19 -0
  28. data/app/helpers/surveyor_helper.rb +4 -0
  29. data/app/inputs/currency_input.rb +5 -0
  30. data/app/inputs/date_picker_input.rb +7 -0
  31. data/app/inputs/datetime_picker_input.rb +5 -0
  32. data/app/inputs/percent_input.rb +5 -0
  33. data/app/inputs/time_picker_input.rb +5 -0
  34. data/app/mailers/.gitkeep +0 -0
  35. data/app/models/.gitkeep +0 -0
  36. data/app/models/answer.rb +4 -0
  37. data/app/models/column.rb +3 -0
  38. data/app/models/dependency.rb +4 -0
  39. data/app/models/dependency_condition.rb +4 -0
  40. data/app/models/permitted_params_decorator.rb +80 -0
  41. data/app/models/question.rb +4 -0
  42. data/app/models/question_group.rb +4 -0
  43. data/app/models/question_type.rb +7 -0
  44. data/app/models/response.rb +4 -0
  45. data/app/models/response_set.rb +4 -0
  46. data/app/models/row.rb +3 -0
  47. data/app/models/survey.rb +4 -0
  48. data/app/models/survey_section.rb +4 -0
  49. data/app/models/surveyform.rb +103 -0
  50. data/app/uploaders/blob_uploader.rb +48 -0
  51. data/app/views/dependencys/_column.html.erb +1 -0
  52. data/app/views/dependencys/_dependency.html.erb +22 -0
  53. data/app/views/dependencys/_dependency_condition_fields.html.erb +48 -0
  54. data/app/views/dependencys/_form.html.erb +20 -0
  55. data/app/views/dependencys/blank.html.erb +0 -0
  56. data/app/views/dependencys/edit.html.erb +1 -0
  57. data/app/views/dependencys/new.html.erb +1 -0
  58. data/app/views/layouts/application.html.erb +14 -0
  59. data/app/views/layouts/surveyor_gui_blank.html.erb +12 -0
  60. data/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  61. data/app/views/layouts/surveyor_modified.html.erb +14 -0
  62. data/app/views/partials/_answer.html.haml +33 -0
  63. data/app/views/partials/_question.html.haml +33 -0
  64. data/app/views/partials/_question_group.html.haml +73 -0
  65. data/app/views/partials/_section.html.haml +13 -0
  66. data/app/views/question_groups/_form.html.erb +56 -0
  67. data/app/views/question_groups/_group_inline_field.html.erb +21 -0
  68. data/app/views/question_groups/_group_inline_fields.html.erb +25 -0
  69. data/app/views/question_groups/blank.html.erb +0 -0
  70. data/app/views/question_groups/edit.html.erb +1 -0
  71. data/app/views/question_groups/new.html.erb +1 -0
  72. data/app/views/questions/_answer_fields.html.erb +23 -0
  73. data/app/views/questions/_answer_options.html.erb +28 -0
  74. data/app/views/questions/_form.html.erb +65 -0
  75. data/app/views/questions/_grid_dropdown_columns.html.erb +10 -0
  76. data/app/views/questions/_grid_dropdown_fields.html.erb +42 -0
  77. data/app/views/questions/_grid_fields.html.erb +9 -0
  78. data/app/views/questions/_no_picks.html.erb +29 -0
  79. data/app/views/questions/_pick.html +21 -0
  80. data/app/views/questions/_picks.html.erb +12 -0
  81. data/app/views/questions/blank.html.erb +0 -0
  82. data/app/views/questions/edit.html.erb +1 -0
  83. data/app/views/questions/new.html.erb +1 -0
  84. data/app/views/survey_sections/_form.html.erb +13 -0
  85. data/app/views/survey_sections/blank.html.erb +0 -0
  86. data/app/views/survey_sections/edit.html.erb +1 -0
  87. data/app/views/survey_sections/new.html.erb +1 -0
  88. data/app/views/surveyforms/_form.html.erb +50 -0
  89. data/app/views/surveyforms/_question_field.html.erb +148 -0
  90. data/app/views/surveyforms/_question_group.html.erb +116 -0
  91. data/app/views/surveyforms/_question_group_fields.html.erb +3 -0
  92. data/app/views/surveyforms/_question_name_and_number.html.erb +6 -0
  93. data/app/views/surveyforms/_question_section.html.erb +15 -0
  94. data/app/views/surveyforms/_question_wrapper.html.erb +109 -0
  95. data/app/views/surveyforms/_survey_section_fields.html.erb +138 -0
  96. data/app/views/surveyforms/clone_survey.html.erb +13 -0
  97. data/app/views/surveyforms/edit.html.erb +5 -0
  98. data/app/views/surveyforms/index.html.erb +40 -0
  99. data/app/views/surveyforms/new.html.erb +1 -0
  100. data/app/views/surveyforms/show.html.erb +5 -0
  101. data/app/views/surveyor_gui/reports/_graphs.html.haml +21 -0
  102. data/app/views/surveyor_gui/reports/_grid.html.haml +42 -0
  103. data/app/views/surveyor_gui/reports/_grid_dropdown.html.haml +56 -0
  104. data/app/views/surveyor_gui/reports/_repeater.html.haml +28 -0
  105. data/app/views/surveyor_gui/reports/_show_report.html.haml +33 -0
  106. data/app/views/surveyor_gui/reports/_single_question.html.haml +70 -0
  107. data/app/views/surveyor_gui/reports/show.html.erb +14 -0
  108. data/app/views/surveyor_gui/responses/_grid.html.haml +20 -0
  109. data/app/views/surveyor_gui/responses/_grid_dropdown.html.haml +20 -0
  110. data/app/views/surveyor_gui/responses/_repeater.html.haml +22 -0
  111. data/app/views/surveyor_gui/responses/_survey_results.html.haml +40 -0
  112. data/app/views/surveyor_gui/responses/index.html.haml +24 -0
  113. data/app/views/surveyor_gui/responses/show.html.haml +42 -0
  114. data/app/views/surveyor_gui/shared/_grid_comments.html.haml +10 -0
  115. data/app/views/surveyor_gui/shared/_new_line.html.haml +2 -0
  116. data/app/views/surveyor_gui/shared/_pick_comments.html.haml +15 -0
  117. data/app/views/surveyor_gui/shared/_question_number.html.haml +9 -0
  118. data/app/views/surveyor_gui/shared/_report_data.html.haml +24 -0
  119. data/app/views/surveyor_gui/shared/_stars_report_data.html.haml +14 -0
  120. data/config.ru +4 -0
  121. data/config/environment.rb +0 -0
  122. data/config/routes.rb +71 -0
  123. data/db/migrate/20140307204049_add_template_to_surveys.rb +5 -0
  124. data/db/migrate/20140307235607_add_test_data_to_response_sets.rb +5 -0
  125. data/db/migrate/20140308171947_add_original_choice_to_answers.rb +5 -0
  126. data/db/migrate/20140308172118_add_blob_to_responses.rb +5 -0
  127. data/db/migrate/20140308172417_add_modifiable_to_survey_section.rb +5 -0
  128. data/db/migrate/20140308174532_add_modifiable_to_question.rb +5 -0
  129. data/db/migrate/20140308175305_add_dynamically_generate_to_questions.rb +5 -0
  130. data/db/migrate/20140311032923_add_dummy_blob_to_questions.rb +5 -0
  131. data/db/migrate/20140311160609_add_dynamic_source_to_questions.rb +5 -0
  132. data/db/migrate/20140311161714_add_report_code_to_questions.rb +5 -0
  133. data/db/migrate/20140530181134_add_is_comment_to_questions.rb +5 -0
  134. data/db/migrate/20140531012006_add_is_comment_to_answers.rb +5 -0
  135. data/db/migrate/20140531225529_create_rows.rb +9 -0
  136. data/db/migrate/20140601011151_create_columns.rb +11 -0
  137. data/db/migrate/20140602030330_add_column_id_to_answers.rb +5 -0
  138. data/db/migrate/20140603155606_add_column_id_to_responses.rb +5 -0
  139. data/db/migrate/20140606023527_add_column_id_to_dependency_conditions.rb +5 -0
  140. data/db/migrate/20140815165307_add_user_id_to_survey.rb +5 -0
  141. data/lib/assets/.gitkeep +0 -0
  142. data/lib/assets/images/addicon.png +0 -0
  143. data/lib/assets/images/datepicker.gif +0 -0
  144. data/lib/assets/images/delete.gif +0 -0
  145. data/lib/assets/images/delete.png +0 -0
  146. data/lib/assets/images/images/border.png +0 -0
  147. data/lib/assets/images/images/controls.png +0 -0
  148. data/lib/assets/images/images/loading.gif +0 -0
  149. data/lib/assets/images/images/loading_background.png +0 -0
  150. data/lib/assets/images/images/overlay.png +0 -0
  151. data/lib/assets/images/rails.png +0 -0
  152. data/lib/assets/images/star.gif +0 -0
  153. data/lib/assets/javascripts/.gitkeep +0 -0
  154. data/lib/assets/javascripts/surveyor_gui/jquery.MetaData.js +121 -0
  155. data/lib/assets/javascripts/surveyor_gui/jquery.blockUI.js +619 -0
  156. data/lib/assets/javascripts/surveyor_gui/jquery.rating.js +377 -0
  157. data/lib/assets/javascripts/surveyor_gui/jquery.validate.js +1188 -0
  158. data/lib/assets/javascripts/surveyor_gui/surveyor_add_ons.js +10 -0
  159. data/lib/assets/javascripts/surveyor_gui/surveyor_gui.js +1417 -0
  160. data/lib/assets/stylesheets/.gitkeep +0 -0
  161. data/lib/assets/stylesheets/surveyor_gui/jquery.rating.css +12 -0
  162. data/lib/assets/stylesheets/surveyor_gui/surveyor_add_ons.css +3 -0
  163. data/lib/assets/stylesheets/surveyor_gui/surveyor_gui.sass +650 -0
  164. data/lib/enumerable_extenders.rb +31 -0
  165. data/lib/generators/surveyor_gui/install_generator.rb +57 -0
  166. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_add_ons.js +2 -0
  167. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_gui_all.js +24 -0
  168. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_add_ons.css.sass +1 -0
  169. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_gui_all.css.sass +8 -0
  170. data/lib/generators/surveyor_gui/templates/app/helpers/surveyor_helper.rb +4 -0
  171. data/lib/generators/surveyor_gui/templates/app/models/response_set_user.rb +13 -0
  172. data/lib/generators/surveyor_gui/templates/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  173. data/lib/generators/surveyor_gui/templates/config/initializers/simple_form.rb +140 -0
  174. data/lib/generators/surveyor_gui/templates/config/locales/en.yml +5 -0
  175. data/lib/surveyor_gui.rb +17 -0
  176. data/lib/surveyor_gui/engine.rb +30 -0
  177. data/lib/surveyor_gui/helpers/surveyor_helper_methods.rb +19 -0
  178. data/lib/surveyor_gui/models/answer_methods.rb +24 -0
  179. data/lib/surveyor_gui/models/column_methods.rb +43 -0
  180. data/lib/surveyor_gui/models/dependency_condition_methods.rb +53 -0
  181. data/lib/surveyor_gui/models/dependency_methods.rb +83 -0
  182. data/lib/surveyor_gui/models/question_and_group_shared_methods.rb +11 -0
  183. data/lib/surveyor_gui/models/question_group_methods.rb +55 -0
  184. data/lib/surveyor_gui/models/question_methods.rb +435 -0
  185. data/lib/surveyor_gui/models/question_type_methods.rb +493 -0
  186. data/lib/surveyor_gui/models/response_methods.rb +67 -0
  187. data/lib/surveyor_gui/models/response_set_methods.rb +54 -0
  188. data/lib/surveyor_gui/models/row_methods.rb +11 -0
  189. data/lib/surveyor_gui/models/survey_methods.rb +32 -0
  190. data/lib/surveyor_gui/models/survey_section_methods.rb +32 -0
  191. data/lib/surveyor_gui/surveyforms_controller_methods.rb +258 -0
  192. data/lib/surveyor_gui/version.rb +3 -0
  193. data/lib/tasks/.gitkeep +0 -0
  194. data/lib/tasks/surveyor_gui_tasks.rake +4 -0
  195. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  196. data/spec/controllers/surveyforms_controller_spec.rb +361 -0
  197. data/spec/controllers/surveyor_controller_spec.rb +303 -0
  198. data/spec/factories.rb +181 -0
  199. data/spec/features/create_survey_spec.rb +418 -0
  200. data/spec/features/dependencies_spec.rb +61 -0
  201. data/spec/features/rearrange_survey_spec.rb +118 -0
  202. data/spec/features/ui_spec.rb +469 -0
  203. data/spec/fixtures/REDCapDemoDatabase_DataDictionary.csv +127 -0
  204. data/spec/fixtures/chinese_survey.rb +14 -0
  205. data/spec/fixtures/everything.rb +215 -0
  206. data/spec/fixtures/favorites-ish.rb +22 -0
  207. data/spec/fixtures/favorites.rb +22 -0
  208. data/spec/fixtures/feelings.rb +38 -0
  209. data/spec/fixtures/lifestyle.rb +55 -0
  210. data/spec/fixtures/numbers.rb +21 -0
  211. data/spec/fixtures/redcap_new_headers.csv +1 -0
  212. data/spec/fixtures/redcap_siblings.csv +1 -0
  213. data/spec/fixtures/redcap_whitespace.csv +1 -0
  214. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  215. data/spec/helpers/surveyor_helper_spec.rb +116 -0
  216. data/spec/lib/common_spec.rb +37 -0
  217. data/spec/lib/parser_spec.rb +393 -0
  218. data/spec/lib/rake_kitchen_sink.rb +42 -0
  219. data/spec/lib/redcap_parser_spec.rb +129 -0
  220. data/spec/lib/unparser_spec.rb +126 -0
  221. data/spec/models/answer_spec.rb +144 -0
  222. data/spec/models/dependency_condition_spec.rb +428 -0
  223. data/spec/models/dependency_spec.rb +90 -0
  224. data/spec/models/question_group_spec.rb +66 -0
  225. data/spec/models/question_spec.rb +176 -0
  226. data/spec/models/response_set_spec.rb +452 -0
  227. data/spec/models/response_spec.rb +208 -0
  228. data/spec/models/survey_section_spec.rb +58 -0
  229. data/spec/models/survey_spec.rb +155 -0
  230. data/spec/models/surveyor_gui/question_spec.rb +60 -0
  231. data/spec/models/surveyor_gui/question_type_spec.rb +268 -0
  232. data/spec/models/validation_condition_spec.rb +98 -0
  233. data/spec/models/validation_spec.rb +64 -0
  234. data/spec/spec.opts +4 -0
  235. data/spec/spec_helper.rb +119 -0
  236. data/spec/support/scenario_outline_helper.rb +39 -0
  237. data/spec/support/shared.rb +10 -0
  238. data/spec/support/surveyforms_creation_helpers.rb +312 -0
  239. data/spec/support/surveyforms_rearrangement_helpers.rb +170 -0
  240. data/spec/support/surveyor_api_helpers.rb +15 -0
  241. data/spec/support/surveyor_ui_helpers.rb +108 -0
  242. data/spec/support/wait_for_ajax.rb +11 -0
  243. data/spec/views/questions/edit.html.erb_spec.rb +73 -0
  244. data/spec/views/surveyforms/edit.html.erb_spec.rb +126 -0
  245. data/surveyor_gui.gemspec +52 -0
  246. data/test/dummy/README.rdoc +261 -0
  247. data/test/dummy/Rakefile +7 -0
  248. data/test/dummy/app/assets/javascripts/application.js +15 -0
  249. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  250. data/test/dummy/app/controllers/application_controller.rb +3 -0
  251. data/test/dummy/app/helpers/application_helper.rb +2 -0
  252. data/test/dummy/app/mailers/.gitkeep +0 -0
  253. data/test/dummy/app/models/.gitkeep +0 -0
  254. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  255. data/test/dummy/config.ru +4 -0
  256. data/test/dummy/config/application.rb +59 -0
  257. data/test/dummy/config/boot.rb +10 -0
  258. data/test/dummy/config/database.yml +25 -0
  259. data/test/dummy/config/environment.rb +5 -0
  260. data/test/dummy/config/environments/development.rb +37 -0
  261. data/test/dummy/config/environments/production.rb +67 -0
  262. data/test/dummy/config/environments/test.rb +37 -0
  263. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  264. data/test/dummy/config/initializers/inflections.rb +15 -0
  265. data/test/dummy/config/initializers/mime_types.rb +5 -0
  266. data/test/dummy/config/initializers/secret_token.rb +7 -0
  267. data/test/dummy/config/initializers/session_store.rb +8 -0
  268. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  269. data/test/dummy/config/locales/en.yml +5 -0
  270. data/test/dummy/config/routes.rb +58 -0
  271. data/test/dummy/lib/assets/.gitkeep +0 -0
  272. data/test/dummy/log/.gitkeep +0 -0
  273. data/test/dummy/public/404.html +26 -0
  274. data/test/dummy/public/422.html +26 -0
  275. data/test/dummy/public/500.html +25 -0
  276. data/test/dummy/public/favicon.ico +0 -0
  277. data/test/dummy/script/rails +6 -0
  278. data/test/surveyor-gui_test.rb +7 -0
  279. data/test/test_helper.rb +15 -0
  280. data/vendor/assets/stylesheets/.gitkeep +0 -0
  281. data/vendor/assets/stylesheets/custom.sass +5 -0
  282. data/vendor/plugins/.gitkeep +0 -0
  283. metadata +664 -0
@@ -0,0 +1,21 @@
1
+ survey "Numbers" do
2
+ section "Addition" do
3
+ q_1 "What is one plus one?", pick: :one, correct: "2"
4
+ a_1 "1"
5
+ a_2 "2"
6
+ a_3 "3"
7
+ a_4 "4"
8
+
9
+ q_2 "What is five plus one?", pick: :one, correct: "6"
10
+ a_5 "five"
11
+ a_6 "six"
12
+ a_7 "seven"
13
+ a_8 "eight"
14
+ end
15
+ section "Literature" do
16
+ q_the_answer "What is the 'Answer to the Ultimate Question of Life, The Universe, and Everything'", pick: :one, correct: "adams"
17
+ a_pi "3.14"
18
+ a_zero "0"
19
+ a_adams "42"
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ Variable / Field Name,Form Name,Field Units,Section Header,Field Type,Field Label,Choices Calculations OR Slider Labels,Field Note,Text Validation Type OR Show Slider Number,Text Validation Min,Text Validation Max,Identifier?,Branching Logic (Show field only if...),Required Field?
@@ -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?
@@ -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?
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ #require File.expand_path(File.dirname(__FILE__) + '/../../lib/surveyor/helpers/formtastic_custom_input')
3
+
4
+ describe Surveyor::Helpers::FormtasticCustomInput do
5
+ context "input helpers" do
6
+ it "should translate response class into attribute" do
7
+ helper.response_class_to_method(:string).should == :string_value
8
+ helper.response_class_to_method(:integer).should == :integer_value
9
+ helper.response_class_to_method(:float).should == :float_value
10
+ helper.response_class_to_method(:datetime).should == :datetime_value
11
+ helper.response_class_to_method(:date).should == :date_value
12
+ helper.response_class_to_method(:time).should == :time_value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,116 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SurveyorHelper do
4
+ context "numbering" do
5
+ it "should return the question text with number, except for labels, dependencies, images, and grouped questions" do
6
+ q1 = FactoryGirl.create(:question)
7
+ q2 = FactoryGirl.create(:question, :display_type => "label")
8
+ q3 = FactoryGirl.create(:question) do |question|
9
+ FactoryGirl.create(:dependency, :question=>question)
10
+ end
11
+ q4 = FactoryGirl.create(:question, :display_type => "image", :text => "something.jpg")
12
+ q5 = FactoryGirl.create(:question, :question_group => FactoryGirl.create(:question_group))
13
+ helper.q_text(q1).should == "<span class='qnum'>1) </span>#{q1.text}"
14
+ helper.q_text(q2).should == q2.text
15
+ helper.q_text(q3).should == q3.text
16
+ helper.q_text(q4).should =~ /<img alt="Something" src="\/(images|assets)\/something\.jpg" \/>/
17
+ helper.q_text(q5).should == q5.text
18
+ end
19
+ end
20
+
21
+ context "with mustache text substitution" do
22
+ require 'mustache'
23
+ let(:mustache_context){ Class.new(::Mustache){ def site; "Northwestern"; end; def somethingElse; "something new"; end; def group; "NUBIC"; end } }
24
+ it "substitues values into Question#text" do
25
+ q1 = FactoryGirl.create(:question, :text => "You are in {{site}}")
26
+ label = FactoryGirl.create(:question, :display_type => "label", :text => "Testing {{somethingElse}}")
27
+ helper.q_text(q1, mustache_context).should == "<span class='qnum'>1) </span>You are in Northwestern"
28
+ helper.q_text(label, mustache_context).should == "Testing something new"
29
+ end
30
+ end
31
+
32
+ context "response methods" do
33
+ it "should find or create responses, with index" do
34
+ q1 = FactoryGirl.create(:question, :answers => [a = FactoryGirl.create(:answer, :text => "different")])
35
+ q2 = FactoryGirl.create(:question, :answers => [b = FactoryGirl.create(:answer, :text => "strokes")])
36
+ q3 = FactoryGirl.create(:question, :answers => [c = FactoryGirl.create(:answer, :text => "folks")])
37
+ rs = FactoryGirl.create(:response_set, :responses => [r1 = FactoryGirl.create(:response, :question => q1, :answer => a), r3 = FactoryGirl.create(:response, :question => q3, :answer => c, :response_group => 1)])
38
+
39
+ helper.response_for(rs, nil).should == nil
40
+ helper.response_for(nil, q1).should == nil
41
+ helper.response_for(rs, q1).should == r1
42
+ helper.response_for(rs, q1, a).should == r1
43
+ helper.response_for(rs, q2).attributes.reject{|k,v| k == "api_id"}.should == Response.new(:question => q2, :response_set => rs).attributes.reject{|k,v| k == "api_id"}
44
+ helper.response_for(rs, q2, b).attributes.reject{|k,v| k == "api_id"}.should == Response.new(:question => q2, :response_set => rs).attributes.reject{|k,v| k == "api_id"}
45
+ helper.response_for(rs, q3, c, "1").should == r3
46
+
47
+ end
48
+ it "should keep an index of responses" do
49
+ helper.response_idx.should == "1"
50
+ helper.response_idx.should == "2"
51
+ helper.response_idx(false).should == "2"
52
+ helper.response_idx.should == "3"
53
+ end
54
+ it "should translate response class into attribute" do
55
+ helper.rc_to_attr(:string).should == :string_value
56
+ helper.rc_to_attr(:text).should == :text_value
57
+ helper.rc_to_attr(:integer).should == :integer_value
58
+ helper.rc_to_attr(:float).should == :float_value
59
+ helper.rc_to_attr(:datetime).should == :datetime_value
60
+ helper.rc_to_attr(:date).should == :date_value
61
+ helper.rc_to_attr(:time).should == :time_value
62
+ end
63
+
64
+ it "should translate response class into as" do
65
+ helper.rc_to_as(:string).should == :string
66
+ helper.rc_to_as(:text).should == :text
67
+ helper.rc_to_as(:integer).should == :string
68
+ helper.rc_to_as(:float).should == :string
69
+ helper.rc_to_as(:datetime).should == :string
70
+ helper.rc_to_as(:date).should == :string
71
+ helper.rc_to_as(:time).should == :string
72
+ end
73
+ end
74
+
75
+ context "overriding methods" do
76
+ before do
77
+ module SurveyorHelper
78
+ include Surveyor::Helpers::SurveyorHelperMethods
79
+ alias :old_rc_to_as :rc_to_as
80
+ def rc_to_as(type_sym)
81
+ case type_sym.to_s
82
+ when /(integer|float)/ then :string
83
+ when /(datetime)/ then :datetime
84
+ else type_sym
85
+ end
86
+ end
87
+ end
88
+ end
89
+ it "should translate response class into as" do
90
+ helper.rc_to_as(:string).should == :string
91
+ helper.rc_to_as(:text).should == :text
92
+ helper.rc_to_as(:integer).should == :string
93
+ helper.rc_to_as(:float).should == :string
94
+ helper.rc_to_as(:datetime).should == :datetime # not string
95
+ helper.rc_to_as(:date).should == :date # not string
96
+ helper.rc_to_as(:time).should == :time
97
+ end
98
+ after do
99
+ module SurveyorHelper
100
+ include Surveyor::Helpers::SurveyorHelperMethods
101
+ def rc_to_as(type_sym)
102
+ old_rc_to_as(type_sym)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ # run this context after 'overriding methods'
109
+ context "post override test" do
110
+ # Sanity check
111
+ it "should translate response class into as after override" do
112
+ helper.rc_to_as(:datetime).should == :string # back to string
113
+ helper.rc_to_as(:date).should == :string # back to string
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Surveyor::Common, "" do
4
+ it "should convert text to a code that is more appropirate for a database entry" do
5
+ # A few answers from the survey
6
+ { "This? is a in - t3rrible-@nswer of! (question) on" => "this_t3rrible_nswer",
7
+ "Private insurance/ HMO/ PPO" => "private_insurance_hmo_ppo",
8
+ "<bold>VA</bold>" => "va",
9
+ "PMS (Premenstrual syndrome)/ PMDD (Premenstrual Dysphoric Disorder)" => "pms_pmdd",
10
+ "Have never been employed outside the home" => "never_been_employed_outside_home",
11
+ "Professional" => "professional",
12
+ "Not working because of temporary disability, but expect to return to a job" => "temporary_disability_expect_return_job",
13
+ "How long has it been since you last visited a doctor for a routine checkup (routine being not for a particular reason)?" => "visited_doctor_for_routine_checkup",
14
+ "Do you take medications as directed?" => "you_take_medications_as_directed",
15
+ "Do you every leak urine (or) water when you didn't want to?" => "urine_water_you_didnt_want", #checking for () and ' removal
16
+ "Do your biological family members (not adopted) have a \"history\" of any of the following?" => "family_members_history_any_following",
17
+ "Your health:" => "your_health",
18
+ "In general, you would say your health is:" => "you_would_say_your_health"
19
+ }.each{|k, v| Surveyor::Common.to_normalized_string(k).should == v}
20
+ end
21
+ it "should have a list of operators" do
22
+ %w(== != < > <= >= =~).each{|operator| Surveyor::Common::OPERATORS.include?(operator).should be_true }
23
+ end
24
+ describe '#generate_api_id' do
25
+ def generate
26
+ Surveyor::Common.generate_api_id
27
+ end
28
+
29
+ it 'generates a String' do
30
+ generate.should be_a String
31
+ end
32
+
33
+ it 'generates a new value every time' do
34
+ (1..100).collect { generate }.uniq.size.should == 100
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,393 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Surveyor::Parser do
5
+ let(:parser){ Surveyor::Parser.new }
6
+ it "should return a survey object" do
7
+ Surveyor::Parser.new.parse("survey 'hi' do\n end").is_a?(Survey).should be_true
8
+ end
9
+ context "basic questions" do
10
+ include_context "favorites"
11
+ it "parses" do
12
+ expect(Survey.count).to eq(1)
13
+ expect(SurveySection.count).to eq(2)
14
+ expect(Question.count).to eq(4)
15
+ expect(Answer.count).to eq(9)
16
+ surveys = [{title: "Favorites", display_order: 0}]
17
+ sections = [{title: "Colors", reference_identifier: "colors", display_order: 0},
18
+ {title: "Numbers", reference_identifier: "numbers", display_order: 1}]
19
+ questions = [{reference_identifier: nil, text: "These questions are examples of the basic supported input types", pick: "none", display_type: "label", display_order: 0},
20
+ {reference_identifier: "1", text: "What is your favorite color?", pick: "one", display_type: "default", display_order: 1},
21
+ {reference_identifier: "2b", text: "Choose the colors you don't like", pick: "any", display_type: "default", display_order: 2},
22
+ {reference_identifier: "fire_engine", text: "What is the best color for a fire engine?",display_type: "default", display_order: 3}]
23
+ answers_1 = [{reference_identifier: "r", data_export_identifier: "1", text: "red", response_class: "answer", display_order: 0},
24
+ {reference_identifier: "b", data_export_identifier: "2", text: "blue", response_class: "answer", display_order: 1},
25
+ {reference_identifier: "g", data_export_identifier: "3", text: "green", response_class: "answer", display_order: 2},
26
+ {reference_identifier: nil, text: "Other", response_class: "answer", display_order: 3}]
27
+ answers_2 = [{reference_identifier: "1", text: "orange", response_class: "answer", display_order: 1},
28
+ {reference_identifier: "2", text: "purple", response_class: "answer", display_order: 2},
29
+ {reference_identifier: "3", text: "brown", response_class: "answer", display_order: 0},
30
+ {reference_identifier: nil, text: "Omit", response_class: "answer", display_order: 3}]
31
+ surveys.each{|attrs| attrs.each{|k,v| expect(Survey.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
32
+ sections.each{|attrs| attrs.each{|k,v| expect(SurveySection.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
33
+ questions.each{|attrs| attrs.each{|k,v| expect(Question.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
34
+ answers_1.each{|attrs| attrs.each{|k,v| expect(Question.where(display_order: 1).first.answers.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
35
+ answers_2.each{|attrs| attrs.each{|k,v| expect(Question.where(display_order: 2).first.answers.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
36
+ end
37
+ end
38
+ context "complex questions" do
39
+ include_context "feelings"
40
+ it "parses" do
41
+ expect(Survey.count).to eq(1)
42
+ expect(QuestionGroup.count).to eq(3)
43
+ expect(Question.count).to eq(10)
44
+ expect(Answer.count).to eq(34)
45
+ surveys = [{title: "Feelings", display_order: 0}]
46
+ question_groups = [{text: "Tell us how you feel today", display_type: "grid", reference_identifier: "today"},
47
+ {text: "How interested are you in the following?", display_type: "grid", reference_identifier: "events"},
48
+ {text: "Tell us about your family", display_type: "repeater", reference_identifier: "family"}]
49
+ dropdown_question_attributes = {text: "Relation", pick: "one"}
50
+ grid_questions = QuestionGroup.where(reference_identifier: "today").first.questions
51
+ grid_answers_1 = [{text: "-2", display_order: 0},
52
+ {text: "-1", display_order: 1},
53
+ {text: "0", display_order: 2},
54
+ {text: "1", display_order: 3},
55
+ {text: "2", display_order: 4}]
56
+ surveys.each{|attrs| attrs.each{|k,v| expect(Survey.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
57
+ question_groups.each{|attrs| attrs.each{|k,v| expect(QuestionGroup.where(reference_identifier: attrs[:reference_identifier]).first[k]).to eq(v)} }
58
+ grid_questions.each{|question| grid_answers_1.each{|attrs| attrs.each{|k,v| expect(question.answers.where(display_order: attrs[:display_order]).first[k]).to eq(v)} } }
59
+ dropdown_question_attributes.each{|k,v| expect(Question.where(display_type: "dropdown").first[k]).to eq(v)}
60
+ end
61
+ it "clears grid answers" do
62
+ grid_answers_1 = [{text: "-2", display_order: 0},
63
+ {text: "-1", display_order: 1},
64
+ {text: "0", display_order: 2},
65
+ {text: "1", display_order: 3},
66
+ {text: "2", display_order: 4}]
67
+ grid_answers_2 = [{text: "indifferent", display_order: 0},
68
+ {text: "neutral", display_order: 1},
69
+ {text: "interested", display_order: 2}]
70
+ end
71
+ end
72
+ context "depdencies and validations" do
73
+ include_context "lifestyle"
74
+ it "parses" do
75
+ expect(Survey.count).to eq(1)
76
+ expect(SurveySection.count).to eq(2)
77
+ expect(QuestionGroup.count).to eq(1)
78
+ expect(Question.count).to eq(10)
79
+ expect(Answer.count).to eq(12)
80
+ expect(Dependency.count).to eq(6)
81
+ expect(DependencyCondition.count).to eq(6)
82
+ expect(Validation.count).to eq(2)
83
+ expect(ValidationCondition.count).to eq(2)
84
+ depdendencies = [{rule: "B", question_reference_identifier: "copd_sh_1b"},
85
+ {rule: "C", question_reference_identifier: "copd_sh_1ba"},
86
+ {rule: "D", question_reference_identifier: "copd_sh_1bb"},
87
+ {rule: "Q", question_group_reference_identifier: "one_pet"},
88
+ {rule: "R", question_reference_identifier: "very_creative"},
89
+ {rule: "S", question_reference_identifier: "oh_my"}]
90
+ depdendencies.each{|attrs| (expect(Dependency.where(rule: attrs[:rule]).first.question.reference_identifier).to eq(attrs[:question_reference_identifier])) if attrs[:question_reference_identifier] }
91
+ depdendencies.each{|attrs| (expect(Dependency.where(rule: attrs[:rule]).first.question_group.reference_identifier).to eq(attrs[:question_group_reference_identifier])) if attrs[:question_group_reference_identifier] }
92
+ dependency_conditions = [{rule_key: "B", question_reference_identifier: "copd_sh_1", answer_reference_identifier: "1"},
93
+ {rule_key: "C", question_reference_identifier: "copd_sh_1b", answer_reference_identifier: "quit"},
94
+ {rule_key: "D", question_reference_identifier: "copd_sh_1b", answer_reference_identifier: "current_as_of_one_month"},
95
+ {rule_key: "Q", question_reference_identifier: "pets", answer_reference_identifier: "number"},
96
+ {rule_key: "R", question_reference_identifier: "favorite_pet", answer_reference_identifier: "name"},
97
+ {rule_key: "S", question_reference_identifier: "dream_pet"}]
98
+ dependency_conditions.each{|attrs| expect(DependencyCondition.where(rule_key: attrs[:rule_key]).first.question.reference_identifier).to eq(attrs[:question_reference_identifier]) }
99
+ dependency_conditions.each{|attrs| (expect(DependencyCondition.where(rule_key: attrs[:rule_key]).first.answer.reference_identifier).to eq(attrs[:answer_reference_identifier])) if attrs[:answer_reference_identifier] }
100
+ end
101
+ end
102
+ context "translations" do
103
+ it 'should produce the survey text for :default locale' do
104
+ survey_text = %{
105
+ survey "One language is never enough" do
106
+ translations :en => :default, :es =>{'questions' => {'name' =>{ 'text' => '¡Hola!'}}}
107
+ section_one "One" do
108
+ label_name "Hello!"
109
+ end
110
+ end
111
+ }
112
+ survey = Surveyor::Parser.new.parse(survey_text)
113
+ survey.is_a?(Survey).should == true
114
+ survey.translations.size.should == 2
115
+ question = survey.sections.first.questions.first
116
+ question.translation(:en)[:text].should == "Hello!"
117
+ question.translation(:es)[:text].should == "¡Hola!"
118
+ end
119
+ it 'should raise an error w/o :default locale' do
120
+ survey_text = %{
121
+ survey "One language is never enough" do
122
+ translations :es =>{'questions' => {'name' =>{ 'text' => '¡Hola!'}}}
123
+ section_one "One" do
124
+ label_name "Hello!"
125
+ end
126
+ end
127
+ }
128
+ s = Survey.all.size
129
+ expect {survey = Surveyor::Parser.new.parse(survey_text)}.to raise_error
130
+ Survey.all.size.should == s
131
+ end
132
+ it 'should allow multiple default locales' do
133
+ survey_text = %{
134
+ survey "Just don't talk about tyres" do
135
+ translations :'en-US' => :default, :'en-GB' => :default, :es =>{'questions' => {'name' =>{'text' => '¡Hola!'}}}
136
+ section_one "One" do
137
+ label_name "Hello!"
138
+ end
139
+ end
140
+ }
141
+ survey = Surveyor::Parser.new.parse(survey_text)
142
+ survey.is_a?(Survey).should == true
143
+ survey.translations.size.should == 3
144
+ question = survey.sections.first.questions.first
145
+ question.translation(:'en-US')[:text].should == "Hello!"
146
+ question.translation(:'en-GB')[:text].should == "Hello!"
147
+ question.translation(:es)[:text].should == "¡Hola!"
148
+ end
149
+ context 'when a translation is specified as a Hash' do
150
+ it 'should should treat the hash as an inline translation' do
151
+ survey_text = %{
152
+ survey "One language is never enough" do
153
+ translations :en => :default, :es => {"title"=>"Un idioma nunca es suficiente", "survey_sections"=>{"one"=>{"title"=>"Uno"}}, "question_groups"=>{"hello"=>{"text"=>"¡Hola!"}}, "questions"=>{"name"=>{"text"=>"¿Cómo se llama Usted?", "answers"=>{"name"=>{"help_text"=>"Mi nombre es..."}}}}}
154
+ section_one "One" do
155
+ g_hello "Hello" do
156
+ q_name "What is your name?"
157
+ a_name :string, :help_text => "My name is..."
158
+ end
159
+ end
160
+ end
161
+ }
162
+ survey = Surveyor::Parser.new.parse(survey_text)
163
+ survey.is_a?(Survey).should == true
164
+ survey.translations.size.should == 2
165
+ survey.translation(:es)['title'].should == "Un idioma nunca es suficiente"
166
+ end
167
+ end
168
+ context 'when a translation is specified as a String' do
169
+ context 'when the survey filename is not given' do
170
+ it 'should look for the translation file relative to pwd' do
171
+ Dir.mktmpdir do |dir|
172
+ FileUtils.cd(dir) do
173
+ translation_yaml = YAML::dump({'title' => 'Un idioma nunca es suficiente'})
174
+ translation_temp_file = Tempfile.new('parser_spec_translation.yml',dir)
175
+ translation_temp_file.write(translation_yaml)
176
+ translation_temp_file.flush
177
+ survey_text = %{
178
+ survey "One language is never enough" do
179
+ translations :es =>'#{File.basename(translation_temp_file.path)}', :en => :default
180
+ section_one "One" do
181
+ g_hello "Hello" do
182
+ q_name "What is your name?"
183
+ a_name :string, :help_text => "My name is..."
184
+ end
185
+ end
186
+ end
187
+ }
188
+ survey_temp_file = Tempfile.new('parser_spec_survey.rb',dir)
189
+ survey_temp_file.write(survey_text)
190
+ survey_temp_file.flush
191
+ Surveyor::Parser.parse(File.read(survey_temp_file.path))
192
+ survey = Survey.where(:title=>'One language is never enough').first
193
+ survey.nil?.should == false
194
+ survey.translation(:es)['title'].should == "Un idioma nunca es suficiente"
195
+ end
196
+ end
197
+ end
198
+ end
199
+ context 'when the survey filename is given' do
200
+ it 'should look for the translation file relative to the survey directory' do
201
+ Dir.mktmpdir do |dir|
202
+ translation_yaml = YAML::dump({'title' => 'Un idioma nunca es suficiente'})
203
+ translation_temp_file = Tempfile.new('surveyor:parser_spec.rb',dir)
204
+ translation_temp_file.write(translation_yaml)
205
+ translation_temp_file.flush
206
+ survey_text = %{
207
+ survey "One language is never enough" do
208
+ translations :es =>'#{File.basename(translation_temp_file.path)}', :en => :default
209
+ section_one "One" do
210
+ g_hello "Hello" do
211
+ q_name "What is your name?"
212
+ a_name :string, :help_text => "My name is..."
213
+ end
214
+ end
215
+ end
216
+ }
217
+ survey_temp_file = Tempfile.new('surveyor:parser_spec.rb',dir)
218
+ survey_temp_file.write(survey_text)
219
+ survey_temp_file.flush
220
+ Surveyor::Parser.parse_file(survey_temp_file.path)
221
+ survey = Survey.where(:title=>'One language is never enough').first
222
+ survey.nil?.should == false
223
+ survey.translation(:es)['title'].should == "Un idioma nunca es suficiente"
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+ context "quizzes" do
230
+ include_context "numbers"
231
+ it "parses" do
232
+ expect(Survey.count).to eq(1)
233
+ expect(SurveySection.count).to eq(2)
234
+ expect(Question.count).to eq(3)
235
+ expect(Answer.count).to eq(11)
236
+ surveys = [{title: "Numbers", display_order: 0}]
237
+ sections = [{title: "Addition", reference_identifier: nil, display_order: 0},
238
+ {title: "Literature", reference_identifier: nil, display_order: 1}]
239
+ questions = [{reference_identifier: "1", text: "What is one plus one?", pick: "one", display_type: "default", display_order: 0},
240
+ {reference_identifier: "2", text: "What is five plus one?", pick: "one", display_type: "default", display_order: 1},
241
+ {reference_identifier: "the_answer", text: "What is the 'Answer to the Ultimate Question of Life, The Universe, and Everything'", pick: "one", display_type: "default", display_order: 0}]
242
+ answers_1 = [{reference_identifier: "1", text: "1", response_class: "answer", display_order: 0},
243
+ {reference_identifier: "2", text: "2", response_class: "answer", display_order: 1},
244
+ {reference_identifier: "3", text: "3", response_class: "answer", display_order: 2},
245
+ {reference_identifier: "4", text: "4", response_class: "answer", display_order: 3}]
246
+ answers_2 = [{reference_identifier: "5", text: "five", response_class: "answer", display_order: 0},
247
+ {reference_identifier: "6", text: "six", response_class: "answer", display_order: 1},
248
+ {reference_identifier: "7", text: "seven", response_class: "answer", display_order: 2},
249
+ {reference_identifier: "8", text: "eight", response_class: "answer", display_order: 3}]
250
+ correct_answers = [{question_reference_identifier: "1", correct_answer_text: "2"},
251
+ {question_reference_identifier: "2", correct_answer_text: "six"},
252
+ {question_reference_identifier: "the_answer", correct_answer_text: "42"}]
253
+ surveys.each{|attrs| attrs.each{|k,v| expect(Survey.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
254
+ sections.each{|attrs| attrs.each{|k,v| expect(SurveySection.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
255
+ questions.each{|attrs| attrs.each{|k,v| expect(Question.where(reference_identifier: attrs[:reference_identifier]).first[k]).to eq(v)} }
256
+ answers_1.each{|attrs| attrs.each{|k,v| expect(Question.where(reference_identifier: "1").first.answers.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
257
+ answers_2.each{|attrs| attrs.each{|k,v| expect(Question.where(reference_identifier: "2").first.answers.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
258
+ correct_answers.each{|attrs| expect(Question.where(reference_identifier: attrs[:question_reference_identifier]).first.correct_answer.text).to eq(attrs[:correct_answer_text]) }
259
+ end
260
+ end
261
+ context "mandatory" do
262
+ it "parses" do
263
+ survey_text = %{
264
+ survey "Chores", default_mandatory: true do
265
+ section "Morning" do
266
+ q "Did you take out the trash", pick: :one
267
+ a "Yes"
268
+ a "No"
269
+
270
+ q "Did you do the laundry", pick: :one
271
+ a "Yes"
272
+ a "No"
273
+
274
+ q "Optional comments", is_mandatory: false
275
+ a :string
276
+ end
277
+ end
278
+ }
279
+ survey = Surveyor::Parser.new.parse(survey_text)
280
+ expect(Survey.count).to eq(1)
281
+ expect(SurveySection.count).to eq(1)
282
+ expect(Question.count).to eq(3)
283
+ questions = [{display_order: 0, text: "Did you take out the trash", is_mandatory: true},
284
+ {display_order: 1, text: "Did you do the laundry", is_mandatory: true},
285
+ {display_order: 2, text: "Optional comments", is_mandatory: false}]
286
+ questions.each{|attrs| attrs.each{|k,v| expect(Question.where(display_order: attrs[:display_order]).first[k]).to eq(v)} }
287
+ end
288
+ end
289
+ context "failures" do
290
+ it "typos in blocks" do
291
+ survey_text = %q{
292
+ survey "Basics" do
293
+ sectionals "Typo" do
294
+ end
295
+ end
296
+ }
297
+ expect { Surveyor::Parser.parse(survey_text) }.to raise_error(Surveyor::ParserError, /\"sectionals\" is not a surveyor method./)
298
+ end
299
+ it "bad references" do
300
+ survey_text = %q{
301
+ survey "Refs" do
302
+ section "Bad" do
303
+ q_watch "Do you watch football?", :pick => :one
304
+ a_1 "Yes"
305
+ a_2 "No"
306
+
307
+ q "Do you like the replacement refs?", :pick => :one
308
+ dependency :rule => "A or B"
309
+ condition_A :q_1, "==", :a_1
310
+ condition_B :q_watch, "==", :b_1
311
+ a "Yes"
312
+ a "No"
313
+ end
314
+ end
315
+ }
316
+ expect { Surveyor::Parser.parse(survey_text) }.to raise_error(Surveyor::ParserError, /Bad references: q_1; q_1, a_1; q_watch, a_b_1/)
317
+ end
318
+ it "repeated references" do
319
+ survey_text = %q{
320
+ survey "Refs" do
321
+ section "Bad" do
322
+ q_watch "Do you watch football?", :pick => :one
323
+ a_1 "Yes"
324
+ a_1 "No"
325
+
326
+ q_watch "Do you watch baseball?", :pick => :one
327
+ a_yes "Yes"
328
+ a_no "No"
329
+
330
+ q "Do you like the replacement refs?", :pick => :one
331
+ dependency :rule => "A or B"
332
+ condition_A :q_watch, "==", :a_1
333
+ a "Yes"
334
+ a "No"
335
+ end
336
+ end
337
+ }
338
+ expect { Surveyor::Parser.parse(survey_text) }.to raise_error(Surveyor::ParserError, /Duplicate references: q_watch, a_1; q_watch/)
339
+ end
340
+ it "with Rails validation errors" do
341
+ survey_text = %q{
342
+ survey do
343
+ section "Usage" do
344
+ q_PLACED_BAG_1 "Is the bag placed?", :pick => :one
345
+ a_1 "Yes"
346
+ a_2 "No"
347
+ a_3 "Refused"
348
+ end
349
+ end
350
+ }
351
+ expect { Surveyor::Parser.parse(survey_text) }.to raise_error(Surveyor::ParserError, /Survey not saved: Title can't be blank/)
352
+ end
353
+ it "bad shortcuts" do
354
+ survey_text = %q{
355
+ survey "shortcuts" do
356
+ section "Bad" do
357
+ quack "Do you like ducks?", :pick => :one
358
+ a_1 "Yes"
359
+ a_1 "No"
360
+ end
361
+ end
362
+ }
363
+ expect { Surveyor::Parser.parse(survey_text) }.to raise_error(Surveyor::ParserError, /\"quack\" is not a surveyor method./)
364
+ end
365
+ end
366
+ context "helper methods" do
367
+ it "should translate shortcuts into full model names" do
368
+ parser.send(:full, "section").should == "survey_section"
369
+ parser.send(:full, "g").should == "question_group"
370
+ parser.send(:full, "repeater").should == "question_group"
371
+ parser.send(:full, "label").should == "question"
372
+ parser.send(:full, "vc").should == "validation_condition"
373
+ parser.send(:full, "vcondition").should == "validation_condition"
374
+ end
375
+ it "should translate 'condition' based on context" do
376
+ parser.send(:full, "condition").should == "dependency_condition"
377
+ parser.send(:full, "c").should == "dependency_condition"
378
+ parser.context[:validation] = Validation.new
379
+ parser.send(:full, "condition").should == "validation_condition"
380
+ parser.send(:full, "c").should == "validation_condition"
381
+ parser.context[:validation] = nil
382
+ parser.send(:full, "condition").should == "dependency_condition"
383
+ parser.send(:full, "c").should == "dependency_condition"
384
+ end
385
+ it "should not translate bad shortcuts" do
386
+ parser.send(:full, "quack").should == "quack"
387
+ parser.send(:full, "grizzly").should == "grizzly"
388
+ end
389
+ it "should identify models that take blocks" do
390
+ parser.send(:block_models).should == %w(survey survey_section question_group)
391
+ end
392
+ end
393
+ end