breakpointer-surveyor 0.2.0

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 (198) hide show
  1. data/.gitignore +6 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +20 -0
  4. data/Rakefile +57 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/answers_controller.rb +87 -0
  7. data/app/controllers/dependencies_controller.rb +87 -0
  8. data/app/controllers/dependency_conditions_controller.rb +87 -0
  9. data/app/controllers/questions_controller.rb +85 -0
  10. data/app/controllers/sections_controller.rb +87 -0
  11. data/app/controllers/surveying_controller.rb +139 -0
  12. data/app/controllers/surveys_controller.rb +87 -0
  13. data/app/helpers/answers_helper.rb +2 -0
  14. data/app/helpers/application_helper.rb +3 -0
  15. data/app/helpers/questions_helper.rb +2 -0
  16. data/app/helpers/sections_helper.rb +2 -0
  17. data/app/helpers/survey_form_builder.rb +38 -0
  18. data/app/helpers/survey_importer_helper.rb +2 -0
  19. data/app/helpers/surveying_helper.rb +91 -0
  20. data/app/helpers/surveys_helper.rb +2 -0
  21. data/app/models/answer.rb +18 -0
  22. data/app/models/dependency.rb +43 -0
  23. data/app/models/dependency_condition.rb +76 -0
  24. data/app/models/question.rb +44 -0
  25. data/app/models/question_group.rb +5 -0
  26. data/app/models/response.rb +58 -0
  27. data/app/models/response_set.rb +174 -0
  28. data/app/models/survey.rb +54 -0
  29. data/app/models/survey_section.rb +19 -0
  30. data/app/models/user.rb +5 -0
  31. data/app/views/answer_display_types/_any_answer.html.haml +3 -0
  32. data/app/views/answer_display_types/_any_other_and_string.html.haml +5 -0
  33. data/app/views/answer_display_types/_any_string.html.haml +4 -0
  34. data/app/views/answer_display_types/_date.html.haml +3 -0
  35. data/app/views/answer_display_types/_datetime.html.haml +2 -0
  36. data/app/views/answer_display_types/_default.html.haml +1 -0
  37. data/app/views/answer_display_types/_float.html.haml +5 -0
  38. data/app/views/answer_display_types/_grid_any_answer.html.haml +2 -0
  39. data/app/views/answer_display_types/_grid_default.html.haml +2 -0
  40. data/app/views/answer_display_types/_grid_float.html.haml +2 -0
  41. data/app/views/answer_display_types/_grid_integer.html.haml +2 -0
  42. data/app/views/answer_display_types/_grid_one_answer.html.haml +2 -0
  43. data/app/views/answer_display_types/_grid_string.html.haml +2 -0
  44. data/app/views/answer_display_types/_integer.html.haml +6 -0
  45. data/app/views/answer_display_types/_one_answer.html.haml +3 -0
  46. data/app/views/answer_display_types/_one_string.html.haml +6 -0
  47. data/app/views/answer_display_types/_repeater_integer.html.haml +6 -0
  48. data/app/views/answer_display_types/_repeater_string.html.haml +7 -0
  49. data/app/views/answer_display_types/_string.html.haml +7 -0
  50. data/app/views/answer_display_types/_text.html.haml +6 -0
  51. data/app/views/answer_display_types/_time.html.haml +2 -0
  52. data/app/views/layouts/surveys.html.erb +17 -0
  53. data/app/views/question_display_types/_default.html.haml +12 -0
  54. data/app/views/question_display_types/_dropdown.html.haml +12 -0
  55. data/app/views/question_display_types/_grid_default.html.haml +14 -0
  56. data/app/views/question_display_types/_grid_dropdown.html.haml +15 -0
  57. data/app/views/question_display_types/_group_default.html.haml +8 -0
  58. data/app/views/question_display_types/_group_dropdown.html.haml +6 -0
  59. data/app/views/question_display_types/_image.html.haml +2 -0
  60. data/app/views/question_display_types/_inline.html.haml +12 -0
  61. data/app/views/question_display_types/_label.html.haml +4 -0
  62. data/app/views/question_display_types/_repeater_default.html.haml +10 -0
  63. data/app/views/question_display_types/_repeater_dropdown.html.haml +8 -0
  64. data/app/views/question_display_types/_slider.html.haml +17 -0
  65. data/app/views/question_group_display_types/_default.html.haml +13 -0
  66. data/app/views/question_group_display_types/_grid.html.haml +24 -0
  67. data/app/views/question_group_display_types/_repeater.html.haml +20 -0
  68. data/app/views/surveying/edit.html.haml +38 -0
  69. data/app/views/surveying/finish.html.haml +1 -0
  70. data/app/views/surveying/index.html.erb +19 -0
  71. data/app/views/surveying/new.html.haml +17 -0
  72. data/app/views/surveying/show.html.haml +8 -0
  73. data/config/routes.rb +10 -0
  74. data/generators/surveyor/surveyor_generator.rb +38 -0
  75. data/generators/surveyor/templates/README +9 -0
  76. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_leftright.gif +0 -0
  77. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_updown.gif +0 -0
  78. data/generators/surveyor/templates/assets/images/222222_11x11_icon_close.gif +0 -0
  79. data/generators/surveyor/templates/assets/images/222222_11x11_icon_doc.gif +0 -0
  80. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_closed.gif +0 -0
  81. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_open.gif +0 -0
  82. data/generators/surveyor/templates/assets/images/222222_11x11_icon_minus.gif +0 -0
  83. data/generators/surveyor/templates/assets/images/222222_11x11_icon_plus.gif +0 -0
  84. data/generators/surveyor/templates/assets/images/222222_11x11_icon_resize_se.gif +0 -0
  85. data/generators/surveyor/templates/assets/images/222222_35x9_colorpicker_indicator.gif.gif +0 -0
  86. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_down.gif +0 -0
  87. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_left.gif +0 -0
  88. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_right.gif +0 -0
  89. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_up.gif +0 -0
  90. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_leftright.gif +0 -0
  91. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_updown.gif +0 -0
  92. data/generators/surveyor/templates/assets/images/454545_11x11_icon_close.gif +0 -0
  93. data/generators/surveyor/templates/assets/images/454545_11x11_icon_doc.gif +0 -0
  94. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_closed.gif +0 -0
  95. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_open.gif +0 -0
  96. data/generators/surveyor/templates/assets/images/454545_11x11_icon_minus.gif +0 -0
  97. data/generators/surveyor/templates/assets/images/454545_11x11_icon_plus.gif +0 -0
  98. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_down.gif +0 -0
  99. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_left.gif +0 -0
  100. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_right.gif +0 -0
  101. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_up.gif +0 -0
  102. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_leftright.gif +0 -0
  103. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_updown.gif +0 -0
  104. data/generators/surveyor/templates/assets/images/888888_11x11_icon_close.gif +0 -0
  105. data/generators/surveyor/templates/assets/images/888888_11x11_icon_doc.gif +0 -0
  106. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_closed.gif +0 -0
  107. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_open.gif +0 -0
  108. data/generators/surveyor/templates/assets/images/888888_11x11_icon_minus.gif +0 -0
  109. data/generators/surveyor/templates/assets/images/888888_11x11_icon_plus.gif +0 -0
  110. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_down.gif +0 -0
  111. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_left.gif +0 -0
  112. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_right.gif +0 -0
  113. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_up.gif +0 -0
  114. data/generators/surveyor/templates/assets/images/dadada_40x100_textures_02_glass_75.png +0 -0
  115. data/generators/surveyor/templates/assets/images/e6e6e6_40x100_textures_02_glass_75.png +0 -0
  116. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_01_flat_0.png +0 -0
  117. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_02_glass_65.png +0 -0
  118. data/generators/surveyor/templates/assets/javascripts/accessibleUISlider.jQuery.js +201 -0
  119. data/generators/surveyor/templates/assets/javascripts/jquery-1.2.6.js +3549 -0
  120. data/generators/surveyor/templates/assets/javascripts/jquery-ui-personalized-1.5.3.js +7616 -0
  121. data/generators/surveyor/templates/assets/javascripts/jquery.form.js +637 -0
  122. data/generators/surveyor/templates/assets/javascripts/surveyor.js +35 -0
  123. data/generators/surveyor/templates/assets/stylesheets/jquery-ui-slider-additions.css +71 -0
  124. data/generators/surveyor/templates/assets/stylesheets/reset.css +46 -0
  125. data/generators/surveyor/templates/assets/stylesheets/sass/surveyor.sass +321 -0
  126. data/generators/surveyor/templates/assets/stylesheets/surveyor.css +245 -0
  127. data/generators/surveyor/templates/assets/stylesheets/ui.theme.css +851 -0
  128. data/generators/surveyor/templates/migrate/create_answers.rb +46 -0
  129. data/generators/surveyor/templates/migrate/create_dependencies.rb +21 -0
  130. data/generators/surveyor/templates/migrate/create_dependency_conditions.rb +29 -0
  131. data/generators/surveyor/templates/migrate/create_question_groups.rb +18 -0
  132. data/generators/surveyor/templates/migrate/create_questions.rb +33 -0
  133. data/generators/surveyor/templates/migrate/create_response_sets.rb +22 -0
  134. data/generators/surveyor/templates/migrate/create_responses.rb +33 -0
  135. data/generators/surveyor/templates/migrate/create_survey_sections.rb +25 -0
  136. data/generators/surveyor/templates/migrate/create_surveys.rb +25 -0
  137. data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +201 -0
  138. data/init.rb +1 -0
  139. data/install.rb +1 -0
  140. data/lib/tasks/surveyor_tasks.rake +29 -0
  141. data/lib/tiny_code.rb +58 -0
  142. data/lib/user_manager.rb +9 -0
  143. data/lib/xml_formatter.rb +12 -0
  144. data/script/surveyor/answer.rb +84 -0
  145. data/script/surveyor/columnizer.rb +36 -0
  146. data/script/surveyor/dependency.rb +43 -0
  147. data/script/surveyor/dependency_condition.rb +74 -0
  148. data/script/surveyor/dslparse.rb +66 -0
  149. data/script/surveyor/question.rb +76 -0
  150. data/script/surveyor/question_group.rb +33 -0
  151. data/script/surveyor/specs/answer_spec.rb +66 -0
  152. data/script/surveyor/specs/question_dependency_spec.rb +46 -0
  153. data/script/surveyor/specs/question_group_spec.rb +9 -0
  154. data/script/surveyor/specs/question_spec.rb +111 -0
  155. data/script/surveyor/specs/section_spec.rb +58 -0
  156. data/script/surveyor/survey.rb +108 -0
  157. data/script/surveyor/survey_section.rb +153 -0
  158. data/script/surveyor/whr_dsl.tmproj +244 -0
  159. data/spec/controllers/answers_controller_spec.rb +64 -0
  160. data/spec/controllers/dependencies_controller_spec.rb +63 -0
  161. data/spec/controllers/dependency_conditions_controller_spec.rb +64 -0
  162. data/spec/controllers/questions_controller_spec.rb +64 -0
  163. data/spec/controllers/sections_controller_spec.rb +64 -0
  164. data/spec/controllers/surveying_controller_spec.rb +328 -0
  165. data/spec/controllers/surveying_routing_spec.rb +45 -0
  166. data/spec/controllers/surveys_controller_spec.rb +64 -0
  167. data/spec/fixtures/answers.yml +9 -0
  168. data/spec/fixtures/dependencies.yml +7 -0
  169. data/spec/fixtures/dependency_conditions.yml +27 -0
  170. data/spec/fixtures/question_groups.yml +7 -0
  171. data/spec/fixtures/questions.yml +15 -0
  172. data/spec/fixtures/response_sets.yml +13 -0
  173. data/spec/fixtures/responses.yml +9 -0
  174. data/spec/fixtures/survey_sections.yml +11 -0
  175. data/spec/fixtures/surveys.yml +9 -0
  176. data/spec/fixtures/users.yml +7 -0
  177. data/spec/helpers/survey_importer_helper_spec.rb +11 -0
  178. data/spec/helpers/surveying_helper_spec.rb +11 -0
  179. data/spec/models/answer_spec.rb +62 -0
  180. data/spec/models/dependency_condition_spec.rb +347 -0
  181. data/spec/models/dependency_spec.rb +82 -0
  182. data/spec/models/question_group_spec.rb +11 -0
  183. data/spec/models/question_spec.rb +70 -0
  184. data/spec/models/response_set_spec.rb +172 -0
  185. data/spec/models/response_spec.rb +94 -0
  186. data/spec/models/survey_section_spec.rb +34 -0
  187. data/spec/models/survey_spec.rb +72 -0
  188. data/spec/models/user_spec.rb +11 -0
  189. data/spec/rcov.opts +2 -0
  190. data/spec/spec.opts +4 -0
  191. data/spec/spec_helper.rb +72 -0
  192. data/spec/views/app/edit.html.erb_spec.rb +20 -0
  193. data/spec/views/app/index.html.erb_spec.rb +19 -0
  194. data/spec/views/app/new.html.erb_spec.rb +21 -0
  195. data/spec/views/app/show.html.erb_spec.rb +17 -0
  196. data/surveyor.gemspec +258 -0
  197. data/uninstall.rb +1 -0
  198. metadata +286 -0
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dependency do
4
+ before(:each) do
5
+ @dependency = Dependency.new(:rule => "1 and 2 or 3", :question_id => 23)
6
+ end
7
+
8
+ it "should be valid" do
9
+ @dependency.should be_valid
10
+ end
11
+
12
+ it "should be invalid without a rule" do
13
+ @dependency.rule = nil
14
+ @dependency.should have(2).errors_on(:rule)
15
+ @dependency.rule = " "
16
+ @dependency.should have(1).errors_on(:rule)
17
+ end
18
+
19
+ it "should be invalid without a question_id" do
20
+ @dependency.question_id = nil
21
+ @dependency.should have(1).error_on(:question_id)
22
+ end
23
+
24
+ it "should alias question_id as dependent_question_id" do
25
+ @dependency.question_id = 19
26
+ @dependency.dependent_question_id.should == 19
27
+ @dependency.dependent_question_id = 14
28
+ @dependency.question_id.should == 14
29
+ end
30
+
31
+ it "should be invalid unless rule composed of only references and operators" do
32
+ @dependency.rule = "foo"
33
+ @dependency.should have(1).error_on(:rule)
34
+ @dependency.rule = "1 to 2"
35
+ @dependency.should have(1).error_on(:rule)
36
+ @dependency.rule = "a and b"
37
+ @dependency.should have(1).error_on(:rule)
38
+ end
39
+
40
+ end
41
+
42
+ describe Dependency, "when evaluating dependency conditions of a question in a response set" do
43
+
44
+ before(:each) do
45
+ @dep = Dependency.new(:rule => "A", :question_id => 1)
46
+ @dep2 = Dependency.new(:rule => "A and B", :question_id => 1)
47
+ @dep3 = Dependency.new(:rule => "A or B", :question_id => 1)
48
+ @dep4 = Dependency.new(:rule => "!(A and B) and C", :question_id => 1)
49
+
50
+ @dep_c = mock_model(DependencyCondition, :id => 1, :rule_key => "A", :to_evaluation_hash => {:A => true})
51
+ @dep_c2 = mock_model(DependencyCondition, :id => 2, :rule_key => "B", :to_evaluation_hash => {:B => false})
52
+ @dep_c3 = mock_model(DependencyCondition, :id => 3, :rule_key => "C", :to_evaluation_hash => {:C => true})
53
+
54
+ @dep.stub!(:dependency_conditions).and_return([@dep_c])
55
+ @dep2.stub!(:dependency_conditions).and_return([@dep_c, @dep_c2])
56
+ @dep3.stub!(:dependency_conditions).and_return([@dep_c, @dep_c2])
57
+ @dep4.stub!(:dependency_conditions).and_return([@dep_c, @dep_c2, @dep_c3])
58
+ end
59
+
60
+ it "knows if the dependencies are met" do
61
+ @dep.met?(@response_set).should be_true
62
+ @dep2.met?(@response_set).should be_false
63
+ @dep3.met?(@response_set).should be_true
64
+ @dep4.met?(@response_set).should be_true
65
+ end
66
+
67
+ it "returns the proper keyed pairs from the dependency conditions" do
68
+ @dep.keyed_conditions(@response_set).should == {:A => true}
69
+ @dep2.keyed_conditions(@response_set).should == {:A => true, :B => false}
70
+ @dep3.keyed_conditions(@response_set).should == {:A => true, :B => false}
71
+ @dep4.keyed_conditions(@response_set).should == {:A => true, :B => false, :C => true}
72
+ end
73
+
74
+ it "evaluates the rule from the keyed pairs and return a boolean value" do
75
+ @dep.rule_evaluation(@dep.keyed_conditions(@response_set)).should be_true
76
+ @dep2.rule_evaluation(@dep2.keyed_conditions(@response_set)).should be_false
77
+ @dep3.rule_evaluation(@dep3.keyed_conditions(@response_set)).should be_true
78
+ @dep4.rule_evaluation(@dep4.keyed_conditions(@response_set)).should be_true
79
+ end
80
+
81
+
82
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe QuestionGroup do
4
+ before(:each) do
5
+ @question_group = QuestionGroup.new
6
+ end
7
+
8
+ it "should be valid" do
9
+ @question_group.should be_valid
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Question, "when creating a new question" do
4
+ before(:each) do
5
+ @ss = mock_model(SurveySection)
6
+ @question = Question.new(:text => "What is your favorite color?", :survey_section => @ss, :is_mandatory => true, :display_order => 1)
7
+ end
8
+
9
+ it "should be valid" do
10
+ @question.should be_valid
11
+ end
12
+
13
+ it "should be invalid without text" do
14
+ @question.text = nil
15
+ @question.should have(1).error_on(:text)
16
+ end
17
+
18
+ it "should have a parent survey section" do
19
+ @question.survey_section = nil
20
+ @question.should have(1).error_on(:survey_section_id)
21
+ end
22
+
23
+ it "should be mandatory by default" do
24
+ @question.mandatory?.should be_true
25
+ end
26
+
27
+ end
28
+
29
+ describe Question, "that has answers" do
30
+ before(:each) do
31
+ @ss = mock_model(SurveySection)
32
+ @question = Question.new(:text => "What is your favorite color?", :survey_section => @ss)
33
+ 3.times{ |x| @question.answers.build(:text => "ANSWER #{x}") }
34
+ end
35
+
36
+ it "should have answers" do
37
+ @question.answers.should have(3).answers
38
+ end
39
+
40
+ end
41
+
42
+ describe Question, "when interacting with an instance" do
43
+
44
+ before(:each) do
45
+ @ss = mock_model(SurveySection)
46
+ @question = Question.new(:text => "What is your favorite color?", :survey_section => @ss)
47
+ end
48
+
49
+ it "should return 'default' for nil display type" do
50
+ @question.display_type = nil
51
+ @question.display_type.should == "default"
52
+ end
53
+
54
+ end
55
+
56
+ describe Question, "with dependencies" do
57
+ before(:each) do
58
+ @ss = mock_model(SurveySection)
59
+ @rs = mock_model(ResponseSet)
60
+ @question = Question.new(:text => "Which island?", :survey_section => @ss)
61
+ end
62
+
63
+ it "should check its dependency" do
64
+ @dependency = mock_model(Dependency)
65
+ @dependency.stub!(:met?).with(@rs).and_return(true)
66
+ @question.stub!(:dependency).and_return(@dependency)
67
+ @question.dependency_is_satisfied?(@rs).should == true
68
+ end
69
+
70
+ end
@@ -0,0 +1,172 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe ResponseSet, "class methods" do
4
+ before(:each) do
5
+ @survey = mock_model(Survey, :access_code => "XYZ")
6
+ @response_set = ResponseSet.new(:access_code => "PDQ", :survey => @survey)
7
+ ResponseSet.stub!(:find_by_access_code).with("PDQ").and_return(@response_set)
8
+ end
9
+ it "should find a response set by response_set.access_code or return false" do
10
+ ResponseSet.find_by_access_code("PDQ").should == @response_set
11
+ ResponseSet.find_by_access_code("Different").should be_nil
12
+ end
13
+ end
14
+ describe ResponseSet, "when saving" do
15
+ before(:each) do
16
+ @valid_attributes = {
17
+ :user_id => 1,
18
+ :survey_id => 1,
19
+ }
20
+ @response_set = ResponseSet.new(@valid_attributes)
21
+ end
22
+
23
+ it "should be valid" do
24
+ @response_set.should be_valid
25
+ end
26
+ it "should be invalid without a parent user and survey" do
27
+ @response_set.user_id = nil
28
+ @response_set.survey_id = nil
29
+ @response_set.should have(1).error_on(:user_id)
30
+ @response_set.should have(1).error_on(:survey_id)
31
+ end
32
+
33
+ it "should have a default started at date/time" do
34
+ @response_set.started_at.blank?.should_not == true
35
+ @response_set.started_at.localtime.to_date.should == Date.today
36
+ end
37
+
38
+ it "should have no errors after save" do
39
+ user = mock_model(User)
40
+ survey = mock_model(Survey)
41
+
42
+ @response_set.user = user #User.find(1)
43
+ @response_set.survey = survey #Survey.find(1)
44
+ @response_set.save.should be_true
45
+ @response_set.errors.should be_empty
46
+ end
47
+
48
+ end
49
+ describe ResponseSet, "with responses" do
50
+ before(:each) do
51
+ @valid_attributes = {
52
+ :user_id => 1,
53
+ :survey_id => 1,
54
+ }
55
+ @response_set = ResponseSet.new(@valid_attributes)
56
+ end
57
+
58
+ it "can tell you its responses" do
59
+ 3.times{ |x| @response_set.responses.build }
60
+ @response_set.responses.should have(3).items
61
+ end
62
+
63
+ it "is completable" do
64
+ @response_set.completed_at.should be_nil
65
+ @response_set.complete!
66
+ @response_set.completed_at.should_not be_nil
67
+ @response_set.completed_at.is_a?(Time).should be_true
68
+ end
69
+
70
+ it "allows completion through mass assignment" do
71
+ @response_set.completed_at.should be_nil
72
+ @response_set.update_attributes(:completed_at => Time.now)
73
+ @response_set.completed_at.should be_nil
74
+ end
75
+
76
+ end
77
+ describe ResponseSet, "Creating new set for user" do
78
+ before(:each) do
79
+ @valid_attributes = {
80
+ :user_id => 1,
81
+ :survey_id => 1,
82
+ }
83
+ @response_set = ResponseSet.new(@valid_attributes)
84
+ end
85
+ it "should have a unique code with length 10 that identifies the survey" do
86
+ @response_set.access_code.should_not be_nil
87
+ @response_set.access_code.length.should == 10
88
+ end
89
+ end
90
+ describe ResponseSet, "Updating the response set" do
91
+ before(:each) do
92
+ @valid_attributes = {
93
+ :user_id => 1,
94
+ :survey_id => 1,
95
+ }
96
+ # {"responses"=>{
97
+ # "6"=>{"question_id"=>"6", "20"=>{"string_value"=>""}},
98
+ # "7"=>{"question_id"=>"7", "21"=>{"text_value"=>"Brian is tired"}},
99
+ # "1"=>{"question_id"=>"1", "answer_id"=>"1", "4"=>{"string_value"=>"XXL"}},
100
+ # "2"=>{"question_id"=>"2", "answer_id"=>"6"},
101
+ # "3"=>{"question_id"=>"3"},
102
+ # "4"=>{"question_id"=>"4"},
103
+ # "5"=>{"question_id"=>"5", "19"=>{"string_value"=>""}}},
104
+ # "survey_code"=>"test_survey",
105
+ # "commit"=>"Next Section (Utensiles and you!) >>",
106
+ # "authenticity_token"=>"d03bc1b52fa9669e1ed87c313b939836e7b93e34",
107
+ # "_method"=>"put",
108
+ # "action"=>"update",
109
+ # "controller"=>"app",
110
+ # "response_set_code"=>"cIFn0DnxlU",
111
+ # "section"=>"2"}
112
+
113
+ #TODO test views to produce these params. e.g., blank responses should still have a hash with question_id
114
+ @radio_response_attributes = HashWithIndifferentAccess.new({
115
+ "1"=>{"question_id"=>"1", "answer_id"=>"1", "4"=>{"string_value"=>"XXL"}},
116
+ "2"=>{"question_id"=>"2", "answer_id"=>"6"},
117
+ "3"=>{"question_id"=>"3"}
118
+ })
119
+ @other_response_attributes = HashWithIndifferentAccess.new({
120
+ "6"=>{"question_id"=>"6", "20"=>{"string_value"=>""}},
121
+ "7"=>{"question_id"=>"7", "21"=>{"text_value"=>"Brian is tired"}},
122
+ "5"=>{"question_id"=>"5", "19"=>{"string_value"=>""}}
123
+ })
124
+ @response_set = ResponseSet.new(@valid_attributes)
125
+ end
126
+
127
+ it "should delete existing responses corresponding to every question key that comes in" do
128
+ Response.should_receive(:delete_all).exactly(3).times
129
+ @response_set.update_attributes(:response_attributes => @radio_response_attributes)
130
+ end
131
+ it "should save new responses from radio buttons, ignoring blanks" do
132
+ @response_set.update_attributes(:response_attributes => @radio_response_attributes)
133
+ @response_set.responses.should have(2).items
134
+ @response_set.responses.detect{|r| r.question_id == 2}.answer_id.should == 6
135
+ end
136
+ it "should save new responses from other types, ignoring blanks" do
137
+ @response_set.update_attributes(:response_attributes => @other_response_attributes)
138
+ @response_set.responses.should have(1).items
139
+ @response_set.responses.detect{|r| r.question_id == 7}.text_value.should == "Brian is tired"
140
+ end
141
+ it "should ignore data if corresponding radio button is not selected" do
142
+ @response_set.update_attributes(:response_attributes => @radio_response_attributes)
143
+ @response_set.responses.select{|r| r.question_id == 2}.should have(1).item
144
+ @response_set.responses.detect{|r| r.question_id == 2}.string_value.should == nil
145
+ end
146
+ it "should preserve data in checkboxes regardless of selection" do
147
+ pending
148
+ end
149
+
150
+ it "should give convenient access to responses through response_for" do
151
+ @response_set.save #need to save for the associated models to build/save
152
+ @response_set.attributes = {:response_attributes => @radio_response_attributes}
153
+ @response_set.save.should be_true
154
+ @response_set.responses.should have(2).items
155
+
156
+ pending
157
+ end
158
+ end
159
+
160
+ describe ResponseSet, "knowing internal status" do
161
+
162
+ it "knows when it is empty" do
163
+ @response_set = ResponseSet.new
164
+ @response_set.empty?.should be_true
165
+ end
166
+
167
+ it "knows when it is not empty" do
168
+ @response_set = ResponseSet.new
169
+ @response_set.responses.build({:question_id => 1, :answer_id => 8})
170
+ @response_set.empty?.should be_false
171
+ end
172
+ end
@@ -0,0 +1,94 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Response, "when saving a response" do
4
+ before(:each) do
5
+ @response = Response.new(:question_id => 314, :response_set_id => 159, :answer_id => 1)
6
+ end
7
+
8
+ it "should be valid" do
9
+ @response.should be_valid
10
+ end
11
+
12
+ it "should be invalid without a parent response set and question" do
13
+ @response.response_set_id = nil
14
+ @response.should have(1).error_on(:response_set_id)
15
+
16
+ @response.question_id = nil
17
+ @response.should have(1).error_on(:question_id)
18
+ end
19
+
20
+ describe "returns the response as the type requested" do
21
+
22
+ it "returns 'string'" do
23
+ @response.string_value = "blah"
24
+ @response.as("string").should == "blah"
25
+ @response.as(:string).should == "blah"
26
+ end
27
+
28
+ it "returns 'integer'" do
29
+ @response.integer_value = 1001
30
+ @response.as(:integer).should == 1001
31
+ end
32
+
33
+ it "returns 'float'"do
34
+ @response.float_value = 3.14
35
+ @response.as(:float).should == 3.14
36
+ end
37
+
38
+ it "returns 'answer'" do
39
+ @response.answer_id = 14
40
+ @response.as(:answer).should == 14
41
+ end
42
+
43
+ it "default returns answer type if not specified" do
44
+ @response.answer_id =18
45
+ @response.as(:stuff).should == 18
46
+ end
47
+
48
+ it "returns empty elements if the response is cast as a type that is not present" do
49
+ resp = Response.new(:question_id => 314, :response_set_id => 156)
50
+ resp.as(:string).should == nil
51
+ resp.as(:integer).should == nil
52
+ resp.as(:float).should == nil
53
+ resp.as(:answer).should == nil
54
+ resp.as(:stuff).should == nil
55
+ end
56
+
57
+ end
58
+
59
+ describe "model validation defined in the answer class attributes" do
60
+
61
+ before(:each) do
62
+ # faking out all the basic validations on the model
63
+ @response = Response.new(:question_id => 123, :response_set_id => 421, :answer_id => 213)
64
+ end
65
+
66
+ describe "Integer response_type validations" do
67
+
68
+ before(:each) do
69
+ @response.stub!(:answer).and_return(mock(Answer, {:response_class => :integer}))
70
+ end
71
+
72
+ it "validates an upper limit on responses" do
73
+ @response.answer.stub!(:max_value).and_return(10)
74
+ @response.integer_value = 100
75
+ @response.save.should be_false
76
+ @response.should have(1).error_on(:integer_value)
77
+ end
78
+
79
+ end
80
+
81
+ describe "Float response_type validations" do
82
+
83
+ before(:each) do
84
+ @response.stub!(:answer).and_return(mock(Answer, {:response_class => :float}))
85
+ end
86
+
87
+ it "validates an upper limit on responses" do
88
+ pending
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SurveySection, "when saving a survey_section" do
4
+ before(:each) do
5
+ @valid_attributes={:title => "foo", :survey_id => 2, :display_order => 4}
6
+ @survey_section = SurveySection.new(@valid_attributes)
7
+ end
8
+
9
+ it "should be invalid without title" do
10
+ @survey_section.title = nil
11
+ @survey_section.should have(1).error_on(:title)
12
+ end
13
+
14
+ it "should have a parent survey" do
15
+ @survey_section.survey_id = nil
16
+ @survey_section.should have(1).error_on(:survey)
17
+ end
18
+ end
19
+
20
+ describe SurveySection, "with questions" do
21
+ before(:each) do
22
+ @survey = mock_model(Survey)
23
+ @valid_attributes={:title => "Rhymes", :survey => @survey, :display_order => 4}
24
+ @survey_section = SurveySection.create(@valid_attributes)
25
+ @q1 = @survey_section.questions.create(:text => "Peep", :display_order => 3)
26
+ @q2 = @survey_section.questions.create(:text => "Little", :display_order => 1)
27
+ @q3 = @survey_section.questions.create(:text => "Bo", :display_order => 2)
28
+ end
29
+
30
+ it "should return questions sorted in display order" do
31
+ @survey_section.questions.should have(3).questions
32
+ @survey_section.questions.should == [@q2,@q3,@q1]
33
+ end
34
+ end