diff --git a/vendor/plugins/will_paginate/.rspec b/vendor/plugins/will_paginate/.rspec
new file mode 100644
index 0000000..4e1e0d2
--- /dev/null
+++ b/vendor/plugins/will_paginate/.rspec
@@ -0,0 +1 @@
+--color
diff --git a/vendor/plugins/will_paginate/.travis.yml b/vendor/plugins/will_paginate/.travis.yml
new file mode 100644
index 0000000..133b268
--- /dev/null
+++ b/vendor/plugins/will_paginate/.travis.yml
@@ -0,0 +1,26 @@
+bundler_args: "--standalone --binstubs --without development"
+script: script/test_all
+services: mongodb
+before_script:
+ - mysql -e 'create database will_paginate;'
+ - psql -c 'create database will_paginate;' -U postgres
+rvm:
+ - 1.8.7
+ - 1.9.2
+ - 1.9.3
+gemfile:
+ - Gemfile
+ - Gemfile.rails3.0
+ - Gemfile.rails3.1
+ - Gemfile.rails3.2
+ - Gemfile.rails-edge
+matrix:
+ exclude:
+ - rvm: 1.8.7
+ gemfile: Gemfile.rails-edge
+ - rvm: 1.8.7
+ gemfile: Gemfile
+ - rvm: 1.9.2
+ gemfile: Gemfile.rails-edge
+ - rvm: 1.9.2
+ gemfile: Gemfile
diff --git a/vendor/plugins/will_paginate/Gemfile b/vendor/plugins/will_paginate/Gemfile
new file mode 100644
index 0000000..7bb1ded
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile
@@ -0,0 +1,22 @@
+source 'https://rubygems.org'
+
+rails_version = '~> 4.0.0.rc2'
+
+gem 'activerecord', rails_version
+gem 'actionpack', rails_version
+
+gem 'rspec', '~> 2.6.0'
+gem 'mocha', '~> 0.9.8'
+
+gem 'sqlite3', '~> 1.3.6'
+
+group :mysql do
+ gem 'mysql', '~> 2.9'
+ gem 'mysql2', '~> 0.3.10'
+end
+gem 'pg', '~> 0.11', :group => :pg
+
+group :development do
+ gem 'ruby-debug', :platforms => :mri_18
+ gem 'debugger', :platforms => :mri_19
+end
diff --git a/vendor/plugins/will_paginate/Gemfile.rails-edge b/vendor/plugins/will_paginate/Gemfile.rails-edge
new file mode 100644
index 0000000..4d6e2a5
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails-edge
@@ -0,0 +1,25 @@
+source 'https://rubygems.org'
+
+gem 'activerecord-deprecated_finders', :github => 'rails/activerecord-deprecated_finders', :branch => 'master'
+gem 'journey', :github => 'rails/journey', :branch => 'master'
+
+gem 'activerecord', :github => 'rails/rails', :branch => 'master'
+gem 'actionpack', :github => 'rails/rails', :branch => 'master'
+
+gem 'thread_safe'
+
+gem 'rspec', '~> 2.6.0'
+gem 'mocha', '~> 0.9.8'
+
+gem 'sqlite3', '~> 1.3.6'
+
+group :mysql do
+ gem 'mysql', '~> 2.9'
+ gem 'mysql2', '~> 0.3.10'
+end
+gem 'pg', '~> 0.11', :group => :pg
+
+group :development do
+ gem 'ruby-debug', :platforms => :mri_18
+ gem 'debugger', :platforms => :mri_19
+end
diff --git a/vendor/plugins/will_paginate/Gemfile.rails-edge.lock b/vendor/plugins/will_paginate/Gemfile.rails-edge.lock
new file mode 100644
index 0000000..6186bb4
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails-edge.lock
@@ -0,0 +1,107 @@
+GIT
+ remote: git://github.com/rails/activerecord-deprecated_finders.git
+ revision: f6ed71d62d47f0f6397b5b3e801271567f30f960
+ branch: master
+ specs:
+ activerecord-deprecated_finders (1.0.3)
+
+GIT
+ remote: git://github.com/rails/journey.git
+ revision: f0938d664286dc0b47f13092fa5d04a9225038d4
+ branch: master
+ specs:
+ journey (2.0.0.20120723141804)
+
+GIT
+ remote: git://github.com/rails/rails.git
+ revision: 12fe66b56479abc2ca399c002d38a7e81fce2eb2
+ branch: master
+ specs:
+ actionpack (4.1.0.beta)
+ actionview (= 4.1.0.beta)
+ activesupport (= 4.1.0.beta)
+ rack (~> 1.5.2)
+ rack-test (~> 0.6.2)
+ actionview (4.1.0.beta)
+ activemodel (= 4.1.0.beta)
+ activesupport (= 4.1.0.beta)
+ builder (~> 3.1.0)
+ erubis (~> 2.7.0)
+ activemodel (4.1.0.beta)
+ activesupport (= 4.1.0.beta)
+ builder (~> 3.1.0)
+ activerecord (4.1.0.beta)
+ activemodel (= 4.1.0.beta)
+ activerecord-deprecated_finders (~> 1.0.2)
+ activesupport (= 4.1.0.beta)
+ arel (~> 4.0.0)
+ activesupport (4.1.0.beta)
+ i18n (~> 0.6, >= 0.6.4)
+ json (~> 1.7)
+ minitest (~> 5.0)
+ thread_safe (~> 0.1)
+ tzinfo (~> 0.3.37)
+
+GEM
+ remote: https://rubygems.org/
+ specs:
+ arel (4.0.0)
+ atomic (1.1.9)
+ builder (3.1.4)
+ columnize (0.3.6)
+ debugger (1.6.0)
+ columnize (>= 0.3.1)
+ debugger-linecache (~> 1.2.0)
+ debugger-ruby_core_source (~> 1.2.1)
+ debugger-linecache (1.2.0)
+ debugger-ruby_core_source (1.2.2)
+ diff-lcs (1.1.3)
+ erubis (2.7.0)
+ i18n (0.6.4)
+ json (1.8.0)
+ linecache (0.46)
+ rbx-require-relative (> 0.0.4)
+ minitest (5.0.5)
+ mocha (0.9.12)
+ mysql (2.9.1)
+ mysql2 (0.3.11)
+ pg (0.15.1)
+ rack (1.5.2)
+ rack-test (0.6.2)
+ rack (>= 1.0)
+ rbx-require-relative (0.0.9)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+ ruby-debug (0.10.4)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.4.0)
+ ruby-debug-base (0.10.4)
+ linecache (>= 0.3)
+ sqlite3 (1.3.7)
+ thread_safe (0.1.0)
+ atomic
+ tzinfo (0.3.37)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ actionpack!
+ activerecord!
+ activerecord-deprecated_finders!
+ debugger
+ journey!
+ mocha (~> 0.9.8)
+ mysql (~> 2.9)
+ mysql2 (~> 0.3.10)
+ pg (~> 0.11)
+ rspec (~> 2.6.0)
+ ruby-debug
+ sqlite3 (~> 1.3.6)
+ thread_safe
diff --git a/vendor/plugins/will_paginate/Gemfile.rails3.0 b/vendor/plugins/will_paginate/Gemfile.rails3.0
new file mode 100644
index 0000000..68de9d9
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails3.0
@@ -0,0 +1,19 @@
+source 'http://rubygems.org'
+
+rails_version = '~> 3.0.0'
+
+gem 'activerecord', rails_version
+gem 'actionpack', rails_version
+
+gem 'rspec', '~> 2.6.0'
+gem 'mocha', '~> 0.9.8'
+
+gem 'sqlite3', '~> 1.3.3'
+
+gem 'mysql', '~> 2.8.1', :group => :mysql
+gem 'pg', '~> 0.11', :group => :pg
+
+group :development do
+ gem 'ruby-debug', :platforms => :mri_18
+ gem 'debugger', :platforms => :mri_19
+end
diff --git a/vendor/plugins/will_paginate/Gemfile.rails3.0.lock b/vendor/plugins/will_paginate/Gemfile.rails3.0.lock
new file mode 100644
index 0000000..83fd353
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails3.0.lock
@@ -0,0 +1,78 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ abstract (1.0.0)
+ actionpack (3.0.19)
+ activemodel (= 3.0.19)
+ activesupport (= 3.0.19)
+ builder (~> 2.1.2)
+ erubis (~> 2.6.6)
+ i18n (~> 0.5.0)
+ rack (~> 1.2.5)
+ rack-mount (~> 0.6.14)
+ rack-test (~> 0.5.7)
+ tzinfo (~> 0.3.23)
+ activemodel (3.0.19)
+ activesupport (= 3.0.19)
+ builder (~> 2.1.2)
+ i18n (~> 0.5.0)
+ activerecord (3.0.19)
+ activemodel (= 3.0.19)
+ activesupport (= 3.0.19)
+ arel (~> 2.0.10)
+ tzinfo (~> 0.3.23)
+ activesupport (3.0.19)
+ arel (2.0.10)
+ builder (2.1.2)
+ columnize (0.3.4)
+ debugger (1.2.2)
+ columnize (>= 0.3.1)
+ debugger-linecache (~> 1.1.1)
+ debugger-ruby_core_source (~> 1.1.5)
+ debugger-linecache (1.1.2)
+ debugger-ruby_core_source (>= 1.1.1)
+ debugger-ruby_core_source (1.1.5)
+ diff-lcs (1.1.2)
+ erubis (2.6.6)
+ abstract (>= 1.0.0)
+ i18n (0.5.0)
+ linecache (0.46)
+ rbx-require-relative (> 0.0.4)
+ mocha (0.9.12)
+ mysql (2.8.1)
+ pg (0.11.0)
+ rack (1.2.6)
+ rack-mount (0.6.14)
+ rack (>= 1.0.0)
+ rack-test (0.5.7)
+ rack (>= 1.0)
+ rbx-require-relative (0.0.5)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+ ruby-debug (0.10.4)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.4.0)
+ ruby-debug-base (0.10.4)
+ linecache (>= 0.3)
+ sqlite3 (1.3.4)
+ tzinfo (0.3.35)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ actionpack (~> 3.0.0)
+ activerecord (~> 3.0.0)
+ debugger
+ mocha (~> 0.9.8)
+ mysql (~> 2.8.1)
+ pg (~> 0.11)
+ rspec (~> 2.6.0)
+ ruby-debug
+ sqlite3 (~> 1.3.3)
diff --git a/vendor/plugins/will_paginate/Gemfile.rails3.1 b/vendor/plugins/will_paginate/Gemfile.rails3.1
new file mode 100644
index 0000000..fba6cde
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails3.1
@@ -0,0 +1,22 @@
+source 'http://rubygems.org'
+
+rails_version = '~> 3.1.0'
+
+gem 'activerecord', rails_version
+gem 'actionpack', rails_version
+
+gem 'rspec', '~> 2.6.0'
+gem 'mocha', '~> 0.9.8'
+
+gem 'sqlite3', '~> 1.3.3'
+
+group :mysql do
+ gem 'mysql', '~> 2.8.1'
+ gem 'mysql2', '>= 0.3.6'
+end
+gem 'pg', '~> 0.11', :group => :pg
+
+group :development do
+ gem 'ruby-debug', :platforms => :mri_18
+ gem 'debugger', :platforms => :mri_19
+end
diff --git a/vendor/plugins/will_paginate/Gemfile.rails3.1.lock b/vendor/plugins/will_paginate/Gemfile.rails3.1.lock
new file mode 100644
index 0000000..1987891
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails3.1.lock
@@ -0,0 +1,93 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ actionpack (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ builder (~> 3.0.0)
+ erubis (~> 2.7.0)
+ i18n (~> 0.6)
+ rack (~> 1.3.6)
+ rack-cache (~> 1.2)
+ rack-mount (~> 0.8.2)
+ rack-test (~> 0.6.1)
+ sprockets (~> 2.0.4)
+ activemodel (3.1.12)
+ activesupport (= 3.1.12)
+ builder (~> 3.0.0)
+ i18n (~> 0.6)
+ activerecord (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ arel (~> 2.2.3)
+ tzinfo (~> 0.3.29)
+ activesupport (3.1.12)
+ multi_json (~> 1.0)
+ arel (2.2.3)
+ builder (3.0.4)
+ columnize (0.3.6)
+ debugger (1.2.2)
+ columnize (>= 0.3.1)
+ debugger-linecache (~> 1.1.1)
+ debugger-ruby_core_source (~> 1.1.5)
+ debugger-linecache (1.1.2)
+ debugger-ruby_core_source (>= 1.1.1)
+ debugger-ruby_core_source (1.1.5)
+ diff-lcs (1.1.3)
+ erubis (2.7.0)
+ hike (1.2.3)
+ i18n (0.6.4)
+ linecache (0.46)
+ rbx-require-relative (> 0.0.4)
+ mocha (0.9.12)
+ multi_json (1.7.7)
+ mysql (2.8.1)
+ mysql2 (0.3.11)
+ pg (0.12.0)
+ rake-compiler (~> 0.7)
+ rack (1.3.10)
+ rack-cache (1.2)
+ rack (>= 0.4)
+ rack-mount (0.8.3)
+ rack (>= 1.0.0)
+ rack-test (0.6.2)
+ rack (>= 1.0)
+ rake (0.9.2.2)
+ rake-compiler (0.7.9)
+ rake
+ rbx-require-relative (0.0.5)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+ ruby-debug (0.10.4)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.4.0)
+ ruby-debug-base (0.10.4)
+ linecache (>= 0.3)
+ sprockets (2.0.4)
+ hike (~> 1.2)
+ rack (~> 1.0)
+ tilt (~> 1.1, != 1.3.0)
+ sqlite3 (1.3.5)
+ tilt (1.4.1)
+ tzinfo (0.3.37)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ actionpack (~> 3.1.0)
+ activerecord (~> 3.1.0)
+ debugger
+ mocha (~> 0.9.8)
+ mysql (~> 2.8.1)
+ mysql2 (>= 0.3.6)
+ pg (~> 0.11)
+ rspec (~> 2.6.0)
+ ruby-debug
+ sqlite3 (~> 1.3.3)
diff --git a/vendor/plugins/will_paginate/Gemfile.rails3.2 b/vendor/plugins/will_paginate/Gemfile.rails3.2
new file mode 100644
index 0000000..3ace7e0
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails3.2
@@ -0,0 +1,28 @@
+source 'http://rubygems.org'
+
+rails_version = '~> 3.2.0'
+
+gem 'activerecord', rails_version
+gem 'actionpack', rails_version
+
+gem 'rspec', '~> 2.6.0'
+gem 'mocha', '~> 0.9.8'
+
+gem 'sequel', '~> 3.8'
+gem 'sqlite3', '~> 1.3.3'
+gem 'dm-core'
+gem 'dm-aggregates'
+gem 'dm-migrations'
+gem 'dm-sqlite-adapter'
+gem 'mongoid'
+
+group :mysql do
+ gem 'mysql', '~> 2.8.1'
+ gem 'mysql2', '>= 0.3.6'
+end
+gem 'pg', '~> 0.11', :group => :pg
+
+group :development do
+ gem 'ruby-debug', :platforms => :mri_18
+ gem 'debugger', :platforms => :mri_19
+end
diff --git a/vendor/plugins/will_paginate/Gemfile.rails3.2.lock b/vendor/plugins/will_paginate/Gemfile.rails3.2.lock
new file mode 100644
index 0000000..fc4bf3c
--- /dev/null
+++ b/vendor/plugins/will_paginate/Gemfile.rails3.2.lock
@@ -0,0 +1,123 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ actionpack (3.2.13)
+ activemodel (= 3.2.13)
+ activesupport (= 3.2.13)
+ builder (~> 3.0.0)
+ erubis (~> 2.7.0)
+ journey (~> 1.0.4)
+ rack (~> 1.4.5)
+ rack-cache (~> 1.2)
+ rack-test (~> 0.6.1)
+ sprockets (~> 2.2.1)
+ activemodel (3.2.13)
+ activesupport (= 3.2.13)
+ builder (~> 3.0.0)
+ activerecord (3.2.13)
+ activemodel (= 3.2.13)
+ activesupport (= 3.2.13)
+ arel (~> 3.0.2)
+ tzinfo (~> 0.3.29)
+ activesupport (3.2.13)
+ i18n (= 0.6.1)
+ multi_json (~> 1.0)
+ addressable (2.2.6)
+ arel (3.0.2)
+ bson (1.6.4)
+ builder (3.0.4)
+ columnize (0.3.5)
+ data_objects (0.10.7)
+ addressable (~> 2.1)
+ debugger (1.2.2)
+ columnize (>= 0.3.1)
+ debugger-linecache (~> 1.1.1)
+ debugger-ruby_core_source (~> 1.1.5)
+ debugger-linecache (1.1.2)
+ debugger-ruby_core_source (>= 1.1.1)
+ debugger-ruby_core_source (1.1.5)
+ diff-lcs (1.1.3)
+ dm-aggregates (1.2.0)
+ dm-core (~> 1.2.0)
+ dm-core (1.2.0)
+ addressable (~> 2.2.6)
+ dm-do-adapter (1.2.0)
+ data_objects (~> 0.10.6)
+ dm-core (~> 1.2.0)
+ dm-migrations (1.2.0)
+ dm-core (~> 1.2.0)
+ dm-sqlite-adapter (1.2.0)
+ dm-do-adapter (~> 1.2.0)
+ do_sqlite3 (~> 0.10.6)
+ do_sqlite3 (0.10.7)
+ data_objects (= 0.10.7)
+ erubis (2.7.0)
+ hike (1.2.3)
+ i18n (0.6.1)
+ journey (1.0.4)
+ linecache (0.46)
+ rbx-require-relative (> 0.0.4)
+ mocha (0.9.12)
+ mongo (1.6.2)
+ bson (~> 1.6.2)
+ mongoid (2.4.11)
+ activemodel (~> 3.1)
+ mongo (<= 1.6.2)
+ tzinfo (~> 0.3.22)
+ multi_json (1.7.7)
+ mysql (2.8.1)
+ mysql2 (0.3.11)
+ pg (0.12.0)
+ rake-compiler (~> 0.7)
+ rack (1.4.5)
+ rack-cache (1.2)
+ rack (>= 0.4)
+ rack-test (0.6.2)
+ rack (>= 1.0)
+ rake (0.9.2.2)
+ rake-compiler (0.7.9)
+ rake
+ rbx-require-relative (0.0.5)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+ ruby-debug (0.10.4)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.4.0)
+ ruby-debug-base (0.10.4)
+ linecache (>= 0.3)
+ sequel (3.30.0)
+ sprockets (2.2.2)
+ hike (~> 1.2)
+ multi_json (~> 1.0)
+ rack (~> 1.0)
+ tilt (~> 1.1, != 1.3.0)
+ sqlite3 (1.3.5)
+ tilt (1.4.1)
+ tzinfo (0.3.37)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ actionpack (~> 3.2.0)
+ activerecord (~> 3.2.0)
+ debugger
+ dm-aggregates
+ dm-core
+ dm-migrations
+ dm-sqlite-adapter
+ mocha (~> 0.9.8)
+ mongoid
+ mysql (~> 2.8.1)
+ mysql2 (>= 0.3.6)
+ pg (~> 0.11)
+ rspec (~> 2.6.0)
+ ruby-debug
+ sequel (~> 3.8)
+ sqlite3 (~> 1.3.3)
diff --git a/vendor/plugins/will_paginate/LICENSE b/vendor/plugins/will_paginate/LICENSE
new file mode 100644
index 0000000..44c52a6
--- /dev/null
+++ b/vendor/plugins/will_paginate/LICENSE
@@ -0,0 +1,18 @@
+Copyright (c) 2009 Mislav Marohnić
+
+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.
diff --git a/vendor/plugins/will_paginate/README.md b/vendor/plugins/will_paginate/README.md
new file mode 100644
index 0000000..1a5ac51
--- /dev/null
+++ b/vendor/plugins/will_paginate/README.md
@@ -0,0 +1,61 @@
+# will_paginate
+
+will_paginate is a pagination library that integrates with Ruby on Rails, Sinatra, Merb, DataMapper and Sequel.
+
+Installation:
+
+``` ruby
+## Gemfile for Rails 3, Sinatra, and Merb
+gem 'will_paginate', '~> 3.0'
+```
+
+See [installation instructions][install] on the wiki for more info.
+
+
+## Basic will_paginate use
+
+``` ruby
+## perform a paginated query:
+@posts = Post.paginate(:page => params[:page])
+
+# or, use an explicit "per page" limit:
+Post.paginate(:page => params[:page], :per_page => 30)
+
+## render page links in the view:
+<%= will_paginate @posts %>
+```
+
+And that's it! You're done. You just need to add some CSS styles to [make those pagination links prettier][css].
+
+You can customize the default "per_page" value:
+
+``` ruby
+# for the Post model
+class Post
+ self.per_page = 10
+end
+
+# set per_page globally
+WillPaginate.per_page = 10
+```
+
+New in Active Record 3:
+
+``` ruby
+# paginate in Active Record now returns a Relation
+Post.where(:published => true).paginate(:page => params[:page]).order('id DESC')
+
+# the new, shorter page() method
+Post.page(params[:page]).order('created_at DESC')
+```
+
+See [the wiki][wiki] for more documentation. [Ask on the group][group] if you have usage questions. [Report bugs][issues] on GitHub.
+
+Happy paginating.
+
+
+[wiki]: https://github.com/mislav/will_paginate/wiki
+[install]: https://github.com/mislav/will_paginate/wiki/Installation "will_paginate installation"
+[group]: http://groups.google.com/group/will_paginate "will_paginate discussion and support group"
+[issues]: https://github.com/mislav/will_paginate/issues
+[css]: http://mislav.uniqpath.com/will_paginate/
diff --git a/vendor/plugins/will_paginate/init.rb b/vendor/plugins/will_paginate/init.rb
new file mode 100644
index 0000000..dcaead0
--- /dev/null
+++ b/vendor/plugins/will_paginate/init.rb
@@ -0,0 +1,18 @@
+require 'will_paginate'
+
+# This is all duplication of what Railtie does, but is necessary because
+# the initializer defined by the Railtie won't ever run when loaded as plugin.
+
+if defined? ActiveRecord::Base
+ require 'will_paginate/active_record'
+end
+
+if defined? ActionController::Base
+ WillPaginate::Railtie.setup_actioncontroller
+end
+
+if defined? ActionView::Base
+ require 'will_paginate/view_helpers/action_view'
+end
+
+WillPaginate::Railtie.add_locale_path config
diff --git a/vendor/plugins/will_paginate/lib/will_paginate.rb b/vendor/plugins/will_paginate/lib/will_paginate.rb
new file mode 100644
index 0000000..5821d34
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate.rb
@@ -0,0 +1,25 @@
+# You will paginate!
+module WillPaginate
+end
+
+if defined?(Rails::Railtie)
+ require 'will_paginate/railtie'
+elsif defined?(Rails::Initializer)
+ raise "will_paginate 3.0 is not compatible with Rails 2.3 or older"
+end
+
+if defined?(Merb::AbstractController)
+ require 'will_paginate/view_helpers/merb'
+
+ Merb::BootLoader.before_app_loads do
+ adapters = { :datamapper => 'data_mapper', :activerecord => 'active_record', :sequel => 'sequel' }
+ # auto-load the right ORM adapter
+ if adapter = adapters[Merb.orm]
+ require "will_paginate/#{adapter}"
+ end
+ end
+end
+
+if defined?(Sinatra) and Sinatra.respond_to? :register
+ require 'will_paginate/view_helpers/sinatra'
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/active_record.rb b/vendor/plugins/will_paginate/lib/will_paginate/active_record.rb
new file mode 100644
index 0000000..9c14e81
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/active_record.rb
@@ -0,0 +1,247 @@
+require 'will_paginate/per_page'
+require 'will_paginate/page_number'
+require 'will_paginate/collection'
+require 'active_record'
+
+module WillPaginate
+ # = Paginating finders for ActiveRecord models
+ #
+ # WillPaginate adds +paginate+, +per_page+ and other methods to
+ # ActiveRecord::Base class methods and associations.
+ #
+ # In short, paginating finders are equivalent to ActiveRecord finders; the
+ # only difference is that we start with "paginate" instead of "find" and
+ # that :page is required parameter:
+ #
+ # @posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC'
+ #
+ module ActiveRecord
+ # makes a Relation look like WillPaginate::Collection
+ module RelationMethods
+ include WillPaginate::CollectionMethods
+
+ attr_accessor :current_page
+ attr_writer :total_entries, :wp_count_options
+
+ def per_page(value = nil)
+ if value.nil? then limit_value
+ else limit(value)
+ end
+ end
+
+ # TODO: solve with less relation clones and code dups
+ def limit(num)
+ rel = super
+ if rel.current_page
+ rel.offset rel.current_page.to_offset(rel.limit_value).to_i
+ else
+ rel
+ end
+ end
+
+ # dirty hack to enable `first` after `limit` behavior above
+ def first(*args)
+ if current_page
+ rel = clone
+ rel.current_page = nil
+ rel.first(*args)
+ else
+ super
+ end
+ end
+
+ # fix for Rails 3.0
+ def find_last
+ if !loaded? and offset_value || limit_value
+ @last ||= to_a.last
+ else
+ super
+ end
+ end
+
+ def offset(value = nil)
+ if value.nil? then offset_value
+ else super(value)
+ end
+ end
+
+ def total_entries
+ @total_entries ||= begin
+ if loaded? and size < limit_value and (current_page == 1 or size > 0)
+ offset_value + size
+ else
+ @total_entries_queried = true
+ result = count
+ result = result.size if result.respond_to?(:size) and !result.is_a?(Integer)
+ result
+ end
+ end
+ end
+
+ def count
+ if limit_value
+ excluded = [:order, :limit, :offset, :reorder]
+ excluded << :includes unless eager_loading?
+ rel = self.except(*excluded)
+ # TODO: hack. decide whether to keep
+ rel = rel.apply_finder_options(@wp_count_options) if defined? @wp_count_options
+ rel.count
+ else
+ super
+ end
+ end
+
+ # workaround for Active Record 3.0
+ def size
+ if !loaded? and limit_value and group_values.empty?
+ [super, limit_value].min
+ else
+ super
+ end
+ end
+
+ # overloaded to be pagination-aware
+ def empty?
+ if !loaded? and offset_value
+ result = count
+ result = result.size if result.respond_to?(:size) and !result.is_a?(Integer)
+ result <= offset_value
+ else
+ super
+ end
+ end
+
+ def clone
+ copy_will_paginate_data super
+ end
+
+ # workaround for Active Record 3.0
+ def scoped(options = nil)
+ copy_will_paginate_data super
+ end
+
+ def to_a
+ if current_page.nil? then super # workaround for Active Record 3.0
+ else
+ ::WillPaginate::Collection.create(current_page, limit_value) do |col|
+ col.replace super
+ col.total_entries ||= total_entries
+ end
+ end
+ end
+
+ private
+
+ def copy_will_paginate_data(other)
+ other.current_page = current_page unless other.current_page
+ other.total_entries = nil if defined? @total_entries_queried
+ other.wp_count_options = @wp_count_options if defined? @wp_count_options
+ other
+ end
+ end
+
+ module Pagination
+ def paginate(options)
+ options = options.dup
+ pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" }
+ per_page = options.delete(:per_page) || self.per_page
+ total = options.delete(:total_entries)
+
+ count_options = options.delete(:count)
+ options.delete(:page)
+
+ rel = limit(per_page.to_i).page(pagenum)
+ rel = rel.apply_finder_options(options) if options.any?
+ rel.wp_count_options = count_options if count_options
+ rel.total_entries = total.to_i unless total.blank?
+ rel
+ end
+
+ def page(num)
+ rel = if ::ActiveRecord::Relation === self
+ self
+ elsif !defined?(::ActiveRecord::Scoping) or ::ActiveRecord::Scoping::ClassMethods.method_defined? :with_scope
+ # Active Record 3
+ scoped
+ else
+ # Active Record 4
+ all
+ end
+
+ rel = rel.extending(RelationMethods)
+ pagenum = ::WillPaginate::PageNumber(num.nil? ? 1 : num)
+ per_page = rel.limit_value || self.per_page
+ rel = rel.offset(pagenum.to_offset(per_page).to_i)
+ rel = rel.limit(per_page) unless rel.limit_value
+ rel.current_page = pagenum
+ rel
+ end
+ end
+
+ module BaseMethods
+ # Wraps +find_by_sql+ by simply adding LIMIT and OFFSET to your SQL string
+ # based on the params otherwise used by paginating finds: +page+ and
+ # +per_page+.
+ #
+ # Example:
+ #
+ # @developers = Developer.paginate_by_sql ['select * from developers where salary > ?', 80000],
+ # :page => params[:page], :per_page => 3
+ #
+ # A query for counting rows will automatically be generated if you don't
+ # supply :total_entries. If you experience problems with this
+ # generated SQL, you might want to perform the count manually in your
+ # application.
+ #
+ def paginate_by_sql(sql, options)
+ pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" } || 1
+ per_page = options[:per_page] || self.per_page
+ total = options[:total_entries]
+
+ WillPaginate::Collection.create(pagenum, per_page, total) do |pager|
+ query = sanitize_sql(sql.dup)
+ original_query = query.dup
+ oracle = self.connection.adapter_name =~ /^(oracle|oci$)/i
+
+ # add limit, offset
+ if oracle
+ query = <<-SQL
+ SELECT * FROM (
+ SELECT rownum rnum, a.* FROM (#{query}) a
+ WHERE rownum <= #{pager.offset + pager.per_page}
+ ) WHERE rnum >= #{pager.offset}
+ SQL
+ else
+ query << " LIMIT #{pager.per_page} OFFSET #{pager.offset}"
+ end
+
+ # perfom the find
+ pager.replace find_by_sql(query)
+
+ unless pager.total_entries
+ count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s.]+$/mi, ''
+ count_query = "SELECT COUNT(*) FROM (#{count_query})"
+ count_query << ' AS count_table' unless oracle
+ # perform the count query
+ pager.total_entries = count_by_sql(count_query)
+ end
+ end
+ end
+ end
+
+ # mix everything into Active Record
+ ::ActiveRecord::Base.extend PerPage
+ ::ActiveRecord::Base.extend Pagination
+ ::ActiveRecord::Base.extend BaseMethods
+
+ klasses = [::ActiveRecord::Relation]
+ if defined? ::ActiveRecord::Associations::CollectionProxy
+ klasses << ::ActiveRecord::Associations::CollectionProxy
+ else
+ klasses << ::ActiveRecord::Associations::AssociationCollection
+ end
+
+ # support pagination on associations and scopes
+ klasses.each { |klass| klass.send(:include, Pagination) }
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/array.rb b/vendor/plugins/will_paginate/lib/will_paginate/array.rb
new file mode 100644
index 0000000..e3dbf6c
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/array.rb
@@ -0,0 +1,33 @@
+require 'will_paginate/collection'
+
+class Array
+ # Paginates a static array (extracting a subset of it). The result is a
+ # WillPaginate::Collection instance, which is an array with a few more
+ # properties about its paginated state.
+ #
+ # Parameters:
+ # * :page - current page, defaults to 1
+ # * :per_page - limit of items per page, defaults to 30
+ # * :total_entries - total number of items in the array, defaults to
+ # array.length (obviously)
+ #
+ # Example:
+ # arr = ['a', 'b', 'c', 'd', 'e']
+ # paged = arr.paginate(:per_page => 2) #-> ['a', 'b']
+ # paged.total_entries #-> 5
+ # arr.paginate(:page => 2, :per_page => 2) #-> ['c', 'd']
+ # arr.paginate(:page => 3, :per_page => 2) #-> ['e']
+ #
+ # This method was originally {suggested by Desi
+ # McAdam}[http://www.desimcadam.com/archives/8] and later proved to be the
+ # most useful method of will_paginate library.
+ def paginate(options = {})
+ page = options[:page] || 1
+ per_page = options[:per_page] || WillPaginate.per_page
+ total = options[:total_entries] || self.length
+
+ WillPaginate::Collection.create(page, per_page, total) do |pager|
+ pager.replace self[pager.offset, pager.per_page].to_a
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/collection.rb b/vendor/plugins/will_paginate/lib/will_paginate/collection.rb
new file mode 100644
index 0000000..720c722
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/collection.rb
@@ -0,0 +1,136 @@
+require 'will_paginate/per_page'
+require 'will_paginate/page_number'
+
+module WillPaginate
+ # Any will_paginate-compatible collection should have these methods:
+ #
+ # current_page, per_page, offset, total_entries, total_pages
+ #
+ # It can also define some of these optional methods:
+ #
+ # out_of_bounds?, previous_page, next_page
+ #
+ # This module provides few of these methods.
+ module CollectionMethods
+ def total_pages
+ total_entries.zero? ? 1 : (total_entries / per_page.to_f).ceil
+ end
+
+ # current_page - 1 or nil if there is no previous page
+ def previous_page
+ current_page > 1 ? (current_page - 1) : nil
+ end
+
+ # current_page + 1 or nil if there is no next page
+ def next_page
+ current_page < total_pages ? (current_page + 1) : nil
+ end
+
+ # Helper method that is true when someone tries to fetch a page with a
+ # larger number than the last page. Can be used in combination with flashes
+ # and redirecting.
+ def out_of_bounds?
+ current_page > total_pages
+ end
+ end
+
+ # = The key to pagination
+ # Arrays returned from paginating finds are, in fact, instances of this little
+ # class. You may think of WillPaginate::Collection as an ordinary array with
+ # some extra properties. Those properties are used by view helpers to generate
+ # correct page links.
+ #
+ # WillPaginate::Collection also assists in rolling out your own pagination
+ # solutions: see +create+.
+ #
+ # If you are writing a library that provides a collection which you would like
+ # to conform to this API, you don't have to copy these methods over; simply
+ # make your plugin/gem dependant on this library and do:
+ #
+ # require 'will_paginate/collection'
+ # # WillPaginate::Collection is now available for use
+ class Collection < Array
+ include CollectionMethods
+
+ attr_reader :current_page, :per_page, :total_entries
+
+ # Arguments to the constructor are the current page number, per-page limit
+ # and the total number of entries. The last argument is optional because it
+ # is best to do lazy counting; in other words, count *conditionally* after
+ # populating the collection using the +replace+ method.
+ def initialize(page, per_page = WillPaginate.per_page, total = nil)
+ @current_page = WillPaginate::PageNumber(page)
+ @per_page = per_page.to_i
+ self.total_entries = total if total
+ end
+
+ # Just like +new+, but yields the object after instantiation and returns it
+ # afterwards. This is very useful for manual pagination:
+ #
+ # @entries = WillPaginate::Collection.create(1, 10) do |pager|
+ # result = Post.find(:all, :limit => pager.per_page, :offset => pager.offset)
+ # # inject the result array into the paginated collection:
+ # pager.replace(result)
+ #
+ # unless pager.total_entries
+ # # the pager didn't manage to guess the total count, do it manually
+ # pager.total_entries = Post.count
+ # end
+ # end
+ #
+ # The possibilities with this are endless. For another example, here is how
+ # WillPaginate used to define pagination for Array instances:
+ #
+ # Array.class_eval do
+ # def paginate(page = 1, per_page = 15)
+ # WillPaginate::Collection.create(page, per_page, size) do |pager|
+ # pager.replace self[pager.offset, pager.per_page].to_a
+ # end
+ # end
+ # end
+ #
+ # The Array#paginate API has since then changed, but this still serves as a
+ # fine example of WillPaginate::Collection usage.
+ def self.create(page, per_page, total = nil)
+ pager = new(page, per_page, total)
+ yield pager
+ pager
+ end
+
+ # Current offset of the paginated collection. If we're on the first page,
+ # it is always 0. If we're on the 2nd page and there are 30 entries per page,
+ # the offset is 30. This property is useful if you want to render ordinals
+ # side by side with records in the view: simply start with offset + 1.
+ def offset
+ current_page.to_offset(per_page).to_i
+ end
+
+ def total_entries=(number)
+ @total_entries = number.to_i
+ end
+
+ # This is a magic wrapper for the original Array#replace method. It serves
+ # for populating the paginated collection after initialization.
+ #
+ # Why magic? Because it tries to guess the total number of entries judging
+ # by the size of given array. If it is shorter than +per_page+ limit, then we
+ # know we're on the last page. This trick is very useful for avoiding
+ # unnecessary hits to the database to do the counting after we fetched the
+ # data for the current page.
+ #
+ # However, after using +replace+ you should always test the value of
+ # +total_entries+ and set it to a proper value if it's +nil+. See the example
+ # in +create+.
+ def replace(array)
+ result = super
+
+ # The collection is shorter then page limit? Rejoice, because
+ # then we know that we are on the last page!
+ if total_entries.nil? and length < per_page and (current_page == 1 or length > 0)
+ self.total_entries = offset + length
+ end
+
+ result
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb b/vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb
new file mode 100644
index 0000000..7de066c
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb
@@ -0,0 +1,30 @@
+require 'set'
+
+# copied from ActiveSupport so we don't depend on it
+
+unless Hash.method_defined? :except
+ Hash.class_eval do
+ # Returns a new hash without the given keys.
+ def except(*keys)
+ rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
+ reject { |key,| rejected.include?(key) }
+ end
+
+ # Replaces the hash without only the given keys.
+ def except!(*keys)
+ replace(except(*keys))
+ end
+ end
+end
+
+unless String.method_defined? :underscore
+ String.class_eval do
+ def underscore
+ self.to_s.gsub(/::/, '/').
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
+ tr("-", "_").
+ downcase
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/data_mapper.rb b/vendor/plugins/will_paginate/lib/will_paginate/data_mapper.rb
new file mode 100644
index 0000000..13f4364
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/data_mapper.rb
@@ -0,0 +1,95 @@
+require 'dm-core'
+require 'dm-aggregates'
+require 'will_paginate/per_page'
+require 'will_paginate/page_number'
+require 'will_paginate/collection'
+
+module WillPaginate
+ module DataMapper
+ module Pagination
+ def page(num)
+ pagenum = ::WillPaginate::PageNumber(num.nil? ? 1 : num)
+ per_page = query.limit || self.per_page
+ options = {:offset => pagenum.to_offset(per_page).to_i}
+ options[:limit] = per_page unless query.limit
+ col = new_collection(query.merge(options))
+ col.current_page = pagenum
+ col
+ end
+
+ def paginate(options)
+ options = options.dup
+ pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" }
+ per_page = options.delete(:per_page) || self.per_page
+
+ options.delete(:page)
+ options[:limit] = per_page.to_i
+
+ all(options).page(pagenum)
+ end
+ end
+
+ module CollectionMethods
+ include WillPaginate::CollectionMethods
+
+ attr_accessor :current_page
+
+ def paginated?
+ !current_page.nil?
+ end
+
+ def per_page
+ query.limit || model.per_page
+ end
+
+ def offset
+ query.offset
+ end
+
+ def total_entries
+ @total_entries ||= begin
+ if loaded? and @array.size < per_page and (current_page == 1 or @array.size > 0)
+ offset + @array.size
+ else
+ # :reload prevents Collection.filter from being run, which
+ # would cause a stack overflow
+ clean_query = query.merge(:reload => true)
+ # seems like the only way
+ clean_query.instance_variable_set('@limit', nil)
+ clean_query.instance_variable_set('@offset', 0)
+ new_collection(clean_query).count
+ end
+ end
+ end
+
+ def to_a
+ if paginated?
+ ::WillPaginate::Collection.create(current_page, per_page) do |col|
+ col.replace super
+ col.total_entries ||= total_entries
+ end
+ else
+ super
+ end
+ end
+
+ private
+
+ def new_collection(query, resources = nil)
+ col = super
+ col.current_page = self.current_page
+ col
+ end
+
+ def initialize_copy(original)
+ super
+ @total_entries = nil
+ end
+ end
+
+ ::DataMapper::Model.append_extensions PerPage
+ ::DataMapper::Model.append_extensions Pagination
+ ::DataMapper::Collection.send(:include, Pagination)
+ ::DataMapper::Collection.send(:include, CollectionMethods)
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/deprecation.rb b/vendor/plugins/will_paginate/lib/will_paginate/deprecation.rb
new file mode 100644
index 0000000..aa66e6a
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/deprecation.rb
@@ -0,0 +1,55 @@
+module WillPaginate::Deprecation
+ class << self
+ def warn(message, stack = caller)
+ offending_line = origin_of_call(stack)
+ full_message = "DEPRECATION WARNING: #{message} (called from #{offending_line})"
+ logger = rails_logger || Kernel
+ logger.warn full_message
+ end
+
+ private
+
+ def rails_logger
+ defined?(Rails) && Rails.logger
+ end
+
+ def origin_of_call(stack)
+ lib_root = File.expand_path('../../..', __FILE__)
+ stack.find { |line| line.index(lib_root) != 0 } || stack.first
+ end
+ end
+
+ class Hash < ::Hash
+ def initialize(values = {})
+ super()
+ update values
+ @deprecated = {}
+ end
+
+ def []=(key, value)
+ check_deprecated(key, value)
+ super
+ end
+
+ def deprecate_key(*keys)
+ message = block_given? ? Proc.new : keys.pop
+ Array(keys).each { |key| @deprecated[key] = message }
+ end
+
+ def merge(another)
+ to_hash.update(another)
+ end
+
+ def to_hash
+ ::Hash.new.update(self)
+ end
+
+ private
+
+ def check_deprecated(key, value)
+ if msg = @deprecated[key] and (!msg.respond_to?(:call) or (msg = msg.call(key, value)))
+ WillPaginate::Deprecation.warn(msg)
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/i18n.rb b/vendor/plugins/will_paginate/lib/will_paginate/i18n.rb
new file mode 100644
index 0000000..3443caf
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/i18n.rb
@@ -0,0 +1,22 @@
+module WillPaginate
+ module I18n
+ def self.locale_dir
+ File.expand_path('../locale', __FILE__)
+ end
+
+ def self.load_path
+ Dir["#{locale_dir}/*.{rb,yml}"]
+ end
+
+ def will_paginate_translate(keys, options = {})
+ if defined? ::I18n
+ defaults = Array(keys).dup
+ defaults << Proc.new if block_given?
+ ::I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => :will_paginate))
+ else
+ key = Array === keys ? keys.first : keys
+ yield key, options
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/mongoid.rb b/vendor/plugins/will_paginate/lib/will_paginate/mongoid.rb
new file mode 100644
index 0000000..5792412
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/mongoid.rb
@@ -0,0 +1,46 @@
+require 'mongoid'
+require 'will_paginate/collection'
+
+module WillPaginate
+ module Mongoid
+ module CriteriaMethods
+ def paginate(options = {})
+ extend CollectionMethods
+ @current_page = WillPaginate::PageNumber(options[:page] || @current_page || 1)
+ @page_multiplier = current_page - 1
+ pp = (options[:per_page] || per_page || WillPaginate.per_page).to_i
+ limit(pp).skip(@page_multiplier * pp)
+ end
+
+ def per_page(value = :non_given)
+ if value == :non_given
+ options[:limit] == 0 ? nil : options[:limit] # in new Mongoid versions a nil limit is saved as 0
+ else
+ limit(value)
+ end
+ end
+
+ def page(page)
+ paginate(:page => page)
+ end
+ end
+
+ module CollectionMethods
+ attr_reader :current_page
+
+ def total_entries
+ @total_entries ||= count
+ end
+
+ def total_pages
+ (total_entries / per_page.to_f).ceil
+ end
+
+ def offset
+ @page_multiplier * per_page
+ end
+ end
+
+ ::Mongoid::Criteria.send(:include, CriteriaMethods)
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/page_number.rb b/vendor/plugins/will_paginate/lib/will_paginate/page_number.rb
new file mode 100644
index 0000000..7883b12
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/page_number.rb
@@ -0,0 +1,57 @@
+require 'delegate'
+require 'forwardable'
+
+module WillPaginate
+ # a module that page number exceptions are tagged with
+ module InvalidPage; end
+
+ # integer representing a page number
+ class PageNumber < DelegateClass(Integer)
+ # a value larger than this is not supported in SQL queries
+ BIGINT = 9223372036854775807
+
+ extend Forwardable
+
+ def initialize(value, name)
+ value = Integer(value)
+ if 'offset' == name ? (value < 0 or value > BIGINT) : value < 1
+ raise RangeError, "invalid #{name}: #{value.inspect}"
+ end
+ @name = name
+ super(value)
+ rescue ArgumentError, TypeError, RangeError => error
+ error.extend InvalidPage
+ raise error
+ end
+
+ alias_method :to_i, :__getobj__
+
+ def inspect
+ "#{@name} #{to_i}"
+ end
+
+ def to_offset(per_page)
+ PageNumber.new((to_i - 1) * per_page.to_i, 'offset')
+ end
+
+ def kind_of?(klass)
+ super || to_i.kind_of?(klass)
+ end
+ alias is_a? kind_of?
+ end
+
+ # Ultrahax: makes `Fixnum === current_page` checks pass
+ Numeric.extend Module.new {
+ def ===(obj)
+ obj.instance_of? PageNumber or super
+ end
+ }
+
+ # An idemptotent coercion method
+ def self.PageNumber(value, name = 'page')
+ case value
+ when PageNumber then value
+ else PageNumber.new(value, name)
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/per_page.rb b/vendor/plugins/will_paginate/lib/will_paginate/per_page.rb
new file mode 100644
index 0000000..29303e1
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/per_page.rb
@@ -0,0 +1,27 @@
+module WillPaginate
+ module PerPage
+ def per_page
+ defined?(@per_page) ? @per_page : WillPaginate.per_page
+ end
+
+ def per_page=(limit)
+ @per_page = limit.to_i
+ end
+
+ def self.extended(base)
+ base.extend Inheritance if base.is_a? Class
+ end
+
+ module Inheritance
+ def inherited(subclass)
+ super
+ subclass.per_page = self.per_page
+ end
+ end
+ end
+
+ extend PerPage
+
+ # default number of items per page
+ self.per_page = 30
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/railtie.rb b/vendor/plugins/will_paginate/lib/will_paginate/railtie.rb
new file mode 100644
index 0000000..72137fd
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/railtie.rb
@@ -0,0 +1,68 @@
+require 'will_paginate'
+require 'will_paginate/page_number'
+require 'will_paginate/collection'
+require 'will_paginate/i18n'
+
+module WillPaginate
+ class Railtie < Rails::Railtie
+ initializer "will_paginate" do |app|
+ ActiveSupport.on_load :active_record do
+ require 'will_paginate/active_record'
+ end
+
+ ActiveSupport.on_load :action_controller do
+ WillPaginate::Railtie.setup_actioncontroller
+ end
+
+ ActiveSupport.on_load :action_view do
+ require 'will_paginate/view_helpers/action_view'
+ end
+
+ self.class.add_locale_path config
+
+ # early access to ViewHelpers.pagination_options
+ require 'will_paginate/view_helpers'
+ end
+
+ def self.setup_actioncontroller
+ ( defined?(ActionDispatch::ExceptionWrapper) ?
+ ActionDispatch::ExceptionWrapper : ActionDispatch::ShowExceptions
+ ).send :include, ShowExceptionsPatch
+ ActionController::Base.extend ControllerRescuePatch
+ end
+
+ def self.add_locale_path(config)
+ config.i18n.railties_load_path.unshift(*WillPaginate::I18n.load_path)
+ end
+
+ # Extending the exception handler middleware so it properly detects
+ # WillPaginate::InvalidPage regardless of it being a tag module.
+ module ShowExceptionsPatch
+ extend ActiveSupport::Concern
+ included { alias_method_chain :status_code, :paginate }
+ def status_code_with_paginate(exception = @exception)
+ if exception.is_a?(WillPaginate::InvalidPage) or
+ (exception.respond_to?(:original_exception) &&
+ exception.original_exception.is_a?(WillPaginate::InvalidPage))
+ Rack::Utils.status_code(:not_found)
+ else
+ original_method = method(:status_code_without_paginate)
+ if original_method.arity != 0
+ original_method.call(exception)
+ else
+ original_method.call()
+ end
+ end
+ end
+ end
+
+ module ControllerRescuePatch
+ def rescue_from(*args, &block)
+ if idx = args.index(WillPaginate::InvalidPage)
+ args[idx] = args[idx].name
+ end
+ super(*args, &block)
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/sequel.rb b/vendor/plugins/will_paginate/lib/will_paginate/sequel.rb
new file mode 100644
index 0000000..07f794d
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/sequel.rb
@@ -0,0 +1,39 @@
+require 'sequel'
+require 'sequel/extensions/pagination'
+require 'will_paginate/collection'
+
+module WillPaginate
+ # Sequel already supports pagination; we only need to make the
+ # resulting dataset look a bit more like WillPaginate::Collection
+ module SequelMethods
+ include WillPaginate::CollectionMethods
+
+ def total_pages
+ page_count
+ end
+
+ def per_page
+ page_size
+ end
+
+ def size
+ current_page_record_count
+ end
+ alias length size
+
+ def total_entries
+ pagination_record_count
+ end
+
+ def out_of_bounds?
+ current_page > total_pages
+ end
+
+ # Current offset of the paginated collection
+ def offset
+ (current_page - 1) * per_page
+ end
+ end
+
+ Sequel::Dataset::Pagination.send(:include, SequelMethods)
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/version.rb b/vendor/plugins/will_paginate/lib/will_paginate/version.rb
new file mode 100644
index 0000000..6084a4a
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/version.rb
@@ -0,0 +1,9 @@
+module WillPaginate #:nodoc:
+ module VERSION #:nodoc:
+ MAJOR = 3
+ MINOR = 0
+ TINY = 4
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb
new file mode 100644
index 0000000..089f5bf
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb
@@ -0,0 +1,162 @@
+# encoding: utf-8
+require 'will_paginate/core_ext'
+require 'will_paginate/i18n'
+require 'will_paginate/deprecation'
+
+module WillPaginate
+ # = Will Paginate view helpers
+ #
+ # The main view helper is +will_paginate+. It renders the pagination links
+ # for the given collection. The helper itself is lightweight and serves only
+ # as a wrapper around LinkRenderer instantiation; the renderer then does
+ # all the hard work of generating the HTML.
+ module ViewHelpers
+ class << self
+ # Write to this hash to override default options on the global level:
+ #
+ # WillPaginate::ViewHelpers.pagination_options[:page_links] = false
+ #
+ attr_accessor :pagination_options
+ end
+
+ # default view options
+ self.pagination_options = Deprecation::Hash.new \
+ :class => 'pagination',
+ :previous_label => nil,
+ :next_label => nil,
+ :inner_window => 4, # links around the current page
+ :outer_window => 1, # links around beginning and end
+ :link_separator => ' ', # single space is friendly to spiders and non-graphic browsers
+ :param_name => :page,
+ :params => nil,
+ :page_links => true,
+ :container => true
+
+ label_deprecation = Proc.new { |key, value|
+ "set the 'will_paginate.#{key}' key in your i18n locale instead of editing pagination_options" if defined? Rails
+ }
+ pagination_options.deprecate_key(:previous_label, :next_label, &label_deprecation)
+ pagination_options.deprecate_key(:renderer) { |key, _| "pagination_options[#{key.inspect}] shouldn't be set globally" }
+
+ include WillPaginate::I18n
+
+ # Returns HTML representing page links for a WillPaginate::Collection-like object.
+ # In case there is no more than one page in total, nil is returned.
+ #
+ # ==== Options
+ # * :class -- CSS class name for the generated DIV (default: "pagination")
+ # * :previous_label -- default: "« Previous"
+ # * :next_label -- default: "Next »"
+ # * :inner_window -- how many links are shown around the current page (default: 4)
+ # * :outer_window -- how many links are around the first and the last page (default: 1)
+ # * :link_separator -- string separator for page HTML elements (default: single space)
+ # * :param_name -- parameter name for page number in URLs (default: :page)
+ # * :params -- additional parameters when generating pagination links
+ # (eg. :controller => "foo", :action => nil)
+ # * :renderer -- class name, class or instance of a link renderer (default in Rails:
+ # WillPaginate::ActionView::LinkRenderer)
+ # * :page_links -- when false, only previous/next links are rendered (default: true)
+ # * :container -- toggles rendering of the DIV container for pagination links, set to
+ # false only when you are rendering your own pagination markup (default: true)
+ #
+ # All options not recognized by will_paginate will become HTML attributes on the container
+ # element for pagination links (the DIV). For example:
+ #
+ # <%= will_paginate @posts, :style => 'color:blue' %>
+ #
+ # will result in:
+ #
+ #
+ #
+ def will_paginate(collection, options = {})
+ # early exit if there is nothing to render
+ return nil unless collection.total_pages > 1
+
+ options = WillPaginate::ViewHelpers.pagination_options.merge(options)
+
+ options[:previous_label] ||= will_paginate_translate(:previous_label) { '← Previous' }
+ options[:next_label] ||= will_paginate_translate(:next_label) { 'Next →' }
+
+ # get the renderer instance
+ renderer = case options[:renderer]
+ when nil
+ raise ArgumentError, ":renderer not specified"
+ when String
+ klass = if options[:renderer].respond_to? :constantize then options[:renderer].constantize
+ else Object.const_get(options[:renderer]) # poor man's constantize
+ end
+ klass.new
+ when Class then options[:renderer].new
+ else options[:renderer]
+ end
+ # render HTML for pagination
+ renderer.prepare collection, options, self
+ output = renderer.to_html
+ output = output.html_safe if output.respond_to?(:html_safe)
+ output
+ end
+
+ # Renders a message containing number of displayed vs. total entries.
+ #
+ # <%= page_entries_info @posts %>
+ # #-> Displaying posts 6 - 12 of 26 in total
+ #
+ # The default output contains HTML. Use ":html => false" for plain text.
+ def page_entries_info(collection, options = {})
+ model = options[:model]
+ model = collection.first.class unless model or collection.empty?
+ model ||= 'entry'
+ model_key = if model.respond_to? :model_name
+ model.model_name.i18n_key # ActiveModel::Naming
+ else
+ model.to_s.underscore
+ end
+
+ if options.fetch(:html, true)
+ b, eb = '', ''
+ sp = ' '
+ html_key = '_html'
+ else
+ b = eb = html_key = ''
+ sp = ' '
+ end
+
+ model_count = collection.total_pages > 1 ? 5 : collection.size
+ defaults = ["models.#{model_key}"]
+ defaults << Proc.new { |_, opts|
+ if model.respond_to? :model_name
+ model.model_name.human(:count => opts[:count])
+ else
+ name = model_key.to_s.tr('_', ' ')
+ raise "can't pluralize model name: #{model.inspect}" unless name.respond_to? :pluralize
+ opts[:count] == 1 ? name : name.pluralize
+ end
+ }
+ model_name = will_paginate_translate defaults, :count => model_count
+
+ if collection.total_pages < 2
+ i18n_key = :"page_entries_info.single_page#{html_key}"
+ keys = [:"#{model_key}.#{i18n_key}", i18n_key]
+
+ will_paginate_translate keys, :count => collection.total_entries, :model => model_name do |_, opts|
+ case opts[:count]
+ when 0; "No #{opts[:model]} found"
+ when 1; "Displaying #{b}1#{eb} #{opts[:model]}"
+ else "Displaying #{b}all#{sp}#{opts[:count]}#{eb} #{opts[:model]}"
+ end
+ end
+ else
+ i18n_key = :"page_entries_info.multi_page#{html_key}"
+ keys = [:"#{model_key}.#{i18n_key}", i18n_key]
+ params = {
+ :model => model_name, :count => collection.total_entries,
+ :from => collection.offset + 1, :to => collection.offset + collection.length
+ }
+ will_paginate_translate keys, params do |_, opts|
+ %{Displaying %s #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} %
+ [ opts[:model], opts[:from], opts[:to], opts[:count] ]
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/action_view.rb b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/action_view.rb
new file mode 100644
index 0000000..6fa2929
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/action_view.rb
@@ -0,0 +1,148 @@
+require 'will_paginate/view_helpers'
+require 'will_paginate/view_helpers/link_renderer'
+
+module WillPaginate
+ # = ActionView helpers
+ #
+ # This module serves for availability in ActionView templates. It also adds a new
+ # view helper: +paginated_section+.
+ #
+ # == Using the helper without arguments
+ # If the helper is called without passing in the collection object, it will
+ # try to read from the instance variable inferred by the controller name.
+ # For example, calling +will_paginate+ while the current controller is
+ # PostsController will result in trying to read from the @posts
+ # variable. Example:
+ #
+ # <%= will_paginate :id => true %>
+ #
+ # ... will result in @post collection getting paginated:
+ #
+ #
+ #
+ module ActionView
+ include ViewHelpers
+
+ def will_paginate(collection = nil, options = {}) #:nodoc:
+ options, collection = collection, nil if collection.is_a? Hash
+ collection ||= infer_collection_from_controller
+
+ options = options.symbolize_keys
+ options[:renderer] ||= LinkRenderer
+
+ super(collection, options)
+ end
+
+ def page_entries_info(collection = nil, options = {}) #:nodoc:
+ options, collection = collection, nil if collection.is_a? Hash
+ collection ||= infer_collection_from_controller
+
+ super(collection, options.symbolize_keys)
+ end
+
+ # Wrapper for rendering pagination links at both top and bottom of a block
+ # of content.
+ #
+ # <% paginated_section @posts do %>
+ #
+ # <% for post in @posts %>
+ # - ...
+ # <% end %>
+ #
+ # <% end %>
+ #
+ # will result in:
+ #
+ #
+ #
+ # ...
+ #
+ #
+ #
+ # Arguments are passed to a will_paginate call, so the same options
+ # apply. Don't use the :id option; otherwise you'll finish with two
+ # blocks of pagination links sharing the same ID (which is invalid HTML).
+ def paginated_section(*args, &block)
+ pagination = will_paginate(*args)
+ if pagination
+ pagination + capture(&block) + pagination
+ else
+ capture(&block)
+ end
+ end
+
+ def will_paginate_translate(keys, options = {})
+ if respond_to? :translate
+ if Array === keys
+ defaults = keys.dup
+ key = defaults.shift
+ else
+ defaults = nil
+ key = keys
+ end
+ translate(key, options.merge(:default => defaults, :scope => :will_paginate))
+ else
+ super
+ end
+ end
+
+ protected
+
+ def infer_collection_from_controller
+ collection_name = "@#{controller.controller_name}"
+ collection = instance_variable_get(collection_name)
+ raise ArgumentError, "The #{collection_name} variable appears to be empty. Did you " +
+ "forget to pass the collection object for will_paginate?" if collection.nil?
+ collection
+ end
+
+ class LinkRenderer < ViewHelpers::LinkRenderer
+ protected
+
+ def default_url_params
+ {}
+ end
+
+ def url(page)
+ @base_url_params ||= begin
+ url_params = merge_get_params(default_url_params)
+ merge_optional_params(url_params)
+ end
+
+ url_params = @base_url_params.dup
+ add_current_page_param(url_params, page)
+
+ @template.url_for(url_params)
+ end
+
+ def merge_get_params(url_params)
+ if @template.respond_to? :request and @template.request and @template.request.get?
+ symbolized_update(url_params, @template.params)
+ end
+ url_params
+ end
+
+ def merge_optional_params(url_params)
+ symbolized_update(url_params, @options[:params]) if @options[:params]
+ url_params
+ end
+
+ def add_current_page_param(url_params, page)
+ unless param_name.index(/[^\w-]/)
+ url_params[param_name.to_sym] = page
+ else
+ page_param = parse_query_parameters("#{param_name}=#{page}")
+ symbolized_update(url_params, page_param)
+ end
+ end
+
+ private
+
+ def parse_query_parameters(params)
+ Rack::Utils.parse_nested_query(params)
+ end
+ end
+
+ ::ActionView::Base.send :include, self
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer.rb b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer.rb
new file mode 100644
index 0000000..d1745f8
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer.rb
@@ -0,0 +1,131 @@
+require 'cgi'
+require 'will_paginate/core_ext'
+require 'will_paginate/view_helpers'
+require 'will_paginate/view_helpers/link_renderer_base'
+
+module WillPaginate
+ module ViewHelpers
+ # This class does the heavy lifting of actually building the pagination
+ # links. It is used by +will_paginate+ helper internally.
+ class LinkRenderer < LinkRendererBase
+
+ # * +collection+ is a WillPaginate::Collection instance or any other object
+ # that conforms to that API
+ # * +options+ are forwarded from +will_paginate+ view helper
+ # * +template+ is the reference to the template being rendered
+ def prepare(collection, options, template)
+ super(collection, options)
+ @template = template
+ @container_attributes = @base_url_params = nil
+ end
+
+ # Process it! This method returns the complete HTML string which contains
+ # pagination links. Feel free to subclass LinkRenderer and change this
+ # method as you see fit.
+ def to_html
+ html = pagination.map do |item|
+ item.is_a?(Fixnum) ?
+ page_number(item) :
+ send(item)
+ end.join(@options[:link_separator])
+
+ @options[:container] ? html_container(html) : html
+ end
+
+ # Returns the subset of +options+ this instance was initialized with that
+ # represent HTML attributes for the container element of pagination links.
+ def container_attributes
+ @container_attributes ||= @options.except(*(ViewHelpers.pagination_options.keys + [:renderer] - [:class]))
+ end
+
+ protected
+
+ def page_number(page)
+ unless page == current_page
+ link(page, page, :rel => rel_value(page))
+ else
+ tag(:em, page, :class => 'current')
+ end
+ end
+
+ def gap
+ text = @template.will_paginate_translate(:page_gap) { '…' }
+ %(#{text})
+ end
+
+ def previous_page
+ num = @collection.current_page > 1 && @collection.current_page - 1
+ previous_or_next_page(num, @options[:previous_label], 'previous_page')
+ end
+
+ def next_page
+ num = @collection.current_page < total_pages && @collection.current_page + 1
+ previous_or_next_page(num, @options[:next_label], 'next_page')
+ end
+
+ def previous_or_next_page(page, text, classname)
+ if page
+ link(text, page, :class => classname)
+ else
+ tag(:span, text, :class => classname + ' disabled')
+ end
+ end
+
+ def html_container(html)
+ tag(:div, html, container_attributes)
+ end
+
+ # Returns URL params for +page_link_or_span+, taking the current GET params
+ # and :params option into account.
+ def url(page)
+ raise NotImplementedError
+ end
+
+ private
+
+ def param_name
+ @options[:param_name].to_s
+ end
+
+ def link(text, target, attributes = {})
+ if target.is_a? Fixnum
+ attributes[:rel] = rel_value(target)
+ target = url(target)
+ end
+ attributes[:href] = target
+ tag(:a, text, attributes)
+ end
+
+ def tag(name, value, attributes = {})
+ string_attributes = attributes.inject('') do |attrs, pair|
+ unless pair.last.nil?
+ attrs << %( #{pair.first}="#{CGI::escapeHTML(pair.last.to_s)}")
+ end
+ attrs
+ end
+ "<#{name}#{string_attributes}>#{value}#{name}>"
+ end
+
+ def rel_value(page)
+ case page
+ when @collection.current_page - 1; 'prev' + (page == 1 ? ' start' : '')
+ when @collection.current_page + 1; 'next'
+ when 1; 'start'
+ end
+ end
+
+ def symbolized_update(target, other)
+ other.each do |key, value|
+ key = key.to_sym
+ existing = target[key]
+
+ if value.is_a?(Hash) and (existing.is_a?(Hash) or existing.nil?)
+ symbolized_update(existing || (target[key] = {}), value)
+ else
+ target[key] = value
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer_base.rb b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer_base.rb
new file mode 100644
index 0000000..385b1b2
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer_base.rb
@@ -0,0 +1,77 @@
+module WillPaginate
+ module ViewHelpers
+ # This class does the heavy lifting of actually building the pagination
+ # links. It is used by +will_paginate+ helper internally.
+ class LinkRendererBase
+
+ # * +collection+ is a WillPaginate::Collection instance or any other object
+ # that conforms to that API
+ # * +options+ are forwarded from +will_paginate+ view helper
+ def prepare(collection, options)
+ @collection = collection
+ @options = options
+
+ # reset values in case we're re-using this instance
+ @total_pages = nil
+ end
+
+ def pagination
+ items = @options[:page_links] ? windowed_page_numbers : []
+ items.unshift :previous_page
+ items.push :next_page
+ end
+
+ protected
+
+ # Calculates visible page numbers using the :inner_window and
+ # :outer_window options.
+ def windowed_page_numbers
+ inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i
+ window_from = current_page - inner_window
+ window_to = current_page + inner_window
+
+ # adjust lower or upper limit if other is out of bounds
+ if window_to > total_pages
+ window_from -= window_to - total_pages
+ window_to = total_pages
+ end
+ if window_from < 1
+ window_to += 1 - window_from
+ window_from = 1
+ window_to = total_pages if window_to > total_pages
+ end
+
+ # these are always visible
+ middle = window_from..window_to
+
+ # left window
+ if outer_window + 3 < middle.first # there's a gap
+ left = (1..(outer_window + 1)).to_a
+ left << :gap
+ else # runs into visible pages
+ left = 1...middle.first
+ end
+
+ # right window
+ if total_pages - outer_window - 2 > middle.last # again, gap
+ right = ((total_pages - outer_window)..total_pages).to_a
+ right.unshift :gap
+ else # runs into visible pages
+ right = (middle.last + 1)..total_pages
+ end
+
+ left.to_a + middle.to_a + right.to_a
+ end
+
+ private
+
+ def current_page
+ @collection.current_page
+ end
+
+ def total_pages
+ @total_pages ||= @collection.total_pages
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/merb.rb b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/merb.rb
new file mode 100644
index 0000000..d9b3a6b
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/merb.rb
@@ -0,0 +1,26 @@
+require 'will_paginate/core_ext'
+require 'will_paginate/view_helpers'
+require 'will_paginate/view_helpers/link_renderer'
+
+module WillPaginate
+ module Merb
+ include ViewHelpers
+
+ def will_paginate(collection, options = {}) #:nodoc:
+ options = options.merge(:renderer => LinkRenderer) unless options[:renderer]
+ super(collection, options)
+ end
+
+ class LinkRenderer < ViewHelpers::LinkRenderer
+ protected
+
+ def url(page)
+ params = @template.request.params.except(:action, :controller).merge(param_name => page)
+ @template.url(:this, params)
+ end
+ end
+
+ ::Merb::AbstractController.send(:include, self)
+ end
+end
+
diff --git a/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/sinatra.rb b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/sinatra.rb
new file mode 100644
index 0000000..2ba17f8
--- /dev/null
+++ b/vendor/plugins/will_paginate/lib/will_paginate/view_helpers/sinatra.rb
@@ -0,0 +1,41 @@
+require 'sinatra/base'
+require 'will_paginate/view_helpers'
+require 'will_paginate/view_helpers/link_renderer'
+
+module WillPaginate
+ module Sinatra
+ module Helpers
+ include ViewHelpers
+
+ def will_paginate(collection, options = {}) #:nodoc:
+ options = options.merge(:renderer => LinkRenderer) unless options[:renderer]
+ super(collection, options)
+ end
+ end
+
+ class LinkRenderer < ViewHelpers::LinkRenderer
+ protected
+
+ def url(page)
+ str = File.join(request.script_name.to_s, request.path_info)
+ params = request.GET.merge(param_name.to_s => page.to_s)
+ params.update @options[:params] if @options[:params]
+ str << '?' << build_query(params)
+ end
+
+ def request
+ @template.request
+ end
+
+ def build_query(params)
+ Rack::Utils.build_nested_query params
+ end
+ end
+
+ def self.registered(app)
+ app.helpers Helpers
+ end
+
+ ::Sinatra.register self
+ end
+end
diff --git a/vendor/plugins/will_paginate/script/each-gemfile b/vendor/plugins/will_paginate/script/each-gemfile
new file mode 100755
index 0000000..09bd47f
--- /dev/null
+++ b/vendor/plugins/will_paginate/script/each-gemfile
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+set -e
+
+if [ -z "$1" ]; then
+ echo "Usage: script/each-bundle COMMAND []" >&2
+ exit 1
+fi
+
+for gemfile in $(ls Gemfile* | grep -v lock); do
+ printf "\e[31m[%s]\e[0m\n" $gemfile
+ BUNDLE_GEMFILE=$gemfile "$@"
+done
diff --git a/vendor/plugins/will_paginate/script/test_all b/vendor/plugins/will_paginate/script/test_all
new file mode 100755
index 0000000..c8db215
--- /dev/null
+++ b/vendor/plugins/will_paginate/script/test_all
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+status=0
+
+run_all(){
+ spec_files="spec"
+ [[ $DB != "sqlite3" ]] && spec_files="spec/finders/active_record_spec.rb"
+ set -x
+ rspec -r fake_rubygems $spec_files
+ set +x
+}
+
+export PATH="${PWD}/bin:$PATH"
+
+for db in sqlite3 mysql mysql2 postgres; do
+ if ! [[ $db = "mysql2" && $BUNDLE_GEMFILE =~ "rails3.0" ]]; then
+ printf "\e[1;33m[DB] ${db}\e[m\n"
+ DB=$db run_all || status=1
+ fi
+done
+
+exit $status
diff --git a/vendor/plugins/will_paginate/spec/collection_spec.rb b/vendor/plugins/will_paginate/spec/collection_spec.rb
new file mode 100644
index 0000000..d561e83
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/collection_spec.rb
@@ -0,0 +1,139 @@
+require 'will_paginate/array'
+require 'spec_helper'
+
+describe WillPaginate::Collection do
+
+ before :all do
+ @simple = ('a'..'e').to_a
+ end
+
+ it "should be a subset of original collection" do
+ @simple.paginate(:page => 1, :per_page => 3).should == %w( a b c )
+ end
+
+ it "can be shorter than per_page if on last page" do
+ @simple.paginate(:page => 2, :per_page => 3).should == %w( d e )
+ end
+
+ it "should include whole collection if per_page permits" do
+ @simple.paginate(:page => 1, :per_page => 5).should == @simple
+ end
+
+ it "should be empty if out of bounds" do
+ @simple.paginate(:page => 2, :per_page => 5).should be_empty
+ end
+
+ it "should default to 1 as current page and 30 per-page" do
+ result = (1..50).to_a.paginate
+ result.current_page.should == 1
+ result.size.should == 30
+ end
+
+ it "should give total_entries precedence over actual size" do
+ %w(a b c).paginate(:total_entries => 5).total_entries.should == 5
+ end
+
+ it "should be an augmented Array" do
+ entries = %w(a b c)
+ collection = create(2, 3, 10) do |pager|
+ pager.replace(entries).should == entries
+ end
+
+ collection.should == entries
+ for method in %w(total_pages each offset size current_page per_page total_entries)
+ collection.should respond_to(method)
+ end
+ collection.should be_kind_of(Array)
+ collection.entries.should be_instance_of(Array)
+ # TODO: move to another expectation:
+ collection.offset.should == 3
+ collection.total_pages.should == 4
+ collection.should_not be_out_of_bounds
+ end
+
+ describe "previous/next pages" do
+ it "should have previous_page nil when on first page" do
+ collection = create(1, 1, 3)
+ collection.previous_page.should be_nil
+ collection.next_page.should == 2
+ end
+
+ it "should have both prev/next pages" do
+ collection = create(2, 1, 3)
+ collection.previous_page.should == 1
+ collection.next_page.should == 3
+ end
+
+ it "should have next_page nil when on last page" do
+ collection = create(3, 1, 3)
+ collection.previous_page.should == 2
+ collection.next_page.should be_nil
+ end
+ end
+
+ describe "out of bounds" do
+ it "is out of bounds when page number is too high" do
+ create(2, 3, 2).should be_out_of_bounds
+ end
+
+ it "isn't out of bounds when inside collection" do
+ create(1, 3, 2).should_not be_out_of_bounds
+ end
+
+ it "isn't out of bounds when the collection is empty" do
+ collection = create(1, 3, 0)
+ collection.should_not be_out_of_bounds
+ collection.total_pages.should == 1
+ end
+ end
+
+ describe "guessing total count" do
+ it "can guess when collection is shorter than limit" do
+ collection = create { |p| p.replace array }
+ collection.total_entries.should == 8
+ end
+
+ it "should allow explicit total count to override guessed" do
+ collection = create(2, 5, 10) { |p| p.replace array }
+ collection.total_entries.should == 10
+ end
+
+ it "should not be able to guess when collection is same as limit" do
+ collection = create { |p| p.replace array(5) }
+ collection.total_entries.should be_nil
+ end
+
+ it "should not be able to guess when collection is empty" do
+ collection = create { |p| p.replace array(0) }
+ collection.total_entries.should be_nil
+ end
+
+ it "should be able to guess when collection is empty and this is the first page" do
+ collection = create(1) { |p| p.replace array(0) }
+ collection.total_entries.should == 0
+ end
+ end
+
+ it "should not respond to page_count anymore" do
+ Proc.new { create.page_count }.should raise_error(NoMethodError)
+ end
+
+ it "inherits per_page from global value" do
+ collection = described_class.new(1)
+ collection.per_page.should == 30
+ end
+
+ private
+
+ def create(page = 2, limit = 5, total = nil, &block)
+ if block_given?
+ described_class.create(page, limit, total, &block)
+ else
+ described_class.new(page, limit, total)
+ end
+ end
+
+ def array(size = 3)
+ Array.new(size)
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/console b/vendor/plugins/will_paginate/spec/console
new file mode 100755
index 0000000..4c64785
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/console
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
+opts = %w[ --simple-prompt -rirb/completion ]
+if ARGV.include? '-dm'
+ opts << '-rwill_paginate/data_mapper' << '-rfinders/data_mapper_test_connector'
+elsif ARGV.include? '-seq'
+ opts << '-rwill_paginate/sequel' << '-rfinders/sequel_test_connector'
+else
+ opts << '-rconsole_fixtures'
+end
+
+exec 'bundle', 'exec', irb, '-Ilib:spec', *opts
diff --git a/vendor/plugins/will_paginate/spec/console_fixtures.rb b/vendor/plugins/will_paginate/spec/console_fixtures.rb
new file mode 100644
index 0000000..40b41d1
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/console_fixtures.rb
@@ -0,0 +1,28 @@
+require 'bundler'
+Bundler.setup
+
+require 'will_paginate/active_record'
+require 'finders/activerecord_test_connector'
+
+ActiverecordTestConnector.setup
+
+windows = RUBY_PLATFORM =~ /(:?mswin|mingw)/
+# used just for the `color` method
+log_subscriber = ActiveSupport::LogSubscriber.log_subscribers.first
+
+IGNORE_SQL = /\b(sqlite_master|sqlite_version)\b|^(CREATE TABLE|PRAGMA)\b/
+
+ActiveSupport::Notifications.subscribe(/^sql\./) do |*args|
+ data = args.last
+ unless data[:name] =~ /^Fixture/ or data[:sql] =~ IGNORE_SQL
+ if windows
+ puts data[:sql]
+ else
+ puts log_subscriber.send(:color, data[:sql], :cyan)
+ end
+ end
+end
+
+# load all fixtures
+ActiverecordTestConnector::Fixtures.create_fixtures \
+ ActiverecordTestConnector::FIXTURES_PATH, ActiveRecord::Base.connection.tables
diff --git a/vendor/plugins/will_paginate/spec/database.yml b/vendor/plugins/will_paginate/spec/database.yml
new file mode 100644
index 0000000..87ca11b
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/database.yml
@@ -0,0 +1,22 @@
+sqlite3:
+ database: ":memory:"
+ adapter: sqlite3
+ timeout: 500
+
+mysql:
+ adapter: mysql
+ database: will_paginate
+ username:
+ encoding: utf8
+
+mysql2:
+ adapter: mysql2
+ database: will_paginate
+ username:
+ encoding: utf8
+
+postgres:
+ adapter: postgresql
+ database: will_paginate
+ username: postgres
+ min_messages: warning
diff --git a/vendor/plugins/will_paginate/spec/fake_rubygems.rb b/vendor/plugins/will_paginate/spec/fake_rubygems.rb
new file mode 100644
index 0000000..04df569
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fake_rubygems.rb
@@ -0,0 +1,18 @@
+# Makes the test suite compatible with Bundler standalone mode (used in CI)
+# because Active Record uses `gem` for loading adapters.
+Kernel.module_eval do
+
+ remove_method :gem if 'method' == defined? gem
+
+ def gem(*args)
+ return if $VERBOSE.nil?
+ $stderr << "warning: gem(#{args.map {|o| o.inspect }.join(', ')}) ignored"
+ $stderr << "; called from:\n " << caller[0,5].join("\n ") if $DEBUG
+ $stderr << "\n"
+ end
+
+ private :gem
+
+end
+
+$" << "rubygems.rb"
diff --git a/vendor/plugins/will_paginate/spec/finders/active_record_spec.rb b/vendor/plugins/will_paginate/spec/finders/active_record_spec.rb
new file mode 100644
index 0000000..c3a6c11
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/active_record_spec.rb
@@ -0,0 +1,561 @@
+require 'spec_helper'
+require 'will_paginate/active_record'
+require File.expand_path('../activerecord_test_connector', __FILE__)
+
+ActiverecordTestConnector.setup
+abort unless ActiverecordTestConnector.able_to_connect
+
+describe WillPaginate::ActiveRecord do
+
+ extend ActiverecordTestConnector::FixtureSetup
+
+ fixtures :topics, :replies, :users, :projects, :developers_projects
+
+ it "should integrate with ActiveRecord::Base" do
+ ActiveRecord::Base.should respond_to(:paginate)
+ end
+
+ it "should paginate" do
+ lambda {
+ users = User.paginate(:page => 1, :per_page => 5).to_a
+ users.length.should == 5
+ }.should run_queries(2)
+ end
+
+ it "should fail when encountering unknown params" do
+ lambda {
+ User.paginate :foo => 'bar', :page => 1, :per_page => 4
+ }.should raise_error(ArgumentError)
+ end
+
+ describe "relation" do
+ it "should return a relation" do
+ rel = nil
+ lambda {
+ rel = Developer.paginate(:page => 1)
+ rel.per_page.should == 10
+ rel.current_page.should == 1
+ }.should run_queries(0)
+
+ lambda {
+ rel.total_pages.should == 2
+ }.should run_queries(1)
+ end
+
+ it "should keep per-class per_page number" do
+ rel = Developer.order('id').paginate(:page => 1)
+ rel.per_page.should == 10
+ end
+
+ it "should be able to change per_page number" do
+ rel = Developer.order('id').paginate(:page => 1).limit(5)
+ rel.per_page.should == 5
+ end
+
+ it "remembers pagination in sub-relations" do
+ rel = Topic.paginate(:page => 2, :per_page => 3)
+ lambda {
+ rel.total_entries.should == 4
+ }.should run_queries(1)
+ rel = rel.mentions_activerecord
+ rel.current_page.should == 2
+ rel.per_page.should == 3
+ lambda {
+ rel.total_entries.should == 1
+ }.should run_queries(1)
+ end
+
+ it "supports the page() method" do
+ rel = Developer.page('1').order('id')
+ rel.current_page.should == 1
+ rel.per_page.should == 10
+ rel.offset.should == 0
+
+ rel = rel.limit(5).page(2)
+ rel.per_page.should == 5
+ rel.offset.should == 5
+ end
+
+ it "raises on invalid page number" do
+ lambda {
+ Developer.page('foo')
+ }.should raise_error(ArgumentError)
+ end
+
+ it "supports first limit() then page()" do
+ rel = Developer.limit(3).page(3)
+ rel.offset.should == 6
+ end
+
+ it "supports first page() then limit()" do
+ rel = Developer.page(3).limit(3)
+ rel.offset.should == 6
+ end
+
+ it "supports #first" do
+ rel = Developer.order('id').page(2).per_page(4)
+ rel.first.should == users(:dev_5)
+ rel.first(2).should == users(:dev_5, :dev_6)
+ end
+
+ it "supports #last" do
+ rel = Developer.order('id').page(2).per_page(4)
+ rel.last.should == users(:dev_8)
+ rel.last(2).should == users(:dev_7, :dev_8)
+ rel.page(3).last.should == users(:poor_jamis)
+ end
+
+ it "keeps pagination data after 'scoped'" do
+ rel = Developer.page(2).scoped
+ rel.per_page.should == 10
+ rel.offset.should == 10
+ rel.current_page.should == 2
+ end
+ end
+
+ describe "counting" do
+ it "should guess the total count" do
+ lambda {
+ topics = Topic.paginate :page => 2, :per_page => 3
+ topics.total_entries.should == 4
+ }.should run_queries(1)
+ end
+
+ it "should guess that there are no records" do
+ lambda {
+ topics = Topic.where(:project_id => 999).paginate :page => 1, :per_page => 3
+ topics.total_entries.should == 0
+ }.should run_queries(1)
+ end
+
+ it "forgets count in sub-relations" do
+ lambda {
+ topics = Topic.paginate :page => 1, :per_page => 3
+ topics.total_entries.should == 4
+ topics.where('1 = 1').total_entries.should == 4
+ }.should run_queries(2)
+ end
+
+ it "remembers custom count options in sub-relations" do
+ topics = Topic.paginate :page => 1, :per_page => 3, :count => {:conditions => "title LIKE '%futurama%'"}
+ topics.total_entries.should == 1
+ topics.length.should == 3
+ lambda {
+ topics.order('id').total_entries.should == 1
+ }.should run_queries(1)
+ end
+
+ it "supports empty? method" do
+ topics = Topic.paginate :page => 1, :per_page => 3
+ lambda {
+ topics.should_not be_empty
+ }.should run_queries(1)
+ end
+
+ it "support empty? for grouped queries" do
+ topics = Topic.group(:project_id).paginate :page => 1, :per_page => 3
+ lambda {
+ topics.should_not be_empty
+ }.should run_queries(1)
+ end
+
+ it "supports `size` for grouped queries" do
+ topics = Topic.group(:project_id).paginate :page => 1, :per_page => 3
+ lambda {
+ topics.size.should == {nil=>2, 1=>2}
+ }.should run_queries(1)
+ end
+
+ it "overrides total_entries count with a fixed value" do
+ lambda {
+ topics = Topic.paginate :page => 1, :per_page => 3, :total_entries => 999
+ topics.total_entries.should == 999
+ # value is kept even in sub-relations
+ topics.where('1 = 1').total_entries.should == 999
+ }.should run_queries(0)
+ end
+
+ it "supports a non-int for total_entries" do
+ topics = Topic.paginate :page => 1, :per_page => 3, :total_entries => "999"
+ topics.total_entries.should == 999
+ end
+
+ it "removes :include for count" do
+ lambda {
+ developers = Developer.paginate(:page => 1, :per_page => 1).includes(:projects)
+ developers.total_entries.should == 11
+ $query_sql.last.should_not =~ /\bJOIN\b/
+ }.should run_queries(1)
+ end
+
+ it "keeps :include for count when they are referenced in :conditions" do
+ developers = Developer.paginate(:page => 1, :per_page => 1).includes(:projects)
+ with_condition = developers.where('projects.id > 1')
+ with_condition.total_entries.should == 1
+
+ $query_sql.last.should =~ /\bJOIN\b/
+ end
+
+ it "should count with group" do
+ Developer.group(:salary).page(1).total_entries.should == 4
+ end
+
+ it "removes :reorder for count with group" do
+ Project.group(:id).reorder(:id).page(1).total_entries
+ $query_sql.last.should_not =~ /\ORDER\b/
+ end
+
+ it "should not have zero total_pages when the result set is empty" do
+ Developer.where("1 = 2").page(1).total_pages.should == 1
+ end
+ end
+
+ it "should not ignore :select parameter when it says DISTINCT" do
+ users = User.select('DISTINCT salary').paginate :page => 2
+ users.total_entries.should == 5
+ end
+
+ describe "paginate_by_sql" do
+ it "should respond" do
+ User.should respond_to(:paginate_by_sql)
+ end
+
+ it "should paginate" do
+ lambda {
+ sql = "select content from topics where content like '%futurama%'"
+ topics = Topic.paginate_by_sql sql, :page => 1, :per_page => 1
+ topics.total_entries.should == 1
+ topics.first.attributes.has_key?('title').should be_false
+ }.should run_queries(2)
+ end
+
+ it "should respect total_entries setting" do
+ lambda {
+ sql = "select content from topics"
+ topics = Topic.paginate_by_sql sql, :page => 1, :per_page => 1, :total_entries => 999
+ topics.total_entries.should == 999
+ }.should run_queries(1)
+ end
+
+ it "defaults to page 1" do
+ sql = "select content from topics"
+ topics = Topic.paginate_by_sql sql, :page => nil, :per_page => 1
+ topics.current_page.should == 1
+ topics.size.should == 1
+ end
+
+ it "should strip the order when counting" do
+ lambda {
+ sql = "select id, title, content from topics order by topics.title"
+ topics = Topic.paginate_by_sql sql, :page => 1, :per_page => 2
+ topics.first.should == topics(:ar)
+ }.should run_queries(2)
+
+ $query_sql.last.should include('COUNT')
+ $query_sql.last.should_not include('order by topics.title')
+ end
+
+ it "shouldn't change the original query string" do
+ query = 'select * from topics where 1 = 2'
+ original_query = query.dup
+ Topic.paginate_by_sql(query, :page => 1)
+ query.should == original_query
+ end
+ end
+
+ it "doesn't mangle options" do
+ options = { :page => 1 }
+ options.expects(:delete).never
+ options_before = options.dup
+
+ Topic.paginate(options)
+ options.should == options_before
+ end
+
+ it "should get first page of Topics with a single query" do
+ lambda {
+ result = Topic.paginate :page => nil
+ result.to_a # trigger loading of records
+ result.current_page.should == 1
+ result.total_pages.should == 1
+ result.size.should == 4
+ }.should run_queries(1)
+ end
+
+ it "should get second (inexistent) page of Topics, requiring 2 queries" do
+ lambda {
+ result = Topic.paginate :page => 2
+ result.total_pages.should == 1
+ result.should be_empty
+ }.should run_queries(2)
+ end
+
+ it "should paginate with :order" do
+ result = Topic.paginate :page => 1, :order => 'created_at DESC'
+ result.should == topics(:futurama, :harvey_birdman, :rails, :ar).reverse
+ result.total_pages.should == 1
+ end
+
+ it "should paginate with :conditions" do
+ result = Topic.paginate :page => 1, :order => 'id ASC',
+ :conditions => ["created_at > ?", 30.minutes.ago]
+ result.should == topics(:rails, :ar)
+ result.total_pages.should == 1
+ end
+
+ it "should paginate with :include and :conditions" do
+ result = Topic.paginate \
+ :page => 1,
+ :include => :replies,
+ :conditions => "replies.content LIKE 'Bird%' ",
+ :per_page => 10
+
+ expected = Topic.find :all,
+ :include => 'replies',
+ :conditions => "replies.content LIKE 'Bird%' ",
+ :limit => 10
+
+ result.should == expected
+ result.total_entries.should == 1
+ end
+
+ it "should paginate with :include and :order" do
+ result = nil
+ lambda {
+ result = Topic.paginate(:page => 1, :include => :replies, :per_page => 10,
+ :order => 'replies.created_at asc, topics.created_at asc').to_a
+ }.should run_queries(2)
+
+ expected = Topic.find :all,
+ :include => 'replies',
+ :order => 'replies.created_at asc, topics.created_at asc',
+ :limit => 10
+
+ result.should == expected
+ result.total_entries.should == 4
+ end
+
+ describe "associations" do
+ it "should paginate with include" do
+ project = projects(:active_record)
+
+ result = project.topics.paginate \
+ :page => 1,
+ :include => :replies,
+ :conditions => ["replies.content LIKE ?", 'Nice%'],
+ :per_page => 10
+
+ expected = Topic.find :all,
+ :include => 'replies',
+ :conditions => ["project_id = ? AND replies.content LIKE ?", project.id, 'Nice%'],
+ :limit => 10
+
+ result.should == expected
+ end
+
+ it "should paginate" do
+ dhh = users(:david)
+ expected_name_ordered = projects(:action_controller, :active_record)
+ expected_id_ordered = projects(:active_record, :action_controller)
+
+ lambda {
+ # with association-specified order
+ result = ignore_deprecation { dhh.projects.paginate(:page => 1) }
+ result.should == expected_name_ordered
+ result.total_entries.should == 2
+ }.should run_queries(2)
+
+ # with explicit order
+ result = dhh.projects.paginate(:page => 1).reorder('projects.id')
+ result.should == expected_id_ordered
+ result.total_entries.should == 2
+
+ lambda {
+ dhh.projects.find(:all, :order => 'projects.id', :limit => 4)
+ }.should_not raise_error
+
+ result = dhh.projects.paginate(:page => 1, :per_page => 4).reorder('projects.id')
+ result.should == expected_id_ordered
+
+ # has_many with implicit order
+ topic = Topic.find(1)
+ expected = replies(:spam, :witty_retort)
+ # FIXME: wow, this is ugly
+ topic.replies.paginate(:page => 1).map(&:id).sort.should == expected.map(&:id).sort
+ topic.replies.paginate(:page => 1).reorder('replies.id ASC').should == expected.reverse
+ end
+
+ it "should paginate through association extension" do
+ project = Project.order('id').first
+ expected = [replies(:brave)]
+
+ lambda {
+ result = project.replies.only_recent.paginate(:page => 1)
+ result.should == expected
+ }.should run_queries(1)
+ end
+ end
+
+ it "should paginate with joins" do
+ result = nil
+ join_sql = 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id'
+
+ lambda {
+ result = Developer.paginate(:page => 1, :joins => join_sql, :conditions => 'project_id = 1')
+ result.to_a # trigger loading of records
+ result.size.should == 2
+ developer_names = result.map(&:name)
+ developer_names.should include('David')
+ developer_names.should include('Jamis')
+ }.should run_queries(1)
+
+ lambda {
+ expected = result.to_a
+ result = Developer.paginate(:page => 1, :joins => join_sql,
+ :conditions => 'project_id = 1', :count => { :select => "users.id" }).to_a
+ result.should == expected
+ result.total_entries.should == 2
+ }.should run_queries(1)
+ end
+
+ it "should paginate with group" do
+ result = nil
+ lambda {
+ result = Developer.paginate(:page => 1, :per_page => 10,
+ :group => 'salary', :select => 'salary', :order => 'salary').to_a
+ }.should run_queries(1)
+
+ expected = users(:david, :jamis, :dev_10, :poor_jamis).map(&:salary).sort
+ result.map(&:salary).should == expected
+ end
+
+ it "should not paginate with dynamic finder" do
+ lambda {
+ Developer.paginate_by_salary(100000, :page => 1, :per_page => 5)
+ }.should raise_error(NoMethodError)
+ end
+
+ it "should paginate with_scope" do
+ result = Developer.with_poor_ones { Developer.paginate :page => 1 }
+ result.size.should == 2
+ result.total_entries.should == 2
+ end
+
+ describe "scopes" do
+ it "should paginate" do
+ result = Developer.poor.paginate :page => 1, :per_page => 1
+ result.size.should == 1
+ result.total_entries.should == 2
+ end
+
+ it "should paginate on habtm association" do
+ project = projects(:active_record)
+ lambda {
+ result = ignore_deprecation { project.developers.poor.paginate :page => 1, :per_page => 1 }
+ result.size.should == 1
+ result.total_entries.should == 1
+ }.should run_queries(2)
+ end
+
+ it "should paginate on hmt association" do
+ project = projects(:active_record)
+ expected = [replies(:brave)]
+
+ lambda {
+ result = project.replies.recent.paginate :page => 1, :per_page => 1
+ result.should == expected
+ result.total_entries.should == 1
+ }.should run_queries(2)
+ end
+
+ it "should paginate on has_many association" do
+ project = projects(:active_record)
+ expected = [topics(:ar)]
+
+ lambda {
+ result = project.topics.mentions_activerecord.paginate :page => 1, :per_page => 1
+ result.should == expected
+ result.total_entries.should == 1
+ }.should run_queries(2)
+ end
+ end
+
+ it "should paginate with :readonly option" do
+ lambda {
+ Developer.paginate :readonly => true, :page => 1
+ }.should_not raise_error
+ end
+
+ it "should not paginate an array of IDs" do
+ lambda {
+ Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
+ }.should raise_error(ArgumentError)
+ end
+
+ it "errors out for invalid values" do |variable|
+ lambda {
+ # page that results in an offset larger than BIGINT
+ Project.page(307445734561825862)
+ }.should raise_error(WillPaginate::InvalidPage, "invalid offset: 9223372036854775830")
+ end
+
+ protected
+
+ def ignore_deprecation
+ ActiveSupport::Deprecation.silence { yield }
+ end
+
+ def run_queries(num)
+ QueryCountMatcher.new(num)
+ end
+
+ def show_queries(&block)
+ counter = QueryCountMatcher.new(nil)
+ counter.run block
+ ensure
+ queries = counter.performed_queries
+ if queries.any?
+ puts queries
+ else
+ puts "no queries"
+ end
+ end
+
+end
+
+class QueryCountMatcher
+ def initialize(num)
+ @expected_count = num
+ end
+
+ def matches?(block)
+ run(block)
+
+ if @expected_count.respond_to? :include?
+ @expected_count.include? @count
+ else
+ @count == @expected_count
+ end
+ end
+
+ def run(block)
+ $query_count = 0
+ $query_sql = []
+ block.call
+ ensure
+ @queries = $query_sql.dup
+ @count = $query_count
+ end
+
+ def performed_queries
+ @queries
+ end
+
+ def failure_message
+ "expected #{@expected_count} queries, got #{@count}\n#{@queries.join("\n")}"
+ end
+
+ def negative_failure_message
+ "expected query count not to be #{@expected_count}"
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/finders/activerecord_test_connector.rb b/vendor/plugins/will_paginate/spec/finders/activerecord_test_connector.rb
new file mode 100644
index 0000000..5328acd
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/activerecord_test_connector.rb
@@ -0,0 +1,118 @@
+require 'active_record'
+require 'active_record/fixtures'
+require 'active_support/multibyte' # needed for Ruby 1.9.1
+
+$query_count = 0
+$query_sql = []
+
+ignore_sql = /
+ ^(
+ PRAGMA | SHOW\ max_identifier_length |
+ SELECT\ (currval|CAST|@@IDENTITY|@@ROWCOUNT) |
+ SHOW\ (FIELDS|TABLES)
+ )\b |
+ \bFROM\ (sqlite_master|pg_tables|pg_attribute)\b
+ /x
+
+ActiveSupport::Notifications.subscribe(/^sql\./) do |*args|
+ payload = args.last
+ unless payload[:name] =~ /^Fixture/ or payload[:sql] =~ ignore_sql
+ $query_count += 1
+ $query_sql << payload[:sql]
+ end
+end
+
+module ActiverecordTestConnector
+ extend self
+
+ attr_accessor :able_to_connect
+ attr_accessor :connected
+
+ FIXTURES_PATH = File.expand_path('../../fixtures', __FILE__)
+
+ Fixtures = defined?(ActiveRecord::FixtureSet) ? ActiveRecord::FixtureSet :
+ defined?(ActiveRecord::Fixtures) ? ActiveRecord::Fixtures :
+ ::Fixtures
+
+ # Set our defaults
+ self.connected = false
+ self.able_to_connect = true
+
+ def setup
+ unless self.connected || !self.able_to_connect
+ setup_connection
+ load_schema
+ add_load_path FIXTURES_PATH
+ self.connected = true
+ end
+ rescue Exception => e # errors from ActiveRecord setup
+ $stderr.puts "\nSkipping ActiveRecord tests: #{e}\n\n"
+ self.able_to_connect = false
+ end
+
+ private
+
+ def add_load_path(path)
+ dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
+ dep.autoload_paths.unshift path
+ end
+
+ def setup_connection
+ db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
+
+ configurations = YAML.load_file(File.expand_path('../../database.yml', __FILE__))
+ raise "no configuration for '#{db}'" unless configurations.key? db
+ configuration = configurations[db]
+
+ # ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
+ puts "using #{configuration['adapter']} adapter"
+
+ ActiveRecord::Base.configurations = { db => configuration }
+ ActiveRecord::Base.establish_connection(db)
+ ActiveRecord::Base.default_timezone = :utc
+ end
+
+ def load_schema
+ silencer = ActiveRecord::Base.method(:silence)
+ silence_args = []
+ silence_args << :stdout if silencer.arity != 0
+ silencer.call(*silence_args) do
+ ActiveRecord::Migration.verbose = false
+ load File.join(FIXTURES_PATH, 'schema.rb')
+ end
+ end
+
+ module FixtureSetup
+ def fixtures(*tables)
+ table_names = tables.map { |t| t.to_s }
+
+ fixtures = Fixtures.create_fixtures ActiverecordTestConnector::FIXTURES_PATH, table_names
+ @@loaded_fixtures = {}
+ @@fixture_cache = {}
+
+ unless fixtures.nil?
+ if fixtures.instance_of?(Fixtures)
+ @@loaded_fixtures[fixtures.table_name] = fixtures
+ else
+ fixtures.each { |f| @@loaded_fixtures[f.table_name] = f }
+ end
+ end
+
+ table_names.each do |table_name|
+ define_method(table_name) do |*fixtures|
+ @@fixture_cache[table_name] ||= {}
+
+ instances = fixtures.map do |fixture|
+ if @@loaded_fixtures[table_name][fixture.to_s]
+ @@fixture_cache[table_name][fixture] ||= @@loaded_fixtures[table_name][fixture.to_s].find
+ else
+ raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
+ end
+ end
+
+ instances.size == 1 ? instances.first : instances
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/finders/data_mapper_spec.rb b/vendor/plugins/will_paginate/spec/finders/data_mapper_spec.rb
new file mode 100644
index 0000000..c04074f
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/data_mapper_spec.rb
@@ -0,0 +1,103 @@
+require 'spec_helper'
+
+begin
+ require 'will_paginate/data_mapper'
+ require File.expand_path('../data_mapper_test_connector', __FILE__)
+rescue LoadError => error
+ warn "Error running DataMapper specs: #{error.message}"
+ datamapper_loaded = false
+else
+ datamapper_loaded = true
+end
+
+describe WillPaginate::DataMapper do
+
+ it "has per_page" do
+ Animal.per_page.should == 30
+ begin
+ Animal.per_page = 10
+ Animal.per_page.should == 10
+
+ subclass = Class.new(Animal)
+ subclass.per_page.should == 10
+ ensure
+ Animal.per_page = 30
+ end
+ end
+
+ it "doesn't make normal collections appear paginated" do
+ Animal.all.should_not be_paginated
+ end
+
+ it "paginates to first page by default" do
+ animals = Animal.paginate(:page => nil)
+
+ animals.should be_paginated
+ animals.current_page.should == 1
+ animals.per_page.should == 30
+ animals.offset.should == 0
+ animals.total_entries.should == 3
+ animals.total_pages.should == 1
+ end
+
+ it "paginates to first page, explicit limit" do
+ animals = Animal.paginate(:page => 1, :per_page => 2)
+
+ animals.current_page.should == 1
+ animals.per_page.should == 2
+ animals.total_entries.should == 3
+ animals.total_pages.should == 2
+ animals.map {|a| a.name }.should == %w[ Dog Cat ]
+ end
+
+ it "paginates to second page" do
+ animals = Animal.paginate(:page => 2, :per_page => 2)
+
+ animals.current_page.should == 2
+ animals.offset.should == 2
+ animals.map {|a| a.name }.should == %w[ Lion ]
+ end
+
+ it "paginates a collection" do
+ friends = Animal.all(:notes.like => '%friend%')
+ friends.paginate(:page => 1).per_page.should == 30
+ friends.paginate(:page => 1, :per_page => 1).total_entries.should == 2
+ end
+
+ it "paginates a limited collection" do
+ animals = Animal.all(:limit => 2).paginate(:page => 1)
+ animals.per_page.should == 2
+ end
+
+ it "has page() method" do
+ Animal.page(2).per_page.should == 30
+ Animal.page(2).offset.should == 30
+ Animal.page(2).current_page.should == 2
+ Animal.all(:limit => 2).page(2).per_page.should == 2
+ end
+
+ it "has total_pages at 1 for empty collections" do
+ Animal.all(:conditions => ['1=2']).page(1).total_pages.should == 1
+ end
+
+ it "can iterate and then call WP methods" do
+ animals = Animal.all(:limit => 2).page(1)
+ animals.each { |a| }
+ animals.total_entries.should == 3
+ end
+
+ it "augments to_a to return a WP::Collection" do
+ animals = Animal.all(:limit => 2).page(1)
+ array = animals.to_a
+ array.size.should == 2
+ array.should be_kind_of(WillPaginate::Collection)
+ array.current_page.should == 1
+ array.per_page.should == 2
+ end
+
+ it "doesn't have a problem assigning has-one-through relationship" do
+ human = Human.create :name => "Mislav"
+ human.pet = Animal.first
+ end
+
+end if datamapper_loaded
diff --git a/vendor/plugins/will_paginate/spec/finders/data_mapper_test_connector.rb b/vendor/plugins/will_paginate/spec/finders/data_mapper_test_connector.rb
new file mode 100644
index 0000000..9d7453f
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/data_mapper_test_connector.rb
@@ -0,0 +1,54 @@
+require 'sqlite3'
+require 'dm-core'
+require 'dm-core/support/logger'
+require 'dm-migrations'
+
+DataMapper.setup :default, 'sqlite3::memory:'
+
+# Define models
+class Animal
+ include DataMapper::Resource
+ property :id, Serial
+ property :name, String
+ property :notes, Text
+
+ def self.setup
+ Animal.create(:name => 'Dog', :notes => "Man's best friend")
+ Animal.create(:name => 'Cat', :notes => "Woman's best friend")
+ Animal.create(:name => 'Lion', :notes => 'King of the Jungle')
+ end
+end
+
+class Ownership
+ include DataMapper::Resource
+
+ belongs_to :animal, :key => true
+ belongs_to :human, :key => true
+
+ def self.setup
+ end
+end
+
+class Human
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :name, String
+
+ has n, :ownerships
+ has 1, :pet, :model => 'Animal', :through => :ownerships, :via => :animal
+
+ def self.setup
+ end
+end
+
+# Load fixtures
+[Animal, Ownership, Human].each do |klass|
+ klass.auto_migrate!
+ klass.setup
+end
+
+if 'irb' == $0
+ DataMapper.logger.set_log($stdout, :debug)
+ DataMapper.logger.auto_flush = true
+end
diff --git a/vendor/plugins/will_paginate/spec/finders/mongoid_spec.rb b/vendor/plugins/will_paginate/spec/finders/mongoid_spec.rb
new file mode 100644
index 0000000..88571f8
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/mongoid_spec.rb
@@ -0,0 +1,140 @@
+require 'spec_helper'
+
+begin
+ require 'will_paginate/mongoid'
+rescue LoadError => error
+ warn "Error running Sequel specs: #{error.message}"
+ mongoid_loaded = false
+else
+ Mongoid.database = Mongo::Connection.new.db('will_paginate_test')
+
+ class MongoidModel
+ include Mongoid::Document
+ end
+
+ mongoid_loaded = true
+end
+
+describe WillPaginate::Mongoid do
+ before(:all) do
+ MongoidModel.delete_all
+ 4.times { MongoidModel.create! }
+ end
+
+ let(:criteria) { MongoidModel.criteria }
+
+ describe "#page" do
+ it "should forward to the paginate method" do
+ criteria.expects(:paginate).with(:page => 2).returns("itself")
+ criteria.page(2).should == "itself"
+ end
+
+ it "should not override per_page if set earlier in the chain" do
+ criteria.paginate(:per_page => 10).page(1).per_page.should == 10
+ criteria.paginate(:per_page => 20).page(1).per_page.should == 20
+ end
+ end
+
+ describe "#per_page" do
+ it "should set the limit if given an argument" do
+ criteria.per_page(10).options[:limit].should == 10
+ end
+
+ it "should return the current limit if no argument is given" do
+ criteria.per_page.should == nil
+ criteria.per_page(10).per_page.should == 10
+ end
+
+ it "should be interchangable with limit" do
+ criteria.limit(15).per_page.should == 15
+ end
+
+ it "should be nil'able" do
+ criteria.per_page(nil).per_page.should be_nil
+ end
+ end
+
+ describe "#paginate" do
+ it "should use criteria" do
+ criteria.paginate.should be_instance_of(::Mongoid::Criteria)
+ end
+
+ it "should not override page number if set earlier in the chain" do
+ criteria.page(3).paginate.current_page.should == 3
+ end
+
+ it "should limit according to per_page parameter" do
+ criteria.paginate(:per_page => 10).options.should include(:limit => 10)
+ end
+
+ it "should skip according to page and per_page parameters" do
+ criteria.paginate(:page => 2, :per_page => 5).options.should include(:skip => 5)
+ end
+
+ specify "first fallback value for per_page option is the current limit" do
+ criteria.limit(12).paginate.options.should include(:limit => 12)
+ end
+
+ specify "second fallback value for per_page option is WillPaginate.per_page" do
+ criteria.paginate.options.should include(:limit => WillPaginate.per_page)
+ end
+
+ specify "page should default to 1" do
+ criteria.paginate.options.should include(:skip => 0)
+ end
+
+ it "should convert strings to integers" do
+ criteria.paginate(:page => "2", :per_page => "3").options.should include(:limit => 3, :limit => 3)
+ end
+
+ describe "collection compatibility" do
+ describe "#total_count" do
+ it "should be calculated correctly" do
+ criteria.paginate(:per_page => 1).total_entries.should == 4
+ criteria.paginate(:per_page => 3).total_entries.should == 4
+ end
+
+ it "should be cached" do
+ criteria.expects(:count).once.returns(123)
+ criteria.paginate
+ 2.times { criteria.total_entries.should == 123 }
+ end
+ end
+
+ it "should calculate total_pages" do
+ criteria.paginate(:per_page => 1).total_pages.should == 4
+ criteria.paginate(:per_page => 3).total_pages.should == 2
+ criteria.paginate(:per_page => 10).total_pages.should == 1
+ end
+
+ it "should return per_page" do
+ criteria.paginate(:per_page => 1).per_page.should == 1
+ criteria.paginate(:per_page => 5).per_page.should == 5
+ end
+
+ describe "#current_page" do
+ it "should return current_page" do
+ criteria.paginate(:page => 1).current_page.should == 1
+ criteria.paginate(:page => 3).current_page.should == 3
+ end
+
+ it "should be casted to PageNumber" do
+ criteria.paginate(:page => 1).current_page.should be_instance_of(WillPaginate::PageNumber)
+ end
+ end
+
+ it "should return offset" do
+ criteria.paginate(:page => 1).offset.should == 0
+ criteria.paginate(:page => 2, :per_page => 5).offset.should == 5
+ criteria.paginate(:page => 3, :per_page => 10).offset.should == 20
+ end
+
+ it "should not pollute plain mongoid criterias" do
+ %w(total_entries total_pages current_page).each do |method|
+ criteria.should_not respond_to(method)
+ end
+ criteria.offset.should be_nil # this is already a criteria method
+ end
+ end
+ end
+end if mongoid_loaded
diff --git a/vendor/plugins/will_paginate/spec/finders/sequel_spec.rb b/vendor/plugins/will_paginate/spec/finders/sequel_spec.rb
new file mode 100644
index 0000000..720c06a
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/sequel_spec.rb
@@ -0,0 +1,67 @@
+require 'spec_helper'
+
+begin
+ require 'will_paginate/sequel'
+ require File.expand_path('../sequel_test_connector', __FILE__)
+rescue LoadError, ArgumentError => error
+ warn "Error running Sequel specs: #{error.message}"
+ sequel_loaded = false
+else
+ sequel_loaded = true
+end
+
+describe Sequel::Dataset::Pagination, 'extension' do
+
+ class Car < Sequel::Model
+ end
+
+ it "should have the #paginate method" do
+ Car.should respond_to(:paginate)
+ end
+
+ it "should NOT have the #paginate_by_sql method" do
+ Car.should_not respond_to(:paginate_by_sql)
+ end
+
+ describe 'pagination' do
+ before(:all) do
+ Car.create(:name => 'Shelby', :notes => "Man's best friend")
+ Car.create(:name => 'Aston Martin', :notes => "Woman's best friend")
+ Car.create(:name => 'Corvette', :notes => 'King of the Jungle')
+ end
+
+ it "should imitate WillPaginate::Collection" do
+ result = Car.paginate(1, 2)
+
+ result.should_not be_empty
+ result.size.should == 2
+ result.length.should == 2
+ result.total_entries.should == 3
+ result.total_pages.should == 2
+ result.per_page.should == 2
+ result.current_page.should == 1
+ end
+
+ it "should perform" do
+ Car.paginate(1, 2).all.should == [Car[1], Car[2]]
+ end
+
+ it "should be empty" do
+ result = Car.paginate(3, 2)
+ result.should be_empty
+ end
+
+ it "should perform with #select and #order" do
+ result = Car.select("name as foo".lit).order(:name).paginate(1, 2).all
+ result.size.should == 2
+ result.first.values[:foo].should == "Aston Martin"
+ end
+
+ it "should perform with #filter" do
+ results = Car.filter(:name => 'Shelby').paginate(1, 2).all
+ results.size.should == 1
+ results.first.should == Car.find(:name => 'Shelby')
+ end
+ end
+
+end if sequel_loaded
diff --git a/vendor/plugins/will_paginate/spec/finders/sequel_test_connector.rb b/vendor/plugins/will_paginate/spec/finders/sequel_test_connector.rb
new file mode 100644
index 0000000..d7c69b6
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/finders/sequel_test_connector.rb
@@ -0,0 +1,15 @@
+require 'sequel'
+
+Symbol.class_eval do
+ # Active Record calculations tries `as` on some objects but chokes when that
+ # object was a Symbol and it gets a Sequel::SQL::AliasedExpression.
+ undef as if method_defined? :as
+end
+
+db = Sequel.sqlite
+
+db.create_table :cars do
+ primary_key :id, :integer, :auto_increment => true
+ column :name, :text
+ column :notes, :text
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/admin.rb b/vendor/plugins/will_paginate/spec/fixtures/admin.rb
new file mode 100644
index 0000000..1d5e7f3
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/admin.rb
@@ -0,0 +1,3 @@
+class Admin < User
+ has_many :companies, :finder_sql => 'SELECT * FROM companies'
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/developer.rb b/vendor/plugins/will_paginate/spec/fixtures/developer.rb
new file mode 100644
index 0000000..4c55bc9
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/developer.rb
@@ -0,0 +1,15 @@
+class Developer < User
+ has_and_belongs_to_many :projects, :include => :topics, :order => 'projects.name', :join_table => 'developers_projects'
+
+ def self.with_poor_ones(&block)
+ with_scope :find => { :conditions => ['salary <= ?', 80000], :order => 'salary' } do
+ yield
+ end
+ end
+
+ scope :poor, lambda {
+ where(['salary <= ?', 80000]).order('salary')
+ }
+
+ def self.per_page() 10 end
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/developers_projects.yml b/vendor/plugins/will_paginate/spec/fixtures/developers_projects.yml
new file mode 100644
index 0000000..cee359c
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/developers_projects.yml
@@ -0,0 +1,13 @@
+david_action_controller:
+ developer_id: 1
+ project_id: 2
+ joined_on: 2004-10-10
+
+david_active_record:
+ developer_id: 1
+ project_id: 1
+ joined_on: 2004-10-10
+
+jamis_active_record:
+ developer_id: 2
+ project_id: 1
\ No newline at end of file
diff --git a/vendor/plugins/will_paginate/spec/fixtures/project.rb b/vendor/plugins/will_paginate/spec/fixtures/project.rb
new file mode 100644
index 0000000..d421981
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/project.rb
@@ -0,0 +1,15 @@
+class Project < ActiveRecord::Base
+ has_and_belongs_to_many :developers, :uniq => true, :join_table => 'developers_projects'
+
+ has_many :topics
+ # :finder_sql => 'SELECT * FROM topics WHERE (topics.project_id = #{id})',
+ # :counter_sql => 'SELECT COUNT(*) FROM topics WHERE (topics.project_id = #{id})'
+
+ has_many :replies, :through => :topics do
+ def only_recent(params = {})
+ scoped.where(['replies.created_at > ?', 15.minutes.ago])
+ end
+ end
+
+ has_many :unique_replies, :through => :topics, :source => :replies, :uniq => true
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/projects.yml b/vendor/plugins/will_paginate/spec/fixtures/projects.yml
new file mode 100644
index 0000000..4104a3d
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/projects.yml
@@ -0,0 +1,6 @@
+active_record:
+ id: 1
+ name: Active Record
+action_controller:
+ id: 2
+ name: Action Controller
diff --git a/vendor/plugins/will_paginate/spec/fixtures/replies.yml b/vendor/plugins/will_paginate/spec/fixtures/replies.yml
new file mode 100644
index 0000000..25fff58
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/replies.yml
@@ -0,0 +1,29 @@
+witty_retort:
+ id: 1
+ topic_id: 1
+ content: Birdman is better!
+ created_at: <%= 6.hours.ago.utc.to_s(:db) %>
+
+another:
+ id: 2
+ topic_id: 2
+ content: Nuh uh!
+ created_at: <%= 1.hour.ago.utc.to_s(:db) %>
+
+spam:
+ id: 3
+ topic_id: 1
+ content: Nice site!
+ created_at: <%= 1.hour.ago.utc.to_s(:db) %>
+
+decisive:
+ id: 4
+ topic_id: 4
+ content: "I'm getting to the bottom of this"
+ created_at: <%= 30.minutes.ago.utc.to_s(:db) %>
+
+brave:
+ id: 5
+ topic_id: 4
+ content: "AR doesn't scare me a bit"
+ created_at: <%= 10.minutes.ago.utc.to_s(:db) %>
diff --git a/vendor/plugins/will_paginate/spec/fixtures/reply.rb b/vendor/plugins/will_paginate/spec/fixtures/reply.rb
new file mode 100644
index 0000000..5f09fba
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/reply.rb
@@ -0,0 +1,10 @@
+class Reply < ActiveRecord::Base
+ belongs_to :topic, :include => [:replies]
+
+ scope :recent, lambda {
+ where(['replies.created_at > ?', 15.minutes.ago]).
+ order('replies.created_at DESC')
+ }
+
+ validates_presence_of :content
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/schema.rb b/vendor/plugins/will_paginate/spec/fixtures/schema.rb
new file mode 100644
index 0000000..8831aad
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/schema.rb
@@ -0,0 +1,38 @@
+ActiveRecord::Schema.define do
+
+ create_table "users", :force => true do |t|
+ t.column "name", :text
+ t.column "salary", :integer, :default => 70000
+ t.column "created_at", :datetime
+ t.column "updated_at", :datetime
+ t.column "type", :text
+ end
+
+ create_table "projects", :force => true do |t|
+ t.column "name", :text
+ end
+
+ create_table "developers_projects", :id => false, :force => true do |t|
+ t.column "developer_id", :integer, :null => false
+ t.column "project_id", :integer, :null => false
+ t.column "joined_on", :date
+ t.column "access_level", :integer, :default => 1
+ end
+
+ create_table "topics", :force => true do |t|
+ t.column "project_id", :integer
+ t.column "title", :string
+ t.column "subtitle", :string
+ t.column "content", :text
+ t.column "created_at", :datetime
+ t.column "updated_at", :datetime
+ end
+
+ create_table "replies", :force => true do |t|
+ t.column "content", :text
+ t.column "created_at", :datetime
+ t.column "updated_at", :datetime
+ t.column "topic_id", :integer
+ end
+
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/topic.rb b/vendor/plugins/will_paginate/spec/fixtures/topic.rb
new file mode 100644
index 0000000..ea5a39b
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/topic.rb
@@ -0,0 +1,11 @@
+class Topic < ActiveRecord::Base
+ has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
+ belongs_to :project
+
+ scope :mentions_activerecord, lambda {
+ where(['topics.title LIKE ?', '%ActiveRecord%'])
+ }
+ scope :distinct, lambda {
+ select("DISTINCT #{table_name}.*")
+ }
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/topics.yml b/vendor/plugins/will_paginate/spec/fixtures/topics.yml
new file mode 100644
index 0000000..f93cf48
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/topics.yml
@@ -0,0 +1,30 @@
+futurama:
+ id: 1
+ title: Isnt futurama awesome?
+ subtitle: It really is, isnt it.
+ content: I like futurama
+ created_at: <%= 1.day.ago.utc.to_s(:db) %>
+ updated_at:
+
+harvey_birdman:
+ id: 2
+ title: Harvey Birdman is the king of all men
+ subtitle: yup
+ content: He really is
+ created_at: <%= 2.hours.ago.utc.to_s(:db) %>
+ updated_at:
+
+rails:
+ id: 3
+ project_id: 1
+ title: Rails is nice
+ subtitle: It makes me happy
+ content: except when I have to hack internals to fix pagination. even then really.
+ created_at: <%= 20.minutes.ago.utc.to_s(:db) %>
+
+ar:
+ id: 4
+ project_id: 1
+ title: ActiveRecord sometimes freaks me out
+ content: "I mean, what's the deal with eager loading?"
+ created_at: <%= 15.minutes.ago.utc.to_s(:db) %>
diff --git a/vendor/plugins/will_paginate/spec/fixtures/user.rb b/vendor/plugins/will_paginate/spec/fixtures/user.rb
new file mode 100644
index 0000000..4a57cf0
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/user.rb
@@ -0,0 +1,2 @@
+class User < ActiveRecord::Base
+end
diff --git a/vendor/plugins/will_paginate/spec/fixtures/users.yml b/vendor/plugins/will_paginate/spec/fixtures/users.yml
new file mode 100644
index 0000000..ed2c03a
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/fixtures/users.yml
@@ -0,0 +1,35 @@
+david:
+ id: 1
+ name: David
+ salary: 80000
+ type: Developer
+
+jamis:
+ id: 2
+ name: Jamis
+ salary: 150000
+ type: Developer
+
+<% for digit in 3..10 %>
+dev_<%= digit %>:
+ id: <%= digit %>
+ name: fixture_<%= digit %>
+ salary: 100000
+ type: Developer
+<% end %>
+
+poor_jamis:
+ id: 11
+ name: Jamis
+ salary: 9000
+ type: Developer
+
+admin:
+ id: 12
+ name: admin
+ type: Admin
+
+goofy:
+ id: 13
+ name: Goofy
+ type: Admin
diff --git a/vendor/plugins/will_paginate/spec/page_number_spec.rb b/vendor/plugins/will_paginate/spec/page_number_spec.rb
new file mode 100644
index 0000000..1287116
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/page_number_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+require 'will_paginate/page_number'
+
+describe WillPaginate::PageNumber do
+ describe "valid" do
+ subject { described_class.new('12', 'page') }
+
+ it { should eq(12) }
+ its(:inspect) { should eq('page 12') }
+ it { should be_a(WillPaginate::PageNumber) }
+ it { should be_instance_of(WillPaginate::PageNumber) }
+ it { should be_a(Numeric) }
+ it { should be_a(Fixnum) }
+ it { should_not be_instance_of(Fixnum) }
+
+ it "passes the PageNumber=== type check" do |variable|
+ (WillPaginate::PageNumber === subject).should be
+ end
+
+ it "passes the Numeric=== type check" do |variable|
+ (Numeric === subject).should be
+ (Fixnum === subject).should be
+ end
+ end
+
+ describe "invalid" do
+ def create(value, name = 'page')
+ described_class.new(value, name)
+ end
+
+ it "errors out on non-int values" do
+ lambda { create(nil) }.should raise_error(WillPaginate::InvalidPage)
+ lambda { create('') }.should raise_error(WillPaginate::InvalidPage)
+ lambda { create('Schnitzel') }.should raise_error(WillPaginate::InvalidPage)
+ end
+
+ it "errors out on zero or less" do
+ lambda { create(0) }.should raise_error(WillPaginate::InvalidPage)
+ lambda { create(-1) }.should raise_error(WillPaginate::InvalidPage)
+ end
+
+ it "doesn't error out on zero for 'offset'" do
+ lambda { create(0, 'offset') }.should_not raise_error
+ lambda { create(-1, 'offset') }.should raise_error(WillPaginate::InvalidPage)
+ end
+ end
+
+ describe "coercion method" do
+ it "defaults to 'page' name" do
+ num = WillPaginate::PageNumber(12)
+ num.inspect.should eq('page 12')
+ end
+
+ it "accepts a custom name" do
+ num = WillPaginate::PageNumber(12, 'monkeys')
+ num.inspect.should eq('monkeys 12')
+ end
+
+ it "doesn't affect PageNumber instances" do
+ num = WillPaginate::PageNumber(12)
+ num2 = WillPaginate::PageNumber(num)
+ num2.object_id.should eq(num.object_id)
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/per_page_spec.rb b/vendor/plugins/will_paginate/spec/per_page_spec.rb
new file mode 100644
index 0000000..ece303f
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/per_page_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+require 'will_paginate/per_page'
+
+describe WillPaginate::PerPage do
+
+ class MyModel
+ extend WillPaginate::PerPage
+ end
+
+ it "has the default value" do
+ MyModel.per_page.should == 30
+
+ WillPaginate.per_page = 10
+ begin
+ MyModel.per_page.should == 10
+ ensure
+ WillPaginate.per_page = 30
+ end
+ end
+
+ it "casts values to int" do
+ WillPaginate.per_page = '10'
+ begin
+ MyModel.per_page.should == 10
+ ensure
+ WillPaginate.per_page = 30
+ end
+ end
+
+ it "has an explicit value" do
+ MyModel.per_page = 12
+ begin
+ MyModel.per_page.should == 12
+ subclass = Class.new(MyModel)
+ subclass.per_page.should == 12
+ ensure
+ MyModel.send(:remove_instance_variable, '@per_page')
+ end
+ end
+
+end
diff --git a/vendor/plugins/will_paginate/spec/spec_helper.rb b/vendor/plugins/will_paginate/spec/spec_helper.rb
new file mode 100644
index 0000000..ca5853a
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/spec_helper.rb
@@ -0,0 +1,71 @@
+require 'rspec'
+require 'view_helpers/view_example_group'
+begin
+ require 'ruby-debug'
+rescue LoadError
+ # no debugger available
+end
+
+RSpec.configure do |config|
+ config.include Module.new {
+ protected
+
+ def include_phrase(string)
+ PhraseMatcher.new(string)
+ end
+
+ def have_deprecation(msg)
+ DeprecationMatcher.new(msg)
+ end
+ }
+
+ config.mock_with :mocha
+end
+
+class PhraseMatcher
+ def initialize(string)
+ @string = string
+ @pattern = /\b#{Regexp.escape string}\b/
+ end
+
+ def matches?(actual)
+ @actual = actual.to_s
+ @actual =~ @pattern
+ end
+
+ def failure_message
+ "expected #{@actual.inspect} to contain phrase #{@string.inspect}"
+ end
+
+ def negative_failure_message
+ "expected #{@actual.inspect} not to contain phrase #{@string.inspect}"
+ end
+end
+
+require 'stringio'
+
+class DeprecationMatcher
+ def initialize(message)
+ @message = message
+ end
+
+ def matches?(block)
+ @actual = hijack_stderr(&block)
+ PhraseMatcher.new("DEPRECATION WARNING: #{@message}").matches?(@actual)
+ end
+
+ def failure_message
+ "expected deprecation warning #{@message.inspect}, got #{@actual.inspect}"
+ end
+
+ private
+
+ def hijack_stderr
+ err = $stderr
+ $stderr = StringIO.new
+ yield
+ $stderr.string.rstrip
+ ensure
+ $stderr = err
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/view_helpers/action_view_spec.rb b/vendor/plugins/will_paginate/spec/view_helpers/action_view_spec.rb
new file mode 100644
index 0000000..1cda184
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/view_helpers/action_view_spec.rb
@@ -0,0 +1,423 @@
+require 'spec_helper'
+require 'active_support/rescuable' # needed for Ruby 1.9.1
+require 'action_controller'
+require 'will_paginate/view_helpers/action_view'
+require 'will_paginate/collection'
+
+Routes = ActionDispatch::Routing::RouteSet.new
+
+Routes.draw do
+ get 'dummy/page/:page' => 'dummy#index'
+ get 'dummy/dots/page.:page' => 'dummy#dots'
+ get 'ibocorp(/:page)' => 'ibocorp#index',
+ :constraints => { :page => /\d+/ }, :defaults => { :page => 1 }
+
+ get ':controller(/:action(/:id(.:format)))'
+end
+
+describe WillPaginate::ActionView do
+
+ before(:all) do
+ I18n.load_path.concat WillPaginate::I18n.load_path
+ end
+
+ before(:each) do
+ I18n.reload!
+ end
+
+ before(:each) do
+ @assigns = {}
+ @controller = DummyController.new
+ @request = @controller.request
+ @template = '<%= will_paginate collection, options %>'
+ end
+
+ attr_reader :assigns, :controller, :request
+
+ def render(locals)
+ @view = ActionView::Base.new([], @assigns, @controller)
+ @view.request = @request
+ @view.singleton_class.send(:include, @controller._routes.url_helpers)
+ @view.render(:inline => @template, :locals => locals)
+ end
+
+ ## basic pagination ##
+
+ it "should render" do
+ paginate do |pagination|
+ assert_select 'a[href]', 3 do |elements|
+ validate_page_numbers [2,3,2], elements
+ assert_select elements.last, ':last-child', "Next →"
+ end
+ assert_select 'span', 1
+ assert_select 'span.disabled:first-child', '← Previous'
+ assert_select 'em.current', '1'
+ pagination.first.inner_text.should == '← Previous 1 2 3 Next →'
+ end
+ end
+
+ it "should render nothing when there is only 1 page" do
+ paginate(:per_page => 30).should be_empty
+ end
+
+ it "should paginate with options" do
+ paginate({ :page => 2 }, :class => 'will_paginate', :previous_label => 'Prev', :next_label => 'Next') do
+ assert_select 'a[href]', 4 do |elements|
+ validate_page_numbers [1,1,3,3], elements
+ # test rel attribute values:
+ assert_select elements[1], 'a', '1' do |link|
+ link.first['rel'].should == 'prev start'
+ end
+ assert_select elements.first, 'a', "Prev" do |link|
+ link.first['rel'].should == 'prev start'
+ end
+ assert_select elements.last, 'a', "Next" do |link|
+ link.first['rel'].should == 'next'
+ end
+ end
+ assert_select '.current', '2'
+ end
+ end
+
+ it "should paginate using a custom renderer class" do
+ paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
+ assert_select 'a[default=true]', 3
+ end
+ end
+
+ it "should paginate using a custom renderer instance" do
+ renderer = WillPaginate::ActionView::LinkRenderer.new
+ def renderer.gap() '~~' end
+
+ paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
+ assert_select 'span.my-gap', '~~'
+ end
+
+ renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
+ paginate({}, :renderer => renderer) do
+ assert_select 'a[title=rendered]', 3
+ end
+ end
+
+ it "should have classnames on previous/next links" do
+ paginate do |pagination|
+ assert_select 'span.disabled.previous_page:first-child'
+ assert_select 'a.next_page[href]:last-child'
+ end
+ end
+
+ it "should match expected markup" do
+ paginate
+ expected = <<-HTML
+
+ HTML
+ expected.strip!.gsub!(/\s{2,}/, ' ')
+ expected_dom = HTML::Document.new(expected).root
+
+ html_document.root.should == expected_dom
+ end
+
+ it "should output escaped URLs" do
+ paginate({:page => 1, :per_page => 1, :total_entries => 2},
+ :page_links => false, :params => { :tag => '
' })
+
+ assert_select 'a[href]', 1 do |links|
+ query = links.first['href'].split('?', 2)[1]
+ query.split('&').sort.should == %w(page=2 tag=%3Cbr%3E)
+ end
+ end
+
+ ## advanced options for pagination ##
+
+ it "should be able to render without container" do
+ paginate({}, :container => false)
+ assert_select 'div.pagination', 0, 'main DIV present when it shouldn\'t'
+ assert_select 'a[href]', 3
+ end
+
+ it "should be able to render without page links" do
+ paginate({ :page => 2 }, :page_links => false) do
+ assert_select 'a[href]', 2 do |elements|
+ validate_page_numbers [1,3], elements
+ end
+ end
+ end
+
+ ## other helpers ##
+
+ it "should render a paginated section" do
+ @template = <<-ERB
+ <%= paginated_section collection, options do %>
+ <%= content_tag :div, '', :id => "developers" %>
+ <% end %>
+ ERB
+
+ paginate
+ assert_select 'div.pagination', 2
+ assert_select 'div.pagination + div#developers', 1
+ end
+
+ it "should not render a paginated section with a single page" do
+ @template = <<-ERB
+ <%= paginated_section collection, options do %>
+ <%= content_tag :div, '', :id => "developers" %>
+ <% end %>
+ ERB
+
+ paginate(:total_entries => 1)
+ assert_select 'div.pagination', 0
+ assert_select 'div#developers', 1
+ end
+
+ ## parameter handling in page links ##
+
+ it "should preserve parameters on GET" do
+ request.params :foo => { :bar => 'baz' }
+ paginate
+ assert_links_match /foo\[bar\]=baz/
+ end
+
+ it "should not preserve parameters on POST" do
+ request.post
+ request.params :foo => 'bar'
+ paginate
+ assert_no_links_match /foo=bar/
+ end
+
+ it "should add additional parameters to links" do
+ paginate({}, :params => { :foo => 'bar' })
+ assert_links_match /foo=bar/
+ end
+
+ it "should add anchor parameter" do
+ paginate({}, :params => { :anchor => 'anchor' })
+ assert_links_match /#anchor$/
+ end
+
+ it "should remove arbitrary parameters" do
+ request.params :foo => 'bar'
+ paginate({}, :params => { :foo => nil })
+ assert_no_links_match /foo=bar/
+ end
+
+ it "should override default route parameters" do
+ paginate({}, :params => { :controller => 'baz', :action => 'list' })
+ assert_links_match %r{\Wbaz/list\W}
+ end
+
+ it "should paginate with custom page parameter" do
+ paginate({ :page => 2 }, :param_name => :developers_page) do
+ assert_select 'a[href]', 4 do |elements|
+ validate_page_numbers [1,1,3,3], elements, :developers_page
+ end
+ end
+ end
+
+ it "should paginate with complex custom page parameter" do
+ request.params :developers => { :page => 2 }
+
+ paginate({ :page => 2 }, :param_name => 'developers[page]') do
+ assert_select 'a[href]', 4 do |links|
+ assert_links_match /\?developers\[page\]=\d+$/, links
+ validate_page_numbers [1,1,3,3], links, 'developers[page]'
+ end
+ end
+ end
+
+ it "should paginate with custom route page parameter" do
+ request.symbolized_path_parameters.update :controller => 'dummy', :action => nil
+ paginate :per_page => 2 do
+ assert_select 'a[href]', 6 do |links|
+ assert_links_match %r{/page/(\d+)$}, links, [2, 3, 4, 5, 6, 2]
+ end
+ end
+ end
+
+ it "should paginate with custom route with dot separator page parameter" do
+ request.symbolized_path_parameters.update :controller => 'dummy', :action => 'dots'
+ paginate :per_page => 2 do
+ assert_select 'a[href]', 6 do |links|
+ assert_links_match %r{/page\.(\d+)$}, links, [2, 3, 4, 5, 6, 2]
+ end
+ end
+ end
+
+ it "should paginate with custom route and first page number implicit" do
+ request.symbolized_path_parameters.update :controller => 'ibocorp', :action => nil
+ paginate :page => 2, :per_page => 2 do
+ assert_select 'a[href]', 7 do |links|
+ assert_links_match %r{/ibocorp(?:/(\d+))?$}, links, [nil, nil, 3, 4, 5, 6, 3]
+ end
+ end
+ # Routes.recognize_path('/ibocorp/2').should == {:page=>'2', :action=>'index', :controller=>'ibocorp'}
+ # Routes.recognize_path('/ibocorp/foo').should == {:action=>'foo', :controller=>'ibocorp'}
+ end
+
+ ## internal hardcore stuff ##
+
+ it "should be able to guess the collection name" do
+ collection = mock
+ collection.expects(:total_pages).returns(1)
+
+ @template = '<%= will_paginate options %>'
+ controller.controller_name = 'developers'
+ assigns['developers'] = collection
+
+ paginate(nil)
+ end
+
+ it "should fail if the inferred collection is nil" do
+ @template = '<%= will_paginate options %>'
+ controller.controller_name = 'developers'
+
+ lambda {
+ paginate(nil)
+ }.should raise_error(ActionView::TemplateError, /@developers/)
+ end
+
+ ## i18n
+
+ it "is able to translate previous/next labels" do
+ translation :will_paginate => {
+ :previous_label => 'Go back',
+ :next_label => 'Load more'
+ }
+
+ paginate do |pagination|
+ assert_select 'span.disabled:first-child', 'Go back'
+ assert_select 'a[rel=next]', 'Load more'
+ end
+ end
+
+ it "renders using ActionView helpers on a custom object" do
+ helper = Object.new
+ class << helper
+ attr_reader :controller
+ include ActionView::Helpers::UrlHelper
+ include Routes.url_helpers
+ include WillPaginate::ActionView
+ end
+ helper.default_url_options[:controller] = 'dummy'
+
+ collection = WillPaginate::Collection.new(2, 1, 3)
+ @render_output = helper.will_paginate(collection)
+
+ assert_select 'a[href]', 4 do |links|
+ urls = links.map {|l| l['href'] }.uniq
+ urls.should == ['/dummy/page/1', '/dummy/page/3']
+ end
+ end
+
+ it "renders using ActionDispatch helper on a custom object" do
+ helper = Object.new
+ class << helper
+ include ActionDispatch::Routing::UrlFor
+ include Routes.url_helpers
+ include WillPaginate::ActionView
+ end
+ helper.default_url_options[:host] = 'example.com'
+ helper.default_url_options[:controller] = 'dummy'
+ # helper.default_url_options[:only_path] = true
+
+ collection = WillPaginate::Collection.new(2, 1, 3)
+ @render_output = helper.will_paginate(collection)
+
+ assert_select 'a[href]', 4 do |links|
+ urls = links.map {|l| l['href'] }.uniq
+ urls.should == ['http://example.com/dummy/page/1', 'http://example.com/dummy/page/3']
+ end
+ end
+
+ private
+
+ def translation(data)
+ I18n.available_locales # triggers loading existing translations
+ I18n.backend.store_translations(:en, data)
+ end
+end
+
+class AdditionalLinkAttributesRenderer < WillPaginate::ActionView::LinkRenderer
+ def initialize(link_attributes = nil)
+ super()
+ @additional_link_attributes = link_attributes || { :default => 'true' }
+ end
+
+ def link(text, target, attributes = {})
+ super(text, target, attributes.merge(@additional_link_attributes))
+ end
+end
+
+class DummyController
+ attr_reader :request
+ attr_accessor :controller_name
+
+ include ActionController::UrlFor
+ include Routes.url_helpers
+
+ def initialize
+ @request = DummyRequest.new
+ end
+
+ def params
+ @request.params
+ end
+
+ def env
+ {}
+ end
+
+ def _prefixes
+ []
+ end
+end
+
+class IbocorpController < DummyController
+end
+
+class DummyRequest
+ attr_accessor :symbolized_path_parameters
+
+ def initialize
+ @get = true
+ @params = {}
+ @symbolized_path_parameters = { :controller => 'foo', :action => 'bar' }
+ end
+
+ def get?
+ @get
+ end
+
+ def post
+ @get = false
+ end
+
+ def relative_url_root
+ ''
+ end
+
+ def script_name
+ ''
+ end
+
+ def params(more = nil)
+ @params.update(more) if more
+ @params
+ end
+
+ def host_with_port
+ 'example.com'
+ end
+ alias host host_with_port
+
+ def optional_port
+ ''
+ end
+
+ def protocol
+ 'http:'
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/view_helpers/base_spec.rb b/vendor/plugins/will_paginate/spec/view_helpers/base_spec.rb
new file mode 100644
index 0000000..5fd97f1
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/view_helpers/base_spec.rb
@@ -0,0 +1,142 @@
+require 'spec_helper'
+require 'will_paginate/view_helpers'
+require 'will_paginate/array'
+require 'active_support'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/inflections'
+
+describe WillPaginate::ViewHelpers do
+
+ before(:all) do
+ # make sure default translations aren't loaded
+ I18n.load_path.clear
+ end
+
+ before(:each) do
+ I18n.reload!
+ end
+
+ include WillPaginate::ViewHelpers
+
+ describe "will_paginate" do
+ it "should render" do
+ collection = WillPaginate::Collection.new(1, 2, 4)
+ renderer = mock 'Renderer'
+ renderer.expects(:prepare).with(collection, instance_of(Hash), self)
+ renderer.expects(:to_html).returns('')
+
+ will_paginate(collection, :renderer => renderer).should == ''
+ end
+
+ it "should return nil for single-page collections" do
+ collection = mock 'Collection', :total_pages => 1
+ will_paginate(collection).should be_nil
+ end
+
+ it "should call html_safe on result" do
+ collection = WillPaginate::Collection.new(1, 2, 4)
+
+ html = mock 'HTML'
+ html.expects(:html_safe).returns(html)
+ renderer = mock 'Renderer'
+ renderer.stubs(:prepare)
+ renderer.expects(:to_html).returns(html)
+
+ will_paginate(collection, :renderer => renderer).should eql(html)
+ end
+ end
+
+ describe "pagination_options" do
+ let(:pagination_options) { WillPaginate::ViewHelpers.pagination_options }
+
+ it "deprecates setting :renderer" do
+ begin
+ lambda {
+ pagination_options[:renderer] = 'test'
+ }.should have_deprecation("pagination_options[:renderer] shouldn't be set")
+ ensure
+ pagination_options.delete :renderer
+ end
+ end
+ end
+
+ describe "page_entries_info" do
+ before :all do
+ @array = ('a'..'z').to_a
+ end
+
+ def info(params, options = {})
+ collection = Hash === params ? @array.paginate(params) : params
+ page_entries_info collection, {:html => false}.merge(options)
+ end
+
+ it "should display middle results and total count" do
+ info(:page => 2, :per_page => 5).should == "Displaying strings 6 - 10 of 26 in total"
+ end
+
+ it "uses translation if available" do
+ translation :will_paginate => {
+ :page_entries_info => {:multi_page => 'Showing %{from} - %{to}'}
+ }
+ info(:page => 2, :per_page => 5).should == "Showing 6 - 10"
+ end
+
+ it "uses specific translation if available" do
+ translation :will_paginate => {
+ :page_entries_info => {:multi_page => 'Showing %{from} - %{to}'},
+ :string => { :page_entries_info => {:multi_page => 'Strings %{from} to %{to}'} }
+ }
+ info(:page => 2, :per_page => 5).should == "Strings 6 to 10"
+ end
+
+ it "should output HTML by default" do
+ info({ :page => 2, :per_page => 5 }, :html => true).should ==
+ "Displaying strings 6 - 10 of 26 in total"
+ end
+
+ it "should display shortened end results" do
+ info(:page => 7, :per_page => 4).should include_phrase('strings 25 - 26')
+ end
+
+ it "should handle longer class names" do
+ collection = @array.paginate(:page => 2, :per_page => 5)
+ model = stub('Class', :name => 'ProjectType', :to_s => 'ProjectType')
+ collection.first.stubs(:class).returns(model)
+ info(collection).should include_phrase('project types')
+ end
+
+ it "should adjust output for single-page collections" do
+ info(('a'..'d').to_a.paginate(:page => 1, :per_page => 5)).should == "Displaying all 4 strings"
+ info(['a'].paginate(:page => 1, :per_page => 5)).should == "Displaying 1 string"
+ end
+
+ it "should display 'no entries found' for empty collections" do
+ info([].paginate(:page => 1, :per_page => 5)).should == "No entries found"
+ end
+
+ it "uses model_name.human when available" do
+ name = stub('model name', :i18n_key => :flower_key)
+ name.expects(:human).with(:count => 1).returns('flower')
+ model = stub('Class', :model_name => name)
+ collection = [1].paginate(:page => 1)
+
+ info(collection, :model => model).should == "Displaying 1 flower"
+ end
+
+ it "uses custom translation instead of model_name.human" do
+ name = stub('model name', :i18n_key => :flower_key)
+ name.expects(:human).never
+ model = stub('Class', :model_name => name)
+ translation :will_paginate => {:models => {:flower_key => 'tulip'}}
+ collection = [1].paginate(:page => 1)
+
+ info(collection, :model => model).should == "Displaying 1 tulip"
+ end
+
+ private
+
+ def translation(data)
+ I18n.backend.store_translations(:en, data)
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/spec/view_helpers/link_renderer_base_spec.rb b/vendor/plugins/will_paginate/spec/view_helpers/link_renderer_base_spec.rb
new file mode 100644
index 0000000..cdf5f9b
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/view_helpers/link_renderer_base_spec.rb
@@ -0,0 +1,87 @@
+require 'spec_helper'
+require 'will_paginate/view_helpers/link_renderer_base'
+require 'will_paginate/collection'
+
+describe WillPaginate::ViewHelpers::LinkRendererBase do
+
+ before do
+ @renderer = described_class.new
+ end
+
+ it "should raise error when unprepared" do
+ lambda {
+ @renderer.pagination
+ }.should raise_error
+ end
+
+ it "should prepare with collection and options" do
+ prepare({})
+ @renderer.send(:current_page).should == 1
+ end
+
+ it "should have total_pages accessor" do
+ prepare :total_pages => 42
+ @renderer.send(:total_pages).should == 42
+ end
+
+ it "should clear old cached values when prepared" do
+ prepare(:total_pages => 1)
+ @renderer.send(:total_pages).should == 1
+ # prepare with different object:
+ prepare(:total_pages => 2)
+ @renderer.send(:total_pages).should == 2
+ end
+
+ it "should have pagination definition" do
+ prepare({ :total_pages => 1 }, :page_links => true)
+ @renderer.pagination.should == [:previous_page, 1, :next_page]
+ end
+
+ describe "visible page numbers" do
+ it "should calculate windowed visible links" do
+ prepare({ :page => 6, :total_pages => 11 }, :inner_window => 1, :outer_window => 1)
+ showing_pages 1, 2, :gap, 5, 6, 7, :gap, 10, 11
+ end
+
+ it "should eliminate small gaps" do
+ prepare({ :page => 6, :total_pages => 11 }, :inner_window => 2, :outer_window => 1)
+ # pages 4 and 8 appear instead of the gap
+ showing_pages 1..11
+ end
+
+ it "should support having no windows at all" do
+ prepare({ :page => 4, :total_pages => 7 }, :inner_window => 0, :outer_window => 0)
+ showing_pages 1, :gap, 4, :gap, 7
+ end
+
+ it "should adjust upper limit if lower is out of bounds" do
+ prepare({ :page => 1, :total_pages => 10 }, :inner_window => 2, :outer_window => 1)
+ showing_pages 1, 2, 3, 4, 5, :gap, 9, 10
+ end
+
+ it "should adjust lower limit if upper is out of bounds" do
+ prepare({ :page => 10, :total_pages => 10 }, :inner_window => 2, :outer_window => 1)
+ showing_pages 1, 2, :gap, 6, 7, 8, 9, 10
+ end
+
+ def showing_pages(*pages)
+ pages = pages.first.to_a if Array === pages.first or Range === pages.first
+ @renderer.send(:windowed_page_numbers).should == pages
+ end
+ end
+
+ protected
+
+ def collection(params = {})
+ if params[:total_pages]
+ params[:per_page] = 1
+ params[:total_entries] = params[:total_pages]
+ end
+ WillPaginate::Collection.new(params[:page] || 1, params[:per_page] || 30, params[:total_entries])
+ end
+
+ def prepare(collection_options, options = {})
+ @renderer.prepare(collection(collection_options), options)
+ end
+
+end
diff --git a/vendor/plugins/will_paginate/spec/view_helpers/view_example_group.rb b/vendor/plugins/will_paginate/spec/view_helpers/view_example_group.rb
new file mode 100644
index 0000000..b9c3509
--- /dev/null
+++ b/vendor/plugins/will_paginate/spec/view_helpers/view_example_group.rb
@@ -0,0 +1,121 @@
+require 'active_support'
+begin
+ require 'minitest/unit'
+rescue LoadError
+ # Fails on Ruby 1.8, but it's OK since we only need MiniTest::Assertions
+ # on Rails 4 which doesn't support 1.8 anyway.
+end
+require 'action_dispatch/testing/assertions'
+require 'will_paginate/array'
+
+module ViewExampleGroup
+
+ include ActionDispatch::Assertions::SelectorAssertions
+ include MiniTest::Assertions if defined? MiniTest
+
+ def assert(value, message)
+ raise message unless value
+ end
+
+ def paginate(collection = {}, options = {}, &block)
+ if collection.instance_of? Hash
+ page_options = { :page => 1, :total_entries => 11, :per_page => 4 }.merge(collection)
+ collection = [1].paginate(page_options)
+ end
+
+ locals = { :collection => collection, :options => options }
+
+ @render_output = render(locals)
+ @html_document = nil
+
+ if block_given?
+ classname = options[:class] || WillPaginate::ViewHelpers.pagination_options[:class]
+ assert_select("div.#{classname}", 1, 'no main DIV', &block)
+ end
+
+ @render_output
+ end
+
+ def html_document
+ @html_document ||= HTML::Document.new(@render_output, true, false)
+ end
+
+ def response_from_page_or_rjs
+ html_document.root
+ end
+
+ def validate_page_numbers(expected, links, param_name = :page)
+ param_pattern = /\W#{Regexp.escape(param_name.to_s)}=([^&]*)/
+
+ links.map { |el|
+ unescape_href(el) =~ param_pattern
+ $1 ? $1.to_i : $1
+ }.should == expected
+ end
+
+ def assert_links_match(pattern, links = nil, numbers = nil)
+ links ||= assert_select 'div.pagination a[href]' do |elements|
+ elements
+ end
+
+ pages = [] if numbers
+
+ links.each do |el|
+ href = unescape_href(el)
+ href.should =~ pattern
+ if numbers
+ href =~ pattern
+ pages << ($1.nil?? nil : $1.to_i)
+ end
+ end
+
+ pages.should == numbers if numbers
+ end
+
+ def assert_no_links_match(pattern)
+ assert_select 'div.pagination a[href]' do |elements|
+ elements.each do |el|
+ unescape_href(el).should_not =~ pattern
+ end
+ end
+ end
+
+ def unescape_href(el)
+ CGI.unescape CGI.unescapeHTML(el['href'])
+ end
+
+ def build_message(message, pattern, *args)
+ built_message = pattern.dup
+ for value in args
+ built_message.sub! '?', value.inspect
+ end
+ built_message
+ end
+
+end
+
+RSpec.configure do |config|
+ config.include ViewExampleGroup, :type => :view, :example_group => {
+ :file_path => %r{spec/view_helpers/}
+ }
+end
+
+module HTML
+ Node.class_eval do
+ def inner_text
+ children.map(&:inner_text).join('')
+ end
+ end
+
+ Text.class_eval do
+ def inner_text
+ self.to_s
+ end
+ end
+
+ Tag.class_eval do
+ def inner_text
+ childless?? '' : super
+ end
+ end
+end
diff --git a/vendor/plugins/will_paginate/will_paginate.gemspec b/vendor/plugins/will_paginate/will_paginate.gemspec
new file mode 100644
index 0000000..cac7b6c
--- /dev/null
+++ b/vendor/plugins/will_paginate/will_paginate.gemspec
@@ -0,0 +1,30 @@
+# encoding: utf-8
+require 'rbconfig'
+require File.expand_path('../lib/will_paginate/version', __FILE__)
+
+Gem::Specification.new do |s|
+ s.name = 'will_paginate'
+ s.version = WillPaginate::VERSION::STRING
+
+ s.summary = "Pagination plugin for web frameworks and other apps"
+ s.description = "will_paginate provides a simple API for performing paginated queries with Active Record, DataMapper and Sequel, and includes helpers for rendering pagination links in Rails, Sinatra and Merb web apps."
+
+ s.authors = ['Mislav Marohnić']
+ s.email = 'mislav.marohnic@gmail.com'
+ s.homepage = 'https://github.com/mislav/will_paginate/wiki'
+ s.license = 'MIT'
+
+ s.rdoc_options = ['--main', 'README.md', '--charset=UTF-8']
+ s.extra_rdoc_files = ['README.md', 'LICENSE']
+
+ s.files = Dir['Rakefile', '{bin,lib,test,spec}/**/*', 'README*', 'LICENSE*']
+
+ # include only files in version control
+ git_dir = File.expand_path('../.git', __FILE__)
+ void = defined?(File::NULL) ? File::NULL :
+ RbConfig::CONFIG['host_os'] =~ /msdos|mswin|djgpp|mingw/ ? 'NUL' : '/dev/null'
+
+ if File.directory?(git_dir) and system "git --version >>#{void} 2>&1"
+ s.files &= `git --git-dir='#{git_dir}' ls-files -z`.split("\0")
+ end
+end
--
libgit2 0.21.2