active_record_survey 0.1.39 → 0.1.40
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.
- checksums.yaml +4 -4
- data/lib/active_record_survey/instance_node.rb +24 -19
- data/lib/active_record_survey/node.rb +8 -1
- data/lib/active_record_survey/version.rb +1 -1
- data/spec/active_record_survey/instance_node_spec.rb +5 -0
- data/spec/active_record_survey/instance_spec.rb +93 -0
- data/spec/active_record_survey/node/answer_spec.rb +15 -0
- data/spec/factories/active_record_survey/survey.rb +75 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ec49942bdb8de3f5ea1c79c524a7756c0c23ca5
|
4
|
+
data.tar.gz: 4a951bb87e0f5b9990eb1b6648fe41652a18426e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4095f4b2118338abeed4e6a9c69f134479491ff45af9b997a8389b7f6562df34318c0b0ce842217599c1b43128e108c083ca57421de52723e5d4fe360554bba1
|
7
|
+
data.tar.gz: 57dcd1b8f5c50ccfcb43d551fb6d6ae0414f6f39cfd1527418dfe761ddc4ba50721c26e0ff257ff83bc1744c2d4e20ce8e881a9f0358ab95315a2579838c0edf
|
@@ -7,28 +7,33 @@ module ActiveRecordSurvey
|
|
7
7
|
validates_presence_of :instance
|
8
8
|
|
9
9
|
validate do |instance_node|
|
10
|
-
#
|
11
|
-
if
|
12
|
-
instance_node.errors[:base] << "
|
13
|
-
|
10
|
+
# No node to begin with!
|
11
|
+
if self.node.nil?
|
12
|
+
instance_node.errors[:base] << "INVALID_NODE"
|
13
|
+
else
|
14
|
+
# This instance_node has no valid path to the root node
|
15
|
+
if !self.node.instance_node_path_to_root?(self)
|
16
|
+
instance_node.errors[:base] << "INVALID_PATH"
|
17
|
+
end
|
14
18
|
|
15
|
-
|
19
|
+
parent_nodes = self.node.survey.node_maps.select { |i| i.node == self.node }.collect { |j| j.parent }
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
# Two instance_nodes on the same node for this instance
|
22
|
+
if self.instance.instance_nodes.select { |i|
|
23
|
+
# We don't care about paths that are going to be deleted
|
24
|
+
!i.marked_for_destruction?
|
25
|
+
}.select { |i|
|
26
|
+
# And the two arrays
|
27
|
+
# Two votes share a parent (this means a question has two answers for this instance)
|
28
|
+
(i.node.survey.node_maps.select { |j| i.node == j.node }.collect { |j| j.parent } & parent_nodes).length > 0
|
29
|
+
}.length > 1
|
30
|
+
instance_node.errors[:base] << "DUPLICATE_PATH"
|
31
|
+
end
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
# Validate against the associated node
|
34
|
+
if !self.node.validate_instance_node(self)
|
35
|
+
instance_node.errors[:base] << "INVALID"
|
36
|
+
end
|
32
37
|
end
|
33
38
|
end
|
34
39
|
end
|
@@ -92,7 +92,7 @@ module ActiveRecordSurvey
|
|
92
92
|
|
93
93
|
# Whether there is a valid answer path from this node to the root node for the instance
|
94
94
|
def instance_node_path_to_root?(instance_node)
|
95
|
-
instance_nodes = instance_node.instance.instance_nodes.select { |i| i.node
|
95
|
+
instance_nodes = instance_node.instance.instance_nodes.select { |i| i.node == self }
|
96
96
|
|
97
97
|
# if ::ActiveRecordSurvey::Node::Answer but no votes, not a valid path
|
98
98
|
if self.class.ancestors.include?(::ActiveRecordSurvey::Node::Answer) &&
|
@@ -100,6 +100,13 @@ module ActiveRecordSurvey
|
|
100
100
|
return false
|
101
101
|
end
|
102
102
|
|
103
|
+
# if ::ActiveRecordSurvey::Node::Question but no answers, so needs at least one vote directly on itself
|
104
|
+
if self.class.ancestors.include?(::ActiveRecordSurvey::Node::Question) &&
|
105
|
+
(self.answers.length === 0) &&
|
106
|
+
(instance_nodes.length === 0)
|
107
|
+
return false
|
108
|
+
end
|
109
|
+
|
103
110
|
# Start at each node_map of this node
|
104
111
|
# Find the parent node ma
|
105
112
|
paths = self.survey.node_maps.select { |i| i.node == self }.collect { |node_map|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveRecordSurvey::Instance, :instance_spec => true do
|
4
|
+
before(:each) do
|
5
|
+
@survey = FactoryGirl.build(:boolean_survey)
|
6
|
+
@survey.save
|
7
|
+
|
8
|
+
@survey.questions.each { |q|
|
9
|
+
@q1 = q if q.text == "Q1"
|
10
|
+
@q2 = q if q.text == "Q2"
|
11
|
+
@q3 = q if q.text == "Q3"
|
12
|
+
@q4 = q if q.text == "Q4"
|
13
|
+
@q5 = q if q.text == "Q5"
|
14
|
+
}
|
15
|
+
|
16
|
+
@q1.answers.each { |a|
|
17
|
+
@q1_a1 = a if a.text == "Q1 A1"
|
18
|
+
@q1_a2 = a if a.text == "Q1 A2"
|
19
|
+
}
|
20
|
+
@q2.answers.each { |a|
|
21
|
+
@q2_a1 = a if a.text == "Q2 A1"
|
22
|
+
@q2_a2 = a if a.text == "Q2 A2"
|
23
|
+
}
|
24
|
+
@q3.answers.each { |a|
|
25
|
+
@q3_a1 = a if a.text == "Q3 A1"
|
26
|
+
@q3_a2 = a if a.text == "Q3 A2"
|
27
|
+
}
|
28
|
+
@q4.answers.each { |a|
|
29
|
+
@q4_a1 = a if a.text == "Q4 A1"
|
30
|
+
@q4_a2 = a if a.text == "Q4 A2"
|
31
|
+
}
|
32
|
+
@instance = ActiveRecordSurvey::Instance.new(:survey => @survey)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#invalid?" do
|
36
|
+
it 'should not allow not starting from the root' do
|
37
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q3_a1)
|
38
|
+
|
39
|
+
expect(@instance.invalid?).to eq(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should not allow impossible answers' do
|
43
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q1_a1)
|
44
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q3_a1)
|
45
|
+
|
46
|
+
expect(@instance.invalid?).to eq(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should fail when boolean answer is not passed an value of [0,1]' do
|
50
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q1_a1)
|
51
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a1)
|
52
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a2)
|
53
|
+
|
54
|
+
expect(@instance.invalid?).to eq(true)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should allow an incompleted survey, even if a missing part is a question node only' do
|
58
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q1_a1)
|
59
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a1, :value => 1)
|
60
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a2, :value => 0)
|
61
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q3_a1)
|
62
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q5)
|
63
|
+
|
64
|
+
expect(@instance.invalid?).to eq(true)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#valid?" do
|
69
|
+
it 'should allow a single answer' do
|
70
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q1_a1)
|
71
|
+
|
72
|
+
expect(@instance.valid?).to eq(true)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should allow multiple answers' do
|
76
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q1_a1)
|
77
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a1, :value => 0)
|
78
|
+
|
79
|
+
expect(@instance.valid?).to eq(true)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should allow a completed survey' do
|
83
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q1_a1)
|
84
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a1, :value => 1)
|
85
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q2_a2, :value => 0)
|
86
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q3_a1)
|
87
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q4)
|
88
|
+
@instance.instance_nodes << ActiveRecordSurvey::InstanceNode.new(:instance => @instance, :node => @q5)
|
89
|
+
|
90
|
+
expect(@instance.valid?).to eq(true)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -345,6 +345,21 @@ describe ActiveRecordSurvey::Node::Answer, :answer_spec => true do
|
|
345
345
|
end
|
346
346
|
|
347
347
|
describe '#next_question' do
|
348
|
+
it 'should not have a next question if not linked anywhere' do
|
349
|
+
survey = FactoryGirl.build(:survey1)
|
350
|
+
survey.save
|
351
|
+
|
352
|
+
q2 = survey.questions.select { |i|
|
353
|
+
i.text == "Question #2"
|
354
|
+
}.first
|
355
|
+
|
356
|
+
q2_a1 = q2.answers.select { |i|
|
357
|
+
i.text == "Q2 Answer #1"
|
358
|
+
}.first
|
359
|
+
|
360
|
+
expect(q2_a1.next_question).to be(nil)
|
361
|
+
end
|
362
|
+
|
348
363
|
it 'should get the next question' do
|
349
364
|
expected = {
|
350
365
|
"Q1" => {
|
@@ -1,5 +1,72 @@
|
|
1
1
|
module FactoryGirlSurveyHelpers
|
2
2
|
extend self
|
3
|
+
def build_survey1(survey)
|
4
|
+
q1 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #1", :survey => survey)
|
5
|
+
q1_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #1")
|
6
|
+
q1_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #2")
|
7
|
+
q1.build_answer(q1_a1)
|
8
|
+
q1.build_answer(q1_a2)
|
9
|
+
|
10
|
+
q2 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #2", :survey => survey)
|
11
|
+
q2_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q2 Answer #1")
|
12
|
+
q2_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q2 Answer #2")
|
13
|
+
q2.build_answer(q2_a1)
|
14
|
+
q2.build_answer(q2_a2)
|
15
|
+
|
16
|
+
q3 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #3", :survey => survey)
|
17
|
+
q3_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q3 Answer #1")
|
18
|
+
q3_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q3 Answer #2")
|
19
|
+
q3.build_answer(q3_a1)
|
20
|
+
q3.build_answer(q3_a2)
|
21
|
+
|
22
|
+
q4 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #4", :survey => survey)
|
23
|
+
|
24
|
+
q5 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #5", :survey => survey)
|
25
|
+
|
26
|
+
q1_a1.build_link(q2)
|
27
|
+
q1_a2.build_link(q3)
|
28
|
+
q2_a2.build_link(q3)
|
29
|
+
|
30
|
+
q3_a1.build_link(q4)
|
31
|
+
q3_a2.build_link(q4)
|
32
|
+
|
33
|
+
q4.build_link(q5)
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_boolean_survey(survey)
|
37
|
+
q1 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Q1", :survey => survey)
|
38
|
+
q1_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 A1")
|
39
|
+
q1_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 A2")
|
40
|
+
q1.build_answer(q1_a1)
|
41
|
+
q1.build_answer(q1_a2)
|
42
|
+
|
43
|
+
q2 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Q2", :survey => survey)
|
44
|
+
q2_a1 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Q2 A1")
|
45
|
+
q2_a2 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Q2 A2")
|
46
|
+
q2.build_answer(q2_a1)
|
47
|
+
q2.build_answer(q2_a2)
|
48
|
+
|
49
|
+
q3 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Q3", :survey => survey)
|
50
|
+
q3_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q3 A1")
|
51
|
+
q3_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q3 A2")
|
52
|
+
q3.build_answer(q3_a1)
|
53
|
+
q3.build_answer(q3_a2)
|
54
|
+
|
55
|
+
q4 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Q4", :survey => survey)
|
56
|
+
|
57
|
+
q5 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Q5", :survey => survey)
|
58
|
+
|
59
|
+
q1_a1.build_link(q2)
|
60
|
+
q1_a2.build_link(q3)
|
61
|
+
|
62
|
+
q2_a2.build_link(q3)
|
63
|
+
|
64
|
+
q3_a1.build_link(q4)
|
65
|
+
q3_a2.build_link(q4)
|
66
|
+
|
67
|
+
q4.build_link(q5)
|
68
|
+
end
|
69
|
+
|
3
70
|
def build_simple_survey(survey)
|
4
71
|
q1 = survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #1", :survey => survey)
|
5
72
|
q1_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #1")
|
@@ -106,6 +173,10 @@ FactoryGirl.define do
|
|
106
173
|
|
107
174
|
end
|
108
175
|
|
176
|
+
factory :survey1, parent: :survey do |f|
|
177
|
+
after(:build) { |survey| FactoryGirlSurveyHelpers.build_survey1(survey) }
|
178
|
+
end
|
179
|
+
|
109
180
|
factory :simple_survey, parent: :survey do |f|
|
110
181
|
after(:build) { |survey| FactoryGirlSurveyHelpers.build_simple_survey(survey) }
|
111
182
|
end
|
@@ -113,4 +184,8 @@ FactoryGirl.define do
|
|
113
184
|
factory :basic_survey, parent: :survey do |f|
|
114
185
|
after(:build) { |survey| FactoryGirlSurveyHelpers.build_basic_survey(survey) }
|
115
186
|
end
|
187
|
+
|
188
|
+
factory :boolean_survey, parent: :survey do |f|
|
189
|
+
after(:build) { |survey| FactoryGirlSurveyHelpers.build_boolean_survey(survey) }
|
190
|
+
end
|
116
191
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_survey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.40
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Butch Marshall
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -163,6 +163,8 @@ files:
|
|
163
163
|
- lib/generators/active_record_survey/templates/migration_0.1.0.rb
|
164
164
|
- lib/generators/active_record_survey/templates/migration_0.1.26.rb
|
165
165
|
- rspec_rvm
|
166
|
+
- spec/active_record_survey/instance_node_spec.rb
|
167
|
+
- spec/active_record_survey/instance_spec.rb
|
166
168
|
- spec/active_record_survey/node/answer/boolean_spec.rb
|
167
169
|
- spec/active_record_survey/node/answer/rank_spec.rb
|
168
170
|
- spec/active_record_survey/node/answer/scale_spec.rb
|
@@ -199,6 +201,8 @@ signing_key:
|
|
199
201
|
specification_version: 4
|
200
202
|
summary: Surveys using activerecord
|
201
203
|
test_files:
|
204
|
+
- spec/active_record_survey/instance_node_spec.rb
|
205
|
+
- spec/active_record_survey/instance_spec.rb
|
202
206
|
- spec/active_record_survey/node/answer/boolean_spec.rb
|
203
207
|
- spec/active_record_survey/node/answer/rank_spec.rb
|
204
208
|
- spec/active_record_survey/node/answer/scale_spec.rb
|