active_record_survey 0.1.5 → 0.1.6

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 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