From d6e775c9cc7db1ff57fe3daf316c8343ad38accb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohnic=CC=81?= Date: Sat, 17 Sep 2011 15:10:34 +0200 Subject: [PATCH] deprecate renderer, previous/next_label global settings with pagination_options Renderer shouldn't be set globally because of mounted apps compatibility, and previous/next_label in Rails should be customized with i18n rather than editing pagination_options. --- lib/will_paginate/deprecation.rb | 55 +++++++++++++++++++ lib/will_paginate/view_helpers.rb | 8 ++- spec/spec_helper.rb | 56 +++++++++++++------- spec/view_helpers/base_spec.rb | 14 +++++ spec/view_helpers/link_renderer_base_spec.rb | 10 +++- 5 files changed, 123 insertions(+), 20 deletions(-) create mode 100644 lib/will_paginate/deprecation.rb diff --git a/lib/will_paginate/deprecation.rb b/lib/will_paginate/deprecation.rb new file mode 100644 index 000000000..aa66e6a8e --- /dev/null +++ b/lib/will_paginate/deprecation.rb @@ -0,0 +1,55 @@ +module WillPaginate::Deprecation + class << self + def warn(message, stack = caller) + offending_line = origin_of_call(stack) + full_message = "DEPRECATION WARNING: #{message} (called from #{offending_line})" + logger = rails_logger || Kernel + logger.warn full_message + end + + private + + def rails_logger + defined?(Rails) && Rails.logger + end + + def origin_of_call(stack) + lib_root = File.expand_path('../../..', __FILE__) + stack.find { |line| line.index(lib_root) != 0 } || stack.first + end + end + + class Hash < ::Hash + def initialize(values = {}) + super() + update values + @deprecated = {} + end + + def []=(key, value) + check_deprecated(key, value) + super + end + + def deprecate_key(*keys) + message = block_given? ? Proc.new : keys.pop + Array(keys).each { |key| @deprecated[key] = message } + end + + def merge(another) + to_hash.update(another) + end + + def to_hash + ::Hash.new.update(self) + end + + private + + def check_deprecated(key, value) + if msg = @deprecated[key] and (!msg.respond_to?(:call) or (msg = msg.call(key, value))) + WillPaginate::Deprecation.warn(msg) + end + end + end +end diff --git a/lib/will_paginate/view_helpers.rb b/lib/will_paginate/view_helpers.rb index 8bc54b8ea..9e2210306 100644 --- a/lib/will_paginate/view_helpers.rb +++ b/lib/will_paginate/view_helpers.rb @@ -1,6 +1,7 @@ # encoding: utf-8 require 'will_paginate/core_ext' require 'will_paginate/i18n' +require 'will_paginate/deprecation' module WillPaginate # = Will Paginate view helpers @@ -19,7 +20,7 @@ class << self end # default view options - self.pagination_options = { + self.pagination_options = Deprecation::Hash.new \ :class => 'pagination', :previous_label => nil, :next_label => nil, @@ -30,7 +31,12 @@ class << self :params => nil, :page_links => true, :container => true + + label_deprecation = Proc.new { |key, value| + "set the 'will_paginate.#{key}' key in your i18n locale instead of editing pagination_options" if defined? Rails } + pagination_options.deprecate_key(:previous_label, :next_label, &label_deprecation) + pagination_options.deprecate_key(:renderer) { |key| "pagination_options[#{key.inspect}] shouldn't be set globally" } include WillPaginate::I18n diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3b48b28d2..9879166eb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,26 +6,18 @@ # no debugger available end -module MyExtras - protected - - def include_phrase(string) - PhraseMatcher.new(string) - end +RSpec.configure do |config| + config.include Module.new { + protected - def collection(params = {}) - if params[:total_pages] - params[:per_page] = 1 - params[:total_entries] = params[:total_pages] + def include_phrase(string) + PhraseMatcher.new(string) end - WillPaginate::Collection.new(params[:page] || 1, params[:per_page] || 30, params[:total_entries]) - end -end -RSpec.configure do |config| - # config.include My::Pony, My::Horse, :type => :farm - config.include MyExtras - # config.predicate_matchers[:swim] = :can_swim? + def have_deprecation(msg) + DeprecationMatcher.new(msg) + end + } config.mock_with :mocha end @@ -33,7 +25,7 @@ def collection(params = {}) class PhraseMatcher def initialize(string) @string = string - @pattern = /\b#{string}\b/ + @pattern = /\b#{Regexp.escape string}\b/ end def matches?(actual) @@ -49,3 +41,31 @@ def negative_failure_message "expected #{@actual.inspect} not to contain phrase #{@string.inspect}" end end + +require 'stringio' + +class DeprecationMatcher + def initialize(message) + @message = message + end + + def matches?(block) + @actual = hijack_stderr(&block) + PhraseMatcher.new("DEPRECATION WARNING: #{@message}").matches?(@actual) + end + + def failure_message + "expected deprecation warning #{@message.inspect}, got #{@actual.inspect}" + end + + private + + def hijack_stderr + err = $stderr + $stderr = StringIO.new + yield + $stderr.string.rstrip + ensure + $stderr = err + end +end diff --git a/spec/view_helpers/base_spec.rb b/spec/view_helpers/base_spec.rb index 57236eab6..77542bd34 100644 --- a/spec/view_helpers/base_spec.rb +++ b/spec/view_helpers/base_spec.rb @@ -33,6 +33,20 @@ will_paginate(collection).should be_nil end end + + describe "pagination_options" do + let(:pagination_options) { WillPaginate::ViewHelpers.pagination_options } + + it "deprecates setting :renderer" do + begin + lambda { + pagination_options[:renderer] = 'test' + }.should have_deprecation("pagination_options[:renderer] shouldn't be set") + ensure + pagination_options.delete :renderer + end + end + end describe "page_entries_info" do before :all do diff --git a/spec/view_helpers/link_renderer_base_spec.rb b/spec/view_helpers/link_renderer_base_spec.rb index 81f0ff668..cdf5f9bd1 100644 --- a/spec/view_helpers/link_renderer_base_spec.rb +++ b/spec/view_helpers/link_renderer_base_spec.rb @@ -71,7 +71,15 @@ def showing_pages(*pages) end protected - + + def collection(params = {}) + if params[:total_pages] + params[:per_page] = 1 + params[:total_entries] = params[:total_pages] + end + WillPaginate::Collection.new(params[:page] || 1, params[:per_page] || 30, params[:total_entries]) + end + def prepare(collection_options, options = {}) @renderer.prepare(collection(collection_options), options) end