surveyor 0.9.1 → 0.9.2
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/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
|