Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added rspecs and removed text fixtures

  • Loading branch information...
commit a14e73c1669c259f9898db2e3304e10a8973b25e 1 parent 7915cbf
arunsark authored

Showing 34 changed files with 668 additions and 386 deletions. Show diff stats Hide diff stats

  1. +1 0  .rspec
  2. +9 3 Gemfile
  3. +57 0 Gemfile.lock
  4. +5 3 app/controllers/posts_controller.rb
  5. +13 2 app/models/post.rb
  6. +4 0 app/models/user.rb
  7. +9 0 app/views/devise/registrations/new.html.erb
  8. +12 0 app/views/posts/_form.html.erb
  9. +1 0  app/views/posts/show.html.erb
  10. +1 1  config/application.rb
  11. +8 0 config/cucumber.yml
  12. +211 0 features/step_definitions/web_steps.rb
  13. +39 0 features/support/env.rb
  14. +33 0 features/support/paths.rb
  15. +39 0 features/support/selectors.rb
  16. +57 0 lib/tasks/cucumber.rake
  17. +0 239 public/index.html
  18. +10 0 script/cucumber
  19. +115 0 spec/models/post_spec.rb
  20. +37 0 spec/spec_helper.rb
  21. +3 0  spec/support/devise.rb
  22. +4 0 spec/support/mongoid.rb
  23. +0 13 test/fixtures/comments.yml
  24. +0 9 test/fixtures/posts.yml
  25. +0 11 test/fixtures/users.yml
  26. +0 8 test/functional/comments_controller_test.rb
  27. +0 49 test/functional/posts_controller_test.rb
  28. +0 9 test/performance/browsing_test.rb
  29. +0 7 test/test_helper.rb
  30. +0 8 test/unit/comment_test.rb
  31. +0 4 test/unit/helpers/comments_helper_test.rb
  32. +0 4 test/unit/helpers/posts_helper_test.rb
  33. +0 8 test/unit/post_test.rb
  34. +0 8 test/unit/user_test.rb
1  .rspec
... ... @@ -0,0 +1 @@
  1 +--colour
12 Gemfile
@@ -31,6 +31,12 @@ gem 'devise'
31 31 # Bundle gems for the local environment. Make sure to
32 32 # put test-only gems in this group so their generators
33 33 # and rake tasks are available in development mode:
34   -# group :development, :test do
35   -# gem 'webrat'
36   -# end
  34 +group :development, :test do
  35 + gem 'rspec-rails'
  36 +# gem 'cucumber-rails'
  37 + gem 'launchy'
  38 + gem 'capybara'
  39 + gem 'database_cleaner'
  40 + gem 'mongoid-rspec'
  41 + gem 'factory_girl_rails'
  42 +end
57 Gemfile.lock
@@ -33,12 +33,34 @@ GEM
33 33 bson (1.3.0)
34 34 bson_ext (1.3.0)
35 35 builder (2.1.2)
  36 + capybara (0.4.1.2)
  37 + celerity (>= 0.7.9)
  38 + culerity (>= 0.2.4)
  39 + mime-types (>= 1.16)
  40 + nokogiri (>= 1.3.3)
  41 + rack (>= 1.0.0)
  42 + rack-test (>= 0.5.4)
  43 + selenium-webdriver (>= 0.0.27)
  44 + xpath (~> 0.1.3)
  45 + celerity (0.8.9)
  46 + childprocess (0.1.8)
  47 + ffi (~> 1.0.6)
  48 + configuration (1.2.0)
  49 + culerity (0.2.15)
  50 + database_cleaner (0.6.7)
36 51 devise (1.2.1)
37 52 bcrypt-ruby (~> 2.1.2)
38 53 orm_adapter (~> 0.0.3)
39 54 warden (~> 1.0.3)
  55 + diff-lcs (1.1.2)
40 56 erubis (2.6.6)
41 57 abstract (>= 1.0.0)
  58 + factory_girl (1.3.3)
  59 + factory_girl_rails (1.0.1)
  60 + factory_girl (~> 1.3)
  61 + railties (>= 3.0.0)
  62 + ffi (1.0.7)
  63 + rake (>= 0.8.7)
42 64 formtastic (1.2.3)
43 65 actionpack (>= 2.3.7)
44 66 activesupport (>= 2.3.7)
@@ -47,6 +69,10 @@ GEM
47 69 jquery-rails (0.2.7)
48 70 rails (~> 3.0)
49 71 thor (~> 0.14.4)
  72 + json_pure (1.5.1)
  73 + launchy (0.4.0)
  74 + configuration (>= 0.0.5)
  75 + rake (>= 0.8.1)
50 76 mail (2.2.19)
51 77 activesupport (>= 2.3.6)
52 78 i18n (>= 0.4.0)
@@ -60,9 +86,13 @@ GEM
60 86 mongo (~> 1.3)
61 87 tzinfo (~> 0.3.22)
62 88 will_paginate (~> 3.0.pre)
  89 + mongoid-rspec (1.4.2)
  90 + mongoid (~> 2.0)
  91 + rspec (~> 2)
63 92 mongoid_slug (0.7.2)
64 93 mongoid (~> 2.0.0)
65 94 stringex (~> 1.2.0)
  95 + nokogiri (1.4.4)
66 96 orm_adapter (0.0.4)
67 97 polyglot (0.3.1)
68 98 rack (1.2.2)
@@ -84,6 +114,25 @@ GEM
84 114 rake (>= 0.8.7)
85 115 thor (~> 0.14.4)
86 116 rake (0.8.7)
  117 + rspec (2.5.0)
  118 + rspec-core (~> 2.5.0)
  119 + rspec-expectations (~> 2.5.0)
  120 + rspec-mocks (~> 2.5.0)
  121 + rspec-core (2.5.2)
  122 + rspec-expectations (2.5.0)
  123 + diff-lcs (~> 1.1.2)
  124 + rspec-mocks (2.5.0)
  125 + rspec-rails (2.5.0)
  126 + actionpack (~> 3.0)
  127 + activesupport (~> 3.0)
  128 + railties (~> 3.0)
  129 + rspec (~> 2.5.0)
  130 + rubyzip (0.9.4)
  131 + selenium-webdriver (0.2.0)
  132 + childprocess (>= 0.1.7)
  133 + ffi (>= 1.0.7)
  134 + json_pure
  135 + rubyzip
87 136 stringex (1.2.1)
88 137 thor (0.14.6)
89 138 treetop (1.4.9)
@@ -92,15 +141,23 @@ GEM
92 141 warden (1.0.3)
93 142 rack (>= 1.0.0)
94 143 will_paginate (3.0.pre2)
  144 + xpath (0.1.4)
  145 + nokogiri (~> 1.3)
95 146
96 147 PLATFORMS
97 148 ruby
98 149
99 150 DEPENDENCIES
100 151 bson_ext
  152 + capybara
  153 + database_cleaner
101 154 devise
  155 + factory_girl_rails
102 156 formtastic
103 157 jquery-rails
  158 + launchy
104 159 mongoid
  160 + mongoid-rspec
105 161 mongoid_slug
106 162 rails (= 3.0.7)
  163 + rspec-rails
8 app/controllers/posts_controller.rb
@@ -44,9 +44,11 @@ def edit
44 44 # POST /posts.xml
45 45 def create
46 46 @post = Post.new(params[:post])
47   - @post.users << current_user
48   - logger.debug "Going to save #{Rails.logger.level} #{@post.title.inspect}"
49   - respond_to do |format|
  47 + unless params[:author].blank?
  48 + @post.users << User.find(params[:author])
  49 + end
  50 + logger.debug "Going to save #{Rails.logger.level} #{@post.title.inspect} #{params[:post]}"
  51 + respond_to do |format|
50 52 begin
51 53 @post.safely.save!
52 54 logger.debug "Saved successfully #{@post.title.inspect}"
15 app/models/post.rb
... ... @@ -1,6 +1,7 @@
1 1 class Post
2 2 include Mongoid::Document
3 3 include Mongoid::Slug
  4 + include Mongoid::MultiParameterAttributes
4 5
5 6 attr_accessor :post_tags
6 7 attr_accessible :title, :content, :post_tags
@@ -10,11 +11,11 @@ class Post
10 11 field :published_on, :type => DateTime
11 12 field :tags, :type => Array
12 13 validates_presence_of :title, :content
13   - embeds_many :comments
  14 + embeds_many :comments, :dependent => :destroy
14 15 index :slug, unique:true
15 16
16 17 validates_uniqueness_of :title, :case_sensitive => false
17   - before_save :set_published_on, :generate_slug, :generate_tags
  18 + before_save :set_published_on, :generate_slug, :generate_tags
18 19 slug :slug
19 20
20 21 has_and_belongs_to_many :users
@@ -26,6 +27,16 @@ def get_tags
26 27 self.tags.inject{|tag_string,tag| tag_string + ", " + tag}
27 28 end
28 29 end
  30 +
  31 + def authors
  32 + unless users.empty?
  33 + users.map{|user| user.nick_name}
  34 + .inject{|author_1,author_2| author_1 + ", " + author_2 }
  35 + else
  36 + "None"
  37 + end
  38 + end
  39 +
29 40 private
30 41 def set_published_on
31 42 self.published_on = DateTime.now
4 app/models/user.rb
@@ -5,4 +5,8 @@ class User
5 5 devise :database_authenticatable, :registerable,
6 6 :recoverable, :rememberable, :trackable, :validatable
7 7 has_and_belongs_to_many :posts
  8 +
  9 + field :first_name
  10 + field :last_name
  11 + field :nick_name
8 12 end
9 app/views/devise/registrations/new.html.erb
@@ -3,6 +3,15 @@
3 3 <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
4 4 <%= devise_error_messages! %>
5 5
  6 + <p><%= f.label :first_name %><br />
  7 + <%= f.text_field :first_name %></p>
  8 +
  9 + <p><%= f.label :last_name %><br />
  10 + <%= f.text_field :last_name %></p>
  11 +
  12 + <p><%= f.label :nick_name %><br />
  13 + <%= f.text_field :nick_name %></p>
  14 +
6 15 <p><%= f.label :email %><br />
7 16 <%= f.email_field :email %></p>
8 17
12 app/views/posts/_form.html.erb
@@ -25,6 +25,18 @@
25 25 <%= f.label :tags %><br />
26 26 <%= f.text_field :post_tags %>
27 27 </div>
  28 + <div class="field">
  29 + <%= f.label :published_on %><br />
  30 + <%= f.datetime_select :published_on %>
  31 + </div>
  32 +
  33 +
  34 + <div class="field">
  35 + <%= f.label :author %><br />
  36 + <%= select_tag(:author,options_from_collection_for_select(User.all,:_id,:nick_name),:multiple=>true,:size=>3) %>
  37 + <%= options_from_collection_for_select(User.all,:_id,:nick_name) %>
  38 + </div>
  39 +
28 40 <div class="actions">
29 41 <%= f.submit %>
30 42 </div>
1  app/views/posts/show.html.erb
@@ -6,6 +6,7 @@
6 6 <p>
7 7 <%= @post.content %>
8 8 </p>
  9 +<p> Author(s) : <%= @post.authors %> </p>
9 10 <p> Tags : <%= @post.get_tags || "None" %> </p>
10 11
11 12 <%= link_to 'Edit', edit_post_path(@post) %> |
2  config/application.rb
@@ -5,7 +5,7 @@
5 5 require "action_controller/railtie"
6 6 require "action_mailer/railtie"
7 7 require "active_resource/railtie"
8   -require "rails/test_unit/railtie"
  8 +# require "rails/test_unit/railtie"
9 9
10 10 # If you have a Gemfile, require the gems listed there, including any gems
11 11 # you've limited to :test, :development, or :production.
8 config/cucumber.yml
... ... @@ -0,0 +1,8 @@
  1 +<%
  2 +rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
  3 +rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
  4 +std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
  5 +%>
  6 +default: <%= std_opts %> features
  7 +wip: --tags @wip:3 --wip features
  8 +rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
211 features/step_definitions/web_steps.rb
... ... @@ -0,0 +1,211 @@
  1 +# TL;DR: YOU SHOULD DELETE THIS FILE
  2 +#
  3 +# This file was generated by Cucumber-Rails and is only here to get you a head start
  4 +# These step definitions are thin wrappers around the Capybara/Webrat API that lets you
  5 +# visit pages, interact with widgets and make assertions about page content.
  6 +#
  7 +# If you use these step definitions as basis for your features you will quickly end up
  8 +# with features that are:
  9 +#
  10 +# * Hard to maintain
  11 +# * Verbose to read
  12 +#
  13 +# A much better approach is to write your own higher level step definitions, following
  14 +# the advice in the following blog posts:
  15 +#
  16 +# * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
  17 +# * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
  18 +# * http://elabs.se/blog/15-you-re-cuking-it-wrong
  19 +#
  20 +
  21 +
  22 +require 'uri'
  23 +require 'cgi'
  24 +require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
  25 +require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
  26 +
  27 +module WithinHelpers
  28 + def with_scope(locator)
  29 + locator ? within(*selector_for(locator)) { yield } : yield
  30 + end
  31 +end
  32 +World(WithinHelpers)
  33 +
  34 +# Single-line step scoper
  35 +When /^(.*) within ([^:]+)$/ do |step, parent|
  36 + with_scope(parent) { When step }
  37 +end
  38 +
  39 +# Multi-line step scoper
  40 +When /^(.*) within ([^:]+):$/ do |step, parent, table_or_string|
  41 + with_scope(parent) { When "#{step}:", table_or_string }
  42 +end
  43 +
  44 +Given /^(?:|I )am on (.+)$/ do |page_name|
  45 + visit path_to(page_name)
  46 +end
  47 +
  48 +When /^(?:|I )go to (.+)$/ do |page_name|
  49 + visit path_to(page_name)
  50 +end
  51 +
  52 +When /^(?:|I )press "([^"]*)"$/ do |button|
  53 + click_button(button)
  54 +end
  55 +
  56 +When /^(?:|I )follow "([^"]*)"$/ do |link|
  57 + click_link(link)
  58 +end
  59 +
  60 +When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
  61 + fill_in(field, :with => value)
  62 +end
  63 +
  64 +When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
  65 + fill_in(field, :with => value)
  66 +end
  67 +
  68 +# Use this to fill in an entire form with data from a table. Example:
  69 +#
  70 +# When I fill in the following:
  71 +# | Account Number | 5002 |
  72 +# | Expiry date | 2009-11-01 |
  73 +# | Note | Nice guy |
  74 +# | Wants Email? | |
  75 +#
  76 +# TODO: Add support for checkbox, select og option
  77 +# based on naming conventions.
  78 +#
  79 +When /^(?:|I )fill in the following:$/ do |fields|
  80 + fields.rows_hash.each do |name, value|
  81 + When %{I fill in "#{name}" with "#{value}"}
  82 + end
  83 +end
  84 +
  85 +When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
  86 + select(value, :from => field)
  87 +end
  88 +
  89 +When /^(?:|I )check "([^"]*)"$/ do |field|
  90 + check(field)
  91 +end
  92 +
  93 +When /^(?:|I )uncheck "([^"]*)"$/ do |field|
  94 + uncheck(field)
  95 +end
  96 +
  97 +When /^(?:|I )choose "([^"]*)"$/ do |field|
  98 + choose(field)
  99 +end
  100 +
  101 +When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
  102 + attach_file(field, File.expand_path(path))
  103 +end
  104 +
  105 +Then /^(?:|I )should see "([^"]*)"$/ do |text|
  106 + if page.respond_to? :should
  107 + page.should have_content(text)
  108 + else
  109 + assert page.has_content?(text)
  110 + end
  111 +end
  112 +
  113 +Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
  114 + regexp = Regexp.new(regexp)
  115 +
  116 + if page.respond_to? :should
  117 + page.should have_xpath('//*', :text => regexp)
  118 + else
  119 + assert page.has_xpath?('//*', :text => regexp)
  120 + end
  121 +end
  122 +
  123 +Then /^(?:|I )should not see "([^"]*)"$/ do |text|
  124 + if page.respond_to? :should
  125 + page.should have_no_content(text)
  126 + else
  127 + assert page.has_no_content?(text)
  128 + end
  129 +end
  130 +
  131 +Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
  132 + regexp = Regexp.new(regexp)
  133 +
  134 + if page.respond_to? :should
  135 + page.should have_no_xpath('//*', :text => regexp)
  136 + else
  137 + assert page.has_no_xpath?('//*', :text => regexp)
  138 + end
  139 +end
  140 +
  141 +Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
  142 + with_scope(parent) do
  143 + field = find_field(field)
  144 + field_value = (field.tag_name == 'textarea') ? field.text : field.value
  145 + if field_value.respond_to? :should
  146 + field_value.should =~ /#{value}/
  147 + else
  148 + assert_match(/#{value}/, field_value)
  149 + end
  150 + end
  151 +end
  152 +
  153 +Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
  154 + with_scope(parent) do
  155 + field = find_field(field)
  156 + field_value = (field.tag_name == 'textarea') ? field.text : field.value
  157 + if field_value.respond_to? :should_not
  158 + field_value.should_not =~ /#{value}/
  159 + else
  160 + assert_no_match(/#{value}/, field_value)
  161 + end
  162 + end
  163 +end
  164 +
  165 +Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
  166 + with_scope(parent) do
  167 + field_checked = find_field(label)['checked']
  168 + if field_checked.respond_to? :should
  169 + field_checked.should be_true
  170 + else
  171 + assert field_checked
  172 + end
  173 + end
  174 +end
  175 +
  176 +Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
  177 + with_scope(parent) do
  178 + field_checked = find_field(label)['checked']
  179 + if field_checked.respond_to? :should
  180 + field_checked.should be_false
  181 + else
  182 + assert !field_checked
  183 + end
  184 + end
  185 +end
  186 +
  187 +Then /^(?:|I )should be on (.+)$/ do |page_name|
  188 + current_path = URI.parse(current_url).path
  189 + if current_path.respond_to? :should
  190 + current_path.should == path_to(page_name)
  191 + else
  192 + assert_equal path_to(page_name), current_path
  193 + end
  194 +end
  195 +
  196 +Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
  197 + query = URI.parse(current_url).query
  198 + actual_params = query ? CGI.parse(query) : {}
  199 + expected_params = {}
  200 + expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
  201 +
  202 + if actual_params.respond_to? :should
  203 + actual_params.should == expected_params
  204 + else
  205 + assert_equal expected_params, actual_params
  206 + end
  207 +end
  208 +
  209 +Then /^show me the page$/ do
  210 + save_and_open_page
  211 +end
39 features/support/env.rb
... ... @@ -0,0 +1,39 @@
  1 +# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
  2 +# It is recommended to regenerate this file in the future when you upgrade to a
  3 +# newer version of cucumber-rails. Consider adding your own code to a new file
  4 +# instead of editing this one. Cucumber will automatically load all features/**/*.rb
  5 +# files.
  6 +
  7 +require 'cucumber/rails'
  8 +
  9 +# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
  10 +# order to ease the transition to Capybara we set the default here. If you'd
  11 +# prefer to use XPath just remove this line and adjust any selectors in your
  12 +# steps to use the XPath syntax.
  13 +Capybara.default_selector = :css
  14 +
  15 +# By default, any exception happening in your Rails application will bubble up
  16 +# to Cucumber so that your scenario will fail. This is a different from how
  17 +# your application behaves in the production environment, where an error page will
  18 +# be rendered instead.
  19 +#
  20 +# Sometimes we want to override this default behaviour and allow Rails to rescue
  21 +# exceptions and display an error page (just like when the app is running in production).
  22 +# Typical scenarios where you want to do this is when you test your error pages.
  23 +# There are two ways to allow Rails to rescue exceptions:
  24 +#
  25 +# 1) Tag your scenario (or feature) with @allow-rescue
  26 +#
  27 +# 2) Set the value below to true. Beware that doing this globally is not
  28 +# recommended as it will mask a lot of errors for you!
  29 +#
  30 +ActionController::Base.allow_rescue = false
  31 +
  32 +# Remove/comment out the lines below if your app doesn't have a database.
  33 +# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
  34 +begin
  35 + DatabaseCleaner.strategy = :transaction
  36 +rescue NameError
  37 + raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
  38 +end
  39 +
33 features/support/paths.rb
... ... @@ -0,0 +1,33 @@
  1 +module NavigationHelpers
  2 + # Maps a name to a path. Used by the
  3 + #
  4 + # When /^I go to (.+)$/ do |page_name|
  5 + #
  6 + # step definition in web_steps.rb
  7 + #
  8 + def path_to(page_name)
  9 + case page_name
  10 +
  11 + when /the home\s?page/
  12 + '/'
  13 +
  14 + # Add more mappings here.
  15 + # Here is an example that pulls values out of the Regexp:
  16 + #
  17 + # when /^(.*)'s profile page$/i
  18 + # user_profile_path(User.find_by_login($1))
  19 +
  20 + else
  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
  29 + end
  30 + end
  31 +end
  32 +
  33 +World(NavigationHelpers)
39 features/support/selectors.rb
... ... @@ -0,0 +1,39 @@
  1 +module HtmlSelectorsHelpers
  2 + # Maps a name to a selector. Used primarily by the
  3 + #
  4 + # When /^(.+) within (.+)$/ do |step, scope|
  5 + #
  6 + # step definitions in web_steps.rb
  7 + #
  8 + def selector_for(locator)
  9 + case locator
  10 +
  11 + when /the page/
  12 + "html > body"
  13 +
  14 + # Add more mappings here.
  15 + # Here is an example that pulls values out of the Regexp:
  16 + #
  17 + # when /the (notice|error|info) flash/
  18 + # ".flash.#{$1}"
  19 +
  20 + # You can also return an array to use a different selector
  21 + # type, like:
  22 + #
  23 + # when /the header/
  24 + # [:xpath, "//header"]
  25 +
  26 + # This allows you to provide a quoted selector as the scope
  27 + # for "within" steps as was previously the default for the
  28 + # web steps:
  29 + when /"(.+)"/
  30 + $1
  31 +
  32 + else
  33 + raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
  34 + "Now, go and add a mapping in #{__FILE__}"
  35 + end
  36 + end
  37 +end
  38 +
  39 +World(HtmlSelectorsHelpers)
57 lib/tasks/cucumber.rake
... ... @@ -0,0 +1,57 @@
  1 +# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
  2 +# It is recommended to regenerate this file in the future when you upgrade to a
  3 +# newer version of cucumber-rails. Consider adding your own code to a new file
  4 +# instead of editing this one. Cucumber will automatically load all features/**/*.rb
  5 +# files.
  6 +
  7 +
  8 +unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
  9 +
  10 +vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
  11 +$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
  12 +
  13 +begin
  14 + require 'cucumber/rake/task'
  15 +
  16 + namespace :cucumber do
  17 + Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
  18 + t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
  19 + t.fork = true # You may get faster startup if you set this to false
  20 + t.profile = 'default'
  21 + end
  22 +
  23 + Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
  24 + t.binary = vendored_cucumber_bin
  25 + t.fork = true # You may get faster startup if you set this to false
  26 + t.profile = 'wip'
  27 + end
  28 +
  29 + Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
  30 + t.binary = vendored_cucumber_bin
  31 + t.fork = true # You may get faster startup if you set this to false
  32 + t.profile = 'rerun'
  33 + end
  34 +
  35 + desc 'Run all features'
  36 + task :all => [:ok, :wip]
  37 + end
  38 + desc 'Alias for cucumber:ok'
  39 + task :cucumber => 'cucumber:ok'
  40 +
  41 + task :default => :cucumber
  42 +
  43 + task :features => :cucumber do
  44 + STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
  45 + end
  46 +
  47 + # In case we don't have ActiveRecord, append a no-op task that we can depend upon.
  48 + task 'db:test:prepare' do
  49 + end
  50 +rescue LoadError
  51 + desc 'cucumber rake task not available (cucumber not installed)'
  52 + task :cucumber do
  53 + abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
  54 + end
  55 +end
  56 +
  57 +end
239 public/index.html
... ... @@ -1,239 +0,0 @@
1   -<!DOCTYPE html>
2   -<html>
3   - <head>
4   - <title>Ruby on Rails: Welcome aboard</title>
5   - <style type="text/css" media="screen">
6   - body {
7   - margin: 0;
8   - margin-bottom: 25px;
9   - padding: 0;
10   - background-color: #f0f0f0;
11   - font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
12   - font-size: 13px;
13   - color: #333;
14   - }
15   -
16   - h1 {
17   - font-size: 28px;
18   - color: #000;
19   - }
20   -
21   - a {color: #03c}
22   - a:hover {
23   - background-color: #03c;
24   - color: white;
25   - text-decoration: none;
26   - }
27   -
28   -
29   - #page {
30   - background-color: #f0f0f0;
31   - width: 750px;
32   - margin: 0;
33   - margin-left: auto;
34   - margin-right: auto;
35   - }
36   -
37   - #content {
38   - float: left;
39   - background-color: white;
40   - border: 3px solid #aaa;
41   - border-top: none;
42   - padding: 25px;
43   - width: 500px;
44   - }
45   -
46   - #sidebar {
47   - float: right;
48   - width: 175px;
49   - }
50   -
51   - #footer {
52   - clear: both;
53   - }
54   -
55   -
56   - #header, #about, #getting-started {
57   - padding-left: 75px;
58   - padding-right: 30px;
59   - }
60   -
61   -
62   - #header {
63   - background-image: url("images/rails.png");
64   - background-repeat: no-repeat;
65   - background-position: top left;
66   - height: 64px;
67   - }
68   - #header h1, #header h2 {margin: 0}
69   - #header h2 {
70   - color: #888;
71   - font-weight: normal;
72   - font-size: 16px;
73   - }
74   -
75   -
76   - #about h3 {
77   - margin: 0;
78   - margin-bottom: 10px;
79   - font-size: 14px;
80   - }
81   -
82   - #about-content {
83   - background-color: #ffd;
84   - border: 1px solid #fc0;
85   - margin-left: -55px;
86   - margin-right: -10px;
87   - }
88   - #about-content table {
89   - margin-top: 10px;
90   - margin-bottom: 10px;
91   - font-size: 11px;
92   - border-collapse: collapse;
93   - }
94   - #about-content td {
95   - padding: 10px;
96   - padding-top: 3px;
97   - padding-bottom: 3px;
98   - }
99   - #about-content td.name {color: #555}
100   - #about-content td.value {color: #000}
101   -
102   - #about-content ul {
103   - padding: 0;
104   - list-style-type: none;
105   - }
106   -
107   - #about-content.failure {
108   - background-color: #fcc;
109   - border: 1px solid #f00;
110   - }
111   - #about-content.failure p {
112   - margin: 0;
113   - padding: 10px;
114   - }
115   -
116   -
117   - #getting-started {
118   - border-top: 1px solid #ccc;
119   - margin-top: 25px;
120   - padding-top: 15px;
121   - }
122   - #getting-started h1 {
123   - margin: 0;
124   - font-size: 20px;
125   - }
126   - #getting-started h2 {
127   - margin: 0;
128   - font-size: 14px;
129   - font-weight: normal;
130   - color: #333;
131   - margin-bottom: 25px;
132   - }
133   - #getting-started ol {
134   - margin-left: 0;
135   - padding-left: 0;
136   - }
137   - #getting-started li {
138   - font-size: 18px;
139   - color: #888;
140   - margin-bottom: 25px;
141   - }
142   - #getting-started li h2 {
143   - margin: 0;
144   - font-weight: normal;
145   - font-size: 18px;
146   - color: #333;
147   - }
148   - #getting-started li p {
149   - color: #555;
150   - font-size: 13px;
151   - }
152   -
153   -
154   - #sidebar ul {
155   - margin-left: 0;
156   - padding-left: 0;
157   - }
158   - #sidebar ul h3 {
159   - margin-top: 25px;
160   - font-size: 16px;
161   - padding-bottom: 10px;
162   - border-bottom: 1px solid #ccc;
163   - }
164   - #sidebar li {
165   - list-style-type: none;
166   - }
167   - #sidebar ul.links li {
168   - margin-bottom: 5px;
169   - }
170   -
171   - </style>
172   - <script type="text/javascript">
173   - function about() {
174   - info = document.getElementById('about-content');
175   - if (window.XMLHttpRequest)
176   - { xhr = new XMLHttpRequest(); }
177   - else
178   - { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
179   - xhr.open("GET","rails/info/properties",false);
180   - xhr.send("");
181   - info.innerHTML = xhr.responseText;
182   - info.style.display = 'block'
183   - }
184   - </script>
185   - </head>
186   - <body>
187   - <div id="page">
188   - <div id="sidebar">
189   - <ul id="sidebar-items">
190   - <li>
191   - <h3>Browse the documentation</h3>
192   - <ul class="links">
193   - <li><a href="http://api.rubyonrails.org/">Rails API</a></li>
194   - <li><a href="http://stdlib.rubyonrails.org/">Ruby standard library</a></li>
195   - <li><a href="http://corelib.rubyonrails.org/">Ruby core</a></li>
196   - <li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
197   - </ul>
198   - </li>
199   - </ul>
200   - </div>
201   -
202   - <div id="content">
203   - <div id="header">
204   - <h1>Welcome aboard</h1>
205   - <h2>You&rsquo;re riding Ruby on Rails!</h2>
206   - </div>
207   -
208   - <div id="about">
209   - <h3><a href="rails/info/properties" onclick="about(); return false">About your application&rsquo;s environment</a></h3>
210   - <div id="about-content" style="display: none"></div>
211   - </div>
212   -
213   - <div id="getting-started">
214   - <h1>Getting started</h1>
215   - <h2>Here&rsquo;s how to get rolling:</h2>
216   -
217   - <ol>
218   - <li>
219   - <h2>Use <code>rails generate</code> to create your models and controllers</h2>
220   - <p>To see all available options, run it without parameters.</p>
221   - </li>
222   -
223   - <li>
224   - <h2>Set up a default route and remove or rename this file</h2>
225   - <p>Routes are set up in config/routes.rb.</p>
226   - </li>
227   -
228   - <li>
229   - <h2>Create your database</h2>
230   - <p>Run <code>rake db:migrate</code> to create your database. If you're not using SQLite (the default), edit <code>config/database.yml</code> with your username and password.</p>
231   - </li>
232   - </ol>
233   - </div>
234   - </div>
235   -
236   - <div id="footer">&nbsp;</div>
237   - </div>
238   - </body>
239   -</html>
10 script/cucumber
... ... @@ -0,0 +1,10 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
  4 +if vendored_cucumber_bin
  5 + load File.expand_path(vendored_cucumber_bin)
  6 +else
  7 + require 'rubygems' unless ENV['NO_RUBYGEMS']
  8 + require 'cucumber'
  9 + load Cucumber::BINARY
  10 +end
115 spec/models/post_spec.rb
... ... @@ -0,0 +1,115 @@
  1 +
  2 +require 'spec_helper'
  3 +
  4 +describe Post do
  5 +
  6 + before(:each) do
  7 + @attr = {
  8 + :title => "Foo Post",
  9 + :content => "Bar Content"
  10 + }
  11 + @post = Post.new(@attr)
  12 + end
  13 +
  14 + describe "create post" do
  15 + it "should create a post with title and content" do
  16 + @post.should be_valid
  17 + end
  18 +
  19 + it "should not create a post without title" do
  20 + @post.title = nil
  21 + @post.should_not be_valid
  22 + end
  23 +
  24 + it "should not create a post without content" do
  25 + @post.content = nil
  26 + @post.should_not be_valid
  27 + end
  28 +
  29 + it "should not create a post with blank title" do
  30 + @post.title = " "
  31 + @post.should_not be_valid
  32 + end
  33 +
  34 + it "should embed many comments" do
  35 + @post.should embed_many(:comments).with_dependent(:destroy)
  36 + end
  37 +
  38 + it "should have one or many authors" do
  39 + @post.should have_and_belong_to_many(:users)
  40 + end
  41 + end
  42 +
  43 + context "create post validations" do
  44 +
  45 + describe "#slug" do
  46 + it "should be generated while saving" do
  47 + @post.save!
  48 + @post.slug.should_not be_nil
  49 + @post.slug.should == "foo-post"
  50 + end
  51 +
  52 + it "should truncate unwanted spaces and put - in slug" do
  53 + @post.title = "Foo Post"
  54 + @post.save!
  55 + @post.slug.should == "foo-post"
  56 + @post.title.should == "Foo Post"
  57 + end
  58 +
  59 + it "should replace all special characters with -" do
  60 + @post.title = "Foo+Post#Test"
  61 + @post.save!
  62 + @post.slug.should == "foo-post-test"
  63 + @post.title.should == "Foo+Post#Test"
  64 + end
  65 +
  66 + it "should replace all consecutive occurences of -'s to a single -" do
  67 + @post.title = "Foo+-Post*#Test"
  68 + @post.save!
  69 + @post.slug.should == "foo-post-test"
  70 + @post.title.should == "Foo+-Post*#Test"
  71 + end
  72 +
  73 + it "should not accept duplicates while saving" do
  74 + @post.save!
  75 + post1 = Post.new(@attr.merge(:title=>"Foo+Post"))
  76 + post1.safely.save.should raise_error
  77 + end
  78 + end
  79 +
  80 + describe "#tags" do
  81 + it "should be nil if not given" do
  82 + @post.tags.should be_nil
  83 + end
  84 +
  85 + it "should have one element if input has one tag" do
  86 + @post.post_tags = "Ruby"
  87 + @post.save!
  88 + @post.tags.should_not be_empty
  89 + @post.tags.should include("Ruby")
  90 + @post.tags.size.should == 1
  91 + end
  92 +
  93 + it "should have n elements if input has n tags" do
  94 + @post.post_tags = "Ruby,Rails,Sinatra,Merb"
  95 + @post.save!
  96 + @post.tags.should == ["Ruby","Rails","Sinatra","Merb"]
  97 + end
  98 + end
  99 +
  100 + describe "#title" do
  101 + it "should not accept duplicates" do
  102 + @post.save!
  103 + post1 = Post.new(@attr)
  104 + post1.should_not be_valid
  105 + end
  106 + end
  107 +
  108 + describe "#published_on" do
  109 + it "should be a valid date time" do
  110 + @post.save!
  111 + @post.published_on.should_not be_nil
  112 + end
  113 + end
  114 + end
  115 +end
37 spec/spec_helper.rb
... ... @@ -0,0 +1,37 @@
  1 +# This file is copied to spec/ when you run 'rails generate rspec:install'
  2 +ENV["RAILS_ENV"] ||= 'test'
  3 +require File.expand_path("../../config/environment", __FILE__)
  4 +require 'rspec/rails'
  5 +
  6 +# Requires supporting ruby files with custom matchers and macros, etc,
  7 +# in spec/support/ and its subdirectories.
  8 +Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
  9 +
  10 +RSpec.configure do |config|
  11 + # == Mock Framework
  12 + #
  13 + # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
  14 + #
  15 + # config.mock_with :mocha
  16 + # config.mock_with :flexmock
  17 + # config.mock_with :rr
  18 + config.mock_with :rspec
  19 +
  20 + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  21 + #config.fixture_path = "#{::Rails.root}/spec/fixtures"
  22 +
  23 + # If you're not using ActiveRecord, or you'd prefer not to run each of your
  24 + # examples within a transaction, remove the following line or assign false
  25 + # instead of true.
  26 + #config.use_transactional_fixtures = true
  27 +
  28 + require 'database_cleaner'
  29 + config.before(:suite) do
  30 + DatabaseCleaner.strategy = :truncation
  31 + DatabaseCleaner.orm = "mongoid"
  32 + end
  33 +
  34 + config.before(:each) do
  35 + DatabaseCleaner.clean
  36 + end
  37 +end
3  spec/support/devise.rb
... ... @@ -0,0 +1,3 @@
  1 +RSpec.configure do |config|
  2 + config.include Devise::TestHelpers, :type => :controller
  3 +end
4 spec/support/mongoid.rb
... ... @@ -0,0 +1,4 @@
  1 +
  2 +RSpec.configure do |config|
  3 + config.include Mongoid::Matchers
  4 +end
13 test/fixtures/comments.yml
... ... @@ -1,13 +0,0 @@
1   -# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2   -
3   -one:
4   - author:
5   - email:
6   - url:
7   - content: MyText
8   -
9   -two:
10   - author:
11   - email:
12   - url:
13   - content: MyText
9 test/fixtures/posts.yml
... ... @@ -1,9 +0,0 @@
1   -# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2   -
3   -one:
4   - title: MyString
5   - content: MyText
6   -
7   -two:
8   - title: MyString
9   - content: MyText
11 test/fixtures/users.yml
... ... @@ -1,11 +0,0 @@
1   -# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2   -
3   -# This model initially had no columns defined. If you add columns to the
4   -# model remove the '{}' from the fixture names and add the columns immediately
5   -# below each fixture, per the syntax in the comments below
6   -#
7   -one: {}
8   -# column: value
9   -#
10   -two: {}
11   -# column: value
8 test/functional/comments_controller_test.rb
... ... @@ -1,8 +0,0 @@
1   -require 'test_helper'
2   -
3   -class CommentsControllerTest < ActionController::TestCase
4   - # Replace this with your real tests.
5   - test "the truth" do
6   - assert true
7   - end
8   -end
49 test/functional/posts_controller_test.rb
... ... @@ -1,49 +0,0 @@
1   -require 'test_helper'
2   -
3   -class PostsControllerTest < ActionController::TestCase
4   - setup do
5   - @post = posts(:one)
6   - end
7   -
8   - test "should get index" do
9   - get :index
10   - assert_response :success
11   - assert_not_nil assigns(:posts)
12   - end
13   -
14   - test "should get new" do
15   - get :new
16   - assert_response :success
17   - end
18   -
19   - test "should create post" do
20   - assert_difference('Post.count') do
21   - post :create, :post => @post.attributes
22   - end
23   -
24   - assert_redirected_to post_path(assigns(:post))
25   - end
26   -
27   - test "should show post" do
28   - get :show, :id => @post.to_param
29   - assert_response :success
30   - end
31   -
32   - test "should get edit" do
33   - get :edit, :id => @post.to_param
34   - assert_response :success
35   - end
36   -
37   - test "should update post" do
38   - put :update, :id => @post.to_param, :post => @post.attributes
39   - assert_redirected_to post_path(assigns(:post))
40