surveyor 0.18.0 → 0.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +21 -4
  2. data/CHANGELOG +19 -0
  3. data/README.md +2 -3
  4. data/Rakefile +6 -93
  5. data/VERSION +1 -1
  6. data/ci-env.sh +29 -0
  7. data/features/step_definitions/surveyor_steps.rb +11 -1
  8. data/features/step_definitions/web_steps.rb +62 -54
  9. data/features/support/env.rb +40 -2
  10. data/features/support/paths.rb +12 -4
  11. data/features/surveyor.feature +34 -0
  12. data/generators/surveyor/surveyor_generator.rb +1 -1
  13. data/hudson.rakefile +33 -0
  14. data/init_testbed.rakefile +55 -0
  15. data/lib/surveyor/models/answer_methods.rb +9 -5
  16. data/lib/surveyor/models/dependency_condition_methods.rb +12 -7
  17. data/lib/surveyor/models/dependency_methods.rb +12 -7
  18. data/lib/surveyor/models/question_methods.rb +11 -6
  19. data/lib/surveyor/models/response_methods.rb +9 -4
  20. data/lib/surveyor/models/response_set_methods.rb +11 -6
  21. data/lib/surveyor/models/survey_methods.rb +9 -4
  22. data/lib/surveyor/models/survey_section_methods.rb +10 -5
  23. data/lib/surveyor/models/validation_condition_methods.rb +13 -8
  24. data/lib/surveyor/models/validation_methods.rb +11 -6
  25. data/lib/surveyor/parser.rb +7 -10
  26. data/lib/surveyor/redcap_parser.rb +2 -9
  27. data/lib/surveyor/unparser.rb +10 -9
  28. data/rails/init.rb +1 -0
  29. data/spec/rcov.opts +1 -1
  30. data/spec/spec_helper.rb +50 -15
  31. data/surveyor.gemspec +9 -54
  32. data/testbed/Gemfile +13 -0
  33. metadata +22 -99
  34. data/Gemfile +0 -17
  35. data/Gemfile.lock +0 -86
  36. data/init.rb +0 -1
  37. data/install.rb +0 -1
  38. data/spec/test_Gemfile +0 -15
  39. data/spec/test_boot.rb +0 -128
  40. data/spec/test_preinitializer.rb +0 -21
@@ -5,7 +5,7 @@
5
5
  # files.
6
6
 
7
7
  ENV["RAILS_ENV"] ||= "cucumber"
8
- require File.expand_path(File.dirname(__FILE__) + '/../../spec/test_app/config/environment')
8
+ require File.expand_path(File.dirname(__FILE__) + '/../../testbed/config/environment')
9
9
 
10
10
  require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
11
11
  require 'cucumber/rails/world'
@@ -15,4 +15,42 @@ require 'cucumber/web/tableish'
15
15
  require 'webrat'
16
16
  require 'webrat/core/matchers'
17
17
 
18
- # Since we're using the test_app, and it has cucumber installed we don't need to do any configuration here.
18
+ Webrat.configure do |config|
19
+ config.mode = :rails
20
+ config.open_error_files = false # Set to true if you want error pages to pop up in the browser
21
+ end
22
+
23
+
24
+ # If you set this to false, any error raised from within your app will bubble
25
+ # up to your step definition and out to cucumber unless you catch it somewhere
26
+ # on the way. You can make Rails rescue errors and render error pages on a
27
+ # per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
28
+ #
29
+ # If you set this to true, Rails will rescue all errors and render error
30
+ # pages, more or less in the same way your application would behave in the
31
+ # default production environment. It's not recommended to do this for all
32
+ # of your scenarios, as this makes it hard to discover errors in your application.
33
+ ActionController::Base.allow_rescue = false
34
+
35
+ # If you set this to true, each scenario will run in a database transaction.
36
+ # You can still turn off transactions on a per-scenario basis, simply tagging
37
+ # a feature or scenario with the @no-txn tag. If you are using Capybara,
38
+ # tagging with @culerity or @javascript will also turn transactions off.
39
+ #
40
+ # If you set this to false, transactions will be off for all scenarios,
41
+ # regardless of whether you use @no-txn or not.
42
+ #
43
+ # Beware that turning transactions off will leave data in your database
44
+ # after each scenario, which can lead to hard-to-debug failures in
45
+ # subsequent scenarios. If you do this, we recommend you create a Before
46
+ # block that will explicitly put your database in a known state.
47
+ Cucumber::Rails::World.use_transactional_fixtures = true
48
+ # How to clean your database when transactions are turned off. See
49
+ # http://github.com/bmabey/database_cleaner for more info.
50
+ if defined?(ActiveRecord::Base)
51
+ begin
52
+ require 'database_cleaner'
53
+ DatabaseCleaner.strategy = :truncation
54
+ rescue LoadError => ignore_if_database_cleaner_not_present
55
+ end
56
+ end
@@ -7,7 +7,7 @@ module NavigationHelpers
7
7
  #
8
8
  def path_to(page_name)
9
9
  case page_name
10
-
10
+
11
11
  when /the home\s?page/
12
12
  '/'
13
13
 
@@ -18,8 +18,16 @@ module NavigationHelpers
18
18
  # user_profile_path(User.find_by_login($1))
19
19
 
20
20
  else
21
- raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
22
- "Now, go and add a mapping in #{__FILE__}"
21
+ begin
22
+ page_name =~ /the (.*) page/
23
+ path_components = $1.split(/\s+/)
24
+ self.send(path_components.push('path').join('_').to_sym)
25
+ rescue Object => e
26
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
27
+ "Now, go and add a mapping in #{__FILE__}"
28
+ end
23
29
  end
24
30
  end
25
- end
31
+ end
32
+
33
+ World(NavigationHelpers)
@@ -155,3 +155,37 @@ Feature: Survey creation
155
155
  And there should be 2 validation_conditions with:
156
156
  | rule_key | integer_value |
157
157
  | A | 0 |
158
+ Scenario: Group dependencies
159
+ Given I parse
160
+ """
161
+ survey "Group dependencies" do
162
+ section "Meds" do
163
+ repeater "Medication regimen (PPI)" do
164
+ dependency :rule => "A"
165
+ condition_A :q_dayone_1, "==", :a_2
166
+ q_dayone_2 "Medication", :pick=> :one, :display_type => :dropdown
167
+ a_0 "None"
168
+ a_1 "Dexlansoprazole (Kapidex)"
169
+ a_2 "Esomeprazole (Nexium)"
170
+ a_3 "Lansoprazole (Prevacid)"
171
+ a_4 "Omeprazole (Prilosec)"
172
+ a_5 "Omeprazole, Sodium Bicarbonate (Zegerid)"
173
+ a_6 "Pantoprazole (Protonix)"
174
+ a_7 "Rabeprazole (Aciphex)"
175
+ a_8 "Other", :string
176
+
177
+ q_dayone_3 "Dose (mg)"
178
+ a :string
179
+ q_dayone_4 "Frequency", :pick => :one, :display_type => :dropdown
180
+ a_1 "Daily (AM)"
181
+ a_2 "Daily (PM)"
182
+ a_3 "Twice daily"
183
+ end
184
+ end
185
+ end
186
+ """
187
+ And there should be 1 group dependency with:
188
+ | rule |
189
+ | A |
190
+
191
+
@@ -5,7 +5,7 @@ class SurveyorGenerator < Rails::Generator::Base
5
5
  m.directory "surveys"
6
6
 
7
7
  # Copy README to your app
8
- m.file "../../../README.md", "surveys/README.md"
8
+ # m.file "../../../README.md", "surveys/README.md"
9
9
 
10
10
  # Gem plugin rake tasks
11
11
  m.file "tasks/surveyor.rb", "lib/tasks/surveyor.rb"
data/hudson.rakefile ADDED
@@ -0,0 +1,33 @@
1
+ BUNDLER_VERSION="1.0.7"
2
+ import 'init_testbed.rakefile'
3
+
4
+ namespace :bundle do
5
+ task :ensure_bundler_available do
6
+ `gem list -i bundler -v '=#{BUNDLER_VERSION}'`
7
+ unless $? == 0
8
+ puts bordered_message("Installing bundler #{BUNDLER_VERSION}")
9
+ system("gem install bundler -v '=#{BUNDLER_VERSION}' --no-ri --no-rdoc")
10
+ unless $? == 0
11
+ fail bordered_message("Install failed.\nPlease fix the problem and try again or manually install bundler #{BUNDLER_VERSION}.")
12
+ end
13
+ end
14
+ end
15
+
16
+ def bordered_message(msg)
17
+ len = msg.split("\n").collect { |l| l.size }.max
18
+ ['=' * len, msg, '=' * len].join("\n")
19
+ end
20
+ end
21
+ namespace :ci do
22
+ task :generate_testbed_for_hudson => [:'testbed:remove', :'testbed:generate'] do
23
+ # Hudson
24
+ chdir("testbed") do
25
+ database_yml = File.read('config/database.yml') + "\n\nhudson:\n <<: *test\n"
26
+ File.open('config/database.yml', 'w'){|f| f.write database_yml}
27
+ sh "cp config/environments/cucumber.rb config/environments/hudson.rb"
28
+ end
29
+ end
30
+ task :setup_testbed_for_hudson => [:'testbed:setup', :'testbed:migrate']
31
+ end
32
+
33
+ task :default => [:'bundle:ensure_bundler_available', :'ci:generate_testbed_for_hudson', :'ci:setup_testbed_for_hudson']
@@ -0,0 +1,55 @@
1
+ desc "Set up a rails app for testing in the spec dir"
2
+ task :default => [:"testbed:generate", :"testbed:setup", :"testbed:migrate"]
3
+
4
+ namespace "testbed" do
5
+ # "testbed" is also hardcoded in the spec/spec_helper.rb features/support/env.rb and gitignore file. Change it there too...
6
+
7
+ "Generate rails, rspec, cucumber"
8
+ task :generate do
9
+ chdir("testbed") do
10
+ sh "bundle install"
11
+ sh "bundle exec rails ."
12
+ sh "bundle exec script/generate rspec"
13
+ sh "bundle exec script/generate cucumber --webrat"
14
+ sh "rm -rf spec features"
15
+ end
16
+ end
17
+
18
+ desc "Setup bundler, rspec, cucumber"
19
+ task :setup do
20
+ chdir("testbed") do
21
+ # Bundler
22
+ preinitializer_rb = "begin\n require \"rubygems\"\n require \"bundler\"\nrescue LoadError\n raise \"Could not load the bundler gem. Install it with `gem install bundler`.\"\nend\n\nif Gem::Version.new(Bundler::VERSION) <= Gem::Version.new(\"0.9.24\")\n raise RuntimeError, \"Your bundler version is too old for Rails 2.3.\" +\n \"Run `gem install bundler` to upgrade.\"\nend\n\nbegin\n # Set up load paths for all bundled gems\n ENV[\"BUNDLE_GEMFILE\"] = File.expand_path(\"../../Gemfile\", __FILE__)\n Bundler.setup\nrescue Bundler::GemNotFound\n raise RuntimeError, \"Bundler couldn't find some gems.\" +\n \"Did you run `bundle install`?\"\nend\n"
23
+ File.open('config/preinitializer.rb', 'w'){|f| f.write preinitializer_rb}
24
+
25
+ boot_rb = File.read('config/boot.rb').sub("# All that for this:", "class Rails::Boot\n def run\n load_initializer\n\n Rails::Initializer.class_eval do\n def load_gems\n @bundler_loaded ||= Bundler.require :default, Rails.env\n end\n end\n\n Rails::Initializer.run(:set_load_path)\n end\nend\n\n# All that for this:")
26
+ File.open('config/boot.rb', 'w'){|f| f.write boot_rb}
27
+ puts "NOTE: These files were created/modified as described here: http://gembundler.com/rails23.html"
28
+
29
+ # Rspec
30
+ rspec_rake = File.read('lib/tasks/rspec.rake').gsub('#{RAILS_ROOT}/spec/', '#{RAILS_ROOT}/../spec/').gsub("FileList['spec/", "FileList['../spec/").gsub("File.exist?('spec/","File.exist?('../spec/")
31
+ File.open('lib/tasks/rspec.rake', 'w'){|f| f.write rspec_rake}
32
+
33
+ # Cucumber
34
+ cucumber_rake = File.read('lib/tasks/cucumber.rake').sub("begin", "ENV['FEATURE'] ||= '../features'\n\nbegin")
35
+ File.open('lib/tasks/cucumber.rake', 'w'){|f| f.write cucumber_rake}
36
+ end
37
+ end
38
+
39
+ desc "Generate, migrate testbed"
40
+ task :migrate do
41
+ sh "cp -R generators testbed/lib"
42
+ chdir("testbed") do
43
+ sh "bundle exec script/generate surveyor"
44
+ sh "bundle exec rake db:migrate db:test:prepare"
45
+ end
46
+ end
47
+
48
+ desc "Remove testbed app"
49
+ task :remove do
50
+ puts "Removing the test_app in the spec folder"
51
+ chdir("testbed") do
52
+ sh 'rm -rf Gemfile.lock README Rakefile app config db doc features lib log public script spec surveys test tmp vendor'
53
+ end
54
+ end
55
+ end
@@ -9,11 +9,15 @@ module Surveyor
9
9
 
10
10
  # Scopes
11
11
  base.send :default_scope, :order => "display_order ASC"
12
-
13
- # Validations
14
- base.send :validates_presence_of, :text
15
- # this causes issues with building and saving
16
- # base.send :validates_numericality_of, :question_id, :allow_nil => false, :only_integer => true
12
+
13
+ @@validations_already_included ||= nil
14
+ unless @@validations_already_included
15
+ # Validations
16
+ base.send :validates_presence_of, :text
17
+ # this causes issues with building and saving
18
+ # base.send :validates_numericality_of, :question_id, :allow_nil => false, :only_integer => true
19
+ @@validations_already_included = true
20
+ end
17
21
  end
18
22
 
19
23
  # Instance Methods
@@ -7,14 +7,19 @@ module Surveyor
7
7
  base.send :belongs_to, :dependency
8
8
  base.send :belongs_to, :dependent_question, :foreign_key => :question_id, :class_name => :question
9
9
  base.send :belongs_to, :question
10
-
11
- # Validations
12
- base.send :validates_presence_of, :operator, :rule_key
13
- base.send :validate, :validates_operator
14
- base.send :validates_uniqueness_of, :rule_key, :scope => :dependency_id
15
- # this causes issues with building and saving
16
- # base.send :validates_numericality_of, :question_id, :dependency_id
17
10
 
11
+ @@validations_already_included ||= nil
12
+ unless @@validations_already_included
13
+ # Validations
14
+ base.send :validates_presence_of, :operator, :rule_key
15
+ base.send :validate, :validates_operator
16
+ base.send :validates_uniqueness_of, :rule_key, :scope => :dependency_id
17
+ # this causes issues with building and saving
18
+ # base.send :validates_numericality_of, :question_id, :dependency_id
19
+
20
+ @@validations_already_included = true
21
+ end
22
+
18
23
  base.send :include, Surveyor::ActsAsResponse # includes "as" instance method
19
24
 
20
25
  # Class methods
@@ -6,13 +6,18 @@ module Surveyor
6
6
  base.send :belongs_to, :question
7
7
  base.send :belongs_to, :question_group
8
8
  base.send :has_many, :dependency_conditions, :dependent => :destroy
9
-
10
- # Validations
11
- base.send :validates_presence_of, :rule
12
- base.send :validates_format_of, :rule, :with => /^(?:and|or|\)|\(|[A-Z]|\s)+$/ #TODO properly formed parenthesis etc.
13
- base.send :validates_numericality_of, :question_id, :if => Proc.new { |d| d.question_group_id.nil? }
14
- base.send :validates_numericality_of, :question_group_id, :if => Proc.new { |d| d.question_id.nil? }
15
-
9
+
10
+ @@validations_already_included ||= nil
11
+ unless @@validations_already_included
12
+ # Validations
13
+ base.send :validates_presence_of, :rule
14
+ base.send :validates_format_of, :rule, :with => /^(?:and|or|\)|\(|[A-Z]|\s)+$/ #TODO properly formed parenthesis etc.
15
+ base.send :validates_numericality_of, :question_id, :if => Proc.new { |d| d.question_group_id.nil? }
16
+ base.send :validates_numericality_of, :question_group_id, :if => Proc.new { |d| d.question_id.nil? }
17
+
18
+ @@validations_already_included = true
19
+ end
20
+
16
21
  # Attribute aliases
17
22
  base.send :alias_attribute, :dependent_question_id, :question_id
18
23
  end
@@ -10,12 +10,17 @@ module Surveyor
10
10
 
11
11
  # Scopes
12
12
  base.send :default_scope, :order => "display_order ASC"
13
-
14
- # Validations
15
- base.send :validates_presence_of, :text, :display_order
16
- # this causes issues with building and saving
17
- #, :survey_section_id
18
- base.send :validates_inclusion_of, :is_mandatory, :in => [true, false]
13
+
14
+ @@validations_already_included ||= nil
15
+ unless @@validations_already_included
16
+ # Validations
17
+ base.send :validates_presence_of, :text, :display_order
18
+ # this causes issues with building and saving
19
+ #, :survey_section_id
20
+ base.send :validates_inclusion_of, :is_mandatory, :in => [true, false]
21
+
22
+ @@validations_already_included = true
23
+ end
19
24
  end
20
25
 
21
26
  # Instance Methods
@@ -6,10 +6,15 @@ module Surveyor
6
6
  base.send :belongs_to, :response_set
7
7
  base.send :belongs_to, :question
8
8
  base.send :belongs_to, :answer
9
-
10
- # Validations
11
- base.send :validates_presence_of, :response_set_id, :question_id, :answer_id
12
-
9
+
10
+ @@validations_already_included ||= nil
11
+ unless @@validations_already_included
12
+ # Validations
13
+ base.send :validates_presence_of, :response_set_id, :question_id, :answer_id
14
+
15
+ @@validations_already_included = true
16
+ end
17
+
13
18
  base.send :include, Surveyor::ActsAsResponse # includes "as" instance method
14
19
 
15
20
  end
@@ -6,12 +6,17 @@ module Surveyor
6
6
  base.send :belongs_to, :survey
7
7
  base.send :belongs_to, :user
8
8
  base.send :has_many, :responses, :dependent => :destroy
9
-
10
- # Validations
11
- base.send :validates_presence_of, :survey_id
12
- base.send :validates_associated, :responses
13
- base.send :validates_uniqueness_of, :access_code
14
-
9
+
10
+ @@validations_already_included ||= nil
11
+ unless @@validations_already_included
12
+ # Validations
13
+ base.send :validates_presence_of, :survey_id
14
+ base.send :validates_associated, :responses
15
+ base.send :validates_uniqueness_of, :access_code
16
+
17
+ @@validations_already_included = true
18
+ end
19
+
15
20
  # Attributes
16
21
  base.send :attr_protected, :completed_at
17
22
  base.send :attr_accessor, :current_section_id
@@ -9,10 +9,15 @@ module Surveyor
9
9
 
10
10
  # Scopes
11
11
  base.send :named_scope, :with_sections, {:include => :sections}
12
-
13
- # Validations
14
- base.send :validates_presence_of, :title
15
- base.send :validates_uniqueness_of, :access_code
12
+
13
+ @@validations_already_included ||= nil
14
+ unless @@validations_already_included
15
+ # Validations
16
+ base.send :validates_presence_of, :title
17
+ base.send :validates_uniqueness_of, :access_code
18
+
19
+ @@validations_already_included = true
20
+ end
16
21
 
17
22
  # Class methods
18
23
  base.instance_eval do
@@ -9,11 +9,16 @@ module Surveyor
9
9
  # Scopes
10
10
  base.send :default_scope, :order => "display_order ASC"
11
11
  base.send :named_scope, :with_includes, { :include => {:questions => [:answers, :question_group, {:dependency => :dependency_conditions}]}}
12
-
13
- # Validations
14
- base.send :validates_presence_of, :title, :display_order
15
- # this causes issues with building and saving
16
- #, :survey
12
+
13
+ @@validations_already_included ||= nil
14
+ unless @@validations_already_included
15
+ # Validations
16
+ base.send :validates_presence_of, :title, :display_order
17
+ # this causes issues with building and saving
18
+ #, :survey
19
+
20
+ @@validations_already_included = true
21
+ end
17
22
  end
18
23
 
19
24
  # Instance Methods
@@ -6,14 +6,19 @@ module Surveyor
6
6
  base.send :belongs_to, :validation
7
7
 
8
8
  # Scopes
9
-
10
- # Validations
11
- base.send :validates_presence_of, :operator, :rule_key
12
- base.send :validates_inclusion_of, :operator, :in => Surveyor::Common::OPERATORS
13
- base.send :validates_uniqueness_of, :rule_key, :scope => :validation_id
14
- # this causes issues with building and saving
15
- # base.send :validates_numericality_of, :validation_id #, :question_id, :answer_id
16
-
9
+
10
+ @@validations_already_included ||= nil
11
+ unless @@validations_already_included
12
+ # Validations
13
+ base.send :validates_presence_of, :operator, :rule_key
14
+ base.send :validates_inclusion_of, :operator, :in => Surveyor::Common::OPERATORS
15
+ base.send :validates_uniqueness_of, :rule_key, :scope => :validation_id
16
+ # this causes issues with building and saving
17
+ # base.send :validates_numericality_of, :validation_id #, :question_id, :answer_id
18
+
19
+ @@validations_already_included = true
20
+ end
21
+
17
22
  base.send :include, Surveyor::ActsAsResponse # includes "as" instance method
18
23
 
19
24
  # Class methods
@@ -7,12 +7,17 @@ module Surveyor
7
7
  base.send :has_many, :validation_conditions, :dependent => :destroy
8
8
 
9
9
  # Scopes
10
-
11
- # Validations
12
- base.send :validates_presence_of, :rule
13
- base.send :validates_format_of, :rule, :with => /^(?:and|or|\)|\(|[A-Z]|\s)+$/
14
- # this causes issues with building and saving
15
- # base.send :validates_numericality_of, :answer_id
10
+
11
+ @@validations_already_included ||= nil
12
+ unless @@validations_already_included
13
+ # Validations
14
+ base.send :validates_presence_of, :rule
15
+ base.send :validates_format_of, :rule, :with => /^(?:and|or|\)|\(|[A-Z]|\s)+$/
16
+ # this causes issues with building and saving
17
+ # base.send :validates_numericality_of, :answer_id
18
+
19
+ @@validations_already_included = true
20
+ end
16
21
  end
17
22
 
18
23
  # Instance Methods