Created
January 16, 2015 10:10
-
-
Save vassilevsky/db1024be724166ec0294 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/.document b/.document | |
index 3d618dd..3bab9e5 100644 | |
--- a/.document | |
+++ b/.document | |
@@ -1,5 +1,2 @@ | |
lib/**/*.rb | |
-bin/* | |
-- | |
-features/**/*.feature | |
-LICENSE.txt | |
+MIT-LICENSE | |
diff --git a/.gitignore b/.gitignore | |
index d7452db..d232f91 100644 | |
--- a/.gitignore | |
+++ b/.gitignore | |
@@ -1,6 +1,9 @@ | |
*.gem | |
.bundle | |
+.idea | |
Gemfile.lock | |
+gemfiles/*.lock | |
+coverage/* | |
pkg/* | |
doc | |
diff --git a/.travis.yml b/.travis.yml | |
index ba14b0b..fd68d2f 100644 | |
--- a/.travis.yml | |
+++ b/.travis.yml | |
@@ -1,6 +1,53 @@ | |
+services: mongodb | |
+ | |
+script: "bundle exec rake spec" | |
+ | |
rvm: | |
- 1.8.7 | |
- 1.9.3 | |
+ - 2.0.0 | |
+ - 2.1 | |
- ruby-head | |
+ - jruby | |
+ - rbx-2 | |
+ | |
+gemfile: | |
+ - gemfiles/active_record_30.gemfile | |
+ - gemfiles/active_record_31.gemfile | |
+ - gemfiles/active_record_32.gemfile | |
+ - gemfiles/active_record_40.gemfile | |
+ - gemfiles/active_record_41.gemfile | |
+ - gemfiles/active_record_edge.gemfile | |
+ - gemfiles/data_mapper_12.gemfile | |
+ - gemfiles/mongo_mapper.gemfile | |
+ - gemfiles/mongoid_24.gemfile | |
+ - gemfiles/mongoid_30.gemfile | |
+ - gemfiles/mongoid_31.gemfile | |
+ - gemfiles/mongoid_40.gemfile | |
+ - gemfiles/sinatra_13.gemfile | |
+ - gemfiles/sinatra_14.gemfile | |
-script: bundle exec rake spec | |
+matrix: | |
+ exclude: | |
+ - rvm: 1.8.7 | |
+ gemfile: gemfiles/active_record_40.gemfile | |
+ - rvm: 1.8.7 | |
+ gemfile: gemfiles/active_record_41.gemfile | |
+ - rvm: 1.8.7 | |
+ gemfile: gemfiles/active_record_edge.gemfile | |
+ - rvm: 1.8.7 | |
+ gemfile: gemfiles/mongoid_30.gemfile | |
+ - rvm: 1.8.7 | |
+ gemfile: gemfiles/mongoid_31.gemfile | |
+ - rvm: 1.8.7 | |
+ gemfile: gemfiles/mongoid_40.gemfile | |
+ - rvm: ruby-head | |
+ gemfile: gemfiles/active_record_30.gemfile | |
+ - rvm: ruby-head | |
+ gemfile: gemfiles/active_record_31.gemfile | |
+ - rvm: ruby-head | |
+ gemfile: gemfiles/active_record_32.gemfile | |
+ allow_failures: | |
+ - rvm: ruby-head | |
+ - gemfile: gemfiles/active_record_edge.gemfile | |
+ fast_finish: true | |
diff --git a/CHANGELOG b/CHANGELOG | |
deleted file mode 100644 | |
index 859d2a5..0000000 | |
--- a/CHANGELOG | |
+++ /dev/null | |
@@ -1,307 +0,0 @@ | |
-== 0.13.0 | |
- | |
-* Rails 3.2 ready! #180 [slbug] | |
- | |
-* DataMapper support! #149 [NoICE, Ragmaanir] | |
- | |
-* Sinatra & Padrino support! #179 [udzura, mlightner, aereal] | |
- | |
-* Added mongoid embedded documents support! #155 [yuki24] | |
- | |
-* Added `each_relevant_page` that only visits pages in the inner or outer | |
-windows #154 [cbeer] | |
- Performance improved, particularly with very large number of pages. | |
- | |
-* Memoize count for AR when calling `total_count` #138 [sarmiena] | |
- Increases performance for large datasets. | |
- | |
-* Added `page_entries_info` view helper #140 [jeffreyiacono] | |
- Example: | |
- <%= page_entries_info @posts %> | |
- #=> Displaying posts 6 - 10 of 26 in total | |
- | |
-* Added `link_to_next_page` helper method that simply links to the next page | |
- Example: | |
- <%= link_to_next_page @posts, 'More' %> | |
- #=> <a href="/posts?page=7" rel="next">More</a> | |
- | |
-* Let one override the `rel` attribute for 'link_to_next_page` helper #177 | |
-[webmat] | |
- | |
-* Added `total_count` param for PaginatableArray. Useful for when working with | |
-RSolr #141 [samdalton] | |
- | |
-* Changed `Kaminari.paginate_array` API to take a Hash `options` | |
- And specifying :limit & :offset immediately builds a pagination ready object | |
- Example: | |
- # the following two are equivalent. Use whichever you like | |
- Kaminari.paginate_array((1..100).to_a, limit: 10, offset: 10) | |
- Kaminari.paginate_array((1..100).to_a).page(2).per(10) | |
- | |
-* Added `padding` method to skip an arbitrary record count #60 [aaronjensen] | |
- Example: | |
- User.page(2).per(10).padding(3) # this will return users 14..23 | |
- | |
-* Made the pagination method name (defaulted to `page`) configurable #57, #162 | |
- Example: | |
- # you can use the config file and its generator for this | |
- Kaminari.config.page_method_name = :paging | |
- Article.paging(3).per(30) | |
- | |
-* Only add extensions to direct descendents of ActiveRecord::Base #108 | |
-[seejohnrun] | |
- | |
-* AR models that were subclassed before Kaminari::ActiveRecordExtension is | |
-included pick up the extensions #119 [pivotal-casebook] | |
- | |
-* Avoid overwriting AR::Base inherited method #165 [briandmcnabb] | |
- | |
-* Stopped depending on Rails gem #159 [alsemyonov] | |
- | |
-* introduced Travis CI #181 [hsbt] | |
- | |
-== 0.12.4 | |
- | |
-* Support for config.param_name as lambda #102 [ajrkerr] | |
- | |
-* Stop duplicating order_values #65 [zettabyte] | |
- | |
-* Preserve select value (e.g. "distinct") when counting #77, #104 [tbeauvais, | |
-beatlevic] | |
- | |
-== 0.12.3 | |
- | |
-* Haml 3.1 Support #96 [FlyboyArt, sonic921] | |
- | |
-== 0.12.2 | |
- | |
-* Added MongoMapper Support #101 [hamin] | |
- | |
-* Add first_page? and last_page? to page_scope_methods #51 [holinnn] | |
- | |
-* Make sure that the paginate helper always returns a String #99 [Draiken] | |
- | |
-* Don't remove includes scopes from count if they are needed #100 [flop] | |
- | |
-== 0.12.1 | |
- | |
-* Slim template support #93 [detrain] | |
- | |
-* Use Kaminari.config to specify default value for param_name #94 [avsej] | |
- | |
-* Fixed "super called outside of method" error happened in particular versions | |
-of Ruby 1.8.7 #91 [Skulli] | |
- | |
-* _paginate.html.erb isn't rendered with custom theme #97 [danlunde] | |
- | |
-== 0.12.0 | |
- | |
-* General configuration options #41 #62 [javierv, iain] | |
- You can now globally override some default values such as default_per_page, | |
- window, etc. via configuration file. | |
- Also, here comes a generator command that generates the default | |
- configuration file into your app's config/initilizers directory. | |
- | |
-* Generic pagination support for Array object #47 #68 #74 [lda, ened, jianlin] | |
- You can now paginate through any kind of Arrayish object in this way: | |
- Kaminari.paginate_array(my_array_object).page(params[:page]).per(10) | |
- | |
-* Fixed a serious performance regression in 0.11.0 [ankane] | |
- There was a critical performance issue on #count method in 0.11.0 gem. | |
- | |
-* Bugfix: Pass the real @params to url_for #90 [utkarshkukreti] | |
- | |
-* Fixed a gem packaging problem (circular dependency) | |
- There was a packaging problem with Kaminari 0.11.0 that the gem depends on | |
- Kaminari gem. Maybe Jeweler + "gemspec" method didn't work well... | |
- | |
-== 0.11.0 | |
- | |
-This release contains several backward incompatibilities on template API. | |
-You probably need to update your existing templates if you're already using | |
-your own custom theme. | |
- | |
-* Merge _current_page, _first_page_link, _last_page_link and _page_link into | |
-one _page partial #28 [GarthSnyder] | |
- | |
-* Add real first/last page links, and use them by default instead of outer | |
-window #30 [GarthSnyder] | |
- | |
-* The disabled items should simply not be emitted, even as an empty span #30 | |
-[GarthSnyder] | |
- | |
-* Skip :order in #count_all so complex groups with generated columns don't | |
-blow up in SQL-land #61 [keeran, Empact] | |
- | |
-* Ignore :include in #count_all to make it work better with polymorphic eager | |
-loading #80 [njakobsen] | |
- | |
-* Quick fix on #count to return the actual number of records on AR 3.0 #45 #50 | |
- | |
-* Removed "TERRIBLE HORRIBLE NO GOOD VERY BAD HACK" #82 [janx, flop, pda] | |
- | |
-* Allow for Multiple Themes #64 [tmilewski] | |
- | |
-* Themes can contain the whole application directory structure now | |
- | |
-* Use gemspec method in Gemfile [p_elliott] | |
- | |
-== 0.10.4 | |
- | |
-* Do not break ActiveRecord::Base.descendants, by making sure to call super | |
-from ActiveRecord::Base.inherited #34 [rolftimmermans] | |
- | |
-* Fixed vanishing mongoid criteria after calling page() #26 [tyok] | |
- | |
-== 0.10.3 | |
- | |
-* Fixed a bug that total_count() didn't work when chained with group() scope | |
-#21 [jgeiger] | |
- | |
-* Fixed a bug that the paginate helper didn't work properly with an Ajax call | |
-#23 [hjuskewycz] | |
- | |
-== 0.10.2 | |
- | |
-* Added :param_name option to the pagination helper #10 [ivanvr] | |
- Example: | |
- = paginate @users, :param_name => :pagina | |
- | |
-== 0.10.1 | |
- | |
-* Fixed a bug that the whole <nav> section was not rendered in some cases | |
-[GarthSnyder] | |
- | |
-== 0.10.0 | |
- | |
-* Railtie initializer name is "kaminari" from now | |
-* Changed bundler settings to work both on 1.9.2 and 1.8.7 #12 [l15n] | |
-* Fixed bugs encountered when running specs on Ruby 1.9.2 #12 [l15n] | |
-* Clean up documentation (formatting and editing) #12 [l15n] | |
-* Use Proc.new instead of lambda for scoped_options #13 [l15n] | |
-* Use AS hooks for loading AR #14 [hasimo] | |
-* Refactor scope definition with Concerns #15 [l15n] | |
-* Ensure output_buffer is always initialized #11 [kichiro] | |
- | |
-== 0.9.13 | |
- | |
-* Added Mongoid support #5 [juno, hibariya] | |
- This means, Kaminari is now *ORM agnostic* ☇3☇3☇3 | |
- | |
-== 0.9.12 | |
- | |
-* Moved the whole pagination logic to the paginator partial so that users can | |
-touch it | |
- Note: You need to update your _paginator.html.* if you've already customized | |
- it. If you haven't overridden _paginator.html.* files, then probably | |
- there're nothing you have to do. | |
- See this commit for the example: | |
- https://github.com/amatsuda/kaminari_themes/commit/2dfb41c | |
- | |
-== 0.9.10 | |
- | |
-* the per() method accepts String, zero and minus value now #7 [koic] | |
- This enables you to do something like this: | |
- Model.page(params[:page]).per(params[:per]) | |
- | |
-* Added support for Gem Testers (http://gem-testers.org/) #8 [joealba] | |
- | |
-== 0.9.9 | |
- | |
-* :params option for the helper [yomukaku_memo] | |
- You can override each link's url_for option by this option | |
- Example: | |
- = paginate @users, :params => {:controller => 'users', :action => 'index2'} | |
- | |
-* refactor tags | |
- | |
-== 0.9.8 | |
- | |
-* I18n for the partials | |
- [:previous, :next, :truncate] are externalized to the I18n resource. | |
- | |
-== 0.9.7 | |
- | |
-* moved template themes to another repo | |
- https://github.com/amatsuda/kaminari_themes | |
- | |
-== 0.9.6 | |
- | |
-* added paginates_per method for setting default per_page value for each model | |
-in a declarative way | |
- Example: | |
- class Article < ActiveRecord::Base | |
- paginates_per 10 | |
- end | |
- | |
-== 0.9.5 | |
- | |
-* works on AR 3.0.0 and 3.0.1 now #4 [danillos] | |
- | |
-== 0.9.4 | |
- | |
-* introduced module based tags | |
- As a side effect of this internal change, I have to confess that this | |
- version brings you a slight backward incompatibility on template API. | |
- If you're using custom templates, be sure to update your existing templates. | |
- To catch up the new API, you need to update %w[next_url prev_url page_url] | |
- local variables to simple 'url' like this. | |
- https://github.com/amatsuda/kaminari/commit/da88729 | |
- | |
-== 0.9.3 | |
- | |
-* improved template detection logic | |
- When a template for a tag could not be found in the app/views/kaminari/ | |
- directory, it searches the tag's ancestor template files before falling back | |
- to engine's default template. This may help keeping your custom templates DRY. | |
- | |
-* simplified bundled template themes | |
- | |
-== 0.9.2 | |
- | |
-* stop adding extra LF between templates when joining | |
- | |
-* githubish template theme [maztomo] | |
- | |
-== 0.9.1 | |
- | |
-* googlish template theme [maztomo] | |
- | |
-== 0.9.0 | |
- | |
-* added "per_page" to the template local variables #3 [hsbt] | |
- | |
-* show no contents when the current page is the only page (in other words, | |
-num_pages == 1) #2 [hsbt] | |
- | |
-== 0.8.0 | |
- | |
-* using HTML5 <nav> tag rather than <div> for the container tag | |
- | |
-== 0.7.0 | |
- | |
-* Ajaxified paginator templates | |
- | |
-== 0.6.0 | |
- | |
-* Hamlized paginator templates | |
- | |
-== 0.5.0 | |
- | |
-* reset content_for :kaminari_paginator_tags before rendering #1 [hsbt] | |
- | |
-== 0.4.0 | |
- | |
-* partialize the outer div | |
- | |
-== 0.3.0 | |
- | |
-* suppress logging when rendering each partial | |
- | |
-== 0.2.0 | |
- | |
-* default PER_PAGE to 25 [hsbt] | |
- | |
-== 0.1.0 | |
- | |
-* First release | |
diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc | |
new file mode 100644 | |
index 0000000..805fc44 | |
--- /dev/null | |
+++ b/CHANGELOG.rdoc | |
@@ -0,0 +1,423 @@ | |
+== 0.16.1 | |
+ | |
+* Fix a bug where :theme option for #paginate method doesn't work properly | |
+#566 [commstratdev] | |
+ | |
+== 0.16.0 | |
+ | |
+* Add support for mongoid max_scan option #500 [aptx4869] | |
+ | |
+* Add `link_to_previous_page` helper for Sinatra #504 [ikeay] | |
+ | |
+* Add :views_prefix option to #paginate for alternative views directory #552 | |
+[apotonick] | |
+ | |
+* Simplify `page_entries_info` by adding entry_name interface to each ORM | |
+ | |
+* Refer ActiveRecord::Base from top level namespace for more safety when | |
+inherited class's namespace has 'ActiveRecord' constant #522 [yuroyoro] | |
+ | |
+* Fix a bug where runtime persistence not taken into account with | |
+mongoid/kaminari #326 [nubeod] | |
+ | |
+* Fix a bug where helper methods were not available from inside | |
+`paginator.render do ... end` block #239 [damien-roche] | |
+ | |
+* Fix a bug where theme generator didn't work on Rails 4.1 #526 [jimryan] | |
+ | |
+* Fix a bug that paginatable arrays with `total_count` option always returns | |
+whole array #516 [abhichvn] | |
+ | |
+== 0.15.1 | |
+ | |
+* page_method_name option was not working in 0.15.0 #481 [mauriciopasquier] | |
+ | |
+* Use the mongoid criteria #length method to cache the count of the collection | |
+per criteria #484 [camallen] | |
+ | |
+* Don't inherit host, port, and protocol from the given params | |
+ | |
+== 0.15.0 | |
+ | |
+* Allow count, total count to pass parameters to super #193 [bsimpson] | |
+ | |
+* Add `max_pages` and `max_pages_per` methods to limit displayed pages per | |
+model or globally #301 [zpieslak] | |
+ | |
+* Add support for Sinatra views overrides (add app views paths) #332 [j15e] | |
+ | |
+* Fix wrong pagination when used with `padding` #359 [vladimir-vg, negipo] | |
+ | |
+* check for Hash in addition to OrderedHash, which seems to break in Rails 4, | |
+for total_count #369 [aew] | |
+ | |
+* Make `to_s` in paginator threadsafe #374 [bf4] | |
+ | |
+* Fix Missing partial Error when 'paginate' called from different format | |
+template #381 [joker1007] | |
+ | |
+* Add `PageScopeMethods#next_page`, `prev_page`, and `out_of_range?` [yuki24] | |
+ | |
+* Use html_safe in view partials instead of raw fixed #73 [zzak] | |
+ | |
+* Fix a bug that `PaginatableArray#total_pages` returns the wrong value #416 [yuki24] | |
+ | |
+* Make `num_pages` to return the same value as `total_pages` for backward compat [yuki24, eitoball] | |
+ | |
+* Change #page_entries_info to use model name #340, #348 [znz, eitoball] | |
+ | |
+* Change scope to class method #433 [kolodovskyy] | |
+ | |
+* Fix arity problem with Rails 4.1.0 #449 [bricker] | |
+ | |
+== 0.14.1 | |
+ | |
+* Changed the default "truncation" String from "..." to … #264 [pjaspers] | |
+ | |
+* The theme generator is Github API v3 compatible now! #279 [eitoball] | |
+ | |
+* Made Kaminari.config.default_per_page changeable again #280 [yuki24] | |
+ | |
+== 0.14.0 | |
+ | |
+* Grape framework support! #218 [mrplum] | |
+ | |
+* Mongoid 3 ready! #238 [shingara] | |
+ | |
+* Added link_to_previous_page helper #191 [timgremore] | |
+ | |
+* Added helper to generate rel="next" and rel="prev" link tags for SEO #200 | |
+[joe1chen] | |
+ | |
+* Added `max_per_page` configuration option #274 [keiko0713] | |
+ This would be useful for the case when you are using user input `per_page` | |
+ value but want to impose the upper bound. | |
+ | |
+* Added I18n to page_entries_info #207 [plribeiro3000] | |
+ | |
+* Changed method name "num_pages" to "total_pages" | |
+ num_pages" is still available as an alias of "total_pages", but will be | |
+ deprecated or removed in some future version. | |
+ | |
+* Changed the way page_entries_info behave so it can show appropriate names | |
+for models with namespace #207 [plribeiro3000] | |
+ | |
+* Added html_safe to page_entries_info helper #190 [lucapette] | |
+ | |
+* Fixed displayed number of items on each page w/ Mongoid 2.4.x and | |
+MongoMapper #194 [dblock] | |
+ | |
+* Removed a unused local variable from templates from default tamplate #245 [juno] | |
+ | |
+* Fixed page_entry_info to use the value of `entry_name` option when given | |
+collection is empty or a PaginatableArray #265, #277 [eitoball] | |
+ | |
+* Added require 'dm-aggregates' in DataMapper hook #259 [shingara] | |
+ | |
+== 0.13.0 | |
+ | |
+* Rails 3.2 ready! #180 [slbug] | |
+ | |
+* DataMapper support! #149 [NoICE, Ragmaanir] | |
+ | |
+* Sinatra & Padrino support! #179 [udzura, mlightner, aereal] | |
+ | |
+* Added mongoid embedded documents support! #155 [yuki24] | |
+ | |
+* Added `each_relevant_page` that only visits pages in the inner or outer | |
+windows #154 [cbeer] | |
+ Performance improved, particularly with very large number of pages. | |
+ | |
+* Memoize count for AR when calling `total_count` #138 [sarmiena] | |
+ Increases performance for large datasets. | |
+ | |
+* Added `page_entries_info` view helper #140 [jeffreyiacono] | |
+ Example: | |
+ <%= page_entries_info @posts %> | |
+ #=> Displaying posts 6 - 10 of 26 in total | |
+ | |
+* Added `link_to_next_page` helper method that simply links to the next page | |
+ Example: | |
+ <%= link_to_next_page @posts, 'More' %> | |
+ #=> <a href="/posts?page=7" rel="next">More</a> | |
+ | |
+* Let one override the `rel` attribute for 'link_to_next_page` helper #177 | |
+[webmat] | |
+ | |
+* Added `total_count` param for PaginatableArray. Useful for when working with | |
+RSolr #141 [samdalton] | |
+ | |
+* Changed `Kaminari.paginate_array` API to take a Hash `options` | |
+ And specifying :limit & :offset immediately builds a pagination ready object | |
+ Example: | |
+ # the following two are equivalent. Use whichever you like | |
+ Kaminari.paginate_array((1..100).to_a, limit: 10, offset: 10) | |
+ Kaminari.paginate_array((1..100).to_a).page(2).per(10) | |
+ | |
+* Added `padding` method to skip an arbitrary record count #60 [aaronjensen] | |
+ Example: | |
+ User.page(2).per(10).padding(3) # this will return users 14..23 | |
+ | |
+* Made the pagination method name (defaulted to `page`) configurable #57, #162 | |
+ Example: | |
+ # you can use the config file and its generator for this | |
+ Kaminari.config.page_method_name = :paging | |
+ Article.paging(3).per(30) | |
+ | |
+* Only add extensions to direct descendents of ActiveRecord::Base #108 | |
+[seejohnrun] | |
+ | |
+* AR models that were subclassed before Kaminari::ActiveRecordExtension is | |
+included pick up the extensions #119 [pivotal-casebook] | |
+ | |
+* Avoid overwriting AR::Base inherited method #165 [briandmcnabb] | |
+ | |
+* Stopped depending on Rails gem #159 [alsemyonov] | |
+ | |
+* introduced Travis CI #181 [hsbt] | |
+ | |
+== 0.12.4 | |
+ | |
+* Support for config.param_name as lambda #102 [ajrkerr] | |
+ | |
+* Stop duplicating order_values #65 [zettabyte] | |
+ | |
+* Preserve select value (e.g. "distinct") when counting #77, #104 [tbeauvais, | |
+beatlevic] | |
+ | |
+== 0.12.3 | |
+ | |
+* Haml 3.1 Support #96 [FlyboyArt, sonic921] | |
+ | |
+== 0.12.2 | |
+ | |
+* Added MongoMapper Support #101 [hamin] | |
+ | |
+* Add first_page? and last_page? to page_scope_methods #51 [holinnn] | |
+ | |
+* Make sure that the paginate helper always returns a String #99 [Draiken] | |
+ | |
+* Don't remove includes scopes from count if they are needed #100 [flop] | |
+ | |
+== 0.12.1 | |
+ | |
+* Slim template support #93 [detrain] | |
+ | |
+* Use Kaminari.config to specify default value for param_name #94 [avsej] | |
+ | |
+* Fixed "super called outside of method" error happened in particular versions | |
+of Ruby 1.8.7 #91 [Skulli] | |
+ | |
+* _paginate.html.erb isn't rendered with custom theme #97 [danlunde] | |
+ | |
+== 0.12.0 | |
+ | |
+* General configuration options #41 #62 [javierv, iain] | |
+ You can now globally override some default values such as default_per_page, | |
+ window, etc. via configuration file. | |
+ Also, here comes a generator command that generates the default | |
+ configuration file into your app's config/initilizers directory. | |
+ | |
+* Generic pagination support for Array object #47 #68 #74 [lda, ened, jianlin] | |
+ You can now paginate through any kind of Arrayish object in this way: | |
+ Kaminari.paginate_array(my_array_object).page(params[:page]).per(10) | |
+ | |
+* Fixed a serious performance regression in 0.11.0 [ankane] | |
+ There was a critical performance issue on #count method in 0.11.0 gem. | |
+ | |
+* Bugfix: Pass the real @params to url_for #90 [utkarshkukreti] | |
+ | |
+* Fixed a gem packaging problem (circular dependency) | |
+ There was a packaging problem with Kaminari 0.11.0 that the gem depends on | |
+ Kaminari gem. Maybe Jeweler + "gemspec" method didn't work well... | |
+ | |
+== 0.11.0 | |
+ | |
+This release contains several backward incompatibilities on template API. | |
+You probably need to update your existing templates if you're already using | |
+your own custom theme. | |
+ | |
+* Merge _current_page, _first_page_link, _last_page_link and _page_link into | |
+one _page partial #28 [GarthSnyder] | |
+ | |
+* Add real first/last page links, and use them by default instead of outer | |
+window #30 [GarthSnyder] | |
+ | |
+* The disabled items should simply not be emitted, even as an empty span #30 | |
+[GarthSnyder] | |
+ | |
+* Skip :order in #count_all so complex groups with generated columns don't | |
+blow up in SQL-land #61 [keeran, Empact] | |
+ | |
+* Ignore :include in #count_all to make it work better with polymorphic eager | |
+loading #80 [njakobsen] | |
+ | |
+* Quick fix on #count to return the actual number of records on AR 3.0 #45 #50 | |
+ | |
+* Removed "TERRIBLE HORRIBLE NO GOOD VERY BAD HACK" #82 [janx, flop, pda] | |
+ | |
+* Allow for Multiple Themes #64 [tmilewski] | |
+ | |
+* Themes can contain the whole application directory structure now | |
+ | |
+* Use gemspec method in Gemfile [p_elliott] | |
+ | |
+== 0.10.4 | |
+ | |
+* Do not break ActiveRecord::Base.descendants, by making sure to call super | |
+from ActiveRecord::Base.inherited #34 [rolftimmermans] | |
+ | |
+* Fixed vanishing mongoid criteria after calling page() #26 [tyok] | |
+ | |
+== 0.10.3 | |
+ | |
+* Fixed a bug that total_count() didn't work when chained with group() scope | |
+#21 [jgeiger] | |
+ | |
+* Fixed a bug that the paginate helper didn't work properly with an Ajax call | |
+#23 [hjuskewycz] | |
+ | |
+== 0.10.2 | |
+ | |
+* Added :param_name option to the pagination helper #10 [ivanvr] | |
+ Example: | |
+ = paginate @users, :param_name => :pagina | |
+ | |
+== 0.10.1 | |
+ | |
+* Fixed a bug that the whole <nav> section was not rendered in some cases | |
+[GarthSnyder] | |
+ | |
+== 0.10.0 | |
+ | |
+* Railtie initializer name is "kaminari" from now | |
+* Changed bundler settings to work both on 1.9.2 and 1.8.7 #12 [l15n] | |
+* Fixed bugs encountered when running specs on Ruby 1.9.2 #12 [l15n] | |
+* Clean up documentation (formatting and editing) #12 [l15n] | |
+* Use Proc.new instead of lambda for scoped_options #13 [l15n] | |
+* Use AS hooks for loading AR #14 [hasimo] | |
+* Refactor scope definition with Concerns #15 [l15n] | |
+* Ensure output_buffer is always initialized #11 [kichiro] | |
+ | |
+== 0.9.13 | |
+ | |
+* Added Mongoid support #5 [juno, hibariya] | |
+ This means, Kaminari is now *ORM agnostic* ☇3☇3☇3 | |
+ | |
+== 0.9.12 | |
+ | |
+* Moved the whole pagination logic to the paginator partial so that users can | |
+touch it | |
+ Note: You need to update your _paginator.html.* if you've already customized | |
+ it. If you haven't overridden _paginator.html.* files, then probably | |
+ there're nothing you have to do. | |
+ See this commit for the example: | |
+ https://github.com/amatsuda/kaminari_themes/commit/2dfb41c | |
+ | |
+== 0.9.10 | |
+ | |
+* the per() method accepts String, zero and minus value now #7 [koic] | |
+ This enables you to do something like this: | |
+ Model.page(params[:page]).per(params[:per]) | |
+ | |
+* Added support for Gem Testers (http://gem-testers.org/) #8 [joealba] | |
+ | |
+== 0.9.9 | |
+ | |
+* :params option for the helper [yomukaku_memo] | |
+ You can override each link's url_for option by this option | |
+ Example: | |
+ = paginate @users, :params => {:controller => 'users', :action => 'index2'} | |
+ | |
+* refactor tags | |
+ | |
+== 0.9.8 | |
+ | |
+* I18n for the partials | |
+ [:previous, :next, :truncate] are externalized to the I18n resource. | |
+ | |
+== 0.9.7 | |
+ | |
+* moved template themes to another repo | |
+ https://github.com/amatsuda/kaminari_themes | |
+ | |
+== 0.9.6 | |
+ | |
+* added paginates_per method for setting default per_page value for each model | |
+in a declarative way | |
+ Example: | |
+ class Article < ActiveRecord::Base | |
+ paginates_per 10 | |
+ end | |
+ | |
+== 0.9.5 | |
+ | |
+* works on AR 3.0.0 and 3.0.1 now #4 [danillos] | |
+ | |
+== 0.9.4 | |
+ | |
+* introduced module based tags | |
+ As a side effect of this internal change, I have to confess that this | |
+ version brings you a slight backward incompatibility on template API. | |
+ If you're using custom templates, be sure to update your existing templates. | |
+ To catch up the new API, you need to update %w[next_url prev_url page_url] | |
+ local variables to simple 'url' like this. | |
+ https://github.com/amatsuda/kaminari/commit/da88729 | |
+ | |
+== 0.9.3 | |
+ | |
+* improved template detection logic | |
+ When a template for a tag could not be found in the app/views/kaminari/ | |
+ directory, it searches the tag's ancestor template files before falling back | |
+ to engine's default template. This may help keeping your custom templates DRY. | |
+ | |
+* simplified bundled template themes | |
+ | |
+== 0.9.2 | |
+ | |
+* stop adding extra LF between templates when joining | |
+ | |
+* githubish template theme [maztomo] | |
+ | |
+== 0.9.1 | |
+ | |
+* googlish template theme [maztomo] | |
+ | |
+== 0.9.0 | |
+ | |
+* added "per_page" to the template local variables #3 [hsbt] | |
+ | |
+* show no contents when the current page is the only page (in other words, | |
+num_pages == 1) #2 [hsbt] | |
+ | |
+== 0.8.0 | |
+ | |
+* using HTML5 <nav> tag rather than <div> for the container tag | |
+ | |
+== 0.7.0 | |
+ | |
+* Ajaxified paginator templates | |
+ | |
+== 0.6.0 | |
+ | |
+* Hamlized paginator templates | |
+ | |
+== 0.5.0 | |
+ | |
+* reset content_for :kaminari_paginator_tags before rendering #1 [hsbt] | |
+ | |
+== 0.4.0 | |
+ | |
+* partialize the outer div | |
+ | |
+== 0.3.0 | |
+ | |
+* suppress logging when rendering each partial | |
+ | |
+== 0.2.0 | |
+ | |
+* default PER_PAGE to 25 [hsbt] | |
+ | |
+== 0.1.0 | |
+ | |
+* First release | |
diff --git a/Gemfile b/Gemfile | |
index e90d1af..f57d852 100644 | |
--- a/Gemfile | |
+++ b/Gemfile | |
@@ -1,4 +1,4 @@ | |
-source "http://rubygems.org" | |
+source 'https://rubygems.org' | |
# Specify your gem's dependencies in kaminari.gemspec | |
gemspec | |
diff --git a/README.rdoc b/README.rdoc | |
index bbacee9..709960a 100644 | |
--- a/README.rdoc | |
+++ b/README.rdoc | |
@@ -1,4 +1,4 @@ | |
-= Kaminari | |
+= Kaminari {<img src="https://travis-ci.org/amatsuda/kaminari.svg"/>}[http://travis-ci.org/amatsuda/kaminari] {<img src="https://img.shields.io/codeclimate/github/amatsuda/kaminari.svg" />}[https://codeclimate.com/github/amatsuda/kaminari] {<img src="http://inch-ci.org/github/amatsuda/kaminari.svg" alt="Inline docs" />}[http://inch-ci.org/github/amatsuda/kaminari] | |
A Scope & Engine based, clean, powerful, customizable and sophisticated paginator for modern web app frameworks and ORMs | |
@@ -19,7 +19,7 @@ No special collection class or anything for the paginated values, instead using | |
As the whole pagination helper is basically just a collection of links and non-links, Kaminari renders each of them through its own partial template inside the Engine. So, you can easily modify their behaviour, style or whatever by overriding partial templates. | |
=== ORM & template engine agnostic | |
-Kaminari supports multiple ORMs (ActiveRecord, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra), and multiple template engines (ERB, Haml). | |
+Kaminari supports multiple ORMs (ActiveRecord, DataMapper, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra, Grape), and multiple template engines (ERB, Haml, Slim). | |
=== Modern | |
The pagination helper outputs the HTML5 <nav> tag by default. Plus, the helper supports Rails 3 unobtrusive Ajax. | |
@@ -27,9 +27,9 @@ The pagination helper outputs the HTML5 <nav> tag by default. Plus, the helper s | |
== Supported versions | |
-* Ruby 1.8.7, 1.9.2, 1.9.3, 2.0 (trunk) | |
+* Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.1 | |
-* Rails 3.0.x, 3.1, 3.2, 4.0 (edge) | |
+* Rails 3.0, 3.1, 3.2, 4.0, 4.1 | |
* Haml 3+ | |
@@ -63,9 +63,14 @@ Then bundle: | |
User.page(7).per(50) | |
Note that the +per+ scope is not directly defined on the models but is just a method defined on the page scope. This is absolutely reasonable because you will never actually use +per_page+ without specifying the +page+ number. | |
+ Keep in mind that +per+ utilizes internally +limit+ and so it will override any +limit+ that was set previously | |
+ User.count # => 1000 | |
+ a = User.limit(5).count # => 5 | |
+ b = a.page(1).per(20).size # => 20 | |
+ | |
* the +padding+ scope | |
- Occasionally you need to padding a number of records that is not a multiple of the page size. | |
+ Occasionally you need to pad a number of records that is not a multiple of the page size. | |
User.page(7).per(50).padding(3) | |
Note that the +padding+ scope also is not directly defined on the models. | |
@@ -73,6 +78,8 @@ Then bundle: | |
You can configure the following default values by overriding these values using <tt>Kaminari.configure</tt> method. | |
default_per_page # 25 by default | |
+ max_per_page # nil by default | |
+ max_pages # nil by default | |
window # 4 by default | |
outer_window # 0 by default | |
left # 0 by default | |
@@ -86,7 +93,7 @@ Run the following generator command, then edit the generated file. | |
* changing +page_method_name+ | |
- You can change the method name `page` to `bonzo` or `plant` or whatever you like, in order to play nice with existing `page` method or association or scope or any other plugin that defines `page` method on your models. | |
+ You can change the method name +page+ to +bonzo+ or +plant+ or whatever you like, in order to play nice with existing +page+ method or association or scope or any other plugin that defines +page+ method on your models. | |
=== Configuring default +per_page+ value for each model | |
@@ -98,6 +105,16 @@ Run the following generator command, then edit the generated file. | |
paginates_per 50 | |
end | |
+=== Configuring max +per_page+ value for each model | |
+ | |
+* +max_paginates_per+ | |
+ | |
+ You can specify max +per_page+ value per each model using the following declarative DSL. | |
+ If the variable that specified via +per+ scope is more than this variable, +max_paginates_per+ is used instead of it. Default value is nil, which means you are not imposing any max +per_page+ value. | |
+ class User < ActiveRecord::Base | |
+ max_paginates_per 100 | |
+ end | |
+ | |
=== Controllers | |
* the page parameter is in <tt>params[:page]</tt> | |
@@ -121,17 +138,17 @@ Run the following generator command, then edit the generated file. | |
<%= paginate @users %> | |
This would output several pagination links such as <tt>« First ‹ Prev ... 2 3 4 5 6 7 8 9 10 ... Next › Last »</tt> | |
-* specifing the "inner window" size (4 by default) | |
+* specifying the "inner window" size (4 by default) | |
<%= paginate @users, :window => 2 %> | |
This would output something like <tt>... 5 6 7 8 9 ...</tt> when 7 is the current page. | |
-* specifing the "outer window" size (0 by default) | |
+* specifying the "outer window" size (0 by default) | |
<%= paginate @users, :outer_window => 3 %> | |
This would output something like <tt>1 2 3 4 ...(snip)... 17 18 19 20</tt> while having 20 pages in total. | |
-* outer window can be separetely specified by +left+, +right+ (0 by default) | |
+* outer window can be separately specified by +left+, +right+ (0 by default) | |
<%= paginate @users, :left => 1, :right => 3 %> | |
This would output something like <tt>1 ...(snip)... 18 19 20</tt> while having 20 pages in total. | |
@@ -151,10 +168,15 @@ Run the following generator command, then edit the generated file. | |
<%= paginate @users, :remote => true %> | |
This would add <tt>data-remote="true"</tt> to all the links inside. | |
-* the +link_to_next_page+ helper method | |
+* specifying an alternative views directory (default is <tt>kaminari/</tt>) | |
+ | |
+ <%= paginate @users, :views_prefix => 'templates/' %> | |
+ This would search for partials in <tt>app/views/templates/kaminari</tt>. This option makes it easier to do things like A/B testing pagination templates/themes, using new/old templates at the same time as well as better intergration with other gems sush as {cells}[https://github.com/apotonick/cells]. | |
+ | |
+* the +link_to_next_page+ and +link_to_previous_page+ helper method | |
<%= link_to_next_page @items, 'Next Page' %> | |
- This simply renders a link to the next page. This would be helpful for creating "Twitter like" pagination feature. | |
+ This simply renders a link to the next page. This would be helpful for creating a Twitter-like pagination feature. | |
* the +page_entries_info+ helper method | |
@@ -173,7 +195,16 @@ Keys and the default values are the following. You can override them by adding t | |
last: "Last »" | |
previous: "‹ Prev" | |
next: "Next ›" | |
- truncate: "..." | |
+ truncate: "…" | |
+ helpers: | |
+ page_entries_info: | |
+ one_page: | |
+ display_entries: | |
+ zero: "No %{entry_name} found" | |
+ one: "Displaying <b>1</b> %{entry_name}" | |
+ other: "Displaying <b>all %{count}</b> %{entry_name}" | |
+ more_pages: | |
+ display_entries: "Displaying %{entry_name} <b>%{first} - %{last}</b> of <b>%{total}</b> in total" | |
=== Customizing the pagination helper | |
@@ -195,7 +226,7 @@ Kaminari includes a handy template generator. | |
* themes | |
The generator has the ability to fetch several sample template themes from | |
- the external repository (https://github.com/amatsuda/kaminari_themes) in | |
+ the external repository (https://github.com/amatsuda/kaminari_themes) in | |
addition to the bundled "default" one, which will help you creating a nice | |
looking paginator. | |
% rails g kaminari:views THEME | |
@@ -212,7 +243,7 @@ Kaminari includes a handy template generator. | |
% mkdir my_custom_theme | |
% cp _*.html.* my_custom_theme/ | |
- Next reference that directory when calling the paginate method: | |
+ Next, reference that directory when calling the +paginate+ method: | |
<%= paginate @users, :theme => 'my_custom_theme' %> | |
@@ -225,24 +256,26 @@ Kaminari includes a handy template generator. | |
Kaminari provides an Array wrapper class that adapts a generic Array object to the <tt>paginate</tt> view helper. | |
However, the <tt>paginate</tt> helper doesn't automatically handle your Array object (this is intentional and by design). | |
<tt>Kaminari::paginate_array</tt> method converts your Array object into a paginatable Array that accepts <tt>page</tt> method. | |
- Kaminari.paginate_array(my_array_object).page(params[:page]).per(10) | |
-You can specify the `total_count` value through options Hash. This would be helpful when handling an Array-ish object that has a different `count` value from actual `count` such as RSolr search result. | |
+ @paginatable_array = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10) | |
+You can specify the +total_count+ value through options Hash. This would be helpful when handling an Array-ish object that has a different +count+ value from actual +count+ such as RSolr search result or when you need to generate a custom pagination. For example: | |
+ | |
+ @paginatable_array = Kaminari.paginate_array([], total_count: 145).page(params[:page]).per(10) | |
== Creating friendly URLs and caching | |
-Because of the `page` parameter and Rails 3 routing, you can easily generate SEO and user-friendly URLs. For any resource you'd like to paginate, just add the following to your `routes.rb`: | |
+Because of the +page+ parameter and Rails 3 routing, you can easily generate SEO and user-friendly URLs. For any resource you'd like to paginate, just add the following to your +routes.rb+: | |
resources :my_resources do | |
get 'page/:page', :action => :index, :on => :collection | |
end | |
-This will create URLs like `/my_resources/page/33` instead of `/my_resources?page=33`. This is now a friendly URL, but it also has other added benefits... | |
+This will create URLs like <tt>/my_resources/page/33</tt> instead of <tt>/my_resources?page=33</tt>. This is now a friendly URL, but it also has other added benefits... | |
-Because the `page` parameter is now a URL segment, we can leverage on Rails page caching[http://guides.rubyonrails.org/caching_with_rails.html#page-caching]! | |
+Because the +page+ parameter is now a URL segment, we can leverage on Rails page caching[http://guides.rubyonrails.org/caching_with_rails.html#page-caching]! | |
-NOTE: In this example, I've pointed the route to my `:index` action. You may have defined a custom pagination action in your controller - you should point `:action => :your_custom_action` instead. | |
+NOTE: In this example, I've pointed the route to my <tt>:index</tt> action. You may have defined a custom pagination action in your controller - you should point <tt>:action => :your_custom_action</tt> instead. | |
== Sinatra/Padrino support | |
@@ -257,6 +290,12 @@ or edit gemfile: | |
gem 'kaminari', :require => 'kaminari/sinatra' | |
+This line just enables model-side features, such as <tt>Model#page</tt> and <tt>Model#per</tt>. If you want to use view helpers, please explicitly <tt>register</tt> helpers in your Sinatra or Padrino app: | |
+ | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ | |
+Or, you can implement your own awesome helper :) | |
+ | |
More features are coming, and again, this is still experimental. Please let us know if you found anything wrong with the Sinatra support. | |
@@ -266,9 +305,6 @@ Check out Kaminari recipes on the GitHub Wiki for more advanced tips and techniq | |
https://github.com/amatsuda/kaminari/wiki/Kaminari-recipes | |
-== Build Status {<img src="https://secure.travis-ci.org/amatsuda/kaminari.png"/>}[http://travis-ci.org/amatsuda/kaminari] | |
- | |
- | |
== Questions, Feedback | |
Feel free to message me on Github (amatsuda) or Twitter (@a_matsuda) ☇☇☇ :) | |
@@ -276,7 +312,23 @@ Feel free to message me on Github (amatsuda) or Twitter (@a_matsuda) ☇☇☇ | |
== Contributing to Kaminari | |
-* Fork, fix, then send me a pull request. | |
+Fork, fix, then send a pull request. | |
+ | |
+To run the test suite locally against all supported frameworks: | |
+ | |
+ % bundle install | |
+ % rake spec:all | |
+ | |
+To target the test suite against one framework: | |
+ | |
+ % rake spec:active_record_40 | |
+ | |
+You can find a list of supported spec tasks by running <tt>rake -T</tt>. You may also find it useful to run a specific test | |
+for a specific framework. To do so, you'll have to first make sure you have bundled everything for that configuration, | |
+then you can run the specific test: | |
+ | |
+ % BUNDLE_GEMFILE='gemfiles/active_record_40.gemfile' bundle install | |
+ % BUNDLE_GEMFILE='gemfiles/active_record_40.gemfile' bundle exec rspec ./spec/requests/users_spec.rb | |
== Copyright | |
diff --git a/Rakefile b/Rakefile | |
index 1468421..c9a838a 100644 | |
--- a/Rakefile | |
+++ b/Rakefile | |
@@ -5,18 +5,42 @@ Bundler::GemHelper.install_tasks | |
require 'rspec/core' | |
require 'rspec/core/rake_task' | |
+ | |
RSpec::Core::RakeTask.new(:spec) do |spec| | |
spec.pattern = FileList['spec/**/*_spec.rb'] | |
end | |
-task :default => :spec | |
+task :default => "spec:all" | |
+ | |
+namespace :spec do | |
+ %w(active_record_edge active_record_40 active_record_41 active_record_32 active_record_31 active_record_30 data_mapper_12 mongoid_40 mongoid_31 mongoid_30 mongoid_24 mongo_mapper sinatra_13 sinatra_14).each do |gemfile| | |
+ desc "Run Tests against #{gemfile}" | |
+ task gemfile do | |
+ sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle --quiet" | |
+ sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle exec rake -t spec" | |
+ end | |
+ end | |
+ | |
+ desc "Run Tests against all ORMs" | |
+ task :all do | |
+ %w(active_record_edge active_record_40 active_record_41 active_record_32 active_record_31 active_record_30 data_mapper_12 mongoid_40 mongoid_31 mongoid_30 mongoid_24 mongo_mapper sinatra_13 sinatra_14).each do |gemfile| | |
+ sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle --quiet" | |
+ sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle exec rake spec" | |
+ end | |
+ end | |
+end | |
+ | |
+begin | |
+ require 'rdoc/task' | |
-require 'rake/rdoctask' | |
-Rake::RDocTask.new do |rdoc| | |
- require 'kaminari/version' | |
+ Rake::RDocTask.new do |rdoc| | |
+ require 'kaminari/version' | |
- rdoc.rdoc_dir = 'rdoc' | |
- rdoc.title = "kaminari #{Kaminari::VERSION}" | |
- rdoc.rdoc_files.include('README*') | |
- rdoc.rdoc_files.include('lib/**/*.rb') | |
+ rdoc.rdoc_dir = 'rdoc' | |
+ rdoc.title = "kaminari #{Kaminari::VERSION}" | |
+ rdoc.rdoc_files.include('README*') | |
+ rdoc.rdoc_files.include('lib/**/*.rb') | |
+ end | |
+rescue LoadError | |
+ puts 'RDocTask is not supported on this VM and platform combination.' | |
end | |
diff --git a/app/views/kaminari/_first_page.html.erb b/app/views/kaminari/_first_page.html.erb | |
index f147502..2682d34 100644 | |
--- a/app/views/kaminari/_first_page.html.erb | |
+++ b/app/views/kaminari/_first_page.html.erb | |
@@ -2,10 +2,10 @@ | |
- available local variables | |
url: url to the first page | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
-%> | |
<span class="first"> | |
- <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote %> | |
+ <%= link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, :remote => remote %> | |
</span> | |
diff --git a/app/views/kaminari/_first_page.html.haml b/app/views/kaminari/_first_page.html.haml | |
index fee8112..e38219c 100644 | |
--- a/app/views/kaminari/_first_page.html.haml | |
+++ b/app/views/kaminari/_first_page.html.haml | |
@@ -2,8 +2,8 @@ | |
-# available local variables | |
-# url: url to the first page | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
%span.first | |
- = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote | |
+ = link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, :remote => remote | |
diff --git a/app/views/kaminari/_first_page.html.slim b/app/views/kaminari/_first_page.html.slim | |
index 388ec33..fa7ef64 100644 | |
--- a/app/views/kaminari/_first_page.html.slim | |
+++ b/app/views/kaminari/_first_page.html.slim | |
@@ -2,9 +2,9 @@ | |
- available local variables | |
url : url to the first page | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
span.first | |
- == link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote | |
+ == link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, :remote => remote | |
' | |
diff --git a/app/views/kaminari/_gap.html.erb b/app/views/kaminari/_gap.html.erb | |
index d1800e1..bbb0f98 100644 | |
--- a/app/views/kaminari/_gap.html.erb | |
+++ b/app/views/kaminari/_gap.html.erb | |
@@ -1,8 +1,8 @@ | |
<%# Non-link tag that stands for skipped pages... | |
- available local variables | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
-%> | |
-<span class="page gap"><%= raw(t 'views.pagination.truncate') %></span> | |
+<span class="page gap"><%= t('views.pagination.truncate').html_safe %></span> | |
diff --git a/app/views/kaminari/_gap.html.haml b/app/views/kaminari/_gap.html.haml | |
index f82f185..dd5789c 100644 | |
--- a/app/views/kaminari/_gap.html.haml | |
+++ b/app/views/kaminari/_gap.html.haml | |
@@ -1,8 +1,8 @@ | |
-# Non-link tag that stands for skipped pages... | |
-# available local variables | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
%span.page.gap | |
- = raw(t 'views.pagination.truncate') | |
+ = t('views.pagination.truncate').html_safe | |
diff --git a/app/views/kaminari/_gap.html.slim b/app/views/kaminari/_gap.html.slim | |
index bb1f32a..a1ac4c5 100644 | |
--- a/app/views/kaminari/_gap.html.slim | |
+++ b/app/views/kaminari/_gap.html.slim | |
@@ -1,9 +1,9 @@ | |
/ Non-link tag that stands for skipped pages... | |
- available local variables | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
span.page.gap | |
- == raw(t 'views.pagination.truncate') | |
+ == t('views.pagination.truncate').html_safe | |
' | |
diff --git a/app/views/kaminari/_last_page.html.erb b/app/views/kaminari/_last_page.html.erb | |
index 73ce4d4..53d6130 100644 | |
--- a/app/views/kaminari/_last_page.html.erb | |
+++ b/app/views/kaminari/_last_page.html.erb | |
@@ -2,10 +2,10 @@ | |
- available local variables | |
url: url to the last page | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
-%> | |
<span class="last"> | |
- <%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} %> | |
+ <%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote %> | |
</span> | |
diff --git a/app/views/kaminari/_last_page.html.haml b/app/views/kaminari/_last_page.html.haml | |
index 6e41d23..cdddb9e 100644 | |
--- a/app/views/kaminari/_last_page.html.haml | |
+++ b/app/views/kaminari/_last_page.html.haml | |
@@ -2,8 +2,8 @@ | |
-# available local variables | |
-# url: url to the last page | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
%span.last | |
- = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} | |
+ = link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote | |
diff --git a/app/views/kaminari/_last_page.html.slim b/app/views/kaminari/_last_page.html.slim | |
index 72b3354..cc0a22b 100644 | |
--- a/app/views/kaminari/_last_page.html.slim | |
+++ b/app/views/kaminari/_last_page.html.slim | |
@@ -2,9 +2,9 @@ | |
- available local variables | |
url : url to the last page | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
span.last | |
- == link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} | |
+ == link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote | |
' | |
diff --git a/app/views/kaminari/_next_page.html.erb b/app/views/kaminari/_next_page.html.erb | |
index 1900875..4fc2071 100644 | |
--- a/app/views/kaminari/_next_page.html.erb | |
+++ b/app/views/kaminari/_next_page.html.erb | |
@@ -2,10 +2,10 @@ | |
- available local variables | |
url: url to the next page | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
-%> | |
<span class="next"> | |
- <%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote %> | |
+ <%= link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote %> | |
</span> | |
diff --git a/app/views/kaminari/_next_page.html.haml b/app/views/kaminari/_next_page.html.haml | |
index e87ab4e..2865dcd 100644 | |
--- a/app/views/kaminari/_next_page.html.haml | |
+++ b/app/views/kaminari/_next_page.html.haml | |
@@ -2,8 +2,8 @@ | |
-# available local variables | |
-# url: url to the next page | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
%span.next | |
- = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote | |
+ = link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote | |
diff --git a/app/views/kaminari/_next_page.html.slim b/app/views/kaminari/_next_page.html.slim | |
index 0633935..f7a7681 100644 | |
--- a/app/views/kaminari/_next_page.html.slim | |
+++ b/app/views/kaminari/_next_page.html.slim | |
@@ -2,9 +2,9 @@ | |
- available local variables | |
url : url to the next page | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
span.next | |
- == link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote | |
+ == link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote | |
' | |
diff --git a/app/views/kaminari/_page.html.erb b/app/views/kaminari/_page.html.erb | |
index 1683069..582af7b 100644 | |
--- a/app/views/kaminari/_page.html.erb | |
+++ b/app/views/kaminari/_page.html.erb | |
@@ -3,10 +3,10 @@ | |
page: a page object for "this" page | |
url: url to this page | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
-%> | |
<span class="page<%= ' current' if page.current? %>"> | |
- <%= link_to_unless page.current?, page, url, opts = {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %> | |
+ <%= link_to_unless page.current?, page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %> | |
</span> | |
diff --git a/app/views/kaminari/_page.html.haml b/app/views/kaminari/_page.html.haml | |
index 528bba8..acfb0cf 100644 | |
--- a/app/views/kaminari/_page.html.haml | |
+++ b/app/views/kaminari/_page.html.haml | |
@@ -3,7 +3,7 @@ | |
-# page: a page object for "this" page | |
-# url: url to this page | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
%span{:class => "page#{' current' if page.current?}"} | |
diff --git a/app/views/kaminari/_page.html.slim b/app/views/kaminari/_page.html.slim | |
index b1babb1..b21f545 100644 | |
--- a/app/views/kaminari/_page.html.slim | |
+++ b/app/views/kaminari/_page.html.slim | |
@@ -3,7 +3,7 @@ | |
page : a page object for "this" page | |
url : url to this page | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
span class="page#{' current' if page.current?}" | |
diff --git a/app/views/kaminari/_paginator.html.erb b/app/views/kaminari/_paginator.html.erb | |
index aad45ef..4fb445f 100644 | |
--- a/app/views/kaminari/_paginator.html.erb | |
+++ b/app/views/kaminari/_paginator.html.erb | |
@@ -1,7 +1,7 @@ | |
<%# The container tag | |
- available local variables | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
paginator: the paginator that renders the pagination tags inside | |
diff --git a/app/views/kaminari/_paginator.html.haml b/app/views/kaminari/_paginator.html.haml | |
index 1bf1884..4f33e2d 100644 | |
--- a/app/views/kaminari/_paginator.html.haml | |
+++ b/app/views/kaminari/_paginator.html.haml | |
@@ -1,7 +1,7 @@ | |
-# The container tag | |
-# available local variables | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
-# paginator: the paginator that renders the pagination tags inside | |
diff --git a/app/views/kaminari/_paginator.html.slim b/app/views/kaminari/_paginator.html.slim | |
index d51f0a1..6a587d7 100644 | |
--- a/app/views/kaminari/_paginator.html.slim | |
+++ b/app/views/kaminari/_paginator.html.slim | |
@@ -1,7 +1,7 @@ | |
/ The container tag | |
- available local variables | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
paginator : the paginator that renders the pagination tags inside | |
diff --git a/app/views/kaminari/_prev_page.html.erb b/app/views/kaminari/_prev_page.html.erb | |
index 4e94c8a..9c4aff4 100644 | |
--- a/app/views/kaminari/_prev_page.html.erb | |
+++ b/app/views/kaminari/_prev_page.html.erb | |
@@ -2,10 +2,10 @@ | |
- available local variables | |
url: url to the previous page | |
current_page: a page object for the currently displayed page | |
- num_pages: total number of pages | |
+ total_pages: total number of pages | |
per_page: number of items to fetch per page | |
remote: data-remote | |
-%> | |
<span class="prev"> | |
- <%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote %> | |
+ <%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote %> | |
</span> | |
diff --git a/app/views/kaminari/_prev_page.html.haml b/app/views/kaminari/_prev_page.html.haml | |
index 13f0d8a..d20b1b1 100644 | |
--- a/app/views/kaminari/_prev_page.html.haml | |
+++ b/app/views/kaminari/_prev_page.html.haml | |
@@ -2,8 +2,8 @@ | |
-# available local variables | |
-# url: url to the previous page | |
-# current_page: a page object for the currently displayed page | |
--# num_pages: total number of pages | |
+-# total_pages: total number of pages | |
-# per_page: number of items to fetch per page | |
-# remote: data-remote | |
%span.prev | |
- = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote | |
+ = link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote | |
diff --git a/app/views/kaminari/_prev_page.html.slim b/app/views/kaminari/_prev_page.html.slim | |
index 8f37596..8249cb0 100644 | |
--- a/app/views/kaminari/_prev_page.html.slim | |
+++ b/app/views/kaminari/_prev_page.html.slim | |
@@ -2,9 +2,9 @@ | |
- available local variables | |
url : url to the previous page | |
current_page : a page object for the currently displayed page | |
- num_pages : total number of pages | |
+ total_pages : total number of pages | |
per_page : number of items to fetch per page | |
remote : data-remote | |
span.prev | |
- == link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote | |
+ == link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote | |
' | |
diff --git a/config/locales/kaminari.yml b/config/locales/kaminari.yml | |
index eb3ec65..65c06ff 100644 | |
--- a/config/locales/kaminari.yml | |
+++ b/config/locales/kaminari.yml | |
@@ -7,4 +7,13 @@ en: | |
last: "Last »" | |
previous: "‹ Prev" | |
next: "Next ›" | |
- truncate: "..." | |
+ truncate: "…" | |
+ helpers: | |
+ page_entries_info: | |
+ one_page: | |
+ display_entries: | |
+ zero: "No %{entry_name} found" | |
+ one: "Displaying <b>1</b> %{entry_name}" | |
+ other: "Displaying <b>all %{count}</b> %{entry_name}" | |
+ more_pages: | |
+ display_entries: "Displaying %{entry_name} <b>%{first} - %{last}</b> of <b>%{total}</b> in total" | |
diff --git a/gemfiles/active_record_30.gemfile b/gemfiles/active_record_30.gemfile | |
new file mode 100644 | |
index 0000000..e3481f5 | |
--- /dev/null | |
+++ b/gemfiles/active_record_30.gemfile | |
@@ -0,0 +1,30 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 3.0.20' | |
+gem 'activerecord', '~> 3.0.20', :require => 'active_record' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'capybara', '< 2.1' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'rubyzip', '< 1' | |
+gem 'mime-types', '< 2' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/active_record_31.gemfile b/gemfiles/active_record_31.gemfile | |
new file mode 100644 | |
index 0000000..b736402 | |
--- /dev/null | |
+++ b/gemfiles/active_record_31.gemfile | |
@@ -0,0 +1,30 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 3.1.12' | |
+gem 'activerecord', '~> 3.1.12', :require => 'active_record' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'capybara', '< 2.1' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'rubyzip', '< 1' | |
+gem 'mime-types', '< 2' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/active_record_32.gemfile b/gemfiles/active_record_32.gemfile | |
new file mode 100644 | |
index 0000000..aada0ee | |
--- /dev/null | |
+++ b/gemfiles/active_record_32.gemfile | |
@@ -0,0 +1,30 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 3.2.3' | |
+gem 'activerecord', '~> 3.2.3', :require => 'active_record' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+# Stick To Versions That Work Under Ruby 1.8 For Now | |
+gem 'capybara', '< 2.1' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'rubyzip', '< 1' | |
+gem 'mime-types', '< 2' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/active_record_40.gemfile b/gemfiles/active_record_40.gemfile | |
new file mode 100644 | |
index 0000000..aae97ff | |
--- /dev/null | |
+++ b/gemfiles/active_record_40.gemfile | |
@@ -0,0 +1,24 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 4.0.0' | |
+gem 'activerecord', '~> 4.0.0', :require => 'active_record' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/active_record_41.gemfile b/gemfiles/active_record_41.gemfile | |
new file mode 100644 | |
index 0000000..fef6135 | |
--- /dev/null | |
+++ b/gemfiles/active_record_41.gemfile | |
@@ -0,0 +1,24 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 4.1.0' | |
+gem 'activerecord', '~> 4.1.0', :require => 'active_record' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'minitest' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/active_record_edge.gemfile b/gemfiles/active_record_edge.gemfile | |
new file mode 100644 | |
index 0000000..b6c0aa7 | |
--- /dev/null | |
+++ b/gemfiles/active_record_edge.gemfile | |
@@ -0,0 +1,30 @@ | |
+source 'https://rubygems.org' | |
+ | |
+git 'git://github.com/rails/rails.git' do | |
+ gem 'railties' | |
+ gem 'activerecord', :require => 'active_record' | |
+ gem 'actionview', :require => 'action_view' | |
+end | |
+ | |
+gem 'arel', :github => 'rails/arel' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'minitest' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gem 'rspec-rails', '2.99.0' | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/data_mapper_12.gemfile b/gemfiles/data_mapper_12.gemfile | |
new file mode 100644 | |
index 0000000..b848a6e | |
--- /dev/null | |
+++ b/gemfiles/data_mapper_12.gemfile | |
@@ -0,0 +1,35 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '>= 3.2.3' | |
+gem 'dm-core', '~> 1.2.0' | |
+gem 'dm-migrations', '~> 1.2.0' | |
+gem 'dm-aggregates', '~> 1.2.0' | |
+gem 'dm-transactions', '~> 1.2.0' | |
+gem 'dm-active_model', '~> 1.2.1' | |
+gem 'dm-sqlite-adapter', '~> 1.2.0' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'capybara', '< 2.1' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'rubyzip', '< 1' | |
+gem 'mime-types', '< 2' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '~> 1.2.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/mongo_mapper.gemfile b/gemfiles/mongo_mapper.gemfile | |
new file mode 100644 | |
index 0000000..b393872 | |
--- /dev/null | |
+++ b/gemfiles/mongo_mapper.gemfile | |
@@ -0,0 +1,25 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '>= 3.2.3' | |
+gem 'bson', '~> 1.9.2' | |
+gem 'mongo_mapper', '>= 0.11.0' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'capybara', '< 2.1' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'rubyzip', '< 1' | |
+gem 'mime-types', '< 2' | |
+ | |
+if RUBY_VERSION == '1.8.7' | |
+ gem 'activesupport', '~> 3.2.18' | |
+end | |
+ | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'minitest' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/mongoid_24.gemfile b/gemfiles/mongoid_24.gemfile | |
new file mode 100644 | |
index 0000000..b30b93e | |
--- /dev/null | |
+++ b/gemfiles/mongoid_24.gemfile | |
@@ -0,0 +1,21 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '>= 3.2.3' | |
+gem 'mongoid', '~> 2.4.0' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'capybara', '< 2.1' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'rubyzip', '< 1' | |
+gem 'mime-types', '< 2' | |
+gem 'database_cleaner', '< 1.0.0' | |
+ | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'minitest' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/mongoid_30.gemfile b/gemfiles/mongoid_30.gemfile | |
new file mode 100644 | |
index 0000000..e0824d5 | |
--- /dev/null | |
+++ b/gemfiles/mongoid_30.gemfile | |
@@ -0,0 +1,17 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '>= 3.2.3' | |
+gem 'mongoid', '~> 3.0.0' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+gem 'origin' | |
+gem 'moped' | |
+gem 'activesupport', '~> 3.2.18' | |
+ | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/mongoid_31.gemfile b/gemfiles/mongoid_31.gemfile | |
new file mode 100644 | |
index 0000000..35b3f1a | |
--- /dev/null | |
+++ b/gemfiles/mongoid_31.gemfile | |
@@ -0,0 +1,16 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 3.2' | |
+gem 'mongoid', '~> 3.1.0' | |
+gem 'rspec-rails', '~> 2.14.1' | |
+gem 'origin' | |
+gem 'moped' | |
+ | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/mongoid_40.gemfile b/gemfiles/mongoid_40.gemfile | |
new file mode 100644 | |
index 0000000..ed8f020 | |
--- /dev/null | |
+++ b/gemfiles/mongoid_40.gemfile | |
@@ -0,0 +1,14 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'railties', '~> 4.0' | |
+gem "mongoid", "~> 4.0.0.beta2" | |
+gem 'rspec-rails', '~> 2.14.1' | |
+ | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'minitest' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/sinatra_13.gemfile b/gemfiles/sinatra_13.gemfile | |
new file mode 100644 | |
index 0000000..59f13ff | |
--- /dev/null | |
+++ b/gemfiles/sinatra_13.gemfile | |
@@ -0,0 +1,34 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'activerecord', '~> 3.2.3', :require => 'active_record' | |
+gem 'sinatra', '~> 1.3.0' | |
+gem 'tilt', '~> 1.3.0' | |
+gem 'padrino-helpers', '~> 0.10.6' | |
+gem 'rack-test', '>= 0' | |
+gem 'sinatra-contrib', '~> 1.3.0' | |
+gem 'rspec', '~> 2.14.1' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'mime-types', '< 2.0' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'capybara', '< 2.1' | |
+gem 'rubyzip', '< 1' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/gemfiles/sinatra_14.gemfile b/gemfiles/sinatra_14.gemfile | |
new file mode 100644 | |
index 0000000..b96abf3 | |
--- /dev/null | |
+++ b/gemfiles/sinatra_14.gemfile | |
@@ -0,0 +1,39 @@ | |
+source 'https://rubygems.org' | |
+ | |
+gem 'activerecord', '~> 3.2.0', :require => 'active_record' | |
+gem 'sinatra', '~> 1.4.0' | |
+gem 'rspec', '~> 2.14.1' | |
+ | |
+if RUBY_VERSION <= "1.8.7" | |
+ gem 'padrino-helpers', '~> 0.11.0' | |
+else | |
+ gem 'padrino-helpers', '~> 0.12.0' | |
+end | |
+ | |
+gem 'rack-test', '>= 0' | |
+gem 'sinatra-contrib', '~> 1.4.0' | |
+ | |
+# stick to versions that work under Ruby 1.8 for now | |
+gem 'mime-types', '< 2.0' | |
+gem 'nokogiri', '< 1.6' | |
+gem 'capybara', '< 2.1' | |
+gem 'rubyzip', '< 1' | |
+ | |
+platforms :ruby do | |
+ if RUBY_VERSION > "2.1.0" | |
+ gem 'sqlite3' | |
+ else | |
+ gem 'sqlite3', '1.3.8' | |
+ end | |
+end | |
+platforms :jruby do | |
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' | |
+end | |
+platforms :rbx do | |
+ gem 'rubysl', '~> 2.0' | |
+ gem 'racc' | |
+ gem 'rubysl-test-unit' | |
+ gem 'rubinius-developer_tools' | |
+end | |
+ | |
+gemspec :path => '../' | |
diff --git a/kaminari.gemspec b/kaminari.gemspec | |
index 38ec42c..7c13c56 100644 | |
--- a/kaminari.gemspec | |
+++ b/kaminari.gemspec | |
@@ -6,11 +6,11 @@ Gem::Specification.new do |s| | |
s.name = 'kaminari' | |
s.version = Kaminari::VERSION | |
s.platform = Gem::Platform::RUBY | |
- s.authors = ['Akira Matsuda'] | |
+ s.authors = ['Akira Matsuda', 'Yuki Nishijima', 'Zachary Scott', 'Hiroshi Shibata'] | |
s.email = ['[email protected]'] | |
s.homepage = 'https://github.com/amatsuda/kaminari' | |
- s.summary = 'A pagination engine plugin for Rails 3 or other modern frameworks' | |
- s.description = 'Kaminari is a Scope & Engine based, clean, powerful, agnostic, customizable and sophisticated paginator for Rails 3' | |
+ s.summary = 'A pagination engine plugin for Rails 3+ and other modern frameworks' | |
+ s.description = 'Kaminari is a Scope & Engine based, clean, powerful, agnostic, customizable and sophisticated paginator for Rails 3+' | |
s.rubyforge_project = 'kaminari' | |
@@ -21,28 +21,15 @@ Gem::Specification.new do |s| | |
s.licenses = ['MIT'] | |
- %w{ activesupport actionpack railties }.each do |gem| | |
- s.add_dependency gem, ['>= 3.0.0'] | |
- end | |
+ s.add_dependency 'activesupport', ['>= 3.0.0'] | |
+ s.add_dependency 'actionpack', ['>= 3.0.0'] | |
+ | |
s.add_development_dependency 'bundler', ['>= 1.0.0'] | |
- s.add_development_dependency 'sqlite3', ['>= 0'] | |
- %w{ activerecord activemodel }.each do |gem| | |
- s.add_development_dependency gem, ['>= 3.0.0'] | |
- end | |
- s.add_development_dependency 'sinatra', ['>= 1.3'] | |
- s.add_development_dependency 'mongoid', ['>= 2'] | |
- s.add_development_dependency 'mongo_mapper', ['>= 0.9'] | |
- s.add_development_dependency 'dm-core', ['>= 1.1.0'] | |
- s.add_development_dependency 'dm-migrations', ['>= 1.1.0'] | |
- s.add_development_dependency 'dm-aggregates', ['>= 1.1.0'] | |
- s.add_development_dependency 'dm-sqlite-adapter', ['>= 1.1.0'] | |
+ s.add_development_dependency 'rake', ['>= 0'] | |
+ s.add_development_dependency 'tzinfo', ['>= 0'] | |
s.add_development_dependency 'rspec', ['>= 0'] | |
- s.add_development_dependency 'rspec-rails', ['>= 0'] | |
s.add_development_dependency 'rr', ['>= 0'] | |
s.add_development_dependency 'capybara', ['>= 1.0'] | |
- s.add_development_dependency 'database_cleaner', ['>= 0'] | |
- s.add_development_dependency 'padrino-helpers', ['~> 0.10'] | |
- s.add_development_dependency 'rack-test', ['>= 0'] | |
- s.add_development_dependency 'sinatra-contrib', ['~> 1.3'] | |
- s.add_development_dependency 'nokogiri', ['>= 0'] | |
+ s.add_development_dependency 'database_cleaner', ['~> 1.2.0'] | |
+ s.add_development_dependency 'rdoc', ['>= 0'] | |
end | |
diff --git a/lib/generators/kaminari/templates/kaminari_config.rb b/lib/generators/kaminari/templates/kaminari_config.rb | |
index 73bd31d..b1d87b0 100644 | |
--- a/lib/generators/kaminari/templates/kaminari_config.rb | |
+++ b/lib/generators/kaminari/templates/kaminari_config.rb | |
@@ -1,5 +1,6 @@ | |
Kaminari.configure do |config| | |
# config.default_per_page = 25 | |
+ # config.max_per_page = nil | |
# config.window = 4 | |
# config.outer_window = 0 | |
# config.left = 0 | |
diff --git a/lib/generators/kaminari/views_generator.rb b/lib/generators/kaminari/views_generator.rb | |
index fa167da..8526fb6 100644 | |
--- a/lib/generators/kaminari/views_generator.rb | |
+++ b/lib/generators/kaminari/views_generator.rb | |
@@ -1,7 +1,5 @@ | |
module Kaminari | |
module Generators | |
- SHOW_API = 'http://github.com/api/v2/json/blob/show/amatsuda/kaminari_themes' | |
- ALL_API = 'http://github.com/api/v2/json/blob/all/amatsuda/kaminari_themes/master' | |
class ViewsGenerator < Rails::Generators::NamedBase | |
source_root File.expand_path('../../../../app/views/kaminari', __FILE__) | |
@@ -37,13 +35,8 @@ BANNER | |
private | |
def self.themes | |
begin | |
- @themes ||= open ALL_API do |json| | |
-# @themes ||= open(File.join(File.dirname(__FILE__), '../../../spec/generators/sample.json')) do |json| | |
- files = ActiveSupport::JSON.decode(json)['blobs'] | |
- hash = files.group_by {|fn, _| fn[0...(fn.index('/') || 0)]}.delete_if {|fn, _| fn.blank?} | |
- hash.map do |name, files| | |
- Theme.new name, files | |
- end | |
+ @themes ||= GitHubApiHelper.get_files_in_master.group_by {|fn, _| fn[0...(fn.index('/') || 0)]}.delete_if {|fn, _| fn.blank?}.map do |name, files| | |
+ Theme.new name, files | |
end | |
rescue SocketError | |
[] | |
@@ -53,7 +46,7 @@ BANNER | |
def download_templates(theme) | |
theme.templates_for(template_engine).each do |template| | |
say " downloading #{template.name} from kaminari_themes..." | |
- get "#{SHOW_API}/#{template.sha}", template.name | |
+ create_file template.name, GitHubApiHelper.get_content_for("#{theme.name}/#{template.name}") | |
end | |
end | |
@@ -92,12 +85,34 @@ BANNER | |
def description #:nodoc: | |
file = @templates.detect(&:description?) | |
return "#{' ' * 12}#{name}" unless file | |
- open("#{SHOW_API}/#{file.sha}").read.chomp.gsub /^/, ' ' * 12 | |
+ GitHubApiHelper.get_content_for("#{@name}/#{file.name}").chomp.gsub(/^/, ' ' * 12) | |
end | |
def templates_for(template_engine) #:nodoc: | |
@templates.select {|t| !t.description?}.select {|t| !t.view? || (t.engine == template_engine)} | |
end | |
end | |
+ | |
+ module GitHubApiHelper | |
+ def get_files_in_master | |
+ master_tree_sha = open('https://api.github.com/repos/amatsuda/kaminari_themes/git/refs/heads/master') do |json| | |
+ ActiveSupport::JSON.decode(json.read)['object']['sha'] | |
+ end | |
+ open('https://api.github.com/repos/amatsuda/kaminari_themes/git/trees/' + master_tree_sha + '?recursive=1') do |json| | |
+ blobs = ActiveSupport::JSON.decode(json.read)['tree'].find_all {|i| i['type'] == 'blob' } | |
+ blobs.map do |blob| | |
+ [blob['path'], blob['sha']] | |
+ end | |
+ end | |
+ end | |
+ module_function :get_files_in_master | |
+ | |
+ def get_content_for(path) | |
+ open('https://api.github.com/repos/amatsuda/kaminari_themes/contents/' + path) do |json| | |
+ Base64.decode64(ActiveSupport::JSON.decode(json.read)['content']) | |
+ end | |
+ end | |
+ module_function :get_content_for | |
+ end | |
end | |
end | |
diff --git a/lib/kaminari.rb b/lib/kaminari.rb | |
index 746750e..41304ff 100644 | |
--- a/lib/kaminari.rb | |
+++ b/lib/kaminari.rb | |
@@ -1,73 +1,39 @@ | |
module Kaminari | |
- def self.frameworks | |
- frameworks = [] | |
- case | |
- when rails? then frameworks << 'rails' | |
- when sinatra? then frameworks << 'sinatra/base' | |
- end | |
- frameworks | |
- end | |
+end | |
- def self.load_framework! | |
- show_warning if frameworks.empty? | |
- frameworks.each do |framework| | |
- begin | |
- require framework | |
- rescue NameError => e | |
- raise "Failed to load framework #{framework.inspect}. Have you added it to Gemfile?" | |
- end | |
- end | |
- end | |
+# load Rails/Railtie | |
+begin | |
+ require 'rails' | |
+rescue LoadError | |
+ #do nothing | |
+end | |
- def self.show_warning | |
- $stderr.puts <<-EOC | |
+$stderr.puts <<-EOC if !defined?(Rails) && !defined?(Sinatra) && !defined?(Grape) | |
warning: no framework detected. | |
-would you check out if your Gemfile appropriately configured? | |
+ | |
+Your Gemfile might not be configured properly. | |
---- e.g. ---- | |
-when Rails: | |
- gem 'rails' | |
+Rails: | |
gem 'kaminari' | |
-when Sinatra/Padrino: | |
+Sinatra/Padrino: | |
gem 'kaminari', :require => 'kaminari/sinatra' | |
- EOC | |
- end | |
+Grape: | |
+ gem 'kaminari', :require => 'kaminari/grape' | |
- def self.load_kaminari! | |
- require 'kaminari/config' | |
- require 'kaminari/helpers/action_view_extension' | |
- require 'kaminari/helpers/paginator' | |
- require 'kaminari/models/page_scope_methods' | |
- require 'kaminari/models/configuration_methods' | |
- end | |
+EOC | |
- def self.hook! | |
- load_framework! | |
- load_kaminari! | |
- require 'kaminari/hooks' | |
- if rails? | |
- require 'kaminari/railtie' | |
- require 'kaminari/engine' | |
- elsif sinatra? | |
- require 'kaminari/sinatra' | |
- else | |
- Kaminari::Hooks.init! | |
- end | |
- end | |
+# load Kaminari components | |
+require 'kaminari/config' | |
+require 'kaminari/helpers/action_view_extension' | |
+require 'kaminari/helpers/paginator' | |
+require 'kaminari/models/page_scope_methods' | |
+require 'kaminari/models/configuration_methods' | |
+require 'kaminari/hooks' | |
- def self.load! | |
- hook! | |
- end | |
- | |
- private | |
- def self.rails? | |
- defined?(::Rails) | |
- end | |
- | |
- def self.sinatra? | |
- defined?(::Sinatra) | |
- end | |
+# if not using Railtie, call `Kaminari::Hooks.init` directly | |
+if defined? Rails | |
+ require 'kaminari/railtie' | |
+ require 'kaminari/engine' | |
end | |
- | |
-Kaminari.load! | |
diff --git a/lib/kaminari/config.rb b/lib/kaminari/config.rb | |
index 2b7d5dd..1e709ee 100644 | |
--- a/lib/kaminari/config.rb | |
+++ b/lib/kaminari/config.rb | |
@@ -18,26 +18,34 @@ module Kaminari | |
class Configuration #:nodoc: | |
include ActiveSupport::Configurable | |
config_accessor :default_per_page | |
+ config_accessor :max_per_page | |
config_accessor :window | |
config_accessor :outer_window | |
config_accessor :left | |
config_accessor :right | |
config_accessor :page_method_name | |
- config_accessor :param_name | |
+ config_accessor :max_pages | |
def param_name | |
config.param_name.respond_to?(:call) ? config.param_name.call : config.param_name | |
end | |
+ | |
+ # define param_name writer (copied from AS::Configurable) | |
+ writer, line = 'def param_name=(value); config.param_name = value; end', __LINE__ | |
+ singleton_class.class_eval writer, __FILE__, line | |
+ class_eval writer, __FILE__, line | |
end | |
# this is ugly. why can't we pass the default value to config_accessor...? | |
configure do |config| | |
config.default_per_page = 25 | |
+ config.max_per_page = nil | |
config.window = 4 | |
config.outer_window = 0 | |
config.left = 0 | |
config.right = 0 | |
config.page_method_name = :page | |
config.param_name = :page | |
+ config.max_pages = nil | |
end | |
end | |
diff --git a/lib/kaminari/grape.rb b/lib/kaminari/grape.rb | |
new file mode 100644 | |
index 0000000..84f1ec5 | |
--- /dev/null | |
+++ b/lib/kaminari/grape.rb | |
@@ -0,0 +1,4 @@ | |
+require 'grape' | |
+require 'kaminari' | |
+ | |
+Kaminari::Hooks.init | |
diff --git a/lib/kaminari/helpers/action_view_extension.rb b/lib/kaminari/helpers/action_view_extension.rb | |
index 8ddf7ae..1ec1ebb 100644 | |
--- a/lib/kaminari/helpers/action_view_extension.rb | |
+++ b/lib/kaminari/helpers/action_view_extension.rb | |
@@ -15,10 +15,35 @@ module Kaminari | |
# * <tt>:remote</tt> - Ajax? (false by default) | |
# * <tt>:ANY_OTHER_VALUES</tt> - Any other hash key & values would be directly passed into each tag as :locals value. | |
def paginate(scope, options = {}, &block) | |
- paginator = Kaminari::Helpers::Paginator.new self, options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages, :per_page => scope.limit_value, :param_name => Kaminari.config.param_name, :remote => false) | |
+ paginator = Kaminari::Helpers::Paginator.new self, options.reverse_merge(:current_page => scope.current_page, :total_pages => scope.total_pages, :per_page => scope.limit_value, :remote => false) | |
paginator.to_s | |
end | |
+ # A simple "Twitter like" pagination link that creates a link to the previous page. | |
+ # | |
+ # ==== Examples | |
+ # Basic usage: | |
+ # | |
+ # <%= link_to_previous_page @items, 'Previous Page' %> | |
+ # | |
+ # Ajax: | |
+ # | |
+ # <%= link_to_previous_page @items, 'Previous Page', :remote => true %> | |
+ # | |
+ # By default, it renders nothing if there are no more results on the previous page. | |
+ # You can customize this output by passing a block. | |
+ # | |
+ # <%= link_to_previous_page @users, 'Previous Page' do %> | |
+ # <span>At the Beginning</span> | |
+ # <% end %> | |
+ def link_to_previous_page(scope, name, options = {}, &block) | |
+ params = options.delete(:params) || {} | |
+ param_name = options.delete(:param_name) || Kaminari.config.param_name | |
+ link_to_unless scope.first_page?, name, params.merge(param_name => scope.prev_page), options.reverse_merge(:rel => 'previous') do | |
+ block.call if block | |
+ end | |
+ end | |
+ | |
# A simple "Twitter like" pagination link that creates a link to the next page. | |
# | |
# ==== Examples | |
@@ -39,7 +64,7 @@ module Kaminari | |
def link_to_next_page(scope, name, options = {}, &block) | |
params = options.delete(:params) || {} | |
param_name = options.delete(:param_name) || Kaminari.config.param_name | |
- link_to_unless scope.last_page?, name, params.merge(param_name => (scope.current_page + 1)), options.reverse_merge(:rel => 'next') do | |
+ link_to_unless scope.last_page?, name, params.merge(param_name => scope.next_page), options.reverse_merge(:rel => 'next') do | |
block.call if block | |
end | |
end | |
@@ -55,26 +80,51 @@ module Kaminari | |
# | |
# By default, the message will use the humanized class name of objects | |
# in collection: for instance, "project types" for ProjectType models. | |
+ # The namespace will be cutted out and only the last name will be used. | |
# Override this with the <tt>:entry_name</tt> parameter: | |
# | |
# <%= page_entries_info @posts, :entry_name => 'item' %> | |
# #-> Displaying items 6 - 10 of 26 in total | |
def page_entries_info(collection, options = {}) | |
- entry_name = options[:entry_name] || (collection.empty?? 'entry' : collection.first.class.name.underscore.sub('_', ' ')) | |
- if collection.num_pages < 2 | |
- case collection.total_count | |
- when 0; "No #{entry_name.pluralize} found" | |
- when 1; "Displaying <b>1</b> #{entry_name}" | |
- else; "Displaying <b>all #{collection.total_count}</b> #{entry_name.pluralize}" | |
- end | |
+ entry_name = options[:entry_name] || collection.entry_name | |
+ entry_name = entry_name.pluralize unless collection.total_count == 1 | |
+ | |
+ if collection.total_pages < 2 | |
+ t('helpers.page_entries_info.one_page.display_entries', :entry_name => entry_name, :count => collection.total_count) | |
else | |
- offset = (collection.current_page - 1) * collection.limit_value | |
- %{Displaying #{entry_name.pluralize} <b>%d - %d</b> of <b>%d</b> in total} % [ | |
- offset + 1, | |
- offset + collection.count, | |
- collection.total_count | |
- ] | |
- end | |
+ first = collection.offset_value + 1 | |
+ last = collection.last_page? ? collection.total_count : collection.offset_value + collection.limit_value | |
+ t('helpers.page_entries_info.more_pages.display_entries', :entry_name => entry_name, :first => first, :last => last, :total => collection.total_count) | |
+ end.html_safe | |
+ end | |
+ | |
+ # Renders rel="next" and rel="prev" links to be used in the head. | |
+ # | |
+ # ==== Examples | |
+ # Basic usage: | |
+ # | |
+ # In head: | |
+ # <head> | |
+ # <title>My Website</title> | |
+ # <%= yield :head %> | |
+ # </head> | |
+ # | |
+ # Somewhere in body: | |
+ # <% content_for :head do %> | |
+ # <%= rel_next_prev_link_tags @items %> | |
+ # <% end %> | |
+ # | |
+ # #-> <link rel="next" href="/items/page/3" /><link rel="prev" href="/items/page/1" /> | |
+ # | |
+ def rel_next_prev_link_tags(scope, options = {}) | |
+ params = options.delete(:params) || {} | |
+ param_name = options.delete(:param_name) || Kaminari.config.param_name | |
+ | |
+ output = "" | |
+ output << '<link rel="next" href="' + url_for(params.merge(param_name => scope.next_page, :only_path => true)) + '"/>' if scope.next_page | |
+ output << '<link rel="prev" href="' + url_for(params.merge(param_name => scope.prev_page, :only_path => true)) + '"/>' if scope.prev_page | |
+ | |
+ output.html_safe | |
end | |
end | |
end | |
diff --git a/lib/kaminari/helpers/paginator.rb b/lib/kaminari/helpers/paginator.rb | |
index bd8d758..5f1ee13 100644 | |
--- a/lib/kaminari/helpers/paginator.rb | |
+++ b/lib/kaminari/helpers/paginator.rb | |
@@ -12,6 +12,10 @@ module Kaminari | |
include ::ActionView::Context | |
def initialize(template, options) #:nodoc: | |
+ #FIXME for compatibility. remove num_pages at some time in the future | |
+ options[:total_pages] ||= options[:num_pages] | |
+ options[:num_pages] ||= options[:total_pages] | |
+ | |
@window_options = {}.tap do |h| | |
h[:window] = options.delete(:window) || options.delete(:inner_window) || Kaminari.config.window | |
outer_window = options.delete(:outer_window) || Kaminari.config.outer_window | |
@@ -21,15 +25,19 @@ module Kaminari | |
h[:right] = outer_window if h[:right] == 0 | |
end | |
@template, @options = template, options | |
- @theme = @options[:theme] ? "#{@options[:theme]}/" : '' | |
- @options[:current_page] = PageProxy.new @window_options.merge(@options), @options[:current_page], nil | |
+ @theme = @options[:theme] | |
+ @views_prefix = @options[:views_prefix] | |
+ @window_options.merge! @options | |
+ @window_options[:current_page] = @options[:current_page] = PageProxy.new(@window_options, @options[:current_page], nil) | |
+ | |
+ @last = nil | |
# initialize the output_buffer for Context | |
@output_buffer = ActionView::OutputBuffer.new | |
end | |
# render given block as a view template | |
def render(&block) | |
- instance_eval &block if @options[:num_pages] > 1 | |
+ instance_eval(&block) if @options[:total_pages] > 1 | |
@output_buffer | |
end | |
@@ -42,18 +50,18 @@ module Kaminari | |
def each_relevant_page | |
return to_enum(:each_relevant_page) unless block_given? | |
- relevant_pages(@window_options.merge(@options)).each do |i| | |
- yield PageProxy.new(@window_options.merge(@options), i, @last) | |
+ relevant_pages(@window_options).each do |page| | |
+ yield PageProxy.new(@window_options, page, @last) | |
end | |
end | |
alias each_page each_relevant_page | |
def relevant_pages(options) | |
left_window_plus_one = 1.upto(options[:left] + 1).to_a | |
- right_window_plus_one = (options[:num_pages] - options[:right]).upto(options[:num_pages]).to_a | |
+ right_window_plus_one = (options[:total_pages] - options[:right]).upto(options[:total_pages]).to_a | |
inside_window_plus_each_sides = (options[:current_page] - options[:window] - 1).upto(options[:current_page] + options[:window] + 1).to_a | |
- (left_window_plus_one + inside_window_plus_each_sides + right_window_plus_one).uniq.sort.reject {|x| (x < 1) || (x > options[:num_pages])} | |
+ (left_window_plus_one + inside_window_plus_each_sides + right_window_plus_one).uniq.sort.reject {|x| (x < 1) || (x > options[:total_pages])} | |
end | |
private :relevant_pages | |
@@ -71,24 +79,40 @@ module Kaminari | |
def to_s #:nodoc: | |
subscriber = ActionView::LogSubscriber.log_subscribers.detect {|ls| ls.is_a? ActionView::LogSubscriber} | |
- return super @window_options.merge(@options).merge :paginator => self unless subscriber | |
- # dirty hack to suppress logging render_partial | |
- class << subscriber | |
- alias_method :render_partial_with_logging, :render_partial | |
- # do nothing | |
- def render_partial(event); end | |
- end | |
+ # There is a logging subscriber | |
+ # and we don't want it to log render_partial | |
+ # It is threadsafe, but might not repress logging | |
+ # consistently in a high-load environment | |
+ if subscriber | |
+ unless defined? subscriber.render_partial_with_logging | |
+ class << subscriber | |
+ alias_method :render_partial_with_logging, :render_partial | |
+ attr_accessor :render_without_logging | |
+ # ugly hack to make a renderer where | |
+ # we can turn logging on or off | |
+ def render_partial(event) | |
+ render_partial_with_logging(event) unless render_without_logging | |
+ end | |
+ end | |
+ end | |
- ret = super @window_options.merge(@options).merge :paginator => self | |
+ subscriber.render_without_logging = true | |
+ ret = super @window_options.merge :paginator => self | |
+ subscriber.render_without_logging = false | |
- class << subscriber | |
- alias_method :render_partial, :render_partial_with_logging | |
- undef :render_partial_with_logging | |
+ ret | |
+ else | |
+ super @window_options.merge :paginator => self | |
end | |
- ret | |
end | |
+ # delegates view helper methods to @template | |
+ def method_missing(name, *args, &block) | |
+ @template.respond_to?(name) ? @template.send(name, *args, &block) : super | |
+ end | |
+ private :method_missing | |
+ | |
# Wraps a "page number" and provides some utility methods | |
class PageProxy | |
include Comparable | |
@@ -114,7 +138,7 @@ module Kaminari | |
# the last page or not | |
def last? | |
- @page == @options[:num_pages] | |
+ @page == @options[:total_pages] | |
end | |
# the previous page or not | |
@@ -134,7 +158,7 @@ module Kaminari | |
# within the right outer window or not | |
def right_outer? | |
- @options[:num_pages] - @page < @options[:right] | |
+ @options[:total_pages] - @page < @options[:right] | |
end | |
# inside the inner window or not | |
diff --git a/lib/kaminari/helpers/sinatra_helpers.rb b/lib/kaminari/helpers/sinatra_helpers.rb | |
index 66fc407..de8e963 100644 | |
--- a/lib/kaminari/helpers/sinatra_helpers.rb | |
+++ b/lib/kaminari/helpers/sinatra_helpers.rb | |
@@ -10,12 +10,23 @@ module Kaminari::Helpers | |
def registered(app) | |
app.register Padrino::Helpers | |
app.helpers HelperMethods | |
+ @app = app | |
+ end | |
+ | |
+ def view_paths | |
+ @app.views | |
end | |
alias included registered | |
end | |
- | |
+ | |
class ActionViewTemplateProxy | |
+ include Padrino::Helpers::OutputHelpers | |
+ include Padrino::Helpers::TagHelpers | |
+ include Padrino::Helpers::AssetTagHelpers | |
+ include Padrino::Helpers::FormatHelpers | |
+ include Padrino::Helpers::TranslationHelpers | |
+ | |
def initialize(opts={}) | |
@current_path = opts[:current_path] | |
@param_name = (opts[:param_name] || :page).to_sym | |
@@ -25,6 +36,7 @@ module Kaminari::Helpers | |
def render(*args) | |
base = ActionView::Base.new.tap do |a| | |
+ a.view_paths << SinatraHelpers.view_paths | |
a.view_paths << File.expand_path('../../../../app/views', __FILE__) | |
end | |
base.render(*args) | |
@@ -38,12 +50,25 @@ module Kaminari::Helpers | |
query = @current_params.merge(extra_params) | |
@current_path + (query.empty? ? '' : "?#{query.to_query}") | |
end | |
- | |
+ | |
+ def link_to_unless(condition, name, options = {}, html_options = {}, &block) | |
+ options = url_for(options) if options.is_a? Hash | |
+ if condition | |
+ if block_given? | |
+ block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block) | |
+ else | |
+ name | |
+ end | |
+ else | |
+ link_to(name, options, html_options) | |
+ end | |
+ end | |
+ | |
def params | |
@current_params | |
end | |
end | |
- | |
+ | |
module HelperMethods | |
# A helper that renders the pagination links - for Sinatra. | |
# | |
@@ -63,11 +88,41 @@ module Kaminari::Helpers | |
current_params = Rack::Utils.parse_query(env['QUERY_STRING']).symbolize_keys rescue {} | |
paginator = Kaminari::Helpers::Paginator.new( | |
ActionViewTemplateProxy.new(:current_params => current_params, :current_path => current_path, :param_name => options[:param_name] || Kaminari.config.param_name), | |
- options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages, :per_page => scope.limit_value, :param_name => Kaminari.config.param_name, :remote => false) | |
+ options.reverse_merge(:current_page => scope.current_page, :total_pages => scope.total_pages, :per_page => scope.limit_value, :param_name => Kaminari.config.param_name, :remote => false) | |
) | |
paginator.to_s | |
end | |
+ # A simple "Twitter like" pagination link that creates a link to the previous page. | |
+ # Works on Sinatra. | |
+ # | |
+ # ==== Examples | |
+ # Basic usage: | |
+ # | |
+ # <%= link_to_previous_page @items, 'Previous Page' %> | |
+ # | |
+ # Ajax: | |
+ # | |
+ # <%= link_to_previous_page @items, 'Previous Page', :remote => true %> | |
+ # | |
+ # By default, it renders nothing if there are no more results on the previous page. | |
+ # You can customize this output by passing a parameter <tt>:placeholder</tt>. | |
+ # | |
+ # <%= link_to_previous_page @users, 'Previous Page', :placeholder => %{<span>At the Beginning</span>} %> | |
+ # | |
+ def link_to_previous_page(scope, name, options = {}) | |
+ params = options.delete(:params) || (Rack::Utils.parse_query(env['QUERY_STRING']).symbolize_keys rescue {}) | |
+ param_name = options.delete(:param_name) || Kaminari.config.param_name | |
+ placeholder = options.delete(:placeholder) | |
+ | |
+ unless scope.first_page? | |
+ query = params.merge(param_name => scope.prev_page) | |
+ link_to name, env['PATH_INFO'] + (query.empty? ? '' : "?#{query.to_query}"), options.reverse_merge(:rel => 'previous') | |
+ else | |
+ placeholder.to_s.html_safe | |
+ end | |
+ end | |
+ | |
# A simple "Twitter like" pagination link that creates a link to the next page. | |
# Works on Sinatra. | |
# | |
@@ -88,12 +143,13 @@ module Kaminari::Helpers | |
def link_to_next_page(scope, name, options = {}) | |
params = options.delete(:params) || (Rack::Utils.parse_query(env['QUERY_STRING']).symbolize_keys rescue {}) | |
param_name = options.delete(:param_name) || Kaminari.config.param_name | |
- placeholder = options.delete(:placeholder) || "" | |
- query = params.merge(param_name => (scope.current_page + 1)) | |
+ placeholder = options.delete(:placeholder) | |
+ | |
unless scope.last_page? | |
- link_to name, env['PATH_INFO'] + (query.empty? ? '' : "?#{query.to_query}"), options.merge(:rel => 'next') | |
+ query = params.merge(param_name => scope.next_page) | |
+ link_to name, env['PATH_INFO'] + (query.empty? ? '' : "?#{query.to_query}"), options.reverse_merge(:rel => 'next') | |
else | |
- placeholder | |
+ placeholder.to_s.html_safe | |
end | |
end | |
end | |
@@ -106,7 +162,7 @@ end | |
rescue LoadError | |
-$stderr.puts "[!]You shold install `padrino-helpers' gem if you want to use kaminari's pagination helpers with Sinatra." | |
+$stderr.puts "[!]You should install `padrino-helpers' gem if you want to use kaminari's pagination helpers with Sinatra." | |
$stderr.puts "[!]Kaminari::Helpers::SinatraHelper does nothing now..." | |
module Kaminari::Helpers | |
diff --git a/lib/kaminari/helpers/tags.rb b/lib/kaminari/helpers/tags.rb | |
index 844b736..ebbc112 100644 | |
--- a/lib/kaminari/helpers/tags.rb | |
+++ b/lib/kaminari/helpers/tags.rb | |
@@ -15,17 +15,27 @@ module Kaminari | |
class Tag | |
def initialize(template, options = {}) #:nodoc: | |
@template, @options = template, options.dup | |
- @param_name = @options.delete(:param_name) | |
- @theme = @options[:theme] ? "#{@options.delete(:theme)}/" : '' | |
+ @param_name = @options.delete(:param_name) || Kaminari.config.param_name | |
+ @theme = @options.delete(:theme) | |
+ @views_prefix = @options.delete(:views_prefix) | |
@params = @options[:params] ? template.params.merge(@options.delete :params) : template.params | |
end | |
def to_s(locals = {}) #:nodoc: | |
- @template.render :partial => "kaminari/#{@theme}#{self.class.name.demodulize.underscore}", :locals => @options.merge(locals) | |
+ @template.render :partial => partial_path, :locals => @options.merge(locals), :formats => [:html] | |
end | |
def page_url_for(page) | |
- @template.url_for @params.merge(@param_name => (page <= 1 ? nil : page)) | |
+ @template.url_for @params.merge(@param_name => (page <= 1 ? nil : page), :only_path => true) | |
+ end | |
+ | |
+ def partial_path | |
+ [ | |
+ @views_prefix, | |
+ "kaminari", | |
+ @theme, | |
+ self.class.name.demodulize.underscore | |
+ ].compact.join("/") | |
end | |
end | |
@@ -68,7 +78,7 @@ module Kaminari | |
class LastPage < Tag | |
include Link | |
def page #:nodoc: | |
- @options[:num_pages] | |
+ @options[:total_pages] | |
end | |
end | |
diff --git a/lib/kaminari/hooks.rb b/lib/kaminari/hooks.rb | |
index f6ca8fb..0a8911c 100644 | |
--- a/lib/kaminari/hooks.rb | |
+++ b/lib/kaminari/hooks.rb | |
@@ -1,29 +1,30 @@ | |
module Kaminari | |
class Hooks | |
- def self.init! | |
+ def self.init | |
ActiveSupport.on_load(:active_record) do | |
require 'kaminari/models/active_record_extension' | |
::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension | |
end | |
+ begin; require 'data_mapper'; rescue LoadError; end | |
+ if defined? ::DataMapper | |
+ require 'dm-aggregates' | |
+ require 'kaminari/models/data_mapper_extension' | |
+ ::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection | |
+ ::DataMapper::Model.append_extensions Kaminari::DataMapperExtension::Model | |
+ # ::DataMapper::Model.send :extend, Kaminari::DataMapperExtension::Model | |
+ end | |
+ | |
+ begin; require 'mongoid'; rescue LoadError; end | |
if defined? ::Mongoid | |
require 'kaminari/models/mongoid_extension' | |
::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document | |
- ::Mongoid::Criteria.send :include, Kaminari::MongoidExtension::Criteria | |
end | |
ActiveSupport.on_load(:mongo_mapper) do | |
require 'kaminari/models/mongo_mapper_extension' | |
::MongoMapper::Document.send :include, Kaminari::MongoMapperExtension::Document | |
::Plucky::Query.send :include, Kaminari::PluckyCriteriaMethods | |
- ::Plucky::Query.send :include, Kaminari::PageScopeMethods | |
- end | |
- | |
- if defined? ::DataMapper | |
- require 'kaminari/models/data_mapper_extension' | |
- ::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection | |
- ::DataMapper::Model.append_extensions Kaminari::DataMapperExtension::Model | |
- # ::DataMapper::Model.send :extend, Kaminari::DataMapperExtension::Model | |
end | |
require 'kaminari/models/array_extension' | |
diff --git a/lib/kaminari/models/active_record_extension.rb b/lib/kaminari/models/active_record_extension.rb | |
index edcad90..b2c7dc4 100644 | |
--- a/lib/kaminari/models/active_record_extension.rb | |
+++ b/lib/kaminari/models/active_record_extension.rb | |
@@ -8,14 +8,14 @@ module Kaminari | |
class << self | |
def inherited_with_kaminari(kls) #:nodoc: | |
inherited_without_kaminari kls | |
- kls.send(:include, Kaminari::ActiveRecordModelExtension) if kls.superclass == ActiveRecord::Base | |
+ kls.send(:include, Kaminari::ActiveRecordModelExtension) if kls.superclass == ::ActiveRecord::Base | |
end | |
alias_method_chain :inherited, :kaminari | |
end | |
# Existing subclasses pick up the model extension as well | |
self.descendants.each do |kls| | |
- kls.send(:include, Kaminari::ActiveRecordModelExtension) if kls.superclass == ActiveRecord::Base | |
+ kls.send(:include, Kaminari::ActiveRecordModelExtension) if kls.superclass == ::ActiveRecord::Base | |
end | |
end | |
end | |
diff --git a/lib/kaminari/models/active_record_model_extension.rb b/lib/kaminari/models/active_record_model_extension.rb | |
index b788092..e4c8c8f 100644 | |
--- a/lib/kaminari/models/active_record_model_extension.rb | |
+++ b/lib/kaminari/models/active_record_model_extension.rb | |
@@ -9,12 +9,14 @@ module Kaminari | |
# Fetch the values at the specified page number | |
# Model.page(5) | |
- self.scope Kaminari.config.page_method_name, Proc.new {|num| | |
- limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1)) | |
- } do | |
- include Kaminari::ActiveRecordRelationMethods | |
- include Kaminari::PageScopeMethods | |
- end | |
+ eval <<-RUBY | |
+ def self.#{Kaminari.config.page_method_name}(num = nil) | |
+ limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1)).extending do | |
+ include Kaminari::ActiveRecordRelationMethods | |
+ include Kaminari::PageScopeMethods | |
+ end | |
+ end | |
+ RUBY | |
end | |
end | |
end | |
diff --git a/lib/kaminari/models/active_record_relation_methods.rb b/lib/kaminari/models/active_record_relation_methods.rb | |
index 16b1209..6b9bf41 100644 | |
--- a/lib/kaminari/models/active_record_relation_methods.rb | |
+++ b/lib/kaminari/models/active_record_relation_methods.rb | |
@@ -3,30 +3,33 @@ module Kaminari | |
# a workaround for AR 3.0.x that returns 0 for #count when page > 1 | |
# if +limit_value+ is specified, load all the records and count them | |
if ActiveRecord::VERSION::STRING < '3.1' | |
- def count #:nodoc: | |
- limit_value ? length : super | |
+ def count(column_name = nil, options = {}) #:nodoc: | |
+ limit_value && !options[:distinct] ? length : super(column_name, options) | |
end | |
end | |
- def total_count #:nodoc: | |
+ def entry_name | |
+ model_name.human.downcase | |
+ end | |
+ | |
+ def total_count(column_name = :all, options = {}) #:nodoc: | |
# #count overrides the #select which could include generated columns referenced in #order, so skip #order here, where it's irrelevant to the result anyway | |
@total_count ||= begin | |
c = except(:offset, :limit, :order) | |
- # a workaround for 3.1.beta1 bug. see: https://github.com/rails/rails/issues/406 | |
- c = c.reorder nil | |
- | |
# Remove includes only if they are irrelevant | |
c = c.except(:includes) unless references_eager_loaded_tables? | |
- # a workaround to count the actual model instances on distinct query because count + distinct returns wrong value in some cases. see https://github.com/amatsuda/kaminari/pull/160 | |
- uses_distinct_sql_statement = c.to_sql =~ /DISTINCT/i | |
- if uses_distinct_sql_statement | |
- c.length | |
+ # Rails 4.1 removes the `options` argument from AR::Relation#count | |
+ args = [column_name] | |
+ args << options if ActiveRecord::VERSION::STRING < '4.1.0' | |
+ | |
+ # .group returns an OrderdHash that responds to #count | |
+ c = c.count(*args) | |
+ if c.is_a?(Hash) || c.is_a?(ActiveSupport::OrderedHash) | |
+ c.count | |
else | |
- # .group returns an OrderdHash that responds to #count | |
- c = c.count | |
- c.respond_to?(:count) ? c.count : c | |
+ c.respond_to?(:count) ? c.count(*args) : c | |
end | |
end | |
end | |
diff --git a/lib/kaminari/models/array_extension.rb b/lib/kaminari/models/array_extension.rb | |
index 363b0be..6d28485 100644 | |
--- a/lib/kaminari/models/array_extension.rb | |
+++ b/lib/kaminari/models/array_extension.rb | |
@@ -11,19 +11,21 @@ module Kaminari | |
# * <tt>:offset</tt> - offset | |
# * <tt>:total_count</tt> - total_count | |
def initialize(original_array = [], options = {}) | |
- @_original_array, @_limit_value, @_offset_value, @_total_count = original_array, (options[:limit] || default_per_page).to_i, options[:offset].to_i, options[:total_count] | |
+ @_original_array, @_limit_value, @_offset_value, @_total_count, @_padding = original_array, (options[:limit] || default_per_page).to_i, options[:offset].to_i, options[:total_count], options[:padding].to_i | |
if options[:limit] && options[:offset] | |
- class << self | |
- include Kaminari::PageScopeMethods | |
- end | |
+ extend Kaminari::PageScopeMethods | |
end | |
- if options[:total_count] | |
- super original_array | |
- else | |
- super(original_array[@_offset_value, @_limit_value] || []) | |
+ if @_total_count | |
+ original_array = original_array.first(@_total_count) | |
end | |
+ | |
+ super(original_array[@_offset_value, @_limit_value] || []) | |
+ end | |
+ | |
+ def entry_name | |
+ "entry" | |
end | |
# items at the specified "page" | |
@@ -35,7 +37,7 @@ module Kaminari | |
# returns another chunk of the original array | |
def limit(num) | |
- self.class.new @_original_array, :limit => num, :offset => @_offset_value, :total_count => @_total_count | |
+ self.class.new @_original_array, :limit => num, :offset => @_offset_value, :total_count => @_total_count, :padding => @_padding | |
end | |
# total item numbers of the original array | |
@@ -45,7 +47,7 @@ module Kaminari | |
# returns another chunk of the original array | |
def offset(num) | |
- self.class.new @_original_array, :limit => @_limit_value, :offset => num, :total_count => @_total_count | |
+ self.class.new @_original_array, :limit => @_limit_value, :offset => num, :total_count => @_total_count, :padding => @_padding | |
end | |
end | |
diff --git a/lib/kaminari/models/configuration_methods.rb b/lib/kaminari/models/configuration_methods.rb | |
index 724f94a..747b4bf 100644 | |
--- a/lib/kaminari/models/configuration_methods.rb | |
+++ b/lib/kaminari/models/configuration_methods.rb | |
@@ -13,7 +13,35 @@ module Kaminari | |
# This model's default +per_page+ value | |
# returns +default_per_page+ value unless explicitly overridden via <tt>paginates_per</tt> | |
def default_per_page | |
- @_default_per_page || Kaminari.config.default_per_page | |
+ (defined?(@_default_per_page) && @_default_per_page) || Kaminari.config.default_per_page | |
+ end | |
+ | |
+ # Overrides the max +per_page+ value per model | |
+ # class Article < ActiveRecord::Base | |
+ # max_paginates_per 100 | |
+ # end | |
+ def max_paginates_per(val) | |
+ @_max_per_page = val | |
+ end | |
+ | |
+ # This model's max +per_page+ value | |
+ # returns +max_per_page+ value unless explicitly overridden via <tt>max_paginates_per</tt> | |
+ def max_per_page | |
+ (defined?(@_max_per_page) && @_max_per_page) || Kaminari.config.max_per_page | |
+ end | |
+ | |
+ # Overrides the max_pages value per model | |
+ # class Article < ActiveRecord::Base | |
+ # max_pages_per 100 | |
+ # end | |
+ def max_pages_per(val) | |
+ @_max_pages = val | |
+ end | |
+ | |
+ # This model's max_pages value | |
+ # returns max_pages value unless explicitly overridden via <tt>max_pages_per</tt> | |
+ def max_pages | |
+ (defined?(@_max_pages) && @_max_pages) || Kaminari.config.max_pages | |
end | |
end | |
end | |
diff --git a/lib/kaminari/models/data_mapper_collection_methods.rb b/lib/kaminari/models/data_mapper_collection_methods.rb | |
index 7400b38..8bff962 100644 | |
--- a/lib/kaminari/models/data_mapper_collection_methods.rb | |
+++ b/lib/kaminari/models/data_mapper_collection_methods.rb | |
@@ -1,5 +1,9 @@ | |
module Kaminari | |
module DataMapperCollectionMethods | |
+ def entry_name | |
+ model.model_name.human.downcase | |
+ end | |
+ | |
def limit_value #:nodoc: | |
query.options[:limit] || 0 | |
end | |
diff --git a/lib/kaminari/models/data_mapper_extension.rb b/lib/kaminari/models/data_mapper_extension.rb | |
index 4778da7..409c307 100644 | |
--- a/lib/kaminari/models/data_mapper_extension.rb | |
+++ b/lib/kaminari/models/data_mapper_extension.rb | |
@@ -5,8 +5,10 @@ module Kaminari | |
module Paginatable | |
class_eval <<-RUBY, __FILE__, __LINE__ + 1 | |
def #{Kaminari.config.page_method_name}(num = 1) | |
+ model = self | |
+ model = self.model if self.is_a? DataMapper::Collection | |
num = [num.to_i, 1].max - 1 | |
- all(:limit => default_per_page, :offset => default_per_page * num).extend Paginating | |
+ all(:limit => model.default_per_page, :offset => model.default_per_page * num).extend Paginating | |
end | |
RUBY | |
end | |
@@ -26,9 +28,10 @@ module Kaminari | |
module Collection | |
extend ActiveSupport::Concern | |
included do | |
- include Kaminari::ConfigurationMethods::ClassMethods | |
include Kaminari::DataMapperCollectionMethods | |
include Paginatable | |
+ | |
+ delegate :default_per_page, :max_per_page, :max_pages, :to => :model | |
end | |
end | |
diff --git a/lib/kaminari/models/mongoid_criteria_methods.rb b/lib/kaminari/models/mongoid_criteria_methods.rb | |
index d401a59..22c1dad 100644 | |
--- a/lib/kaminari/models/mongoid_criteria_methods.rb | |
+++ b/lib/kaminari/models/mongoid_criteria_methods.rb | |
@@ -1,5 +1,9 @@ | |
module Kaminari | |
module MongoidCriteriaMethods | |
+ def entry_name | |
+ model_name.human.downcase | |
+ end | |
+ | |
def limit_value #:nodoc: | |
options[:limit] | |
end | |
@@ -9,7 +13,15 @@ module Kaminari | |
end | |
def total_count #:nodoc: | |
- embedded? ? unpage.count : count | |
+ @total_count ||= if embedded? | |
+ unpage.count | |
+ else | |
+ if options[:max_scan] && options[:max_scan] < count | |
+ options[:max_scan] | |
+ else | |
+ count | |
+ end | |
+ end | |
end | |
private | |
diff --git a/lib/kaminari/models/mongoid_extension.rb b/lib/kaminari/models/mongoid_extension.rb | |
index 8b2f8bc..eb50cd0 100644 | |
--- a/lib/kaminari/models/mongoid_extension.rb | |
+++ b/lib/kaminari/models/mongoid_extension.rb | |
@@ -2,18 +2,6 @@ require 'kaminari/models/mongoid_criteria_methods' | |
module Kaminari | |
module MongoidExtension | |
- module Criteria | |
- extend ActiveSupport::Concern | |
- | |
- included do | |
- class_eval <<-RUBY, __FILE__, __LINE__ + 1 | |
- def #{Kaminari.config.page_method_name}(*args) | |
- super(*args).criteria.merge(self) | |
- end | |
- RUBY | |
- end | |
- end | |
- | |
module Document | |
extend ActiveSupport::Concern | |
include Kaminari::ConfigurationMethods | |
diff --git a/lib/kaminari/models/page_scope_methods.rb b/lib/kaminari/models/page_scope_methods.rb | |
index 273f983..b47134a 100644 | |
--- a/lib/kaminari/models/page_scope_methods.rb | |
+++ b/lib/kaminari/models/page_scope_methods.rb | |
@@ -5,33 +5,66 @@ module Kaminari | |
def per(num) | |
if (n = num.to_i) <= 0 | |
self | |
+ elsif max_per_page && max_per_page < n | |
+ limit(max_per_page).offset(offset_value / limit_value * max_per_page) | |
else | |
limit(n).offset(offset_value / limit_value * n) | |
end | |
end | |
def padding(num) | |
+ @_padding = num | |
offset(offset_value + num.to_i) | |
end | |
# Total number of pages | |
- def num_pages | |
- (total_count.to_f / limit_value).ceil | |
+ def total_pages | |
+ count_without_padding = total_count | |
+ count_without_padding -= @_padding if defined?(@_padding) && @_padding | |
+ count_without_padding = 0 if count_without_padding < 0 | |
+ | |
+ total_pages_count = (count_without_padding.to_f / limit_value).ceil | |
+ if max_pages.present? && max_pages < total_pages_count | |
+ max_pages | |
+ else | |
+ total_pages_count | |
+ end | |
end | |
+ #FIXME for compatibility. remove num_pages at some time in the future | |
+ alias num_pages total_pages | |
# Current page number | |
def current_page | |
- (offset_value / limit_value) + 1 | |
+ offset_without_padding = offset_value | |
+ offset_without_padding -= @_padding if defined?(@_padding) && @_padding | |
+ offset_without_padding = 0 if offset_without_padding < 0 | |
+ | |
+ (offset_without_padding / limit_value) + 1 | |
+ end | |
+ | |
+ # Next page number in the collection | |
+ def next_page | |
+ current_page + 1 unless last_page? | |
+ end | |
+ | |
+ # Previous page number in the collection | |
+ def prev_page | |
+ current_page - 1 unless first_page? | |
end | |
- # First page of the collection ? | |
+ # First page of the collection? | |
def first_page? | |
current_page == 1 | |
end | |
# Last page of the collection? | |
def last_page? | |
- current_page >= num_pages | |
+ current_page >= total_pages | |
+ end | |
+ | |
+ # Out of range of the collection? | |
+ def out_of_range? | |
+ current_page > total_pages | |
end | |
end | |
end | |
diff --git a/lib/kaminari/models/plucky_criteria_methods.rb b/lib/kaminari/models/plucky_criteria_methods.rb | |
index 039f6d9..9286746 100644 | |
--- a/lib/kaminari/models/plucky_criteria_methods.rb | |
+++ b/lib/kaminari/models/plucky_criteria_methods.rb | |
@@ -1,5 +1,13 @@ | |
module Kaminari | |
module PluckyCriteriaMethods | |
+ include Kaminari::PageScopeMethods | |
+ | |
+ delegate :default_per_page, :max_per_page, :max_pages, :to => :model | |
+ | |
+ def entry_name | |
+ model.model_name.human.downcase | |
+ end | |
+ | |
def limit_value #:nodoc: | |
options[:limit] | |
end | |
diff --git a/lib/kaminari/railtie.rb b/lib/kaminari/railtie.rb | |
index a5d908a..96a42bb 100644 | |
--- a/lib/kaminari/railtie.rb | |
+++ b/lib/kaminari/railtie.rb | |
@@ -1,7 +1,7 @@ | |
module Kaminari | |
class Railtie < ::Rails::Railtie #:nodoc: | |
- initializer 'kaminari' do |app| | |
- Kaminari::Hooks.init! | |
+ initializer 'kaminari' do |_app| | |
+ Kaminari::Hooks.init | |
end | |
end | |
end | |
diff --git a/lib/kaminari/sinatra.rb b/lib/kaminari/sinatra.rb | |
index ec317e4..6b28024 100644 | |
--- a/lib/kaminari/sinatra.rb | |
+++ b/lib/kaminari/sinatra.rb | |
@@ -1,13 +1,5 @@ | |
-begin | |
- require 'sinatra/base' | |
-rescue LoadError | |
- raise LoadError, "couldn't load `sinatra/base`, check out if appropriately bundled sinatra gem?" | |
-end | |
- | |
+require 'sinatra/base' | |
require 'kaminari' | |
-module Kaminari::Helpers | |
-end | |
require 'kaminari/helpers/sinatra_helpers' | |
-Kaminari::Hooks.init! | |
- | |
+Kaminari::Hooks.init | |
diff --git a/lib/kaminari/version.rb b/lib/kaminari/version.rb | |
index 4513711..ee9ab7c 100644 | |
--- a/lib/kaminari/version.rb | |
+++ b/lib/kaminari/version.rb | |
@@ -1,3 +1,3 @@ | |
module Kaminari | |
- VERSION = '0.13.0' | |
+ VERSION = '0.16.1' | |
end | |
diff --git a/spec/config/config_spec.rb b/spec/config/config_spec.rb | |
index 2fa70c6..260d07b 100644 | |
--- a/spec/config/config_spec.rb | |
+++ b/spec/config/config_spec.rb | |
@@ -17,6 +17,21 @@ describe Kaminari::Configuration do | |
end | |
end | |
+ describe 'max_per_page' do | |
+ context 'by default' do | |
+ its(:max_per_page) { should == nil } | |
+ end | |
+ context 'configure via config block' do | |
+ before do | |
+ Kaminari.configure {|c| c.max_per_page = 100} | |
+ end | |
+ its(:max_per_page) { should == 100 } | |
+ after do | |
+ Kaminari.configure {|c| c.max_per_page = nil} | |
+ end | |
+ end | |
+ end | |
+ | |
describe 'window' do | |
context 'by default' do | |
its(:window) { should == 4 } | |
@@ -58,4 +73,19 @@ describe Kaminari::Configuration do | |
end | |
end | |
end | |
+ | |
+ describe 'max_pages' do | |
+ context 'by default' do | |
+ its(:max_pages) { should == nil } | |
+ end | |
+ context 'configure via config block' do | |
+ before do | |
+ Kaminari.configure {|c| c.max_pages = 5} | |
+ end | |
+ its(:max_pages) { should == 5 } | |
+ after do | |
+ Kaminari.configure {|c| c.max_pages = nil} | |
+ end | |
+ end | |
+ end | |
end | |
diff --git a/spec/fake_app.rb b/spec/fake_app.rb | |
deleted file mode 100644 | |
index 38a21f5..0000000 | |
--- a/spec/fake_app.rb | |
+++ /dev/null | |
@@ -1,84 +0,0 @@ | |
-require 'active_record' | |
-require 'action_controller/railtie' | |
-require 'action_view/railtie' | |
- | |
-# database | |
-ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}} | |
-ActiveRecord::Base.establish_connection('test') | |
- | |
-# config | |
-app = Class.new(Rails::Application) | |
-app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" | |
-app.config.session_store :cookie_store, :key => "_myapp_session" | |
-app.config.active_support.deprecation = :log | |
-app.initialize! | |
- | |
-# routes | |
-app.routes.draw do | |
- resources :users | |
-end | |
- | |
-# models | |
-class User < ActiveRecord::Base | |
- has_many :authorships | |
- has_many :readerships | |
- has_many :books_authored, :through => :authorships, :source => :book | |
- has_many :books_read, :through => :readerships, :source => :book | |
- | |
- def readers | |
- User.joins(:books_read => :authors).where(:authors_books => {:id => self}) | |
- end | |
- | |
- scope :by_name, order(:name) | |
- scope :by_read_count, lambda { | |
- cols = if connection.adapter_name == "PostgreSQL" | |
- column_names.map { |column| %{"users"."#{column}"} }.join(", ") | |
- else | |
- '"users"."id"' | |
- end | |
- group(cols).select("count(readerships.id) AS read_count, #{cols}").order('read_count DESC') | |
- } | |
-end | |
-class Authorship < ActiveRecord::Base | |
- belongs_to :user | |
- belongs_to :book | |
-end | |
-class Readership < ActiveRecord::Base | |
- belongs_to :user | |
- belongs_to :book | |
-end | |
-class Book < ActiveRecord::Base | |
- has_many :authorships | |
- has_many :readerships | |
- has_many :authors, :through => :authorships, :source => :user | |
- has_many :readers, :through => :readerships, :source => :user | |
-end | |
-# a model that is a descendant of AR::Base but doesn't directly inherit AR::Base | |
-class Admin < User | |
-end | |
- | |
-# controllers | |
-class ApplicationController < ActionController::Base; end | |
-class UsersController < ApplicationController | |
- def index | |
- @users = User.page params[:page] | |
- render :inline => <<-ERB | |
-<%= @users.map(&:name).join("\n") %> | |
-<%= paginate @users %> | |
-ERB | |
- end | |
-end | |
- | |
-# helpers | |
-Object.const_set(:ApplicationHelper, Module.new) | |
- | |
-#migrations | |
-class CreateAllTables < ActiveRecord::Migration | |
- def self.up | |
- create_table(:gem_defined_models) { |t| t.string :name; t.integer :age } | |
- create_table(:users) {|t| t.string :name; t.integer :age} | |
- create_table(:books) {|t| t.string :title} | |
- create_table(:readerships) {|t| t.integer :user_id; t.integer :book_id } | |
- create_table(:authorships) {|t| t.integer :user_id; t.integer :book_id } | |
- end | |
-end | |
diff --git a/spec/fake_app/active_record/config.rb b/spec/fake_app/active_record/config.rb | |
new file mode 100644 | |
index 0000000..7176b33 | |
--- /dev/null | |
+++ b/spec/fake_app/active_record/config.rb | |
@@ -0,0 +1,3 @@ | |
+# database | |
+ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}} | |
+ActiveRecord::Base.establish_connection :test | |
diff --git a/spec/fake_app/active_record/models.rb b/spec/fake_app/active_record/models.rb | |
new file mode 100644 | |
index 0000000..ab59d84 | |
--- /dev/null | |
+++ b/spec/fake_app/active_record/models.rb | |
@@ -0,0 +1,65 @@ | |
+# models | |
+class User < ActiveRecord::Base | |
+ has_many :authorships | |
+ has_many :readerships | |
+ has_many :books_authored, :through => :authorships, :source => :book | |
+ has_many :books_read, :through => :readerships, :source => :book | |
+ has_many :addresses, :class_name => 'User::Address' | |
+ | |
+ def readers | |
+ User.joins(:books_read => :authors).where(:authors_books => {:id => self}) | |
+ end | |
+ | |
+ scope :by_name, order(:name) | |
+ scope :by_read_count, lambda { | |
+ cols = if connection.adapter_name == "PostgreSQL" | |
+ column_names.map { |column| %{"users"."#{column}"} }.join(", ") | |
+ else | |
+ '"users"."id"' | |
+ end | |
+ group(cols).select("count(readerships.id) AS read_count, #{cols}").order('read_count DESC') | |
+ } | |
+end | |
+class Authorship < ActiveRecord::Base | |
+ belongs_to :user | |
+ belongs_to :book | |
+end | |
+class Readership < ActiveRecord::Base | |
+ belongs_to :user | |
+ belongs_to :book | |
+end | |
+class Book < ActiveRecord::Base | |
+ has_many :authorships | |
+ has_many :readerships | |
+ has_many :authors, :through => :authorships, :source => :user | |
+ has_many :readers, :through => :readerships, :source => :user | |
+end | |
+# a model that is a descendant of AR::Base but doesn't directly inherit AR::Base | |
+class Admin < User | |
+end | |
+# a model with namespace | |
+class User::Address < ActiveRecord::Base | |
+ belongs_to :user | |
+end | |
+ | |
+# a class that uses abstract class | |
+class Product < ActiveRecord::Base | |
+ self.abstract_class = true | |
+end | |
+class Device < Product | |
+end | |
+ | |
+#migrations | |
+class CreateAllTables < ActiveRecord::Migration | |
+ def self.up | |
+ create_table(:gem_defined_models) { |t| t.string :name; t.integer :age } | |
+ create_table(:users) {|t| t.string :name; t.integer :age} | |
+ create_table(:books) {|t| t.string :title} | |
+ create_table(:readerships) {|t| t.integer :user_id; t.integer :book_id } | |
+ create_table(:authorships) {|t| t.integer :user_id; t.integer :book_id } | |
+ create_table(:user_addresses) {|t| t.string :street; t.integer :user_id } | |
+ create_table(:devices) {|t| t.string :name; t.integer :age} | |
+ end | |
+end | |
+ActiveRecord::Migration.verbose = false | |
+CreateAllTables.up | |
diff --git a/spec/fake_app/data_mapper/config.rb b/spec/fake_app/data_mapper/config.rb | |
new file mode 100644 | |
index 0000000..f81a281 | |
--- /dev/null | |
+++ b/spec/fake_app/data_mapper/config.rb | |
@@ -0,0 +1 @@ | |
+DataMapper.setup(:default, 'sqlite::memory:') | |
diff --git a/spec/fake_app/data_mapper/models.rb b/spec/fake_app/data_mapper/models.rb | |
new file mode 100644 | |
index 0000000..a4d8fdd | |
--- /dev/null | |
+++ b/spec/fake_app/data_mapper/models.rb | |
@@ -0,0 +1,27 @@ | |
+class User | |
+ include ::DataMapper::Resource | |
+ | |
+ property :id, Serial | |
+ property :name, String, :required => true | |
+ property :age, Integer | |
+ | |
+ has n, :projects, :through => Resource | |
+end | |
+ | |
+class User::Address | |
+ include ::DataMapper::Resource | |
+ | |
+ property :id, Serial | |
+end | |
+ | |
+class Project | |
+ include ::DataMapper::Resource | |
+ | |
+ property :id, Serial | |
+ property :name, String, :required => true | |
+ | |
+ has n, :users, :through => Resource | |
+end | |
+ | |
+DataMapper.finalize | |
+DataMapper.auto_migrate! | |
diff --git a/spec/fake_app/mongo_mapper/config.rb b/spec/fake_app/mongo_mapper/config.rb | |
new file mode 100644 | |
index 0000000..ef00915 | |
--- /dev/null | |
+++ b/spec/fake_app/mongo_mapper/config.rb | |
@@ -0,0 +1,2 @@ | |
+MongoMapper.connection = Mongo::Connection.new 'localhost', 27017 | |
+MongoMapper.database = 'kaminari_test' | |
diff --git a/spec/fake_app/mongo_mapper/models.rb b/spec/fake_app/mongo_mapper/models.rb | |
new file mode 100644 | |
index 0000000..95e5062 | |
--- /dev/null | |
+++ b/spec/fake_app/mongo_mapper/models.rb | |
@@ -0,0 +1,9 @@ | |
+class User | |
+ include ::MongoMapper::Document | |
+ key :name, String | |
+ key :age, Integer | |
+end | |
+ | |
+class User::Address | |
+ include ::MongoMapper::Document | |
+end | |
diff --git a/spec/fake_app/mongoid/config.rb b/spec/fake_app/mongoid/config.rb | |
new file mode 100644 | |
index 0000000..6fef455 | |
--- /dev/null | |
+++ b/spec/fake_app/mongoid/config.rb | |
@@ -0,0 +1,18 @@ | |
+# Ensure we use 'syck' instead of 'psych' in 1.9.2 | |
+# RubyGems >= 1.5.0 uses 'psych' on 1.9.2, but | |
+# Psych does not yet support YAML 1.1 merge keys. | |
+# Merge keys is often used in mongoid.yml | |
+# See: http://redmine.ruby-lang.org/issues/show/4300 | |
+require 'mongoid/version' | |
+ | |
+if RUBY_VERSION >= '1.9.2' | |
+ YAML::ENGINE.yamler = 'syck' | |
+end | |
+ | |
+Mongoid.configure do |config| | |
+ if Mongoid::VERSION > '3.0.0' | |
+ config.sessions = {:default => {:hosts => ['localhost:27017'], :database => 'kaminari_test'}} | |
+ else | |
+ config.master = Mongo::Connection.new.db('kaminari_test') | |
+ end | |
+end | |
diff --git a/spec/fake_app/mongoid/models.rb b/spec/fake_app/mongoid/models.rb | |
new file mode 100644 | |
index 0000000..8a167fc | |
--- /dev/null | |
+++ b/spec/fake_app/mongoid/models.rb | |
@@ -0,0 +1,26 @@ | |
+class User | |
+ include ::Mongoid::Document | |
+ if Mongoid::VERSION > '4.0.0' | |
+ include Mongoid::Attributes::Dynamic | |
+ end | |
+ | |
+ field :name, :type => String | |
+ field :age, :type => Integer | |
+end | |
+ | |
+class User::Address | |
+ include ::Mongoid::Document | |
+end | |
+ | |
+class MongoMongoidExtensionDeveloper | |
+ include ::Mongoid::Document | |
+ field :salary, :type => Integer | |
+ embeds_many :frameworks | |
+end | |
+ | |
+class Framework | |
+ include ::Mongoid::Document | |
+ field :name, :type => String | |
+ field :language, :type => String | |
+ embedded_in :mongo_mongoid_extension_developer | |
+end | |
diff --git a/spec/fake_app/rails_app.rb b/spec/fake_app/rails_app.rb | |
new file mode 100644 | |
index 0000000..6180331 | |
--- /dev/null | |
+++ b/spec/fake_app/rails_app.rb | |
@@ -0,0 +1,56 @@ | |
+# require 'rails/all' | |
+require 'action_controller/railtie' | |
+require 'action_view/railtie' | |
+ | |
+require 'fake_app/active_record/config' if defined? ActiveRecord | |
+require 'fake_app/data_mapper/config' if defined? DataMapper | |
+require 'fake_app/mongoid/config' if defined? Mongoid | |
+require 'fake_app/mongo_mapper/config' if defined? MongoMapper | |
+# config | |
+app = Class.new(Rails::Application) | |
+app.config.secret_token = '3b7cd727ee24e8444053437c36cc66c4' | |
+app.config.session_store :cookie_store, :key => '_myapp_session' | |
+app.config.active_support.deprecation = :log | |
+app.config.eager_load = false | |
+# Rais.root | |
+app.config.root = File.dirname(__FILE__) | |
+Rails.backtrace_cleaner.remove_silencers! | |
+app.initialize! | |
+ | |
+# routes | |
+app.routes.draw do | |
+ resources :users | |
+end | |
+ | |
+#models | |
+require 'fake_app/active_record/models' if defined? ActiveRecord | |
+require 'fake_app/data_mapper/models' if defined? DataMapper | |
+require 'fake_app/mongoid/models' if defined? Mongoid | |
+require 'fake_app/mongo_mapper/models' if defined? MongoMapper | |
+ | |
+# controllers | |
+class ApplicationController < ActionController::Base; end | |
+class UsersController < ApplicationController | |
+ def index | |
+ @users = User.page params[:page] | |
+ render :inline => <<-ERB | |
+<%= @users.map(&:name).join("\n") %> | |
+<%= paginate @users %> | |
+ERB | |
+ end | |
+end | |
+ | |
+if defined? ActiveRecord | |
+ class AddressesController < ApplicationController | |
+ def index | |
+ @addresses = User::Address.page params[:page] | |
+ render :inline => <<-ERB | |
+ <%= @addresses.map(&:street).join("\n") %> | |
+ <%= paginate @addresses %> | |
+ ERB | |
+ end | |
+ end | |
+end | |
+ | |
+# helpers | |
+Object.const_set(:ApplicationHelper, Module.new) | |
diff --git a/spec/fake_app/sinatra_app.rb b/spec/fake_app/sinatra_app.rb | |
new file mode 100644 | |
index 0000000..1ee8e24 | |
--- /dev/null | |
+++ b/spec/fake_app/sinatra_app.rb | |
@@ -0,0 +1,22 @@ | |
+require 'fake_app/active_record/config' if defined? ActiveRecord | |
+require 'fake_app/data_mapper/config' if defined? DataMapper | |
+require 'fake_app/mongoid/config' if defined? Mongoid | |
+require 'fake_app/mongo_mapper/config' if defined? MongoMapper | |
+ | |
+#models | |
+require 'fake_app/active_record/models' if defined? ActiveRecord | |
+require 'fake_app/data_mapper/models' if defined? DataMapper | |
+require 'fake_app/mongoid/models' if defined? Mongoid | |
+require 'fake_app/mongo_mapper/models' if defined? MongoMapper | |
+ | |
+class SinatraApp < Sinatra::Base | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ | |
+ get '/users' do | |
+ @users = User.page params[:page] | |
+ erb <<-ERB | |
+<%= @users.map(&:name).join("\n") %> | |
+<%= paginate @users %> | |
+ERB | |
+ end | |
+end | |
diff --git a/spec/fake_app/views/alternative/kaminari/_first_page.html.erb b/spec/fake_app/views/alternative/kaminari/_first_page.html.erb | |
new file mode 100644 | |
index 0000000..124343a | |
--- /dev/null | |
+++ b/spec/fake_app/views/alternative/kaminari/_first_page.html.erb | |
@@ -0,0 +1 @@ | |
+<b><%= current_page %></b> | |
\ No newline at end of file | |
diff --git a/spec/fake_app/views/alternative/kaminari/_paginator.html.erb b/spec/fake_app/views/alternative/kaminari/_paginator.html.erb | |
new file mode 100644 | |
index 0000000..8d6cbec | |
--- /dev/null | |
+++ b/spec/fake_app/views/alternative/kaminari/_paginator.html.erb | |
@@ -0,0 +1,3 @@ | |
+<%= paginator.render do -%> | |
+ <%= first_page_tag %> | |
+<% end -%> | |
diff --git a/spec/fake_app/views/kaminari/bootstrap/_page.html.erb b/spec/fake_app/views/kaminari/bootstrap/_page.html.erb | |
new file mode 100644 | |
index 0000000..bf46589 | |
--- /dev/null | |
+++ b/spec/fake_app/views/kaminari/bootstrap/_page.html.erb | |
@@ -0,0 +1 @@ | |
+<li class="bootstrap-page-link"><%= link_to page, url %></li> | |
diff --git a/spec/fake_app/views/kaminari/bootstrap/_paginator.html.erb b/spec/fake_app/views/kaminari/bootstrap/_paginator.html.erb | |
new file mode 100644 | |
index 0000000..7022818 | |
--- /dev/null | |
+++ b/spec/fake_app/views/kaminari/bootstrap/_paginator.html.erb | |
@@ -0,0 +1,7 @@ | |
+<div class="bootstrap-paginator"> | |
+<%= paginator.render do -%> | |
+<% each_page do |page| %> | |
+<%= page_tag(page) -%> | |
+<% end %> | |
+<% end %> | |
+</div> | |
diff --git a/spec/fake_gem.rb b/spec/fake_gem.rb | |
index a142811..fa3a1c2 100644 | |
--- a/spec/fake_gem.rb | |
+++ b/spec/fake_gem.rb | |
@@ -1,6 +1,4 @@ | |
# Simulate a gem providing a subclass of ActiveRecord::Base before the Railtie is loaded. | |
-require 'active_record' | |
- | |
class GemDefinedModel < ActiveRecord::Base | |
end | |
diff --git a/spec/generators/views_generator_spec.rb b/spec/generators/views_generator_spec.rb | |
new file mode 100644 | |
index 0000000..02870d9 | |
--- /dev/null | |
+++ b/spec/generators/views_generator_spec.rb | |
@@ -0,0 +1,18 @@ | |
+require 'spec_helper' | |
+ | |
+if defined?(Rails) | |
+ require 'rails/generators' | |
+ require 'generators/kaminari/views_generator' | |
+ | |
+ describe Kaminari::Generators::GitHubApiHelper, :generator_spec => true do | |
+ describe '.get_files_in_master' do | |
+ subject { Kaminari::Generators::GitHubApiHelper.get_files_in_master } | |
+ it { should include(["README", "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"]) } | |
+ end | |
+ | |
+ describe '.get_content_for' do | |
+ subject { Kaminari::Generators::GitHubApiHelper.get_content_for("README") } | |
+ it { should == "" } | |
+ end | |
+ end | |
+end | |
diff --git a/spec/helpers/action_view_extension_spec.rb b/spec/helpers/action_view_extension_spec.rb | |
index f82de3e..0c3285c 100644 | |
--- a/spec/helpers/action_view_extension_spec.rb | |
+++ b/spec/helpers/action_view_extension_spec.rb | |
@@ -1,115 +1,301 @@ | |
require 'spec_helper' | |
-describe 'Kaminari::ActionViewExtension' do | |
+describe 'Kaminari::ActionViewExtension', :if => defined?(Rails)do | |
describe '#paginate' do | |
before do | |
50.times {|i| User.create! :name => "user#{i}"} | |
@users = User.page(1) | |
end | |
+ | |
subject { helper.paginate @users, :params => {:controller => 'users', :action => 'index'} } | |
it { should be_a String } | |
context 'escaping the pagination for javascript' do | |
it 'should escape for javascript' do | |
- lambda { escape_javascript(helper.paginate @users, :params => {:controller => 'users', :action => 'index'}) }.should_not raise_error | |
+ lambda { helper.escape_javascript(helper.paginate @users, :params => {:controller => 'users', :action => 'index'}) }.should_not raise_error | |
end | |
end | |
+ | |
+ context 'accepts :theme option' do | |
+ before { helper.controller.append_view_path "spec/fake_app/views" } | |
+ subject { helper.paginate @users, :theme => "bootstrap", :params => {:controller => 'users', :action => 'index'} } | |
+ it { should match(/bootstrap-paginator/) } | |
+ it { should match(/bootstrap-page-link/) } | |
+ end | |
+ | |
+ context 'accepts :view_prefix option' do | |
+ before { helper.controller.append_view_path "spec/fake_app/views" } | |
+ subject { helper.paginate @users, :views_prefix => "alternative/", :params => {:controller => 'users', :action => 'index'} } | |
+ it { should eq(" <b>1</b>\n") } | |
+ end | |
end | |
- describe '#link_to_next_page' do | |
+ describe '#link_to_previous_page' do | |
before do | |
50.times {|i| User.create! :name => "user#{i}"} | |
end | |
- context 'having more page' do | |
+ | |
+ context 'having previous pages' do | |
before do | |
- @users = User.page(1) | |
+ @users = User.page(50) | |
end | |
+ | |
context 'the default behaviour' do | |
- subject { helper.link_to_next_page @users, 'More', :params => {:controller => 'users', :action => 'index'} } | |
+ subject { helper.link_to_previous_page @users, 'Previous', :params => {:controller => 'users', :action => 'index'} } | |
it { should be_a String } | |
- it { should match /rel="next"/ } | |
+ it { should match(/rel="previous"/) } | |
end | |
+ | |
context 'overriding rel=' do | |
- subject { helper.link_to_next_page @users, 'More', :rel => 'external', :params => {:controller => 'users', :action => 'index'} } | |
- it { should match /rel="external"/ } | |
+ subject { helper.link_to_previous_page @users, 'Previous', :rel => 'external', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should match(/rel="external"/) } | |
end | |
end | |
- context 'the last page' do | |
+ | |
+ context 'the first page' do | |
before do | |
- @users = User.page(2) | |
+ @users = User.page(1) | |
end | |
- subject { helper.link_to_next_page @users, 'More', :params => {:controller => 'users', :action => 'index'} } | |
+ | |
+ subject { helper.link_to_previous_page @users, 'Previous', :params => {:controller => 'users', :action => 'index'} } | |
it { should_not be } | |
end | |
end | |
- describe '#page_entries_info' do | |
+ describe '#link_to_next_page' do | |
before do | |
- @users = User.page(1).per(25) | |
- end | |
- context 'having no entries' do | |
- subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'No entries found' } | |
+ 50.times {|i| User.create! :name => "user#{i}"} | |
end | |
- context 'having 1 entry' do | |
+ context 'having more page' do | |
before do | |
- User.create! | |
- @users = User.page(1).per(25) | |
+ @users = User.page(1) | |
end | |
- subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying <b>1</b> user' } | |
- context 'setting the entry name option to "member"' do | |
- subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying <b>1</b> member' } | |
+ context 'the default behaviour' do | |
+ subject { helper.link_to_next_page @users, 'More', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should be_a String } | |
+ it { should match(/rel="next"/) } | |
+ end | |
+ | |
+ context 'overriding rel=' do | |
+ subject { helper.link_to_next_page @users, 'More', :rel => 'external', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should match(/rel="external"/) } | |
end | |
end | |
- context 'having more than 1 but less than a page of entries' do | |
+ context 'the last page' do | |
before do | |
- 10.times {|i| User.create!} | |
- @users = User.page(1).per(25) | |
+ @users = User.page(2) | |
end | |
- subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying <b>all 10</b> users' } | |
- context 'setting the entry name option to "member"' do | |
- subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying <b>all 10</b> members' } | |
- end | |
+ subject { helper.link_to_next_page @users, 'More', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should_not be } | |
end | |
+ end | |
- context 'having more than one page of entries' do | |
+ describe '#page_entries_info' do | |
+ context 'on a model without namespace' do | |
before do | |
- 50.times {|i| User.create!} | |
+ @users = User.page(1).per(25) | |
+ end | |
+ | |
+ context 'having no entries' do | |
+ subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
+ it { should == 'No users found' } | |
+ | |
+ context 'setting the entry name option to "member"' do | |
+ subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should == 'No members found' } | |
+ end | |
end | |
- describe 'the first page' do | |
+ context 'having 1 entry' do | |
before do | |
+ User.create! :name => 'user1' | |
@users = User.page(1).per(25) | |
end | |
+ | |
subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying users <b>1 - 25</b> of <b>50</b> in total' } | |
+ it { should == 'Displaying <b>1</b> user' } | |
context 'setting the entry name option to "member"' do | |
subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying members <b>1 - 25</b> of <b>50</b> in total' } | |
+ it { should == 'Displaying <b>1</b> member' } | |
end | |
end | |
- describe 'the next page' do | |
+ context 'having more than 1 but less than a page of entries' do | |
before do | |
- @users = User.page(2).per(25) | |
+ 10.times {|i| User.create! :name => "user#{i}"} | |
+ @users = User.page(1).per(25) | |
end | |
+ | |
subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying users <b>26 - 50</b> of <b>50</b> in total' } | |
+ it { should == 'Displaying <b>all 10</b> users' } | |
context 'setting the entry name option to "member"' do | |
subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
- it { should == 'Displaying members <b>26 - 50</b> of <b>50</b> in total' } | |
+ it { should == 'Displaying <b>all 10</b> members' } | |
end | |
end | |
+ | |
+ context 'having more than one page of entries' do | |
+ before do | |
+ 50.times {|i| User.create! :name => "user#{i}"} | |
+ end | |
+ | |
+ describe 'the first page' do | |
+ before do | |
+ @users = User.page(1).per(25) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
+ it { should == 'Displaying users <b>1 - 25</b> of <b>50</b> in total' } | |
+ | |
+ context 'setting the entry name option to "member"' do | |
+ subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should == 'Displaying members <b>1 - 25</b> of <b>50</b> in total' } | |
+ end | |
+ end | |
+ | |
+ describe 'the next page' do | |
+ before do | |
+ @users = User.page(2).per(25) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @users, :params => {:controller => 'users', :action => 'index'} } | |
+ it { should == 'Displaying users <b>26 - 50</b> of <b>50</b> in total' } | |
+ | |
+ context 'setting the entry name option to "member"' do | |
+ subject { helper.page_entries_info @users, :entry_name => 'member', :params => {:controller => 'users', :action => 'index'} } | |
+ it { should == 'Displaying members <b>26 - 50</b> of <b>50</b> in total' } | |
+ end | |
+ end | |
+ end | |
+ end | |
+ context 'on a model with namespace' do | |
+ before do | |
+ @addresses = User::Address.page(1).per(25) | |
+ end | |
+ | |
+ context 'having no entries' do | |
+ subject { helper.page_entries_info @addresses, :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'No addresses found' } | |
+ end | |
+ | |
+ context 'having 1 entry' do | |
+ before do | |
+ User::Address.create! | |
+ @addresses = User::Address.page(1).per(25) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @addresses, :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying <b>1</b> address' } | |
+ | |
+ context 'setting the entry name option to "place"' do | |
+ subject { helper.page_entries_info @addresses, :entry_name => 'place', :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying <b>1</b> place' } | |
+ end | |
+ end | |
+ | |
+ context 'having more than 1 but less than a page of entries' do | |
+ before do | |
+ 10.times {|i| User::Address.create!} | |
+ @addresses = User::Address.page(1).per(25) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @addresses, :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying <b>all 10</b> addresses' } | |
+ | |
+ context 'setting the entry name option to "place"' do | |
+ subject { helper.page_entries_info @addresses, :entry_name => 'place', :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying <b>all 10</b> places' } | |
+ end | |
+ end | |
+ | |
+ context 'having more than one page of entries' do | |
+ before do | |
+ 50.times {|i| User::Address.create!} | |
+ end | |
+ | |
+ describe 'the first page' do | |
+ before do | |
+ @addresses = User::Address.page(1).per(25) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @addresses, :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying addresses <b>1 - 25</b> of <b>50</b> in total' } | |
+ | |
+ context 'setting the entry name option to "place"' do | |
+ subject { helper.page_entries_info @addresses, :entry_name => 'place', :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying places <b>1 - 25</b> of <b>50</b> in total' } | |
+ end | |
+ end | |
+ | |
+ describe 'the next page' do | |
+ before do | |
+ @addresses = User::Address.page(2).per(25) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @addresses, :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying addresses <b>26 - 50</b> of <b>50</b> in total' } | |
+ | |
+ context 'setting the entry name option to "place"' do | |
+ subject { helper.page_entries_info @addresses, :entry_name => 'place', :params => {:controller => 'addresses', :action => 'index'} } | |
+ it { should == 'Displaying places <b>26 - 50</b> of <b>50</b> in total' } | |
+ end | |
+ end | |
+ end | |
+ end | |
+ | |
+ context 'on a PaginatableArray' do | |
+ before do | |
+ @numbers = Kaminari.paginate_array(%w{one two three}).page(1) | |
+ end | |
+ | |
+ subject { helper.page_entries_info @numbers } | |
+ it { should == 'Displaying <b>all 3</b> entries' } | |
+ end | |
+ end | |
+ | |
+ describe '#rel_next_prev_link_tags' do | |
+ before do | |
+ 80.times {|i| User.create! :name => "user#{i}"} | |
+ end | |
+ | |
+ context 'the first page' do | |
+ before do | |
+ @users = User.page(1).per(25) | |
+ end | |
+ | |
+ subject { helper.rel_next_prev_link_tags @users, :params => {:controller => 'users', :action => 'index'} } | |
+ it { should_not match(/rel="prev"/) } | |
+ it { should match(/rel="next"/) } | |
+ it { should match(/\?page=2/) } | |
+ end | |
+ | |
+ context 'the middle page' do | |
+ before do | |
+ @users = User.page(3).per(25) | |
+ end | |
+ | |
+ subject { helper.rel_next_prev_link_tags @users, :params => {:controller => 'users', :action => 'index'} } | |
+ it { should match(/rel="prev"/) } | |
+ it { should match(/\?page=2/) } | |
+ it { should match(/rel="next"/) } | |
+ it { should match(/\?page=4/) } | |
+ end | |
+ | |
+ context 'the last page' do | |
+ before do | |
+ @users = User.page(4).per(25) | |
+ end | |
+ | |
+ subject { helper.rel_next_prev_link_tags @users, :params => {:controller => 'users', :action => 'index'} } | |
+ it { should match(/rel="prev"/) } | |
+ it { should match(/\?page=3"/) } | |
+ it { should_not match(/rel="next"/) } | |
end | |
end | |
end | |
diff --git a/spec/helpers/helpers_spec.rb b/spec/helpers/helpers_spec.rb | |
index d1ff21d..fe6d7ce 100644 | |
--- a/spec/helpers/helpers_spec.rb | |
+++ b/spec/helpers/helpers_spec.rb | |
@@ -8,10 +8,19 @@ describe 'Kaminari::Helpers::Paginator' do | |
params { {} } | |
options { {} } | |
url_for {|h| "/foo?page=#{h[:page]}"} | |
+ link_to { "<a href='#'>link</a>" } | |
end | |
r | |
end | |
+ describe "view helper methods delegated to template" do | |
+ before do | |
+ @paginator = Paginator.new(template, :params => {}) | |
+ end | |
+ subject { @paginator.link_to("link", "#") } | |
+ it { should == "<a href='#'>link</a>" } | |
+ end | |
+ | |
describe '#params' do | |
before do | |
@paginator = Paginator.new(template, :params => {:controller => 'foo', :action => 'bar'}) | |
@@ -35,13 +44,13 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context '1 page in total' do | |
-# subject { tags_with :num_pages => 1, :current_page => 1 } | |
+# subject { tags_with :total_pages => 1, :current_page => 1 } | |
# it { should have(0).tags } | |
# end | |
# context '10 pages in total' do | |
# context 'first page' do | |
-# subject { tags_with :num_pages => 10, :current_page => 1 } | |
+# subject { tags_with :total_pages => 10, :current_page => 1 } | |
# it { should_not contain_tag PrevLink } | |
# it { should contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
@@ -54,7 +63,7 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context 'second page' do | |
-# subject { tags_with :num_pages => 10, :current_page => 2 } | |
+# subject { tags_with :total_pages => 10, :current_page => 2 } | |
# it { should contain_tag PrevLink } | |
# it { should_not contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
@@ -67,7 +76,7 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context 'third page' do | |
-# subject { tags_with :num_pages => 10, :current_page => 3 } | |
+# subject { tags_with :total_pages => 10, :current_page => 3 } | |
# it { should contain_tag PrevLink } | |
# it { should_not contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
@@ -80,7 +89,7 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context 'fourth page(no truncation)' do | |
-# subject { tags_with :num_pages => 10, :current_page => 4 } | |
+# subject { tags_with :total_pages => 10, :current_page => 4 } | |
# it { should contain_tag PrevLink } | |
# it { should_not contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
@@ -93,7 +102,7 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context 'seventh page(no truncation)' do | |
-# subject { tags_with :num_pages => 10, :current_page => 7 } | |
+# subject { tags_with :total_pages => 10, :current_page => 7 } | |
# it { should contain_tag PrevLink } | |
# it { should_not contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
@@ -106,7 +115,7 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context 'eighth page' do | |
-# subject { tags_with :num_pages => 10, :current_page => 8 } | |
+# subject { tags_with :total_pages => 10, :current_page => 8 } | |
# it { should contain_tag PrevLink } | |
# it { should_not contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
@@ -119,7 +128,7 @@ describe 'Kaminari::Helpers::Paginator' do | |
# end | |
# context 'last page' do | |
-# subject { tags_with :num_pages => 10, :current_page => 10 } | |
+# subject { tags_with :total_pages => 10, :current_page => 10 } | |
# it { should contain_tag PrevLink } | |
# it { should_not contain_tag PrevSpan } | |
# it { should contain_tag CurrentPage } | |
diff --git a/spec/helpers/sinatra_helpers_spec.rb b/spec/helpers/sinatra_helpers_spec.rb | |
index 750e326..d189531 100644 | |
--- a/spec/helpers/sinatra_helpers_spec.rb | |
+++ b/spec/helpers/sinatra_helpers_spec.rb | |
@@ -1,173 +1,222 @@ | |
require 'spec_helper' | |
-require 'spec_helper_for_sinatra' | |
- | |
-ERB_TEMPLATE_FOR_PAGINATE = <<EOT | |
-<div> | |
-<ul> | |
-<% @users.each do |user| %> | |
- <li class="user_info"><%= user.id %></li> | |
-<% end %> | |
-</ul> | |
-<%= paginate @users, @options %> | |
-</div> | |
+ | |
+if defined? Sinatra | |
+ ERB_TEMPLATE_FOR_PAGINATE = <<EOT | |
+ <div> | |
+ <ul> | |
+ <% @users.each do |user| %> | |
+ <li class="user_info"><%= user.id %></li> | |
+ <% end %> | |
+ </ul> | |
+ <%= paginate @users, @options %> | |
+ </div> | |
EOT | |
-ERB_TEMPLATE_FOR_NEXT_PAGE = <<EOT | |
-<div> | |
-<ul> | |
-<% @users.each do |user| %> | |
- <li class="user_info"><%= user.id %></li> | |
-<% end %> | |
-</ul> | |
-<%= link_to_next_page(@users, "Next!", {:id => 'next_page_link'}.merge(@options || {})) %> | |
-</div> | |
+ ERB_TEMPLATE_FOR_PREVIOUS_PAGE = <<EOT | |
+ <div> | |
+ <ul> | |
+ <% @users.each do |user| %> | |
+ <li class="user_info"><%= user.id %></li> | |
+ <% end %> | |
+ </ul> | |
+ <%= link_to_previous_page(@users, "Previous!", {:id => 'previous_page_link'}.merge(@options || {})) %> | |
+ </div> | |
EOT | |
-describe 'Kaminari::Helpers::SinatraHelper' do | |
- before do | |
- 50.times {|i| User.create! :name => "user#{i}"} | |
- end | |
+ ERB_TEMPLATE_FOR_NEXT_PAGE = <<EOT | |
+ <div> | |
+ <ul> | |
+ <% @users.each do |user| %> | |
+ <li class="user_info"><%= user.id %></li> | |
+ <% end %> | |
+ </ul> | |
+ <%= link_to_next_page(@users, "Next!", {:id => 'next_page_link'}.merge(@options || {})) %> | |
+ </div> | |
+EOT | |
- describe '#paginate' do | |
+ describe 'Kaminari::Helpers::SinatraHelper' do | |
before do | |
- mock_app do | |
- register Kaminari::Helpers::SinatraHelpers | |
- get '/users' do | |
- @page = params[:page] || 1 | |
- @users = User.page(@page) | |
- @options = {} | |
- erb ERB_TEMPLATE_FOR_PAGINATE | |
+ 50.times {|i| User.create! :name => "user#{i}"} | |
+ end | |
+ | |
+ describe '#paginate' do | |
+ before do | |
+ mock_app do | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ get '/users' do | |
+ @page = params[:page] || 1 | |
+ @users = User.page(@page) | |
+ @options = {} | |
+ erb ERB_TEMPLATE_FOR_PAGINATE | |
+ end | |
end | |
end | |
- end | |
- context 'normal paginations with Sinatra' do | |
- before { get '/users' } | |
+ context 'normal paginations with Sinatra' do | |
+ before { get '/users' } | |
- it 'should have a navigation tag' do | |
- last_document.search('nav.pagination').should_not be_empty | |
- end | |
+ it 'should have a navigation tag' do | |
+ last_document.search('nav.pagination').should_not be_empty | |
+ end | |
- it 'should have pagination links' do | |
- last_document.search('.page a').should have_at_least(1).items | |
- last_document.search('.next a').should have_at_least(1).items | |
- last_document.search('.last a').should have_at_least(1).items | |
- end | |
+ it 'should have pagination links' do | |
+ last_document.search('.page a').should have_at_least(1).items | |
+ last_document.search('.next a').should have_at_least(1).items | |
+ last_document.search('.last a').should have_at_least(1).items | |
+ end | |
- it 'should point to current page' do | |
- last_document.search('.current').text.should match /1/ | |
+ it 'should point to current page' do | |
+ last_document.search('.current').text.should match(/1/) | |
- get '/users?page=2' | |
- last_document.search('.current').text.should match /2/ | |
- end | |
+ get '/users?page=2' | |
+ last_document.search('.current').text.should match(/2/) | |
+ end | |
- it 'should load 25 users' do | |
- last_document.search('li.user_info').should have(25).items | |
- end | |
+ it 'should load 25 users' do | |
+ last_document.search('li.user_info').should have(25).items | |
+ end | |
- it 'should preserve params' do | |
- get '/users?foo=bar' | |
- last_document.search('.page a').should(be_all do |elm| | |
- elm.attribute('href').value =~ /foo=bar/ | |
- end) | |
+ it 'should preserve params' do | |
+ get '/users?foo=bar' | |
+ last_document.search('.page a').should(be_all do |elm| | |
+ elm.attribute('href').value =~ /foo=bar/ | |
+ end) | |
+ end | |
end | |
- end | |
- context 'optional paginations with Sinatra' do | |
- it 'should have 5 windows with 1 gap' do | |
- mock_app do | |
- register Kaminari::Helpers::SinatraHelpers | |
- get '/users' do | |
- @page = params[:page] || 1 | |
- @users = User.page(@page).per(5) | |
- @options = {} | |
- erb ERB_TEMPLATE_FOR_PAGINATE | |
+ context 'optional paginations with Sinatra' do | |
+ it 'should have 5 windows with 1 gap' do | |
+ mock_app do | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ get '/users' do | |
+ @page = params[:page] || 1 | |
+ @users = User.page(@page).per(5) | |
+ @options = {} | |
+ erb ERB_TEMPLATE_FOR_PAGINATE | |
+ end | |
end | |
- end | |
- get '/users' | |
- last_document.search('.page').should have(6).items | |
- last_document.search('.gap').should have(1).item | |
- end | |
+ get '/users' | |
+ last_document.search('.page').should have(6).items | |
+ last_document.search('.gap').should have(1).item | |
+ end | |
- it 'should controll the inner window size' do | |
- mock_app do | |
- register Kaminari::Helpers::SinatraHelpers | |
- get '/users' do | |
- @page = params[:page] || 1 | |
- @users = User.page(@page).per(3) | |
- @options = {:window => 10} | |
- erb ERB_TEMPLATE_FOR_PAGINATE | |
+ it 'should controll the inner window size' do | |
+ mock_app do | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ get '/users' do | |
+ @page = params[:page] || 1 | |
+ @users = User.page(@page).per(3) | |
+ @options = {:window => 10} | |
+ erb ERB_TEMPLATE_FOR_PAGINATE | |
+ end | |
end | |
+ | |
+ get '/users' | |
+ last_document.search('.page').should have(12).items | |
+ last_document.search('.gap').should have(1).item | |
end | |
- get '/users' | |
- last_document.search('.page').should have(12).items | |
- last_document.search('.gap').should have(1).item | |
+ it 'should specify a page param name' do | |
+ mock_app do | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ get '/users' do | |
+ @page = params[:page] || 1 | |
+ @users = User.page(@page).per(3) | |
+ @options = {:param_name => :user_page} | |
+ erb ERB_TEMPLATE_FOR_PAGINATE | |
+ end | |
+ end | |
+ | |
+ get '/users' | |
+ last_document.search('.page a').should(be_all do |elm| | |
+ elm.attribute('href').value =~ /user_page=\d+/ | |
+ end) | |
+ end | |
end | |
+ end | |
- it 'should specify a page param name' do | |
+ describe '#link_to_previous_page' do | |
+ before do | |
mock_app do | |
register Kaminari::Helpers::SinatraHelpers | |
get '/users' do | |
- @page = params[:page] || 1 | |
- @users = User.page(@page).per(3) | |
- @options = {:param_name => :user_page} | |
- erb ERB_TEMPLATE_FOR_PAGINATE | |
+ @page = params[:page] || 2 | |
+ @users = User.page(@page) | |
+ erb ERB_TEMPLATE_FOR_PREVIOUS_PAGE | |
end | |
- end | |
- get '/users' | |
- last_document.search('.page a').should(be_all do |elm| | |
- elm.attribute('href').value =~ /user_page=\d+/ | |
- end) | |
+ get '/users_placeholder' do | |
+ @page = params[:page] || 2 | |
+ @options = {:placeholder => %{<span id='no_previous_page'>No Previous Page</span>}} | |
+ @users = User.page(@page) | |
+ erb ERB_TEMPLATE_FOR_PREVIOUS_PAGE | |
+ end | |
+ end | |
end | |
- end | |
- end | |
- describe '#link_to_next_page' do | |
- before do | |
- mock_app do | |
- register Kaminari::Helpers::SinatraHelpers | |
- get '/users' do | |
- @page = params[:page] || 1 | |
- @users = User.page(@page) | |
- erb ERB_TEMPLATE_FOR_NEXT_PAGE | |
+ context 'having more page' do | |
+ it 'should have a more page link' do | |
+ get '/users' | |
+ last_document.search('a#previous_page_link').should be_present | |
+ last_document.search('a#previous_page_link').text.should match(/Previous!/) | |
end | |
+ end | |
- get '/users_placeholder' do | |
- @page = params[:page] || 1 | |
- @options = {:placeholder => %{<span id='no_next_page'>No Next Page</span>}} | |
- @users = User.page(@page) | |
- erb ERB_TEMPLATE_FOR_NEXT_PAGE | |
+ context 'the first page' do | |
+ it 'should not have a more page link' do | |
+ get '/users?page=1' | |
+ last_document.search('a#previous_page_link').should be_empty | |
end | |
- end | |
- end | |
- context 'having more page' do | |
- it 'should have a more page link' do | |
- get '/users' | |
- last_document.search('a#next_page_link').should be_present | |
- last_document.search('a#next_page_link').text.should match /Next!/ | |
+ it 'should have a no more page notation using placeholder' do | |
+ get '/users_placeholder?page=1' | |
+ last_document.search('a#previous_page_link').should be_empty | |
+ last_document.search('span#no_previous_page').should be_present | |
+ last_document.search('span#no_previous_page').text.should match(/No Previous Page/) | |
+ end | |
end | |
end | |
- context 'the last page' do | |
+ describe '#link_to_next_page' do | |
before do | |
- User.delete_all | |
- 50.times {|i| User.create! :name => "user#{i}"} | |
+ mock_app do | |
+ register Kaminari::Helpers::SinatraHelpers | |
+ get '/users' do | |
+ @page = params[:page] || 1 | |
+ @users = User.page(@page) | |
+ erb ERB_TEMPLATE_FOR_NEXT_PAGE | |
+ end | |
+ | |
+ get '/users_placeholder' do | |
+ @page = params[:page] || 1 | |
+ @options = {:placeholder => %{<span id='no_next_page'>No Next Page</span>}} | |
+ @users = User.page(@page) | |
+ erb ERB_TEMPLATE_FOR_NEXT_PAGE | |
+ end | |
+ end | |
end | |
- it 'should not have a more page link' do | |
- get '/users?page=2' | |
- last_document.search('a#next_page_link').should be_empty | |
+ context 'having more page' do | |
+ it 'should have a more page link' do | |
+ get '/users' | |
+ last_document.search('a#next_page_link').should be_present | |
+ last_document.search('a#next_page_link').text.should match(/Next!/) | |
+ end | |
end | |
- it 'should have a no more page notation using placeholder' do | |
- get '/users_placeholder?page=2' | |
- last_document.search('a#next_page_link').should be_empty | |
- last_document.search('span#no_next_page').should be_present | |
- last_document.search('span#no_next_page').text.should match /No Next Page/ | |
+ context 'the last page' do | |
+ it 'should not have a more page link' do | |
+ get '/users?page=2' | |
+ last_document.search('a#next_page_link').should be_empty | |
+ end | |
+ | |
+ it 'should have a no more page notation using placeholder' do | |
+ get '/users_placeholder?page=2' | |
+ last_document.search('a#next_page_link').should be_empty | |
+ last_document.search('span#no_next_page').should be_present | |
+ last_document.search('span#no_next_page').text.should match(/No Next Page/) | |
+ end | |
end | |
end | |
end | |
diff --git a/spec/helpers/tags_spec.rb b/spec/helpers/tags_spec.rb | |
index f8a96d3..54e18f9 100644 | |
--- a/spec/helpers/tags_spec.rb | |
+++ b/spec/helpers/tags_spec.rb | |
@@ -28,11 +28,11 @@ describe 'Kaminari::Helpers' do | |
describe '#last?' do | |
context 'current_page == page' do | |
- subject { Paginator::PageProxy.new({:num_pages => 39}, 39, nil) } | |
+ subject { Paginator::PageProxy.new({:total_pages => 39}, 39, nil) } | |
its(:last?) { should be_true } | |
end | |
context 'current_page != page' do | |
- subject { Paginator::PageProxy.new({:num_pages => 39}, 38, nil) } | |
+ subject { Paginator::PageProxy.new({:total_pages => 39}, 38, nil) } | |
its(:last?) { should_not be_true } | |
end | |
end | |
@@ -75,16 +75,16 @@ describe 'Kaminari::Helpers' do | |
end | |
describe '#right_outer?' do | |
- context 'num_pages - page > right' do | |
- subject { Paginator::PageProxy.new({:num_pages => 10, :right => 3}, 6, nil) } | |
+ context 'total_pages - page > right' do | |
+ subject { Paginator::PageProxy.new({:total_pages => 10, :right => 3}, 6, nil) } | |
its(:right_outer?) { should_not be_true } | |
end | |
- context 'num_pages - page == right' do | |
- subject { Paginator::PageProxy.new({:num_pages => 10, :right => 3}, 7, nil) } | |
+ context 'total_pages - page == right' do | |
+ subject { Paginator::PageProxy.new({:total_pages => 10, :right => 3}, 7, nil) } | |
its(:right_outer?) { should_not be_true } | |
end | |
- context 'num_pages - page < right' do | |
- subject { Paginator::PageProxy.new({:num_pages => 10, :right => 3}, 8, nil) } | |
+ context 'total_pages - page < right' do | |
+ subject { Paginator::PageProxy.new({:total_pages => 10, :right => 3}, 8, nil) } | |
its(:right_outer?) { should be_true } | |
end | |
end | |
diff --git a/spec/models/active_record/active_record_relation_methods_spec.rb b/spec/models/active_record/active_record_relation_methods_spec.rb | |
new file mode 100644 | |
index 0000000..b53faea | |
--- /dev/null | |
+++ b/spec/models/active_record/active_record_relation_methods_spec.rb | |
@@ -0,0 +1,71 @@ | |
+require 'spec_helper' | |
+ | |
+if defined? ActiveRecord | |
+ describe Kaminari::ActiveRecordRelationMethods do | |
+ describe '#total_count' do | |
+ before do | |
+ @author = User.create! :name => 'author' | |
+ @author2 = User.create! :name => 'author2' | |
+ @author3 = User.create! :name => 'author3' | |
+ @books = 2.times.map {|i| @author.books_authored.create!(:title => "title%03d" % i) } | |
+ @books2 = 3.times.map {|i| @author2.books_authored.create!(:title => "title%03d" % i) } | |
+ @books3 = 4.times.map {|i| @author3.books_authored.create!(:title => "subject%03d" % i) } | |
+ @readers = 4.times.map { User.create! :name => 'reader' } | |
+ @books.each {|book| book.readers << @readers } | |
+ end | |
+ | |
+ context "when the scope includes an order which references a generated column" do | |
+ it "should successfully count the results" do | |
+ @author.readers.by_read_count.page(1).total_count.should == @readers.size | |
+ end | |
+ end | |
+ | |
+ context "when the scope use conditions on includes" do | |
+ it "should keep includes and successfully count the results" do | |
+ # Only @author and @author2 have books titled with the title00x partern | |
+ if ActiveRecord::VERSION::STRING >= "4.1.0" | |
+ User.includes(:books_authored).references(:books).where("books.title LIKE 'title00%'").page(1).total_count.should == 2 | |
+ else | |
+ User.includes(:books_authored).where("books.title LIKE 'title00%'").page(1).total_count.should == 2 | |
+ end | |
+ end | |
+ end | |
+ | |
+ context 'when the Relation has custom select clause' do | |
+ specify do | |
+ lambda { User.select('*, 1 as one').page(1).total_count }.should_not raise_exception | |
+ end | |
+ end | |
+ | |
+ context "when total_count receives options" do | |
+ it "should return a distinct total count for rails < 4.1" do | |
+ if ActiveRecord::VERSION::STRING < "4.1.0" | |
+ User.page(1).total_count(:name, :distinct => true).should == 4 | |
+ end | |
+ end | |
+ | |
+ it "should ignore the options for rails 4.1+" do | |
+ if ActiveRecord::VERSION::STRING >= "4.1.0" | |
+ User.page(1).total_count(:name, :distinct => true).should == 7 | |
+ end | |
+ end | |
+ end | |
+ | |
+ if ActiveRecord::VERSION::STRING < '4.1.0' | |
+ context 'when count receives options' do | |
+ it 'should return a distinct set by column for rails < 4.1' do | |
+ User.page(1).count(:name, :distinct => true).should == 4 | |
+ end | |
+ end | |
+ end | |
+ | |
+ context "when the scope returns an ActiveSupport::OrderedHash" do | |
+ it "should not throw exception by passing options to count" do | |
+ lambda { | |
+ @author.readers.by_read_count.page(1).total_count(:name, :distinct => true) | |
+ }.should_not raise_exception | |
+ end | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/spec/models/active_record/scopes_spec.rb b/spec/models/active_record/scopes_spec.rb | |
new file mode 100644 | |
index 0000000..44bfa64 | |
--- /dev/null | |
+++ b/spec/models/active_record/scopes_spec.rb | |
@@ -0,0 +1,262 @@ | |
+require 'spec_helper' | |
+ | |
+if defined? ActiveRecord | |
+ | |
+ describe Kaminari::ActiveRecordModelExtension do | |
+ before do | |
+ Kaminari.configure do |config| | |
+ config.page_method_name = :per_page_kaminari | |
+ end | |
+ class Comment < ActiveRecord::Base; end | |
+ end | |
+ | |
+ subject { Comment } | |
+ it { should respond_to(:per_page_kaminari) } | |
+ it { should_not respond_to(:page) } | |
+ | |
+ after do | |
+ Kaminari.configure do |config| | |
+ config.page_method_name = :page | |
+ end | |
+ end | |
+ end | |
+ | |
+ shared_examples_for 'the first page' do | |
+ it { should have(25).users } | |
+ its('first.name') { should == 'user001' } | |
+ end | |
+ | |
+ shared_examples_for 'blank page' do | |
+ it { should have(0).users } | |
+ end | |
+ | |
+ describe Kaminari::ActiveRecordExtension do | |
+ before do | |
+ 1.upto(100) {|i| User.create! :name => "user#{'%03d' % i}", :age => (i / 10)} | |
+ 1.upto(100) {|i| GemDefinedModel.create! :name => "user#{'%03d' % i}", :age => (i / 10)} | |
+ 1.upto(100) {|i| Device.create! :name => "user#{'%03d' % i}", :age => (i / 10)} | |
+ end | |
+ | |
+ [User, Admin, GemDefinedModel, Device].each do |model_class| | |
+ context "for #{model_class}" do | |
+ describe '#page' do | |
+ context 'page 1' do | |
+ subject { model_class.page 1 } | |
+ it_should_behave_like 'the first page' | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { model_class.page 2 } | |
+ it { should have(25).users } | |
+ its('first.name') { should == 'user026' } | |
+ end | |
+ | |
+ context 'page without an argument' do | |
+ subject { model_class.page } | |
+ it_should_behave_like 'the first page' | |
+ end | |
+ | |
+ context 'page < 1' do | |
+ subject { model_class.page 0 } | |
+ it_should_behave_like 'the first page' | |
+ end | |
+ | |
+ context 'page > max page' do | |
+ subject { model_class.page 5 } | |
+ it_should_behave_like 'blank page' | |
+ end | |
+ | |
+ describe 'ensure #order_values is preserved' do | |
+ subject { model_class.order('id').page 1 } | |
+ its('order_values.uniq') { should == ['id'] } | |
+ end | |
+ end | |
+ | |
+ describe '#per' do | |
+ context 'page 1 per 5' do | |
+ subject { model_class.page(1).per(5) } | |
+ it { should have(5).users } | |
+ its('first.name') { should == 'user001' } | |
+ end | |
+ | |
+ context "page 1 per nil (using default)" do | |
+ subject { model_class.page(1).per(nil) } | |
+ it { should have(model_class.default_per_page).users } | |
+ end | |
+ end | |
+ | |
+ describe '#padding' do | |
+ context 'page 1 per 5 padding 1' do | |
+ subject { model_class.page(1).per(5).padding(1) } | |
+ it { should have(5).users } | |
+ its('first.name') { should == 'user002' } | |
+ end | |
+ | |
+ context 'page 19 per 5 padding 5' do | |
+ subject { model_class.page(19).per(5).padding(5) } | |
+ its(:current_page) { should == 19 } | |
+ its(:total_pages) { should == 19 } | |
+ end | |
+ end | |
+ | |
+ describe '#total_pages' do | |
+ context 'per 25 (default)' do | |
+ subject { model_class.page } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'per 7' do | |
+ subject { model_class.page(2).per(7) } | |
+ its(:total_pages) { should == 15 } | |
+ end | |
+ | |
+ context 'per 65536' do | |
+ subject { model_class.page(50).per(65536) } | |
+ its(:total_pages) { should == 1 } | |
+ end | |
+ | |
+ context 'per 0 (using default)' do | |
+ subject { model_class.page(50).per(0) } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'per -1 (using default)' do | |
+ subject { model_class.page(5).per(-1) } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'per "String value that can not be converted into Number" (using default)' do | |
+ subject { model_class.page(5).per('aho') } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'with max_pages < total pages count from database' do | |
+ before { model_class.max_pages_per 3 } | |
+ subject { model_class.page } | |
+ its(:total_pages) { should == 3 } | |
+ after { model_class.max_pages_per nil } | |
+ end | |
+ | |
+ context 'with max_pages > total pages count from database' do | |
+ before { model_class.max_pages_per 11 } | |
+ subject { model_class.page } | |
+ its(:total_pages) { should == 4 } | |
+ after { model_class.max_pages_per nil } | |
+ end | |
+ | |
+ context 'with max_pages is nil' do | |
+ before { model_class.max_pages_per nil } | |
+ subject { model_class.page } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context "with per(nil) using default" do | |
+ subject { model_class.page.per(nil) } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ end | |
+ | |
+ describe '#current_page' do | |
+ context 'page 1' do | |
+ subject { model_class.page } | |
+ its(:current_page) { should == 1 } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { model_class.page(2).per 3 } | |
+ its(:current_page) { should == 2 } | |
+ end | |
+ end | |
+ | |
+ describe '#next_page' do | |
+ context 'page 1' do | |
+ subject { model_class.page } | |
+ its(:next_page) { should == 2 } | |
+ end | |
+ | |
+ context 'page 5' do | |
+ subject { model_class.page(5) } | |
+ its(:next_page) { should be_nil } | |
+ end | |
+ end | |
+ | |
+ describe '#prev_page' do | |
+ context 'page 1' do | |
+ subject { model_class.page } | |
+ its(:prev_page) { should be_nil } | |
+ end | |
+ | |
+ context 'page 5' do | |
+ subject { model_class.page(5) } | |
+ its(:prev_page) { should == 4 } | |
+ end | |
+ end | |
+ | |
+ describe '#first_page?' do | |
+ context 'on first page' do | |
+ subject { model_class.page(1).per(10) } | |
+ its(:first_page?) { should == true } | |
+ end | |
+ | |
+ context 'not on first page' do | |
+ subject { model_class.page(5).per(10) } | |
+ its(:first_page?) { should == false } | |
+ end | |
+ end | |
+ | |
+ describe '#last_page?' do | |
+ context 'on last page' do | |
+ subject { model_class.page(10).per(10) } | |
+ its(:last_page?) { should == true } | |
+ end | |
+ | |
+ context 'not on last page' do | |
+ subject { model_class.page(1).per(10) } | |
+ its(:last_page?) { should == false } | |
+ end | |
+ end | |
+ | |
+ describe '#out_of_range?' do | |
+ context 'on last page' do | |
+ subject { model_class.page(10).per(10) } | |
+ its(:out_of_range?) { should == false } | |
+ end | |
+ | |
+ context 'within range' do | |
+ subject { model_class.page(1).per(10) } | |
+ its(:out_of_range?) { should == false } | |
+ end | |
+ | |
+ context 'out of range' do | |
+ subject { model_class.page(11).per(10) } | |
+ its(:out_of_range?) { should == true } | |
+ end | |
+ end | |
+ | |
+ describe '#count' do | |
+ context 'page 1' do | |
+ subject { model_class.page } | |
+ its(:count) { should == 25 } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { model_class.page 2 } | |
+ its(:count) { should == 25 } | |
+ end | |
+ end | |
+ | |
+ context 'chained with .group' do | |
+ subject { model_class.group('age').page(2).per 5 } | |
+ # 0..10 | |
+ its(:total_count) { should == 11 } | |
+ its(:total_pages) { should == 3 } | |
+ end | |
+ | |
+ context 'activerecord descendants' do | |
+ subject { ActiveRecord::Base.descendants } | |
+ its(:length) { should_not == 0 } | |
+ end | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/spec/models/active_record_relation_methods_spec.rb b/spec/models/active_record_relation_methods_spec.rb | |
deleted file mode 100644 | |
index 1476389..0000000 | |
--- a/spec/models/active_record_relation_methods_spec.rb | |
+++ /dev/null | |
@@ -1,28 +0,0 @@ | |
-require 'spec_helper' | |
- | |
-describe Kaminari::ActiveRecordRelationMethods do | |
- describe '#total_count' do | |
- before do | |
- @author = User.create! :name => 'author' | |
- @author2 = User.create! :name => 'author2' | |
- @author3 = User.create! :name => 'author3' | |
- @books = 2.times.map {|i| @author.books_authored.create!(:title => "title%03d" % i) } | |
- @books2 = 3.times.map {|i| @author2.books_authored.create!(:title => "title%03d" % i) } | |
- @books3 = 4.times.map {|i| @author3.books_authored.create!(:title => "subject%03d" % i) } | |
- @readers = 4.times.map { User.create! :name => 'reader' } | |
- @books.each {|book| book.readers << @readers } | |
- end | |
- | |
- context "when the scope includes an order which references a generated column" do | |
- it "should successfully count the results" do | |
- @author.readers.by_read_count.page(1).total_count.should == @readers.size | |
- end | |
- end | |
- context "when the scope use conditions on includes" do | |
- it "should keep includes and successfully count the results" do | |
- # Only @author and @author2 have books titled with the title00x partern | |
- User.includes(:books_authored).where("books.title LIKE 'title00%'").page(1).total_count.should == 2 | |
- end | |
- end | |
- end | |
-end | |
diff --git a/spec/models/array_spec.rb b/spec/models/array_spec.rb | |
index a95c68c..30bd508 100644 | |
--- a/spec/models/array_spec.rb | |
+++ b/spec/models/array_spec.rb | |
@@ -56,35 +56,40 @@ describe Kaminari::PaginatableArray do | |
end | |
end | |
- describe '#num_pages' do | |
+ describe '#total_pages' do | |
context 'per 25 (default)' do | |
subject { array.page } | |
- its(:num_pages) { should == 4 } | |
+ its(:total_pages) { should == 4 } | |
end | |
context 'per 7' do | |
subject { array.page(2).per(7) } | |
- its(:num_pages) { should == 15 } | |
+ its(:total_pages) { should == 15 } | |
end | |
context 'per 65536' do | |
subject { array.page(50).per(65536) } | |
- its(:num_pages) { should == 1 } | |
+ its(:total_pages) { should == 1 } | |
end | |
context 'per 0 (using default)' do | |
subject { array.page(50).per(0) } | |
- its(:num_pages) { should == 4 } | |
+ its(:total_pages) { should == 4 } | |
end | |
context 'per -1 (using default)' do | |
subject { array.page(5).per(-1) } | |
- its(:num_pages) { should == 4 } | |
+ its(:total_pages) { should == 4 } | |
end | |
context 'per "String value that can not be converted into Number" (using default)' do | |
subject { array.page(5).per('aho') } | |
- its(:num_pages) { should == 4 } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'per 25, padding 25' do | |
+ subject { array.page(1).padding(25) } | |
+ its(:total_pages) { should == 3 } | |
end | |
end | |
@@ -100,6 +105,30 @@ describe Kaminari::PaginatableArray do | |
end | |
end | |
+ describe '#next_page' do | |
+ context 'page 1' do | |
+ subject { array.page } | |
+ its(:next_page) { should == 2 } | |
+ end | |
+ | |
+ context 'page 5' do | |
+ subject { array.page 5 } | |
+ its(:next_page) { should be_nil } | |
+ end | |
+ end | |
+ | |
+ describe '#prev_page' do | |
+ context 'page 1' do | |
+ subject { array.page } | |
+ its(:prev_page) { should be_nil } | |
+ end | |
+ | |
+ context 'page 5' do | |
+ subject { array.page 5 } | |
+ its(:prev_page) { should == 4 } | |
+ end | |
+ end | |
+ | |
describe '#count' do | |
context 'page 1' do | |
subject { array.page } | |
@@ -113,9 +142,28 @@ describe Kaminari::PaginatableArray do | |
end | |
context 'when setting total count explicitly' do | |
- subject { Kaminari::PaginatableArray.new((1..10).to_a, :total_count => 9999).page(5).per(10) } | |
- it { should have(10).items } | |
- its(:first) { should == 1 } | |
- its(:total_count) { should == 9999 } | |
+ context "total_count > size of the given array" do | |
+ subject { Kaminari::PaginatableArray.new((1..10).to_a, :total_count => 9999).page(5).per(10) } | |
+ | |
+ it { should have(0).items } | |
+ its(:first) { should be_nil } | |
+ its(:total_count) { should == 9999 } | |
+ end | |
+ | |
+ context "total_count == size of the given array" do | |
+ subject { Kaminari.paginate_array((1..15).to_a, :total_count => 15).page(1).per(10) } | |
+ | |
+ it { should have(10).items } | |
+ its(:first) { should == 1 } | |
+ its(:total_count) { should == 15 } | |
+ end | |
+ | |
+ context "total_count < size of the given array" do | |
+ subject { Kaminari.paginate_array((1..25).to_a, :total_count => 15).page(2).per(10) } | |
+ | |
+ it { should have(5).items } | |
+ its(:first) { should == 11 } | |
+ its(:total_count) { should == 15 } | |
+ end | |
end | |
end | |
diff --git a/spec/models/configuration_methods_spec.rb b/spec/models/configuration_methods_spec.rb | |
new file mode 100644 | |
index 0000000..78c69ac | |
--- /dev/null | |
+++ b/spec/models/configuration_methods_spec.rb | |
@@ -0,0 +1,125 @@ | |
+require 'spec_helper' | |
+ | |
+describe "configuration methods" do | |
+ let(:model){ User } | |
+ | |
+ describe "#default_per_page" do | |
+ if defined? ActiveRecord | |
+ describe 'AR::Base' do | |
+ subject { ActiveRecord::Base } | |
+ it { should_not respond_to :paginates_per } | |
+ end | |
+ end | |
+ | |
+ subject { model.page(1) } | |
+ | |
+ context "by default" do | |
+ its(:limit_value){ should == 25 } | |
+ end | |
+ | |
+ context "when configuring both on global and model-level" do | |
+ before do | |
+ Kaminari.configure {|c| c.default_per_page = 50 } | |
+ model.paginates_per 100 | |
+ end | |
+ | |
+ its(:limit_value){ should == 100 } | |
+ end | |
+ | |
+ context "when configuring multiple times" do | |
+ before do | |
+ Kaminari.configure {|c| c.default_per_page = 10 } | |
+ Kaminari.configure {|c| c.default_per_page = 20 } | |
+ end | |
+ | |
+ its(:limit_value){ should == 20 } | |
+ end | |
+ | |
+ after do | |
+ Kaminari.configure {|c| c.default_per_page = 25 } | |
+ model.paginates_per nil | |
+ end | |
+ end | |
+ | |
+ describe "#max_per_page" do | |
+ if defined? ActiveRecord | |
+ describe 'AR::Base' do | |
+ subject { ActiveRecord::Base } | |
+ it { should_not respond_to :max_pages_per } | |
+ end | |
+ end | |
+ | |
+ subject { model.page(1).per(1000) } | |
+ | |
+ context "by default" do | |
+ its(:limit_value){ should == 1000 } | |
+ end | |
+ | |
+ context "when configuring both on global and model-level" do | |
+ before do | |
+ Kaminari.configure {|c| c.max_per_page = 50 } | |
+ model.max_paginates_per 100 | |
+ end | |
+ | |
+ its(:limit_value){ should == 100 } | |
+ end | |
+ | |
+ context "when configuring multiple times" do | |
+ before do | |
+ Kaminari.configure {|c| c.max_per_page = 10 } | |
+ Kaminari.configure {|c| c.max_per_page = 20 } | |
+ end | |
+ | |
+ its(:limit_value){ should == 20 } | |
+ end | |
+ | |
+ after do | |
+ Kaminari.configure {|c| c.max_per_page = nil } | |
+ model.max_paginates_per nil | |
+ end | |
+ end | |
+ | |
+ describe "#max_pages" do | |
+ if defined? ActiveRecord | |
+ describe 'AR::Base' do | |
+ subject { ActiveRecord::Base } | |
+ it { should_not respond_to :max_paginates_per } | |
+ end | |
+ end | |
+ | |
+ before do | |
+ 100.times do |count| | |
+ model.create!(:name => "User#{count}") | |
+ end | |
+ end | |
+ | |
+ subject { model.page(1).per(5) } | |
+ | |
+ context "by default" do | |
+ its(:total_pages){ should == 20 } | |
+ end | |
+ | |
+ context "when configuring both on global and model-level" do | |
+ before do | |
+ Kaminari.configure {|c| c.max_pages = 10 } | |
+ model.max_pages_per 15 | |
+ end | |
+ | |
+ its(:total_pages){ should == 15 } | |
+ end | |
+ | |
+ context "when configuring multiple times" do | |
+ before do | |
+ Kaminari.configure {|c| c.max_pages = 10 } | |
+ Kaminari.configure {|c| c.max_pages = 15 } | |
+ end | |
+ | |
+ its(:total_pages){ should == 15 } | |
+ end | |
+ | |
+ after do | |
+ Kaminari.configure {|c| c.max_pages = nil } | |
+ model.max_pages_per nil | |
+ end | |
+ end | |
+end | |
diff --git a/spec/models/data_mapper/data_mapper_spec.rb b/spec/models/data_mapper/data_mapper_spec.rb | |
new file mode 100644 | |
index 0000000..3b5938e | |
--- /dev/null | |
+++ b/spec/models/data_mapper/data_mapper_spec.rb | |
@@ -0,0 +1,205 @@ | |
+require 'spec_helper' | |
+ | |
+if defined? DataMapper | |
+ # tests for issue #203 | |
+ describe Kaminari::DataMapperCollectionMethods do | |
+ before do | |
+ 30.times do |i| | |
+ User.create(:name => "User#{i}", :age => i) | |
+ end | |
+ end | |
+ | |
+ describe 'Model' do | |
+ subject { User } | |
+ it { User.all.count.should == 30 } | |
+ it { User.page(1).length.should == 25 } | |
+ it { | |
+ User.paginates_per(5) | |
+ User.page(1).length.should == 5 | |
+ User.all.page(1).length.should == 5 | |
+ User.paginates_per(nil) # reset to default | |
+ } | |
+ end | |
+ | |
+ end | |
+ | |
+ describe Kaminari::DataMapperExtension do | |
+ before do | |
+ 90.times do |i| | |
+ User.create(:name => "User#{i}", :age => i) | |
+ end | |
+ end | |
+ | |
+ describe 'Collection' do | |
+ subject{ User.all } | |
+ it { should respond_to(:page) } | |
+ it { should_not respond_to(:per) } | |
+ end | |
+ | |
+ describe 'Model' do | |
+ subject{ User } | |
+ it { should respond_to(:page) } | |
+ it { should respond_to(:default_per_page) } | |
+ it { should_not respond_to(:per) } | |
+ end | |
+ | |
+ describe '#page' do | |
+ context 'page 0' do | |
+ subject { User.all(:age.gte => 60).page 0 } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its('query.limit') { should == 25 } | |
+ its('query.offset') { should == 0 } | |
+ its(:total_count) { should == User.count(:age.gte => 60) } | |
+ its(:total_pages) { should == 2 } | |
+ end | |
+ | |
+ context 'page 1' do | |
+ subject { User.all(:age.gte => 0).page 1 } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its('query.limit') { should == 25 } | |
+ its('query.offset') { should == 0 } | |
+ its(:total_count) { should == 90 } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { User.page 2 } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should == 3 } | |
+ its(:limit_value) { should == 25 } | |
+ its('query.limit') { should == 25 } | |
+ its('query.offset') { should == 25 } | |
+ its(:total_count) { should == 90 } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'page "foobar"' do | |
+ subject { User.page 'foobar' } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its('query.limit') { should == 25 } | |
+ its('query.offset') { should == 0 } | |
+ its(:total_count) { should == 90 } | |
+ its(:total_pages) { should == 4 } | |
+ end | |
+ | |
+ context 'with criteria before' do | |
+ subject { User.all(:age.gt => 60).page 2 } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its('query.limit') { should == 25 } | |
+ its('query.offset') { should == 25 } | |
+ its(:total_count) { should == User.count(:age.gt => 60) } | |
+ its(:total_pages) { should == 2 } | |
+ end | |
+ | |
+ context 'with criteria after' do | |
+ subject { User.page(2).all(:age.gt => 60) } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its('query.limit') { should == 25 } | |
+ its('query.offset') { should == 25 } | |
+ its(:total_count) { should == User.count(:age.gt => 60) } | |
+ its(:total_pages) { should == 2 } | |
+ end | |
+ end | |
+ | |
+ describe '#per' do | |
+ context 'on simple query' do | |
+ subject { User.page(2).per(20) } | |
+ it { should be_a DataMapper::Collection } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should == 3 } | |
+ its('query.limit') { should == 20 } | |
+ its(:limit_value) { should == 20 } | |
+ its('query.offset') { should == 20 } | |
+ its(:total_count) { should == 90 } | |
+ its(:total_pages) { should == 5 } | |
+ end | |
+ | |
+ context 'on query with condition' do | |
+ subject { User.page(5).all(:age.lte => 80).per(13) } | |
+ its(:current_page) { should == 5 } | |
+ its(:prev_page) { should == 4 } | |
+ its(:next_page) { should == 6 } | |
+ its('query.limit') { should == 13 } | |
+ its('query.offset') { should == 52 } | |
+ its(:total_count) { should == 81 } | |
+ its(:total_pages) { should == 7 } | |
+ end | |
+ | |
+ context 'on query with order' do | |
+ subject { User.page(5).all(:age.lte => 80, :order => [:age.asc]).per(13) } | |
+ it('includes user with age 52') { should include(User.first(:age => 52)) } | |
+ it('does not include user with age 51') { should_not include(User.first(:age => 51)) } | |
+ it('includes user with age 52') { should include(User.first(:age => 64)) } | |
+ it('does not include user with age 51') { should_not include(User.first(:age => 65)) } | |
+ its(:current_page) { should == 5 } | |
+ its(:prev_page) { should == 4 } | |
+ its(:next_page) { should == 6 } | |
+ its('query.limit') { should == 13 } | |
+ its('query.offset') { should == 52 } | |
+ its(:total_count) { should == 81 } | |
+ its(:total_pages) { should == 7 } | |
+ end | |
+ | |
+ context 'on chained queries' do | |
+ subject { User.all(:age.gte => 50).page(3).all(:age.lte => 80).per(13) } | |
+ its(:current_page) { should == 3 } | |
+ its(:prev_page) { should == 2 } | |
+ its(:next_page) { should be_nil } | |
+ its('query.limit') { should == 13 } | |
+ its('query.offset') { should == 26 } | |
+ its(:total_count) { should == 31 } | |
+ its(:total_pages) { should == 3 } | |
+ end | |
+ | |
+ context 'for association' do | |
+ before do | |
+ worker0 = User[0] | |
+ 30.times do |i| | |
+ worker0.projects << Project.create(:name => "Project#{i}") | |
+ end | |
+ worker0.projects.save | |
+ end | |
+ | |
+ context 'on query' do | |
+ subject { User[0].projects.page(3).all(:name.like => 'Project%').per(5) } | |
+ its(:current_page) { should == 3 } | |
+ its(:prev_page) { should == 2 } | |
+ its(:next_page) { should == 4 } | |
+ its('query.limit') { should == 5 } | |
+ its('query.offset') { should == 10 } | |
+ its(:total_count) { should == 30 } | |
+ its(:total_pages) { should == 6 } | |
+ end | |
+ | |
+ context 'after association conditions' do | |
+ subject { User.page(3).all(:projects => Project.all).per(5) } | |
+ its(:current_page) { should == 3 } | |
+ its(:prev_page) { should == 2 } | |
+ its(:next_page) { should == 4 } | |
+ its('query.limit') { should == 5 } | |
+ its('query.offset') { should == 10 } | |
+ its(:total_count) { should == 30 } | |
+ its(:total_pages) { should == 6 } | |
+ end | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/spec/models/data_mapper_spec.rb b/spec/models/data_mapper_spec.rb | |
deleted file mode 100644 | |
index 5efe486..0000000 | |
--- a/spec/models/data_mapper_spec.rb | |
+++ /dev/null | |
@@ -1,181 +0,0 @@ | |
-require 'spec_helper' | |
-require 'dm-core' | |
-require 'dm-migrations' | |
-require 'dm-aggregates' | |
-require 'kaminari/models/data_mapper_extension' | |
- | |
-describe Kaminari::DataMapperExtension do | |
- before :all do | |
- DataMapper.setup(:default, 'sqlite::memory:') | |
- | |
- class Worker | |
- include ::DataMapper::Resource | |
- | |
- property :id, Serial | |
- property :name, String, :required => true | |
- property :age, Integer, :required => true | |
- | |
- has n, :projects, :through => Resource | |
- end | |
- | |
- class Project | |
- include ::DataMapper::Resource | |
- | |
- property :id, Serial | |
- property :name, String, :required => true | |
- | |
- has n, :workers, :through => Resource | |
- end | |
- | |
- DataMapper.finalize | |
- DataMapper.auto_migrate! | |
- | |
- 300.times do |i| | |
- Worker.create(:name => "Worker#{i}", :age => i) | |
- end | |
- | |
- worker0 = Worker[0] | |
- 50.times do |i| | |
- worker0.projects << Project.create(:name => "Project#{i}") | |
- end | |
- worker0.projects.save | |
- end | |
- | |
- describe 'Collection' do | |
- subject{ Worker.all } | |
- it { should respond_to(:page) } | |
- it { should_not respond_to(:per) } | |
- end | |
- | |
- describe 'Model' do | |
- subject{ Worker } | |
- it { should respond_to(:page) } | |
- it { should respond_to(:default_per_page) } | |
- it { should_not respond_to(:per) } | |
- end | |
- | |
- describe '#page' do | |
- context 'page 0' do | |
- subject { Worker.all(:age.gte => 200).page 0 } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 1 } | |
- its('query.limit') { should == 25 } | |
- its('query.offset') { should == 0 } | |
- its(:total_count) { should == Worker.count(:age.gte => 200) } | |
- its(:num_pages) { should == 4 } | |
- end | |
- | |
- context 'page 1' do | |
- subject { Worker.all(:age.gte => 0).page 1 } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 1 } | |
- its('query.limit') { should == 25 } | |
- its('query.offset') { should == 0 } | |
- its(:total_count) { should == 300 } | |
- its(:num_pages) { should == 12 } | |
- end | |
- | |
- context 'page 2' do | |
- subject { Worker.page 2 } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its('query.limit') { should == 25 } | |
- its('query.offset') { should == 25 } | |
- its(:total_count) { should == 300 } | |
- its(:num_pages) { should == 12 } | |
- end | |
- | |
- context 'page "foobar"' do | |
- subject { Worker.page 'foobar' } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 1 } | |
- its('query.limit') { should == 25 } | |
- its('query.offset') { should == 0 } | |
- its(:total_count) { should == 300 } | |
- its(:num_pages) { should == 12 } | |
- end | |
- | |
- context 'with criteria before' do | |
- subject { Worker.all(:age.gt => 100).page 2 } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 2 } | |
- its('query.limit') { should == 25 } | |
- its('query.offset') { should == 25 } | |
- its(:total_count) { should == Worker.count(:age.gt => 100) } | |
- its(:num_pages) { should == 8 } | |
- end | |
- | |
- context 'with criteria after' do | |
- subject { Worker.page(2).all(:age.gt => 100) } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 2 } | |
- its('query.limit') { should == 25 } | |
- its('query.offset') { should == 25 } | |
- its(:total_count) { should == Worker.count(:age.gt => 100) } | |
- its(:num_pages) { should == 8 } | |
- end | |
- end | |
- | |
- describe '#per' do | |
- context 'on simple query' do | |
- subject { Worker.page(2).per(10) } | |
- it { should be_a DataMapper::Collection } | |
- its(:current_page) { should == 2 } | |
- its('query.limit') { should == 10 } | |
- its(:limit_value) { should == 10 } | |
- its('query.offset') { should == 10 } | |
- its(:total_count) { should == 300 } | |
- its(:num_pages) { should == 30 } | |
- end | |
- | |
- context 'on query with condition' do | |
- subject { Worker.page(5).all(:age.lte => 100).per(13) } | |
- its(:current_page) { should == 5 } | |
- its('query.limit') { should == 13 } | |
- its('query.offset') { should == 52 } | |
- its(:total_count) { should == 101 } | |
- its(:num_pages) { should == 8 } | |
- end | |
- | |
- context 'on query with order' do | |
- subject { Worker.page(5).all(:age.lte => 100, :order => [:age.asc]).per(13) } | |
- it('includes worker with age 52') { should include(Worker.first(:age => 52)) } | |
- it('does not include worker with age 51') { should_not include(Worker.first(:age => 51)) } | |
- it('includes worker with age 52') { should include(Worker.first(:age => 64)) } | |
- it('does not include worker with age 51') { should_not include(Worker.first(:age => 65)) } | |
- its(:current_page) { should == 5 } | |
- its('query.limit') { should == 13 } | |
- its('query.offset') { should == 52 } | |
- its(:total_count) { should == 101 } | |
- its(:num_pages) { should == 8 } | |
- end | |
- | |
- context 'on chained queries' do | |
- subject { Worker.all(:age.gte => 50).page(3).all(:age.lte => 100).per(13) } | |
- its(:current_page) { should == 3 } | |
- its('query.limit') { should == 13 } | |
- its('query.offset') { should == 26 } | |
- its(:total_count) { should == 51 } | |
- its(:num_pages) { should == 4 } | |
- end | |
- | |
- context 'on query on association' do | |
- subject { Worker[0].projects.page(3).all(:name.like => 'Project%').per(5) } | |
- its(:current_page) { should == 3 } | |
- its('query.limit') { should == 5 } | |
- its('query.offset') { should == 10 } | |
- its(:total_count) { should == 50 } | |
- its(:num_pages) { should == 10 } | |
- end | |
- | |
- context 'on query with association conditions' do | |
- subject { Worker.page(3).all(:projects => Project.all).per(5) } | |
- its(:current_page) { should == 3 } | |
- its('query.limit') { should == 5 } | |
- its('query.offset') { should == 10 } | |
- its(:total_count) { should == 50 } | |
- its(:num_pages) { should == 10 } | |
- end | |
- end | |
-end | |
diff --git a/spec/models/default_per_page_spec.rb b/spec/models/default_per_page_spec.rb | |
deleted file mode 100644 | |
index b116b9c..0000000 | |
--- a/spec/models/default_per_page_spec.rb | |
+++ /dev/null | |
@@ -1,29 +0,0 @@ | |
-require 'spec_helper' | |
- | |
-describe 'default per_page' do | |
- describe 'AR::Base' do | |
- subject { ActiveRecord::Base } | |
- it { should_not respond_to :paginates_per } | |
- end | |
- | |
- subject { User.page 0 } | |
- | |
- context 'by default' do | |
- its(:limit_value) { should == 25 } | |
- end | |
- | |
- context 'when explicitly set via paginates_per' do | |
- before { User.paginates_per 1326 } | |
- its(:limit_value) { should == 1326 } | |
- after { User.paginates_per nil } | |
- end | |
- | |
- describe "default per_page value's independency per model" do | |
- context "when User's default per_page was changed" do | |
- before { User.paginates_per 1326 } | |
- subject { Book.page 0 } | |
- its(:limit_value) { should == 25 } | |
- after { User.paginates_per nil } | |
- end | |
- end | |
-end | |
diff --git a/spec/models/mongo_mapper/mongo_mapper_spec.rb b/spec/models/mongo_mapper/mongo_mapper_spec.rb | |
new file mode 100644 | |
index 0000000..380827d | |
--- /dev/null | |
+++ b/spec/models/mongo_mapper/mongo_mapper_spec.rb | |
@@ -0,0 +1,84 @@ | |
+require 'spec_helper' | |
+ | |
+if defined? MongoMapper | |
+ describe Kaminari::MongoMapperExtension do | |
+ before(:each) do | |
+ User.destroy_all | |
+ 41.times { User.create!({:salary => 1}) } | |
+ end | |
+ | |
+ describe '#page' do | |
+ context 'page 1' do | |
+ subject { User.page(1) } | |
+ it { should be_a Plucky::Query } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip(0) } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { User.page 2 } | |
+ it { should be_a Plucky::Query } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 25 } | |
+ end | |
+ | |
+ context 'page "foobar"' do | |
+ subject { User.page 'foobar' } | |
+ it { should be_a Plucky::Query } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 0 } | |
+ end | |
+ | |
+ context 'with criteria before' do | |
+ it "should have the proper criteria source" do | |
+ User.where(:salary => 1).page(2).criteria.source.should == {:salary => 1} | |
+ end | |
+ | |
+ subject { User.where(:salary => 1).page 2 } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 25 } | |
+ end | |
+ | |
+ context 'with criteria after' do | |
+ it "should have the proper criteria source" do | |
+ User.where(:salary => 1).page(2).criteria.source.should == {:salary => 1} | |
+ end | |
+ | |
+ subject { User.page(2).where(:salary => 1) } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 25 } | |
+ end | |
+ end | |
+ | |
+ describe '#per' do | |
+ subject { User.page(2).per(10) } | |
+ it { should be_a Plucky::Query } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should == 3 } | |
+ its(:limit_value) { should == 10 } | |
+ its(:total_pages) { should == 5 } | |
+ it { should skip 10 } | |
+ end | |
+ end | |
+end | |
diff --git a/spec/models/mongo_mapper_spec.rb b/spec/models/mongo_mapper_spec.rb | |
deleted file mode 100644 | |
index 11244bd..0000000 | |
--- a/spec/models/mongo_mapper_spec.rb | |
+++ /dev/null | |
@@ -1,82 +0,0 @@ | |
-require 'spec_helper' | |
-require 'mongo_mapper' | |
-require 'kaminari/models/mongo_mapper_extension' | |
- | |
-describe Kaminari::MongoMapperExtension do | |
- before do | |
- begin | |
- MongoMapper.connection = Mongo::Connection.new('localhost', 27017) | |
- MongoMapper.database = "kaminari_test" | |
- class Developer | |
- include ::MongoMapper::Document | |
- key :salary, Integer | |
- end | |
- | |
- stub(subject).count { 300 } # in order to avoid DB access... | |
- rescue Mongo::ConnectionFailure | |
- pending 'can not connect to MongoDB' | |
- end | |
- end | |
- | |
- describe '#page' do | |
- context 'page 1' do | |
- subject { Developer.page(1) } | |
- it { should be_a Plucky::Query } | |
- its(:current_page) { should == 1 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip(0) } | |
- end | |
- | |
- context 'page 2' do | |
- subject { Developer.page 2 } | |
- it { should be_a Plucky::Query } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 25 } | |
- end | |
- | |
- context 'page "foobar"' do | |
- subject { Developer.page 'foobar' } | |
- it { should be_a Plucky::Query } | |
- its(:current_page) { should == 1 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 0 } | |
- end | |
- | |
- context 'with criteria before' do | |
- it "should have the proper criteria source" do | |
- Developer.where(:salary => 1).page(2).criteria.source.should == {:salary => 1} | |
- end | |
- | |
- subject { Developer.where(:salary => 1).page 2 } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 25 } | |
- end | |
- | |
- context 'with criteria after' do | |
- it "should have the proper criteria source" do | |
- Developer.where(:salary => 1).page(2).criteria.source.should == {:salary => 1} | |
- end | |
- | |
- subject { Developer.page(2).where(:salary => 1) } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 25 } | |
- end | |
- end | |
- | |
- describe '#per' do | |
- subject { Developer.page(2).per(10) } | |
- it { should be_a Plucky::Query } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 10 } | |
- its(:num_pages) { should == 30 } | |
- it { should skip 10 } | |
- end | |
-end | |
diff --git a/spec/models/mongoid/mongoid_spec.rb b/spec/models/mongoid/mongoid_spec.rb | |
new file mode 100644 | |
index 0000000..952c4f2 | |
--- /dev/null | |
+++ b/spec/models/mongoid/mongoid_spec.rb | |
@@ -0,0 +1,197 @@ | |
+require 'spec_helper' | |
+ | |
+if defined? Mongoid | |
+ describe Kaminari::MongoidExtension do | |
+ before(:each) do | |
+ 41.times do | |
+ User.create!({:salary => 1}) | |
+ end | |
+ end | |
+ | |
+ describe 'max_scan', :if => Mongoid::VERSION >= '3' do | |
+ context 'less than total' do | |
+ context 'page 1' do | |
+ subject { User.max_scan(20).page 1 } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 1 } | |
+ its(:total_count) { should == 20 } | |
+ it { should skip(0) } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { User.max_scan(30).page 2 } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ its(:total_count) { should == 30 } | |
+ it { should skip 25 } | |
+ end | |
+ end | |
+ | |
+ context 'more than total' do | |
+ context 'page 1' do | |
+ subject { User.max_scan(60).page 1 } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ its(:total_count) { should == 41 } | |
+ it { should skip(0) } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { User.max_scan(60).page 2 } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ its(:total_count) { should == 41 } | |
+ it { should skip 25 } | |
+ end | |
+ end | |
+ end | |
+ | |
+ describe '#page' do | |
+ | |
+ context 'page 1' do | |
+ subject { User.page 1 } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip(0) } | |
+ end | |
+ | |
+ context 'page 2' do | |
+ subject { User.page 2 } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 25 } | |
+ end | |
+ | |
+ context 'page "foobar"' do | |
+ subject { User.page 'foobar' } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 0 } | |
+ end | |
+ | |
+ shared_examples 'complete valid pagination' do | |
+ if Mongoid::VERSION > '3.0.0' | |
+ its(:selector) { should == {'salary' => 1} } | |
+ else | |
+ its(:selector) { should == {:salary => 1} } | |
+ end | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should be_nil } | |
+ its(:limit_value) { should == 25 } | |
+ its(:total_pages) { should == 2 } | |
+ it { should skip 25 } | |
+ end | |
+ | |
+ context 'with criteria before' do | |
+ subject { User.where(:salary => 1).page 2 } | |
+ it_should_behave_like 'complete valid pagination' | |
+ end | |
+ | |
+ context 'with criteria after' do | |
+ subject { User.page(2).where(:salary => 1) } | |
+ it_should_behave_like 'complete valid pagination' | |
+ end | |
+ | |
+ context "with database:", :if => Mongoid::VERSION >= '3' do | |
+ before :all do | |
+ 15.times { User.with(:database => "default_db").create!(:salary => 1) } | |
+ 10.times { User.with(:database => "other_db").create!(:salary => 1) } | |
+ end | |
+ | |
+ context "default_db" do | |
+ subject { User.with(:database => "default_db").order_by(:artist.asc).page(1) } | |
+ its(:total_count) { should == 15 } | |
+ end | |
+ | |
+ context "other_db" do | |
+ subject { User.with(:database => "other_db").order_by(:artist.asc).page(1) } | |
+ its(:total_count) { should == 10 } | |
+ end | |
+ end | |
+ end | |
+ | |
+ describe '#per' do | |
+ subject { User.page(2).per(10) } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:current_page) { should == 2 } | |
+ its(:prev_page) { should == 1 } | |
+ its(:next_page) { should == 3 } | |
+ its(:limit_value) { should == 10 } | |
+ its(:total_pages) { should == 5 } | |
+ it { should skip 10 } | |
+ end | |
+ | |
+ describe '#page in embedded documents' do | |
+ before do | |
+ @mongo_developer = MongoMongoidExtensionDeveloper.new | |
+ @mongo_developer.frameworks.new(:name => "rails", :language => "ruby") | |
+ @mongo_developer.frameworks.new(:name => "merb", :language => "ruby") | |
+ @mongo_developer.frameworks.new(:name => "sinatra", :language => "ruby") | |
+ @mongo_developer.frameworks.new(:name => "cakephp", :language => "php") | |
+ @mongo_developer.frameworks.new(:name => "tornado", :language => "python") | |
+ end | |
+ | |
+ context 'page 1' do | |
+ subject { @mongo_developer.frameworks.page(1).per(1) } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:total_count) { should == 5 } | |
+ its(:limit_value) { should == 1 } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:total_pages) { should == 5 } | |
+ end | |
+ | |
+ context 'with criteria after' do | |
+ subject { @mongo_developer.frameworks.page(1).per(2).where(:language => "ruby") } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:total_count) { should == 3 } | |
+ its(:limit_value) { should == 2 } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:total_pages) { should == 2 } | |
+ end | |
+ | |
+ context 'with criteria before' do | |
+ subject { @mongo_developer.frameworks.where(:language => "ruby").page(1).per(2) } | |
+ it { should be_a Mongoid::Criteria } | |
+ its(:total_count) { should == 3 } | |
+ its(:limit_value) { should == 2 } | |
+ its(:current_page) { should == 1 } | |
+ its(:prev_page) { should be_nil } | |
+ its(:next_page) { should == 2 } | |
+ its(:total_pages) { should == 2 } | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/spec/models/mongoid_spec.rb b/spec/models/mongoid_spec.rb | |
deleted file mode 100644 | |
index 1a8d9a8..0000000 | |
--- a/spec/models/mongoid_spec.rb | |
+++ /dev/null | |
@@ -1,129 +0,0 @@ | |
-require 'spec_helper' | |
-require 'mongoid' | |
-require 'kaminari/models/mongoid_extension' | |
- | |
-describe Kaminari::MongoidExtension do | |
- before :all do | |
- class Developer | |
- include ::Mongoid::Document | |
- field :salary, :type => Integer | |
- end | |
- end | |
- | |
- describe '#page' do | |
- before do | |
- stub(subject).count { 300 } # in order to avoid DB access... | |
- end | |
- | |
- context 'page 1' do | |
- subject { Developer.page 1 } | |
- it { should be_a Mongoid::Criteria } | |
- its(:current_page) { should == 1 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip(0) } | |
- end | |
- | |
- context 'page 2' do | |
- subject { Developer.page 2 } | |
- it { should be_a Mongoid::Criteria } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 25 } | |
- end | |
- | |
- context 'page "foobar"' do | |
- subject { Developer.page 'foobar' } | |
- it { should be_a Mongoid::Criteria } | |
- its(:current_page) { should == 1 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 0 } | |
- end | |
- | |
- context 'with criteria before' do | |
- subject { Developer.where(:salary => 1).page 2 } | |
- its(:selector) { should == {:salary => 1} } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 25 } | |
- end | |
- | |
- context 'with criteria after' do | |
- subject { Developer.page(2).where(:salary => 1) } | |
- its(:selector) { should == {:salary => 1} } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 25 } | |
- its(:num_pages) { should == 12 } | |
- it { should skip 25 } | |
- end | |
- end | |
- | |
- describe '#per' do | |
- before do | |
- stub(subject).count { 300 } # in order to avoid DB access... | |
- end | |
- | |
- subject { Developer.page(2).per(10) } | |
- it { should be_a Mongoid::Criteria } | |
- its(:current_page) { should == 2 } | |
- its(:limit_value) { should == 10 } | |
- its(:num_pages) { should == 30 } | |
- it { should skip 10 } | |
- end | |
- | |
- describe '#page in embedded documents' do | |
- before :all do | |
- class MongoDeveloper | |
- include ::Mongoid::Document | |
- field :salary, :type => Integer | |
- embeds_many :frameworks | |
- end | |
- | |
- class Framework | |
- include ::Mongoid::Document | |
- field :name, :type => String | |
- field :language, :type => String | |
- embedded_in :mongo_developer | |
- end | |
- end | |
- | |
- before :all do | |
- @mongo_developer = MongoDeveloper.new | |
- @mongo_developer.frameworks.new(:name => "rails", :language => "ruby") | |
- @mongo_developer.frameworks.new(:name => "merb", :language => "ruby") | |
- @mongo_developer.frameworks.new(:name => "sinatra", :language => "ruby") | |
- @mongo_developer.frameworks.new(:name => "cakephp", :language => "php") | |
- @mongo_developer.frameworks.new(:name => "tornado", :language => "python") | |
- end | |
- | |
- context 'page 1' do | |
- subject { @mongo_developer.frameworks.page(1).per(1) } | |
- it { should be_a Mongoid::Criteria } | |
- its(:total_count) { should == 5 } | |
- its(:limit_value) { should == 1 } | |
- its(:current_page) { should == 1 } | |
- its(:num_pages) { should == 5 } | |
- end | |
- | |
- context 'with criteria after' do | |
- subject { @mongo_developer.frameworks.page(1).per(2).where(:language => "ruby") } | |
- it { should be_a Mongoid::Criteria } | |
- its(:total_count) { should == 3 } | |
- its(:limit_value) { should == 2 } | |
- its(:current_page) { should == 1 } | |
- its(:num_pages) { should == 2 } | |
- end | |
- | |
- context 'with criteria before' do | |
- subject { @mongo_developer.frameworks.where(:language => "ruby").page(1).per(2) } | |
- it { should be_a Mongoid::Criteria } | |
- its(:total_count) { should == 3 } | |
- its(:limit_value) { should == 2 } | |
- its(:current_page) { should == 1 } | |
- its(:num_pages) { should == 2 } | |
- end | |
- end | |
-end | |
diff --git a/spec/models/scopes_spec.rb b/spec/models/scopes_spec.rb | |
deleted file mode 100644 | |
index a21df29..0000000 | |
--- a/spec/models/scopes_spec.rb | |
+++ /dev/null | |
@@ -1,163 +0,0 @@ | |
-require 'spec_helper' | |
- | |
-shared_examples_for 'the first page' do | |
- it { should have(25).users } | |
- its('first.name') { should == 'user001' } | |
-end | |
- | |
-shared_examples_for 'blank page' do | |
- it { should have(0).users } | |
-end | |
- | |
-describe Kaminari::ActiveRecordExtension do | |
- before :all do | |
- 1.upto(100) {|i| User.create! :name => "user#{'%03d' % i}", :age => (i / 10)} | |
- 1.upto(100) {|i| GemDefinedModel.create! :name => "user#{'%03d' % i}", :age => (i / 10)} | |
- end | |
- | |
- [User, Admin, GemDefinedModel].each do |model_class| | |
- context "for #{model_class}" do | |
- describe '#page' do | |
- context 'page 1' do | |
- subject { model_class.page 1 } | |
- it_should_behave_like 'the first page' | |
- end | |
- | |
- context 'page 2' do | |
- subject { model_class.page 2 } | |
- it { should have(25).users } | |
- its('first.name') { should == 'user026' } | |
- end | |
- | |
- context 'page without an argument' do | |
- subject { model_class.page } | |
- it_should_behave_like 'the first page' | |
- end | |
- | |
- context 'page < 1' do | |
- subject { model_class.page 0 } | |
- it_should_behave_like 'the first page' | |
- end | |
- | |
- context 'page > max page' do | |
- subject { model_class.page 5 } | |
- it_should_behave_like 'blank page' | |
- end | |
- | |
- describe 'ensure #order_values is preserved' do | |
- subject { model_class.order('id').page 1 } | |
- its('order_values.uniq') { should == ['id'] } | |
- end | |
- end | |
- | |
- describe '#per' do | |
- context 'page 1 per 5' do | |
- subject { model_class.page(1).per(5) } | |
- it { should have(5).users } | |
- its('first.name') { should == 'user001' } | |
- end | |
- end | |
- | |
- describe '#padding' do | |
- context 'page 1 per 5 padding 1' do | |
- subject { model_class.page(1).per(5).padding(1) } | |
- it { should have(5).users } | |
- its('first.name') { should == 'user002' } | |
- end | |
- end | |
- | |
- describe '#num_pages' do | |
- context 'per 25 (default)' do | |
- subject { model_class.page } | |
- its(:num_pages) { should == 4 } | |
- end | |
- | |
- context 'per 7' do | |
- subject { model_class.page(2).per(7) } | |
- its(:num_pages) { should == 15 } | |
- end | |
- | |
- context 'per 65536' do | |
- subject { model_class.page(50).per(65536) } | |
- its(:num_pages) { should == 1 } | |
- end | |
- | |
- context 'per 0 (using default)' do | |
- subject { model_class.page(50).per(0) } | |
- its(:num_pages) { should == 4 } | |
- end | |
- | |
- context 'per -1 (using default)' do | |
- subject { model_class.page(5).per(-1) } | |
- its(:num_pages) { should == 4 } | |
- end | |
- | |
- context 'per "String value that can not be converted into Number" (using default)' do | |
- subject { model_class.page(5).per('aho') } | |
- its(:num_pages) { should == 4 } | |
- end | |
- end | |
- | |
- | |
- describe '#current_page' do | |
- context 'page 1' do | |
- subject { model_class.page } | |
- its(:current_page) { should == 1 } | |
- end | |
- | |
- context 'page 2' do | |
- subject { model_class.page(2).per 3 } | |
- its(:current_page) { should == 2 } | |
- end | |
- end | |
- | |
- describe '#first_page?' do | |
- context 'on first page' do | |
- subject { model_class.page(1).per(10) } | |
- its(:first_page?) { should == true } | |
- end | |
- | |
- context 'not on first page' do | |
- subject { model_class.page(5).per(10) } | |
- its(:first_page?) { should == false } | |
- end | |
- end | |
- | |
- describe '#last_page?' do | |
- context 'on last page' do | |
- subject { model_class.page(10).per(10) } | |
- its(:last_page?) { should == true } | |
- end | |
- | |
- context 'not on last page' do | |
- subject { model_class.page(1).per(10) } | |
- its(:last_page?) { should == false } | |
- end | |
- end | |
- | |
- describe '#count' do | |
- context 'page 1' do | |
- subject { model_class.page } | |
- its(:count) { should == 25 } | |
- end | |
- | |
- context 'page 2' do | |
- subject { model_class.page 2 } | |
- its(:count) { should == 25 } | |
- end | |
- end | |
- | |
- context 'chained with .group' do | |
- subject { model_class.group('age').page(2).per 5 } | |
- # 0..10 | |
- its(:total_count) { should == 11 } | |
- its(:num_pages) { should == 3 } | |
- end | |
- | |
- context 'activerecord descendants' do | |
- subject { ActiveRecord::Base.descendants } | |
- its(:length) { should_not == 0 } | |
- end | |
- end | |
- end | |
-end | |
diff --git a/spec/requests/users_spec.rb b/spec/requests/users_spec.rb | |
index 7480e6f..d80f71f 100644 | |
--- a/spec/requests/users_spec.rb | |
+++ b/spec/requests/users_spec.rb | |
@@ -3,7 +3,6 @@ require 'spec_helper' | |
feature 'Users' do | |
background do | |
- User.delete_all | |
1.upto(100) {|i| User.create! :name => "user#{'%03d' % i}" } | |
end | |
scenario 'navigating by pagination links' do | |
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb | |
index a4c86b0..700b458 100644 | |
--- a/spec/spec_helper.rb | |
+++ b/spec/spec_helper.rb | |
@@ -1,30 +1,34 @@ | |
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) | |
$LOAD_PATH.unshift(File.dirname(__FILE__)) | |
-require 'rails' | |
-require 'mongoid' | |
-require 'dm-core' | |
-require 'kaminari' | |
+ | |
+begin | |
+ require 'rails' | |
+rescue LoadError | |
+end | |
+ | |
+require 'bundler/setup' | |
+Bundler.require | |
+ | |
+require 'capybara/rspec' | |
require 'database_cleaner' | |
-# Ensure we use 'syck' instead of 'psych' in 1.9.2 | |
-# RubyGems >= 1.5.0 uses 'psych' on 1.9.2, but | |
-# Psych does not yet support YAML 1.1 merge keys. | |
-# Merge keys is often used in mongoid.yml | |
-# See: http://redmine.ruby-lang.org/issues/show/4300 | |
-if RUBY_VERSION >= '1.9.2' | |
- YAML::ENGINE.yamler = 'syck' | |
+ | |
+# Simulate a gem providing a subclass of ActiveRecord::Base before the Railtie is loaded. | |
+require 'fake_gem' if defined? ActiveRecord | |
+ | |
+if defined? Rails | |
+ require 'fake_app/rails_app' | |
+ | |
+ require 'rspec/rails' | |
+end | |
+if defined? Sinatra | |
+ require 'spec_helper_for_sinatra' | |
end | |
-require 'fake_gem' | |
-require 'fake_app' | |
-require 'rspec/rails' | |
# Requires supporting files with custom matchers and macros, etc, | |
# in ./support/ and its subdirectories. | |
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} | |
RSpec.configure do |config| | |
config.mock_with :rr | |
- config.before :all do | |
-# ActiveRecord::Base.connection.execute 'CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255))' unless ActiveRecord::Base.connection.table_exists? 'users' | |
- CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? 'users' | |
- end | |
+ config.filter_run_excluding :generator_spec => true if !ENV['GENERATOR_SPEC'] | |
end | |
diff --git a/spec/spec_helper_for_sinatra.rb b/spec/spec_helper_for_sinatra.rb | |
index 4a6ca92..9e44252 100644 | |
--- a/spec/spec_helper_for_sinatra.rb | |
+++ b/spec/spec_helper_for_sinatra.rb | |
@@ -1,10 +1,31 @@ | |
require 'kaminari/sinatra' | |
+require 'kaminari/helpers/action_view_extension' | |
require 'rack/test' | |
require 'sinatra/test_helpers' | |
+require 'capybara/rspec' | |
+ | |
+require 'fake_app/sinatra_app' | |
+ | |
+Capybara.app = SinatraApp | |
+ | |
+module HelperMethodForHelperSpec | |
+ module FakeEnv | |
+ def env | |
+ {'PATH_INFO' => '/'} | |
+ end | |
+ end | |
+ | |
+ def helper | |
+ # OMG terrible object... | |
+ ::Kaminari::Helpers::SinatraHelpers::ActionViewTemplateProxy.new(:current_params => {}, :current_path => '/', :param_name => Kaminari.config.param_name).extend(Padrino::Helpers, Kaminari::ActionViewExtension, Kaminari::Helpers::SinatraHelpers::HelperMethods, FakeEnv) | |
+ end | |
+end | |
RSpec.configure do |config| | |
config.include Rack::Test::Methods | |
config.include Sinatra::TestHelpers | |
+ config.include HelperMethodForHelperSpec | |
+# config.include HelperMethodForHelperSpec, :type => :helper | |
end | |
require 'nokogiri' | |
diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb | |
index 9008744..05a5c13 100644 | |
--- a/spec/support/database_cleaner.rb | |
+++ b/spec/support/database_cleaner.rb | |
@@ -1,8 +1,14 @@ | |
-DatabaseCleaner.strategy = :transaction | |
+DatabaseCleaner[:active_record].strategy = :transaction if defined? ActiveRecord | |
+DatabaseCleaner[:data_mapper].strategy = :truncation if defined? DataMapper | |
+DatabaseCleaner[:mongoid].strategy = :truncation if defined? Mongoid | |
+DatabaseCleaner[:mongo_mapper].strategy = :truncation if defined? MongoMapper | |
RSpec.configure do |config| | |
config.before :suite do | |
- DatabaseCleaner.clean_with :truncation | |
+ DatabaseCleaner.clean_with :truncation if defined? ActiveRecord | |
+ DatabaseCleaner.clean_with :truncation if defined? DataMapper | |
+ DatabaseCleaner.clean_with :truncation if defined? Mongoid | |
+ DatabaseCleaner.clean_with :truncation if defined? MongoMapper | |
end | |
config.before :each do | |
DatabaseCleaner.start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment