surveyor 0.11.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Survey On Rails
1
+ # Surveys On Rails
2
2
 
3
3
  Surveyor is a rails (gem) plugin, that brings surveys to your rails app. Before Rails 2.3, it was implemented as a Rails Engine. Surveys are written in a DSL (Domain Specific Language), with examples available in the "kitchen sink" survey.
4
4
 
@@ -58,15 +58,23 @@ The survey above shows a couple simple question types. The first one is a "pick
58
58
  As a plugin:
59
59
 
60
60
  gem install haml
61
- script/plugin install git://github.com/breakpointer/surveyor.git -r 'tag v0.10.0'
61
+ gem install fastercsv
62
+ script/plugin install git://github.com/breakpointer/surveyor.git -r 'tag v0.12.0'
62
63
 
63
- Or as a gem plugin:
64
+ Or as a gem:
64
65
 
65
66
  # in environment.rb
66
- config.gem "surveyor", :version => '~> 0.10.0', :source => 'http://gemcutter.org'
67
+ config.gem "surveyor", :version => '~> 0.12.0', :source => 'http://gemcutter.org'
67
68
 
68
69
  rake gems:install
69
70
 
71
+ Or as a gem (with bundler):
72
+
73
+ # in environment.rb
74
+ gem "surveyor", '~> 0.12.0'
75
+
76
+ bundle install
77
+
70
78
  Generate assets, run migrations:
71
79
 
72
80
  script/generate surveyor
@@ -111,7 +119,7 @@ The initializer runs once, when the app starts. The block style is used to keep
111
119
  config['default.layout'] = nil # "surveyor_default"
112
120
  config['default.index'] = nil # "/surveys" # or :index_path_method
113
121
  config['default.finish'] = nil # "/surveys" # or :finish_path_method
114
- config['use_restful_authentication'] = false # set to true to use restful authentication
122
+ #config['authentication_method'] = :login_required # set to true to use restful authentication
115
123
  config['extend'] = %w() # %w(survey surveyor_helper surveyor_controller)
116
124
  end
117
125
 
@@ -165,7 +173,7 @@ The <code>surveyor\_includes</code> helper just calls <code>surveyor\_stylsheets
165
173
 
166
174
  # Dependencices
167
175
 
168
- Surveyor depends on Rails 2.3 and the SASS style sheet language, part of HAML (http://haml.hamptoncatlin.com/download). For running the test suite you will need rspec and have the rspec plugin installed in your application.
176
+ Surveyor depends on Ruby (1.8.7 - 1.9.1), Rails 2.3 and the SASS style sheet language, part of HAML (http://haml.hamptoncatlin.com/download). It also depends on fastercsv for csv exports. For running the test suite you will need rspec and have the rspec plugin installed in your application.
169
177
 
170
178
  # Test Suite and Development
171
179
 
@@ -174,6 +182,16 @@ To work on the plugin code (for enhancements, and bug fixes, etc...) fork this g
174
182
 
175
183
  # Changes
176
184
 
185
+ 0.12.0
186
+
187
+ * fix parser error in ruby 1.9, where instance_variables are symbols. closes #61
188
+ * added fastercsv as dependency. closes #59
189
+ * typo fix and test
190
+ * fixed broken spec for survey urls, made pending surveyor_controller specs pass
191
+ * Added explicit dependencycondition and validationcondition to DSL
192
+ * have authentication work with authlogic
193
+ * added "correct_answer" to parser, so you can specify one correct answer per question
194
+
177
195
  0.11.0
178
196
 
179
197
  * basic csv export. closes #21
data/Rakefile CHANGED
@@ -10,6 +10,7 @@ begin
10
10
  gem.homepage = "http://github.com/breakpointer/surveyor"
11
11
  gem.authors = ["Brian Chamberlain", "Mark Yoon"]
12
12
  gem.add_dependency 'haml'
13
+ gem.add_dependency 'fastercsv'
13
14
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
15
  end
15
16
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.0
1
+ 0.12.1
@@ -11,9 +11,8 @@ class SurveyorController < ApplicationController
11
11
  before_filter :extend_actions
12
12
 
13
13
  # RESTful authentication
14
- if Surveyor::Config['use_restful_authentication']
15
- include AuthenticatedSystem
16
- before_filter :login_required
14
+ if Surveyor::Config['authentication_method']
15
+ before_filter Surveyor::Config['authentication_method']
17
16
  end
18
17
 
19
18
  # Get the response set or current_user
@@ -40,11 +39,16 @@ class SurveyorController < ApplicationController
40
39
 
41
40
  def show
42
41
  @response_set = ResponseSet.find_by_access_code(params[:response_set_code], :include => {:responses => [:question, :answer]})
43
- respond_to do |format|
44
- format.html #{render :action => :show}
45
- format.csv {
46
- send_data(@response_set.to_csv, :type => 'text/csv; charset=utf-8; header=present',:filename => "#{@response_set.updated_at.strftime('%Y-%m-%d')}_#{@response_set.access_code}.csv")
47
- }
42
+ if @response_set
43
+ respond_to do |format|
44
+ format.html #{render :action => :show}
45
+ format.csv {
46
+ send_data(@response_set.to_csv, :type => 'text/csv; charset=utf-8; header=present',:filename => "#{@response_set.updated_at.strftime('%Y-%m-%d')}_#{@response_set.access_code}.csv")
47
+ }
48
+ end
49
+ else
50
+ flash[:notice] = "Unable to find your responses to the survey"
51
+ redirect_to(available_surveys_path)
48
52
  end
49
53
  end
50
54
 
@@ -46,20 +46,27 @@ module SurveyParser
46
46
 
47
47
  # Filter out attributes that shouldn't be in fixtures, including children, parser, placeholders
48
48
  def yml_attrs
49
- instance_variables.sort - self.class.children.map{|model| "@#{model.to_s}"} - %w(@id @parser @dependency @validation @question_reference @answer_reference)
49
+ instance_variables.sort.map(&:to_s) - self.class.children.map{|model| "@#{model.to_s}"} - %w(@id @parser @dependency @validation @question_reference @answer_reference)
50
50
  end
51
+
51
52
  def to_yml
52
53
  out = [ %(#{self.parser.salt}_#{self.class.name.demodulize.underscore}_#{@id}:) ]
53
54
  yml_attrs.each{|a| out << associate_and_format(a)}
54
55
  (out << nil ).join("\r\n")
55
56
  end
57
+
56
58
  def associate_and_format(a)
57
59
  if a =~ /_id$/ # a foreign key, e.g. survey_id
58
- " #{a[1..-4]}: " + (instance_variable_get(a).nil? ? "" : "#{self.parser.salt}_#{a[1..-4]}_#{instance_variable_get(a)}")
60
+ " #{property_name_map(a[1..-4])}: " + (instance_variable_get(a).nil? ? "" : "#{self.parser.salt}_#{a[1..-4]}_#{instance_variable_get(a)}")
59
61
  else # quote strings
60
- " #{a[1..-1]}: #{instance_variable_get(a).is_a?(String) ? "\"#{instance_variable_get(a)}\"" : instance_variable_get(a) }"
62
+ " #{property_name_map(a[1..-1])}: #{instance_variable_get(a).is_a?(String) ? "\"#{instance_variable_get(a)}\"" : instance_variable_get(a) }"
61
63
  end
62
64
  end
65
+
66
+ def property_name_map(property)
67
+ return property
68
+ end
69
+
63
70
  def to_file
64
71
  File.open(self.parser.send("#{self.class.name.demodulize.underscore.pluralize}_yml"), File::CREAT|File::APPEND|File::WRONLY) {|f| f << to_yml}
65
72
  self.class.children.each{|model| self.send(model).compact.map(&:to_file)}
@@ -92,11 +92,35 @@ module SurveyParser
92
92
  raise "Error: No current question" if self.current_question.nil?
93
93
  self.current_answer = Answer.new(self.current_question, args, opts.merge(:display_order => current_question.answers.size + 1))
94
94
  end
95
+
96
+ when "correct"
97
+ drop_the &block
98
+ raise "Error: No current question" if self.current_question.nil?
99
+ self.current_correct_answer = self.current_question.find_current_answers(args)
95
100
 
96
101
  when "validation", "v"
97
102
  drop_the &block
98
103
  self.current_validation = Validation.new(self.current_answer, args, opts)
99
104
 
105
+
106
+ # explicitly define a dependency condition
107
+ # (not really necessary as is default)
108
+ when "dependencycondition", "dcondition", "dc"
109
+ drop_the &block
110
+ raise "Error: No current dependency for this condition" if self.current_dependency.nil?
111
+ self.current_dependency.dependency_conditions << DependencyCondition.new(self.current_dependency, args, opts)
112
+
113
+ # explicitly define a validation condition
114
+ # (is necessary if want dependency AND validation on
115
+ # same question as dependency existance would try to
116
+ # make the condition a dependency condition.)
117
+ when "validationcondition", "vcondition", "vc"
118
+ drop_the &block
119
+ raise "Error: No current validation for this condition" if self.current_validation.nil?
120
+ self.current_validation.validation_conditions << ValidationCondition.new(self.current_validation, args, opts)
121
+
122
+
123
+
100
124
  else
101
125
  raise " ERROR: '#{missing_method}' not valid method"
102
126
 
@@ -135,31 +159,42 @@ module SurveyParser
135
159
  self.surveys << s
136
160
  @current_survey = s
137
161
  end
162
+
138
163
  def current_survey_section=(s)
139
164
  clear_current "survey_section"
140
165
  self.current_survey.survey_sections << s
141
166
  @current_survey_section = s
142
167
  end
168
+
143
169
  def current_question_group=(g)
144
170
  clear_current "question_group"
145
171
  self.current_survey_section.question_groups << g
146
172
  @current_question_group = g
147
- end
173
+ end
174
+
148
175
  def current_question=(q)
149
176
  clear_current "question"
150
177
  self.current_survey_section.questions << q
151
178
  @current_question = q
152
179
  end
180
+
153
181
  def current_dependency=(d)
154
182
  raise "Error: No question or question group" unless (dependent = self.current_question_group || self.current_question)
155
183
  dependent.dependency = d
156
184
  @current_dependency = d
157
185
  end
186
+
158
187
  def current_answer=(a)
159
188
  raise "Error: No current question" if self.current_question.nil?
160
189
  self.current_question.answers << a
161
190
  @current_answer = a
162
- end
191
+ end
192
+
193
+ def current_correct_answer=(a)
194
+ raise "Error: No current question" if self.current_question.nil?
195
+ self.current_question.correct_answer = a
196
+ end
197
+
163
198
  def current_validation=(v)
164
199
  clear_current "validation"
165
200
  self.current_answer.validation = v
@@ -185,4 +220,4 @@ module SurveyParser
185
220
  end
186
221
 
187
222
  end
188
- end
223
+ end
@@ -1,13 +1,15 @@
1
1
  module SurveyParser
2
2
  class Question < SurveyParser::Base
3
+ ANSWER_ID = /\s*\w+_/ unless defined?(ANSWER_ID)
4
+
3
5
  # 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 :id, :parser, :survey_section_id, :question_group_id, :correct_answer_id
7
+ attr_accessor :text, :short_text, :help_text, :pick, :answer_id
6
8
  attr_accessor :reference_identifier, :data_export_identifier, :common_namespace, :common_identifier
7
9
  attr_accessor :display_order, :display_type, :is_mandatory, :display_width, :custom_class, :custom_renderer
8
10
  attr_accessor :dependency
9
11
  has_children :answers
10
-
12
+
11
13
  def default_options
12
14
  { :pick => :none,
13
15
  :display_type => :default,
@@ -15,17 +17,38 @@ module SurveyParser
15
17
  :display_order => self.id
16
18
  }
17
19
  end
20
+
18
21
  def parse_opts(opts)
19
22
  (name = opts.delete(:method_name)) =~ /label|image/ ? opts.merge(:display_type => name) : opts
20
23
  end
24
+
21
25
  def parse_args(args)
22
26
  text = args[0] || "Question"
23
27
  {:text => text, :short_text => text, :data_export_identifier => Surveyor.to_normalized_string(text)}.merge(args[1] || {})
24
28
  end
29
+
30
+ def correct_answer=(a)
31
+ self.answer_id = a.id
32
+ end
25
33
 
26
34
  def find_answer_by_reference(ref_id)
27
35
  self.answers.detect{|a| a.reference_identifier == ref_id}
28
36
  end
37
+
38
+ # currently, only one correct answer is allowed
39
+ def find_current_answers(args)
40
+ ref_ids = args[0][:answer]
41
+ ids = ref_ids.to_s.split(ANSWER_ID).compact
42
+ self.answers.select{|a| ids.include?(a.reference_identifier)}.first
43
+ end
44
+
45
+ # so we can build the correct yaml structure
46
+ def property_name_map(property)
47
+ names = {
48
+ "answer" => "correct_answer"
49
+ }
50
+ return names.has_key?(property) ? names[property] : property
51
+ end
29
52
 
30
53
  def to_file
31
54
  super
@@ -26,31 +26,33 @@ describe SurveyorController do
26
26
  response.should be_success
27
27
  response.should render_template('new')
28
28
  end
29
+
29
30
  it "should find all surveys" do
30
31
  Survey.should_receive(:find).with(:all).and_return([@survey])
31
32
  do_get
32
33
  end
34
+
33
35
  it "should assign the found surveys for the view" do
34
36
  do_get
35
37
  assigns[:surveys].should == [@survey]
36
38
  end
37
39
  end
38
40
 
39
- describe "take survey: POST /surveys/XYZ" do
41
+ describe "take survey: POST /surveys/xyz" do
40
42
 
41
43
  before(:each) do
42
- @survey = Factory(:survey, :title => "XYZ", :access_code => "XYZ")
43
- @response_set = Factory(:response_set, :access_code => "PDQ")
44
+ @survey = Factory(:survey, :title => "xyz", :access_code => "xyz")
45
+ @response_set = Factory(:response_set, :access_code => "pdq")
44
46
  ResponseSet.stub!(:create).and_return(@response_set)
45
47
  Survey.stub!(:find_by_access_code).and_return(@survey)
46
48
  end
47
49
 
48
50
  describe "with success" do
49
51
  def do_post
50
- post :create, :survey_code => "XYZ"
52
+ post :create, :survey_code => "xyz"
51
53
  end
52
54
  it "should look for the survey" do
53
- Survey.should_receive(:find_by_access_code).with("XYZ").and_return(@survey)
55
+ Survey.should_receive(:find_by_access_code).with("xyz").and_return(@survey)
54
56
  do_post
55
57
  end
56
58
  it "should create a new response_set" do
@@ -59,7 +61,7 @@ describe SurveyorController do
59
61
  end
60
62
  it "should redirect to the new response_set" do
61
63
  do_post
62
- response.should redirect_to(edit_my_survey_url(:survey_code => "XYZ", :response_set_code => "PDQ"))
64
+ response.should redirect_to(edit_my_survey_url(:survey_code => "xyz", :response_set_code => "pdq"))
63
65
  end
64
66
  end
65
67
 
@@ -77,47 +79,42 @@ describe SurveyorController do
77
79
  end
78
80
  end
79
81
 
80
- describe "view my survey: GET /surveys/XYZ/PDQ" do
82
+ describe "view my survey: GET /surveys/xyz/pdq" do
81
83
 
82
84
  before(:each) do
83
- @survey = Factory(:survey, :title => "XYZ", :access_code => "XYZ", :sections => [Factory(:survey_section)])
84
- @response_set = Factory(:response_set, :access_code => "PDQ", :survey => @survey)
85
+ @survey = Factory(:survey, :title => "xyz", :access_code => "xyz", :sections => [Factory(:survey_section)])
86
+ @response_set = Factory(:response_set, :access_code => "pdq", :survey => @survey)
85
87
  end
86
88
 
87
89
  def do_get
88
- get :show, :survey_code => "XYZ", :response_set_code => "PDQ"
90
+ get :show, :survey_code => "xyz", :response_set_code => "pdq"
89
91
  end
90
92
 
91
93
  it "should be successful" do
92
94
  do_get
93
95
  response.should be_success
94
96
  end
97
+
95
98
  it "should render show template" do
96
99
  do_get
97
100
  response.should render_template('show')
98
101
  end
102
+
99
103
  it "should find the response_set requested" do
100
- pending
101
- ResponseSet.should_receive(:find_by_access_code).with("PDQ").and_return(@response_set)
104
+ ResponseSet.should_receive(:find_by_access_code).with("pdq",{:include=>{:responses=>[:question, :answer]}}).and_return(@response_set)
102
105
  do_get
103
106
  end
107
+
104
108
  it "should assign the found response_set and survey for the view" do
105
- pending
106
109
  do_get
107
- assigns[:response_set].should equal(@response_set)
108
- assigns[:survey].should equal(@survey)
110
+ assigns[:response_set].should == @response_set
109
111
  end
112
+
110
113
  it "should redirect if :response_code not found" do
111
- pending
112
- get :show, :survey_code => "XYZ", :response_set_code => "DIFFERENT"
114
+ get :show, :survey_code => "xyz", :response_set_code => "DIFFERENT"
113
115
  response.should redirect_to(available_surveys_url)
114
116
  end
115
- # I'm not sure this is enterly neccessary since we look up the survey from the response_code in the url -BC
116
- it "should redirect if :survey_code in url doesn't match response_set.survey.access_code" do
117
- pending
118
- get :show, :survey_code => "DIFFERENT", :response_set_code => "PDQ"
119
- response.should redirect_to(available_surveys_url)
120
- end
117
+
121
118
  end
122
119
 
123
120
  describe "edit my survey: GET /surveys/XYZ/PDQ/take" do
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{surveyor}
8
- s.version = "0.11.0"
8
+ s.version = "0.12.1"
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{2010-04-06}
12
+ s.date = %q{2010-08-19}
13
13
  s.email = %q{yoon@northwestern.edu}
14
14
  s.extra_rdoc_files = [
15
15
  "README.md"
@@ -180,7 +180,7 @@ Gem::Specification.new do |s|
180
180
  s.homepage = %q{http://github.com/breakpointer/surveyor}
181
181
  s.rdoc_options = ["--charset=UTF-8"]
182
182
  s.require_paths = ["lib"]
183
- s.rubygems_version = %q{1.3.6}
183
+ s.rubygems_version = %q{1.3.7}
184
184
  s.summary = %q{A rails (gem) plugin to enable surveys in your application}
185
185
  s.test_files = [
186
186
  "spec/controllers/surveyor_controller_spec.rb",
@@ -204,13 +204,16 @@ Gem::Specification.new do |s|
204
204
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
205
205
  s.specification_version = 3
206
206
 
207
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
207
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
208
208
  s.add_runtime_dependency(%q<haml>, [">= 0"])
209
+ s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
209
210
  else
210
211
  s.add_dependency(%q<haml>, [">= 0"])
212
+ s.add_dependency(%q<fastercsv>, [">= 0"])
211
213
  end
212
214
  else
213
215
  s.add_dependency(%q<haml>, [">= 0"])
216
+ s.add_dependency(%q<fastercsv>, [">= 0"])
214
217
  end
215
218
  end
216
219
 
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: surveyor
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 45
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 11
8
- - 0
9
- version: 0.11.0
8
+ - 12
9
+ - 1
10
+ version: 0.12.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Brian Chamberlain
@@ -15,21 +16,37 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-04-06 00:00:00 -05:00
19
+ date: 2010-08-19 00:00:00 -05:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
22
23
  name: haml
23
24
  prerelease: false
24
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
25
27
  requirements:
26
28
  - - ">="
27
29
  - !ruby/object:Gem::Version
30
+ hash: 3
28
31
  segments:
29
32
  - 0
30
33
  version: "0"
31
34
  type: :runtime
32
35
  version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: fastercsv
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
33
50
  description:
34
51
  email: yoon@northwestern.edu
35
52
  executables: []
@@ -210,23 +227,27 @@ rdoc_options:
210
227
  require_paths:
211
228
  - lib
212
229
  required_ruby_version: !ruby/object:Gem::Requirement
230
+ none: false
213
231
  requirements:
214
232
  - - ">="
215
233
  - !ruby/object:Gem::Version
234
+ hash: 3
216
235
  segments:
217
236
  - 0
218
237
  version: "0"
219
238
  required_rubygems_version: !ruby/object:Gem::Requirement
239
+ none: false
220
240
  requirements:
221
241
  - - ">="
222
242
  - !ruby/object:Gem::Version
243
+ hash: 3
223
244
  segments:
224
245
  - 0
225
246
  version: "0"
226
247
  requirements: []
227
248
 
228
249
  rubyforge_project:
229
- rubygems_version: 1.3.6
250
+ rubygems_version: 1.3.7
230
251
  signing_key:
231
252
  specification_version: 3
232
253
  summary: A rails (gem) plugin to enable surveys in your application