surveyor 0.19.1 → 0.19.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/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ 0.19.2
2
+
3
+ * quiz example
4
+ * support correct answers for quizes through dsl. closes #105
5
+ * test dependency issues. closes #73
6
+ * fixing feature, section menu doens't appear until three sections exist
7
+ * fixing default values to only appear when response is blank
8
+ * fixing typo in specs. fixing cucumber on hudson due to residual objects in db from specs
9
+ * tweak to check hudson cucumber issue
10
+ * added dump rake task. thanks bnadav. closes #100
11
+
1
12
  0.19.1
2
13
 
3
14
  * require formtastic. closes #104
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.19.1
1
+ 0.19.2
@@ -14,6 +14,6 @@
14
14
  - when "none"
15
15
  - if %w(date datetime time float integer string text).include? a.response_class
16
16
  = ff.quiet_input :answer_id, :input_html => {:class => a.css_class, :value => a.id}
17
- = ff.input rc_to_attr(a.response_class), :as => rc_to_as(a.response_class), :label => a.split_or_hidden_text(:pre).blank? ? false : a.split_or_hidden_text(:pre), :hint => a.split_or_hidden_text(:post), :input_html => {:value => a.default_value}
17
+ = ff.input rc_to_attr(a.response_class), :as => rc_to_as(a.response_class), :label => a.split_or_hidden_text(:pre).blank? ? false : a.split_or_hidden_text(:pre), :hint => a.split_or_hidden_text(:post), :input_html => (r.as(a.response_class).blank? ? {:value => a.default_value} : {})
18
18
  - else
19
19
  = a.text
@@ -69,3 +69,9 @@ Then /^there should be (\d+) validation_condition(?:s?) with:$/ do |x, table|
69
69
  ValidationCondition.find(:first, :conditions => hash).should_not be_nil
70
70
  end
71
71
  end
72
+
73
+ Then /^question "([^"]*)" should have correct answer "([^"]*)"$/ do |qr, ar|
74
+ (q = Question.find_by_reference_identifier(qr)).should_not be_nil
75
+ q.correct_answer.should == q.answers.find_by_reference_identifier(ar)
76
+ end
77
+
@@ -7,5 +7,28 @@ end
7
7
  Then /^there should be (\d+) response set with (\d+) responses with:$/ do |rs_num, r_num, table|
8
8
  ResponseSet.count.should == rs_num.to_i
9
9
  Response.count.should == r_num.to_i
10
- # table is a Cucumber::Ast::Table
10
+ table.hashes.each do |hash|
11
+ if hash.keys == ["answer"]
12
+ a = Answer.find_by_text(hash["answer"])
13
+ a.should_not be_nil
14
+ Response.first(:conditions => {:answer_id => a.id}).should_not be_nil
15
+ else
16
+ if !(a = hash.delete("answer")).blank? and !(answer = Answer.find_by_text(a)).blank?
17
+ Response.first(:conditions => hash.merge({:answer_id => answer.id})).should_not be_nil
18
+ elsif
19
+ Response.first(:conditions => hash).should_not be_nil
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ Then /^there should be (\d+) dependencies$/ do |x|
26
+ Dependency.count.should == x.to_i
27
+ end
28
+
29
+ Then /^question "([^"]*)" should have a dependency with rule "([^"]*)"$/ do |qr, rule|
30
+ q = Question.find_by_reference_identifier(qr)
31
+ q.should_not be_blank
32
+ q.dependency.should_not be_nil
33
+ q.dependency.rule.should == rule
11
34
  end
@@ -25,13 +25,14 @@ Feature: Survey creation
25
25
  end
26
26
  """
27
27
  When I start the "Favorites" survey
28
+ Then I should see "You with the sad eyes don't be discouraged"
28
29
  And I choose "red"
29
30
  And I choose "blue"
30
31
  And I check "orange"
31
32
  And I check "brown"
32
33
  And I press "Click here to finish"
33
34
  Then there should be 1 response set with 3 responses with:
34
- | to_s |
35
+ | answer |
35
36
  | blue |
36
37
  | orange |
37
38
  | brown |
@@ -42,12 +43,40 @@ Feature: Survey creation
42
43
  survey "Favorites" do
43
44
  section "Foods" do
44
45
  question_1 "What is your favorite food?"
45
- answer :string, :default_value => "beef"
46
+ answer "food", :string, :default_value => "beef"
47
+ end
48
+ section "Section 2" do
49
+ end
50
+ section "Section 3" do
46
51
  end
47
52
  end
48
53
  """
49
54
  When I start the "Favorites" survey
55
+ And I press "Section 3"
50
56
  And I press "Click here to finish"
51
57
  Then there should be 1 response set with 1 responses with:
52
- | to_s |
53
- | clear |
58
+ | string_value |
59
+ | beef |
60
+
61
+ When I start the "Favorites" survey
62
+ And I fill in "food" with "chicken"
63
+ And I press "Foods"
64
+ And I press "Section 3"
65
+ And I press "Click here to finish"
66
+ Then there should be 2 response set with 2 responses with:
67
+ | string_value |
68
+ | chicken |
69
+
70
+ Scenario: Quiz time
71
+ Given the survey
72
+ """
73
+ survey "Favorites" do
74
+ section "Foods" do
75
+ question_1 "What is the best meat?", :pick => :one, :correct => "oink"
76
+ a_oink "bacon"
77
+ a_tweet "chicken"
78
+ a_moo "beef"
79
+ end
80
+ end
81
+ """
82
+ Then question "1" should have correct answer "oink"
@@ -155,3 +155,47 @@ Feature: Survey creation
155
155
  And there should be 2 validation_conditions with:
156
156
  | rule_key | integer_value |
157
157
  | A | 0 |
158
+
159
+ Scenario: Dependencies and validations
160
+ Given I parse
161
+ """
162
+ survey "dependency test" do
163
+ section "section 1" do
164
+
165
+ q_copd_sh_1 "Have you ever smoked cigarettes?",:pick=>:one,:help_text=>"NO means less than 20 packs of cigarettes or 12 oz. of tobacco in a lifetime or less than 1 cigarette a day for 1 year."
166
+ a_1 "Yes"
167
+ a_2 "No"
168
+
169
+ q_copd_sh_1a "How old were you when you first started smoking cigarettes?", :help_text=>"age in years"
170
+ a :integer
171
+ dependency :rule => "A"
172
+ condition_A :q_copd_sh_1, "==", :a_1
173
+
174
+ q_copd_sh_1b "Do you currently smoke cigarettes?",:pick=>:one, :help_text=>"as of 1 month ago"
175
+ a_1 "Yes"
176
+ a_2 "No"
177
+ dependency :rule => "B"
178
+ condition_B :q_copd_sh_1, "==", :a_1
179
+
180
+ q_copd_sh_1c "On the average of the entire time you smoked, how many cigarettes did you smoke per day?"
181
+ a :integer
182
+ dependency :rule => "C"
183
+ condition_C :q_copd_sh_1, "==", :a_1
184
+
185
+ q_copd_sh_1bb "How many cigarettes do you smoke per day now?"
186
+ a_2 "integer"
187
+ dependency :rule => "D"
188
+ condition_D :q_copd_sh_1b, "==", :a_1
189
+
190
+
191
+ q_copd_sh_1ba "How old were you when you stopped?"
192
+ a "Years", :integer
193
+ dependency :rule => "E"
194
+ condition_E :q_copd_sh_1b, "==", :a_2
195
+
196
+ end
197
+ end
198
+ """
199
+ Then there should be 5 dependencies
200
+ And question "copd_sh_1a" should have a dependency with rule "A"
201
+ And question "copd_sh_1ba" should have a dependency with rule "E"
@@ -54,8 +54,8 @@ class SurveyorGenerator < Rails::Generator::Base
54
54
  end
55
55
 
56
56
  # Surveys
57
- m.directory "surveys/fixtures"
58
57
  m.file "surveys/kitchen_sink_survey.rb", "surveys/kitchen_sink_survey.rb"
58
+ m.file "surveys/quiz.rb", "surveys/quiz.rb"
59
59
 
60
60
  m.readme "README"
61
61
 
@@ -0,0 +1,10 @@
1
+ survey "Favorites" do
2
+ section "Foods" do
3
+ # In a quiz, both the questions and the answers need to have reference identifiers
4
+ # Here, the question has reference_identifier: "1", and the answers: "oint", "tweet", and "moo"
5
+ question_1 "What is the best meat?", :pick => :one, :correct => "oink"
6
+ a_oink "bacon"
7
+ a_tweet "chicken"
8
+ a_moo "beef"
9
+ end
10
+ end
@@ -7,6 +7,7 @@ module Surveyor
7
7
  base.send :belongs_to, :question_group, :dependent => :destroy
8
8
  base.send :has_many, :answers, :order => "display_order ASC", :dependent => :destroy # it might not always have answers
9
9
  base.send :has_one, :dependency, :dependent => :destroy
10
+ base.send :has_one, :correct_answer, :class_name => "Answer", :dependent => :destroy
10
11
 
11
12
  # Scopes
12
13
  base.send :default_scope, :order => "display_order ASC"
@@ -58,15 +58,15 @@ module Surveyor
58
58
  super
59
59
  end
60
60
 
61
- def to_csv
61
+ def to_csv(access_code = false, print_header = true)
62
62
  qcols = Question.content_columns.map(&:name) - %w(created_at updated_at)
63
63
  acols = Answer.content_columns.map(&:name) - %w(created_at updated_at)
64
64
  rcols = Response.content_columns.map(&:name)
65
65
  require 'fastercsv'
66
66
  FCSV(result = "") do |csv|
67
- csv << qcols.map{|qcol| "question.#{qcol}"} + acols.map{|acol| "answer.#{acol}"} + rcols.map{|rcol| "response.#{rcol}"}
67
+ csv << (access_code ? ["response set access code"] : []) + qcols.map{|qcol| "question.#{qcol}"} + acols.map{|acol| "answer.#{acol}"} + rcols.map{|rcol| "response.#{rcol}"} if print_header
68
68
  responses.each do |response|
69
- csv << qcols.map{|qcol| response.question.send(qcol)} + acols.map{|acol| response.answer.send(acol)} + rcols.map{|rcol| response.send(rcol)}
69
+ csv << (access_code ? [self.access_code] : []) + qcols.map{|qcol| response.question.send(qcol)} + acols.map{|acol| response.answer.send(acol)} + rcols.map{|rcol| response.send(rcol)}
70
70
  end
71
71
  end
72
72
  result
@@ -130,4 +130,4 @@ module Surveyor
130
130
  end
131
131
  end
132
132
  end
133
- end
133
+ end
@@ -73,7 +73,7 @@ class Survey < ActiveRecord::Base
73
73
 
74
74
  def self.parse_and_build(context, args, original_method, reference_identifier)
75
75
  # clear context
76
- context.delete_if{|k,v| true}
76
+ context.delete_if{|k,v| true }
77
77
  context[:question_references] = {}
78
78
  context[:answer_references] = {}
79
79
 
@@ -83,7 +83,7 @@ class Survey < ActiveRecord::Base
83
83
  :reference_identifier => reference_identifier}.merge(args[1] || {}))
84
84
  end
85
85
  def clear(context)
86
- context.delete_if{|k,v| true}
86
+ context.delete_if{|k,v| true }
87
87
  context[:question_references] = {}
88
88
  context[:answer_references] = {}
89
89
  end
@@ -93,14 +93,14 @@ class SurveySection < ActiveRecord::Base
93
93
 
94
94
  def self.parse_and_build(context, args, original_method, reference_identifier)
95
95
  # clear context
96
- context.delete_if{|k,v| k != :survey && k != :question_references && k != :answer_references}
96
+ context.delete_if{|k,v| !%w(survey question_references answer_references).map(&:to_sym).include?(k)}
97
97
 
98
98
  # build and set context
99
99
  title = args[0]
100
100
  context[:survey_section] = context[:survey].sections.build({ :title => title }.merge(args[1] || {}))
101
101
  end
102
102
  def clear(context)
103
- context.delete_if{|k,v| k != :survey && k != :question_references && k != :answer_references}
103
+ context.delete_if{|k,v| !%w(survey question_references answer_references).map(&:to_sym).include?(k)}
104
104
  end
105
105
  end
106
106
  class QuestionGroup < ActiveRecord::Base
@@ -108,7 +108,7 @@ class QuestionGroup < ActiveRecord::Base
108
108
 
109
109
  def self.parse_and_build(context, args, original_method, reference_identifier)
110
110
  # clear context
111
- context.delete_if{|k,v| k != :survey && k != :survey_section && k != :question_references && k != :answer_references}
111
+ context.delete_if{|k,v| !%w(survey survey_section question_references answer_references).map(&:to_sym).include?(k)}
112
112
 
113
113
  # build and set context
114
114
  context[:question_group] = context[:question_group] = new({ :text => args[0] || "Question Group",
@@ -116,12 +116,16 @@ class QuestionGroup < ActiveRecord::Base
116
116
 
117
117
  end
118
118
  def clear(context)
119
- context.delete_if{|k,v| k != :survey && k != :survey_section && k != :question_references && k != :answer_references}
119
+ context.delete_if{|k,v| !%w(survey survey_section question_references answer_references).map(&:to_sym).include?(k)}
120
120
  end
121
121
  end
122
122
  class Question < ActiveRecord::Base
123
123
  # nonblock
124
124
 
125
+ # attributes
126
+ attr_accessor :correct, :context_reference
127
+ before_save :resolve_correct_answers
128
+
125
129
  def self.parse_and_build(context, args, original_method, reference_identifier)
126
130
  # clear context
127
131
  context.delete_if{|k,v| %w(question dependency dependency_condition answer validation validation_condition).map(&:to_sym).include? k}
@@ -129,6 +133,7 @@ class Question < ActiveRecord::Base
129
133
  # build and set context
130
134
  text = args[0] || "Question"
131
135
  context[:question] = context[:survey_section].questions.build({
136
+ :context_reference => context,
132
137
  :question_group => context[:question_group],
133
138
  :reference_identifier => reference_identifier,
134
139
  :text => text,
@@ -146,6 +151,14 @@ class Question < ActiveRecord::Base
146
151
  end
147
152
  end
148
153
  end
154
+
155
+ def resolve_correct_answers
156
+ unless correct.blank? or reference_identifier.blank? or context_reference.blank?
157
+ # Looking up references for quiz answers
158
+ context_reference[:answer_references][reference_identifier] ||= {}
159
+ print (self.correct_answer = context_reference[:answer_references][reference_identifier][correct]) ? "found correct answer:#{correct} " : "lost! correct answer:#{correct} "
160
+ end
161
+ end
149
162
  end
150
163
  class Dependency < ActiveRecord::Base
151
164
  # nonblock
@@ -60,4 +60,17 @@ namespace :surveyor do
60
60
  puts "There are no surveys without response sets"
61
61
  end
62
62
  end
63
- end
63
+ desc "dump all responses to a given survey"
64
+ task :dump => :environment do
65
+ require 'fileutils.rb'
66
+ raise "USAGE: rake surveyor:dump SURVEY_ACCESS_CODE=<access_code> [OUTPUT_DIR=<dir>]" unless ENV["SURVEY_ACCESS_CODE"]
67
+ survey = Survey.find_by_access_code(ENV["SURVEY_ACCESS_CODE"])
68
+ raise "No Survey found with code " + ENV["SURVEY_ACCESS_CODE"] unless survey
69
+ dir = ENV["OUTPUT_DIR"] || Rails.root
70
+ mkpath(dir) # Create all non-existent directories
71
+ full_path = File.join(dir,"#{survey.access_code}_#{Time.now.to_i}.csv")
72
+ File.open(full_path, 'w') do |f|
73
+ survey.response_sets.each_with_index{|r,i| f.write(r.to_csv(true, i == 0)) } # print access code every time, print_header first time
74
+ end
75
+ end
76
+ end
@@ -79,11 +79,13 @@ describe Dependency, "when evaluating dependency conditions of a question in a r
79
79
  end
80
80
  end
81
81
  describe Dependency, "with conditions" do
82
- @dependency = Dependency.new(:rule => "A and B and C", :question_id => 1)
83
- Factory(:dependency_condition, :dependency => @dependency, :rule_key => "A")
84
- Factory(:dependency_condition, :dependency => @dependency, :rule_key => "B")
85
- Factory(:dependency_condition, :dependency => @dependency, :rule_key => "C")
86
- dc_ids = @dependency.dependency_conditions.map(&:id)
87
- @dependency.destroy
88
- dc_ids.each{|id| DependencyCondition.find_by_id(id).should == nil}
82
+ it "should destroy conditions when destroyed" do
83
+ @dependency = Dependency.new(:rule => "A and B and C", :question_id => 1)
84
+ Factory(:dependency_condition, :dependency => @dependency, :rule_key => "A")
85
+ Factory(:dependency_condition, :dependency => @dependency, :rule_key => "B")
86
+ Factory(:dependency_condition, :dependency => @dependency, :rule_key => "C")
87
+ dc_ids = @dependency.dependency_conditions.map(&:id)
88
+ @dependency.destroy
89
+ dc_ids.each{|id| DependencyCondition.find_by_id(id).should == nil}
90
+ end
89
91
  end
@@ -50,20 +50,15 @@ describe Validation, "reporting its status" do
50
50
  it "should validate a response by regexp" do
51
51
  test_var({}, [{:operator => "=~", :regexp => /^[a-z]{1,6}$/}], {:response_class => "string"}, {:string_value => ""}).should be_false
52
52
  end
53
- it "should validate a response by (in)equality" do
54
- # test_var({:operator => "!=", :datetime_value => Date.today + 1}, {:response_class => "date"}, {:datetime_value => Date.today}).should be_true
55
- # test_var({:operator => "==", :answer_id => 2}, {:response_class => "answer"}, {:answer_id => 2}).should be_false
56
- end
57
- it "should validate a response by lookup" do
58
-
59
- end
60
53
  end
61
54
  describe Validation, "with conditions" do
62
- @validation = Factory(:validation)
63
- Factory(:validation_condition, :validation => @validation, :rule_key => "A")
64
- Factory(:validation_condition, :validation => @validation, :rule_key => "B")
65
- Factory(:validation_condition, :validation => @validation, :rule_key => "C")
66
- v_ids = @validation.validation_conditions.map(&:id)
67
- @validation.destroy
68
- v_ids.each{|id| DependencyCondition.find_by_id(id).should == nil}
55
+ it "should destroy conditions when destroyed" do
56
+ @validation = Factory(:validation)
57
+ Factory(:validation_condition, :validation => @validation, :rule_key => "A")
58
+ Factory(:validation_condition, :validation => @validation, :rule_key => "B")
59
+ Factory(:validation_condition, :validation => @validation, :rule_key => "C")
60
+ v_ids = @validation.validation_conditions.map(&:id)
61
+ @validation.destroy
62
+ v_ids.each{|id| DependencyCondition.find_by_id(id).should == nil}
63
+ end
69
64
  end
data/surveyor.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{surveyor}
8
- s.version = "0.19.1"
8
+ s.version = "0.19.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"]
12
- s.date = %q{2011-02-02}
12
+ s.date = %q{2011-02-09}
13
13
  s.email = %q{yoon@northwestern.edu}
14
14
  s.extra_rdoc_files = [
15
15
  "README.md"
@@ -98,6 +98,7 @@ Gem::Specification.new do |s|
98
98
  "generators/surveyor/templates/migrate/create_validation_conditions.rb",
99
99
  "generators/surveyor/templates/migrate/create_validations.rb",
100
100
  "generators/surveyor/templates/surveys/kitchen_sink_survey.rb",
101
+ "generators/surveyor/templates/surveys/quiz.rb",
101
102
  "generators/surveyor/templates/tasks/surveyor.rb",
102
103
  "hudson.rakefile",
103
104
  "init_testbed.rakefile",
@@ -149,7 +150,7 @@ Gem::Specification.new do |s|
149
150
  s.homepage = %q{http://github.com/breakpointer/surveyor}
150
151
  s.rdoc_options = ["--charset=UTF-8"]
151
152
  s.require_paths = ["lib"]
152
- s.rubygems_version = %q{1.4.2}
153
+ s.rubygems_version = %q{1.3.7}
153
154
  s.summary = %q{A rails (gem) plugin to enable surveys in your application}
154
155
  s.test_files = [
155
156
  "spec/controllers/surveyor_controller_spec.rb",
@@ -174,6 +175,7 @@ Gem::Specification.new do |s|
174
175
  ]
175
176
 
176
177
  if s.respond_to? :specification_version then
178
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
177
179
  s.specification_version = 3
178
180
 
179
181
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: surveyor
3
3
  version: !ruby/object:Gem::Version
4
- hash: 81
5
- prerelease:
4
+ hash: 87
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 19
9
- - 1
10
- version: 0.19.1
9
+ - 2
10
+ version: 0.19.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian Chamberlain
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-02-02 00:00:00 -06:00
19
+ date: 2011-02-09 00:00:00 -06:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -167,6 +167,7 @@ files:
167
167
  - generators/surveyor/templates/migrate/create_validation_conditions.rb
168
168
  - generators/surveyor/templates/migrate/create_validations.rb
169
169
  - generators/surveyor/templates/surveys/kitchen_sink_survey.rb
170
+ - generators/surveyor/templates/surveys/quiz.rb
170
171
  - generators/surveyor/templates/tasks/surveyor.rb
171
172
  - hudson.rakefile
172
173
  - init_testbed.rakefile
@@ -244,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
245
  requirements: []
245
246
 
246
247
  rubyforge_project:
247
- rubygems_version: 1.4.2
248
+ rubygems_version: 1.3.7
248
249
  signing_key:
249
250
  specification_version: 3
250
251
  summary: A rails (gem) plugin to enable surveys in your application