Permalink
Browse files

refactor engine testing scenario

Engine is now tested standalone by leveraging a dummy rails app
Enable Guard for speedy testing
Move factories to the more standard location `spec/factories/*`
Update README with a Testing section
Rename migrations to contain datetimestamps for their version to fix migration order issues when migrating the dummy application
  • Loading branch information...
1 parent 3454a9c commit 21b19db5a30fcb6db83f4ac9302cc94c6320a0db Jamie Winsor committed Aug 1, 2011
Showing with 2,208 additions and 64 deletions.
  1. +3 −0 .gitignore
  2. +2 −0 .rspec
  3. +8 −0 Gemfile
  4. +34 −0 Guardfile
  5. +26 −0 Rakefile
  6. 0 app/assets/images/refinerycms-blog/.gitkeep
  7. 0 app/assets/javascripts/refinerycms-blog/.gitkeep
  8. 0 app/assets/stylesheets/refinerycms-blog/.gitkeep
  9. 0 app/controllers/.gitkeep
  10. 0 app/helpers/.gitkeep
  11. 0 app/models/.gitkeep
  12. 0 app/views/.gitkeep
  13. +10 −0 config/cucumber.yml
  14. +3 −0 config/environment.rb
  15. +1 −1 db/migrate/{1_create_blog_structure.rb → 20110803223522_create_blog_structure.rb}
  16. 0 db/migrate/{2_add_user_id_to_blog_posts.rb → 20110803223523_add_user_id_to_blog_posts.rb}
  17. 0 db/migrate/{3_acts_as_taggable_on_migration.rb → 20110803223524_acts_as_taggable_on_migration.rb}
  18. 0 db/migrate/{4_create_seo_meta_for_blog.rb → 20110803223525_create_seo_meta_for_blog.rb}
  19. 0 db/migrate/{5_add_cached_slugs.rb → 20110803223526_add_cached_slugs.rb}
  20. 0 .../{6_add_custom_url_field_to_blog_posts.rb → 20110803223527_add_custom_url_field_to_blog_posts.rb}
  21. 0 ...d_custom_teaser_field_to_blog_posts.rb → 20110803223528_add_custom_teaser_field_to_blog_posts.rb}
  22. 0 .../{8_add_primary_key_to_categorizations.rb → 20110803223529_add_primary_key_to_categorizations.rb}
  23. 0 features/{support → }/step_definitions/authors_steps.rb
  24. 0 features/{support → }/step_definitions/category_steps.rb
  25. 0 features/{support → }/step_definitions/tags_steps.rb
  26. +42 −0 features/step_definitions/user_steps.rb
  27. +196 −0 features/step_definitions/web_steps.rb
  28. +50 −0 features/support/env.rb
  29. +14 −20 features/support/paths.rb
  30. +39 −0 features/support/selectors.rb
  31. +21 −0 lib/refinery/blog/engine.rb
  32. +8 −20 lib/refinerycms-blog.rb
  33. +16 −1 readme.md
  34. +13 −0 refinerycms-blog.gemspec
  35. +10 −0 script/cucumber
  36. +6 −0 script/rails
  37. +77 −0 spec/dummy/.gitignore
  38. +7 −0 spec/dummy/Rakefile
  39. +7 −0 spec/dummy/app/assets/javascripts/admin.js
  40. +9 −0 spec/dummy/app/assets/javascripts/application.js
  41. +1 −0 spec/dummy/app/assets/stylesheets/application.css
  42. +1 −0 spec/dummy/app/assets/stylesheets/application.css.backup
  43. +4 −0 spec/dummy/app/assets/stylesheets/formatting.css
  44. +4 −0 spec/dummy/app/assets/stylesheets/home.css
  45. +4 −0 spec/dummy/app/assets/stylesheets/theme.css
  46. +3 −0 spec/dummy/app/controllers/application_controller.rb
  47. +2 −0 spec/dummy/app/helpers/application_helper.rb
  48. 0 spec/dummy/app/mailers/.gitkeep
  49. 0 spec/dummy/app/models/.gitkeep
  50. +14 −0 spec/dummy/app/views/layouts/application.html.erb.backup
  51. +25 −0 spec/dummy/app/views/sitemap/index.xml.builder
  52. +17 −0 spec/dummy/autotest/autotest.rb
  53. +2 −0 spec/dummy/autotest/discover.rb
  54. +4 −0 spec/dummy/config.ru
  55. +42 −0 spec/dummy/config/application.rb
  56. +10 −0 spec/dummy/config/boot.rb
  57. +25 −0 spec/dummy/config/database.yml
  58. +20 −0 spec/dummy/config/database.yml.mysql
  59. +55 −0 spec/dummy/config/database.yml.postgresql
  60. +26 −0 spec/dummy/config/database.yml.sqlite3
  61. +5 −0 spec/dummy/config/environment.rb
  62. +31 −0 spec/dummy/config/environments/development.rb
  63. +55 −0 spec/dummy/config/environments/production.rb
  64. +43 −0 spec/dummy/config/environments/test.rb
  65. +7 −0 spec/dummy/config/initializers/backtrace_silencers.rb
  66. +144 −0 spec/dummy/config/initializers/devise.rb
  67. +10 −0 spec/dummy/config/initializers/inflections.rb
  68. +5 −0 spec/dummy/config/initializers/mime_types.rb
  69. +7 −0 spec/dummy/config/initializers/secret_token.rb
  70. +8 −0 spec/dummy/config/initializers/session_store.rb
  71. +12 −0 spec/dummy/config/initializers/wrap_parameters.rb
  72. +5 −0 spec/dummy/config/locales/en.yml
  73. +58 −0 spec/dummy/config/routes.rb
  74. +23 −0 spec/dummy/db/migrate/20110802081556_create_refinerycms_core_schema.rb
  75. +13 −0 spec/dummy/db/migrate/20110802081557_add_locale_to_slugs.rb
  76. +24 −0 spec/dummy/db/migrate/20110802081558_create_refinerycms_settings_schema.rb
  77. +9 −0 spec/dummy/db/migrate/20110802081559_add_value_type_to_refinery_settings.rb
  78. +48 −0 spec/dummy/db/migrate/20110802081560_create_refinerycms_authentication_schema.rb
  79. +11 −0 spec/dummy/db/migrate/20110802081561_add_missing_indexes_to_roles_users.rb
  80. +31 −0 spec/dummy/db/migrate/20110802081562_change_to_devise_users_table.rb
  81. +5 −0 spec/dummy/db/migrate/20110802081563_add_remember_created_at_to_users.rb
  82. +13 −0 spec/dummy/db/migrate/20110802081564_remove_password_salt_from_users.rb
  83. +23 −0 spec/dummy/db/migrate/20110802081565_create_refinerycms_images_schema.rb
  84. +56 −0 spec/dummy/db/migrate/20110802081566_create_refinerycms_pages_schema.rb
  85. +38 −0 spec/dummy/db/migrate/20110802081567_translate_page_plugin.rb
  86. +11 −0 spec/dummy/db/migrate/20110802081568_remove_cached_slug_from_pages.rb
  87. +26 −0 spec/dummy/db/migrate/20110802081569_translate_custom_title_on_pages.rb
  88. +13 −0 spec/dummy/db/migrate/20110802081570_remove_translated_fields_from_pages.rb
  89. +86 −0 spec/dummy/db/migrate/20110802081571_create_seo_meta.rb
  90. +11 −0 spec/dummy/db/migrate/20110802081572_create_add_template_columns.rb
  91. +21 −0 spec/dummy/db/migrate/20110802081573_create_refinerycms_resources_schema.rb
  92. +239 −0 spec/dummy/db/schema.rb
  93. +5 −0 spec/dummy/db/seeds.rb
  94. +63 −0 spec/dummy/db/seeds/pages.rb
  95. 0 spec/dummy/lib/assets/.gitkeep
  96. 0 spec/dummy/log/.gitkeep
  97. +26 −0 spec/dummy/public/404.html
  98. +26 −0 spec/dummy/public/422.html
  99. +26 −0 spec/dummy/public/500.html
  100. 0 spec/dummy/public/favicon.ico
  101. +6 −0 spec/dummy/script/rails
  102. 0 spec/{support/refinery → }/factories/blog_categories.rb
  103. 0 spec/{support/refinery → }/factories/blog_comments.rb
  104. 0 spec/{support/refinery → }/factories/blog_posts.rb
  105. +27 −0 spec/factories/user.rb
  106. +2 −2 spec/models/refinery/blog_post_spec.rb
  107. +2 −0 spec/rcov.opts
  108. +1 −3 spec/requests/blog_categories_spec.rb
  109. +16 −16 spec/requests/blog_posts_spec.rb
  110. +8 −1 spec/requests/manage_blog_posts_spec.rb
  111. +48 −0 spec/spec_helper.rb
View
@@ -42,3 +42,6 @@ nbproject
# Capybara Bug
capybara-*html
+
+.rvmrc
+Gemfile.lock
View
2 .rspec
@@ -0,0 +1,2 @@
+--color spec
+--drb
View
@@ -0,0 +1,8 @@
+source "http://rubygems.org"
+
+## Uncomment the following lines to develop against a local clone of refinery
+# gem 'refinerycms', :path => '~/Code/refinerycms'
+# gem 'refinerycms-generators', :path => '~/Code/refinerycms-generators'
+# gem 'seo_meta', :git => 'git://github.com/parndt/seo_meta.git'
+
+gemspec
View
@@ -0,0 +1,34 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard 'rspec', :version => 2 do
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
+ watch('spec/spec_helper.rb') { "spec" }
+
+ # Rails example
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
+ watch('spec/spec_helper.rb') { "spec" }
+ watch('config/routes.rb') { "spec/routing" }
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
+ # Capybara request specs
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
+end
+
+guard 'cucumber' do
+ watch(%r{^features/.+\.feature$})
+ watch(%r{^features/support/.+$}) { 'features' }
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
+end
+
+guard 'spork', :wait => 60, :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
+ watch('config/application.rb')
+ watch('config/environment.rb')
+ watch(%r{^config/environments/.+\.rb$})
+ watch(%r{^config/initializers/.+\.rb$})
+ watch('spec/spec_helper.rb')
+end
View
@@ -0,0 +1,26 @@
+#!/usr/bin/env rake
+begin
+ require 'bundler/setup'
+rescue LoadError
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
+end
+begin
+ require 'rdoc/task'
+rescue LoadError
+ require 'rdoc/rdoc'
+ require 'rake/rdoctask'
+ RDoc::Task = Rake::RDocTask
+end
+
+RDoc::Task.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'RefinerycmsBlog'
+ rdoc.options << '--line-numbers'
+ rdoc.rdoc_files.include('README.rdoc')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
+load 'rails/tasks/engine.rake'
+
+Bundler::GemHelper.install_tasks
View
No changes.
View
No changes.
View
No changes.
View
No changes.
View
@@ -0,0 +1,10 @@
+<%
+ENV["RAILS_ENV"] ||= "test"
+require ::File.expand_path('../spec/dummy/config/environment', __FILE__)
+rerun = IO.read('rerun.txt') if File.file?('rerun.txt')
+rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
+std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip -r features"
+%>
+default: <%= std_opts %>
+wip: --tags @wip:3 --wip features
+rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
View
@@ -0,0 +1,3 @@
+# TODO: Remove this when you figure out how to get Cucumber to look for the
+# environment file in the dummy app instead of within the project root
+require File.expand_path('../../spec/dummy/config/environment', __FILE__)
@@ -37,7 +37,7 @@ def up
add_index Refinery::Categorization.table_name, [:blog_category_id, :blog_post_id], :name => 'index_blog_categories_blog_posts_on_bc_and_bp'
- load(Rails.root.join('db', 'seeds', 'refinerycms_blog.rb').to_s)
+ load(File.expand_path('../../seeds/refinerycms_blog.rb', __FILE__))
end
def down
@@ -0,0 +1,42 @@
+def login(options = {})
+ options = {:user => @refinery_user}.merge(options)
+ visit new_refinery_user_session_path
+ fill_in("refinery_user_login", :with => options[:user].email)
+ fill_in("refinery_user_password", :with => 'greenandjuicy')
+ click_button("submit_button")
+end
+
+Given /^I am a logged in refinery user$/i do
+ @refinery_user ||= Factory(:refinery_user)
+ login(:user => @refinery_user)
+end
+
+Given /^I am a logged in refinery translator$/i do
+ @refinery_translator ||= Factory(:refinery_translator)
+ login(:user => @refinery_translator)
+end
+
+Given /^I am a logged in customer$/i do
+ @user ||= Factory(:user)
+ login(:user => @user)
+end
+
+Given /^A Refinery user exists$/i do
+ @refinery_user ||= Factory(:refinery_user)
+end
+
+Given /^I have a user named "(.*)"$/ do |name|
+ @user = Factory(:user, :username => name)
+end
+
+Given /^I have a refinery user named "(.*)"$/i do |name|
+ @refinery_user = Factory(:refinery_user, :username => name)
+end
+
+Given /^I have no users$/ do
+ ::Refinery::User.delete_all
+end
+
+Then /^I should have ([0-9]+) users?$/ do |count|
+ ::Refinery::User.count.should == count.to_i
+end
@@ -0,0 +1,196 @@
+# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
+# It is recommended to regenerate this file in the future when you upgrade to a
+# newer version of cucumber-rails. Consider adding your own code to a new file
+# instead of editing this one. Cucumber will automatically load all features/**/*.rb
+# files.
+
+require 'uri'
+require 'cgi'
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
+
+module WithinHelpers
+ def with_scope(locator)
+ locator ? within(*selector_for(locator)) { yield } : yield
+ end
+end
+World(WithinHelpers)
+
+# Single-line step scoper
+When /^(.*) within (.*[^:])$/ do |step, parent|
+ with_scope(parent) { When step }
+end
+
+# Multi-line step scoper
+When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
+ with_scope(parent) { When "#{step}:", table_or_string }
+end
+
+Given /^(?:|I )am on (.+)$/ do |page_name|
+ visit path_to(page_name)
+end
+
+When /^(?:|I )go to (.+)$/ do |page_name|
+ visit path_to(page_name)
+end
+
+When /^(?:|I )press "([^"]*)"$/ do |button|
+ click_button(button)
+end
+
+When /^(?:|I )follow "([^"]*)"$/ do |link|
+ click_link(link)
+end
+
+When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
+ fill_in(field, :with => value)
+end
+
+When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
+ fill_in(field, :with => value)
+end
+
+# Use this to fill in an entire form with data from a table. Example:
+#
+# When I fill in the following:
+# | Account Number | 5002 |
+# | Expiry date | 2009-11-01 |
+# | Note | Nice guy |
+# | Wants Email? | |
+#
+# TODO: Add support for checkbox, select og option
+# based on naming conventions.
+#
+When /^(?:|I )fill in the following:$/ do |fields|
+ fields.rows_hash.each do |name, value|
+ When %{I fill in "#{name}" with "#{value}"}
+ end
+end
+
+When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
+ select(value, :from => field)
+end
+
+When /^(?:|I )check "([^"]*)"$/ do |field|
+ check(field)
+end
+
+When /^(?:|I )uncheck "([^"]*)"$/ do |field|
+ uncheck(field)
+end
+
+When /^(?:|I )choose "([^"]*)"$/ do |field|
+ choose(field)
+end
+
+When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
+ attach_file(field, File.expand_path(path))
+end
+
+Then /^(?:|I )should see "([^"]*)"$/ do |text|
+ if page.respond_to? :should
+ page.should have_content(text)
+ else
+ assert page.has_content?(text)
+ end
+end
+
+Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
+ regexp = Regexp.new(regexp)
+
+ if page.respond_to? :should
+ page.should have_xpath('//*', :text => regexp)
+ else
+ assert page.has_xpath?('//*', :text => regexp)
+ end
+end
+
+Then /^(?:|I )should not see "([^"]*)"$/ do |text|
+ if page.respond_to? :should
+ page.should have_no_content(text)
+ else
+ assert page.has_no_content?(text)
+ end
+end
+
+Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
+ regexp = Regexp.new(regexp)
+
+ if page.respond_to? :should
+ page.should have_no_xpath('//*', :text => regexp)
+ else
+ assert page.has_no_xpath?('//*', :text => regexp)
+ end
+end
+
+Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
+ with_scope(parent) do
+ field = find_field(field)
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
+ if field_value.respond_to? :should
+ field_value.should =~ /#{value}/
+ else
+ assert_match(/#{value}/, field_value)
+ end
+ end
+end
+
+Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
+ with_scope(parent) do
+ field = find_field(field)
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
+ if field_value.respond_to? :should_not
+ field_value.should_not =~ /#{value}/
+ else
+ assert_no_match(/#{value}/, field_value)
+ end
+ end
+end
+
+Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
+ with_scope(parent) do
+ field_checked = find_field(label)['checked']
+ if field_checked.respond_to? :should
+ field_checked.should be_true
+ else
+ assert field_checked
+ end
+ end
+end
+
+Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
+ with_scope(parent) do
+ field_checked = find_field(label)['checked']
+ if field_checked.respond_to? :should
+ field_checked.should be_false
+ else
+ assert !field_checked
+ end
+ end
+end
+
+Then /^(?:|I )should be on (.+)$/ do |page_name|
+ current_path = URI.parse(current_url).path
+ if current_path.respond_to? :should
+ current_path.should == path_to(page_name)
+ else
+ assert_equal path_to(page_name), current_path
+ end
+end
+
+Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
+ query = URI.parse(current_url).query
+ actual_params = query ? CGI.parse(query) : {}
+ expected_params = {}
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
+
+ if actual_params.respond_to? :should
+ actual_params.should == expected_params
+ else
+ assert_equal expected_params, actual_params
+ end
+end
+
+Then /^show me the page$/ do
+ save_and_open_page
+end
View
@@ -0,0 +1,50 @@
+require 'rubygems'
+require 'bundler/setup'
+require 'spork'
+
+Spork.prefork do
+ require 'cucumber/rails'
+ require 'capybara/rails'
+ require 'capybara/cucumber'
+ require 'capybara/session'
+
+ require 'factory_girl'
+ require 'database_cleaner'
+ require 'database_cleaner/cucumber'
+
+ Dir[File.expand_path("../../../spec/factories/*.rb", __FILE__)].each {|f| require f}
+
+ include ::Devise::Controllers::UrlHelpers
+
+ # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
+ # order to ease the transition to Capybara we set the default here. If you'd
+ # prefer to use XPath just remove this line and adjust any selectors in your
+ # steps to use the XPath syntax.
+ Capybara.default_selector = :css
+
+ # By default, any exception happening in your Rails application will bubble up
+ # to Cucumber so that your scenario will fail. This is a different from how
+ # your application behaves in the production environment, where an error page will
+ # be rendered instead.
+ #
+ # Sometimes we want to override this default behaviour and allow Rails to rescue
+ # exceptions and display an error page (just like when the app is running in production).
+ # Typical scenarios where you want to do this is when you test your error pages.
+ # There are two ways to allow Rails to rescue exceptions:
+ #
+ # 1) Tag your scenario (or feature) with @allow-rescue
+ #
+ # 2) Set the value below to true. Beware that doing this globally is not
+ # recommended as it will mask a lot of errors for you!
+ #
+ ActionController::Base.allow_rescue = false
+
+ DatabaseCleaner.strategy = :truncation
+
+ Before { DatabaseCleaner.start }
+ After { DatabaseCleaner.clean }
+end
+
+Spork.each_run do
+ # This code will be run each time you run your specs.
+end
Oops, something went wrong.

0 comments on commit 21b19db

Please sign in to comment.