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.
- data/.gitignore +6 -0
- data/MIT-LICENSE +20 -0
- data/README.md +20 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/app/controllers/answers_controller.rb +87 -0
- data/app/controllers/dependencies_controller.rb +87 -0
- data/app/controllers/dependency_conditions_controller.rb +87 -0
- data/app/controllers/questions_controller.rb +85 -0
- data/app/controllers/sections_controller.rb +87 -0
- data/app/controllers/surveying_controller.rb +139 -0
- data/app/controllers/surveys_controller.rb +87 -0
- data/app/helpers/answers_helper.rb +2 -0
- data/app/helpers/application_helper.rb +3 -0
- data/app/helpers/questions_helper.rb +2 -0
- data/app/helpers/sections_helper.rb +2 -0
- data/app/helpers/survey_form_builder.rb +38 -0
- data/app/helpers/survey_importer_helper.rb +2 -0
- data/app/helpers/surveying_helper.rb +91 -0
- data/app/helpers/surveys_helper.rb +2 -0
- data/app/models/answer.rb +18 -0
- data/app/models/dependency.rb +43 -0
- data/app/models/dependency_condition.rb +76 -0
- data/app/models/question.rb +44 -0
- data/app/models/question_group.rb +5 -0
- data/app/models/response.rb +58 -0
- data/app/models/response_set.rb +174 -0
- data/app/models/survey.rb +54 -0
- data/app/models/survey_section.rb +19 -0
- data/app/models/user.rb +5 -0
- data/app/views/answer_display_types/_any_answer.html.haml +3 -0
- data/app/views/answer_display_types/_any_other_and_string.html.haml +5 -0
- data/app/views/answer_display_types/_any_string.html.haml +4 -0
- data/app/views/answer_display_types/_date.html.haml +3 -0
- data/app/views/answer_display_types/_datetime.html.haml +2 -0
- data/app/views/answer_display_types/_default.html.haml +1 -0
- data/app/views/answer_display_types/_float.html.haml +5 -0
- data/app/views/answer_display_types/_grid_any_answer.html.haml +2 -0
- data/app/views/answer_display_types/_grid_default.html.haml +2 -0
- data/app/views/answer_display_types/_grid_float.html.haml +2 -0
- data/app/views/answer_display_types/_grid_integer.html.haml +2 -0
- data/app/views/answer_display_types/_grid_one_answer.html.haml +2 -0
- data/app/views/answer_display_types/_grid_string.html.haml +2 -0
- data/app/views/answer_display_types/_integer.html.haml +6 -0
- data/app/views/answer_display_types/_one_answer.html.haml +3 -0
- data/app/views/answer_display_types/_one_string.html.haml +6 -0
- data/app/views/answer_display_types/_repeater_integer.html.haml +6 -0
- data/app/views/answer_display_types/_repeater_string.html.haml +7 -0
- data/app/views/answer_display_types/_string.html.haml +7 -0
- data/app/views/answer_display_types/_text.html.haml +6 -0
- data/app/views/answer_display_types/_time.html.haml +2 -0
- data/app/views/layouts/surveys.html.erb +17 -0
- data/app/views/question_display_types/_default.html.haml +12 -0
- data/app/views/question_display_types/_dropdown.html.haml +12 -0
- data/app/views/question_display_types/_grid_default.html.haml +14 -0
- data/app/views/question_display_types/_grid_dropdown.html.haml +15 -0
- data/app/views/question_display_types/_group_default.html.haml +8 -0
- data/app/views/question_display_types/_group_dropdown.html.haml +6 -0
- data/app/views/question_display_types/_image.html.haml +2 -0
- data/app/views/question_display_types/_inline.html.haml +12 -0
- data/app/views/question_display_types/_label.html.haml +4 -0
- data/app/views/question_display_types/_repeater_default.html.haml +10 -0
- data/app/views/question_display_types/_repeater_dropdown.html.haml +8 -0
- data/app/views/question_display_types/_slider.html.haml +17 -0
- data/app/views/question_group_display_types/_default.html.haml +13 -0
- data/app/views/question_group_display_types/_grid.html.haml +24 -0
- data/app/views/question_group_display_types/_repeater.html.haml +20 -0
- data/app/views/surveying/edit.html.haml +38 -0
- data/app/views/surveying/finish.html.haml +1 -0
- data/app/views/surveying/index.html.erb +19 -0
- data/app/views/surveying/new.html.haml +17 -0
- data/app/views/surveying/show.html.haml +8 -0
- data/config/routes.rb +10 -0
- data/generators/surveyor/surveyor_generator.rb +38 -0
- data/generators/surveyor/templates/README +9 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_leftright.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_updown.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_close.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_doc.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_closed.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_open.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_minus.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_plus.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_11x11_icon_resize_se.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_35x9_colorpicker_indicator.gif.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_7x7_arrow_down.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_7x7_arrow_left.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_7x7_arrow_right.gif +0 -0
- data/generators/surveyor/templates/assets/images/222222_7x7_arrow_up.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_leftright.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_updown.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_close.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_doc.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_closed.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_open.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_minus.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_11x11_icon_plus.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_7x7_arrow_down.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_7x7_arrow_left.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_7x7_arrow_right.gif +0 -0
- data/generators/surveyor/templates/assets/images/454545_7x7_arrow_up.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_leftright.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_updown.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_close.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_doc.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_closed.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_open.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_minus.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_11x11_icon_plus.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_7x7_arrow_down.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_7x7_arrow_left.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_7x7_arrow_right.gif +0 -0
- data/generators/surveyor/templates/assets/images/888888_7x7_arrow_up.gif +0 -0
- data/generators/surveyor/templates/assets/images/dadada_40x100_textures_02_glass_75.png +0 -0
- data/generators/surveyor/templates/assets/images/e6e6e6_40x100_textures_02_glass_75.png +0 -0
- data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_01_flat_0.png +0 -0
- data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_02_glass_65.png +0 -0
- data/generators/surveyor/templates/assets/javascripts/accessibleUISlider.jQuery.js +201 -0
- data/generators/surveyor/templates/assets/javascripts/jquery-1.2.6.js +3549 -0
- data/generators/surveyor/templates/assets/javascripts/jquery-ui-personalized-1.5.3.js +7616 -0
- data/generators/surveyor/templates/assets/javascripts/jquery.form.js +637 -0
- data/generators/surveyor/templates/assets/javascripts/surveyor.js +35 -0
- data/generators/surveyor/templates/assets/stylesheets/jquery-ui-slider-additions.css +71 -0
- data/generators/surveyor/templates/assets/stylesheets/reset.css +46 -0
- data/generators/surveyor/templates/assets/stylesheets/sass/surveyor.sass +321 -0
- data/generators/surveyor/templates/assets/stylesheets/surveyor.css +245 -0
- data/generators/surveyor/templates/assets/stylesheets/ui.theme.css +851 -0
- data/generators/surveyor/templates/migrate/create_answers.rb +46 -0
- data/generators/surveyor/templates/migrate/create_dependencies.rb +21 -0
- data/generators/surveyor/templates/migrate/create_dependency_conditions.rb +29 -0
- data/generators/surveyor/templates/migrate/create_question_groups.rb +18 -0
- data/generators/surveyor/templates/migrate/create_questions.rb +33 -0
- data/generators/surveyor/templates/migrate/create_response_sets.rb +22 -0
- data/generators/surveyor/templates/migrate/create_responses.rb +33 -0
- data/generators/surveyor/templates/migrate/create_survey_sections.rb +25 -0
- data/generators/surveyor/templates/migrate/create_surveys.rb +25 -0
- data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +201 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/tasks/surveyor_tasks.rake +29 -0
- data/lib/tiny_code.rb +58 -0
- data/lib/user_manager.rb +9 -0
- data/lib/xml_formatter.rb +12 -0
- data/script/surveyor/answer.rb +84 -0
- data/script/surveyor/columnizer.rb +36 -0
- data/script/surveyor/dependency.rb +43 -0
- data/script/surveyor/dependency_condition.rb +74 -0
- data/script/surveyor/dslparse.rb +66 -0
- data/script/surveyor/question.rb +76 -0
- data/script/surveyor/question_group.rb +33 -0
- data/script/surveyor/specs/answer_spec.rb +66 -0
- data/script/surveyor/specs/question_dependency_spec.rb +46 -0
- data/script/surveyor/specs/question_group_spec.rb +9 -0
- data/script/surveyor/specs/question_spec.rb +111 -0
- data/script/surveyor/specs/section_spec.rb +58 -0
- data/script/surveyor/survey.rb +108 -0
- data/script/surveyor/survey_section.rb +153 -0
- data/script/surveyor/whr_dsl.tmproj +244 -0
- data/spec/controllers/answers_controller_spec.rb +64 -0
- data/spec/controllers/dependencies_controller_spec.rb +63 -0
- data/spec/controllers/dependency_conditions_controller_spec.rb +64 -0
- data/spec/controllers/questions_controller_spec.rb +64 -0
- data/spec/controllers/sections_controller_spec.rb +64 -0
- data/spec/controllers/surveying_controller_spec.rb +328 -0
- data/spec/controllers/surveying_routing_spec.rb +45 -0
- data/spec/controllers/surveys_controller_spec.rb +64 -0
- data/spec/fixtures/answers.yml +9 -0
- data/spec/fixtures/dependencies.yml +7 -0
- data/spec/fixtures/dependency_conditions.yml +27 -0
- data/spec/fixtures/question_groups.yml +7 -0
- data/spec/fixtures/questions.yml +15 -0
- data/spec/fixtures/response_sets.yml +13 -0
- data/spec/fixtures/responses.yml +9 -0
- data/spec/fixtures/survey_sections.yml +11 -0
- data/spec/fixtures/surveys.yml +9 -0
- data/spec/fixtures/users.yml +7 -0
- data/spec/helpers/survey_importer_helper_spec.rb +11 -0
- data/spec/helpers/surveying_helper_spec.rb +11 -0
- data/spec/models/answer_spec.rb +62 -0
- data/spec/models/dependency_condition_spec.rb +347 -0
- data/spec/models/dependency_spec.rb +82 -0
- data/spec/models/question_group_spec.rb +11 -0
- data/spec/models/question_spec.rb +70 -0
- data/spec/models/response_set_spec.rb +172 -0
- data/spec/models/response_spec.rb +94 -0
- data/spec/models/survey_section_spec.rb +34 -0
- data/spec/models/survey_spec.rb +72 -0
- data/spec/models/user_spec.rb +11 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +72 -0
- data/spec/views/app/edit.html.erb_spec.rb +20 -0
- data/spec/views/app/index.html.erb_spec.rb +19 -0
- data/spec/views/app/new.html.erb_spec.rb +21 -0
- data/spec/views/app/show.html.erb_spec.rb +17 -0
- data/surveyor.gemspec +258 -0
- data/uninstall.rb +1 -0
- 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,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
|