surveyor 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/tasks/surveyor_tasks.rake +1 -1
- data/script/surveyor/answer.rb +47 -45
- data/script/surveyor/base.rb +6 -6
- data/script/surveyor/dependency.rb +10 -8
- data/script/surveyor/dependency_condition.rb +32 -30
- data/script/surveyor/parser.rb +187 -0
- data/script/surveyor/question.rb +31 -29
- data/script/surveyor/question_group.rb +22 -20
- data/script/surveyor/specs/answer_spec.rb +4 -4
- data/script/surveyor/specs/question_spec.rb +10 -10
- data/script/surveyor/specs/spec_helper.rb +1 -0
- data/script/surveyor/specs/survey_section_spec.rb +5 -5
- data/script/surveyor/specs/validation_condition_spec.rb +4 -4
- data/script/surveyor/specs/validation_spec.rb +4 -4
- data/script/surveyor/survey.rb +29 -27
- data/script/surveyor/survey_section.rb +17 -15
- data/script/surveyor/validation.rb +16 -14
- data/script/surveyor/validation_condition.rb +18 -16
- data/spec/factories.rb +1 -1
- data/surveyor.gemspec +2 -2
- metadata +2 -2
- data/script/surveyor/survey_parser.rb +0 -186
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.2
|
@@ -11,7 +11,7 @@ namespace :surveyor do
|
|
11
11
|
raise "USAGE: file name required e.g. 'FILE=surveys/kitchen_sink_survey.rb'" if ENV["FILE"].blank?
|
12
12
|
fixture_dir = File.join(RAILS_ROOT, "surveys", "fixtures")
|
13
13
|
mkdir fixture_dir unless File.exists?(fixture_dir)
|
14
|
-
SurveyParser.parse(File.join(RAILS_ROOT, ENV["FILE"]))
|
14
|
+
SurveyParser::Parser.parse(File.join(RAILS_ROOT, ENV["FILE"]))
|
15
15
|
end
|
16
16
|
|
17
17
|
desc "load survey fixtures"
|
data/script/surveyor/answer.rb
CHANGED
@@ -1,52 +1,54 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class Answer < SurveyParser::Base
|
3
|
+
# Context, Content, Reference, Display
|
4
|
+
attr_accessor :id, :parser, :question_id
|
5
|
+
attr_accessor :text, :short_text, :help_text, :weight, :response_class
|
6
|
+
attr_accessor :reference_identifier, :data_export_identifier, :common_namespace, :common_identitier
|
7
|
+
attr_accessor :display_order, :is_exclusive, :hide_label, :display_length, :custom_class, :custom_renderer
|
8
|
+
attr_accessor :validation
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def default_options
|
11
|
+
{ :is_exclusive => false,
|
12
|
+
:hide_label => false,
|
13
|
+
:response_class => "answer"
|
14
|
+
}
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
def parse_args(args)
|
18
|
+
case args[0]
|
19
|
+
when Hash # Hash
|
20
|
+
text_args(args[0][:text]).merge(args[0])
|
21
|
+
when String # (String, Hash) or (String, Symbol, Hash)
|
22
|
+
text_args(args[0]).merge(hash_from args[1]).merge(args[2] || {})
|
23
|
+
when Symbol # (Symbol, Hash) or (Symbol, Symbol, Hash)
|
24
|
+
symbol_args(args[0]).merge(hash_from args[1]).merge(args[2] || {})
|
25
|
+
else
|
26
|
+
text_args(nil)
|
27
|
+
end
|
26
28
|
end
|
27
|
-
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
def text_args(text = "Answer")
|
31
|
+
{:text => text.to_s, :short_text => text, :data_export_identifier => Surveyor.to_normalized_string(text)}
|
32
|
+
end
|
33
|
+
def hash_from(arg)
|
34
|
+
arg.is_a?(Symbol) ? {:response_class => arg.to_s} : arg.is_a?(Hash) ? arg : {}
|
35
|
+
end
|
36
|
+
def symbol_args(arg)
|
37
|
+
case arg
|
38
|
+
when :other
|
39
|
+
text_args("Other")
|
40
|
+
when :other_and_string
|
41
|
+
text_args("Other").merge({:response_class => "string"})
|
42
|
+
when :none, :omit # is_exclusive erases and disables other checkboxes and input elements
|
43
|
+
text_args(arg.to_s.humanize).merge({:is_exclusive => true})
|
44
|
+
when :integer, :date, :time, :datetime, :text, :datetime, :string
|
45
|
+
text_args(arg.to_s.humanize).merge({:response_class => arg.to_s, :hide_label => true})
|
46
|
+
end
|
47
|
+
end
|
48
|
+
def to_file
|
49
|
+
super
|
50
|
+
if self.validation then self.validation.to_file end
|
45
51
|
end
|
46
|
-
end
|
47
|
-
def to_file
|
48
|
-
super
|
49
|
-
if self.validation then self.validation.to_file end
|
50
|
-
end
|
51
52
|
|
53
|
+
end
|
52
54
|
end
|
data/script/surveyor/base.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module SurveyParser
|
2
2
|
class Base
|
3
3
|
|
4
4
|
# Class level instance variable, because class variable are shared with subclasses
|
@@ -22,17 +22,17 @@ class SurveyParser
|
|
22
22
|
# Instance methods
|
23
23
|
def initialize(obj, args, opts)
|
24
24
|
# inherit the parser from parent (obj)
|
25
|
-
self.parser = (obj.nil? ? nil : obj.class == SurveyParser ? obj : obj.parser)
|
25
|
+
self.parser = (obj.nil? ? nil : obj.class == SurveyParser::Parser ? obj : obj.parser)
|
26
26
|
# get a new id from the parser
|
27
|
-
self.id = parser.nil? ? nil : parser.send("new_#{self.class.name.underscore}_id")
|
27
|
+
self.id = parser.nil? ? nil : parser.send("new_#{self.class.name.demodulize.underscore}_id")
|
28
28
|
# set [parent]_id to obj.id, if we have that attribute
|
29
|
-
self.send("#{obj.class.name.underscore}_id=", obj.nil? ? nil : obj.id) if self.respond_to?("#{obj.class.name.underscore}_id=")
|
29
|
+
self.send("#{obj.class.name.demodulize.underscore}_id=", obj.nil? ? nil : obj.id) if self.respond_to?("#{obj.class.name.demodulize.underscore}_id=")
|
30
30
|
# initialize descendant models
|
31
31
|
self.class.children.each{|model| self.send("#{model}=", [])}
|
32
32
|
# combine default options, parsed opts, parsed args, and initialize instance variables
|
33
33
|
self.default_options.merge(parse_opts(opts)).merge(parse_args(args)).each{|k,v| self.send("#{k.to_s}=", v)}
|
34
34
|
# print to the log
|
35
|
-
print "#{self.class.name.gsub(/[a-z]/, "")[-1,1]}#{self.id} "
|
35
|
+
print "#{self.class.name.demodulize.gsub(/[a-z]/, "")[-1,1]}#{self.id} "
|
36
36
|
end
|
37
37
|
def default_options
|
38
38
|
{}
|
@@ -54,7 +54,7 @@ class SurveyParser
|
|
54
54
|
(out << nil ).join("\r\n")
|
55
55
|
end
|
56
56
|
def to_file
|
57
|
-
File.open(self.parser.send("#{self.class.name.underscore.pluralize}_yml"), File::CREAT|File::APPEND|File::WRONLY) {|f| f << to_yml}
|
57
|
+
File.open(self.parser.send("#{self.class.name.demodulize.underscore.pluralize}_yml"), File::CREAT|File::APPEND|File::WRONLY) {|f| f << to_yml}
|
58
58
|
self.class.children.each{|model| self.send(model).compact.map(&:to_file)}
|
59
59
|
end
|
60
60
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class Dependency < SurveyParser::Base
|
3
|
+
# Context, Conditional, Children
|
4
|
+
attr_accessor :id, :question_id, :question_group_id, :parser
|
5
|
+
attr_accessor :rule
|
6
|
+
has_children :dependency_conditions
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def parse_opts(opts)
|
9
|
+
{} # toss the method name and reference identifier by default
|
10
|
+
end
|
10
11
|
|
12
|
+
end
|
11
13
|
end
|
@@ -1,38 +1,40 @@
|
|
1
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class DependencyCondition < SurveyParser::Base
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# Context, Conditional, Value
|
5
|
+
attr_accessor :id, :dependency_id, :rule_key, :parser
|
6
|
+
attr_accessor :question_id, :operator
|
7
|
+
attr_accessor :answer_id, :datetime_value, :integer_value, :float_value, :unit, :text_value, :string_value, :response_other
|
8
|
+
attr_accessor :question_reference, :answer_reference
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
def default_options
|
11
|
+
{ :operator => "==" }
|
12
|
+
end
|
13
|
+
def parse_args(args)
|
14
|
+
a0, a1, a2 = args
|
15
|
+
{:question_reference => a0.to_s.gsub("q_", ""), :operator => a1}.merge(a2.is_a?(Hash) ? a2 : {:answer_reference => a2.to_s.gsub("a_", "")})
|
16
|
+
end
|
17
|
+
def parse_opts(opts)
|
18
|
+
{:rule_key => opts[:reference_identifier]}
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
def reconcile_dependencies
|
22
|
+
# Looking up references to questions and answers for linking the dependency objects
|
23
|
+
print "Lookup Q ref #{@question_reference}:"
|
24
|
+
if (ref_question = parser.current_survey.find_question_by_reference(@question_reference))
|
25
|
+
print " found Q#{ref_question.id} "
|
26
|
+
@question_id = ref_question.id
|
27
|
+
print "Lookup A ref #{@answer_reference}"
|
28
|
+
if (ref_answer = ref_question.find_answer_by_reference(@answer_reference))
|
29
|
+
print " found A#{ref_answer.id} "
|
30
|
+
@answer_id = ref_answer.id
|
31
|
+
else
|
32
|
+
raise "Could not find referenced answer #{@answer_reference}"
|
33
|
+
end
|
30
34
|
else
|
31
|
-
raise "Could not find referenced
|
35
|
+
raise "Could not find referenced question #{@question_reference}"
|
32
36
|
end
|
33
|
-
else
|
34
|
-
raise "Could not find referenced question #{@question_reference}"
|
35
37
|
end
|
36
|
-
end
|
37
38
|
|
39
|
+
end
|
38
40
|
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'activesupport' # for pluralize, humanize in ActiveSupport::CoreExtensions::String::Inflections
|
2
|
+
module SurveyParser
|
3
|
+
class Parser
|
4
|
+
@@models = %w(survey survey_section question_group question answer dependency dependency_condition validation validation_condition)
|
5
|
+
|
6
|
+
# Require base and all models
|
7
|
+
(%w(base) + @@models).each{|m| require File.dirname(__FILE__) + "/#{m}"}
|
8
|
+
|
9
|
+
# Attributes
|
10
|
+
attr_accessor :surveys, :grid_answers
|
11
|
+
@@models.each{|m| attr_accessor "#{m.pluralize}_yml".to_sym } # for fixtures
|
12
|
+
(@@models - %w(dependency_condition validation_condition)).each {|m| attr_accessor "current_#{m}".to_sym} # for current_model caches
|
13
|
+
|
14
|
+
# Class methods
|
15
|
+
def self.parse(file_name)
|
16
|
+
self.define_counter_methods(@@models)
|
17
|
+
puts "\n--- Parsing '#{file_name}' ---"
|
18
|
+
parser = SurveyParser::Parser.new
|
19
|
+
parser.instance_eval(File.read(file_name))
|
20
|
+
parser.to_files
|
21
|
+
puts "--- End of parsing ---\n\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
# new_survey_id, new_survey_section_id, etc.
|
25
|
+
def self.define_counter_methods(names)
|
26
|
+
names.each do |name|
|
27
|
+
define_method("new_#{name}_id") do
|
28
|
+
instance_variable_set("@last_#{name}_id", instance_variable_get("@last_#{name}_id") + 1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Instance methods
|
34
|
+
def initialize
|
35
|
+
self.surveys = []
|
36
|
+
self.grid_answers = []
|
37
|
+
initialize_counters(@@models)
|
38
|
+
initialize_fixtures(@@models.map(&:pluralize), File.join(RAILS_ROOT, "surveys", "fixtures"))
|
39
|
+
end
|
40
|
+
|
41
|
+
# @last_survey_id, @last_survey_section_id, etc.
|
42
|
+
def initialize_counters(names)
|
43
|
+
names.each{|name| instance_variable_set("@last_#{name}_id", 0)}
|
44
|
+
end
|
45
|
+
|
46
|
+
# @surveys_yml, @survey_sections_yml, etc.
|
47
|
+
def initialize_fixtures(names, path)
|
48
|
+
names.each {|name| file = instance_variable_set("@#{name}_yml", "#{path}/#{name}.yml"); File.truncate(file, 0) if File.exist?(file) }
|
49
|
+
end
|
50
|
+
|
51
|
+
# This method_missing does all the heavy lifting for the DSL
|
52
|
+
def method_missing(missing_method, *args, &block)
|
53
|
+
method_name, reference_identifier = missing_method.to_s.split("_", 2)
|
54
|
+
opts = {:method_name => method_name, :reference_identifier => reference_identifier}
|
55
|
+
case method_name
|
56
|
+
when "survey"
|
57
|
+
self.current_survey = Survey.new(self, args, opts)
|
58
|
+
evaluate_the "survey", &block
|
59
|
+
|
60
|
+
when "section"
|
61
|
+
self.current_survey_section = SurveySection.new(self.current_survey, args, opts.merge({:display_order => current_survey.survey_sections.size + 1}))
|
62
|
+
evaluate_the "survey_section", &block
|
63
|
+
|
64
|
+
when "group", "g", "grid", "repeater"
|
65
|
+
self.current_question_group = QuestionGroup.new(self.current_survey_section, args, opts)
|
66
|
+
evaluate_the "question_group", &block
|
67
|
+
|
68
|
+
when "question", "q", "label", "image"
|
69
|
+
drop_the &block
|
70
|
+
self.current_question = Question.new(self.current_survey_section, args, opts.merge(:question_group_id => current_question_group ? current_question_group.id : nil))
|
71
|
+
add_grid_answers if in_a_grid?
|
72
|
+
|
73
|
+
when "dependency", "d"
|
74
|
+
drop_the &block
|
75
|
+
self.current_dependency = Dependency.new(self.current_question_group || current_question, args, opts)
|
76
|
+
|
77
|
+
when "condition", "c"
|
78
|
+
drop_the &block
|
79
|
+
raise "Error: No current dependency or validation for this condition" if self.current_dependency.nil? && self.current_validation.nil?
|
80
|
+
if self.current_dependency.nil?
|
81
|
+
self.current_validation.validation_conditions << ValidationCondition.new(self.current_validation, args, opts)
|
82
|
+
else
|
83
|
+
self.current_dependency.dependency_conditions << DependencyCondition.new(self.current_dependency, args, opts)
|
84
|
+
end
|
85
|
+
|
86
|
+
when "answer", "a"
|
87
|
+
drop_the &block
|
88
|
+
if in_a_grid?
|
89
|
+
self.grid_answers << Answer.new(nil, args, opts.merge(:display_order => grid_answers.size + 1))
|
90
|
+
else
|
91
|
+
raise "Error: No current question" if self.current_question.nil?
|
92
|
+
self.current_answer = Answer.new(self.current_question, args, opts.merge(:display_order => current_question.answers.size + 1))
|
93
|
+
end
|
94
|
+
|
95
|
+
when "validation", "v"
|
96
|
+
drop_the &block
|
97
|
+
self.current_validation = Validation.new(self.current_answer, args, opts)
|
98
|
+
|
99
|
+
else
|
100
|
+
raise " ERROR: '#{missing_method}' not valid method"
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def drop_the(&block)
|
106
|
+
raise "Error, I'm dropping the block like it's hot" if block_given?
|
107
|
+
end
|
108
|
+
|
109
|
+
def evaluate_the(model, &block)
|
110
|
+
raise "Error: A #{model.humanize} cannot be empty" unless block_given?
|
111
|
+
self.instance_eval(&block)
|
112
|
+
self.send("clear_current", model)
|
113
|
+
end
|
114
|
+
|
115
|
+
def clear_current(model)
|
116
|
+
# puts "clear_current #{model}"
|
117
|
+
case model
|
118
|
+
when "survey"
|
119
|
+
self.current_survey.reconcile_dependencies unless current_survey.nil?
|
120
|
+
when "question_group"
|
121
|
+
self.grid_answers = []
|
122
|
+
clear_current("question")
|
123
|
+
when "question"
|
124
|
+
@current_dependency = nil
|
125
|
+
when "answer"
|
126
|
+
@current_validation = nil
|
127
|
+
end
|
128
|
+
instance_variable_set("@current_#{model}", nil)
|
129
|
+
"SurveyParser::#{model.classify}".constantize.send(:children).each{|m| clear_current(m.to_s.singularize)}
|
130
|
+
end
|
131
|
+
|
132
|
+
def current_survey=(s)
|
133
|
+
clear_current "survey"
|
134
|
+
self.surveys << s
|
135
|
+
@current_survey = s
|
136
|
+
end
|
137
|
+
def current_survey_section=(s)
|
138
|
+
clear_current "survey_section"
|
139
|
+
self.current_survey.survey_sections << s
|
140
|
+
@current_survey_section = s
|
141
|
+
end
|
142
|
+
def current_question_group=(g)
|
143
|
+
clear_current "question_group"
|
144
|
+
self.current_survey_section.question_groups << g
|
145
|
+
@current_question_group = g
|
146
|
+
end
|
147
|
+
def current_question=(q)
|
148
|
+
clear_current "question"
|
149
|
+
self.current_survey_section.questions << q
|
150
|
+
@current_question = q
|
151
|
+
end
|
152
|
+
def current_dependency=(d)
|
153
|
+
raise "Error: No question or question group" unless (dependent = self.current_question_group || self.current_question)
|
154
|
+
dependent.dependency = d
|
155
|
+
@current_dependency = d
|
156
|
+
end
|
157
|
+
def current_answer=(a)
|
158
|
+
raise "Error: No current question" if self.current_question.nil?
|
159
|
+
self.current_question.answers << a
|
160
|
+
@current_answer = a
|
161
|
+
end
|
162
|
+
def current_validation=(v)
|
163
|
+
clear_current "validation"
|
164
|
+
self.current_answer.validation = v
|
165
|
+
@current_validation = v
|
166
|
+
end
|
167
|
+
|
168
|
+
def in_a_grid?
|
169
|
+
self.current_question_group and self.current_question_group.display_type == "grid"
|
170
|
+
end
|
171
|
+
|
172
|
+
def add_grid_answers
|
173
|
+
self.grid_answers.each do |grid_answer|
|
174
|
+
my_answer = grid_answer.dup
|
175
|
+
my_answer.id = new_answer_id
|
176
|
+
my_answer.question_id = self.current_question.id
|
177
|
+
my_answer.parser = self
|
178
|
+
self.current_answer = my_answer
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def to_files
|
183
|
+
self.surveys.compact.map(&:to_file)
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
data/script/surveyor/question.rb
CHANGED
@@ -1,34 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class Question < SurveyParser::Base
|
3
|
+
# Context, Content, Reference, Display, Children
|
4
|
+
attr_accessor :id, :parser, :survey_section_id, :question_group_id
|
5
|
+
attr_accessor :text, :short_text, :help_text, :pick
|
6
|
+
attr_accessor :reference_identifier, :data_export_identifier, :common_namespace, :common_identifier
|
7
|
+
attr_accessor :display_order, :display_type, :is_mandatory, :display_width, :custom_class, :custom_renderer
|
8
|
+
attr_accessor :dependency
|
9
|
+
has_children :answers
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
11
|
+
def default_options
|
12
|
+
{ :pick => :none,
|
13
|
+
:display_type => :default,
|
14
|
+
:is_mandatory => true,
|
15
|
+
:display_order => self.id
|
16
|
+
}
|
17
|
+
end
|
18
|
+
def parse_opts(opts)
|
19
|
+
(name = opts.delete(:method_name)) =~ /label|image/ ? opts.merge(:display_type => name) : opts
|
20
|
+
end
|
21
|
+
def parse_args(args)
|
22
|
+
text = args[0] || "Question"
|
23
|
+
{:text => text, :short_text => text, :data_export_identifier => Surveyor.to_normalized_string(text)}.merge(args[1] || {})
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
def find_answer_by_reference(ref_id)
|
27
|
+
self.answers.detect{|a| a.reference_identifier == ref_id}
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def to_file
|
31
|
+
super
|
32
|
+
if self.dependency then self.dependency.to_file end
|
33
|
+
end
|
33
34
|
|
35
|
+
end
|
34
36
|
end
|
@@ -1,24 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class QuestionGroup < SurveyParser::Base
|
3
|
+
# Context, Content, Display, Children
|
4
|
+
attr_accessor :id, :parser
|
5
|
+
attr_accessor :text, :help_text
|
6
|
+
attr_accessor :reference_identifier, :data_export_identifier, :common_namespace, :common_identitier
|
7
|
+
attr_accessor :display_type, :custom_class, :custom_renderer
|
8
|
+
attr_accessor :dependency
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
def default_options
|
11
|
+
{:display_type => "default"}
|
12
|
+
end
|
13
|
+
def parse_args(args)
|
14
|
+
{:text => args[0] || "Question Group"}.merge(args[1] || {})
|
15
|
+
end
|
16
|
+
def parse_opts(opts)
|
17
|
+
(name = opts.delete(:method_name)) =~ /grid|repeater/ ? opts.merge(:display_type => name) : opts
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def to_file
|
21
|
+
super
|
22
|
+
if self.dependency then self.dependency.to_file end
|
23
|
+
end
|
23
24
|
|
25
|
+
end
|
24
26
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require 'answer'
|
3
3
|
|
4
|
-
describe Answer, " when first created" do
|
4
|
+
describe SurveyParser::Answer, " when first created" do
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
-
question = mock("Question", :id => 2, :parser => mock("Parser", :new_answer_id => 1))
|
8
|
-
question.stub!(:class => Question)
|
7
|
+
question = mock("Question", :id => 2, :parser => mock("SurveyParser::Parser", :new_answer_id => 1))
|
8
|
+
question.stub!(:class => SurveyParser::Question)
|
9
9
|
options = {:help_text => "Never or rarely ever", :reference_identifier => "b3a_1"}
|
10
|
-
@ans = Answer.new(question, ["No / Rarely"], options)
|
10
|
+
@ans = SurveyParser::Answer.new(question, ["No / Rarely"], options)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should set inititalized variables to those passed in" do
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require 'question'
|
3
3
|
|
4
|
-
describe Question, " when first created" do
|
4
|
+
describe SurveyParser::Question, " when first created" do
|
5
5
|
before do
|
6
|
-
section = mock("SurveySection", :id => 2, :parser => mock("Parser", :new_question_id => 1))
|
7
|
-
section.stub!(:class => SurveySection)
|
6
|
+
section = mock("SurveyParser::SurveySection", :id => 2, :parser => mock("SurveyParser::Parser", :new_question_id => 1))
|
7
|
+
section.stub!(:class => SurveyParser::SurveySection)
|
8
8
|
args = {:help_text => "Please give a rough estimate", :reference_identifier => "B3"}
|
9
9
|
options = {}
|
10
|
-
@ques = Question.new(section, ["In the past 12 months how many times have you been to a doctor?", args], options)
|
10
|
+
@ques = SurveyParser::Question.new(section, ["In the past 12 months how many times have you been to a doctor?", args], options)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should set initialization parameters properly" do
|
@@ -39,15 +39,15 @@ describe Question, " when first created" do
|
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
|
-
describe Question, "when it contains data" do
|
42
|
+
describe SurveyParser::Question, "when it contains data" do
|
43
43
|
before(:each) do
|
44
|
-
section = mock("SurveySection", :id => 2, :parser => mock("Parser", :new_question_id => 1))
|
44
|
+
section = mock("SurveyParser::SurveySection", :id => 2, :parser => mock("SurveyParser::Parser", :new_question_id => 1))
|
45
45
|
args = {:help_text => "Please give a rough estimate", :reference_identifier => "B3"}
|
46
46
|
options = {}
|
47
|
-
@ques = Question.new(section, ["In the past 12 months how many times have you been to a doctor?", args], options)
|
48
|
-
@ques.answers << mock("Answer", :reference_identifier => "1", :text => "foo")
|
49
|
-
@ques.answers << mock("Answer", :reference_identifier => "2", :text => "foo")
|
50
|
-
@ques.answers << mock("Answer", :reference_identifier => "3", :text => "foo")
|
47
|
+
@ques = SurveyParser::Question.new(section, ["In the past 12 months how many times have you been to a doctor?", args], options)
|
48
|
+
@ques.answers << mock("SurveyParser::Answer", :reference_identifier => "1", :text => "foo")
|
49
|
+
@ques.answers << mock("SurveyParser::Answer", :reference_identifier => "2", :text => "foo")
|
50
|
+
@ques.answers << mock("SurveyParser::Answer", :reference_identifier => "3", :text => "foo")
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should have added the test answers correctly" do
|
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + "/../../../lib/surveyor")
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/../parser")
|
3
4
|
require File.expand_path(File.dirname(__FILE__) + "/../base")
|
4
5
|
|
5
6
|
Spec::Runner.configure do |config|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require 'survey_section'
|
3
3
|
|
4
|
-
describe SurveySection, "when first created" do
|
4
|
+
describe SurveyParser::SurveySection, "when first created" do
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
-
@section = SurveySection.new(mock("Survey", :id => 2, :parser => mock("Parser", :new_survey_section_id => 1)), ["Demographics"], {})
|
7
|
+
@section = SurveyParser::SurveySection.new(mock("SurveyParser::Survey", :id => 2, :parser => mock("SurveyParser::Parser", :new_survey_section_id => 1)), ["Demographics"], {})
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should generate a data export identifier" do
|
@@ -12,9 +12,9 @@ describe SurveySection, "when first created" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should find a question by reference" do
|
15
|
-
@section.questions << mock("Question", :reference_identifier => "1", :text => "foo")
|
16
|
-
@section.questions << mock("Question", :reference_identifier => "2", :text => "foo")
|
17
|
-
@section.questions << mock("Question", :reference_identifier => "3", :text => "foo")
|
15
|
+
@section.questions << mock("SurveyParser::Question", :reference_identifier => "1", :text => "foo")
|
16
|
+
@section.questions << mock("SurveyParser::Question", :reference_identifier => "2", :text => "foo")
|
17
|
+
@section.questions << mock("SurveyParser::Question", :reference_identifier => "3", :text => "foo")
|
18
18
|
|
19
19
|
q = @section.find_question_by_reference("2")
|
20
20
|
q.should_not be_nil
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require 'validation_condition'
|
3
3
|
|
4
|
-
describe ValidationCondition, " when first created" do
|
4
|
+
describe SurveyParser::ValidationCondition, " when first created" do
|
5
5
|
before do
|
6
|
-
validation = mock("Validation", :id => 29, :parser => mock("Parser", :new_validation_condition_id => 21))
|
7
|
-
validation.stub!(:class => Validation)
|
6
|
+
validation = mock("SurveyParser::Validation", :id => 29, :parser => mock("SurveyParser::Parser", :new_validation_condition_id => 21))
|
7
|
+
validation.stub!(:class => SurveyParser::Validation)
|
8
8
|
args = [">=", {:integer_value => 0}]
|
9
9
|
options = {}
|
10
|
-
@validation_condition = ValidationCondition.new(validation, args, options)
|
10
|
+
@validation_condition = SurveyParser::ValidationCondition.new(validation, args, options)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should set initialization parameters properly" do
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require 'validation'
|
3
3
|
|
4
|
-
describe Validation, " when first created" do
|
4
|
+
describe SurveyParser::Validation, " when first created" do
|
5
5
|
before do
|
6
|
-
answer = mock("Answer", :id => 2, :parser => mock("Parser", :new_validation_id => 1))
|
7
|
-
answer.stub!(:class => Answer)
|
6
|
+
answer = mock("SurveyParser::Answer", :id => 2, :parser => mock("SurveyParser::Parser", :new_validation_id => 1))
|
7
|
+
answer.stub!(:class => SurveyParser::Answer)
|
8
8
|
args = [{:rule => "C", :message => "Please select a number between 0 and 120"}]
|
9
9
|
options = {}
|
10
|
-
@validation = Validation.new(answer, args, options)
|
10
|
+
@validation = SurveyParser::Validation.new(answer, args, options)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should set initialization parameters properly" do
|
data/script/surveyor/survey.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class Survey < SurveyParser::Base
|
3
|
+
# Context, Content, Reference, Expiry, Display
|
4
|
+
attr_accessor :id, :parser
|
5
|
+
attr_accessor :title, :description
|
6
|
+
attr_accessor :access_code, :reference_identifier, :data_export_identifier, :common_namespace, :common_identitier
|
7
|
+
attr_accessor :active_at, :inactive_at
|
8
|
+
attr_accessor :css_url, :custom_class
|
9
|
+
has_children :survey_sections
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def parse_args(args)
|
12
|
+
title = args[0]
|
13
|
+
{:title => title, :access_code => Surveyor.to_normalized_string(title)}.merge(args[1] || {})
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def find_question_by_reference(ref_id)
|
17
|
+
found = nil
|
18
|
+
survey_sections.detect{|s| found = s.find_question_by_reference(ref_id)}
|
19
|
+
return found
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
def reconcile_dependencies
|
23
|
+
survey_sections.each do |section|
|
24
|
+
section.questions.each do |question|
|
25
|
+
question.dependency.dependency_conditions.each { |con| con.reconcile_dependencies} unless question.dependency.nil?
|
26
|
+
end
|
27
|
+
section.question_groups.each do |group|
|
28
|
+
group.dependency.dependency_conditions.each { |con| con.reconcile_dependencies} unless group.dependency.nil?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
31
32
|
|
33
|
+
end
|
32
34
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class SurveySection < SurveyParser::Base
|
3
|
+
# Context, Content, Display, Reference, Children, Placeholders
|
4
|
+
attr_accessor :id, :parser, :survey_id
|
5
|
+
attr_accessor :title, :description
|
6
|
+
attr_accessor :reference_identifier, :data_export_identifier, :common_namespace, :common_identitier
|
7
|
+
attr_accessor :display_order, :custom_class
|
8
|
+
has_children :question_groups, :questions
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def parse_args(args)
|
11
|
+
title = args[0]
|
12
|
+
{:title => title, :data_export_identifier => Surveyor.to_normalized_string(title)}.merge(args[1] || {})
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
# Used to find questions for dependency linking
|
16
|
+
def find_question_by_reference(ref_id)
|
17
|
+
self.questions.detect{|q| q.reference_identifier == ref_id}
|
18
|
+
end
|
18
19
|
|
20
|
+
end
|
19
21
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class Validation < SurveyParser::Base
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# Context, Conditional, Children
|
5
|
+
attr_accessor :id, :answer_id, :parser
|
6
|
+
attr_accessor :rule, :message
|
7
|
+
has_children :validation_conditions
|
7
8
|
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
def default_options
|
11
|
+
{:rule => "A"}
|
12
|
+
end
|
13
|
+
def parse_args(args)
|
14
|
+
args[0] || {}
|
15
|
+
end
|
16
|
+
def parse_opts(opts)
|
17
|
+
{} # toss the method name and reference identifier by default
|
18
|
+
end
|
18
19
|
|
20
|
+
end
|
19
21
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module SurveyParser
|
2
|
+
class ValidationCondition < SurveyParser::Base
|
3
|
+
# Context, Conditional, Value, Reference
|
4
|
+
attr_accessor :id, :validation_id, :rule_key, :parser
|
5
|
+
attr_accessor :operator
|
6
|
+
attr_accessor :question_id, :answer_id, :datetime_value, :integer_value, :float_value, :unit, :text_value, :string_value, :response_other, :regexp
|
7
|
+
attr_accessor :question_reference, :answer_reference
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
def default_options
|
10
|
+
{ :operator => "==" }
|
11
|
+
end
|
12
|
+
def parse_args(args)
|
13
|
+
a0, a1 = args
|
14
|
+
{:operator => a0}.merge(a1 || {})
|
15
|
+
end
|
16
|
+
def parse_opts(opts)
|
17
|
+
{:rule_key => opts[:reference_identifier]}
|
18
|
+
end
|
18
19
|
|
20
|
+
end
|
19
21
|
end
|
data/spec/factories.rb
CHANGED
data/surveyor.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{surveyor}
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Chamberlain", "Mark Yoon"]
|
@@ -137,6 +137,7 @@ Gem::Specification.new do |s|
|
|
137
137
|
"script/surveyor/base.rb",
|
138
138
|
"script/surveyor/dependency.rb",
|
139
139
|
"script/surveyor/dependency_condition.rb",
|
140
|
+
"script/surveyor/parser.rb",
|
140
141
|
"script/surveyor/question.rb",
|
141
142
|
"script/surveyor/question_group.rb",
|
142
143
|
"script/surveyor/specs/answer_spec.rb",
|
@@ -146,7 +147,6 @@ Gem::Specification.new do |s|
|
|
146
147
|
"script/surveyor/specs/validation_condition_spec.rb",
|
147
148
|
"script/surveyor/specs/validation_spec.rb",
|
148
149
|
"script/surveyor/survey.rb",
|
149
|
-
"script/surveyor/survey_parser.rb",
|
150
150
|
"script/surveyor/survey_section.rb",
|
151
151
|
"script/surveyor/validation.rb",
|
152
152
|
"script/surveyor/validation_condition.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surveyor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Chamberlain
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- script/surveyor/base.rb
|
155
155
|
- script/surveyor/dependency.rb
|
156
156
|
- script/surveyor/dependency_condition.rb
|
157
|
+
- script/surveyor/parser.rb
|
157
158
|
- script/surveyor/question.rb
|
158
159
|
- script/surveyor/question_group.rb
|
159
160
|
- script/surveyor/specs/answer_spec.rb
|
@@ -163,7 +164,6 @@ files:
|
|
163
164
|
- script/surveyor/specs/validation_condition_spec.rb
|
164
165
|
- script/surveyor/specs/validation_spec.rb
|
165
166
|
- script/surveyor/survey.rb
|
166
|
-
- script/surveyor/survey_parser.rb
|
167
167
|
- script/surveyor/survey_section.rb
|
168
168
|
- script/surveyor/validation.rb
|
169
169
|
- script/surveyor/validation_condition.rb
|
@@ -1,186 +0,0 @@
|
|
1
|
-
require 'activesupport' # for pluralize, humanize in ActiveSupport::CoreExtensions::String::Inflections
|
2
|
-
|
3
|
-
class SurveyParser
|
4
|
-
@@models = %w(survey survey_section question_group question answer dependency dependency_condition validation validation_condition)
|
5
|
-
|
6
|
-
# Require base and all models
|
7
|
-
(%w(base) + @@models).each{|m| require File.dirname(__FILE__) + "/#{m}"}
|
8
|
-
|
9
|
-
# Attributes
|
10
|
-
attr_accessor :surveys, :grid_answers
|
11
|
-
@@models.each{|m| attr_accessor "#{m.pluralize}_yml".to_sym } # for fixtures
|
12
|
-
(@@models - %w(dependency_condition validation_condition)).each {|m| attr_accessor "current_#{m}".to_sym} # for current_model caches
|
13
|
-
|
14
|
-
# Class methods
|
15
|
-
def self.parse(file_name)
|
16
|
-
self.define_counter_methods(@@models)
|
17
|
-
puts "\n--- Parsing '#{file_name}' ---"
|
18
|
-
parser = SurveyParser.new
|
19
|
-
parser.instance_eval(File.read(file_name))
|
20
|
-
parser.to_files
|
21
|
-
puts "--- End of parsing ---\n\n"
|
22
|
-
end
|
23
|
-
|
24
|
-
# new_survey_id, new_survey_section_id, etc.
|
25
|
-
def self.define_counter_methods(names)
|
26
|
-
names.each do |name|
|
27
|
-
define_method("new_#{name}_id") do
|
28
|
-
instance_variable_set("@last_#{name}_id", instance_variable_get("@last_#{name}_id") + 1)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Instance methods
|
34
|
-
def initialize
|
35
|
-
self.surveys = []
|
36
|
-
self.grid_answers = []
|
37
|
-
initialize_counters(@@models)
|
38
|
-
initialize_fixtures(@@models.map(&:pluralize), File.join(RAILS_ROOT, "surveys", "fixtures"))
|
39
|
-
end
|
40
|
-
|
41
|
-
# @last_survey_id, @last_survey_section_id, etc.
|
42
|
-
def initialize_counters(names)
|
43
|
-
names.each{|name| instance_variable_set("@last_#{name}_id", 0)}
|
44
|
-
end
|
45
|
-
|
46
|
-
# @surveys_yml, @survey_sections_yml, etc.
|
47
|
-
def initialize_fixtures(names, path)
|
48
|
-
names.each {|name| file = instance_variable_set("@#{name}_yml", "#{path}/#{name}.yml"); File.truncate(file, 0) if File.exist?(file) }
|
49
|
-
end
|
50
|
-
|
51
|
-
# This method_missing does all the heavy lifting for the DSL
|
52
|
-
def method_missing(missing_method, *args, &block)
|
53
|
-
method_name, reference_identifier = missing_method.to_s.split("_", 2)
|
54
|
-
opts = {:method_name => method_name, :reference_identifier => reference_identifier}
|
55
|
-
case method_name
|
56
|
-
when "survey"
|
57
|
-
self.current_survey = Survey.new(self, args, opts)
|
58
|
-
evaluate_the "survey", &block
|
59
|
-
|
60
|
-
when "section"
|
61
|
-
self.current_survey_section = SurveySection.new(self.current_survey, args, opts.merge({:display_order => current_survey.survey_sections.size + 1}))
|
62
|
-
evaluate_the "survey_section", &block
|
63
|
-
|
64
|
-
when "group", "g", "grid", "repeater"
|
65
|
-
self.current_question_group = QuestionGroup.new(self.current_survey_section, args, opts)
|
66
|
-
evaluate_the "question_group", &block
|
67
|
-
|
68
|
-
when "question", "q", "label", "image"
|
69
|
-
drop_the &block
|
70
|
-
self.current_question = Question.new(self.current_survey_section, args, opts.merge(:question_group_id => current_question_group ? current_question_group.id : nil))
|
71
|
-
add_grid_answers if in_a_grid?
|
72
|
-
|
73
|
-
when "dependency", "d"
|
74
|
-
drop_the &block
|
75
|
-
self.current_dependency = Dependency.new(self.current_question_group || current_question, args, opts)
|
76
|
-
|
77
|
-
when "condition", "c"
|
78
|
-
drop_the &block
|
79
|
-
raise "Error: No current dependency or validation for this condition" if self.current_dependency.nil? && self.current_validation.nil?
|
80
|
-
if self.current_dependency.nil?
|
81
|
-
self.current_validation.validation_conditions << ValidationCondition.new(self.current_validation, args, opts)
|
82
|
-
else
|
83
|
-
self.current_dependency.dependency_conditions << DependencyCondition.new(self.current_dependency, args, opts)
|
84
|
-
end
|
85
|
-
|
86
|
-
when "answer", "a"
|
87
|
-
drop_the &block
|
88
|
-
if in_a_grid?
|
89
|
-
self.grid_answers << Answer.new(nil, args, opts.merge(:display_order => grid_answers.size + 1))
|
90
|
-
else
|
91
|
-
raise "Error: No current question" if self.current_question.nil?
|
92
|
-
self.current_answer = Answer.new(self.current_question, args, opts.merge(:display_order => current_question.answers.size + 1))
|
93
|
-
end
|
94
|
-
|
95
|
-
when "validation", "v"
|
96
|
-
drop_the &block
|
97
|
-
self.current_validation = Validation.new(self.current_answer, args, opts)
|
98
|
-
|
99
|
-
else
|
100
|
-
raise " ERROR: '#{missing_method}' not valid method"
|
101
|
-
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def drop_the(&block)
|
106
|
-
raise "Error, I'm dropping the block like it's hot" if block_given?
|
107
|
-
end
|
108
|
-
|
109
|
-
def evaluate_the(model, &block)
|
110
|
-
raise "Error: A #{model.humanize} cannot be empty" unless block_given?
|
111
|
-
self.instance_eval(&block)
|
112
|
-
self.send("clear_current", model)
|
113
|
-
end
|
114
|
-
|
115
|
-
def clear_current(model)
|
116
|
-
# puts "clear_current #{model}"
|
117
|
-
case model
|
118
|
-
when "survey"
|
119
|
-
self.current_survey.reconcile_dependencies unless current_survey.nil?
|
120
|
-
when "question_group"
|
121
|
-
self.grid_answers = []
|
122
|
-
clear_current("question")
|
123
|
-
when "question"
|
124
|
-
@current_dependency = nil
|
125
|
-
when "answer"
|
126
|
-
@current_validation = nil
|
127
|
-
end
|
128
|
-
instance_variable_set("@current_#{model}", nil)
|
129
|
-
model.classify.constantize.send(:children).each{|m| clear_current(m.to_s.singularize)}
|
130
|
-
end
|
131
|
-
|
132
|
-
def current_survey=(s)
|
133
|
-
clear_current "survey"
|
134
|
-
self.surveys << s
|
135
|
-
@current_survey = s
|
136
|
-
end
|
137
|
-
def current_survey_section=(s)
|
138
|
-
clear_current "survey_section"
|
139
|
-
self.current_survey.survey_sections << s
|
140
|
-
@current_survey_section = s
|
141
|
-
end
|
142
|
-
def current_question_group=(g)
|
143
|
-
clear_current "question_group"
|
144
|
-
self.current_survey_section.question_groups << g
|
145
|
-
@current_question_group = g
|
146
|
-
end
|
147
|
-
def current_question=(q)
|
148
|
-
clear_current "question"
|
149
|
-
self.current_survey_section.questions << q
|
150
|
-
@current_question = q
|
151
|
-
end
|
152
|
-
def current_dependency=(d)
|
153
|
-
raise "Error: No question or question group" unless (dependent = self.current_question_group || self.current_question)
|
154
|
-
dependent.dependency = d
|
155
|
-
@current_dependency = d
|
156
|
-
end
|
157
|
-
def current_answer=(a)
|
158
|
-
raise "Error: No current question" if self.current_question.nil?
|
159
|
-
self.current_question.answers << a
|
160
|
-
@current_answer = a
|
161
|
-
end
|
162
|
-
def current_validation=(v)
|
163
|
-
clear_current "validation"
|
164
|
-
self.current_answer.validation = v
|
165
|
-
@current_validation = v
|
166
|
-
end
|
167
|
-
|
168
|
-
def in_a_grid?
|
169
|
-
self.current_question_group and self.current_question_group.display_type == "grid"
|
170
|
-
end
|
171
|
-
|
172
|
-
def add_grid_answers
|
173
|
-
self.grid_answers.each do |grid_answer|
|
174
|
-
my_answer = grid_answer.dup
|
175
|
-
my_answer.id = new_answer_id
|
176
|
-
my_answer.question_id = self.current_question.id
|
177
|
-
my_answer.parser = self
|
178
|
-
self.current_answer = my_answer
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def to_files
|
183
|
-
self.surveys.compact.map(&:to_file)
|
184
|
-
end
|
185
|
-
|
186
|
-
end
|