surveyor 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,23 @@
1
1
  History for Surveyor
2
2
  ====================
3
3
 
4
+ 1.0.1
5
+ ------
6
+
7
+ ### Features
8
+
9
+ - Question#display_type == "hidden" and QuestionGroup#display_type == "hidden"
10
+ now exclude the question or question group from the DOM. These display types are
11
+ used to inject data (responses) into surveys. Note, custom_class => "hidden" doesn't
12
+ have any effect until a custom css rule is created by the end user. (#197)
13
+ - more readable parser and more strict parser method aliases (#278)
14
+
15
+ ### Fixes
16
+
17
+ - Replaced deprecated ActiveRecord::Errors#each_full with ActiveRecord::Errors#full_messages. (#363)
18
+ - fixing dependency condition evaluation where #Response.*_value is nil. (#297)
19
+ - fixing grid answers leak, introduced in 5baa7ac3. thanks @jsurrett (#375, #377)
20
+
4
21
  1.0.0
5
22
  ------
6
23
 
@@ -2,26 +2,27 @@
2
2
  - rg ||= nil
3
3
  - renderer = q.renderer(g ||= nil)
4
4
  - disabled = defined?(disableFlag) ? disableFlag : false
5
- = f.inputs q_text(q, @render_context), :id => rg ? "q_#{q.id}_#{rg}" : "q_#{q.id}", :class => "q_#{renderer} #{q.css_class(@response_set)}" do
6
- %span.help= render_help_text(q, @render_context)
7
- - case renderer
8
- - when :image, :label
9
- - when :dropdown, :inline_dropdown, :default_dropdown, :slider, :repeater_dropdown
10
- - r = response_for(@response_set, q, nil, rg)
11
- - i = response_idx
12
- = f.semantic_fields_for i, r do |ff|
13
- = ff.input :question_id, :as => :quiet
14
- = ff.input :response_group, :as => :quiet, :value => rg if g && g.display_type == "repeater"
15
- = ff.input :api_id, :as => :quiet
16
- = ff.input :answer_id, :as => :select, :collection => q.answers.map{|a| [a.text, a.id]}, :include_blank => (renderer != :slider), :label => q.text, :input_html => { :disabled => disabled }
17
- - else # :default, :inline, :inline_default
18
- - if q.pick == "one"
5
+ - unless q.display_type == "hidden"
6
+ = f.inputs q_text(q, @render_context), :id => rg ? "q_#{q.id}_#{rg}" : "q_#{q.id}", :class => "q_#{renderer} #{q.css_class(@response_set)}" do
7
+ %span.help= render_help_text(q, @render_context)
8
+ - case renderer
9
+ - when :image, :label
10
+ - when :dropdown, :inline_dropdown, :default_dropdown, :slider, :repeater_dropdown
19
11
  - r = response_for(@response_set, q, nil, rg)
20
- - i = response_idx # increment the response index since the answer partial skips for q.pick == one
12
+ - i = response_idx
21
13
  = f.semantic_fields_for i, r do |ff|
22
14
  = ff.input :question_id, :as => :quiet
23
15
  = ff.input :response_group, :as => :quiet, :value => rg if g && g.display_type == "repeater"
24
16
  = ff.input :api_id, :as => :quiet
25
- - q.answers.each do |a|
26
- - next if (q.pick == "one" or q.pick == "any") and disabled and @response_set.responses.where( :question_id => q.id, :answer_id => a.id).empty?
27
- = render a.custom_renderer || '/partials/answer', :q => q, :a => a, :f => f, :rg => rg, :g => g, :disableFlag => disabled
17
+ = ff.input :answer_id, :as => :select, :collection => q.answers.map{|a| [a.text, a.id]}, :include_blank => (renderer != :slider), :label => q.text, :input_html => { :disabled => disabled }
18
+ - else # :default, :inline, :inline_default
19
+ - if q.pick == "one"
20
+ - r = response_for(@response_set, q, nil, rg)
21
+ - i = response_idx # increment the response index since the answer partial skips for q.pick == one
22
+ = f.semantic_fields_for i, r do |ff|
23
+ = ff.input :question_id, :as => :quiet
24
+ = ff.input :response_group, :as => :quiet, :value => rg if g && g.display_type == "repeater"
25
+ = ff.input :api_id, :as => :quiet
26
+ - q.answers.each do |a|
27
+ - next if (q.pick == "one" or q.pick == "any") and disabled and @response_set.responses.where( :question_id => q.id, :answer_id => a.id).empty?
28
+ = render a.custom_renderer || '/partials/answer', :q => q, :a => a, :f => f, :rg => rg, :g => g, :disableFlag => disabled
@@ -1,40 +1,41 @@
1
1
  - renderer = g.renderer
2
- = f.inputs q_text(g, @render_context), :id => "g_#{g.id}", :class => "g_#{renderer} #{g.css_class(@response_set)}" do
3
- %li.help= render_help_text(g, @render_context)
4
- - case renderer
5
- - when :grid
6
- %li
7
- %table
8
- %col.pre
9
- - qs.first.answers.each do |a|
10
- %col{:class => cycle("odd", "even")}
11
- %col.post
12
- %tbody
13
- - qs.each_slice(10) do |ten_questions| # header row every 10
14
- %tr
15
- %th  
16
- - ten_questions.first.answers.each do |a|
17
- %th= a_text(a)
18
- %th  
19
- - ten_questions.each_with_index do |q, i|
20
- %tr{:id => "q_#{q.id}", :class => "q_#{renderer} #{q.css_class(@response_set)}"}
21
- %th
22
- = q.split_text(:pre)
23
- - if q.pick == "one"
24
- - r = response_for(@response_set, q, nil, g)
25
- - i = response_idx # increment the response index since the answer partial skips for q.pick == one
26
- = f.semantic_fields_for i, r do |ff|
27
- = ff.input :question_id, :as => :quiet
28
- = ff.input :api_id, :as => :quiet
29
- - q.answers.each do |a|
30
- %td= render a.custom_renderer || '/partials/answer', :g => g, :q => q, :a => a, :f => f
31
- %th= q.split_text(:post)
32
- - when :repeater
33
- - (@response_set.count_group_responses(qs) + 1).times do |rg|
2
+ - unless g.display_type == "hidden"
3
+ = f.inputs q_text(g, @render_context), :id => "g_#{g.id}", :class => "g_#{renderer} #{g.css_class(@response_set)}" do
4
+ %li.help= render_help_text(g, @render_context)
5
+ - case renderer
6
+ - when :grid
34
7
  %li
35
- - qs.each do |q|
36
- = render q.custom_renderer || "/partials/question", :g => g, :rg => rg, :q => q, :f => f
37
- = submit_tag("+ add row", :name => "section[#{@section.id}][g_#{g.id}]", :class => "add_row")
38
- - else # :inline
39
- - qs.each do |q|
40
- = render q.custom_renderer || "/partials/question", :g => g, :q => q, :f => f
8
+ %table
9
+ %col.pre
10
+ - qs.first.answers.each do |a|
11
+ %col{:class => cycle("odd", "even")}
12
+ %col.post
13
+ %tbody
14
+ - qs.each_slice(10) do |ten_questions| # header row every 10
15
+ %tr
16
+ %th  
17
+ - ten_questions.first.answers.each do |a|
18
+ %th= a_text(a)
19
+ %th  
20
+ - ten_questions.each_with_index do |q, i|
21
+ %tr{:id => "q_#{q.id}", :class => "q_#{renderer} #{q.css_class(@response_set)}"}
22
+ %th
23
+ = q.split_text(:pre)
24
+ - if q.pick == "one"
25
+ - r = response_for(@response_set, q, nil, g)
26
+ - i = response_idx # increment the response index since the answer partial skips for q.pick == one
27
+ = f.semantic_fields_for i, r do |ff|
28
+ = ff.input :question_id, :as => :quiet
29
+ = ff.input :api_id, :as => :quiet
30
+ - q.answers.each do |a|
31
+ %td= render a.custom_renderer || '/partials/answer', :g => g, :q => q, :a => a, :f => f
32
+ %th= q.split_text(:post)
33
+ - when :repeater
34
+ - (@response_set.count_group_responses(qs) + 1).times do |rg|
35
+ %li
36
+ - qs.each do |q|
37
+ = render q.custom_renderer || "/partials/question", :g => g, :rg => rg, :q => q, :f => f
38
+ = submit_tag("+ add row", :name => "section[#{@section.id}][g_#{g.id}]", :class => "add_row")
39
+ - else # :inline
40
+ - qs.each do |q|
41
+ = render q.custom_renderer || "/partials/question", :g => g, :q => q, :f => f
@@ -660,3 +660,34 @@ Feature: Survey creation
660
660
  When I check "Refused"
661
661
  Then the checkbox for "Electric" should be disabled
662
662
  And the checkbox for "Don't know" should be disabled
663
+
664
+ # #197 - Add a hidden field type, don't show hidden questions and groups in the DOM
665
+ # don't use up question numbers on them either. custom class "hidden" doesn't
666
+ # do anything until you add your own css to hide it
667
+ Scenario: hidden questions for injecting data
668
+ Given I parse
669
+ """
670
+ survey "Sesame Street" do
671
+ section "The Count" do
672
+ q_name "What is your name?", :display_type => :hidden
673
+ a :string, :help_text => "(e.g. Count Von Count)"
674
+
675
+ group "Friends", :display_type => :hidden do
676
+ q "Who are your friends?"
677
+ a :string
678
+ end
679
+
680
+ label "AH AH AH AH AH!"
681
+
682
+ q_numbers "What is your favorite number?", :pick => :one, :custom_class => "hidden"
683
+ a "One"
684
+ a "Two"
685
+ a "Three!"
686
+ end
687
+ end
688
+ """
689
+ When I start the "Sesame Street" survey
690
+ Then I should see "AH AH AH AH AH!"
691
+ And I should see "1) What is your favorite number?"
692
+ And I should not see "What is your name?"
693
+
@@ -3,7 +3,6 @@ Feature: Survey parser
3
3
  I want to write out the survey in the DSL
4
4
  So that I can give it to survey participants
5
5
 
6
- @focus
7
6
  Scenario: Parsing basic questions
8
7
  Given I parse
9
8
  """
@@ -345,7 +344,7 @@ Feature: Survey parser
345
344
  end
346
345
 
347
346
  """
348
- Then the parser should fail with "Dropping the Sectionals block like it's hot!"
347
+ Then the parser should fail with "\"sectionals\" is not a surveyor method."
349
348
 
350
349
  Scenario: Parsing bad references
351
350
  Given the survey
@@ -390,3 +389,63 @@ Feature: Survey parser
390
389
  end
391
390
  """
392
391
  Then the parser should fail with "Duplicate references: q_watch, a_1; q_watch"
392
+
393
+ Scenario: Parsing with Rails validation errors
394
+ Given the survey
395
+ """
396
+ survey do
397
+ section "Usage" do
398
+ q_PLACED_BAG_1 "Is the bag placed?", :pick => :one
399
+ a_1 "Yes"
400
+ a_2 "No"
401
+ a_3 "Refused"
402
+ end
403
+ end
404
+ """
405
+ Then the parser should fail with "Survey not saved: Title can't be blank"
406
+
407
+ Scenario: Parsing bad shortcuts
408
+ Given the survey
409
+ """
410
+ survey "shortcuts" do
411
+ section "Bad" do
412
+ quack "Do you like ducks?", :pick => :one
413
+ a_1 "Yes"
414
+ a_1 "No"
415
+ end
416
+ end
417
+ """
418
+ Then the parser should fail with "\"quack\" is not a surveyor method."
419
+
420
+ Scenario: Clearing grid answers
421
+ Given I parse
422
+ """
423
+ survey "Grids" do
424
+ section "Leaking" do
425
+ grid "How would you rate the following?" do
426
+ a "bad"
427
+ a "neutral"
428
+ a "good"
429
+ q "steak" , :pick => :one
430
+ q "chicken", :pick => :one
431
+ q "fish", :pick => :one
432
+ end
433
+ grid "How do you feel about the following?" do
434
+ a "sad"
435
+ a "indifferent"
436
+ a "happy"
437
+ q "births" , :pick => :one
438
+ q "weddings", :pick => :one
439
+ q "funerals", :pick => :one
440
+ end
441
+ end
442
+ end
443
+ """
444
+ Then there should be 18 answers with:
445
+ | text | display_order |
446
+ | bad | 0 |
447
+ | neutral | 1 |
448
+ | good | 2 |
449
+ | sad | 0 |
450
+ | indifferent | 1 |
451
+ | happy | 2 |
@@ -46,11 +46,11 @@ module Surveyor
46
46
  return {rule_key.to_sym => true}
47
47
  elsif response = responses.detect{|r| r.answer.id == self.answer.id}
48
48
  klass = response.answer.response_class
49
- klass = "answer" if self.as(klass).nil?
49
+ klass = "answer" if self.as(klass).nil? # it should compare answer ids when the dependency condition *_value is nil
50
50
  case self.operator
51
51
  when "==", "<", ">", "<=", ">="
52
52
  # logger.warn( {rule_key.to_sym => response.as(klass).send(self.operator, self.as(klass))})
53
- return {rule_key.to_sym => response.as(klass).send(self.operator, self.as(klass))}
53
+ return {rule_key.to_sym => !response.as(klass).nil? && response.as(klass).send(self.operator, self.as(klass))}
54
54
  when "!="
55
55
  # logger.warn( {rule_key.to_sym => !response.as(klass).send("==", self.as(klass))})
56
56
  return {rule_key.to_sym => !response.as(klass).send("==", self.as(klass))}
@@ -2,21 +2,53 @@
2
2
  module Surveyor
3
3
  class ParserError < StandardError; end
4
4
  class Parser
5
- class << self; attr_accessor :options end
5
+ class << self; attr_accessor :options, :log end
6
6
 
7
7
  # Attributes
8
8
  attr_accessor :context
9
9
 
10
10
  # Class methods
11
11
  def self.parse(str, options={})
12
+ self.ensure_attrs
12
13
  self.options = options
14
+ self.log[:source] = str
13
15
  Surveyor::Parser.rake_trace "\n"
14
16
  Surveyor::Parser.new.parse(str)
15
17
  Surveyor::Parser.rake_trace "\n"
16
18
  end
17
- def self.rake_trace(str)
19
+ def self.ensure_attrs
18
20
  self.options ||= {}
19
- print str if self.options[:trace] == true
21
+ self.log ||= {}
22
+ self.log[:indent] ||= 0
23
+ self.log[:source] ||= ""
24
+ end
25
+ def self.rake_trace(str, indent_increment=0)
26
+ self.ensure_attrs
27
+ unless str.blank?
28
+ puts "#{' ' * self.log[:indent]}#{str}" if self.options[:trace] == true
29
+ end
30
+ self.log[:indent] += indent_increment
31
+ end
32
+ # from https://github.com/rails/rails/blob/master/actionpack/lib/action_view/template/error.rb#L81
33
+ def self.source_extract(line)
34
+ source_code = self.log[:source].split("\n")
35
+ radius = 3
36
+ start_on_line = [ line - radius - 1, 0 ].max
37
+ end_on_line = [ line + radius - 1, source_code.length].min
38
+
39
+ return unless source_code = source_code[start_on_line..end_on_line]
40
+ line_counter = start_on_line
41
+ source_code.sum do |line|
42
+ line_counter += 1
43
+ "#{line_counter}: #{line}\n"
44
+ end
45
+ end
46
+ def self.raise_error(str, skip_trace = false)
47
+ self.ensure_attrs
48
+ line = caller[1].split('/').last.split(':')[1].to_i
49
+
50
+ raise Surveyor::ParserError, "#{str}\n" if skip_trace
51
+ raise Surveyor::ParserError, "#{self.source_extract(line)}\nline \##{line}: #{str}\n"
20
52
  end
21
53
 
22
54
  # Instance methods
@@ -31,12 +63,14 @@ module Surveyor
31
63
  def method_missing(missing_method, *args, &block)
32
64
  method_name, reference_identifier = missing_method.to_s.split("_", 2)
33
65
  type = full(method_name)
66
+ Surveyor::Parser.raise_error( "\"#{type}\" is not a surveyor method." )if !%w(survey survey_section question_group question dependency dependency_condition answer validation validation_condition).include?(type)
34
67
 
35
- Surveyor::Parser.rake_trace reference_identifier.blank? ? "#{type} " : "#{type}_#{reference_identifier} "
68
+ Surveyor::Parser.rake_trace(reference_identifier.blank? ? "#{type} #{args.map(&:inspect).join ', '}" : "#{type}_#{reference_identifier} #{args.map(&:inspect).join ', '}",
69
+ block_models.include?(type) ? 2 : 0)
36
70
 
37
71
  # check for blocks
38
- raise Surveyor::ParserError, "Error: A #{type.humanize} cannot be empty" if block_models.include?(type) && !block_given?
39
- raise Surveyor::ParserError, "Error: Dropping the #{type.humanize} block like it's hot!" if !block_models.include?(type) && block_given?
72
+ Surveyor::Parser.raise_error "A #{type.humanize.downcase} should take a block" if block_models.include?(type) && !block_given?
73
+ Surveyor::Parser.raise_error "A #{type.humanize.downcase} doesn't take a block" if !block_models.include?(type) && block_given?
40
74
 
41
75
  # parse and build
42
76
  type.classify.constantize.new.extend("SurveyorParser#{type.classify}Methods".constantize).parse_and_build(context, args, method_name, reference_identifier)
@@ -48,9 +82,14 @@ module Surveyor
48
82
  resolve_dependency_condition_references
49
83
  resolve_question_correct_answers
50
84
  report_lost_and_duplicate_references
51
- Surveyor::Parser.rake_trace "\n"
52
- Surveyor::Parser.rake_trace context[:survey].save ? "saved. " : " not saved! #{context[type.to_sym].errors.each_full{|x| x }.join(", ")} "
85
+ Surveyor::Parser.rake_trace("", -2)
86
+ if context[:survey].save
87
+ Surveyor::Parser.rake_trace "Survey saved."
88
+ else
89
+ Surveyor::Parser.raise_error "Survey not saved: #{context[:survey].errors.full_messages.join(", ")}"
90
+ end
53
91
  else
92
+ Surveyor::Parser.rake_trace("", -2)
54
93
  context[type.to_sym].clear(context)
55
94
  end
56
95
  end
@@ -62,8 +101,8 @@ module Surveyor
62
101
  def full(method_name)
63
102
  case method_name.to_s
64
103
  when /^section$/; "survey_section"
65
- when /^g|grid|group|repeater$/; "question_group"
66
- when /^q|label|image$/; "question"
104
+ when /^g$|^grid$|^group$|^repeater$/; "question_group"
105
+ when /^q$|^label$|^image$/; "question"
67
106
  when /^a$/; "answer"
68
107
  when /^d$/; "dependency"
69
108
  when /^c(ondition)?$/; context[:validation] ? "validation_condition" : "dependency_condition"
@@ -77,8 +116,8 @@ module Surveyor
77
116
  %w(survey survey_section question_group)
78
117
  end
79
118
  def report_lost_and_duplicate_references
80
- raise Surveyor::ParserError, "Bad references: #{self.context[:bad_references].join("; ")}" unless self.context[:bad_references].empty?
81
- raise Surveyor::ParserError, "Duplicate references: #{self.context[:duplicate_references].join("; ")}" unless self.context[:duplicate_references].empty?
119
+ Surveyor::Parser.raise_error("Bad references: #{self.context[:bad_references].join("; ")}", true) unless self.context[:bad_references].empty?
120
+ Surveyor::Parser.raise_error("Duplicate references: #{self.context[:duplicate_references].join("; ")}", true) unless self.context[:duplicate_references].empty?
82
121
  end
83
122
  def resolve_question_correct_answers
84
123
  self.context[:questions_with_correct_answers].each do |question_reference_idenitifer, correct_answer_reference|
@@ -126,7 +165,8 @@ module SurveyorParserSurveyMethods
126
165
  :bad_references => [],
127
166
  :duplicate_references => [],
128
167
  :dependency_conditions => [],
129
- :questions_with_correct_answers => {} })
168
+ :questions_with_correct_answers => {}
169
+ })
130
170
  end
131
171
  end
132
172
 
@@ -146,6 +186,7 @@ module SurveyorParserSurveySectionMethods
146
186
  def clear(context)
147
187
  [ :survey_section,
148
188
  :question_group,
189
+ :grid_answers,
149
190
  :question,
150
191
  :dependency,
151
192
  :dependency_condition,
@@ -169,12 +210,14 @@ module SurveyorParserQuestionGroupMethods
169
210
  end
170
211
  def clear(context)
171
212
  [ :question_group,
213
+ :grid_answers,
172
214
  :question,
173
215
  :dependency,
174
216
  :dependency_condition,
175
217
  :answer,
176
218
  :validation,
177
219
  :validation_condition ].each{|k| context.delete k}
220
+ context[:grid_answers] = []
178
221
  end
179
222
  end
180
223
 
@@ -271,8 +314,7 @@ module SurveyorParserAnswerMethods
271
314
 
272
315
  # add answers to grid
273
316
  if context[:question_group] && context[:question_group].display_type == "grid"
274
- context[:grid_answers] ||= []
275
- self.attributes = ({:display_order => [:grid_answers].size}.merge(attrs))
317
+ self.attributes = ({:display_order => context[:grid_answers].size}.merge(attrs))
276
318
  context[:grid_answers] << context[:answer] = self
277
319
  else
278
320
  self.attributes = ({:display_order => context[:question].answers.size}.merge(attrs))
@@ -0,0 +1,55 @@
1
+ module Surveyor
2
+ module SurveyorAdminControllerMethods
3
+ def self.included(base)
4
+ # base.send :before_filter, :get_current_user, :only => [:new, :create]
5
+ # base.send :layout, 'surveyor_default'
6
+ end
7
+
8
+ # Actions
9
+ def new
10
+
11
+ end
12
+
13
+ def create
14
+ end
15
+
16
+
17
+ def show
18
+ end
19
+
20
+ def edit
21
+ end
22
+
23
+ def update
24
+ end
25
+
26
+ private
27
+
28
+ # This is a hoock method for surveyor-using applications to override and provide the context object
29
+ def render_context
30
+ nil
31
+ end
32
+
33
+ # Filters
34
+ def get_current_user
35
+ @current_user = self.respond_to?(:current_user) ? self.current_user : nil
36
+ end
37
+
38
+ def set_render_context
39
+ @render_context = render_context
40
+ end
41
+
42
+ def redirect_with_message(path, message_type, message)
43
+ respond_to do |format|
44
+ format.html do
45
+ flash[message_type] = message if !message.blank? and !message_type.blank?
46
+ redirect_to path
47
+ end
48
+ format.js do
49
+ render :text => message, :status => 403
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -1,3 +1,3 @@
1
1
  module Surveyor
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -2,7 +2,7 @@
2
2
  require 'rubygems'
3
3
  require 'factory_girl'
4
4
 
5
- Factory.sequence(:unique_survey_access_code){|n| "simple_survey" << n.to_s }
5
+ Factory.sequence(:unique_survey_access_code){|n| "simple survey #{UUIDTools::UUID.random_create.to_s}" }
6
6
 
7
7
  Factory.define :survey do |s|
8
8
  s.title {"Simple survey"}
@@ -22,11 +22,15 @@ describe Surveyor::Parser do
22
22
  @parser.send(:full, "condition").should == "dependency_condition"
23
23
  @parser.send(:full, "c").should == "dependency_condition"
24
24
  end
25
+ it "should not translate bad shortcuts" do
26
+ @parser.send(:full, "quack").should == "quack"
27
+ @parser.send(:full, "grizzly").should == "grizzly"
28
+ end
25
29
  it "should identify models that take blocks" do
26
30
  @parser.send(:block_models).should == %w(survey survey_section question_group)
27
31
  end
28
32
  it "should return a survey object" do
29
33
  Surveyor::Parser.new.parse("survey 'hi' do\n end").is_a?(Survey).should be_true
30
34
  end
31
-
35
+
32
36
  end
@@ -78,9 +78,37 @@ describe DependencyCondition do
78
78
  dependency_condition.to_hash(rs).should == {:C => false}
79
79
  end
80
80
 
81
+
82
+ it "should not assume that Response#as is not nil" do
83
+ # q_HEIGHT_FT "Portion of height in whole feet (e.g., 5)",
84
+ # :pick=>:one
85
+ # a :integer
86
+ # a_neg_1 "Refused"
87
+ # a_neg_2 "Don't know"
88
+ # label "Provided value is outside of the suggested range (4 to 7 feet). This value is admissible, but you may wish to verify."
89
+ # dependency :rule=>"A or B"
90
+ # condition_A :q_HEIGHT_FT, "<", {:integer_value => "4"}
91
+ # condition_B :q_HEIGHT_FT, ">", {:integer_value => "7"}
92
+
93
+ answer = Factory(:answer, :response_class => :integer)
94
+ @dependency_condition = DependencyCondition.new(
95
+ :dependency => Factory(:dependency),
96
+ :question => answer.question,
97
+ :answer => answer,
98
+ :operator => ">",
99
+ :integer_value => 4,
100
+ :rule_key => "A")
101
+
102
+ response = Factory(:response, :answer => answer, :question => answer.question)
103
+ response_set = response.response_set
104
+ response.integer_value.should == nil
105
+
106
+ @dependency_condition.to_hash(response_set).should == {:A => false}
107
+ end
108
+
81
109
  describe "evaluate '==' operator" do
82
110
  before(:each) do
83
- @a = Factory(:answer)
111
+ @a = Factory(:answer, :response_class => "answer")
84
112
  @b = Factory(:answer, :question => @a.question)
85
113
  @r = Factory(:response, :question => @a.question, :answer => @a)
86
114
  @rs = @r.response_set
@@ -310,7 +338,7 @@ describe DependencyCondition do
310
338
  end
311
339
 
312
340
  describe "evaluating with response_class string" do
313
- it "should compare answer ids when the string_value is nil" do
341
+ it "should compare answer ids when the dependency condition string_value is nil" do
314
342
  @a = Factory(:answer, :response_class => "string")
315
343
  @b = Factory(:answer, :question => @a.question)
316
344
  @r = Factory(:response, :question => @a.question, :answer => @a, :string_value => "")
@@ -319,7 +347,7 @@ describe DependencyCondition do
319
347
  @dc.to_hash(@rs).should == {:J => true}
320
348
  end
321
349
 
322
- it "should compare strings when the string_value is not nil, even if it is blank" do
350
+ it "should compare strings when the dependency condition string_value is not nil, even if it is blank" do
323
351
  @a = Factory(:answer, :response_class => "string")
324
352
  @b = Factory(:answer, :question => @a.question)
325
353
  @r = Factory(:response, :question => @a.question, :answer => @a, :string_value => "foo")
@@ -389,4 +417,5 @@ describe DependencyCondition do
389
417
  @dc.to_hash(@rs).should == {:M => true}
390
418
  end
391
419
  end
420
+
392
421
  end
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: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-16 00:00:00.000000000 Z
13
+ date: 2012-10-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -505,6 +505,7 @@ files:
505
505
  - lib/surveyor/parser.rb
506
506
  - lib/surveyor/redcap_parser.rb
507
507
  - lib/surveyor/render_text.rb
508
+ - lib/surveyor/surveyor_admin_controller_methods.rb
508
509
  - lib/surveyor/surveyor_controller_methods.rb
509
510
  - lib/surveyor/unparser.rb
510
511
  - lib/surveyor/version.rb