will_paginate 2.3.16 → 3.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. data/CHANGELOG.rdoc +24 -80
  2. data/LICENSE +1 -1
  3. data/README.rdoc +125 -0
  4. data/Rakefile +26 -22
  5. data/lib/will_paginate/array.rb +25 -8
  6. data/lib/will_paginate/collection.rb +15 -28
  7. data/lib/will_paginate/core_ext.rb +26 -0
  8. data/lib/will_paginate/deprecation.rb +50 -0
  9. data/lib/will_paginate/finders/active_record.rb +158 -0
  10. data/lib/will_paginate/finders/active_resource.rb +51 -0
  11. data/lib/will_paginate/finders/base.rb +112 -0
  12. data/lib/will_paginate/finders/data_mapper.rb +30 -0
  13. data/lib/will_paginate/finders/sequel.rb +23 -0
  14. data/lib/will_paginate/finders.rb +9 -0
  15. data/lib/will_paginate/railtie.rb +26 -0
  16. data/lib/will_paginate/version.rb +5 -5
  17. data/lib/will_paginate/view_helpers/action_view.rb +142 -0
  18. data/lib/will_paginate/view_helpers/base.rb +126 -0
  19. data/lib/will_paginate/view_helpers/link_renderer.rb +130 -0
  20. data/lib/will_paginate/view_helpers/link_renderer_base.rb +83 -0
  21. data/lib/will_paginate/view_helpers/merb.rb +13 -0
  22. data/lib/will_paginate/view_helpers.rb +25 -436
  23. data/lib/will_paginate.rb +10 -84
  24. data/spec/collection_spec.rb +147 -0
  25. data/spec/console +8 -0
  26. data/spec/console_fixtures.rb +8 -0
  27. data/spec/database.yml +22 -0
  28. data/spec/finders/active_record_spec.rb +377 -0
  29. data/spec/finders/active_resource_spec.rb +52 -0
  30. data/spec/finders/activerecord_test_connector.rb +114 -0
  31. data/spec/finders/data_mapper_spec.rb +62 -0
  32. data/spec/finders/data_mapper_test_connector.rb +20 -0
  33. data/spec/finders/sequel_spec.rb +53 -0
  34. data/spec/finders/sequel_test_connector.rb +9 -0
  35. data/spec/finders_spec.rb +76 -0
  36. data/{test → spec}/fixtures/developer.rb +2 -3
  37. data/{test → spec}/fixtures/project.rb +2 -6
  38. data/{test → spec}/fixtures/projects.yml +1 -1
  39. data/{test → spec}/fixtures/reply.rb +1 -1
  40. data/spec/fixtures/topic.rb +7 -0
  41. data/spec/rcov.opts +2 -0
  42. data/spec/spec.opts +2 -0
  43. data/spec/spec_helper.rb +74 -0
  44. data/spec/tasks.rake +60 -0
  45. data/spec/view_helpers/action_view_spec.rb +345 -0
  46. data/spec/view_helpers/base_spec.rb +64 -0
  47. data/spec/view_helpers/link_renderer_base_spec.rb +84 -0
  48. data/spec/view_helpers/view_example_group.rb +103 -0
  49. metadata +60 -52
  50. data/README.md +0 -53
  51. data/lib/will_paginate/finder.rb +0 -264
  52. data/lib/will_paginate/i18n.rb +0 -29
  53. data/lib/will_paginate/locale/en.yml +0 -33
  54. data/lib/will_paginate/named_scope.rb +0 -170
  55. data/lib/will_paginate/named_scope_patch.rb +0 -37
  56. data/lib/will_paginate/per_page.rb +0 -27
  57. data/test/ci.rb +0 -56
  58. data/test/collection_test.rb +0 -160
  59. data/test/console +0 -8
  60. data/test/database.yml +0 -16
  61. data/test/finder_test.rb +0 -520
  62. data/test/fixtures/topic.rb +0 -12
  63. data/test/gemfiles/Gemfile.1.2 +0 -13
  64. data/test/gemfiles/Gemfile.1.2.lock +0 -39
  65. data/test/gemfiles/Gemfile.2.0 +0 -16
  66. data/test/gemfiles/Gemfile.2.0.lock +0 -28
  67. data/test/gemfiles/Gemfile.2.1 +0 -16
  68. data/test/gemfiles/Gemfile.2.1.lock +0 -28
  69. data/test/gemfiles/Gemfile.2.2 +0 -16
  70. data/test/gemfiles/Gemfile.2.2.lock +0 -28
  71. data/test/helper.rb +0 -34
  72. data/test/lib/activerecord_test_case.rb +0 -38
  73. data/test/lib/activerecord_test_connector.rb +0 -86
  74. data/test/lib/load_fixtures.rb +0 -12
  75. data/test/lib/view_test_process.rb +0 -186
  76. data/test/view_test.rb +0 -373
  77. /data/{test → spec}/fixtures/admin.rb +0 -0
  78. /data/{test → spec}/fixtures/developers_projects.yml +0 -0
  79. /data/{test → spec}/fixtures/replies.yml +0 -0
  80. /data/{test → spec}/fixtures/schema.rb +0 -0
  81. /data/{test → spec}/fixtures/topics.yml +0 -0
  82. /data/{test → spec}/fixtures/user.rb +0 -0
  83. /data/{test → spec}/fixtures/users.yml +0 -0
@@ -0,0 +1,114 @@
1
+ require 'active_record'
2
+ require 'active_record/version'
3
+ require 'active_record/fixtures'
4
+ require 'active_support/multibyte' # needed for Ruby 1.9.1
5
+
6
+ $query_count = $query_sql = nil
7
+
8
+ class ActiverecordTestConnector
9
+ cattr_accessor :able_to_connect
10
+ cattr_accessor :connected
11
+
12
+ FIXTURES_PATH = File.expand_path('../../fixtures', __FILE__)
13
+
14
+ # Set our defaults
15
+ self.connected = false
16
+ self.able_to_connect = true
17
+
18
+ def self.setup
19
+ unless self.connected || !self.able_to_connect
20
+ setup_connection
21
+ load_schema
22
+ add_load_path FIXTURES_PATH
23
+ self.connected = true
24
+ end
25
+ rescue Exception => e # errors from ActiveRecord setup
26
+ $stderr.puts "\nSkipping ActiveRecord tests: #{e}\n\n"
27
+ self.able_to_connect = false
28
+ end
29
+
30
+ private
31
+
32
+ def self.add_load_path(path)
33
+ dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
34
+ dep.load_paths.unshift path
35
+ end
36
+
37
+ def self.setup_connection
38
+ db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
39
+
40
+ configurations = YAML.load_file(File.expand_path('../../database.yml', __FILE__))
41
+ raise "no configuration for '#{db}'" unless configurations.key? db
42
+ configuration = configurations[db]
43
+
44
+ ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
45
+ puts "using #{configuration['adapter']} adapter"
46
+
47
+ ActiveRecord::Base.configurations = { db => configuration }
48
+ ActiveRecord::Base.establish_connection(db)
49
+ prepare ActiveRecord::Base.connection
50
+ end
51
+
52
+ def self.load_schema
53
+ ActiveRecord::Base.silence do
54
+ ActiveRecord::Migration.verbose = false
55
+ load File.join(FIXTURES_PATH, 'schema.rb')
56
+ end
57
+ end
58
+
59
+ def self.prepare(conn)
60
+ class << conn
61
+ IGNORED_SQL = /^(?:PRAGMA|SELECT (?:currval|CAST|@@IDENTITY|@@ROWCOUNT)|SHOW FIELDS)\b/
62
+
63
+ def execute_with_counting(sql, name = nil, &block)
64
+ if $query_count and IGNORED_SQL !~ sql
65
+ $query_count += 1
66
+ $query_sql << sql
67
+ end
68
+ execute_without_counting(sql, name, &block)
69
+ end
70
+
71
+ alias_method_chain :execute, :counting
72
+ end
73
+ end
74
+
75
+ def self.show_sql
76
+ ActiveSupport::Notifications.subscribe('active_record.sql') do |*args|
77
+ puts args.last[:sql]
78
+ end
79
+ end
80
+
81
+ module FixtureSetup
82
+ def fixtures(*tables)
83
+ table_names = tables.map { |t| t.to_s }
84
+
85
+ fixtures = Fixtures.create_fixtures ActiverecordTestConnector::FIXTURES_PATH, table_names
86
+ @@loaded_fixtures = {}
87
+ @@fixture_cache = {}
88
+
89
+ unless fixtures.nil?
90
+ if fixtures.instance_of?(Fixtures)
91
+ @@loaded_fixtures[fixtures.table_name] = fixtures
92
+ else
93
+ fixtures.each { |f| @@loaded_fixtures[f.table_name] = f }
94
+ end
95
+ end
96
+
97
+ table_names.each do |table_name|
98
+ define_method(table_name) do |*fixtures|
99
+ @@fixture_cache[table_name] ||= {}
100
+
101
+ instances = fixtures.map do |fixture|
102
+ if @@loaded_fixtures[table_name][fixture.to_s]
103
+ @@fixture_cache[table_name][fixture] ||= @@loaded_fixtures[table_name][fixture.to_s].find
104
+ else
105
+ raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
106
+ end
107
+ end
108
+
109
+ instances.size == 1 ? instances.first : instances
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/data_mapper'
3
+ require File.expand_path('../data_mapper_test_connector', __FILE__)
4
+
5
+ require 'will_paginate'
6
+
7
+ describe WillPaginate::Finders::DataMapper do
8
+
9
+ it "should make #paginate available to DM resource classes" do
10
+ Animal.should respond_to(:paginate)
11
+ end
12
+
13
+ it "should paginate" do
14
+ Animal.expects(:all).with(:limit => 5, :offset => 0).returns([])
15
+ Animal.paginate(:page => 1, :per_page => 5)
16
+ end
17
+
18
+ it "should NOT to paginate_by_sql" do
19
+ Animal.should_not respond_to(:paginate_by_sql)
20
+ end
21
+
22
+ it "should support explicit :all argument" do
23
+ Animal.expects(:all).with(instance_of(Hash)).returns([])
24
+ Animal.paginate(:all, :page => nil)
25
+ end
26
+
27
+ it "should support conditional pagination" do
28
+ filtered_result = Animal.paginate(:all, :name => 'Dog', :page => nil)
29
+ filtered_result.size.should == 1
30
+ filtered_result.first.should == Animal.first(:name => 'Dog')
31
+ end
32
+
33
+ it "should leave extra parameters intact" do
34
+ Animal.expects(:all).with(:name => 'Dog', :limit => 4, :offset => 0 ).returns(Array.new(5))
35
+ Animal.expects(:count).with({:name => 'Dog'}).returns(1)
36
+
37
+ Animal.paginate :name => 'Dog', :page => 1, :per_page => 4
38
+ end
39
+
40
+ describe "counting" do
41
+ it "should ignore nil in :count parameter" do
42
+ lambda { Animal.paginate :page => nil, :count => nil }.should_not raise_error
43
+ end
44
+
45
+ it "should guess the total count" do
46
+ Animal.expects(:all).returns(Array.new(2))
47
+ Animal.expects(:count).never
48
+
49
+ result = Animal.paginate :page => 2, :per_page => 4
50
+ result.total_entries.should == 6
51
+ end
52
+
53
+ it "should guess that there are no records" do
54
+ Animal.expects(:all).returns([])
55
+ Animal.expects(:count).never
56
+
57
+ result = Animal.paginate :page => 1, :per_page => 4
58
+ result.total_entries.should == 0
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,20 @@
1
+ require 'dm-core'
2
+ DataMapper.setup :default, 'sqlite3::memory:'
3
+
4
+ # Define models
5
+ class Animal
6
+ include DataMapper::Resource
7
+ property :id, Serial
8
+ property :name, String
9
+ property :notes, Text
10
+
11
+ def self.setup
12
+ Animal.create(:name => 'Dog', :notes => "Man's best friend")
13
+ Animal.create(:name => 'Cat', :notes => "Woman's best friend")
14
+ Animal.create(:name => 'Lion', :notes => 'King of the Jungle')
15
+ end
16
+ end
17
+
18
+ # Load fixtures
19
+ Animal.auto_migrate!
20
+ Animal.setup
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/sequel'
3
+ require File.expand_path('../sequel_test_connector', __FILE__)
4
+
5
+ describe Sequel::Dataset::Pagination, 'extension' do
6
+
7
+ class Car < Sequel::Model
8
+ end
9
+
10
+ it "should have the #paginate method" do
11
+ Car.should respond_to(:paginate)
12
+ end
13
+
14
+ it "should NOT have the #paginate_by_sql method" do
15
+ Car.should_not respond_to(:paginate_by_sql)
16
+ end
17
+
18
+ describe 'pagination' do
19
+ before(:all) do
20
+ Car.create(:name => 'Shelby', :notes => "Man's best friend")
21
+ Car.create(:name => 'Aston Martin', :notes => "Woman's best friend")
22
+ Car.create(:name => 'Corvette', :notes => 'King of the Jungle')
23
+ end
24
+
25
+ it "should imitate WillPaginate::Collection" do
26
+ result = Car.paginate(1, 2)
27
+
28
+ result.total_entries.should == 3
29
+ result.total_pages.should == 2
30
+ result.per_page.should == 2
31
+ result.current_page.should == 1
32
+ result.previous_page.should be_nil
33
+ result.next_page.should == 2
34
+ end
35
+
36
+ it "should perform" do
37
+ Car.paginate(1, 2).all.should == [Car[1], Car[2]]
38
+ end
39
+
40
+ it "should perform with #select and #order" do
41
+ result = Car.select("name as foo".lit).order(:name).paginate(1, 2).all
42
+ result.size.should == 2
43
+ result.first.values[:foo].should == "Aston Martin"
44
+ end
45
+
46
+ it "should perform with #filter" do
47
+ results = Car.filter(:name => 'Shelby').paginate(1, 2).all
48
+ results.size.should == 1
49
+ results.first.should == Car.find(:name => 'Shelby')
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,9 @@
1
+ require 'sequel'
2
+
3
+ db = Sequel.sqlite
4
+
5
+ db.create_table :cars do
6
+ primary_key :id, :integer, :auto_increment => true
7
+ column :name, :text
8
+ column :notes, :text
9
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/base'
3
+
4
+ class Model
5
+ extend WillPaginate::Finders::Base
6
+ end
7
+
8
+ describe WillPaginate::Finders::Base do
9
+ it "should define default per_page of 30" do
10
+ Model.per_page.should == 30
11
+ end
12
+
13
+ it "should allow to set custom per_page" do
14
+ begin
15
+ Model.per_page = 25
16
+ Model.per_page.should == 25
17
+ ensure
18
+ Model.per_page = 30
19
+ end
20
+ end
21
+
22
+ it "should result with WillPaginate::Collection" do
23
+ Model.expects(:wp_query)
24
+ Model.paginate(:page => nil).should be_instance_of(WillPaginate::Collection)
25
+ end
26
+
27
+ it "should delegate pagination to wp_query" do
28
+ Model.expects(:wp_query).with({}, instance_of(WillPaginate::Collection), [])
29
+ Model.paginate :page => nil
30
+ end
31
+
32
+ it "should complain when no hash parameters given" do
33
+ lambda {
34
+ Model.paginate
35
+ }.should raise_error(ArgumentError, 'parameter hash expected')
36
+ end
37
+
38
+ it "should complain when no :page parameter present" do
39
+ lambda {
40
+ Model.paginate :per_page => 6
41
+ }.should raise_error(ArgumentError, ':page parameter required')
42
+ end
43
+
44
+ it "should complain when both :count and :total_entries are given" do
45
+ lambda {
46
+ Model.paginate :page => 1, :count => {}, :total_entries => 1
47
+ }.should raise_error(ArgumentError, ':count and :total_entries are mutually exclusive')
48
+ end
49
+
50
+ it "should never mangle options" do
51
+ options = { :page => 1 }
52
+ options.expects(:delete).never
53
+ options_before = options.dup
54
+
55
+ Model.expects(:wp_query)
56
+ Model.paginate(options)
57
+
58
+ options.should == options_before
59
+ end
60
+
61
+ it "should provide paginated_each functionality" do
62
+ collection = stub('collection', :size => 5, :empty? => false, :per_page => 5)
63
+ collection.expects(:each).times(2).returns(collection)
64
+ last_collection = stub('collection', :size => 4, :empty? => false, :per_page => 5)
65
+ last_collection.expects(:each).returns(last_collection)
66
+
67
+ params = { :order => 'id', :total_entries => 0 }
68
+
69
+ Model.expects(:paginate).with(params.merge(:page => 2)).returns(collection)
70
+ Model.expects(:paginate).with(params.merge(:page => 3)).returns(collection)
71
+ Model.expects(:paginate).with(params.merge(:page => 4)).returns(last_collection)
72
+
73
+ total = Model.paginated_each(:page => '2') { }
74
+ total.should == 14
75
+ end
76
+ end
@@ -7,8 +7,7 @@ class Developer < User
7
7
  end
8
8
  end
9
9
 
10
- named_scope :distinct, :select => 'DISTINCT `users`.*'
11
- named_scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'
10
+ scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'
12
11
 
13
- self.per_page = 10
12
+ def self.per_page() 10 end
14
13
  end
@@ -6,12 +6,8 @@ class Project < ActiveRecord::Base
6
6
  # :counter_sql => 'SELECT COUNT(*) FROM topics WHERE (topics.project_id = #{id})'
7
7
 
8
8
  has_many :replies, :through => :topics do
9
- def find_recent(params = {})
10
- with_scope :find => { :conditions => ['replies.created_at > ?', 15.minutes.ago] } do
11
- find :all, params
12
- end
9
+ def only_recent(params = {})
10
+ scoped.where(['replies.created_at > ?', 15.minutes.ago])
13
11
  end
14
12
  end
15
-
16
- has_many :unique_replies, :through => :topics, :source => :replies, :uniq => true
17
13
  end
@@ -3,4 +3,4 @@ active_record:
3
3
  name: Active Record
4
4
  action_controller:
5
5
  id: 2
6
- name: Active Controller
6
+ name: Action Controller
@@ -1,7 +1,7 @@
1
1
  class Reply < ActiveRecord::Base
2
2
  belongs_to :topic, :include => [:replies]
3
3
 
4
- named_scope :recent, :conditions => ['replies.created_at > ?', 15.minutes.ago]
4
+ scope :recent, :conditions => ['replies.created_at > ?', 15.minutes.ago]
5
5
 
6
6
  validates_presence_of :content
7
7
  end
@@ -0,0 +1,7 @@
1
+ class Topic < ActiveRecord::Base
2
+ has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
3
+ belongs_to :project
4
+
5
+ scope :mentions_activerecord, :conditions => ['topics.title LIKE ?', '%ActiveRecord%']
6
+ scope :distinct, :select => "DISTINCT #{table_name}.*"
7
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1,2 @@
1
+ --exclude ^\/,^spec\/,core_ext.rb,deprecation.rb
2
+ --no-validator-links
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --reverse
@@ -0,0 +1,74 @@
1
+ require 'spec/autorun'
2
+
3
+ module MyExtras
4
+ protected
5
+
6
+ def include_phrase(string)
7
+ PhraseMatcher.new(string)
8
+ end
9
+
10
+ def collection(params = {})
11
+ if params[:total_pages]
12
+ params[:per_page] = 1
13
+ params[:total_entries] = params[:total_pages]
14
+ end
15
+ WillPaginate::Collection.new(params[:page] || 1, params[:per_page] || 30, params[:total_entries])
16
+ end
17
+
18
+ def have_deprecation
19
+ DeprecationMatcher.new
20
+ end
21
+ end
22
+
23
+ Spec::Runner.configure do |config|
24
+ # config.include My::Pony, My::Horse, :type => :farm
25
+ config.include MyExtras
26
+ # config.predicate_matchers[:swim] = :can_swim?
27
+
28
+ config.mock_with :mocha
29
+ end
30
+
31
+ class PhraseMatcher
32
+ def initialize(string)
33
+ @string = string
34
+ @pattern = /\b#{string}\b/
35
+ end
36
+
37
+ def matches?(actual)
38
+ @actual = actual.to_s
39
+ @actual =~ @pattern
40
+ end
41
+
42
+ def failure_message
43
+ "expected #{@actual.inspect} to contain phrase #{@string.inspect}"
44
+ end
45
+
46
+ def negative_failure_message
47
+ "expected #{@actual.inspect} not to contain phrase #{@string.inspect}"
48
+ end
49
+ end
50
+
51
+ class DeprecationMatcher
52
+ def initialize
53
+ @old_behavior = WillPaginate::Deprecation.behavior
54
+ @messages = []
55
+ WillPaginate::Deprecation.behavior = lambda { |message, callstack|
56
+ @messages << message
57
+ }
58
+ end
59
+
60
+ def matches?(block)
61
+ block.call
62
+ !@messages.empty?
63
+ ensure
64
+ WillPaginate::Deprecation.behavior = @old_behavior
65
+ end
66
+
67
+ def failure_message
68
+ "expected block to raise a deprecation warning"
69
+ end
70
+
71
+ def negative_failure_message
72
+ "expected block not to raise deprecation warnings, #{@messages.size} raised"
73
+ end
74
+ end
data/spec/tasks.rake ADDED
@@ -0,0 +1,60 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ spec_opts = 'spec/spec.opts'
4
+
5
+ desc 'Run framework-agnostic specs'
6
+ Spec::Rake::SpecTask.new(:spec) do |t|
7
+ t.libs << 'spec'
8
+ t.spec_opts = ['--options', spec_opts]
9
+ t.spec_files = FileList.new('spec/**/*_spec.rb') do |files|
10
+ files.exclude(/\b(active_record|active_resource|action_view|data_mapper|sequel)_/)
11
+ end
12
+ end
13
+
14
+ namespace :spec do
15
+ desc 'Run specs for core, ActiveRecord and ActionView'
16
+ Spec::Rake::SpecTask.new(:rails) do |t|
17
+ t.libs << 'spec'
18
+ t.spec_opts = ['--options', spec_opts]
19
+ t.spec_files = FileList.new('spec/**/*_spec.rb') do |files|
20
+ files.exclude(/\b(data_mapper|sequel)_/)
21
+ end
22
+ end
23
+
24
+ desc 'Run specs for DataMapper'
25
+ Spec::Rake::SpecTask.new(:datamapper) do |t|
26
+ t.libs << 'spec'
27
+ t.spec_opts = ['--options', spec_opts]
28
+ t.spec_files = FileList.new('spec/finders_spec.rb', 'spec/finders/data_mapper_spec.rb')
29
+ end
30
+
31
+ desc 'Run specs for Sequel'
32
+ Spec::Rake::SpecTask.new(:sequel) do |t|
33
+ t.libs << 'spec'
34
+ t.spec_opts = ['--options', spec_opts]
35
+ t.spec_files = FileList.new('spec/finders_spec.rb', 'spec/finders/sequel_spec.rb')
36
+ end
37
+
38
+ desc 'Analyze spec coverage with RCov'
39
+ Spec::Rake::SpecTask.new(:rcov) do |t|
40
+ t.libs << 'spec'
41
+ t.spec_opts = ['--options', spec_opts]
42
+ t.rcov = true
43
+ t.rcov_opts = lambda do
44
+ IO.readlines('spec/rcov.opts').map { |l| l.chomp.split(" ") }.flatten
45
+ end
46
+ end
47
+
48
+ desc 'Print Specdoc for all specs'
49
+ Spec::Rake::SpecTask.new(:doc) do |t|
50
+ t.libs << 'spec'
51
+ t.spec_opts = ['--format', 'specdoc', '--dry-run']
52
+ end
53
+
54
+ desc 'Generate HTML report'
55
+ Spec::Rake::SpecTask.new(:html) do |t|
56
+ t.libs << 'spec'
57
+ t.spec_opts = ['--format', 'html:doc/spec_results.html', '--diff']
58
+ t.fail_on_error = false
59
+ end
60
+ end