active_record_survey 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 89488bc6129619788df343d2782e6e5789b63ea9
4
- data.tar.gz: 734de7ad575ef2049f491cc289ddfc798e7f4c30
3
+ metadata.gz: cc0440e0c23ed5d966185f62fe83619c7d50fa01
4
+ data.tar.gz: b0e93efb11a6994878ce6c3d5d948043525125a3
5
5
  SHA512:
6
- metadata.gz: 5c5dd82b54caf2511537e2b3261ff0f90329241500fa4ebe3c83830486e5b3a626ae149a5d59cc9477dbb3a97cde32072f48e85258dc3ff76dd95e284b7dc424
7
- data.tar.gz: bbd6dd35bd48ba070e2379ee38a1360fbbaf5e7e027f73c6f10607104d3b2b9886966d423e31ed9772fd84013d1f0794c5a7a504fa184fc996d58c6ed0e71d09
6
+ metadata.gz: 81b0ea583a5d440eddb185547a584dcf471d8f1618a4f8a0e80406882d7a866c5391851e9eb962f28a90f6308bd3c2aba0c30891b700e28a9737acf19fc04f1e
7
+ data.tar.gz: 64b747965c5c7bcefe1753f4518f5f4dcbf5279339c459ed1c60a64d854854f77f88ba12410cbd76bb8fd02da05d671fdf1098405405c82384fe19d750eefad8
@@ -15,12 +15,18 @@ module ActiveRecordSurvey
15
15
  # Two instance_nodes on the same node for this instance
16
16
  if self.instance.instance_nodes.select { |i|
17
17
  # Two votes share a parent (this means a question has two answers for this instance)
18
- (i.node.node_maps.collect { |j| j.parent } & self.node.node_maps.collect { |j| j.parent }).length > 0
18
+ (i.node.node_maps.collect { |j|
19
+ j.parent
20
+ } & self.node.node_maps.collect { |j|
21
+ j.parent
22
+ }).length > 0
19
23
  }.length > 1
20
24
  instance_node.errors[:base] << "DUPLICATE_PATH"
21
25
  end
22
26
 
23
- instance_node.errors[:base] << "INVALID" if !self.node.validate_instance_node(self)
27
+ if !self.node.validate_instance_node(self)
28
+ instance_node.errors[:base] << "INVALID"
29
+ end
24
30
  end
25
31
  end
26
32
  end
@@ -7,5 +7,13 @@ module ActiveRecordSurvey
7
7
  super &&
8
8
  !instance_node.value.to_s.match(/^[0|1]$/).nil?
9
9
  end
10
+
11
+ # Boolean answers are considered answered if they have a value of "1"
12
+ def is_answered_for_instance?(instance)
13
+ if instance_node = self.instance_node_for_instance(instance)
14
+ # Instance node is answered "1"
15
+ (instance_node.value.to_i === 1)
16
+ end
17
+ end
10
18
  end
11
19
  end
@@ -1,4 +1,12 @@
1
1
  module ActiveRecordSurvey
2
2
  class Node::Answer < Node
3
+ # Answer nodes are valid if their questions are valid!
4
+ # Validate this node against an instance
5
+ def validate_node(instance)
6
+ # Ensure each parent node to this node (the goal here is to hit a question node) is valid
7
+ !self.node_maps.collect { |node_map|
8
+ node_map.parent.node.validate_node(instance)
9
+ }.include?(false)
10
+ end
3
11
  end
4
12
  end
@@ -2,12 +2,48 @@ module ActiveRecordSurvey
2
2
  class Node < ::ActiveRecord::Base
3
3
  self.table_name = "active_record_survey_nodes"
4
4
  has_many :node_maps, :class_name => "ActiveRecordSurvey::NodeMap", :foreign_key => :active_record_survey_node_id
5
- has_many :node_validations, :class_name => "ActiveRecordSurvey::NodeValidation", :foreign_key => :active_record_survey_node_id
5
+ has_many :node_validations, :class_name => "ActiveRecordSurvey::NodeValidation", :foreign_key => :active_record_survey_node_id, autosave: true
6
+ has_many :instance_nodes, :class_name => "ActiveRecordSurvey::InstanceNode", :foreign_key => :active_record_survey_node_id
6
7
 
7
- # By default all values are accepted
8
+ # The instance_node recorded for the passed instance for this node
9
+ def instance_node_for_instance(instance)
10
+ instance.instance_nodes.select { |instance_node|
11
+ (instance_node.node === self)
12
+ }.first
13
+ end
14
+
15
+ # Whether this node has an answer recorded the instance
16
+ def has_instance_node_for_instance?(instance)
17
+ !self.instance_node_for_instance(instance).nil?
18
+ end
19
+
20
+ # Whether considered answered for instance
21
+ #
22
+ # Is answered is a little different than has_answer
23
+ # Is answered is answer type specific, as what constitutes "answered" changes depending on
24
+ # the question type asked (e.g. boolean is answered if "1")
25
+ #
26
+ # Each specific answer type should override this method if they have special criteria for answered
27
+ #
28
+ # default - if instance node exists, answered
29
+ def is_answered_for_instance?(instance)
30
+ self.has_instance_node_for_instance?(instance)
31
+ end
32
+
33
+ # Run all validations applied to this node
8
34
  def validate_instance_node(instance_node)
35
+ # UGH - so bsaically this validation doesn't know about the non-saved validation..
36
+ #puts "Valdating #{self.id} - #{self.text} - total validations are - #{self.node_validations(true).length}"
9
37
  !self.node_validations.collect { |node_validation|
10
38
  node_validation.validate_instance_node(instance_node, self)
39
+ }.include?(false) &&
40
+ !self.node_maps.collect { |node_map|
41
+ if node_map.parent
42
+ node_map.parent.node.validate_instance_node(instance_node)
43
+ # Hit top node
44
+ else
45
+ true
46
+ end
11
47
  }.include?(false)
12
48
  end
13
49
 
@@ -22,5 +22,16 @@ module ActiveRecordSurvey
22
22
  }
23
23
  }
24
24
  end
25
+
26
+ # Gets all the child nodes until one is not an ancestor of klass
27
+ def children_until_node_not_ancestor_of(klass)
28
+ if !self.node.class.ancestors.include?(klass)
29
+ return []
30
+ end
31
+
32
+ [self] + self.children.collect { |i|
33
+ i.children_until_node_not_ancestor_of(klass)
34
+ }
35
+ end
25
36
  end
26
37
  end
@@ -2,9 +2,28 @@ module ActiveRecordSurvey
2
2
  # Ensure the a maximum number of answers are made
3
3
  class NodeValidation::MaximumAnswer < NodeValidation
4
4
  # Validate the instance_node to ensure a maximum number of answers are made
5
- def validate_instance_node(instance_node, node = nil)
6
- !instance_node.value.to_s.empty? &&
7
- instance_node.value.to_f >= self.value.to_f
5
+ def validate_instance_node(instance_node, question_node = nil)
6
+ #puts "-------------------------------------------"
7
+ #puts "runnin min answer validation"
8
+
9
+ # Only makes sense for questions to have minimum answers
10
+ if !question_node.class.ancestors.include?(::ActiveRecordSurvey::Node::Question)
11
+ return false
12
+ end
13
+
14
+ instance = instance_node.instance
15
+
16
+ # Go through the node_map of this node
17
+ total_answered = question_node.node_maps.collect { |question_node_map|
18
+ # Get all children until a childs node isn't an answer
19
+ question_node_map.children.collect { |i|
20
+ i.children_until_node_not_ancestor_of(::ActiveRecordSurvey::Node::Answer)
21
+ }.flatten.collect { |i|
22
+ i.node.is_answered_for_instance?(instance)
23
+ }
24
+ }.flatten.select { |i| i }.count
25
+
26
+ total_answered <= self.value.to_i
8
27
  end
9
28
  end
10
29
  end
@@ -2,9 +2,28 @@ module ActiveRecordSurvey
2
2
  # Ensure the a minimum number of answers are made
3
3
  class NodeValidation::MinimumAnswer < NodeValidation
4
4
  # Validate the instance_node to ensure a minimum number of answers are made
5
- def validate_instance_node(instance_node, node = nil)
6
- !instance_node.value.to_s.empty? &&
7
- instance_node.value.to_f >= self.value.to_f
5
+ def validate_instance_node(instance_node, question_node = nil)
6
+ #puts "-------------------------------------------"
7
+ #puts "runnin min answer validation"
8
+
9
+ # Only makes sense for questions to have minimum answers
10
+ if !question_node.class.ancestors.include?(::ActiveRecordSurvey::Node::Question)
11
+ return false
12
+ end
13
+
14
+ instance = instance_node.instance
15
+
16
+ # Go through the node_map of this node
17
+ total_answered = question_node.node_maps.collect { |question_node_map|
18
+ # Get all children until a childs node isn't an answer
19
+ question_node_map.children.collect { |i|
20
+ i.children_until_node_not_ancestor_of(::ActiveRecordSurvey::Node::Answer)
21
+ }.flatten.collect { |i|
22
+ i.node.is_answered_for_instance?(instance)
23
+ }
24
+ }.flatten.select { |i| i }.count
25
+
26
+ total_answered >= self.value.to_i
8
27
  end
9
28
  end
10
29
  end
@@ -5,8 +5,12 @@ module ActiveRecordSurvey
5
5
  belongs_to :node, :class_name => "ActiveRecordSurvey::Node", :foreign_key => :active_record_survey_node_id
6
6
 
7
7
  # By default everything is valid! WOOO!
8
- def validate_instance_node(instance_node, node = nil)
8
+ def validate_instance_node(instance_node)
9
9
  true
10
10
  end
11
+
12
+ def validate_node(instance_node, node)
13
+ #code
14
+ end
11
15
  end
12
16
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordSurvey
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -1,18 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveRecordSurvey::Node::Answer::Boolean do
3
+ describe ActiveRecordSurvey::Node::Answer::Boolean, :focus => true do
4
4
  describe 'a boolean survey is' do
5
5
  before(:all) do
6
6
  @survey = ActiveRecordSurvey::Survey.new
7
7
 
8
- @q1 = ActiveRecordSurvey::Node::Question.new(:text => "Please select one")
8
+ @q1 = ActiveRecordSurvey::Node::Question.new(:text => "Please select two")
9
9
  @q1_a1 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Dog")
10
10
  @q1_a2 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Cat")
11
11
  @q1_a3 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Mouse")
12
+ @q1_a4 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Tiger")
13
+ @q1_a5 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Bear")
12
14
 
13
15
  nodes = @survey.build_question(@q1, [@q1_a1])
14
16
  nodes = @survey.build_question(@q1_a2, [], nodes[1])
15
17
  nodes = @survey.build_question(@q1_a3, [], nodes[0])
18
+ nodes = @survey.build_question(@q1_a4, [], nodes[0])
19
+ nodes = @survey.build_question(@q1_a5, [], nodes[0])
20
+
21
+ @q1.node_validations << ActiveRecordSurvey::NodeValidation::MinimumAnswer.new(
22
+ :node => @q1,
23
+ :value => 1 # min 1 of the 3 answers must be "answered"
24
+ )
25
+ @q1.node_validations << ActiveRecordSurvey::NodeValidation::MaximumAnswer.new(
26
+ :node => @q1,
27
+ :value => 3 # max 2 of the 3 answers must be "answered"
28
+ )
16
29
 
17
30
  @survey.save
18
31
  end
@@ -37,6 +50,11 @@ describe ActiveRecordSurvey::Node::Answer::Boolean do
37
50
  :node => @q1_a1,
38
51
  :value => 0
39
52
  )
53
+ instance.instance_nodes.build(
54
+ :instance => instance,
55
+ :node => @q1_a2,
56
+ :value => 1
57
+ )
40
58
  instance.save
41
59
 
42
60
  expect(instance.valid?).to be(true)
@@ -94,40 +112,122 @@ describe ActiveRecordSurvey::Node::Answer::Boolean do
94
112
  describe ActiveRecordSurvey::NodeValidation::MinimumAnswer do
95
113
  describe 'valid when' do
96
114
  it 'has a value greater than the minimum' do
97
- @q1.node_validations << ActiveRecordSurvey::NodeValidation::MinimumAnswer.new(
98
- :node => @q1,
99
- :value => 2 # 2 of the 3 answers must be "answered"
100
- )
101
115
  instance = ActiveRecordSurvey::Instance.new(:survey => @survey)
102
116
  instance.instance_nodes.build(
103
117
  :instance => instance,
104
118
  :node => @q1_a1,
105
- :value => "this is greater than minimum length",
119
+ :value => 1,
120
+ )
121
+ instance.instance_nodes.build(
122
+ :instance => instance,
123
+ :node => @q1_a2,
124
+ :value => 0,
125
+ )
126
+ instance.instance_nodes.build(
127
+ :instance => instance,
128
+ :node => @q1_a3,
129
+ :value => 1,
106
130
  )
107
131
  instance.save
108
132
 
109
- #expect(instance.valid?).to be(true)
133
+ expect(instance.valid?).to be(true)
110
134
  end
111
135
  end
112
- =begin
136
+
113
137
  describe 'invalid when' do
114
138
  it 'has a value less than the minimum' do
115
- @q1_a1.node_validations << ActiveRecordSurvey::NodeValidation::MinimumLength.new(
139
+ instance = ActiveRecordSurvey::Instance.new(:survey => @survey)
140
+ instance.instance_nodes.build(
141
+ :instance => instance,
116
142
  :node => @q1_a1,
117
- :value => 3
143
+ :value => 0,
118
144
  )
145
+ instance.instance_nodes.build(
146
+ :instance => instance,
147
+ :node => @q1_a2,
148
+ :value => 0,
149
+ )
150
+ instance.instance_nodes.build(
151
+ :instance => instance,
152
+ :node => @q1_a3,
153
+ :value => 0,
154
+ )
155
+ instance.save
156
+
157
+ expect(instance.valid?).to be(false)
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ describe ActiveRecordSurvey::NodeValidation::MaximumAnswer do
164
+ describe 'valid when' do
165
+ it 'has a value less than the maximum' do
119
166
  instance = ActiveRecordSurvey::Instance.new(:survey => @survey)
120
167
  instance.instance_nodes.build(
121
168
  :instance => instance,
122
169
  :node => @q1_a1,
123
- :value => "12",
170
+ :value => 1,
171
+ )
172
+ instance.instance_nodes.build(
173
+ :instance => instance,
174
+ :node => @q1_a2,
175
+ :value => 0,
176
+ )
177
+ instance.instance_nodes.build(
178
+ :instance => instance,
179
+ :node => @q1_a3,
180
+ :value => 1,
181
+ )
182
+ instance.instance_nodes.build(
183
+ :instance => instance,
184
+ :node => @q1_a4,
185
+ :value => 1,
186
+ )
187
+ instance.instance_nodes.build(
188
+ :instance => instance,
189
+ :node => @q1_a5,
190
+ :value => 0,
124
191
  )
125
192
  instance.save
193
+
194
+ expect(instance.valid?).to be(true)
195
+ end
196
+ end
126
197
 
198
+ describe 'invalid when' do
199
+ it 'has a value greater than the maximum' do
200
+ instance = ActiveRecordSurvey::Instance.new(:survey => @survey)
201
+ instance.instance_nodes.build(
202
+ :instance => instance,
203
+ :node => @q1_a1,
204
+ :value => 1,
205
+ )
206
+ instance.instance_nodes.build(
207
+ :instance => instance,
208
+ :node => @q1_a2,
209
+ :value => 1,
210
+ )
211
+ instance.instance_nodes.build(
212
+ :instance => instance,
213
+ :node => @q1_a3,
214
+ :value => 1,
215
+ )
216
+ instance.instance_nodes.build(
217
+ :instance => instance,
218
+ :node => @q1_a4,
219
+ :value => 1,
220
+ )
221
+ instance.instance_nodes.build(
222
+ :instance => instance,
223
+ :node => @q1_a5,
224
+ :value => 1,
225
+ )
226
+ instance.save
227
+
127
228
  expect(instance.valid?).to be(false)
128
229
  end
129
230
  end
130
- =end
131
231
  end
132
232
  end
133
233
  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.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Butch Marshall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-25 00:00:00.000000000 Z
11
+ date: 2015-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord