surveyor 0.7.1 → 0.8.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/VERSION +1 -1
- data/app/controllers/surveyor_controller.rb +3 -4
- data/app/models/answer.rb +1 -2
- data/app/models/dependency.rb +7 -6
- data/app/models/dependency_condition.rb +11 -48
- data/app/models/response.rb +2 -14
- data/app/models/response_set.rb +1 -1
- data/app/models/validation.rb +13 -0
- data/app/models/validation_condition.rb +39 -0
- data/config/routes.rb +3 -3
- data/generators/surveyor/surveyor_generator.rb +1 -1
- data/generators/surveyor/templates/migrate/create_validation_conditions.rb +32 -0
- data/generators/surveyor/templates/migrate/create_validations.rb +20 -0
- data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +19 -3
- data/lib/surveyor/acts_as_response.rb +33 -0
- data/lib/surveyor.rb +1 -0
- data/script/surveyor/question_group.rb +1 -0
- data/script/surveyor/survey.rb +3 -0
- data/spec/controllers/surveyor_controller_spec.rb +68 -203
- data/spec/factories.rb +58 -25
- data/spec/models/answer_spec.rb +1 -1
- data/spec/models/dependency_condition_spec.rb +47 -64
- data/spec/models/dependency_spec.rb +11 -5
- data/spec/models/question_group_spec.rb +25 -1
- data/spec/models/question_spec.rb +2 -2
- data/spec/models/response_set_spec.rb +10 -25
- data/spec/models/response_spec.rb +11 -46
- data/spec/models/survey_spec.rb +9 -10
- data/spec/models/validation_condition_spec.rb +53 -0
- data/spec/models/validation_spec.rb +32 -0
- data/surveyor.gemspec +11 -2
- metadata +11 -2
@@ -58,36 +58,19 @@ describe DependencyCondition, "instance" do
|
|
58
58
|
it "should evaluate within the context of a response set object" do
|
59
59
|
@response = Response.new(:question_id => 45, :response_set_id => 40, :answer_id => 23)
|
60
60
|
@response.answer = Answer.new(:question_id => 45, :response_class => "answer")
|
61
|
-
@
|
62
|
-
@response_set.stub!(:find_response).and_return(@response)
|
63
|
-
@dependency_condition.evaluation_of(@response_set).should be_true
|
61
|
+
@dependency_condition.is_met?(@response).should be_true
|
64
62
|
# inversion
|
65
63
|
@alt_response = Response.new(:question_id => 45, :response_set_id => 40, :answer_id => 55)
|
66
64
|
@alt_response.answer = Answer.new(:question_id => 45, :response_class => "answer")
|
67
|
-
@alt_resp_set = ResponseSet.new()
|
68
65
|
|
69
|
-
@
|
70
|
-
@dependency_condition.evaluation_of(@alt_resp_set).should be_false
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should return false if there is no response set value that corresponds to the dependency condition" do
|
75
|
-
@empty_rs = mock(ResponseSet, :find_response => nil)
|
76
|
-
@dependency_condition.evaluation_of(@empty_rs).should be_false
|
66
|
+
@dependency_condition.is_met?(@alt_response).should be_false
|
77
67
|
end
|
78
68
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
it "converts to a hash for evaluation by the depedency object" do
|
86
|
-
@rs = mock(ResponseSet)
|
87
|
-
@dependency_condition.stub!(:evaluation_of).with(@rs)
|
88
|
-
@dependency_condition.to_evaluation_hash(@rs)
|
89
|
-
end
|
90
|
-
|
69
|
+
it "converts to a hash for evaluation by the depedency object" do
|
70
|
+
@response = Response.new(:question_id => 45, :response_set_id => 40, :answer_id => 23)
|
71
|
+
@rs = mock(ResponseSet, :responses => [@response])
|
72
|
+
@dependency_condition.stub!(:is_met?).and_return(true)
|
73
|
+
@dependency_condition.to_hash(@rs)
|
91
74
|
end
|
92
75
|
end
|
93
76
|
|
@@ -106,45 +89,45 @@ describe DependencyCondition, "evaluting the resonse_set state" do
|
|
106
89
|
end
|
107
90
|
|
108
91
|
it "knows checkbox/radio type response" do
|
109
|
-
@dep_c.
|
92
|
+
@dep_c.is_met?(@response).should be_true
|
110
93
|
@dep_c.answer_id = 12
|
111
|
-
@dep_c.
|
94
|
+
@dep_c.is_met?(@response).should be_false
|
112
95
|
end
|
113
96
|
|
114
97
|
it "knows string value response" do
|
115
98
|
@select_answer.response_class = "string"
|
116
99
|
@response.string_value = "hello123"
|
117
100
|
@dep_c.string_value = "hello123"
|
118
|
-
@dep_c.
|
101
|
+
@dep_c.is_met?(@response).should be_true
|
119
102
|
@response.string_value = "foo_abc"
|
120
|
-
@dep_c.
|
103
|
+
@dep_c.is_met?(@response).should be_false
|
121
104
|
end
|
122
105
|
|
123
106
|
it "knows a text value response" do
|
124
107
|
@select_answer.response_class = "text"
|
125
108
|
@response.text_value = "hello this is some text for comparison"
|
126
109
|
@dep_c.text_value = "hello this is some text for comparison"
|
127
|
-
@dep_c.
|
110
|
+
@dep_c.is_met?(@response).should be_true
|
128
111
|
@response.text_value = "Not the same text"
|
129
|
-
@dep_c.
|
112
|
+
@dep_c.is_met?(@response).should be_false
|
130
113
|
end
|
131
114
|
|
132
115
|
it "knows an integer value response" do
|
133
116
|
@select_answer.response_class = "integer"
|
134
117
|
@response.integer_value = 10045
|
135
118
|
@dep_c.integer_value = 10045
|
136
|
-
@dep_c.
|
119
|
+
@dep_c.is_met?(@response).should be_true
|
137
120
|
@response.integer_value = 421
|
138
|
-
@dep_c.
|
121
|
+
@dep_c.is_met?(@response).should be_false
|
139
122
|
end
|
140
123
|
|
141
124
|
it "knows a float value response" do
|
142
125
|
@select_answer.response_class = "float"
|
143
126
|
@response.float_value = 121.1
|
144
127
|
@dep_c.float_value = 121.1
|
145
|
-
@dep_c.
|
128
|
+
@dep_c.is_met?(@response).should be_true
|
146
129
|
@response.float_value = 130.123
|
147
|
-
@dep_c.
|
130
|
+
@dep_c.is_met?(@response).should be_false
|
148
131
|
end
|
149
132
|
|
150
133
|
end
|
@@ -162,45 +145,45 @@ describe DependencyCondition, "evaluting the resonse_set state" do
|
|
162
145
|
end
|
163
146
|
|
164
147
|
it "knows checkbox/radio type response" do
|
165
|
-
@dep_c.
|
148
|
+
@dep_c.is_met?(@response).should be_false
|
166
149
|
@dep_c.answer_id = 12
|
167
|
-
@dep_c.
|
150
|
+
@dep_c.is_met?(@response).should be_true
|
168
151
|
end
|
169
152
|
|
170
153
|
it "knows string value response" do
|
171
154
|
@select_answer.response_class = "string"
|
172
155
|
@response.string_value = "hello123"
|
173
156
|
@dep_c.string_value = "hello123"
|
174
|
-
@dep_c.
|
157
|
+
@dep_c.is_met?(@response).should be_false
|
175
158
|
@response.string_value = "foo_abc"
|
176
|
-
@dep_c.
|
159
|
+
@dep_c.is_met?(@response).should be_true
|
177
160
|
end
|
178
161
|
|
179
162
|
it "knows a text value response" do
|
180
163
|
@select_answer.response_class = "text"
|
181
164
|
@response.text_value = "hello this is some text for comparison"
|
182
165
|
@dep_c.text_value = "hello this is some text for comparison"
|
183
|
-
@dep_c.
|
166
|
+
@dep_c.is_met?(@response).should be_false
|
184
167
|
@response.text_value = "Not the same text"
|
185
|
-
@dep_c.
|
168
|
+
@dep_c.is_met?(@response).should be_true
|
186
169
|
end
|
187
170
|
|
188
171
|
it "knows an integer value response" do
|
189
172
|
@select_answer.response_class = "integer"
|
190
173
|
@response.integer_value = 10045
|
191
174
|
@dep_c.integer_value = 10045
|
192
|
-
@dep_c.
|
175
|
+
@dep_c.is_met?(@response).should be_false
|
193
176
|
@response.integer_value = 421
|
194
|
-
@dep_c.
|
177
|
+
@dep_c.is_met?(@response).should be_true
|
195
178
|
end
|
196
179
|
|
197
180
|
it "knows a float value response" do
|
198
181
|
@select_answer.response_class = "float"
|
199
182
|
@response.float_value = 121.1
|
200
183
|
@dep_c.float_value = 121.1
|
201
|
-
@dep_c.
|
184
|
+
@dep_c.is_met?(@response).should be_false
|
202
185
|
@response.float_value = 130.123
|
203
|
-
@dep_c.
|
186
|
+
@dep_c.is_met?(@response).should be_true
|
204
187
|
end
|
205
188
|
|
206
189
|
end
|
@@ -219,18 +202,18 @@ describe DependencyCondition, "evaluting the resonse_set state" do
|
|
219
202
|
@select_answer.response_class = "integer"
|
220
203
|
@response.integer_value = 50
|
221
204
|
@dep_c.integer_value = 100
|
222
|
-
@dep_c.
|
205
|
+
@dep_c.is_met?(@response).should be_true
|
223
206
|
@response.integer_value = 421
|
224
|
-
@dep_c.
|
207
|
+
@dep_c.is_met?(@response).should be_false
|
225
208
|
end
|
226
209
|
|
227
210
|
it "knows operator on float value response" do
|
228
211
|
@select_answer.response_class = "float"
|
229
212
|
@response.float_value = 5.1
|
230
213
|
@dep_c.float_value = 121.1
|
231
|
-
@dep_c.
|
214
|
+
@dep_c.is_met?(@response).should be_true
|
232
215
|
@response.float_value = 130.123
|
233
|
-
@dep_c.
|
216
|
+
@dep_c.is_met?(@response).should be_false
|
234
217
|
end
|
235
218
|
|
236
219
|
end
|
@@ -249,22 +232,22 @@ describe DependencyCondition, "evaluting the resonse_set state" do
|
|
249
232
|
@select_answer.response_class = "integer"
|
250
233
|
@response.integer_value = 50
|
251
234
|
@dep_c.integer_value = 100
|
252
|
-
@dep_c.
|
235
|
+
@dep_c.is_met?(@response).should be_true
|
253
236
|
@response.integer_value = 100
|
254
|
-
@dep_c.
|
237
|
+
@dep_c.is_met?(@response).should be_true
|
255
238
|
@response.integer_value = 421
|
256
|
-
@dep_c.
|
239
|
+
@dep_c.is_met?(@response).should be_false
|
257
240
|
end
|
258
241
|
|
259
242
|
it "knows operator on float value response" do
|
260
243
|
@select_answer.response_class = "float"
|
261
244
|
@response.float_value = 5.1
|
262
245
|
@dep_c.float_value = 121.1
|
263
|
-
@dep_c.
|
246
|
+
@dep_c.is_met?(@response).should be_true
|
264
247
|
@response.float_value = 121.1
|
265
|
-
@dep_c.
|
248
|
+
@dep_c.is_met?(@response).should be_true
|
266
249
|
@response.float_value = 130.123
|
267
|
-
@dep_c.
|
250
|
+
@dep_c.is_met?(@response).should be_false
|
268
251
|
end
|
269
252
|
|
270
253
|
end
|
@@ -283,18 +266,18 @@ describe DependencyCondition, "evaluting the resonse_set state" do
|
|
283
266
|
@select_answer.response_class = "integer"
|
284
267
|
@response.integer_value = 50
|
285
268
|
@dep_c.integer_value = 100
|
286
|
-
@dep_c.
|
269
|
+
@dep_c.is_met?(@response).should be_false
|
287
270
|
@response.integer_value = 421
|
288
|
-
@dep_c.
|
271
|
+
@dep_c.is_met?(@response).should be_true
|
289
272
|
end
|
290
273
|
|
291
274
|
it "knows operator on float value response" do
|
292
275
|
@select_answer.response_class = "float"
|
293
276
|
@response.float_value = 5.1
|
294
277
|
@dep_c.float_value = 121.1
|
295
|
-
@dep_c.
|
278
|
+
@dep_c.is_met?(@response).should be_false
|
296
279
|
@response.float_value = 130.123
|
297
|
-
@dep_c.
|
280
|
+
@dep_c.is_met?(@response).should be_true
|
298
281
|
end
|
299
282
|
|
300
283
|
end
|
@@ -313,22 +296,22 @@ describe DependencyCondition, "evaluting the resonse_set state" do
|
|
313
296
|
@select_answer.response_class = "integer"
|
314
297
|
@response.integer_value = 50
|
315
298
|
@dep_c.integer_value = 100
|
316
|
-
@dep_c.
|
299
|
+
@dep_c.is_met?(@response).should be_false
|
317
300
|
@response.integer_value = 100
|
318
|
-
@dep_c.
|
301
|
+
@dep_c.is_met?(@response).should be_true
|
319
302
|
@response.integer_value = 421
|
320
|
-
@dep_c.
|
303
|
+
@dep_c.is_met?(@response).should be_true
|
321
304
|
end
|
322
305
|
|
323
306
|
it "knows operator on float value response" do
|
324
307
|
@select_answer.response_class = "float"
|
325
308
|
@response.float_value = 5.1
|
326
309
|
@dep_c.float_value = 121.1
|
327
|
-
@dep_c.
|
310
|
+
@dep_c.is_met?(@response).should be_false
|
328
311
|
@response.float_value = 121.1
|
329
|
-
@dep_c.
|
312
|
+
@dep_c.is_met?(@response).should be_true
|
330
313
|
@response.float_value = 130.123
|
331
|
-
@dep_c.
|
314
|
+
@dep_c.is_met?(@response).should be_true
|
332
315
|
end
|
333
316
|
end
|
334
317
|
|
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe Dependency do
|
4
4
|
before(:each) do
|
5
|
-
@dependency =
|
5
|
+
@dependency = Factory(:dependency)
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be valid" do
|
@@ -19,6 +19,13 @@ describe Dependency do
|
|
19
19
|
it "should be invalid without a question_id" do
|
20
20
|
@dependency.question_id = nil
|
21
21
|
@dependency.should have(1).error_on(:question_id)
|
22
|
+
|
23
|
+
@dependency.question_group_id = 1
|
24
|
+
@dependency.should be_valid
|
25
|
+
|
26
|
+
@dependency.question_id.should be_nil
|
27
|
+
@dependency.question_group_id = nil
|
28
|
+
@dependency.should have(1).error_on(:question_group_id)
|
22
29
|
end
|
23
30
|
|
24
31
|
it "should alias question_id as dependent_question_id" do
|
@@ -47,9 +54,9 @@ describe Dependency, "when evaluating dependency conditions of a question in a r
|
|
47
54
|
@dep3 = Dependency.new(:rule => "A or B", :question_id => 1)
|
48
55
|
@dep4 = Dependency.new(:rule => "!(A and B) and C", :question_id => 1)
|
49
56
|
|
50
|
-
@dep_c = mock_model(DependencyCondition, :id => 1, :rule_key => "A", :
|
51
|
-
@dep_c2 = mock_model(DependencyCondition, :id => 2, :rule_key => "B", :
|
52
|
-
@dep_c3 = mock_model(DependencyCondition, :id => 3, :rule_key => "C", :
|
57
|
+
@dep_c = mock_model(DependencyCondition, :id => 1, :rule_key => "A", :to_hash => {:A => true})
|
58
|
+
@dep_c2 = mock_model(DependencyCondition, :id => 2, :rule_key => "B", :to_hash => {:B => false})
|
59
|
+
@dep_c3 = mock_model(DependencyCondition, :id => 3, :rule_key => "C", :to_hash => {:C => true})
|
53
60
|
|
54
61
|
@dep.stub!(:dependency_conditions).and_return([@dep_c])
|
55
62
|
@dep2.stub!(:dependency_conditions).and_return([@dep_c, @dep_c2])
|
@@ -78,5 +85,4 @@ describe Dependency, "when evaluating dependency conditions of a question in a r
|
|
78
85
|
@dep4.rule_evaluation(@dep4.keyed_conditions(@response_set)).should be_true
|
79
86
|
end
|
80
87
|
|
81
|
-
|
82
88
|
end
|
@@ -2,10 +2,34 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe QuestionGroup do
|
4
4
|
before(:each) do
|
5
|
-
@question_group =
|
5
|
+
@question_group = Factory(:question_group)
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be valid" do
|
9
9
|
@question_group.should be_valid
|
10
10
|
end
|
11
|
+
it "should have defaults" do
|
12
|
+
@question_group = QuestionGroup.new
|
13
|
+
@question_group.display_type.should == "inline"
|
14
|
+
@question_group.renderer.should == :inline
|
15
|
+
@question_group.display_type = nil
|
16
|
+
@question_group.renderer.should == :default
|
17
|
+
end
|
18
|
+
it "should return its custom css class" do
|
19
|
+
@question_group.custom_class = "foo bar"
|
20
|
+
@question_group.css_class(Factory(:response_set)).should == "foo bar"
|
21
|
+
end
|
22
|
+
it "should return its dependency class" do
|
23
|
+
@dependency = Factory(:dependency)
|
24
|
+
@question_group.dependency = @dependency
|
25
|
+
@dependency.should_receive(:met?).and_return(true)
|
26
|
+
@question_group.css_class(Factory(:response_set)).should == "dependent"
|
27
|
+
|
28
|
+
@dependency.should_receive(:met?).and_return(false)
|
29
|
+
@question_group.css_class(Factory(:response_set)).should == "dependent hidden"
|
30
|
+
|
31
|
+
@question_group.custom_class = "foo bar"
|
32
|
+
@dependency.should_receive(:met?).and_return(false)
|
33
|
+
@question_group.css_class(Factory(:response_set)).should == "dependent hidden foo bar"
|
34
|
+
end
|
11
35
|
end
|
@@ -53,7 +53,7 @@ describe Question, "when interacting with an instance" do
|
|
53
53
|
|
54
54
|
it "should return 'default' for nil display type" do
|
55
55
|
@question.display_type = nil
|
56
|
-
@question.
|
56
|
+
@question.renderer.should == :default
|
57
57
|
end
|
58
58
|
|
59
59
|
end
|
@@ -69,7 +69,7 @@ describe Question, "with dependencies" do
|
|
69
69
|
@dependency = mock_model(Dependency)
|
70
70
|
@dependency.stub!(:met?).with(@rs).and_return(true)
|
71
71
|
@question.stub!(:dependency).and_return(@dependency)
|
72
|
-
@question.
|
72
|
+
@question.triggered?(@rs).should == true
|
73
73
|
end
|
74
74
|
|
75
75
|
end
|
@@ -75,10 +75,6 @@ describe ResponseSet, "Updating the response set" do
|
|
75
75
|
})
|
76
76
|
end
|
77
77
|
|
78
|
-
it "should delete existing responses corresponding to every question key that comes in" do
|
79
|
-
Response.should_receive(:delete_all).exactly(3).times
|
80
|
-
@response_set.update_attributes(:response_attributes => @radio_response_attributes)
|
81
|
-
end
|
82
78
|
it "should save new responses from radio buttons, ignoring blanks" do
|
83
79
|
@response_set.update_attributes(:response_attributes => @radio_response_attributes)
|
84
80
|
@response_set.responses.should have(2).items
|
@@ -108,37 +104,26 @@ describe ResponseSet, "Updating the response set" do
|
|
108
104
|
end
|
109
105
|
end
|
110
106
|
|
111
|
-
describe ResponseSet, "knowing internal status" do
|
112
|
-
before(:each) do
|
113
|
-
@response_set = Factory(:response_set)
|
114
|
-
end
|
115
|
-
it "knows when it is empty" do
|
116
|
-
@response_set.empty?.should be_true
|
117
|
-
end
|
118
|
-
|
119
|
-
it "knows when it is not empty" do
|
120
|
-
@response_set.responses.build({:question_id => 1, :answer_id => 8})
|
121
|
-
@response_set.empty?.should be_false
|
122
|
-
end
|
123
|
-
end
|
124
107
|
describe ResponseSet, "with dependencies" do
|
125
108
|
before(:each) do
|
109
|
+
@section = Factory(:survey_section)
|
126
110
|
# Questions
|
127
|
-
@do_you_like_pie = Factory(:question, :text => "Do you like pie?")
|
128
|
-
@what_flavor = Factory(:question, :text => "What flavor?")
|
129
|
-
@what_bakery = Factory(:question, :text => "What bakery?")
|
111
|
+
@do_you_like_pie = Factory(:question, :text => "Do you like pie?", :survey_section => @section)
|
112
|
+
@what_flavor = Factory(:question, :text => "What flavor?", :survey_section => @section)
|
113
|
+
@what_bakery = Factory(:question, :text => "What bakery?", :survey_section => @section)
|
130
114
|
# Answers
|
131
115
|
@do_you_like_pie.answers << Factory(:answer, :text => "yes", :question_id => @do_you_like_pie.id)
|
132
116
|
@do_you_like_pie.answers << Factory(:answer, :text => "no", :question_id => @do_you_like_pie.id)
|
133
117
|
@what_flavor.answers << Factory(:answer, :response_class => :string, :question_id => @what_flavor.id)
|
134
118
|
@what_bakery.answers << Factory(:answer, :response_class => :string, :question_id => @what_bakery.id)
|
135
119
|
# Dependency
|
136
|
-
@what_flavor_dep = Factory(:dependency, :rule => "
|
137
|
-
|
138
|
-
@what_bakery_dep = Factory(:dependency, :rule => "
|
139
|
-
|
120
|
+
@what_flavor_dep = Factory(:dependency, :rule => "A", :question_id => @what_flavor.id)
|
121
|
+
Factory(:dependency_condition, :rule_key => "A", :question_id => @do_you_like_pie.id, :operator => "==", :answer_id => @do_you_like_pie.answers.first.id, :dependency_id => @what_flavor_dep.id)
|
122
|
+
@what_bakery_dep = Factory(:dependency, :rule => "B", :question_id => @what_bakery.id)
|
123
|
+
Factory(:dependency_condition, :rule_key => "B", :question_id => @do_you_like_pie.id, :operator => "==", :answer_id => @do_you_like_pie.answers.first.id, :dependency_id => @what_bakery_dep.id)
|
140
124
|
# Responses
|
141
125
|
@response_set = Factory(:response_set)
|
126
|
+
@response_set.current_section_id = @section.id
|
142
127
|
@response_set.responses << Factory(:response, :question_id => @do_you_like_pie.id, :answer_id => @do_you_like_pie.answers.first.id, :response_set_id => @response_set.id)
|
143
128
|
@response_set.responses << Factory(:response, :string_value => "pecan pie", :question_id => @what_flavor.id, :answer_id => @what_flavor.answers.first.id, :response_set_id => @response_set.id)
|
144
129
|
end
|
@@ -147,7 +132,7 @@ describe ResponseSet, "with dependencies" do
|
|
147
132
|
@response_set.unanswered_dependencies.should == [@what_bakery]
|
148
133
|
end
|
149
134
|
it "should list answered and unanswered dependencies to show inline (javascript turned on)" do
|
150
|
-
@response_set.all_dependencies[:show].should == [@what_flavor, @what_bakery]
|
135
|
+
@response_set.all_dependencies[:show].should == ["question_#{@what_flavor.id}", "question_#{@what_bakery.id}"]
|
151
136
|
end
|
152
137
|
|
153
138
|
end
|
@@ -4,47 +4,47 @@ describe Response, "when saving a response" do
|
|
4
4
|
before(:each) do
|
5
5
|
@response = Response.new(:question_id => 314, :response_set_id => 159, :answer_id => 1)
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it "should be valid" do
|
9
9
|
@response.should be_valid
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "should be invalid without a parent response set and question" do
|
13
13
|
@response.response_set_id = nil
|
14
14
|
@response.should have(1).error_on(:response_set_id)
|
15
|
-
|
15
|
+
|
16
16
|
@response.question_id = nil
|
17
17
|
@response.should have(1).error_on(:question_id)
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "returns the response as the type requested" do
|
21
|
-
|
21
|
+
|
22
22
|
it "returns 'string'" do
|
23
23
|
@response.string_value = "blah"
|
24
24
|
@response.as("string").should == "blah"
|
25
25
|
@response.as(:string).should == "blah"
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "returns 'integer'" do
|
29
29
|
@response.integer_value = 1001
|
30
30
|
@response.as(:integer).should == 1001
|
31
31
|
end
|
32
|
-
|
33
|
-
it "returns 'float'"do
|
32
|
+
|
33
|
+
it "returns 'float'" do
|
34
34
|
@response.float_value = 3.14
|
35
35
|
@response.as(:float).should == 3.14
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "returns 'answer'" do
|
39
39
|
@response.answer_id = 14
|
40
40
|
@response.as(:answer).should == 14
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "default returns answer type if not specified" do
|
44
44
|
@response.answer_id =18
|
45
45
|
@response.as(:stuff).should == 18
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it "returns empty elements if the response is cast as a type that is not present" do
|
49
49
|
resp = Response.new(:question_id => 314, :response_set_id => 156)
|
50
50
|
resp.as(:string).should == nil
|
@@ -53,42 +53,7 @@ describe Response, "when saving a response" do
|
|
53
53
|
resp.as(:answer).should == nil
|
54
54
|
resp.as(:stuff).should == nil
|
55
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
56
|
|
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
57
|
end
|
58
|
+
|
94
59
|
end
|
data/spec/models/survey_spec.rb
CHANGED
@@ -3,8 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
# Validations
|
4
4
|
describe Survey, "when saving a new one" do
|
5
5
|
before(:each) do
|
6
|
-
@survey =
|
7
|
-
@survey.title = "Foo"
|
6
|
+
@survey = Factory(:survey, :title => "Foo")
|
8
7
|
end
|
9
8
|
|
10
9
|
it "should be invalid without a title" do
|
@@ -16,14 +15,14 @@ end
|
|
16
15
|
# Associations
|
17
16
|
describe Survey, "that has sections" do
|
18
17
|
before(:each) do
|
19
|
-
@survey =
|
20
|
-
@s1 = @survey
|
21
|
-
@s2 = @survey
|
22
|
-
@s3 = @survey
|
23
|
-
@q1 = @s1
|
24
|
-
@q2 = @s2
|
25
|
-
@q3 = @s2
|
26
|
-
@q4 = @s3
|
18
|
+
@survey = Factory(:survey, :title => "Foo")
|
19
|
+
@s1 = Factory(:survey_section, :survey => @survey, :title => "wise", :display_order => 2)
|
20
|
+
@s2 = Factory(:survey_section, :survey => @survey, :title => "er", :display_order => 3)
|
21
|
+
@s3 = Factory(:survey_section, :survey => @survey, :title => "bud", :display_order => 1)
|
22
|
+
@q1 = Factory(:question, :survey_section => @s1, :text => "what is wise?", :display_order => 2)
|
23
|
+
@q2 = Factory(:question, :survey_section => @s2, :text => "what is er?", :display_order => 4)
|
24
|
+
@q3 = Factory(:question, :survey_section => @s2, :text => "what is mill?", :display_order => 3)
|
25
|
+
@q4 = Factory(:question, :survey_section => @s3, :text => "what is bud?", :display_order => 1)
|
27
26
|
end
|
28
27
|
|
29
28
|
it "should return survey_sections in display order" do
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe ValidationCondition, "Class methods" do
|
4
|
+
it "should have a list of operators" do
|
5
|
+
%w(== != < > <= >= =~).each{|operator| ValidationCondition.operators.include?(operator).should be_true }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ValidationCondition do
|
10
|
+
before(:each) do
|
11
|
+
@validation_condition = Factory(:validation_condition)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be valid" do
|
15
|
+
@validation_condition.should be_valid
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be invalid without a parent validation_id" do
|
19
|
+
@validation_condition.validation_id = nil
|
20
|
+
@validation_condition.should have(1).errors_on(:validation_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be invalid without an operator" do
|
24
|
+
@validation_condition.operator = nil
|
25
|
+
@validation_condition.should have(2).errors_on(:operator)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be invalid without a rule_key" do
|
29
|
+
@validation_condition.should be_valid
|
30
|
+
@validation_condition.rule_key = nil
|
31
|
+
@validation_condition.should_not be_valid
|
32
|
+
@validation_condition.should have(1).errors_on(:rule_key)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should have unique rule_key within the context of a validation" do
|
36
|
+
@validation_condition.should be_valid
|
37
|
+
Factory(:validation_condition, :validation_id => 2, :rule_key => "2")
|
38
|
+
@validation_condition.rule_key = "2" #rule key uniquness is scoped by validation_id
|
39
|
+
@validation_condition.validation_id = 2
|
40
|
+
@validation_condition.should_not be_valid
|
41
|
+
@validation_condition.should have(1).errors_on(:rule_key)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have an operator in ValidationCondition.operators" do
|
45
|
+
ValidationCondition.operators.each do |o|
|
46
|
+
@validation_condition.operator = o
|
47
|
+
@validation_condition.should have(0).errors_on(:operator)
|
48
|
+
end
|
49
|
+
@validation_condition.operator = "#"
|
50
|
+
@validation_condition.should have(1).error_on(:operator)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Validation do
|
4
|
+
before(:each) do
|
5
|
+
@validation = Factory(:validation)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be valid" do
|
9
|
+
@validation.should be_valid
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be invalid without a rule" do
|
13
|
+
@validation.rule = nil
|
14
|
+
@validation.should have(2).errors_on(:rule)
|
15
|
+
@validation.rule = " "
|
16
|
+
@validation.should have(1).errors_on(:rule)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be invalid without a answer_id" do
|
20
|
+
@validation.answer_id = nil
|
21
|
+
@validation.should have(1).error_on(:answer_id)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be invalid unless rule composed of only references and operators" do
|
25
|
+
@validation.rule = "foo"
|
26
|
+
@validation.should have(1).error_on(:rule)
|
27
|
+
@validation.rule = "1 to 2"
|
28
|
+
@validation.should have(1).error_on(:rule)
|
29
|
+
@validation.rule = "a and b"
|
30
|
+
@validation.should have(1).error_on(:rule)
|
31
|
+
end
|
32
|
+
end
|