initial upgrade to rails 3.2.3

This commit is contained in:
Reinier Balt 2012-04-05 10:43:56 +02:00
parent f6d08a9cf5
commit a83c8b3f92
73 changed files with 4141 additions and 1079 deletions

25
.gitignore.rails2 Normal file
View file

@ -0,0 +1,25 @@
*~
*.tmproj
.dotest
/.emacs-project
/.redcar
config/database.yml
config/site.yml
config/deploy.rb
db/*.sqlite3
db/data.yml
db/schema.rb
log
nbproject
public/javascripts/cache
public/stylesheets/cache
tmp
vendor/plugins/query_trace/
rerun.txt
public/javascripts/jquery-cached.js
public/javascripts/tracks-cached.js
public/stylesheets/tracks-cached.css
.idea
.rvmrc
.yardoc
tags

84
Gemfile
View file

@ -1,64 +1,38 @@
source :gemcutter source 'https://rubygems.org'
source "http://gems.github.com/"
gem "rake", "~>0.8.7" gem 'rails', '3.2.3'
gem "rails", "~>2.3.12"
gem "highline", "~>1.5.0"
gem "RedCloth", "4.2.8"
gem "sanitize", "~>1.2.1"
gem "rack", "1.1.0"
gem "will_paginate", "~> 2.3.15"
gem "acts_as_list", "~>0.1.4"
gem "aasm", "~>2.2.0"
gem "rubyjedi-actionwebservice", :require => "actionwebservice"
gem "rubycas-client", "~>2.2.1"
gem "ruby-openid", :require => "openid"
# you may comment out the database driver you will not be using. # Bundle edge Rails instead:
# This will prevent a native build of the driver. Building native drivers is not always possible on all hosters # gem 'rails', :git => 'git://github.com/rails/rails.git'
gem "sqlite3"
gem "mysql"
gem 'bcrypt-ruby', '~> 2.1.4' gem 'sqlite3'
gem 'htmlentities', '~> 4.3.0'
gem "mail"
if RUBY_VERSION.to_f >= 1.9
gem "soap4r-ruby1.9" # Gems used only for assets and not required
else # in production environments by default.
gem "soap4r", "~>1.5.8" group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platform => :ruby
gem 'uglifier', '>= 1.0.3'
end end
group :development do gem 'jquery-rails'
if RUBY_VERSION.to_f >= 1.9
gem "ruby-debug19"
gem "mongrel", "1.2.0.pre2"
else
gem "ruby-debug"
gem "mongrel"
end
gem "yard"
end
group :test do # To use ActiveModel has_secure_password
gem "test-unit", "1.2.3" # gem 'bcrypt-ruby', '~> 3.0.0'
gem "flexmock"
gem "ZenTest", ">=4.0.0"
gem "hpricot"
gem "hoe"
gem "rspec-rails", "~>1.3.3"
gem "thoughtbot-factory_girl"
gem 'memory_test_fix', '~>0.1.3'
gem "capybara", ">=0.3.5"
gem "selenium-webdriver" # Note that > 2.14 has problems: https://code.google.com/p/selenium/issues/detail?id=3075
gem "database_cleaner", ">=0.5.0"
gem "cucumber-rails", "~>0.3.2"
gem "aruba", "0.2.2", :path => "vendor/gems/aruba-0.2.2"
# uncomment to use the webkit option. This depends on Qt to be installed # To use Jbuilder templates for JSON
#gem "capybara-webkit" # gem 'jbuilder'
# uncomment to be able to make screenshots from scenarios # Use unicorn as the app server
#gem "capybara-screenshot" # gem 'unicorn'
#gem "launchy"
end # Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'

View file

@ -1,28 +1,36 @@
PATH
remote: vendor/gems/aruba-0.2.2
specs:
aruba (0.2.2)
GEM GEM
remote: http://rubygems.org/ remote: https://rubygems.org/
remote: http://gems.github.com/
specs: specs:
RedCloth (4.2.8) actionmailer (3.2.3)
ZenTest (4.6.2) actionpack (= 3.2.3)
aasm (2.2.1) mail (~> 2.4.4)
actionmailer (2.3.14) actionpack (3.2.3)
actionpack (= 2.3.14) activemodel (= 3.2.3)
actionpack (2.3.14) activesupport (= 3.2.3)
activesupport (= 2.3.14) builder (~> 3.0.0)
rack (~> 1.1.0) erubis (~> 2.7.0)
activerecord (2.3.14) journey (~> 1.0.1)
activesupport (= 2.3.14) rack (~> 1.4.0)
activeresource (2.3.14) rack-cache (~> 1.2)
activesupport (= 2.3.14) rack-test (~> 0.6.1)
activesupport (2.3.14) sprockets (~> 2.1.2)
acts_as_list (0.1.4) activemodel (3.2.3)
bcrypt-ruby (2.1.4) activesupport (= 3.2.3)
builder (~> 3.0.0)
activerecord (3.2.3)
activemodel (= 3.2.3)
activesupport (= 3.2.3)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.3)
activemodel (= 3.2.3)
activesupport (= 3.2.3)
activesupport (3.2.3)
i18n (~> 0.6)
multi_json (~> 1.0)
arel (3.0.2)
builder (3.0.0) builder (3.0.0)
<<<<<<< HEAD
capybara (1.1.2) capybara (1.1.2)
mime-types (>= 1.16) mime-types (>= 1.16)
nokogiri (>= 1.3.3) nokogiri (>= 1.3.3)
@ -57,80 +65,82 @@ GEM
hpricot (0.8.6) hpricot (0.8.6)
htmlentities (4.3.1) htmlentities (4.3.1)
httpclient (2.2.4) httpclient (2.2.4)
=======
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.2.0)
erubis (2.7.0)
execjs (1.3.0)
multi_json (~> 1.0)
hike (1.2.1)
>>>>>>> initial upgrade to rails 3.2.3
i18n (0.6.0) i18n (0.6.0)
json (1.6.5) journey (1.0.3)
linecache (0.46) jquery-rails (2.0.2)
rbx-require-relative (> 0.0.4) railties (>= 3.2.0, < 5.0)
mail (2.4.1) thor (~> 0.14)
json (1.6.6)
mail (2.4.4)
i18n (>= 0.4.0) i18n (>= 0.4.0)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
memory_test_fix (0.1.3) mime-types (1.18)
mime-types (1.17.2) multi_json (1.2.0)
mongrel (1.1.5)
cgi_multipart_eof_fix (>= 2.4)
daemons (>= 1.0.3)
fastthread (>= 1.0.1)
gem_plugin (>= 0.2.3)
multi_json (1.1.0)
mysql (2.8.1)
nokogiri (1.4.7)
polyglot (0.3.3) polyglot (0.3.3)
rack (1.1.0) rack (1.4.1)
rack-cache (1.2)
rack (>= 0.4)
rack-ssl (1.3.2)
rack
rack-test (0.6.1) rack-test (0.6.1)
rack (>= 1.0) rack (>= 1.0)
rails (2.3.14) rails (3.2.3)
actionmailer (= 2.3.14) actionmailer (= 3.2.3)
actionpack (= 2.3.14) actionpack (= 3.2.3)
activerecord (= 2.3.14) activerecord (= 3.2.3)
activeresource (= 2.3.14) activeresource (= 3.2.3)
activesupport (= 2.3.14) activesupport (= 3.2.3)
rake (>= 0.8.3) bundler (~> 1.0)
rake (0.8.7) railties (= 3.2.3)
rbx-require-relative (0.0.5) railties (3.2.3)
rspec (1.3.2) actionpack (= 3.2.3)
rspec-rails (1.3.4) activesupport (= 3.2.3)
rack (>= 1.0.0) rack-ssl (~> 1.3.2)
rspec (~> 1.3.1) rake (>= 0.8.7)
ruby-debug (0.10.4) rdoc (~> 3.4)
columnize (>= 0.1) thor (~> 0.14.6)
ruby-debug-base (~> 0.10.4.0) rake (0.9.2.2)
ruby-debug-base (0.10.4) rdoc (3.12)
linecache (>= 0.3) json (~> 1.4)
ruby-openid (2.1.8) sass (3.1.15)
rubycas-client (2.2.1) sass-rails (3.2.5)
activesupport railties (~> 3.2.0)
rubyjedi-actionwebservice (2.3.5.20100714122544) sass (>= 3.1.10)
actionpack (~> 2.3.0) tilt (~> 1.3)
activerecord (~> 2.3.0) sprockets (2.1.2)
activesupport (~> 2.3.0) hike (~> 1.2)
rubyzip (0.9.6.1) rack (~> 1.0)
sanitize (1.2.1) tilt (~> 1.1, != 1.3.0)
nokogiri (~> 1.4.1)
selenium-webdriver (2.20.0)
childprocess (>= 0.2.5)
ffi (~> 1.0)
multi_json (~> 1.0)
rubyzip
soap4r (1.5.8)
httpclient (>= 2.1.1)
sqlite3 (1.3.5) sqlite3 (1.3.5)
term-ansicolor (1.0.7) thor (0.14.6)
test-unit (1.2.3) tilt (1.3.3)
hoe (>= 1.5.1)
thoughtbot-factory_girl (1.2.2)
treetop (1.4.10) treetop (1.4.10)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
will_paginate (2.3.16) tzinfo (0.3.32)
xpath (0.1.4) uglifier (1.2.4)
nokogiri (~> 1.3) execjs (>= 0.3.0)
yard (0.7.5) multi_json (>= 1.0.2)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
<<<<<<< HEAD
RedCloth (= 4.2.8) RedCloth (= 4.2.8)
ZenTest (>= 4.0.0) ZenTest (>= 4.0.0)
aasm (~> 2.2.0) aasm (~> 2.2.0)
@ -160,8 +170,11 @@ DEPENDENCIES
sanitize (~> 1.2.1) sanitize (~> 1.2.1)
selenium-webdriver selenium-webdriver
soap4r (~> 1.5.8) soap4r (~> 1.5.8)
=======
coffee-rails (~> 3.2.1)
jquery-rails
rails (= 3.2.3)
sass-rails (~> 3.2.3)
>>>>>>> initial upgrade to rails 3.2.3
sqlite3 sqlite3
test-unit (= 1.2.3) uglifier (>= 1.0.3)
thoughtbot-factory_girl
will_paginate (~> 2.3.15)
yard

65
Gemfile.rails2.3 Normal file
View file

@ -0,0 +1,65 @@
source :gemcutter
source "http://gems.github.com/"
gem "rake", "~>0.8.7"
gem "rails", "~>2.3.12"
gem "highline", "~>1.5.0"
gem "RedCloth", "4.2.8"
gem "sanitize", "~>1.2.1"
gem "rack", "1.1.0"
gem "will_paginate", "~> 2.3.15"
gem "has_many_polymorphs", "~> 2.13"
gem "acts_as_list", "~>0.1.4"
gem "aasm", "~>2.2.0"
gem "rubyjedi-actionwebservice", :require => "actionwebservice"
gem "rubycas-client", "~>2.2.1"
gem "ruby-openid", :require => "openid"
# you may comment out the database driver you will not be using.
# This will prevent a native build of the driver. Building native drivers is not always possible on all hosters
gem "sqlite3"
gem "mysql"
gem 'bcrypt-ruby', '~> 2.1.4'
gem 'htmlentities', '~> 4.3.0'
gem "mail"
if RUBY_VERSION.to_f >= 1.9
gem "soap4r-ruby1.9"
else
gem "soap4r", "~>1.5.8"
end
group :development do
if RUBY_VERSION.to_f >= 1.9
gem "ruby-debug19"
gem "mongrel", "1.2.0.pre2"
else
gem "ruby-debug"
gem "mongrel"
end
gem "yard"
end
group :test do
gem "test-unit", "1.2.3"
gem "flexmock"
gem "ZenTest", ">=4.0.0"
gem "hpricot"
gem "hoe"
gem "rspec-rails", "~>1.3.3"
gem "thoughtbot-factory_girl"
gem 'memory_test_fix', '~>0.1.3'
gem "capybara", ">=0.3.5"
gem "selenium-webdriver" # Note that > 2.14 has problems: https://code.google.com/p/selenium/issues/detail?id=3075
gem "database_cleaner", ">=0.5.0"
gem "cucumber-rails", "~>0.3.2"
gem "aruba", "0.2.2", :path => "vendor/gems/aruba-0.2.2"
# uncomment to use the webkit option. This depends on Qt to be installed
#gem "capybara-webkit"
# uncomment to be able to make screenshots from scenarios
#gem "capybara-screenshot"
#gem "launchy"
end

39
Gemfile.rails3 Normal file
View file

@ -0,0 +1,39 @@
source 'https://rubygems.org'
gem 'rails', '3.2.3'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
gem 'mysql'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platform => :ruby
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# To use Jbuilder templates for JSON
# gem 'jbuilder'
# Use unicorn as the app server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'

261
README.rdoc Normal file
View file

@ -0,0 +1,261 @@
== Welcome to Rails
Rails is a web-application framework that includes everything needed to create
database-backed web applications according to the Model-View-Control pattern.
This pattern splits the view (also called the presentation) into "dumb"
templates that are primarily responsible for inserting pre-built data in between
HTML tags. The model contains the "smart" domain objects (such as Account,
Product, Person, Post) that holds all the business logic and knows how to
persist themselves to a database. The controller handles the incoming requests
(such as Save New Account, Update Product, Show Post) by manipulating the model
and directing data to the view.
In Rails, the model is handled by what's called an object-relational mapping
layer entitled Active Record. This layer allows you to present the data from
database rows as objects and embellish these data objects with business logic
methods. You can read more about Active Record in
link:files/vendor/rails/activerecord/README.html.
The controller and view are handled by the Action Pack, which handles both
layers by its two parts: Action View and Action Controller. These two layers
are bundled in a single package due to their heavy interdependence. This is
unlike the relationship between the Active Record and Action Pack that is much
more separate. Each of these packages can be used independently outside of
Rails. You can read more about Action Pack in
link:files/vendor/rails/actionpack/README.html.
== Getting Started
1. At the command prompt, create a new Rails application:
<tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
2. Change directory to <tt>myapp</tt> and start the web server:
<tt>cd myapp; rails server</tt> (run with --help for options)
3. Go to http://localhost:3000/ and you'll see:
"Welcome aboard: You're riding Ruby on Rails!"
4. Follow the guidelines to start developing your application. You can find
the following resources handy:
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
== Debugging Rails
Sometimes your application goes wrong. Fortunately there are a lot of tools that
will help you debug it and get it back on the rails.
First area to check is the application log files. Have "tail -f" commands
running on the server.log and development.log. Rails will automatically display
debugging and runtime information to these files. Debugging info will also be
shown in the browser on requests from 127.0.0.1.
You can also log your own messages directly into the log file from your code
using the Ruby logger class from inside your controllers. Example:
class WeblogController < ActionController::Base
def destroy
@weblog = Weblog.find(params[:id])
@weblog.destroy
logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
end
end
The result will be a message in your log file along the lines of:
Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
More information on how to use the logger is at http://www.ruby-doc.org/core/
Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
several books available online as well:
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
These two books will bring you up to speed on the Ruby language and also on
programming in general.
== Debugger
Debugger support is available through the debugger command when you start your
Mongrel or WEBrick server with --debugger. This means that you can break out of
execution at any point in the code, investigate and change the model, and then,
resume execution! You need to install ruby-debug to run the server in debugging
mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
class WeblogController < ActionController::Base
def index
@posts = Post.all
debugger
end
end
So the controller will accept the action, run the first line, then present you
with a IRB prompt in the server window. Here you can do things like:
>> @posts.inspect
=> "[#<Post:0x14a6be8
@attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
#<Post:0x14a6620
@attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
>> @posts.first.title = "hello from a debugger"
=> "hello from a debugger"
...and even better, you can examine how your runtime objects actually work:
>> f = @posts.first
=> #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
>> f.
Display all 152 possibilities? (y or n)
Finally, when you're ready to resume execution, you can enter "cont".
== Console
The console is a Ruby shell, which allows you to interact with your
application's domain model. Here you'll have all parts of the application
configured, just like it is when the application is running. You can inspect
domain models, change values, and save to the database. Starting the script
without arguments will launch it in the development environment.
To start the console, run <tt>rails console</tt> from the application
directory.
Options:
* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
made to the database.
* Passing an environment name as an argument will load the corresponding
environment. Example: <tt>rails console production</tt>.
To reload your controllers and models after launching the console run
<tt>reload!</tt>
More information about irb can be found at:
link:http://www.rubycentral.org/pickaxe/irb.html
== dbconsole
You can go to the command line of your database directly through <tt>rails
dbconsole</tt>. You would be connected to the database with the credentials
defined in database.yml. Starting the script without arguments will connect you
to the development database. Passing an argument will connect you to a different
database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
PostgreSQL and SQLite 3.
== Description of Contents
The default directory structure of a generated Ruby on Rails application:
|-- app
| |-- assets
| |-- images
| |-- javascripts
| `-- stylesheets
| |-- controllers
| |-- helpers
| |-- mailers
| |-- models
| `-- views
| `-- layouts
|-- config
| |-- environments
| |-- initializers
| `-- locales
|-- db
|-- doc
|-- lib
| `-- tasks
|-- log
|-- public
|-- script
|-- test
| |-- fixtures
| |-- functional
| |-- integration
| |-- performance
| `-- unit
|-- tmp
| |-- cache
| |-- pids
| |-- sessions
| `-- sockets
`-- vendor
|-- assets
`-- stylesheets
`-- plugins
app
Holds all the code that's specific to this particular application.
app/assets
Contains subdirectories for images, stylesheets, and JavaScript files.
app/controllers
Holds controllers that should be named like weblogs_controller.rb for
automated URL mapping. All controllers should descend from
ApplicationController which itself descends from ActionController::Base.
app/models
Holds models that should be named like post.rb. Models descend from
ActiveRecord::Base by default.
app/views
Holds the template files for the view that should be named like
weblogs/index.html.erb for the WeblogsController#index action. All views use
eRuby syntax by default.
app/views/layouts
Holds the template files for layouts to be used with views. This models the
common header/footer method of wrapping views. In your views, define a layout
using the <tt>layout :default</tt> and create a file named default.html.erb.
Inside default.html.erb, call <% yield %> to render the view using this
layout.
app/helpers
Holds view helpers that should be named like weblogs_helper.rb. These are
generated for you automatically when using generators for controllers.
Helpers can be used to wrap functionality for your views into methods.
config
Configuration files for the Rails environment, the routing map, the database,
and other dependencies.
db
Contains the database schema in schema.rb. db/migrate contains all the
sequence of Migrations for your schema.
doc
This directory is where your application documentation will be stored when
generated using <tt>rake doc:app</tt>
lib
Application specific libraries. Basically, any kind of custom code that
doesn't belong under controllers, models, or helpers. This directory is in
the load path.
public
The directory available for the web server. Also contains the dispatchers and the
default HTML files. This should be set as the DOCUMENT_ROOT of your web
server.
script
Helper scripts for automation and generation.
test
Unit and functional tests along with fixtures. When using the rails generate
command, template test files will be generated for you and placed in this
directory.
vendor
External libraries that the application depends on. Also includes the plugins
subdirectory. If the app has frozen rails, those gems also go here, under
vendor/rails/. This directory is in the load path.

View file

@ -1,16 +1,7 @@
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake, # Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require(File.join(File.dirname(__FILE__), 'config', 'boot')) require File.expand_path('../config/application', __FILE__)
require 'rake' Tracksapp::Application.load_tasks
require 'rake/testtask'
require 'rake/rdoctask'
require 'tasks/rails'
begin
require 'test/rails/rake_tasks'
rescue LoadError => e
#It's ok if you don't have ZenTest installed if you're not a developer
end

BIN
app/assets/images/rails.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -0,0 +1,15 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

View file

@ -0,0 +1,13 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require_tree .
*/

View file

@ -1,324 +1,3 @@
# The filters added to this controller will be run for all controllers in the
# application. Likewise will all the methods added be available for all
# controllers.
require_dependency "login_system"
require_dependency "tracks/source_view"
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery protect_from_forgery
helper :application
include LoginSystem
helper_method :current_user, :prefs, :format_date
layout proc{ |controller| controller.mobile? ? "mobile" : "standard" }
exempt_from_layout /\.js\.erb$/
before_filter :check_for_deprecated_password_hash
before_filter :set_session_expiration
before_filter :set_time_zone
before_filter :set_zindex_counter
before_filter :set_locale
prepend_before_filter :login_required
prepend_before_filter :enable_mobile_content_negotiation
after_filter :set_charset
# By default, sets the charset to UTF-8 if it isn't already set
def set_charset
headers["Content-Type"] ||= "text/html; charset=UTF-8"
end
def set_locale
locale = params[:locale] # specifying a locale in the request takes precedence
locale = locale || prefs.locale unless current_user.nil? # otherwise, the locale of the currently logged in user takes over
locale = locale || request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first if request.env['HTTP_ACCEPT_LANGUAGE']
I18n.locale = locale.nil? ? I18n.default_locale : (I18n::available_locales.include?(locale.to_sym) ? locale : I18n.default_locale)
logger.debug("Selected '#{I18n.locale}' as locale")
end
def set_session_expiration
# http://wiki.rubyonrails.com/rails/show/HowtoChangeSessionOptions
unless session == nil
return if self.controller_name == 'feed' or session['noexpiry'] == "on"
# If the method is called by the feed controller (which we don't have
# under session control) or if we checked the box to keep logged in on
# login don't set the session expiry time.
if session
# Get expiry time (allow ten seconds window for the case where we have
# none)
expiry_time = session['expiry_time'] || Time.now + 10
if expiry_time < Time.now
# Too late, matey... bang goes your session!
reset_session
else
# Okay, you get another hour
session['expiry_time'] = Time.now + (60*60)
end
end
end
end
# Redirects to change_password_user_path if the current user uses a
# deprecated password hashing algorithm.
def check_for_deprecated_password_hash
if current_user and current_user.uses_deprecated_password?
notify :warning, t('users.you_have_to_reset_your_password')
redirect_to change_password_user_path current_user
end
end
def render_failure message, status = 404
render :text => message, :status => status
end
# def rescue_action(exception)
# log_error(exception) if logger
# respond_to do |format|
# format.html do
# notify :warning, "An error occurred on the server."
# render :action => "index"
# end
# format.js { render :action => 'error' }
# format.xml { render :text => 'An error occurred on the server.' + $! }
# end
# end
# Returns a count of next actions in the given context or project The result
# is count and a string descriptor, correctly pluralised if there are no
# actions or multiple actions
#
def count_undone_todos_phrase(todos_parent)
count = count_undone_todos(todos_parent)
deferred_count = count_deferred_todos(todos_parent)
if count == 0 && deferred_count > 0
word = I18n.t('common.actions_midsentence', :count => deferred_count)
word = I18n.t('common.deferred') + "&nbsp;" + word
return deferred_count.to_s + "&nbsp;" + word
else
word = I18n.t('common.actions_midsentence', :count => count)
return count.to_s + "&nbsp;" + word
end
end
def count_undone_todos(todos_parent)
if todos_parent.nil?
count = 0
elsif (todos_parent.is_a?(Project) && todos_parent.hidden?)
count = eval "@project_project_hidden_todo_counts[#{todos_parent.id}]"
else
count = eval "@#{todos_parent.class.to_s.downcase}_not_done_counts[#{todos_parent.id}]"
end
count || 0
end
def count_deferred_todos(todos_parent)
if todos_parent.nil?
count = 0
else
count = todos_parent.todos.deferred.count
end
end
# Convert a date object to the format specified in the user's preferences in
# config/settings.yml
#
def format_date(date)
return date ? date.in_time_zone(prefs.time_zone).strftime("#{prefs.date_format}") : ''
end
def for_autocomplete(coll, substr)
if substr # protect agains empty request
filtered = coll.find_all{|item| item.name.downcase.include? substr.downcase}
json_elems = Array[*filtered.map{ |e| {:id => e.id.to_s, :value => e.name} }].to_json
return json_elems
else
return ""
end
end
def format_dependencies_as_json_for_auto_complete(entries)
json_elems = Array[*entries.map{ |e| {:value => e.id.to_s, :label => e.specification} }].to_json
return json_elems
end
# Here's the concept behind this "mobile content negotiation" hack: In
# addition to the main, AJAXy Web UI, Tracks has a lightweight low-feature
# 'mobile' version designed to be suitablef or use from a phone or PDA. It
# makes some sense that tne pages of that mobile version are simply alternate
# representations of the same Todo resources. The implementation goal was to
# treat mobile as another format and be able to use respond_to to render both
# versions. Unfortunately, I ran into a lot of trouble simply registering a
# new mime type 'text/html' with format :m because :html already is linked to
# that mime type and the new registration was forcing all html requests to be
# rendered in the mobile view. The before_filter and after_filter hackery
# below accomplishs that implementation goal by using a 'fake' mime type
# during the processing and then setting it to 'text/html' in an
# 'after_filter' -LKM 2007-04-01
def mobile?
return params[:format] == 'm'
end
def enable_mobile_content_negotiation
if mobile?
request.format = :m
end
end
def create_todo_from_recurring_todo(rt, date=nil)
# create todo and initialize with data from recurring_todo rt
todo = current_user.todos.build( { :description => rt.description, :notes => rt.notes, :project_id => rt.project_id, :context_id => rt.context_id})
todo.recurring_todo_id = rt.id
# set dates
todo.due = rt.get_due_date(date)
show_from_date = rt.get_show_from_date(date)
if show_from_date.nil?
todo.show_from=nil
else
# make sure that show_from is not in the past
todo.show_from = show_from_date < Time.zone.now ? nil : show_from_date
end
saved = todo.save
if saved
todo.tag_with(rt.tag_list)
todo.tags.reload
end
# increate number of occurences created from recurring todo
rt.inc_occurences
# mark recurring todo complete if there are no next actions left
checkdate = todo.due.nil? ? todo.show_from : todo.due
rt.toggle_completion! unless rt.has_next_todo(checkdate)
return saved ? todo : nil
end
def handle_unverified_request
unless request.format=="application/xml"
super # handle xml http auth via our own login code
end
end
protected
def admin_login_required
unless User.find_by_id_and_is_admin(session['user_id'], true)
render :text => t('errors.user_unauthorized'), :status => 401
return false
end
end
def redirect_back_or_home
respond_to do |format|
format.html { redirect_back_or_default home_url }
format.m { redirect_back_or_default mobile_url }
end
end
def boolean_param(param_name)
return false if param_name.blank?
s = params[param_name]
return false if s.blank? || s == false || s =~ /^false$/i
return true if s == true || s =~ /^true$/i
raise ArgumentError.new("invalid value for Boolean: \"#{s}\"")
end
def self.openid_enabled?
Tracks::Config.openid_enabled?
end
def openid_enabled?
self.class.openid_enabled?
end
def self.cas_enabled?
Tracks::Config.cas_enabled?
end
def cas_enabled?
self.class.cas_enabled?
end
def self.prefered_auth?
Tracks::Config.prefered_auth?
end
def prefered_auth?
self.class.prefered_auth?
end
# all completed todos [today@00:00, today@now]
def get_done_today(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES})
start_of_this_day = Time.zone.now.beginning_of_day
completed_todos.completed_after(start_of_this_day).all(includes)
end
# all completed todos [begin_of_week, start_of_today]
def get_done_this_week(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES})
start_of_this_week = Time.zone.now.beginning_of_week
start_of_this_day = Time.zone.now.beginning_of_day
completed_todos.completed_before(start_of_this_day).completed_after(start_of_this_week).all(includes)
end
# all completed todos [begin_of_month, begin_of_week]
def get_done_this_month(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES})
start_of_this_month = Time.zone.now.beginning_of_month
start_of_this_week = Time.zone.now.beginning_of_week
completed_todos.completed_before(start_of_this_week).completed_after(start_of_this_month).all(includes)
end
private
def parse_date_per_user_prefs( s )
prefs.parse_date(s)
end
def init_data_for_sidebar
@completed_projects = current_user.projects.completed
@hidden_projects = current_user.projects.hidden
@active_projects = current_user.projects.active
@active_contexts = current_user.contexts.active
@hidden_contexts = current_user.contexts.hidden
init_not_done_counts
if prefs.show_hidden_projects_in_sidebar
init_project_hidden_todo_counts(['project'])
end
end
def init_not_done_counts(parents = ['project','context'])
parents.each do |parent|
eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || current_user.todos.active.count(:group => :#{parent}_id)")
end
end
def init_project_hidden_todo_counts(parents = ['project','context'])
parents.each do |parent|
eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || current_user.todos.count(:conditions => ['state = ? or state = ?', 'project_hidden', 'active'], :group => :#{parent}_id)")
end
end
# Set the contents of the flash message from a controller Usage: notify
# :warning, "This is the message" Sets the flash of type 'warning' to "This is
# the message"
def notify(type, message)
flash[type] = message
logger.error("ERROR: #{message}") if type == :error
end
def set_time_zone
Time.zone = current_user.prefs.time_zone if logged_in?
end
def set_zindex_counter
# this counter can be used to handle the IE z-index bug
@z_index_counter = 500
end
end end

View file

@ -0,0 +1,324 @@
# The filters added to this controller will be run for all controllers in the
# application. Likewise will all the methods added be available for all
# controllers.
require_dependency "login_system"
require_dependency "tracks/source_view"
class ApplicationController < ActionController::Base
protect_from_forgery
helper :application
include LoginSystem
helper_method :current_user, :prefs, :format_date
layout proc{ |controller| controller.mobile? ? "mobile" : "standard" }
exempt_from_layout /\.js\.erb$/
before_filter :check_for_deprecated_password_hash
before_filter :set_session_expiration
before_filter :set_time_zone
before_filter :set_zindex_counter
before_filter :set_locale
prepend_before_filter :login_required
prepend_before_filter :enable_mobile_content_negotiation
after_filter :set_charset
# By default, sets the charset to UTF-8 if it isn't already set
def set_charset
headers["Content-Type"] ||= "text/html; charset=UTF-8"
end
def set_locale
locale = params[:locale] # specifying a locale in the request takes precedence
locale = locale || prefs.locale unless current_user.nil? # otherwise, the locale of the currently logged in user takes over
locale = locale || request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first if request.env['HTTP_ACCEPT_LANGUAGE']
I18n.locale = locale.nil? ? I18n.default_locale : (I18n::available_locales.include?(locale.to_sym) ? locale : I18n.default_locale)
logger.debug("Selected '#{I18n.locale}' as locale")
end
def set_session_expiration
# http://wiki.rubyonrails.com/rails/show/HowtoChangeSessionOptions
unless session == nil
return if self.controller_name == 'feed' or session['noexpiry'] == "on"
# If the method is called by the feed controller (which we don't have
# under session control) or if we checked the box to keep logged in on
# login don't set the session expiry time.
if session
# Get expiry time (allow ten seconds window for the case where we have
# none)
expiry_time = session['expiry_time'] || Time.now + 10
if expiry_time < Time.now
# Too late, matey... bang goes your session!
reset_session
else
# Okay, you get another hour
session['expiry_time'] = Time.now + (60*60)
end
end
end
end
# Redirects to change_password_user_path if the current user uses a
# deprecated password hashing algorithm.
def check_for_deprecated_password_hash
if current_user and current_user.uses_deprecated_password?
notify :warning, t('users.you_have_to_reset_your_password')
redirect_to change_password_user_path current_user
end
end
def render_failure message, status = 404
render :text => message, :status => status
end
# def rescue_action(exception)
# log_error(exception) if logger
# respond_to do |format|
# format.html do
# notify :warning, "An error occurred on the server."
# render :action => "index"
# end
# format.js { render :action => 'error' }
# format.xml { render :text => 'An error occurred on the server.' + $! }
# end
# end
# Returns a count of next actions in the given context or project The result
# is count and a string descriptor, correctly pluralised if there are no
# actions or multiple actions
#
def count_undone_todos_phrase(todos_parent)
count = count_undone_todos(todos_parent)
deferred_count = count_deferred_todos(todos_parent)
if count == 0 && deferred_count > 0
word = I18n.t('common.actions_midsentence', :count => deferred_count)
word = I18n.t('common.deferred') + "&nbsp;" + word
return deferred_count.to_s + "&nbsp;" + word
else
word = I18n.t('common.actions_midsentence', :count => count)
return count.to_s + "&nbsp;" + word
end
end
def count_undone_todos(todos_parent)
if todos_parent.nil?
count = 0
elsif (todos_parent.is_a?(Project) && todos_parent.hidden?)
count = eval "@project_project_hidden_todo_counts[#{todos_parent.id}]"
else
count = eval "@#{todos_parent.class.to_s.downcase}_not_done_counts[#{todos_parent.id}]"
end
count || 0
end
def count_deferred_todos(todos_parent)
if todos_parent.nil?
count = 0
else
count = todos_parent.todos.deferred.count
end
end
# Convert a date object to the format specified in the user's preferences in
# config/settings.yml
#
def format_date(date)
return date ? date.in_time_zone(prefs.time_zone).strftime("#{prefs.date_format}") : ''
end
def for_autocomplete(coll, substr)
if substr # protect agains empty request
filtered = coll.find_all{|item| item.name.downcase.include? substr.downcase}
json_elems = Array[*filtered.map{ |e| {:id => e.id.to_s, :value => e.name} }].to_json
return json_elems
else
return ""
end
end
def format_dependencies_as_json_for_auto_complete(entries)
json_elems = Array[*entries.map{ |e| {:value => e.id.to_s, :label => e.specification} }].to_json
return json_elems
end
# Here's the concept behind this "mobile content negotiation" hack: In
# addition to the main, AJAXy Web UI, Tracks has a lightweight low-feature
# 'mobile' version designed to be suitablef or use from a phone or PDA. It
# makes some sense that tne pages of that mobile version are simply alternate
# representations of the same Todo resources. The implementation goal was to
# treat mobile as another format and be able to use respond_to to render both
# versions. Unfortunately, I ran into a lot of trouble simply registering a
# new mime type 'text/html' with format :m because :html already is linked to
# that mime type and the new registration was forcing all html requests to be
# rendered in the mobile view. The before_filter and after_filter hackery
# below accomplishs that implementation goal by using a 'fake' mime type
# during the processing and then setting it to 'text/html' in an
# 'after_filter' -LKM 2007-04-01
def mobile?
return params[:format] == 'm'
end
def enable_mobile_content_negotiation
if mobile?
request.format = :m
end
end
def create_todo_from_recurring_todo(rt, date=nil)
# create todo and initialize with data from recurring_todo rt
todo = current_user.todos.build( { :description => rt.description, :notes => rt.notes, :project_id => rt.project_id, :context_id => rt.context_id})
todo.recurring_todo_id = rt.id
# set dates
todo.due = rt.get_due_date(date)
show_from_date = rt.get_show_from_date(date)
if show_from_date.nil?
todo.show_from=nil
else
# make sure that show_from is not in the past
todo.show_from = show_from_date < Time.zone.now ? nil : show_from_date
end
saved = todo.save
if saved
todo.tag_with(rt.tag_list)
todo.tags.reload
end
# increate number of occurences created from recurring todo
rt.inc_occurences
# mark recurring todo complete if there are no next actions left
checkdate = todo.due.nil? ? todo.show_from : todo.due
rt.toggle_completion! unless rt.has_next_todo(checkdate)
return saved ? todo : nil
end
def handle_unverified_request
unless request.format=="application/xml"
super # handle xml http auth via our own login code
end
end
protected
def admin_login_required
unless User.find_by_id_and_is_admin(session['user_id'], true)
render :text => t('errors.user_unauthorized'), :status => 401
return false
end
end
def redirect_back_or_home
respond_to do |format|
format.html { redirect_back_or_default home_url }
format.m { redirect_back_or_default mobile_url }
end
end
def boolean_param(param_name)
return false if param_name.blank?
s = params[param_name]
return false if s.blank? || s == false || s =~ /^false$/i
return true if s == true || s =~ /^true$/i
raise ArgumentError.new("invalid value for Boolean: \"#{s}\"")
end
def self.openid_enabled?
Tracks::Config.openid_enabled?
end
def openid_enabled?
self.class.openid_enabled?
end
def self.cas_enabled?
Tracks::Config.cas_enabled?
end
def cas_enabled?
self.class.cas_enabled?
end
def self.prefered_auth?
Tracks::Config.prefered_auth?
end
def prefered_auth?
self.class.prefered_auth?
end
# all completed todos [today@00:00, today@now]
def get_done_today(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES})
start_of_this_day = Time.zone.now.beginning_of_day
completed_todos.completed_after(start_of_this_day).all(includes)
end
# all completed todos [begin_of_week, start_of_today]
def get_done_this_week(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES})
start_of_this_week = Time.zone.now.beginning_of_week
start_of_this_day = Time.zone.now.beginning_of_day
completed_todos.completed_before(start_of_this_day).completed_after(start_of_this_week).all(includes)
end
# all completed todos [begin_of_month, begin_of_week]
def get_done_this_month(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES})
start_of_this_month = Time.zone.now.beginning_of_month
start_of_this_week = Time.zone.now.beginning_of_week
completed_todos.completed_before(start_of_this_week).completed_after(start_of_this_month).all(includes)
end
private
def parse_date_per_user_prefs( s )
prefs.parse_date(s)
end
def init_data_for_sidebar
@completed_projects = current_user.projects.completed
@hidden_projects = current_user.projects.hidden
@active_projects = current_user.projects.active
@active_contexts = current_user.contexts.active
@hidden_contexts = current_user.contexts.hidden
init_not_done_counts
if prefs.show_hidden_projects_in_sidebar
init_project_hidden_todo_counts(['project'])
end
end
def init_not_done_counts(parents = ['project','context'])
parents.each do |parent|
eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || current_user.todos.active.count(:group => :#{parent}_id)")
end
end
def init_project_hidden_todo_counts(parents = ['project','context'])
parents.each do |parent|
eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || current_user.todos.count(:conditions => ['state = ? or state = ?', 'project_hidden', 'active'], :group => :#{parent}_id)")
end
end
# Set the contents of the flash message from a controller Usage: notify
# :warning, "This is the message" Sets the flash of type 'warning' to "This is
# the message"
def notify(type, message)
flash[type] = message
logger.error("ERROR: #{message}") if type == :error
end
def set_time_zone
Time.zone = current_user.prefs.time_zone if logged_in?
end
def set_zindex_counter
# this counter can be used to handle the IE z-index bug
@z_index_counter = 500
end
end

View file

@ -1,5 +1,3 @@
# The methods added to this helper will be available to all templates in the
# application.
module ApplicationHelper module ApplicationHelper
# Replicates the link_to method but also checks request.request_uri to find # Replicates the link_to method but also checks request.request_uri to find

View file

@ -0,0 +1,301 @@
# The methods added to this helper will be available to all templates in the
# application.
module ApplicationHelper
# Replicates the link_to method but also checks request.request_uri to find
# current page. If that matches the url, the link is marked id = "current"
#
def navigation_link(name, options = {}, html_options = nil, *parameters_for_method_reference)
if html_options
html_options = html_options.stringify_keys
convert_options_to_javascript!(html_options)
tag_options = tag_options(html_options)
else
tag_options = nil
end
url = options.is_a?(String) ? options : self.url_for(options, *parameters_for_method_reference)
id_tag = (request.request_uri == url) ? " id=\"current\"" : ""
"<a href=\"#{url}\"#{tag_options}#{id_tag}>#{name || url}</a>"
end
def days_from_today(date)
date.in_time_zone.to_date - current_user.time.to_date
end
# Check due date in comparison to today's date Flag up date appropriately with
# a 'traffic light' colour code
#
def due_date(due)
return "" if due.nil?
days = days_from_today(due)
colors = ['amber','amber','orange','orange','orange','orange','orange','orange']
color = :red if days < 0
color = :green if days > 7
color = colors[days] if color.nil?
return content_tag(:a, {:title => format_date(due)}) {
content_tag(:span, {:class => color}) {
case days
when 0
t('todos.next_actions_due_date.due_today')
when 1
t('todos.next_actions_due_date.due_tomorrow')
when 2..7
if prefs.due_style == Preference.due_styles[:due_on]
# TODO: internationalize strftime here
t('models.preference.due_on', :date => due.strftime("%A"))
else
t('models.preference.due_in', :days => days)
end
else
# overdue or due very soon! sound the alarm!
if days == -1
t('todos.next_actions_due_date.overdue_by', :days => days * -1)
elsif days < -1
t('todos.next_actions_due_date.overdue_by_plural', :days => days * -1)
else
# more than a week away - relax
t('models.preference.due_in', :days => days)
end
end
}
}
end
# Check due date in comparison to today's date Flag up date appropriately with
# a 'traffic light' colour code Modified method for mobile screen
#
def due_date_mobile(due)
if due == nil
return ""
end
days = days_from_today(due)
case days
when 0
"<span class=\"amber\">"+ format_date(due) + "</span>"
when 1
"<span class=\"amber\">" + format_date(due) + "</span>"
# due 2-7 days away
when 2..7
"<span class=\"orange\">" + format_date(due) + "</span>"
else
# overdue or due very soon! sound the alarm!
if days < 0
"<span class=\"red\">" + format_date(due) +"</span>"
else
# more than a week away - relax
"<span class=\"green\">" + format_date(due) + "</span>"
end
end
end
# Returns a count of next actions in the given context or project. The result
# is count and a string descriptor, correctly pluralised if there are no
# actions or multiple actions
#
def count_undone_todos_phrase(todos_parent, string="actions")
@controller.count_undone_todos_phrase(todos_parent, string)
end
def count_undone_todos_phrase_text(todos_parent, string="actions")
count_undone_todos_phrase(todos_parent, string).gsub("&nbsp;"," ")
end
def count_undone_todos_and_notes_phrase(project, string="actions")
s = count_undone_todos_phrase(project, string)
s += ", #{pluralize(project.note_count, 'note')}" unless project.note_count == 0
s
end
def link_to_context(context, descriptor = sanitize(context.name))
link_to( descriptor, context, :title => "View context: #{context.name}" )
end
def link_to_project(project, descriptor = sanitize(project.name))
link_to( descriptor, project, :title => "View project: #{project.name}" )
end
def link_to_edit_note (note, descriptor = sanitize(note.id.to_s))
link_to(descriptor,
url_for({:controller => 'notes', :action => 'edit', :id => note.id}),
{:id => "link_edit_#{dom_id(note)}", :class => "note_edit_settings"})
end
def link_to_project_mobile(project, accesskey, descriptor = sanitize(project.name))
link_to( descriptor, project_path(project, :format => 'm'), {:title => "View project: #{project.name}", :accesskey => accesskey} )
end
def item_link_to_context(item)
descriptor = "[C]"
descriptor = "[#{item.context.name}]" if prefs.verbose_action_descriptors
link_to_context( item.context, descriptor )
end
def item_link_to_project(item)
descriptor = "[P]"
descriptor = "[#{item.project.name}]" if prefs.verbose_action_descriptors
link_to_project( item.project, descriptor )
end
def render_flash
render :partial => 'shared/flash', :object => flash
end
def recurrence_time_span(rt)
case rt.ends_on
when "no_end_date"
return rt.start_from.nil? ? "" : I18n.t("todos.recurrence.pattern.from") + " " + format_date(rt.start_from)
when "ends_on_number_of_times"
return I18n.t("todos.recurrence.pattern.times", :number => rt.number_of_occurences)
when "ends_on_end_date"
starts = rt.start_from.nil? ? "" : I18n.t("todos.recurrence.pattern.from") + " " + format_date(rt.start_from)
ends = rt.end_date.nil? ? "" : " " + I18n.t("todos.recurrence.pattern.until") + " " + format_date(rt.end_date)
return starts+ends
else
raise Exception.new, "unknown recurrence time span selection (#{rt.ends_on})"
end
end
def recurrence_pattern_as_text(recurring_todo)
rt = recurring_todo.recurring_target_as_text
rp = recurring_todo.recurrence_pattern
# only add space if recurrence_pattern has content
rp = " " + rp if !rp.nil?
rts = recurrence_time_span(recurring_todo)
# only add space if recurrence_time_span has content
rts = " " + rts if !(rts == "")
return rt+rp+rts
end
def date_format_for_date_picker()
standard_format = current_user.prefs.date_format
translations = [
['%m', 'mm'],
['%b', 'M'],
['%B', 'MM'],
['%d', 'dd'],
['%a', 'D'],
['%A', 'DD'],
['%y', 'y'],
['%Y', 'yy']
]
translations.inject(standard_format) do |str, translation|
str.gsub(*translation)
end
end
AUTO_LINK_MESSAGE_RE = %r{message://<[^>]+>} unless const_defined?(:AUTO_LINK_MESSAGE_RE)
# Converts message:// links to href. This URL scheme is used on Mac OS X
# to link to a mail message in Mail.app.
def auto_link_message(text)
text.gsub(AUTO_LINK_MESSAGE_RE) do
href = $&
left, right = $`, $'
# detect already linked URLs and URLs in the middle of a tag
if left =~ /<[^>]+$/ && right =~ /^[^>]*>/
# do not change string; URL is alreay linked
href
else
content = content_tag(:a, h(href), :href => h(href))
end
end
end
def format_note(note)
note = auto_link_message(note)
note = markdown(note)
note = auto_link(note, :link => :urls)
# add onenote and message protocols
Sanitize::Config::RELAXED[:protocols]['a']['href'] << 'onenote'
Sanitize::Config::RELAXED[:protocols]['a']['href'] << 'message'
note = Sanitize.clean(note, Sanitize::Config::RELAXED)
return note
end
def sidebar_html_for_titled_list (list, title)
return content_tag(:h3, title+" (#{list.length})") +
content_tag(:ul, sidebar_html_for_list(list))
end
def sidebar_html_for_list(list)
if list.empty?
return content_tag(:li, t('sidebar.list_empty'))
else
return list.inject("") do |html, item|
link = (item.class == "Project") ? link_to_project( item ) : link_to_context(item)
html << content_tag(:li, link + " (" + count_undone_todos_phrase(item,"actions")+")")
end
end
end
def generate_i18n_strings
js = "i18n_locale='#{I18n.locale}';\n"
js << "i18n = new Array();\n"
%w{
shared.toggle_multi shared.toggle_multi_title
shared.hide_form shared.hide_action_form_title
shared.toggle_single shared.toggle_single_title
projects.hide_form projects.hide_form_title
projects.show_form projects.show_form_title
contexts.hide_form contexts.hide_form_title
contexts.show_form contexts.show_form_title
contexts.new_context_pre contexts.new_context_post
common.cancel common.ok
common.ajaxError todos.unresolved_dependency
}.each do |s|
js << "i18n['#{s}'] = '#{ t(s).gsub(/'/, "\\\\'") }';\n"
end
return js
end
def javascript_tag_for_i18n_datepicker
locale = I18n.locale
# do not include en as locale since this the available by default
if locale and locale != :en
javascript_include_tag("i18n/jquery.ui.datepicker-#{locale}.js")
end
end
def determine_done_path
case @controller.controller_name
when "contexts"
done_todos_context_path(@context)
when "projects"
done_todos_project_path(@project)
when "todos"
if source_view_is(:tag)
done_tag_path(@tag_name)
else
done_todos_path
end
else
done_todos_path
end
end
def determine_all_done_path
case @controller.controller_name
when "contexts"
all_done_todos_context_path(@context)
when "projects"
all_done_todos_project_path(@project)
when "todos"
if source_view_is(:tag)
all_done_tag_path(@tag_name)
else
all_done_todos_path
end
else
all_done_todos_path
end
end
end

0
app/mailers/.gitkeep Normal file
View file

0
app/models/.gitkeep Normal file
View file

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Tracksapp</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>

4
config.ru Normal file
View file

@ -0,0 +1,4 @@
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run Tracksapp::Application

59
config/application.rb Normal file
View file

@ -0,0 +1,59 @@
require File.expand_path('../boot', __FILE__)
require 'rails/all'
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module Tracksapp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Use SQL instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Enforce whitelist mode for mass assignment.
# This will create an empty whitelist of attributes available for mass-assignment for all models
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
# parameters by using an attr_accessible or attr_protected declaration.
config.active_record.whitelist_attributes = true
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
end
end

View file

@ -1,128 +1,6 @@
# Don't change this file! require 'rubygems'
# Configure your app in config/environment.rb and config/environments/*.rb
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) # Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
module Rails require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
class << self
def boot!
unless booted?
preinitialize
pick_boot.run
end
end
def booted?
defined? Rails::Initializer
end
def pick_boot
(vendor_rails? ? VendorBoot : GemBoot).new
end
def vendor_rails?
File.exist?("#{RAILS_ROOT}/vendor/rails")
end
def preinitialize
load(preinitializer_path) if File.exist?(preinitializer_path)
end
def preinitializer_path
"#{RAILS_ROOT}/config/preinitializer.rb"
end
end
class Boot
def run
load_initializer
Rails::Initializer.run(:set_load_path)
end
end
class VendorBoot < Boot
def load_initializer
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
Rails::Initializer.run(:install_gem_spec_stubs)
Rails::GemDependency.add_frozen_gem_path
end
end
class GemBoot < Boot
def load_initializer
self.class.load_rubygems
load_rails_gem
require 'initializer'
end
def load_rails_gem
if version = self.class.gem_version
gem 'rails', version
else
gem 'rails'
end
rescue Gem::LoadError => load_error
if load_error.message =~ /Could not find RubyGem rails/
STDERR.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
exit 1
else
raise
end
end
class << self
def rubygems_version
Gem::RubyGemsVersion rescue nil
end
def gem_version
if defined? RAILS_GEM_VERSION
RAILS_GEM_VERSION
elsif ENV.include?('RAILS_GEM_VERSION')
ENV['RAILS_GEM_VERSION']
else
parse_gem_version(read_environment_rb)
end
end
def load_rubygems
min_version = '1.3.2'
require 'rubygems'
unless rubygems_version >= min_version
$stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
exit 1
end
rescue LoadError
$stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
exit 1
end
def parse_gem_version(text)
$1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
end
private
def read_environment_rb
File.read("#{RAILS_ROOT}/config/environment.rb")
end
end
end
end
class Rails::Boot
def run
load_initializer
Rails::Initializer.class_eval do
def load_gems
@bundler_loaded ||= Bundler.require :default, Rails.env
end
end
Rails::Initializer.run(:set_load_path)
end
end
# All that for this:
Rails.boot!

View file

@ -0,0 +1,37 @@
# MySQL. Versions 4.1 and 5.0 are recommended.
#
#
# Be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
adapter: mysql
database: tracks_trunk
encoding: utf8
host: localhost
username: tracks
password: 32tracks55
mdevelopment:
adapter: sqlite3
database: db/tracks-21-test.sqlite3.db
test: &TEST
# adapter: sqlite3
# database: ":memory:"
# verbosity: quiet
adapter: mysql
database: tracks_test
host: localhost
username: tracks
password: 32tracks55
production:
adapter: mysql
database: tracks_trunk
encoding: utf8
host: localhost
username: tracks
password: 32tracks55
cucumber:
<<: *TEST

View file

@ -1,118 +1,5 @@
# Be sure to restart your webserver when you modify this file. # Load the rails application
# Uncomment below to force Rails into production mode require File.expand_path('../application', __FILE__)
# (Use only when you can't set environment variables through your web/app server) # Initialize the rails application
# ENV['RAILS_ENV'] = 'production' Tracksapp::Application.initialize!
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
require 'yaml'
SITE_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__), 'site.yml'))
class Rails::Configuration
attr_accessor :action_web_service
end
Encoding.default_external = Encoding::UTF_8 if RUBY_VERSION > "1.9"
Rails::Initializer.run do |config|
# Skip frameworks you're not going to use
# config.frameworks -= [ :action_web_service, :action_mailer ]
config.autoload_paths += %W( #{RAILS_ROOT}/app/apis )
config.action_controller.use_accept_header = true
# Use the database for sessions instead of the file system
# (create the session table with 'rake create_sessions_table')
config.action_controller.session_store = :active_record_store
config.action_controller.session = {
:key => '_tracks_session_id',
:secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil #must be at least 30 characters
}
config.action_controller.relative_url_root = SITE_CONFIG['subdir'] if SITE_CONFIG['subdir']
# Enable page/fragment caching by setting a file-based store
# (remember to create the caching directory and make it readable to the application)
# config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector
# Make Active Record use UTC-base instead of local time
config.active_record.default_timezone = :utc
# You''ll probably want to change this to the time zone of the computer where Tracks is running
# run rake time:zones:local have Rails suggest time zone names on your system
config.time_zone = SITE_CONFIG['time_zone']
# Use Active Record's schema dumper instead of SQL when creating the test database
# (enables use of different database adapters for development and test environments)
config.active_record.schema_format = :ruby
# allow other protocols in urls for sanitzer. Add to your liking, for example
# config.action_view.sanitized_allowed_protocols = 'onenote', 'blah', 'proto'
# to enable "link":onenote://... or "link":blah://... hyperlinks
config.action_view.sanitized_allowed_protocols = 'onenote', 'message'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
end
# Add new inflection rules using the following format
# (all these examples are active by default):
# Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
# Include your application configuration below
require 'name_part_finder'
require 'tracks/todo_list'
require 'tracks/config'
require 'digest/sha1' #Needed to support 'rake db:fixtures:load' on some ruby installs: http://dev.rousette.org.uk/ticket/557
if ( SITE_CONFIG['authentication_schemes'].include? 'ldap')
require 'net/ldap' #requires ruby-net-ldap gem be installed
require 'simple_ldap_authenticator'
ldap = SITE_CONFIG['ldap']
SimpleLdapAuthenticator.ldap_library = ldap['library']
SimpleLdapAuthenticator.servers = ldap['servers']
SimpleLdapAuthenticator.use_ssl = ldap['ssl']
SimpleLdapAuthenticator.login_format = ldap['login_format']
end
if ( SITE_CONFIG['authentication_schemes'].include? 'open_id')
#requires ruby-openid gem to be installed
OpenID::Util.logger = RAILS_DEFAULT_LOGGER
end
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
#requires rubycas-client gem to be installed
if defined? CASClient
require 'casclient/frameworks/rails/filter'
CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => SITE_CONFIG['cas_server'] ,
:cas_server_logout => SITE_CONFIG['cas_server_logout']
)
end
end
# changed in development.rb to show under_construction bar
NOTIFY_BAR = "" unless defined?(NOTIFY_BAR)
tracks_version='2.2devel'
# comment out next two lines if you do not want (or can not) the date of the
# last git commit in the footer
info=`git log --pretty=format:"%ai" -1`
tracks_version=tracks_version + ' ('+info+')'
TRACKS_VERSION=tracks_version

View file

@ -0,0 +1,119 @@
# Be sure to restart your webserver when you modify this file.
# Uncomment below to force Rails into production mode
# (Use only when you can't set environment variables through your web/app server)
# ENV['RAILS_ENV'] = 'production'
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
require 'yaml'
SITE_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__), 'site.yml'))
class Rails::Configuration
attr_accessor :action_web_service
end
Encoding.default_external = Encoding::UTF_8 if RUBY_VERSION > "1.9"
Rails::Initializer.run do |config|
# Skip frameworks you're not going to use
# config.frameworks -= [ :action_web_service, :action_mailer ]
config.autoload_paths += %W( #{RAILS_ROOT}/app/apis )
config.action_controller.use_accept_header = true
# Use the database for sessions instead of the file system
# (create the session table with 'rake create_sessions_table')
config.action_controller.session_store = :active_record_store
config.action_controller.session = {
:key => '_tracks_session_id',
:secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil #must be at least 30 characters
}
config.action_controller.relative_url_root = SITE_CONFIG['subdir'] if SITE_CONFIG['subdir']
# Enable page/fragment caching by setting a file-based store
# (remember to create the caching directory and make it readable to the application)
# config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector
# Make Active Record use UTC-base instead of local time
config.active_record.default_timezone = :utc
# You''ll probably want to change this to the time zone of the computer where Tracks is running
# run rake time:zones:local have Rails suggest time zone names on your system
config.time_zone = SITE_CONFIG['time_zone']
# Use Active Record's schema dumper instead of SQL when creating the test database
# (enables use of different database adapters for development and test environments)
config.active_record.schema_format = :ruby
# allow other protocols in urls for sanitzer. Add to your liking, for example
# config.action_view.sanitized_allowed_protocols = 'onenote', 'blah', 'proto'
# to enable "link":onenote://... or "link":blah://... hyperlinks
config.action_view.sanitized_allowed_protocols = 'onenote', 'message'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
end
# Add new inflection rules using the following format
# (all these examples are active by default):
# Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
# Include your application configuration below
require 'name_part_finder'
require 'tracks/todo_list'
require 'tracks/config'
require 'tagging_extensions' # Needed for tagging-specific extensions
require 'digest/sha1' #Needed to support 'rake db:fixtures:load' on some ruby installs: http://dev.rousette.org.uk/ticket/557
if ( SITE_CONFIG['authentication_schemes'].include? 'ldap')
require 'net/ldap' #requires ruby-net-ldap gem be installed
require 'simple_ldap_authenticator'
ldap = SITE_CONFIG['ldap']
SimpleLdapAuthenticator.ldap_library = ldap['library']
SimpleLdapAuthenticator.servers = ldap['servers']
SimpleLdapAuthenticator.use_ssl = ldap['ssl']
SimpleLdapAuthenticator.login_format = ldap['login_format']
end
if ( SITE_CONFIG['authentication_schemes'].include? 'open_id')
#requires ruby-openid gem to be installed
OpenID::Util.logger = RAILS_DEFAULT_LOGGER
end
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
#requires rubycas-client gem to be installed
if defined? CASClient
require 'casclient/frameworks/rails/filter'
CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => SITE_CONFIG['cas_server'] ,
:cas_server_logout => SITE_CONFIG['cas_server_logout']
)
end
end
# changed in development.rb to show under_construction bar
NOTIFY_BAR = "" unless defined?(NOTIFY_BAR)
tracks_version='2.2devel'
# comment out next two lines if you do not want (or can not) the date of the
# last git commit in the footer
info=`git log --pretty=format:"%ai" -1`
tracks_version=tracks_version + ' ('+info+')'
TRACKS_VERSION=tracks_version

View file

@ -1,19 +1,37 @@
# In the development environment your application's code is reloaded on Tracksapp::Application.configure do
# every request. This slows down response time but is perfect for development # Settings specified here will take precedence over those in config/application.rb
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil. # In the development environment your application's code is reloaded on
config.whiny_nils = true # every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Show full error reports and disable caching # Log error messages when you accidentally call methods on nil.
config.action_controller.consider_all_requests_local = true config.whiny_nils = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send # Show full error reports and disable caching
config.action_mailer.raise_delivery_errors = false config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Unique cookies # Don't care if the mailer can't send
config.action_controller.session = { :key => 'TracksDev' } config.action_mailer.raise_delivery_errors = false
NOTIFY_BAR="<div id=\"develop-notify-bar\">&nbsp;</div>" # Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
end

View file

@ -0,0 +1,19 @@
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Unique cookies
config.action_controller.session = { :key => 'TracksDev' }
NOTIFY_BAR="<div id=\"develop-notify-bar\">&nbsp;</div>"

View file

@ -1,17 +1,67 @@
# The production environment is meant for finished, "live" apps. Tracksapp::Application.configure do
# Code is not reloaded between requests # Settings specified here will take precedence over those in config/application.rb
config.cache_classes = true
# Use a different logger for distributed setups # Code is not reloaded between requests
# config.logger = SyslogLogger.new config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Full error reports are disabled and caching is turned on # Disable Rails's static asset server (Apache or nginx will already do this)
config.action_controller.consider_all_requests_local = false config.serve_static_assets = false
config.action_controller.perform_caching = true
# Enable serving of images, stylesheets, and javascripts from an asset server # Compress JavaScripts and CSS
# config.action_controller.asset_host = "http://assets.example.com" config.assets.compress = true
# Disable delivery errors if you bad email addresses should just be ignored # Don't fallback to assets pipeline if a precompiled asset is missed
# config.action_mailer.raise_delivery_errors = false config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to Rails.root.join("public/assets")
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Prepend all log lines with the following tags
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
# config.active_record.auto_explain_threshold_in_seconds = 0.5
end

View file

@ -0,0 +1,17 @@
# The production environment is meant for finished, "live" apps.
# Code is not reloaded between requests
config.cache_classes = true
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
# Full error reports are disabled and caching is turned on
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Enable serving of images, stylesheets, and javascripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Disable delivery errors if you bad email addresses should just be ignored
# config.action_mailer.raise_delivery_errors = false

View file

@ -1,33 +1,37 @@
# The test environment is used exclusively to run your application's Tracksapp::Application.configure do
# test suite. You never need to work with it otherwise. Remember that # Settings specified here will take precedence over those in config/application.rb
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Log error messages when you accidentally call methods on nil. # The test environment is used exclusively to run your application's
config.whiny_nils = true # test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Show full error reports and disable caching # Configure static asset server for tests with Cache-Control for performance
config.action_controller.consider_all_requests_local = true config.serve_static_assets = true
config.action_controller.perform_caching = false config.static_cache_control = "public, max-age=3600"
# Tell ActionMailer not to deliver emails to the real world. # Log error messages when you accidentally call methods on nil
# The :test delivery method accumulates sent emails in the config.whiny_nils = true
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Disable request forgery protection in test environment # Show full error reports and disable caching
config.action_controller.allow_forgery_protection = false config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Unique cookies and use cookies for session # Raise exceptions instead of rendering exception templates
config.action_controller.session_store = :cookie_store config.action_dispatch.show_exceptions = false
config.action_controller.session = { :key => 'TracksTest', :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil }
# Overwrite the default settings for fixtures in tests. See Fixtures # Disable request forgery protection in test environment
# for more details about these settings. config.action_controller.allow_forgery_protection = false
# config.transactional_fixtures = true
# config.instantiated_fixtures = false
# config.pre_loaded_fixtures = false
SITE_CONFIG['salt'] ||= 'change-me'
config.time_zone = 'UTC' # Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
end

View file

@ -3,5 +3,5 @@
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers! # Rails.backtrace_cleaner.remove_silencers!

View file

@ -8,3 +8,8 @@
# inflect.irregular 'person', 'people' # inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep ) # inflect.uncountable %w( fish sheep )
# end # end
#
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.acronym 'RESTful'
# end

View file

@ -1,5 +1,8 @@
# Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks: # Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf # Mime::Type.register "text/richtext", :rtf
# Mime::Type.register "application/x-mobile", :mobile # Mime::Type.register_alias "text/html", :iphone
Mime::Type.register_alias "text/html", :m Mime::Type.register_alias "text/html", :m
Mime::Type.register_alias "text/plain", :autocomplete Mime::Type.register_alias "text/plain", :autocomplete

View file

@ -0,0 +1,7 @@
# Be sure to restart your server when you modify this file.
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Tracksapp::Application.config.secret_token = '978c88b98f3b7885b2e88a831545bd3c5d80d0f528b32096dafa7dc9010b2180e2391c059c5347a244709a2257e3d13f0841fbdc56e8052af3c3396916b5805b'

View file

@ -0,0 +1,8 @@
# Be sure to restart your server when you modify this file.
Tracksapp::Application.config.session_store :cookie_store, key: '_tracksapp_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Tracksapp::Application.config.session_store :active_record_store

View file

@ -0,0 +1,14 @@
# Be sure to restart your server when you modify this file.
#
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
# Disable root element in JSON by default.
ActiveSupport.on_load(:active_record) do
self.include_root_in_json = false
end

View file

@ -1,113 +1,58 @@
ActionController::Routing::Routes.draw do |map| Tracksapp::Application.routes.draw do
map.resources :users, # The priority is based upon order of creation:
:member => {:change_password => :get, :update_password => :post, # first created -> highest priority.
:change_auth_type => :get, :update_auth_type => :post, :complete => :get,
:refresh_token => :post }
map.with_options :controller => :users do |users| # Sample of regular route:
users.signup 'signup', :action => "new" # match 'products/:id' => 'catalog#view'
end # Keep in mind you can assign values other than :controller and :action
map.resources :contexts, :collection => {:order => :post, :done => :get}, :member => {:done_todos => :get, :all_done_todos => :get} do |contexts| # Sample of named route:
contexts.resources :todos, :name_prefix => "context_" # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
end # This route can be invoked with purchase_url(:id => product.id)
map.resources :projects, # Sample resource route (maps HTTP verbs to controller actions automatically):
:collection => {:order => :post, :alphabetize => :post, :actionize => :post, :done => :get}, # resources :products
:member => {:done_todos => :get, :all_done_todos => :get, :set_reviewed => :get} do |projects|
projects.resources :todos, :name_prefix => "project_"
end
map.with_options :controller => :projects do |projects| # Sample resource route with options:
projects.review 'review', :action => :review # resources :products do
end # member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
map.resources :notes # Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
map.resources :todos, # Sample resource route with more complex sub-resources
:member => {:toggle_check => :put, :toggle_star => :put, :defer => :put}, # resources :products do
:collection => {:check_deferred => :post, :filter_to_context => :post, :filter_to_project => :post, :done => :get, :all_done => :get # resources :comments
} # resources :sales do
# get 'recent', :on => :collection
# end
# end
map.with_options :controller => :todos do |todos| # Sample resource route within a namespace:
todos.home '', :action => "index" # namespace :admin do
todos.tickler 'tickler.:format', :action => "list_deferred" # # Directs /admin/products/* to Admin::ProductsController
todos.mobile_tickler 'tickler.m', :action => "list_deferred", :format => 'm' # # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# This route works for tags with dots like /todos/tag/version1.5 # You can have the root of your site routed with "root"
# please note that this pattern consumes everything after /todos/tag # just remember to delete public/index.html.
# so /todos/tag/version1.5.xml will result in :name => 'version1.5.xml' # root :to => 'welcome#index'
# UPDATE: added support for mobile view. All tags ending on .m will be
# routed to mobile view of tags.
todos.mobile_tag 'todos/tag/:name.m', :action => "tag", :format => 'm'
todos.text_tag 'todos/tag/:name.txt', :action => "tag", :format => 'txt'
todos.tag 'todos/tag/:name', :action => "tag", :name => /.*/
todos.done_tag 'todos/done/tag/:name', :action => "done_tag"
todos.all_done_tag 'todos/all_done/tag/:name', :action => "all_done_tag"
todos.tags 'tags.autocomplete', :action => "tags", :format => 'autocomplete' # See how all your routes lay out with "rake routes"
todos.auto_complete_for_predecessor 'auto_complete_for_predecessor', :action => 'auto_complete_for_predecessor'
todos.calendar 'calendar.ics', :action => "calendar", :format => 'ics'
todos.calendar 'calendar.xml', :action => "calendar", :format => 'xml'
todos.calendar 'calendar', :action => "calendar"
todos.hidden 'hidden.xml', :action => "list_hidden", :format => 'xml'
todos.mobile 'mobile', :action => "index", :format => 'm'
todos.mobile_abbrev 'm', :action => "index", :format => 'm'
todos.mobile_abbrev_new 'm/new', :action => "new", :format => 'm'
todos.mobile_todo_show_notes 'todos/notes/:id.m', :action => "show_notes", :format => 'm'
todos.todo_show_notes 'todos/notes/:id', :action => "show_notes"
todos.done_todos 'todos/done', :action => :done
todos.all_done_todos 'todos/all_done', :action => :all_done
end
map.root :controller => 'todos' # Make OpenID happy because it needs #root_url defined
map.resources :recurring_todos, :collection => {:done => :get},
:member => {:toggle_check => :put, :toggle_star => :put}
map.with_options :controller => :recurring_todos do |rt|
rt.recurring_todos 'recurring_todos', :action => 'index'
end
map.with_options :controller => :login do |login|
login.login 'login', :action => 'login'
login.login_cas 'login_cas', :action => 'login_cas'
login.formatted_login 'login.:format', :action => 'login'
login.logout 'logout', :action => 'logout'
login.formatted_logout 'logout.:format', :action => 'logout'
end
map.with_options :controller => :feedlist do |fl|
fl.mobile_feeds 'feeds.m', :action => 'index', :format => 'm'
fl.feeds 'feeds', :action => 'index'
end
map.with_options :controller => :integrations do |i|
i.integrations 'integrations', :action => 'index'
i.rest_api_docs 'integrations/rest_api', :action => "rest_api"
i.search_plugin 'integrations/search_plugin.xml', :action => 'search_plugin', :format => 'xml'
i.google_gadget 'integrations/google_gadget.xml', :action => 'google_gadget', :format => 'xml'
i.cloudmailin 'integrations/cloudmailin', :action => 'cloudmailin'
end
map.with_options :controller => :preferences do |p|
p.preferences 'preferences', :action => 'index'
p.preferences_date_format 'preferences/render_date_format', :action => 'render_date_format'
end
map.with_options :controller => :stats do |stats|
stats.stats 'stats', :action => 'index'
stats.done_overview 'done', :action => 'done'
end
map.search 'search', :controller => 'search', :action => 'index'
map.data 'data', :controller => 'data', :action => 'index'
Translate::Routes.translation_ui(map) if Rails.env != "production"
# Install the default route as the lowest priority.
map.connect ':controller/:action/:id'
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
end end

113
config/routes.rb.rails2 Normal file
View file

@ -0,0 +1,113 @@
ActionController::Routing::Routes.draw do |map|
map.resources :users,
:member => {:change_password => :get, :update_password => :post,
:change_auth_type => :get, :update_auth_type => :post, :complete => :get,
:refresh_token => :post }
map.with_options :controller => :users do |users|
users.signup 'signup', :action => "new"
end
map.resources :contexts, :collection => {:order => :post, :done => :get}, :member => {:done_todos => :get, :all_done_todos => :get} do |contexts|
contexts.resources :todos, :name_prefix => "context_"
end
map.resources :projects,
:collection => {:order => :post, :alphabetize => :post, :actionize => :post, :done => :get},
:member => {:done_todos => :get, :all_done_todos => :get, :set_reviewed => :get} do |projects|
projects.resources :todos, :name_prefix => "project_"
end
map.with_options :controller => :projects do |projects|
projects.review 'review', :action => :review
end
map.resources :notes
map.resources :todos,
:member => {:toggle_check => :put, :toggle_star => :put, :defer => :put},
:collection => {:check_deferred => :post, :filter_to_context => :post, :filter_to_project => :post, :done => :get, :all_done => :get
}
map.with_options :controller => :todos do |todos|
todos.home '', :action => "index"
todos.tickler 'tickler.:format', :action => "list_deferred"
todos.mobile_tickler 'tickler.m', :action => "list_deferred", :format => 'm'
# This route works for tags with dots like /todos/tag/version1.5
# please note that this pattern consumes everything after /todos/tag
# so /todos/tag/version1.5.xml will result in :name => 'version1.5.xml'
# UPDATE: added support for mobile view. All tags ending on .m will be
# routed to mobile view of tags.
todos.mobile_tag 'todos/tag/:name.m', :action => "tag", :format => 'm'
todos.text_tag 'todos/tag/:name.txt', :action => "tag", :format => 'txt'
todos.tag 'todos/tag/:name', :action => "tag", :name => /.*/
todos.done_tag 'todos/done/tag/:name', :action => "done_tag"
todos.all_done_tag 'todos/all_done/tag/:name', :action => "all_done_tag"
todos.tags 'tags.autocomplete', :action => "tags", :format => 'autocomplete'
todos.auto_complete_for_predecessor 'auto_complete_for_predecessor', :action => 'auto_complete_for_predecessor'
todos.calendar 'calendar.ics', :action => "calendar", :format => 'ics'
todos.calendar 'calendar.xml', :action => "calendar", :format => 'xml'
todos.calendar 'calendar', :action => "calendar"
todos.hidden 'hidden.xml', :action => "list_hidden", :format => 'xml'
todos.mobile 'mobile', :action => "index", :format => 'm'
todos.mobile_abbrev 'm', :action => "index", :format => 'm'
todos.mobile_abbrev_new 'm/new', :action => "new", :format => 'm'
todos.mobile_todo_show_notes 'todos/notes/:id.m', :action => "show_notes", :format => 'm'
todos.todo_show_notes 'todos/notes/:id', :action => "show_notes"
todos.done_todos 'todos/done', :action => :done
todos.all_done_todos 'todos/all_done', :action => :all_done
end
map.root :controller => 'todos' # Make OpenID happy because it needs #root_url defined
map.resources :recurring_todos, :collection => {:done => :get},
:member => {:toggle_check => :put, :toggle_star => :put}
map.with_options :controller => :recurring_todos do |rt|
rt.recurring_todos 'recurring_todos', :action => 'index'
end
map.with_options :controller => :login do |login|
login.login 'login', :action => 'login'
login.login_cas 'login_cas', :action => 'login_cas'
login.formatted_login 'login.:format', :action => 'login'
login.logout 'logout', :action => 'logout'
login.formatted_logout 'logout.:format', :action => 'logout'
end
map.with_options :controller => :feedlist do |fl|
fl.mobile_feeds 'feeds.m', :action => 'index', :format => 'm'
fl.feeds 'feeds', :action => 'index'
end
map.with_options :controller => :integrations do |i|
i.integrations 'integrations', :action => 'index'
i.rest_api_docs 'integrations/rest_api', :action => "rest_api"
i.search_plugin 'integrations/search_plugin.xml', :action => 'search_plugin', :format => 'xml'
i.google_gadget 'integrations/google_gadget.xml', :action => 'google_gadget', :format => 'xml'
i.cloudmailin 'integrations/cloudmailin', :action => 'cloudmailin'
end
map.with_options :controller => :preferences do |p|
p.preferences 'preferences', :action => 'index'
p.preferences_date_format 'preferences/render_date_format', :action => 'render_date_format'
end
map.with_options :controller => :stats do |stats|
stats.stats 'stats', :action => 'index'
stats.done_overview 'done', :action => 'done'
end
map.search 'search', :controller => 'search', :action => 'index'
map.data 'data', :controller => 'data', :action => 'index'
Translate::Routes.translation_ui(map) if Rails.env != "production"
# Install the default route as the lowest priority.
map.connect ':controller/:action/:id'
end

7
db/seeds.rb Normal file
View file

@ -0,0 +1,7 @@
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)

2
doc/README_FOR_APP Normal file
View file

@ -0,0 +1,2 @@
Use this README file to introduce your application and point to useful places in the API for learning more.
Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.

0
lib/assets/.gitkeep Normal file
View file

0
lib/tasks/.gitkeep Normal file
View file

View file

@ -1,10 +1,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>The page you were looking for doesn't exist (404)</title> <title>The page you were looking for doesn't exist (404)</title>
<style type="text/css"> <style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; } body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }

View file

@ -1,10 +1,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>The change you wanted was rejected (422)</title> <title>The change you wanted was rejected (422)</title>
<style type="text/css"> <style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; } body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }

View file

@ -1,10 +1,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>We're sorry, but something went wrong (500)</title> <title>We're sorry, but something went wrong (500)</title>
<style type="text/css"> <style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; } body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }

241
public/index.html Normal file
View file

@ -0,0 +1,241 @@
<!DOCTYPE html>
<html>
<head>
<title>Ruby on Rails: Welcome aboard</title>
<style type="text/css" media="screen">
body {
margin: 0;
margin-bottom: 25px;
padding: 0;
background-color: #f0f0f0;
font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
font-size: 13px;
color: #333;
}
h1 {
font-size: 28px;
color: #000;
}
a {color: #03c}
a:hover {
background-color: #03c;
color: white;
text-decoration: none;
}
#page {
background-color: #f0f0f0;
width: 750px;
margin: 0;
margin-left: auto;
margin-right: auto;
}
#content {
float: left;
background-color: white;
border: 3px solid #aaa;
border-top: none;
padding: 25px;
width: 500px;
}
#sidebar {
float: right;
width: 175px;
}
#footer {
clear: both;
}
#header, #about, #getting-started {
padding-left: 75px;
padding-right: 30px;
}
#header {
background-image: url("assets/rails.png");
background-repeat: no-repeat;
background-position: top left;
height: 64px;
}
#header h1, #header h2 {margin: 0}
#header h2 {
color: #888;
font-weight: normal;
font-size: 16px;
}
#about h3 {
margin: 0;
margin-bottom: 10px;
font-size: 14px;
}
#about-content {
background-color: #ffd;
border: 1px solid #fc0;
margin-left: -55px;
margin-right: -10px;
}
#about-content table {
margin-top: 10px;
margin-bottom: 10px;
font-size: 11px;
border-collapse: collapse;
}
#about-content td {
padding: 10px;
padding-top: 3px;
padding-bottom: 3px;
}
#about-content td.name {color: #555}
#about-content td.value {color: #000}
#about-content ul {
padding: 0;
list-style-type: none;
}
#about-content.failure {
background-color: #fcc;
border: 1px solid #f00;
}
#about-content.failure p {
margin: 0;
padding: 10px;
}
#getting-started {
border-top: 1px solid #ccc;
margin-top: 25px;
padding-top: 15px;
}
#getting-started h1 {
margin: 0;
font-size: 20px;
}
#getting-started h2 {
margin: 0;
font-size: 14px;
font-weight: normal;
color: #333;
margin-bottom: 25px;
}
#getting-started ol {
margin-left: 0;
padding-left: 0;
}
#getting-started li {
font-size: 18px;
color: #888;
margin-bottom: 25px;
}
#getting-started li h2 {
margin: 0;
font-weight: normal;
font-size: 18px;
color: #333;
}
#getting-started li p {
color: #555;
font-size: 13px;
}
#sidebar ul {
margin-left: 0;
padding-left: 0;
}
#sidebar ul h3 {
margin-top: 25px;
font-size: 16px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
#sidebar li {
list-style-type: none;
}
#sidebar ul.links li {
margin-bottom: 5px;
}
.filename {
font-style: italic;
}
</style>
<script type="text/javascript">
function about() {
info = document.getElementById('about-content');
if (window.XMLHttpRequest)
{ xhr = new XMLHttpRequest(); }
else
{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
xhr.open("GET","rails/info/properties",false);
xhr.send("");
info.innerHTML = xhr.responseText;
info.style.display = 'block'
}
</script>
</head>
<body>
<div id="page">
<div id="sidebar">
<ul id="sidebar-items">
<li>
<h3>Browse the documentation</h3>
<ul class="links">
<li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
<li><a href="http://api.rubyonrails.org/">Rails API</a></li>
<li><a href="http://www.ruby-doc.org/core/">Ruby core</a></li>
<li><a href="http://www.ruby-doc.org/stdlib/">Ruby standard library</a></li>
</ul>
</li>
</ul>
</div>
<div id="content">
<div id="header">
<h1>Welcome aboard</h1>
<h2>You&rsquo;re riding Ruby on Rails!</h2>
</div>
<div id="about">
<h3><a href="rails/info/properties" onclick="about(); return false">About your application&rsquo;s environment</a></h3>
<div id="about-content" style="display: none"></div>
</div>
<div id="getting-started">
<h1>Getting started</h1>
<h2>Here&rsquo;s how to get rolling:</h2>
<ol>
<li>
<h2>Use <code>rails generate</code> to create your models and controllers</h2>
<p>To see all available options, run it without parameters.</p>
</li>
<li>
<h2>Set up a default route and remove <span class="filename">public/index.html</span></h2>
<p>Routes are set up in <span class="filename">config/routes.rb</span>.</p>
</li>
<li>
<h2>Create your database</h2>
<p>Run <code>rake db:create</code> to create your database. If you're not using SQLite (the default), edit <span class="filename">config/database.yml</span> with your username and password.</p>
</li>
</ol>
</div>
</div>
<div id="footer">&nbsp;</div>
</div>
</body>
</html>

0
script/about Normal file → Executable file
View file

6
script/rails Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'

0
test/fixtures/.gitkeep vendored Normal file
View file

0
test/functional/.gitkeep Normal file
View file

View file

View file

@ -0,0 +1,12 @@
require 'test_helper'
require 'rails/performance_test_help'
class BrowsingTest < ActionDispatch::PerformanceTest
# Refer to the documentation for all available options
# self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
# :output => 'tmp/performance', :formats => [:flat] }
def test_homepage
get '/'
end
end

View file

@ -1,152 +1,13 @@
ENV["RAILS_ENV"] = "test" ENV["RAILS_ENV"] = "test"
require 'thread' require File.expand_path('../../config/environment', __FILE__)
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'rails/test_help'
require File.expand_path(File.dirname(__FILE__) + "/../app/controllers/application_controller")
require 'test_help'
require 'flexmock/test_unit' #and the flexmock gem, too!
require 'action_web_service/test_invoke'
module Tracks
class Config
def self.salt
"change-me"
end
def self.auth_schemes
return ["database","open_id"]
end
end
end
class Test::Unit::TestCase
include AuthenticatedTestHelper
def xml_document
@xml_document ||= HTML::Document.new(@response.body, false, true)
end
def assert_xml_select(*args, &block)
@html_document = xml_document
assert_select(*args, &block)
end
def assert_error_on(model_instance, attribute, expected_error)
actual_error = model_instance.errors.on attribute.to_sym
assert_equal expected_error, actual_error
end
alias_method :assert_errors_on, :assert_error_on
def assert_value_changed(object, method = nil)
initial_value = object.send(method)
yield
assert_not_equal initial_value, object.send(method), "#{object}##{method}"
end
end
class ActiveSupport::TestCase class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
# Generates a random string of ascii characters (a-z, "1 0")
# of a given length for testing assignment to fields
# for validation purposes
# #
def generate_random_string(length) # Note: You'll currently still have to declare fixtures explicitly in integration tests
string = "" # -- they do not yet inherit this setting
characters = %w(a b c d e f g h i j k l m n o p q r s t u v w z y z 1\ 0) fixtures :all
length.times do
pick = characters[rand(26)]
string << pick
end
return string
end
def next_week
1.week.from_now.utc
end
# Courtesy of http://habtm.com/articles/2006/02/20/assert-yourself-man-redirecting-with-rjs
def assert_js_redirected_to(options={}, message=nil)
clean_backtrace do
assert_response(:success, message)
assert_equal 'text/javascript', @response.content_type, 'Response should be Javascript content-type';
js_regexp = %r{(\w+://)?.*?(/|$|\\\?)(.*)}
url_regexp = %r{^window\.location\.href [=] ['"]#{js_regexp}['"][;]$}
redirected_to = @response.body.match(url_regexp)
assert_not_nil(redirected_to, message)
redirected_to = redirected_to[3]
msg = build_message(message, "expected a JS redirect to <?>, found one to <?>", options, redirected_to)
if options.is_a?(String)
assert_equal(options.gsub(/^\//, ''), redirected_to, message)
elsif options.is_a?(Regexp)
assert(options =~ redirected_to, "#{message} #{options} #{redirected_to}")
else
msg = build_message(message, "response is not a redirection to all of the options supplied (redirection is <?>)", redirected_to)
assert_equal(@controller.url_for(options).match(js_regexp)[3], redirected_to, msg)
end
end
end
def set_user_to_current_time_zone(user)
jan_offset = Time.now.beginning_of_year.utc_offset
jul_offset = Time.now.beginning_of_year.change(:month => 7).utc_offset
offset = jan_offset < jul_offset ? jan_offset : jul_offset
offset = if offset.to_s.match(/(\+|-)?(\d+):(\d+)/)
sign = $1 == '-' ? -1 : 1
hours, minutes = $2.to_f, $3.to_f
((hours * 3600) + (minutes.to_f * 60)) * sign
elsif offset.to_f.abs <= 13
offset.to_f * 3600
else
offset.to_f
end
zone = ActiveSupport::TimeZone.all.find{|t| t.utc_offset == offset}
user.prefs.update_attribute(:time_zone, zone.name)
end
end
class ActionController::IntegrationTest
Tag #avoid errors in integration tests
def assert_test_environment_ok
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
end
def authenticated_post_xml(url, username, password, parameters, headers = {})
post url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def authenticated_get_xml(url, username, password, parameters, headers = {})
get url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def assert_response_and_body(type, body, message = nil)
assert_equal body, @response.body, message
assert_response type, message
end
def assert_response_and_body_matches(type, body_regex, message = nil)
assert_response type, message
assert_match body_regex, @response.body, message
end
def assert_401_unauthorized
assert_response_and_body 401, "401 Unauthorized: You are not authorized to interact with Tracks."
end
def assert_401_unauthorized_admin
assert_response_and_body 401, "401 Unauthorized: Only admin users are allowed access to this function."
end
# Add more helper methods to be used by all tests here...
end end

152
test/test_helper.rb.rails2 Normal file
View file

@ -0,0 +1,152 @@
ENV["RAILS_ENV"] = "test"
require 'thread'
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require File.expand_path(File.dirname(__FILE__) + "/../app/controllers/application_controller")
require 'test_help'
require 'flexmock/test_unit' #and the flexmock gem, too!
require 'action_web_service/test_invoke'
module Tracks
class Config
def self.salt
"change-me"
end
def self.auth_schemes
return ["database","open_id"]
end
end
end
class Test::Unit::TestCase
include AuthenticatedTestHelper
def xml_document
@xml_document ||= HTML::Document.new(@response.body, false, true)
end
def assert_xml_select(*args, &block)
@html_document = xml_document
assert_select(*args, &block)
end
def assert_error_on(model_instance, attribute, expected_error)
actual_error = model_instance.errors.on attribute.to_sym
assert_equal expected_error, actual_error
end
alias_method :assert_errors_on, :assert_error_on
def assert_value_changed(object, method = nil)
initial_value = object.send(method)
yield
assert_not_equal initial_value, object.send(method), "#{object}##{method}"
end
end
class ActiveSupport::TestCase
# Generates a random string of ascii characters (a-z, "1 0")
# of a given length for testing assignment to fields
# for validation purposes
#
def generate_random_string(length)
string = ""
characters = %w(a b c d e f g h i j k l m n o p q r s t u v w z y z 1\ 0)
length.times do
pick = characters[rand(26)]
string << pick
end
return string
end
def next_week
1.week.from_now.utc
end
# Courtesy of http://habtm.com/articles/2006/02/20/assert-yourself-man-redirecting-with-rjs
def assert_js_redirected_to(options={}, message=nil)
clean_backtrace do
assert_response(:success, message)
assert_equal 'text/javascript', @response.content_type, 'Response should be Javascript content-type';
js_regexp = %r{(\w+://)?.*?(/|$|\\\?)(.*)}
url_regexp = %r{^window\.location\.href [=] ['"]#{js_regexp}['"][;]$}
redirected_to = @response.body.match(url_regexp)
assert_not_nil(redirected_to, message)
redirected_to = redirected_to[3]
msg = build_message(message, "expected a JS redirect to <?>, found one to <?>", options, redirected_to)
if options.is_a?(String)
assert_equal(options.gsub(/^\//, ''), redirected_to, message)
elsif options.is_a?(Regexp)
assert(options =~ redirected_to, "#{message} #{options} #{redirected_to}")
else
msg = build_message(message, "response is not a redirection to all of the options supplied (redirection is <?>)", redirected_to)
assert_equal(@controller.url_for(options).match(js_regexp)[3], redirected_to, msg)
end
end
end
def set_user_to_current_time_zone(user)
jan_offset = Time.now.beginning_of_year.utc_offset
jul_offset = Time.now.beginning_of_year.change(:month => 7).utc_offset
offset = jan_offset < jul_offset ? jan_offset : jul_offset
offset = if offset.to_s.match(/(\+|-)?(\d+):(\d+)/)
sign = $1 == '-' ? -1 : 1
hours, minutes = $2.to_f, $3.to_f
((hours * 3600) + (minutes.to_f * 60)) * sign
elsif offset.to_f.abs <= 13
offset.to_f * 3600
else
offset.to_f
end
zone = ActiveSupport::TimeZone.all.find{|t| t.utc_offset == offset}
user.prefs.update_attribute(:time_zone, zone.name)
end
end
class ActionController::IntegrationTest
Tag #avoid errors in integration tests
def assert_test_environment_ok
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
end
def authenticated_post_xml(url, username, password, parameters, headers = {})
post url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def authenticated_get_xml(url, username, password, parameters, headers = {})
get url,
parameters,
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def assert_response_and_body(type, body, message = nil)
assert_equal body, @response.body, message
assert_response type, message
end
def assert_response_and_body_matches(type, body_regex, message = nil)
assert_response type, message
assert_match body_regex, @response.body, message
end
def assert_401_unauthorized
assert_response_and_body 401, "401 Unauthorized: You are not authorized to interact with Tracks."
end
def assert_401_unauthorized_admin
assert_response_and_body 401, "401 Unauthorized: Only admin users are allowed access to this function."
end
end

0
test/unit/.gitkeep Normal file
View file

0
vendor/assets/javascripts/.gitkeep vendored Normal file
View file

0
vendor/assets/stylesheets/.gitkeep vendored Normal file
View file

0
vendor/plugins/.gitkeep vendored Normal file
View file

View file

@ -0,0 +1,20 @@
Copyright (c) 2010 Jeremy McAnally
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,26 @@
= rails-upgrade
A simple battery of scripts for upgrading Rails app/checking them for required updates. This application should work on Rails 2.x and 3.0, with a focus on upgrading to 3.0.
== Usage
You need to install this plugin first:
script/plugin install git://github.com/rails/rails_upgrade.git
Then you can run its rake tasks to check your application:
# Check your app for required upgrades
rake rails:upgrade:check
# Backup your likely modified files that might be overwritten by the generator
rake rails:upgrade:backup
# Generate a new route file
rake rails:upgrade:routes
# Generate a Gemfile from your config.gem directives
rake rails:upgrade:gems
# Generate code for a new config/application.rb from your environment.rb
rake rails:upgrade:configuration

22
vendor/plugins/rails_upgrade/Rakefile vendored Normal file
View file

@ -0,0 +1,22 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
Rake::TestTask.new do |t|
t.libs << 'lib'
t.libs << 'test'
t.test_files = FileList['test/*_test.rb']
t.verbose = true
end
desc 'Generate documentation for the rails_upgrade plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Rails-upgrade'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

2
vendor/plugins/rails_upgrade/init.rb vendored Normal file
View file

@ -0,0 +1,2 @@
# Get long stack traces for easier debugging; you'll thank me later.
Rails.backtrace_cleaner.remove_silencers! if Rails.respond_to?(:backtrace_cleaner)

38
vendor/plugins/rails_upgrade/install.rb vendored Normal file
View file

@ -0,0 +1,38 @@
puts "Thanks for installing the Rails upgrade plugin. This is a set of generators and analysis tools to help you upgrade your application to Rails 3. It consists of three tasks...
To get a feel for what you'll need to change to get your app running, run the application analysis:
rake rails:upgrade:check
This should give you an idea of the manual changes that need to be done, but you'll probably want to upgrade some of those automatically. The fastest way to do this is to run 'rails .', which will simply generate a new app on top of your existing code. But this generation also has the effect of replacing some existing files, some of which you might not want to replace. To back those up, first run:
rake rails:upgrade:backup
That will backup files you've probably edited that will be replaced in the upgrade; if you finish the upgrade and find that you don't need the old copies, just delete them. Otherwise, copy their contents back into the new files or run one of the following upgraders...
Routes upgrader
===============
To generate a new routes file from your existing routes file, simply run the following Rake task:
rake rails:upgrade:routes
This will output a new routes file that you can copy and paste or pipe into a new, Rails 3 compatible config/routes.rb.
Gemfile generator
=================
Creating a new Gemfile is as simple as running:
rake rails:upgrade:gems
This task will extract your config.gem calls and generate code you can put into a bundler compatible Gemfile.
Configuration generator
=======================
Much of the configuration information that lived in environment.rb now belongs in a new file named config/application.rb; use the following task to generate code you can put into config/application.rb from your existing config/environment.rb:
rake rails:upgrade:configuration
"

View file

@ -0,0 +1,506 @@
require 'open3'
module Rails
module Upgrading
class ApplicationChecker
def initialize
@issues = []
raise NotInRailsAppError unless in_rails_app?
end
def in_rails_app?
File.exist?("config/environment.rb")
end
# Run all the check methods
def run
# Ruby 1.8 returns method names as strings whereas 1.9 uses symbols
the_methods = (self.public_methods - Object.methods) - [:run, :initialize, "run", "initialize"]
the_methods.each {|m| send m }
end
# Check for deprecated ActiveRecord calls
def check_ar_methods
files = []
["find(:all", "find(:first", "find.*:conditions =>", ":joins =>"].each do |v|
lines = grep_for(v, "app/")
files += extract_filenames(lines) || []
end
unless files.empty?
alert(
"Soon-to-be-deprecated ActiveRecord calls",
"Methods such as find(:all), find(:first), finds with conditions, and the :joins option will soon be deprecated.",
"http://m.onkey.org/2010/1/22/active-record-query-interface",
files
)
end
lines = grep_for("named_scope", "app/models/")
files = extract_filenames(lines)
unless files.empty?
alert(
"named_scope is now just scope",
"The named_scope method has been renamed to just scope.",
"http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914",
files
)
end
end
def check_validation_on_methods
files = []
["validate_on_create", "validate_on_update"].each do |v|
lines = grep_for(v, "app/models/")
files += extract_filenames(lines) || []
end
unless files.empty?
alert(
"Updated syntax for validate_on_* methods",
"Validate-on-callback methods (validate_on_create/validate_on_destroy) have been changed to validate :x, :on => :create",
"https://rails.lighthouseapp.com/projects/8994/tickets/3880-validate_on_create-and-validate_on_update-no-longer-seem-to-exist",
files
)
end
end
def check_before_validation_on_methods
files = []
%w(before_validation_on_create before_validation_on_update).each do |v|
lines = grep_for(v, "app/models/")
files += extract_filenames(lines) || []
end
unless files.empty?
alert(
"Updated syntax for before_validation_on_* methods",
"before_validation_on_* methods have been changed to before_validation(:on => :create/:update) { ... }",
"https://rails.lighthouseapp.com/projects/8994/tickets/4699-before_validation_on_create-and-before_validation_on_update-doesnt-exist",
files
)
end
end
# Check for deprecated router syntax
def check_routes
lines = ["map\\.", "ActionController::Routing::Routes", "\\.resources"].map do |v|
grep_for(v, "config/routes.rb").empty? ? nil : true
end.compact
unless lines.empty?
alert(
"Old router API",
"The router API has totally changed.",
"http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/",
"config/routes.rb"
)
end
end
# Check for deprecated test_help require
def check_test_help
files = []
# Hate to duplicate code, but we have to double quote this one...
lines = grep_for("\'test_help\'", "test/", true)
files += extract_filenames(lines) || []
lines = grep_for("\"test_help\"", "test/")
files += extract_filenames(lines) || []
files.uniq!
unless files.empty?
alert(
"Deprecated test_help path",
"You now must require 'rails/test_help' not just 'test_help'.",
"http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices",
files
)
end
end
# Check for old (pre-application.rb) environment.rb file
def check_environment
unless File.exist?("config/application.rb")
alert(
"New file needed: config/application.rb",
"You need to add a config/application.rb.",
"http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade",
"config/application.rb"
)
end
lines = grep_for("config.", "config/environment.rb")
unless lines.empty?
alert(
"Old environment.rb",
"environment.rb doesn't do what it used to; you'll need to move some of that into application.rb.",
"http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade",
"config/environment.rb"
)
end
end
# Check for deprecated constants
def check_deprecated_constants
files = []
["RAILS_ENV", "RAILS_ROOT", "RAILS_DEFAULT_LOGGER"].each do |v|
lines = grep_for(v, "app/")
files += extract_filenames(lines) || []
lines = grep_for(v, "lib/")
files += extract_filenames(lines) || []
end
unless files.empty?
alert(
"Deprecated constant(s)",
"Constants like RAILS_ENV, RAILS_ROOT, and RAILS_DEFAULT_LOGGER are now deprecated.",
"http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/",
files.uniq
)
end
end
# Check for old-style config.gem calls
def check_gems
lines = grep_for("config.gem ", "config/*.rb")
lines += grep_for("config.gem ", "config/**/*.rb")
files = extract_filenames(lines)
unless files.empty?
alert(
"Old gem bundling (config.gems)",
"The old way of bundling is gone now. You need a Gemfile for bundler.",
"http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade",
files
)
end
end
# Checks for old mailer syntax in both mailer classes and those
# classes utilizing the mailers
def check_mailers
lines = grep_for("deliver_", "app/models/ #{base_path}app/controllers/ #{base_path}app/observers/")
files = extract_filenames(lines)
unless files.empty?
alert(
"Deprecated ActionMailer API",
"You're using the old ActionMailer API to send e-mails in a controller, model, or observer.",
"http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3",
files
)
end
files = []
["recipients ", "attachment(?!s) ", "(?<!:)subject ", "(?<!:)from "].each do |v|
lines = grep_for_with_perl_regex(v, "app/models/")
files += extract_filenames(lines) || []
end
unless files.empty?
alert(
"Old ActionMailer class API",
"You're using the old API in a mailer class.",
"http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3",
files
)
end
end
# Checks for old-style generators
def check_generators
generators = Dir.glob(base_path + "vendor/plugins/**/generators/**/")
unless generators.empty?
files = generators.reject do |g|
grep_for("def manifest", g).empty?
end.compact
unless files.empty?
alert(
"Old Rails generator API",
"A plugin in the app is using the old generator API (a new one may be available at http://github.com/trydionel/rails3-generators).",
"http://blog.plataformatec.com.br/2010/01/discovering-rails-3-generators/",
files
)
end
end
end
# Checks a list of known broken plugins and gems
def check_plugins
# This list is off the wiki; will need to be updated often, esp. since RSpec is working on it
bad_plugins = ["rspec", "rspec-rails", "hoptoad", "authlogic", "nifty-generators",
"restful_authentication", "searchlogic", "cucumber", "cucumber-rails", "devise",
"inherited_resources"]
bad_plugins = bad_plugins.map do |p|
p if File.exist?("#{base_path}vendor/plugins/#{p}") || !Dir.glob("#{base_path}vendor/gems/#{p}-*").empty?
end.compact
unless bad_plugins.empty?
alert(
"Known broken plugins",
"At least one plugin in your app is broken (according to the wiki). Most of project maintainers are rapidly working towards compatibility, but do be aware you may encounter issues.",
"http://wiki.rubyonrails.org/rails/version3/plugins_and_gems",
bad_plugins
)
end
end
# Checks for old-style ERb helpers
def check_old_helpers
lines = grep_for("<% .*content_tag.* do.*%>", "app/views/**/*")
lines += grep_for("<% .*javascript_tag.* do.*%>", "app/views/**/*")
lines += grep_for("<% .*form_for.* do.*%>", "app/views/**/*")
lines += grep_for("<% .*form_tag.* do.*%>", "app/views/**/*")
lines += grep_for("<% .*fields_for.* do.*%>", "app/views/**/*")
lines += grep_for("<% .*field_set_tag.* do.*%>", "app/views/**/*")
files = extract_filenames(lines)
if !files.blank?
alert(
"Deprecated ERb helper calls",
"Block helpers that use concat (e.g., form_for) should use <%= instead of <%. The current form will continue to work for now, but you will get deprecation warnings since this form will go away in the future.",
"http://weblog.rubyonrails.org/",
files
)
end
end
# Checks for old-style AJAX helpers
def check_old_ajax_helpers
files = []
['link_to_remote','form_remote_tag','remote_form_for'].each do |type|
lines = grep_for(type, "app/views/**/*")
inner_files = extract_filenames(lines)
files += inner_files unless inner_files.nil?
end
unless files.empty?
alert(
"Deprecated AJAX helper calls",
"AJAX javascript helpers have been switched to be unobtrusive and use :remote => true instead of having a seperate function to handle remote requests.",
"http://blog.jordanwest.me/modest-rubyist-archive/rails-3-ujs-and-csrf-meta-tags",
files
)
end
end
# Checks for old cookie secret settings
def check_old_cookie_secret
lines = grep_for("ActionController::Base.cookie_verifier_secret = ", "config/**/*")
files = extract_filenames(lines)
unless files.empty?
alert(
"Deprecated cookie secret setting",
"Previously, cookie secret was set directly on ActionController::Base; it's now config.secret_token.",
"http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store",
files
)
end
end
def check_old_session_secret
lines = grep_for("ActionController::Base.session = {", "config/**/*")
files = extract_filenames(lines)
unless files.empty?
alert(
"Deprecated session secret setting",
"Previously, session secret was set directly on ActionController::Base; it's now config.secret_token.",
"http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store",
files
)
end
end
# Checks for old session settings
def check_old_session_setting
lines = grep_for("ActionController::Base.session_store", "config/**/*")
files = extract_filenames(lines)
unless files.empty?
alert(
"Old session store setting",
"Previously, session store was set directly on ActionController::Base; it's now config.session_store :whatever.",
"http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store",
files
)
end
end
#Check for old ActionMailer :sent_on attributes
def check_old_action_mailer_sent_on_setting
files = []
lines = grep_for("sent_on", "app/*")
files += extract_filenames(lines) || []
unless files.empty?
alert(
"Deprecated ActionMailer attribute :sent_on",
"Using the new mailer API, you can specify :date to the mail method.",
"http://stackoverflow.com/questions/7367185/weird-error-when-delivering-mail-undefined-method-index-for-2011-09-09-2215",
files
)
end
end
def check_old_filter_parameter
files = []
lines = grep_for("filter_parameter_logging", "app/controllers/*")
files += extract_filenames(lines) || []
unless files.empty?
alert(
"Deprecated filter_parameter_logging calls",
"The list of filtered parameters are now stored in /config/application.rb. For example: config.filter_parameters += [:password]",
"http://de.asciicasts.com/episodes/224-controller-in-rails-3",
files
)
end
end
private
def grep_for_with_perl_regex(text, where = "./", double_quote = false)
grep_for(text, where, double_quote, true)
end
# Find a string in a set of files; calls +find_with_grep+ and +find_with_rak+
# depending on platform.
#
# TODO: Figure out if this works on Windows.
def grep_for(text, where = "./", double_quote = false, perl_regex = false)
# If they're on Windows, they probably don't have grep.
@probably_has_grep ||= (Config::CONFIG['host_os'].downcase =~ /mswin|windows|mingw/).nil?
# protect against double root paths in Rails 3
where.gsub!(Regexp.new(base_path),'')
lines = if @probably_has_grep
find_with_grep(text, base_path + where, double_quote, perl_regex)
else
find_with_rak(text, base_path + where, double_quote)
end
# ignore comments
lines.gsub /^(\/[^:]+:)?\s*#.+$/m, ""
end
# Sets a base path for finding files; mostly for testing
def base_path
Dir.pwd + "/"
end
# Use the grep utility to find a string in a set of files
def find_with_grep(text, where, double_quote, perl_regex = false)
value = ""
# Specifically double quote for finding 'test_help'
command = if double_quote
"grep -rH #{"-P" if perl_regex} \"#{text}\" #{where} | grep -v \.svn"
else
"grep -rH #{"-P" if perl_regex} '#{text}' #{where} | grep -v \.svn"
end
Open3.popen3(command) do |stdin, stdout, stderr|
value = stdout.read
end
value
end
# Use the rak gem to grep the files (not yet implemented)
def find_with_rak(text, where, double_quote)
value = ""
Open3.popen3("rak --nogroup -l '#{Regexp.escape(text)}' #{where}") do |stdin, stdout, stderr|
value = stdout.read
end
value
end
# Extract the filenames from the grep output
def extract_filenames(output)
if @probably_has_grep
filenames = extract_filenames_from_grep(output)
else
filenames = extract_filenames_from_rak(output)
end
filenames.compact.map do |f|
f.gsub(base_path, "")
end
end
def extract_filenames_from_grep(output)
return [] if output.empty?
output.split("\n").map do |fn|
if m = fn.match(/^(.+?):/)
m[1]
end
end.compact.uniq
end
def extract_filenames_from_rak(output)
return [] if output.empty?
output.split("\n").uniq
end
# Terminal colors, borrowed from Thor
CLEAR = "\e[0m"
BOLD = "\e[1m"
RED = "\e[31m"
YELLOW = "\e[33m"
CYAN = "\e[36m"
WHITE = "\e[37m"
# Show an upgrade alert to the user
def alert(title, text, more_info_url, culprits)
if Config::CONFIG['host_os'].downcase =~ /mswin|windows|mingw/
basic_alert(title, text, more_info_url, culprits)
else
color_alert(title, text, more_info_url, culprits)
end
end
# Show an upgrade alert to the user. If we're on Windows, we can't
# use terminal colors, hence this method.
def basic_alert(title, text, more_info_url, culprits)
puts "** " + title
puts text
puts "More information: #{more_info_url}"
puts
puts "The culprits: "
Array(culprits).each do |c|
puts "\t- #{c}"
end
puts
end
# Show a colorful alert to the user
def color_alert(title, text, more_info_url, culprits)
puts "#{RED}#{BOLD}#{title}#{CLEAR}"
puts "#{WHITE}#{text}"
puts "#{BOLD}More information:#{CLEAR} #{CYAN}#{more_info_url}"
puts
puts "#{WHITE}The culprits: "
Array(culprits).each do |c|
puts "#{YELLOW}\t- #{c}"
end
ensure
puts "#{CLEAR}"
end
end
end
end

View file

@ -0,0 +1,95 @@
module Rails
module Upgrading
class GemfileGenerator
def generate_new_gemfile
if has_environment?
generate_gemfile
else
raise FileNotFoundError, "Can't find environment.rb [config/environment.rb]!"
end
end
def has_environment?
File.exists?("config/environment.rb")
end
def environment_code
File.open("config/environment.rb").read
end
def generate_gemfile
environment_file = environment_code
# Get each line that starts with config.gem
gem_lines = environment_file.split("\n").select {|l| l =~ /^\s*config\.gem/}
# Toss those lines to a generator class; the lines are evaluated in the
# context of that instance.
config = GemfileGenerator.new
config.instance_eval(gem_lines.join("\n"))
config.output
end
end
class GemfileGenerator
# Creates a target for the config.gem calls
def config
self
end
def initialize
@gems = []
end
# Receive a call to add a gem to the list
def gem(name, options={})
data = {}
# Add new keys from old keys
data[:require] = options[:lib] if options[:lib]
data[:source] = options[:source] if options[:source]
version = options[:version]
@gems << [name, version, data]
end
# Generate the Gemfile output
def output
# Generic preamble, taken from Yehuda Katz's blog
preamble = <<STR
# Edit this Gemfile to bundle your application's dependencies.
# This preamble is the current preamble for Rails 3 apps; edit as needed.
source 'http://rubygems.org'
gem 'rails', '3.0.6'
STR
preamble + generate_upgraded_code
end
# Get Gemfile call for all the gems
def generate_upgraded_code
code = @gems.map do |name, version, data|
version_string = (version ? "'#{version}'" : nil)
source = data.delete(:source)
data_string = nil
unless data.empty?
data_string = data.to_a.map {|k, v| ":#{k} => '#{v}'"}.join(", ")
end
# If we have a source, generate a call to +source+ then output the
# gem call. Otherwise, just generate the gem requirement.
if source
str = ["'#{name}'", version_string, data_string].compact.join(", ")
"source '#{source}'\ngem #{str}"
else
str = ["'#{name}'", version_string, data_string].compact.join(", ")
"gem #{str}"
end
end.join("\n")
end
end
end
end

View file

@ -0,0 +1,59 @@
require 'active_support/core_ext/string/inflections'
module Rails
module Upgrading
class NewConfigurationGenerator
def generate_new_configurations
if has_environment?
generate_new_application_rb
else
raise FileNotFoundError, "Can't find environment.rb [config/environment.rb]!"
end
end
def has_environment?
File.exists?("config/environment.rb")
end
def environment_code
File.open("config/environment.rb").read
end
def generate_new_application_rb
environment_file = environment_code
initializer_code = ""
if matches = environment_file.match(/Rails\:\:Initializer\.run do \|config\|\n(.*)\nend/m)
initializer_code = matches[1]
else
raise "There doesn't seem to be a real environment.rb in your app. Are you sure config/environment.rb has the right contents?"
end
frame = "# Put this in config/application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(:default, Rails.env) if defined?(Bundler)
module #{app_name.classify}
class Application < Rails::Application
config.autoload_paths += [config.root.join('lib')]
config.encoding = 'utf-8'
%s
end
end"
frame % [indent(initializer_code)]
end
def indent(text)
text.split("\n").map {|l| " #{l}"}.join("\n")
end
def app_name
File.basename(Dir.pwd)
end
end
end
end

View file

View file

@ -0,0 +1,344 @@
# TODO: Fix formatting on member/collection methods
module Rails
module Upgrading
module FakeRouter
module ActionController
module Routing
class Routes
def self.setup
@redrawer = Rails::Upgrading::RouteRedrawer.new
end
def self.redrawer
@redrawer
end
def self.draw
yield @redrawer
end
end
end
end
end
class RoutesUpgrader
def generate_new_routes
if has_routes_file?
upgrade_routes
else
raise FileNotFoundError, "Can't find your routes file [config/routes.rb]!"
end
end
def has_routes_file?
File.exists?("config/routes.rb")
end
def routes_code
File.read("config/routes.rb")
end
def upgrade_routes
FakeRouter::ActionController::Routing::Routes.setup
# Read and eval the file; our fake route mapper will capture
# the calls to draw routes and generate new route code
FakeRouter.module_eval(routes_code)
# Give the route set to the code generator and get its output
generator = RouteGenerator.new(FakeRouter::ActionController::Routing::Routes.redrawer.routes)
generator.generate
end
end
class RouteRedrawer
attr_accessor :routes
def self.stack
@stack
end
def self.stack=(val)
@stack = val
end
def initialize
@routes = []
# The old default route was actually two routes; we generate the new style
# one only if we haven't generated it for the first old default route.
@default_route_generated = false
# Setup the stack for parents; used use proper indentation
self.class.stack = [@routes]
end
def root(options)
debug "mapping root"
@routes << FakeRoute.new("/", options)
end
def connect(path, options={})
debug "connecting #{path}"
if (path == ":controller/:action/:id.:format" || path == ":controller/:action/:id")
if !@default_route_generated
current_parent << FakeRoute.new("/:controller(/:action(/:id))", {:default_route => true})
@default_route_generated = true
end
else
current_parent << FakeRoute.new(path, options)
end
end
def resources(*args, &block)
_res(FakeResourceRoute, args, &block)
end
def resource(*args, &block)
_res(FakeSingletonResourceRoute, args, &block)
end
def _res(klass, args)
if args.last.is_a?(Hash)
options = args.pop
debug "options #{options.inspect}"
end
args.each do |a|
current_parent << klass.new(a, options || {})
debug "mapping resources #{current_parent.last.name}"
if block_given?
parent = current_parent.last
parent = stack(parent) do
yield(self)
end
end
end
end
def namespace(name, options = {})
debug "mapping namespace #{name}"
namespace = FakeNamespace.new(name, options)
namespace = stack(namespace) do
yield(self)
end
current_parent << namespace
end
def method_missing(m, *args)
debug "named route: #{m}"
current_parent << FakeRoute.new(args.shift, args.pop, m.to_s)
end
def self.indent
' ' * ((stack.length) * 2)
end
private
def debug(txt)
puts txt if ENV['DEBUG']
end
def stack(obj)
self.class.stack << obj
yield
self.class.stack.pop
end
def current_parent
self.class.stack.last
end
end
class RouteObject
def indent_lines(code_lines)
if code_lines.length > 1
code_lines.flatten.map {|l| "#{@indent}#{l.chomp}"}.join("\n") + "\n"
else
"#{@indent}#{code_lines.shift}"
end
end
def opts_to_string(opts)
opts.is_a?(Hash) ? opts.map {|k, v|
":#{k} => " + (v.is_a?(Hash) ? ('{ ' + opts_to_string(v) + ' }') : "#{value_to_string(v)}")
}.join(", ") : opts.to_s
end
def value_to_string(value)
case value
when Regexp, Symbol, Array then value.inspect
when String then "'" + value.to_s + "'"
else value.to_s
end
end
end
class FakeNamespace < RouteObject
attr_accessor :routes, :name, :options
def initialize(name, options = {})
@routes = []
@name, @options = name, options
@indent = RouteRedrawer.indent
end
def to_route_code
if !@options.empty?
options = ', ' + opts_to_string(@options)
else
options = ''
end
lines = ["namespace :#{@name}#{options} do", @routes.map {|r| r.to_route_code}, "end"]
indent_lines(lines)
end
def <<(val)
@routes << val
end
def last
@routes.last
end
end
class FakeRoute < RouteObject
attr_accessor :name, :path, :options
def initialize(path, options, name = "")
@path = path
@options = options || {}
@name = name
@indent = RouteRedrawer.indent
end
def to_route_code
if @options[:default_route]
indent_lines ["match '#{@path}'"]
else
base = "match '%s' => '%s#%s'"
extra_options = []
if not name.empty?
extra_options << ":as => :#{name}"
end
if @options[:requirements]
@options[:constraints] = @options.delete(:requirements)
end
if @options[:conditions]
@options[:via] = @options.delete(:conditions).delete(:method)
end
@options ||= {}
base = (base % [@path, @options.delete(:controller), (@options.delete(:action) || "index")])
opts = opts_to_string(@options)
route_pieces = ([base] + extra_options + [opts])
route_pieces.delete("")
indent_lines [route_pieces.join(", ")]
end
end
end
class FakeResourceRoute < RouteObject
attr_accessor :name, :children
def initialize(name, options = {})
@name = name
@children = []
@options = options
@indent = RouteRedrawer.indent
end
def to_route_code
# preserve :only & :except options
copied_options = @options.reject { |k,v| ![:only, :except].member?(k) }
unless copied_options.empty?
copied_options_str = ", " + copied_options.map { |k, v| "#{k.inspect} => #{v.inspect}" }.join(",")
end
if !@children.empty? || @options.has_key?(:collection) || @options.has_key?(:member)
prefix = ["#{route_method} :#{@name}#{copied_options_str} do"]
lines = prefix + custom_methods + [@children.map {|r| r.to_route_code}.join("\n"), "end"]
indent_lines(lines)
else
base = "#{route_method} :%s#{copied_options_str}"
indent_lines [base % [@name]]
end
end
def custom_methods
collection_code = generate_custom_methods_for(:collection)
member_code = generate_custom_methods_for(:member)
[collection_code, member_code]
end
def generate_custom_methods_for(group)
return "" unless @options[group]
method_code = []
RouteRedrawer.stack << self
@options[group].each do |name, methods|
[*methods].each do |method|
method_code << "#{method} :#{name}"
end
end
RouteRedrawer.stack.pop
indent_lines ["#{group} do", method_code, "end"].flatten
end
def route_method
"resources"
end
def <<(val)
@children << val
end
def last
@children.last
end
end
class FakeSingletonResourceRoute < FakeResourceRoute
def route_method
"resource"
end
end
class RouteGenerator
def initialize(routes)
@routes = routes
@new_code = ""
end
def generate
@new_code = @routes.map do |r|
r.to_route_code
end.join("\n")
"#{app_name.underscore.classify}::Application.routes.draw do\n#{@new_code}\nend\n"
end
private
def app_name
File.basename(Dir.pwd)
end
end
end
end

View file

@ -0,0 +1,79 @@
$:.unshift(File.dirname(__FILE__) + "/../../lib")
require 'routes_upgrader'
require 'gemfile_generator'
require 'application_checker'
require 'new_configuration_generator'
require "active_support"
require 'fileutils'
namespace :rails do
namespace :upgrade do
desc "Runs a battery of checks on your Rails 2.x app and generates a report on required upgrades for Rails 3"
task :check do
checker = Rails::Upgrading::ApplicationChecker.new
checker.run
end
desc "Generates a Gemfile for your Rails 3 app out of your config.gem directives"
task :gems do
generator = Rails::Upgrading::GemfileGenerator.new
new_gemfile = generator.generate_new_gemfile
puts new_gemfile
end
desc "Create a new, upgraded route file from your current routes.rb"
task :routes do
upgrader = Rails::Upgrading::RoutesUpgrader.new
new_routes = upgrader.generate_new_routes
puts new_routes
end
desc "Extracts your configuration code so you can create a new config/application.rb"
task :configuration do
upgrader = Rails::Upgrading::NewConfigurationGenerator.new
new_config = upgrader.generate_new_application_rb
puts new_config
end
CLEAR = "\e[0m" unless defined? CLEAR
CYAN = "\e[36m" unless defined? CYAN
WHITE = "\e[37m" unless defined? WHITE
desc "Backs up your likely modified files so you can run the Rails 3 generator on your app with little risk"
task :backup do
files = [".gitignore",
"app/controllers/application_controller.rb",
"app/helpers/application_helper.rb",
"config/routes.rb",
"config/environment.rb",
"config/environments/development.rb",
"config/environments/production.rb",
"config/environments/staging.rb",
"config/database.yml",
"config.ru",
"doc/README_FOR_APP",
"test/test_helper.rb"]
puts
files.each do |f|
if File.exist?(f)
puts "#{CYAN}* #{CLEAR}backing up #{WHITE}#{f}#{CLEAR} to #{WHITE}#{f}.rails2#{CLEAR}"
FileUtils.cp(f, "#{f}.rails2")
end
end
puts
puts "This is a list of the files analyzed and backed up (if they existed);\nyou will probably not want the generator to replace them since\nyou probably modified them (but now they're safe if you accidentally do!)."
puts
files.each do |f|
puts "#{CYAN}- #{CLEAR}#{f}"
end
puts
end
end
end

View file

@ -0,0 +1,344 @@
require 'test_helper'
require 'application_checker'
require 'fileutils'
tmp_dir = File.expand_path("#{File.dirname(__FILE__)}/fixtures/tmp")
if defined? BASE_ROOT
BASE_ROOT.replace tmp_dir
else
BASE_ROOT = tmp_dir
end
FileUtils.mkdir_p BASE_ROOT
# Stub out methods on upgrader class
module Rails
module Upgrading
class ApplicationChecker
attr_reader :alerts, :culprits
def base_path
BASE_ROOT + "/"
end
def in_rails_app?
true
end
def initialize
@alerts = {}
@culprits = {}
end
def alert(title, text, more_info_url, culprits)
@alerts[title] = [text, more_info_url]
@culprits[title] = culprits
end
end
end
end
class ApplicationCheckerTest < ActiveSupport::TestCase
def setup
@checker = Rails::Upgrading::ApplicationChecker.new
@old_dir = Dir.pwd
Dir.chdir(BASE_ROOT)
end
def test_check_ar_methods_in_controller
make_file("app/controllers", "post_controller.rb", "Post.find(:all)")
@checker.check_ar_methods
assert @checker.alerts.has_key?("Soon-to-be-deprecated ActiveRecord calls")
end
def test_check_ar_methods_in_models
make_file("app/models", "post.rb", "Post.find(:all)")
@checker.check_ar_methods
key = "Soon-to-be-deprecated ActiveRecord calls"
assert @checker.alerts.has_key?(key)
assert_equal "app/models/post.rb", @checker.culprits[key].first
end
def test_check_svn_subdirs_are_not_included
make_file("app/models/.svn/text-base", "foo.rb.tmp", "Post.find(:all)")
@checker.check_ar_methods
assert @checker.alerts.empty?
end
def test_check_validation_on_methods
make_file("app/models", "post.rb", "validate_on_create :comments_valid?")
@checker.check_validation_on_methods
assert @checker.alerts.has_key?("Updated syntax for validate_on_* methods")
end
def test_check_before_validation_on_methods
make_file("app/models", "post.rb", "before_validation_on_create :comments_valid?")
@checker.check_before_validation_on_methods
assert @checker.alerts.has_key?("Updated syntax for before_validation_on_* methods")
end
def test_named_scope_left_over
make_file("app/models", "post.rb", "named_scope :failure")
@checker.check_ar_methods
assert @checker.alerts.has_key?("named_scope is now just scope")
end
def test_check_routes
make_file("config/", "routes.rb", " map.connect 'fail'")
@checker.check_routes
assert @checker.alerts.has_key?("Old router API")
end
def test_check_for_old_test_help
make_file("test/", "test_helper.rb", " require 'test_help'")
@checker.check_test_help
assert @checker.alerts.has_key?("Deprecated test_help path")
end
def test_check_for_old_test_help_with_double_quotes
make_file("test/", "test_helper.rb", " require \"test_help\"")
@checker.check_test_help
assert @checker.alerts.has_key?("Deprecated test_help path")
end
def test_check_for_old_test_help_doesnt_see_test_helper
make_file("test/", "test_helper.rb", " require 'test_helper'")
@checker.check_test_help
assert !@checker.alerts.has_key?("Deprecated test_help path")
end
def test_check_lack_of_app_dot_rb
@checker.check_environment
assert @checker.alerts.has_key?("New file needed: config/application.rb")
end
def test_check_environment_syntax
make_file("config/", "environment.rb", "config.frameworks = []")
@checker.check_environment
assert @checker.alerts.has_key?("Old environment.rb")
end
def test_check_gems
make_file("config/", "environment.rb", "config.gem 'rails'")
@checker.check_gems
assert @checker.alerts.has_key?("Old gem bundling (config.gems)")
end
def test_check_gems_finds_nothing
@checker.check_gems
assert_equal false, @checker.alerts.has_key?("Old gem bundling (config.gems)")
end
def test_check_mailer_finds_nothing
@checker.check_mailers
assert_equal false, @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_check_mailer_syntax
make_file("app/models/", "notifications.rb", "def signup\nrecipients @users\n end")
@checker.check_mailers
assert @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_check_mailer_syntax_from
make_file("app/models/", "notifications.rb", "def signup\nfrom @user\n end")
@checker.check_mailers
assert @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_check_mailer_syntax_subject
make_file("app/models/", "notifications.rb", "def signup\nsubject @subject\n end")
@checker.check_mailers
assert @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_check_mailer_syntax_attachment
make_file("app/models/", "notifications.rb", "def signup\nattachment 'application/pdf' do |a|\n end")
@checker.check_mailers
assert @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_new_check_mailer_syntax_from
make_file("app/models/", "notifications.rb", "def signup\n:from => @users\n end")
@checker.check_mailers
assert ! @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_new_check_mailer_syntax_subject
make_file("app/models/", "notifications.rb", "def signup\n:subject => @users\n end")
@checker.check_mailers
assert ! @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_new_check_mailer_syntax_attachments
make_file("app/models/", "notifications.rb", "def signup\nattachments['an-image.jp'] = File.read('an-image.jpg')\n end")
@checker.check_mailers
assert ! @checker.alerts.has_key?("Old ActionMailer class API")
end
def test_check_mailer_api
make_file("app/controllers/", "thing_controller.rb", "def signup\n Notifications.deliver_signup\n end")
@checker.check_mailers
assert @checker.alerts.has_key?("Deprecated ActionMailer API")
end
def test_check_generators
make_file("vendor/plugins/thing/generators/thing/", "thing_generator.rb", "def manifest\n m.whatever\n end")
@checker.check_generators
assert @checker.alerts.has_key?("Old Rails generator API")
end
def test_check_plugins
make_file("vendor/plugins/rspec-rails/", "whatever.rb", "def rspec; end")
@checker.check_plugins
assert @checker.alerts.has_key?("Known broken plugins")
end
def test_ignoring_comments
make_file("config/", "routes.rb", "# map.connect 'fail'")
@checker.check_routes
assert !@checker.alerts.has_key?("Old router API")
end
def test_check_deprecated_constants_in_app_code
make_file("app/controllers/", "thing_controller.rb", "class ThingController; THING = RAILS_ENV; end;")
@checker.check_deprecated_constants
assert @checker.alerts.has_key?("Deprecated constant(s)")
end
def test_check_deprecated_constants_in_lib
make_file("lib/", "extra_thing.rb", "class ExtraThing; THING = RAILS_ENV; end;")
@checker.check_deprecated_constants
assert @checker.alerts.has_key?("Deprecated constant(s)")
end
def test_check_deprecated_cookie_finds_nothing
@checker.check_old_cookie_secret
assert_equal false, @checker.alerts.has_key?("Deprecated cookie secret setting")
end
def test_check_deprecated_cookie_settings
make_file("config/initializers/", "more_settings.rb", "ActionController::Base.cookie_verifier_secret = 'OMG'")
@checker.check_old_cookie_secret
assert @checker.alerts.has_key?("Deprecated cookie secret setting")
end
def test_check_deprecated_session_finds_nothing
@checker.check_old_session_secret
assert_equal false, @checker.alerts.has_key?("Deprecated session secret setting")
end
def test_check_deprecated_session_secret
make_file("config/initializers/", "more_settings.rb", "ActionController::Base.session = {\n:whatever => 'woot'\n}")
@checker.check_old_session_secret
assert @checker.alerts.has_key?("Deprecated session secret setting")
end
def test_check_old_session_setting_finds_nothing
@checker.check_old_session_setting
assert_equal false, @checker.alerts.has_key?("Old session store setting")
end
def test_check_deprecated_session_settings
make_file("config/initializers/", "more_settings.rb", "ActionController::Base.session_store = :cookie\nthings.awesome(:whatever)")
@checker.check_old_session_setting
assert @checker.alerts.has_key?("Old session store setting")
end
def test_check_helpers
make_file("app/views/users/", "test.html.erb", "<b>blah blah blah</b><% form_for(:thing) do |f| %> <label>doo dah</label> <%= f.whatever %> <% end %>")
@checker.check_old_helpers
assert @checker.alerts.has_key?("Deprecated ERb helper calls")
end
def test_check_old_helpers_lets_regular_blocks_pass
make_file("app/views/users/", "another_test.html.erb", "<b>blah blah blah</b><% @some_items.each do |item| %> <label>doo dah</label> <%= item %> <% end %>")
@checker.check_old_helpers
assert_equal @checker.alerts.has_key?("Deprecated ERb helper calls"), false
end
def test_check_old_helpers_lets_regular_blocks_pass
make_file("app/views/users/", "another_test.html.erb", "<b>blah blah blah</b><% @some_items.each do |item| %> <label>doo dah</label> <%= item %> <% end %>")
@checker.check_old_helpers
assert_equal false, @checker.alerts.has_key?("Deprecated ERb helper calls")
end
def test_check_old_ajax_helpers
make_file("app/views/sections", "section.js", "<%= link_to_remote 'section-', :update => 'sections', :url => {:action => :destroy, :controller => 'sections', :id => @section.id } %>")
@checker.check_old_ajax_helpers
assert @checker.alerts.has_key?("Deprecated AJAX helper calls")
end
def test_check_old_ajax_helpers
make_file("app/controllers", "application_controller.rb", "filter_parameter_logging :password")
@checker.check_old_filter_parameter
assert @checker.alerts.has_key?("Deprecated filter_parameter_logging calls")
end
def test_check_old_ajax_helpers_empty
@checker.check_old_ajax_helpers
assert ! @checker.alerts.has_key?("Deprecated AJAX helper calls")
end
def test_check_old_action_mailer_sent_on_setting
make_file("app/models", "mailer.rb", "sent_on Time.now")
@checker.check_old_action_mailer_sent_on_setting
assert @checker.alerts.has_key?("Deprecated ActionMailer attribute :sent_on")
end
def teardown
clear_files
Dir.chdir(@old_dir)
end
def make_file(where, name=nil, contents=nil)
FileUtils.mkdir_p "#{BASE_ROOT}/#{where}"
File.open("#{BASE_ROOT}/#{where}/#{name}", "w+") do |f|
f.write(contents)
end if name
end
def clear_files
FileUtils.rm_rf(Dir.glob("#{BASE_ROOT}/*"))
end
end

View file

@ -0,0 +1,72 @@
require 'test_helper'
require 'gemfile_generator'
# Stub out methods on upgrader class
module Rails
module Upgrading
class GemfileGenerator
attr_writer :environment_code
def has_environment?
true
end
def environment_code
@environment_code
end
end
end
end
class GemfileGeneratorTest < ActiveSupport::TestCase
PREAMBLE = <<STR
# Edit this Gemfile to bundle your application's dependencies.
# This preamble is the current preamble for Rails 3 apps; edit as needed.
source 'http://rubygems.org'
gem 'rails', '3.0.6'
STR
def test_generates_with_no_gems
generator = Rails::Upgrading::GemfileGenerator.new
generator.environment_code = ""
assert_equal PREAMBLE, generator.generate_gemfile
end
def test_generates_with_gem
generator = Rails::Upgrading::GemfileGenerator.new
generator.environment_code = "config.gem 'camping'"
assert_equal PREAMBLE + "gem 'camping'", generator.generate_gemfile
end
def test_generates_with_version
generator = Rails::Upgrading::GemfileGenerator.new
generator.environment_code = "config.gem 'camping', :version => '2.1.1'"
assert_equal PREAMBLE + "gem 'camping', '2.1.1'", generator.generate_gemfile
end
def test_can_add_sources
generator = Rails::Upgrading::GemfileGenerator.new
generator.environment_code = "config.gem 'camping', :source => 'http://code.whytheluckystiff.net'"
assert_equal PREAMBLE + "source 'http://code.whytheluckystiff.net'\ngem 'camping'", generator.generate_gemfile
end
def test_changes_lib_to_new_key
generator = Rails::Upgrading::GemfileGenerator.new
generator.environment_code = "config.gem 'camping', :lib => 'kamping'"
assert_equal PREAMBLE + "gem 'camping', :require => 'kamping'", generator.generate_gemfile
end
def test_generates_with_all_options
generator = Rails::Upgrading::GemfileGenerator.new
generator.environment_code = "config.gem 'camping', :lib => 'kamping', :source => 'http://code.whytheluckystiff.net', :version => '2.1.1'"
assert_equal PREAMBLE + "source 'http://code.whytheluckystiff.net'\ngem 'camping', '2.1.1', :require => 'kamping'", generator.generate_gemfile
end
end

View file

@ -0,0 +1,63 @@
require 'test_helper'
require 'new_configuration_generator'
# Stub out methods on upgrader class
module Rails
module Upgrading
class NewConfigurationGenerator
attr_writer :environment_code
def has_environment?
true
end
def environment_code
@environment_code
end
def app_name
"my_application"
end
end
end
end
class NewConfigurationGeneratorTest < ActiveSupport::TestCase
FRAME = "# Put this in config/application.rb
require File.expand_path('../boot', __FILE__)
module MyApplication
class Application < Rails::Application
%s
end
end"
CONFIG = " config.what_have_you = 'thing'
config.action_controller = 'what'"
CODE = "require 'w/e'
this_happens_before_the(code)
more_before_the_code!
Rails::Initializer.run do |config|
%s
end
this_is_after_the_code
"
def test_raises_error_with_no_code
generator = Rails::Upgrading::NewConfigurationGenerator.new
generator.environment_code = ""
assert_raises(RuntimeError) { generator.generate_new_application_rb }
end
def test_generates_with_code
generator = Rails::Upgrading::NewConfigurationGenerator.new
generator.environment_code = CODE % [CONFIG]
assert_equal FRAME % [generator.indent(CONFIG)], generator.generate_new_application_rb
end
end

View file

@ -0,0 +1,218 @@
require 'test_helper'
require 'routes_upgrader'
# Stub out methods on upgrader class
module Rails
module Upgrading
class RoutesUpgrader
attr_writer :routes_code
def has_routes_file?
true
end
def routes_code
@routes_code
end
end
class RouteGenerator
def app_name
"MyApplication"
end
end
end
end
class RoutesUpgraderTest < ActiveSupport::TestCase
def setup
Rails::Upgrading::RouteRedrawer.stack = []
end
def test_generates_routes_file
routes_code = "
ActionController::Routing::Routes.draw do |map|
map.connect '/home', :controller => 'home', :action => 'index'
map.login '/login', :controller => 'sessions', :action => 'new'
map.resources :hats
map.resource :store
end
"
new_routes_code = "MyApplication::Application.routes.draw do
match '/home' => 'home#index'
match '/login' => 'sessions#new', :as => :login
resources :hats
resource :store
end
"
upgrader = Rails::Upgrading::RoutesUpgrader.new
upgrader.routes_code = routes_code
result = upgrader.generate_new_routes
assert_equal new_routes_code, result
end
def test_generates_code_for_regular_route
route = Rails::Upgrading::FakeRoute.new("/about", {:controller => 'static', :action => 'about'})
assert_equal "match '/about' => 'static#about'", route.to_route_code
end
def test_generates_code_for_named_route
route = Rails::Upgrading::FakeRoute.new("/about", {:controller => 'static', :action => 'about'}, "about")
assert_equal "match '/about' => 'static#about', :as => :about", route.to_route_code
end
def test_generates_code_for_namespace
ns = Rails::Upgrading::FakeNamespace.new("static")
# Add a route to the namespace
ns << Rails::Upgrading::FakeRoute.new("/about", {:controller => 'static', :action => 'about'})
assert_equal "namespace :static do\nmatch '/about' => 'static#about'\nend\n", ns.to_route_code
end
def test_generates_code_for_namespace_with_options
ns = Rails::Upgrading::FakeNamespace.new("static", { :path_prefix => 'prefix' })
# Add a route to the namespace
ns << Rails::Upgrading::FakeRoute.new("/about", {:controller => 'static', :action => 'about'})
assert_equal "namespace :static, :path_prefix => 'prefix' do\nmatch '/about' => 'static#about'\nend\n", ns.to_route_code
end
def test_generates_code_for_resources
route = Rails::Upgrading::FakeResourceRoute.new("hats")
assert_equal "resources :hats", route.to_route_code
end
def test_generates_code_for_resources
route = Rails::Upgrading::FakeSingletonResourceRoute.new("hat")
assert_equal "resource :hat", route.to_route_code
end
def test_generates_code_for_resources_with_block_and_options
routes_code = <<-ROUTES
ActionController::Routing::Routes.draw do |map|
map.resources :people, :collection => {:search => :get} do |p|
p.resource :vuvuzela
end
end
ROUTES
upgrader = Rails::Upgrading::RoutesUpgrader.new
upgrader.routes_code = routes_code
result = upgrader.generate_new_routes
assert_equal "MyApplication::Application.routes.draw do\n resources :people do\n collection do\n get :search\n end\n \n resource :vuvuzela\n end\n\nend\n", result
end
def test_generates_code_for_resources_with_special_methods
route = Rails::Upgrading::FakeResourceRoute.new("hats", {:member => {:wear => :get}, :collection => {:toss => :post}})
assert_equal "resources :hats do\ncollection do\npost :toss\nend\nmember do\nget :wear\nend\n\nend\n", route.to_route_code
end
def test_generates_code_for_resources_with_multiple_special_methods_per_name
route = Rails::Upgrading::FakeResourceRoute.new("hats", {:member => {:wear => [:get, :put]}, :collection => {:toss => [:get, :post]}})
assert_equal "resources :hats do\ncollection do\nget :toss\npost :toss\nend\nmember do\nget :wear\nput :wear\nend\n\nend\n", route.to_route_code
end
def test_generates_code_for_route_with_extra_params
route = Rails::Upgrading::FakeRoute.new("/about", {:controller => 'static', :action => 'about', :something => 'extra'})
assert_equal "match '/about' => 'static#about', :something => 'extra'", route.to_route_code
end
def test_generates_code_for_route_with_requirements
route = Rails::Upgrading::FakeRoute.new("/foo", {:controller => 'foo', :action => 'bar', :requirements => {:digit => /%d/}})
assert_equal "match '/foo' => 'foo#bar', :constraints => { :digit => /%d/ }", route.to_route_code
end
def test_generates_code_for_root
routes_code = "
ActionController::Routing::Routes.draw do |map|
map.root :controller => 'home', :action => 'index'
end
"
new_routes_code = "MyApplication::Application.routes.draw do
match '/' => 'home#index'
end
"
upgrader = Rails::Upgrading::RoutesUpgrader.new
upgrader.routes_code = routes_code
result = upgrader.generate_new_routes
assert_equal new_routes_code, result
end
def test_generates_code_for_default_route
routes_code = "
ActionController::Routing::Routes.draw do |map|
map.connect ':controller/:action/:id.:format'
map.connect ':controller/:action/:id'
end
"
new_routes_code = "MyApplication::Application.routes.draw do
match '/:controller(/:action(/:id))'
end
"
upgrader = Rails::Upgrading::RoutesUpgrader.new
upgrader.routes_code = routes_code
result = upgrader.generate_new_routes
assert_equal new_routes_code, result
end
def test_preserves_resources_except_option
route = Rails::Upgrading::FakeResourceRoute.new("hats", :except => [:index])
assert_equal "resources :hats, :except => [:index]", route.to_route_code
end
def test_preserves_resources_only_option
route = Rails::Upgrading::FakeResourceRoute.new("hats", :only => :show)
assert_equal "resources :hats, :only => :show", route.to_route_code
end
def test_generates_code_for_delete_route
routes_code = %Q{
ActionController::Routing::Routes.draw do |map|
map.sign_out '/sign_out', :controller => 'sessions', :action => 'destroy', :conditions => {:method => :delete}
end
}
new_routes_code = %Q{
MyApplication::Application.routes.draw do
match '/sign_out' => 'sessions#destroy', :as => :sign_out, :via => :delete
end
}
upgrader = Rails::Upgrading::RoutesUpgrader.new
upgrader.routes_code = routes_code
assert_equal new_routes_code.strip, upgrader.generate_new_routes.strip
end
def test_generates_code_for_delete_route
routes_code = %Q{
ActionController::Routing::Routes.draw do |map|
map.sign_out '/sign_out', :controller => 'sessions', :action => 'destroy', :conditions => {:method => [:delete, :get]}
end
}
new_routes_code = %Q{
MyApplication::Application.routes.draw do
match '/sign_out' => 'sessions#destroy', :as => :sign_out, :via => [:delete, :get]
end
}
upgrader = Rails::Upgrading::RoutesUpgrader.new
upgrader.routes_code = routes_code
assert_equal new_routes_code.strip, upgrader.generate_new_routes.strip
end
end

View file

@ -0,0 +1,5 @@
require 'test/unit'
require 'rubygems'
require 'active_support'
require 'active_support/test_case'

View file

@ -0,0 +1 @@
# Uninstall hook code here