has_scope 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b023c16c60cb24ca941d55d69be48713962b661a68b92f32a0af40bf952686ea
4
- data.tar.gz: 45b61de129e41764aa08bbcbd17c1287a83542d2171cc69ad8452a6da4f22085
3
+ metadata.gz: c24a5ed875375fb5da93be3f90ac863b0c72d676ecc1fe0959933924452b043d
4
+ data.tar.gz: 2f8aacdef384ce75c7fc2e4b4b697ba62e68293deeac5754597d10dffc044052
5
5
  SHA512:
6
- metadata.gz: 35392817be681d709e897972514b215be8860f2b00216745cba37931c77aa27dbf1fc13f56b1cbc775210c266de902b4a79023a8637b8736089669543ee73b9e
7
- data.tar.gz: 8ce1d74c2cfb9a76d4c7a60752aee0d86ede19ba778f7e28983eb77b446162d60091ee7ff3437025b0c841bb75e7f34de8dc4fddfdbd99331dd66707d28b7af5
6
+ metadata.gz: 9541480b36218fb3c1b9b7c48a3297411c8875ec47bb1735b6b394127c02ad90010d79787931c0d0154d662b40f4c236627710ca7b2fa01edb7513f27e043fb9
7
+ data.tar.gz: 5927fbd54e4a019b2d9f9fd7f7a60cf929fd46eac8f15c4c0e8cdb0cab2cac80a2b432e4398a70013d6bf88a519df60d2b6f571fb4f7f5db2d141292762b9eba
data/README.md CHANGED
@@ -1,16 +1,15 @@
1
1
  ## HasScope
2
2
 
3
3
  [![Gem Version](https://fury-badge.herokuapp.com/rb/has_scope.svg)](http://badge.fury.io/rb/has_scope)
4
- [![Build Status](https://api.travis-ci.org/plataformatec/has_scope.svg?branch=master)](http://travis-ci.org/plataformatec/has_scope)
5
- [![Code Climate](https://codeclimate.com/github/plataformatec/has_scope.svg)](https://codeclimate.com/github/plataformatec/has_scope)
4
+ [![Code Climate](https://codeclimate.com/github/heartcombo/has_scope.svg)](https://codeclimate.com/github/heartcombo/has_scope)
6
5
 
7
6
  Has scope allows you to map incoming controller parameters to named scopes in your resources.
8
7
  Imagine the following model called graduations:
9
8
 
10
9
  ```ruby
11
10
  class Graduation < ActiveRecord::Base
12
- scope :featured, -> { where(:featured => true) }
13
- scope :by_degree, -> degree { where(:degree => degree) }
11
+ scope :featured, -> { where(featured: true) }
12
+ scope :by_degree, -> degree { where(degree: degree) }
14
13
  scope :by_period, -> started_at, ended_at { where("started_at = ? AND ended_at = ?", started_at, ended_at) }
15
14
  end
16
15
  ```
@@ -19,7 +18,7 @@ You can use those named scopes as filters by declaring them on your controller:
19
18
 
20
19
  ```ruby
21
20
  class GraduationsController < ApplicationController
22
- has_scope :featured, :type => :boolean
21
+ has_scope :featured, type: :boolean
23
22
  has_scope :by_degree
24
23
  end
25
24
  ```
@@ -28,9 +27,9 @@ Now, if you want to apply them to an specific resource, you just need to call `a
28
27
 
29
28
  ```ruby
30
29
  class GraduationsController < ApplicationController
31
- has_scope :featured, :type => :boolean
30
+ has_scope :featured, type: :boolean
32
31
  has_scope :by_degree
33
- has_scope :by_period, :using => [:started_at, :ended_at], :type => :hash
32
+ has_scope :by_period, using: %i[started_at ended_at], type: :hash
34
33
 
35
34
  def index
36
35
  @graduations = apply_scopes(Graduation).all
@@ -55,7 +54,7 @@ Then for each request:
55
54
  ```
56
55
 
57
56
  You can retrieve all the scopes applied in one action with `current_scopes` method.
58
- In the last case, it would return: { :featured => true, :by_degree => "phd" }.
57
+ In the last case, it would return: `{ featured: true, by_degree: 'phd' }`.
59
58
 
60
59
  ## Installation
61
60
 
@@ -83,23 +82,23 @@ HasScope supports several options:
83
82
 
84
83
  * `:using` - The subkeys to be used as args when type is a hash.
85
84
 
86
- * `:if` - Specifies a method, proc or string to call to determine if the scope should apply.
85
+ * `:in` - A shortcut for combining the `:using` option with nested hashes.
86
+
87
+ * `:if` - Specifies a method or proc to call to determine if the scope should apply. Passing a string is deprecated and it will be removed in a future version.
87
88
 
88
- * `:unless` - Specifies a method, proc or string to call to determine if the scope should NOT apply.
89
+ * `:unless` - Specifies a method or proc to call to determine if the scope should NOT apply. Passing a string is deprecated and it will be removed in a future version.
89
90
 
90
91
  * `:default` - Default value for the scope. Whenever supplied the scope is always called.
91
92
 
92
93
  * `:allow_blank` - Blank values are not sent to scopes by default. Set to true to overwrite.
93
94
 
94
- * `:in` - A shortcut for combining the `:using` option with nested hashes.
95
-
96
95
  ## Boolean usage
97
96
 
98
97
  If `type: :boolean` is set it just calls the named scope, without any arguments, when parameter
99
98
  is set to a "true" value. `'true'` and `'1'` are parsed as `true`, everything else as `false`.
100
99
 
101
- When boolean scope is set up with `allow_blank: true`, it will call the scope
102
- with the value as usual scope.
100
+ When boolean scope is set up with `allow_blank: true`, it will call the scope with the value as
101
+ any usual scope.
103
102
 
104
103
  ```ruby
105
104
  has_scope :visible, type: :boolean
@@ -110,6 +109,11 @@ scope :visible, -> { where(visible: true) }
110
109
  scope :active, ->(value = true) { where(active: value) }
111
110
  ```
112
111
 
112
+ _Note_: it is not possible to apply a boolean scope with just the query param being present, e.g.
113
+ `?active`, that's not considered a "true" value (the param value will be `nil`), and thus the
114
+ scope will be called with `false` as argument. In order for the scope to receive a `true` argument
115
+ the param value must be set to one of the "true" values above, e.g. `?active=true` or `?active=1`.
116
+
113
117
  ## Block usage
114
118
 
115
119
  `has_scope` also accepts a block. The controller, current scope and value are yielded
@@ -118,7 +122,7 @@ need to manipulate the given value:
118
122
 
119
123
  ```ruby
120
124
  has_scope :category do |controller, scope, value|
121
- value != "all" ? scope.by_category(value) : scope
125
+  value != 'all' ? scope.by_category(value) : scope
122
126
  end
123
127
  ```
124
128
 
@@ -126,7 +130,7 @@ When used with booleans without `:allow_blank`, it just receives two arguments
126
130
  and is just invoked if true is given:
127
131
 
128
132
  ```ruby
129
- has_scope :not_voted_by_me, :type => :boolean do |controller, scope|
133
+ has_scope :not_voted_by_me, type: :boolean do |controller, scope|
130
134
  scope.not_voted_by(controller.current_user.id)
131
135
  end
132
136
  ```
@@ -159,10 +163,22 @@ scope :available, ->(*) { where(blocked: false) }
159
163
  This will allow usual users to get only available items, but admins will
160
164
  be able to access blocked items too.
161
165
 
166
+ ## Check which scopes have been applied
167
+
168
+ To check which scopes have been applied, you can call `current_scopes` from the controller or view.
169
+ This returns a hash with the scope name as the key and the scope value as the value.
170
+
171
+ For example, if a boolean `:active` scope has been applied, `current_scopes` will return `{ active: true }`.
172
+
173
+ ## Supported Ruby / Rails versions
174
+
175
+ We intend to maintain support for all Ruby / Rails versions that haven't reached end-of-life.
176
+
177
+ For more information about specific versions please check [Ruby](https://www.ruby-lang.org/en/downloads/branches/)
178
+ and [Rails](https://guides.rubyonrails.org/maintenance_policy.html) maintenance policies, and our test matrix.
179
+
162
180
  ## Bugs and Feedback
163
181
 
164
182
  If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
165
183
 
166
- http://github.com/plataformatec/has_scope/issues
167
-
168
- MIT License. Copyright 2009-2016 Plataformatec. http://blog.plataformatec.com.br
184
+ MIT License. Copyright 2009-2019 Plataformatec. http://blog.plataformatec.com.br
data/lib/has_scope.rb CHANGED
@@ -1,17 +1,20 @@
1
+ require 'active_support'
2
+ require 'action_controller'
3
+
1
4
  module HasScope
2
5
  TRUE_VALUES = ["true", true, "1", 1]
3
6
 
4
7
  ALLOWED_TYPES = {
5
- :array => [[ Array ]],
6
- :hash => [[Hash, ActionController::Parameters]],
7
- :boolean => [[ Object ], -> v { TRUE_VALUES.include?(v) }],
8
- :default => [[ String, Numeric ]],
8
+ array: [[ Array ]],
9
+ hash: [[ Hash, ActionController::Parameters ]],
10
+ boolean: [[ Object ], -> v { TRUE_VALUES.include?(v) }],
11
+ default: [[ String, Numeric ]],
9
12
  }
10
13
 
11
14
  def self.included(base)
12
15
  base.class_eval do
13
16
  extend ClassMethods
14
- class_attribute :scopes_configuration, :instance_writer => false
17
+ class_attribute :scopes_configuration, instance_writer: false
15
18
  self.scopes_configuration = {}
16
19
  end
17
20
  end
@@ -36,6 +39,8 @@ module HasScope
36
39
  # * <tt>:using</tt> - If type is a hash, you can provide :using to convert the hash to
37
40
  # a named scope call with several arguments.
38
41
  #
42
+ # * <tt>:in</tt> - A shortcut for combining the `:using` option with nested hashes.
43
+ #
39
44
  # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
40
45
  # if the scope should apply
41
46
  #
@@ -57,7 +62,7 @@ module HasScope
57
62
  # value != "all" ? scope.by_category(value) : scope
58
63
  # end
59
64
  #
60
- # has_scope :not_voted_by_me, :type => :boolean do |controller, scope|
65
+ # has_scope :not_voted_by_me, type: :boolean do |controller, scope|
61
66
  # scope.not_voted_by(controller.current_user.id)
62
67
  # end
63
68
  #
@@ -69,6 +74,10 @@ module HasScope
69
74
  if options.key?(:in)
70
75
  options[:as] = options[:in]
71
76
  options[:using] = scopes
77
+
78
+ if options.key?(:default) && !options[:default].is_a?(Hash)
79
+ options[:default] = scopes.each_with_object({}) { |scope, hash| hash[scope] = options[:default] }
80
+ end
72
81
  end
73
82
 
74
83
  if options.key?(:using)
@@ -87,7 +96,7 @@ module HasScope
87
96
  self.scopes_configuration = scopes_configuration.dup
88
97
 
89
98
  scopes.each do |scope|
90
- scopes_configuration[scope] ||= { :as => scope, :type => :default, :block => block }
99
+ scopes_configuration[scope] ||= { as: scope, type: :default, block: block }
91
100
  scopes_configuration[scope] = self.scopes_configuration[scope].merge(options)
92
101
  end
93
102
  end
@@ -97,16 +106,16 @@ module HasScope
97
106
 
98
107
  # Receives an object where scopes will be applied to.
99
108
  #
100
- # class GraduationsController < InheritedResources::Base
101
- # has_scope :featured, :type => true, :only => :index
102
- # has_scope :by_degree, :only => :index
109
+ # class GraduationsController < ApplicationController
110
+ # has_scope :featured, type: true, only: :index
111
+ # has_scope :by_degree, only: :index
103
112
  #
104
113
  # def index
105
114
  # @graduations = apply_scopes(Graduation).all
106
115
  # end
107
116
  # end
108
117
  #
109
- def apply_scopes(target, hash=params)
118
+ def apply_scopes(target, hash = params)
110
119
  scopes_configuration.each do |scope, options|
111
120
  next unless apply_scope_to_action?(options)
112
121
  key = options[:as]
@@ -120,12 +129,20 @@ module HasScope
120
129
  end
121
130
  end
122
131
 
123
- value = parse_value(options[:type], key, value)
132
+ value = parse_value(options[:type], value)
124
133
  value = normalize_blanks(value)
125
134
 
126
- if call_scope && (value.present? || options[:allow_blank])
135
+ if value && options.key?(:using)
136
+ scope_value = value.values_at(*options[:using])
137
+ call_scope &&= scope_value.all?(&:present?) || options[:allow_blank]
138
+ else
139
+ scope_value = value
140
+ call_scope &&= value.present? || options[:allow_blank]
141
+ end
142
+
143
+ if call_scope
127
144
  current_scopes[key] = value
128
- target = call_scope_by_type(options[:type], scope, target, value, options)
145
+ target = call_scope_by_type(options[:type], scope, target, scope_value, options)
129
146
  end
130
147
  end
131
148
 
@@ -133,7 +150,7 @@ module HasScope
133
150
  end
134
151
 
135
152
  # Set the real value for the current scope if type check.
136
- def parse_value(type, key, value) #:nodoc:
153
+ def parse_value(type, value) #:nodoc:
137
154
  klasses, parser = ALLOWED_TYPES[type]
138
155
  if klasses.any? { |klass| value.is_a?(klass) }
139
156
  parser ? parser.call(value) : value
@@ -160,8 +177,7 @@ module HasScope
160
177
 
161
178
  if type == :boolean && !options[:allow_blank]
162
179
  block ? block.call(self, target) : target.send(scope)
163
- elsif value && options.key?(:using)
164
- value = value.values_at(*options[:using])
180
+ elsif options.key?(:using)
165
181
  block ? block.call(self, target, value) : target.send(scope, *value)
166
182
  else
167
183
  block ? block.call(self, target, value) : target.send(scope, value)
@@ -185,6 +201,11 @@ module HasScope
185
201
  def applicable?(string_proc_or_symbol, expected) #:nodoc:
186
202
  case string_proc_or_symbol
187
203
  when String
204
+ ActiveSupport::Deprecation.warn <<-DEPRECATION.squish
205
+ [HasScope] Passing a string to determine if the scope should be applied
206
+ is deprecated and it will be removed in a future version of HasScope.
207
+ DEPRECATION
208
+
188
209
  eval(string_proc_or_symbol) == expected
189
210
  when Proc
190
211
  string_proc_or_symbol.call(self) == expected
@@ -1,3 +1,3 @@
1
1
  module HasScope
2
- VERSION = "0.7.2"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -5,21 +5,30 @@ HasScope::ALLOWED_TYPES[:date] = [[String], -> v { Date.parse(v) rescue nil }]
5
5
  class Tree; end
6
6
 
7
7
  class TreesController < ApplicationController
8
- has_scope :color, :unless => :show_all_colors?
9
- has_scope :only_tall, :type => :boolean, :only => :index, :if => :restrict_to_only_tall_trees?
10
- has_scope :shadown_range, :default => 10, :except => [ :index, :show, :new ]
11
- has_scope :root_type, :as => :root, :allow_blank => true
12
- has_scope :planted_before, :default => proc { Date.today }
13
- has_scope :planted_after, :type => :date
14
- has_scope :calculate_height, :default => proc {|c| c.session[:height] || 20 }, :only => :new
15
- has_scope :paginate, :type => :hash
16
- has_scope :args_paginate, :type => :hash, :using => [:page, :per_page]
17
- has_scope :categories, :type => :array
18
- has_scope :title, :in => :q
19
- has_scope :content, :in => :q
20
- has_scope :conifer, type: :boolean, :allow_blank => true
21
-
22
- has_scope :only_short, :type => :boolean do |controller, scope|
8
+ has_scope :color, unless: :show_all_colors?
9
+ has_scope :only_tall, type: :boolean, only: :index, if: :restrict_to_only_tall_trees?
10
+ has_scope :shadown_range, default: 10, except: [ :index, :show, :new ]
11
+ has_scope :root_type, as: :root, allow_blank: true
12
+ has_scope :planted_before, default: proc { Date.today }
13
+ has_scope :planted_after, type: :date
14
+ has_scope :calculate_height, default: proc { |c| c.session[:height] || 20 }, only: :new
15
+ has_scope :paginate, type: :hash
16
+ has_scope :paginate_blank, type: :hash, allow_blank: true
17
+ has_scope :paginate_default, type: :hash, default: { page: 1, per_page: 10 }, only: :edit
18
+ has_scope :args_paginate, type: :hash, using: [:page, :per_page]
19
+ has_scope :args_paginate_blank, using: [:page, :per_page], allow_blank: true
20
+ has_scope :args_paginate_default, using: [:page, :per_page], default: { page: 1, per_page: 10 }, only: :edit
21
+ has_scope :categories, type: :array
22
+ has_scope :title, in: :q
23
+ has_scope :content, in: :q
24
+ has_scope :metadata, in: :q
25
+ has_scope :metadata_blank, in: :q, allow_blank: true
26
+ has_scope :metadata_default, in: :q, default: "default", only: :edit
27
+ has_scope :conifer, type: :boolean, allow_blank: true
28
+ has_scope :eval_plant, if: "params[:eval_plant].present?", unless: "params[:skip_eval_plant].present?"
29
+ has_scope :proc_plant, if: -> c { c.params[:proc_plant].present? }, unless: -> c { c.params[:skip_proc_plant].present? }
30
+
31
+ has_scope :only_short, type: :boolean do |controller, scope|
23
32
  scope.only_really_short!(controller.object_id)
24
33
  end
25
34
 
@@ -42,6 +51,16 @@ class TreesController < ApplicationController
42
51
  alias :edit :show
43
52
 
44
53
  protected
54
+ # Silence deprecations in the test suite, except for the actual deprecated String if/unless options.
55
+ # TODO: remove with the deprecation.
56
+ def apply_scopes(*)
57
+ if params[:eval_plant]
58
+ super
59
+ else
60
+ ActiveSupport::Deprecation.silence { super }
61
+ end
62
+ end
63
+
45
64
  def restrict_to_only_tall_trees?
46
65
  true
47
66
  end
@@ -50,20 +69,13 @@ class TreesController < ApplicationController
50
69
  false
51
70
  end
52
71
 
53
- if ActionPack::VERSION::MAJOR == 5
54
- def default_render
55
- render body: action_name
56
- end
57
- else
58
- # TODO: Remove this when we only support Rails 5.
59
- def default_render
60
- render text: action_name
61
- end
72
+ def default_render
73
+ render body: action_name
62
74
  end
63
75
  end
64
76
 
65
77
  class BonsaisController < TreesController
66
- has_scope :categories, :if => :categories?
78
+ has_scope :categories, if: :categories?
67
79
 
68
80
  protected
69
81
  def categories?
@@ -77,15 +89,19 @@ class HasScopeTest < ActionController::TestCase
77
89
  def test_boolean_scope_is_called_when_boolean_param_is_true
78
90
  Tree.expects(:only_tall).with().returns(Tree).in_sequence
79
91
  Tree.expects(:all).returns([mock_tree]).in_sequence
80
- get :index, :only_tall => 'true'
92
+
93
+ get :index, params: { only_tall: 'true' }
94
+
81
95
  assert_equal([mock_tree], assigns(:@trees))
82
- assert_equal({ :only_tall => true }, current_scopes)
96
+ assert_equal({ only_tall: true }, current_scopes)
83
97
  end
84
98
 
85
99
  def test_boolean_scope_is_not_called_when_boolean_param_is_false
86
100
  Tree.expects(:only_tall).never
87
101
  Tree.expects(:all).returns([mock_tree])
88
- get :index, :only_tall => 'false'
102
+
103
+ get :index, params: { only_tall: 'false' }
104
+
89
105
  assert_equal([mock_tree], assigns(:@trees))
90
106
  assert_equal({ }, current_scopes)
91
107
  end
@@ -93,23 +109,29 @@ class HasScopeTest < ActionController::TestCase
93
109
  def test_boolean_scope_with_allow_blank_is_called_when_boolean_param_is_true
94
110
  Tree.expects(:conifer).with(true).returns(Tree).in_sequence
95
111
  Tree.expects(:all).returns([mock_tree]).in_sequence
96
- get :index, :conifer => 'true'
112
+
113
+ get :index, params: { conifer: 'true' }
114
+
97
115
  assert_equal([mock_tree], assigns(:@trees))
98
- assert_equal({ :conifer => true }, current_scopes)
116
+ assert_equal({ conifer: true }, current_scopes)
99
117
  end
100
118
 
101
119
  def test_boolean_scope_with_allow_blank_is_called_when_boolean_param_is_false
102
120
  Tree.expects(:conifer).with(false).returns(Tree).in_sequence
103
121
  Tree.expects(:all).returns([mock_tree]).in_sequence
104
- get :index, :conifer => 'not_true'
122
+
123
+ get :index, params: { conifer: 'not_true' }
124
+
105
125
  assert_equal([mock_tree], assigns(:@trees))
106
- assert_equal({ :conifer => false }, current_scopes)
126
+ assert_equal({ conifer: false }, current_scopes)
107
127
  end
108
128
 
109
129
  def test_boolean_scope_with_allow_blank_is_not_called_when_boolean_param_is_not_present
110
130
  Tree.expects(:conifer).never
111
131
  Tree.expects(:all).returns([mock_tree])
132
+
112
133
  get :index
134
+
113
135
  assert_equal([mock_tree], assigns(:@trees))
114
136
  assert_equal({ }, current_scopes)
115
137
  end
@@ -117,7 +139,9 @@ class HasScopeTest < ActionController::TestCase
117
139
  def test_scope_is_called_only_on_index
118
140
  Tree.expects(:only_tall).never
119
141
  Tree.expects(:find).with('42').returns(mock_tree)
120
- get :show, :only_tall => 'true', :id => '42'
142
+
143
+ get :show, params: { only_tall: 'true', id: '42' }
144
+
121
145
  assert_equal(mock_tree, assigns(:@tree))
122
146
  assert_equal({ }, current_scopes)
123
147
  end
@@ -126,7 +150,9 @@ class HasScopeTest < ActionController::TestCase
126
150
  @controller.stubs(:restrict_to_only_tall_trees?).returns(false)
127
151
  Tree.expects(:only_tall).never
128
152
  Tree.expects(:all).returns([mock_tree])
129
- get :index, :only_tall => 'true'
153
+
154
+ get :index, params: { only_tall: 'true' }
155
+
130
156
  assert_equal([mock_tree], assigns(:@trees))
131
157
  assert_equal({ }, current_scopes)
132
158
  end
@@ -135,15 +161,41 @@ class HasScopeTest < ActionController::TestCase
135
161
  @controller.stubs(:show_all_colors?).returns(true)
136
162
  Tree.expects(:color).never
137
163
  Tree.expects(:all).returns([mock_tree])
138
- get :index, :color => 'blue'
164
+
165
+ get :index, params: { color: 'blue' }
166
+
139
167
  assert_equal([mock_tree], assigns(:@trees))
140
168
  assert_equal({ }, current_scopes)
141
169
  end
142
170
 
171
+ def test_scope_with_eval_string_if_and_unless_options_is_deprecated
172
+ Tree.expects(:eval_plant).with('value').returns(Tree)
173
+ Tree.expects(:all).returns([mock_tree])
174
+
175
+ assert_deprecated(/Passing a string to determine if the scope should be applied is deprecated/) do
176
+ get :index, params: { eval_plant: 'value', skip_eval_plant: nil }
177
+ end
178
+
179
+ assert_equal([mock_tree], assigns(:@trees))
180
+ assert_equal({ eval_plant: 'value' }, current_scopes)
181
+ end
182
+
183
+ def test_scope_with_proc_if_and_unless_options
184
+ Tree.expects(:proc_plant).with('value').returns(Tree)
185
+ Tree.expects(:all).returns([mock_tree])
186
+
187
+ get :index, params: { proc_plant: 'value', skip_proc_plant: nil }
188
+
189
+ assert_equal([mock_tree], assigns(:@trees))
190
+ assert_equal({ proc_plant: 'value' }, current_scopes)
191
+ end
192
+
143
193
  def test_scope_is_called_except_on_index
144
194
  Tree.expects(:shadown_range).never
145
195
  Tree.expects(:all).returns([mock_tree])
146
- get :index, :shadown_range => 20
196
+
197
+ get :index, params: { shadown_range: 20 }
198
+
147
199
  assert_equal([mock_tree], assigns(:@trees))
148
200
  assert_equal({ }, current_scopes)
149
201
  end
@@ -151,15 +203,19 @@ class HasScopeTest < ActionController::TestCase
151
203
  def test_scope_is_called_with_arguments
152
204
  Tree.expects(:color).with('blue').returns(Tree).in_sequence
153
205
  Tree.expects(:all).returns([mock_tree]).in_sequence
154
- get :index, :color => 'blue'
206
+
207
+ get :index, params: { color: 'blue' }
208
+
155
209
  assert_equal([mock_tree], assigns(:@trees))
156
- assert_equal({ :color => 'blue' }, current_scopes)
210
+ assert_equal({ color: 'blue' }, current_scopes)
157
211
  end
158
212
 
159
213
  def test_scope_is_not_called_if_blank
160
214
  Tree.expects(:color).never
161
215
  Tree.expects(:all).returns([mock_tree]).in_sequence
162
- get :index, :color => ''
216
+
217
+ get :index, params: { color: '' }
218
+
163
219
  assert_equal([mock_tree], assigns(:@trees))
164
220
  assert_equal({ }, current_scopes)
165
221
  end
@@ -167,25 +223,31 @@ class HasScopeTest < ActionController::TestCase
167
223
  def test_scope_is_called_when_blank_if_allow_blank_is_given
168
224
  Tree.expects(:root_type).with('').returns(Tree)
169
225
  Tree.expects(:all).returns([mock_tree]).in_sequence
170
- get :index, :root => ''
226
+
227
+ get :index, params: { root: '' }
228
+
171
229
  assert_equal([mock_tree], assigns(:@trees))
172
- assert_equal({ :root => '' }, current_scopes)
230
+ assert_equal({ root: '' }, current_scopes)
173
231
  end
174
232
 
175
233
  def test_multiple_scopes_are_called
176
234
  Tree.expects(:only_tall).with().returns(Tree)
177
235
  Tree.expects(:color).with('blue').returns(Tree)
178
236
  Tree.expects(:all).returns([mock_tree])
179
- get :index, :color => 'blue', :only_tall => 'true'
237
+
238
+ get :index, params: { color: 'blue', only_tall: 'true' }
239
+
180
240
  assert_equal([mock_tree], assigns(:@trees))
181
- assert_equal({ :color => 'blue', :only_tall => true }, current_scopes)
241
+ assert_equal({ color: 'blue', only_tall: true }, current_scopes)
182
242
  end
183
243
 
184
244
  def test_scope_of_type_hash
185
245
  hash = { "page" => "1", "per_page" => "10" }
186
246
  Tree.expects(:paginate).with(hash).returns(Tree)
187
247
  Tree.expects(:all).returns([mock_tree])
188
- get :index, :paginate => hash
248
+
249
+ get :index, params: { paginate: hash }
250
+
189
251
  assert_equal([mock_tree], assigns(:@trees))
190
252
  assert_equal({ paginate: hash }, current_scopes)
191
253
  end
@@ -194,25 +256,53 @@ class HasScopeTest < ActionController::TestCase
194
256
  hash = { "page" => "1", "per_page" => "10" }
195
257
  Tree.expects(:args_paginate).with("1", "10").returns(Tree)
196
258
  Tree.expects(:all).returns([mock_tree])
197
- get :index, :args_paginate => hash
259
+
260
+ get :index, params: { args_paginate: hash }
261
+
198
262
  assert_equal([mock_tree], assigns(:@trees))
199
- assert_equal({ :args_paginate => hash }, current_scopes)
263
+ assert_equal({ args_paginate: hash }, current_scopes)
200
264
  end
201
265
 
202
266
  def test_hash_with_blank_values_is_ignored
203
267
  hash = { "page" => "", "per_page" => "" }
204
268
  Tree.expects(:paginate).never
205
269
  Tree.expects(:all).returns([mock_tree])
206
- get :index, :paginate => hash
270
+
271
+ get :index, params: { paginate: hash }
272
+
207
273
  assert_equal([mock_tree], assigns(:@trees))
208
274
  assert_equal({ }, current_scopes)
209
275
  end
210
276
 
277
+ def test_hash_with_blank_values_and_allow_blank_is_called
278
+ hash = { "page" => "", "per_page" => "" }
279
+ Tree.expects(:paginate_blank).with({}).returns(Tree)
280
+ Tree.expects(:all).returns([mock_tree])
281
+
282
+ get :index, params: { paginate_blank: hash }
283
+
284
+ assert_equal([mock_tree], assigns(:@trees))
285
+ assert_equal({ paginate_blank: {} }, current_scopes)
286
+ end
287
+
288
+ def test_hash_with_using_and_blank_values_and_allow_blank_is_called
289
+ hash = { "page" => "", "per_page" => "" }
290
+ Tree.expects(:args_paginate_blank).with(nil, nil).returns(Tree)
291
+ Tree.expects(:all).returns([mock_tree])
292
+
293
+ get :index, params: { args_paginate_blank: hash }
294
+
295
+ assert_equal([mock_tree], assigns(:@trees))
296
+ assert_equal({ args_paginate_blank: {} }, current_scopes)
297
+ end
298
+
211
299
  def test_nested_hash_with_blank_values_is_ignored
212
- hash = { "parent" => {"children" => ""} }
300
+ hash = { "parent" => { "children" => "" } }
213
301
  Tree.expects(:paginate).never
214
302
  Tree.expects(:all).returns([mock_tree])
215
- get :index, :paginate => hash
303
+
304
+ get :index, params: { paginate: hash }
305
+
216
306
  assert_equal([mock_tree], assigns(:@trees))
217
307
  assert_equal({ }, current_scopes)
218
308
  end
@@ -221,7 +311,9 @@ class HasScopeTest < ActionController::TestCase
221
311
  hash = { "parent" => [""] }
222
312
  Tree.expects(:paginate).never
223
313
  Tree.expects(:all).returns([mock_tree])
224
- get :index, :paginate => hash
314
+
315
+ get :index, params: { paginate: hash }
316
+
225
317
  assert_equal([mock_tree], assigns(:@trees))
226
318
  assert_equal({ }, current_scopes)
227
319
  end
@@ -230,99 +322,148 @@ class HasScopeTest < ActionController::TestCase
230
322
  array = %w(book kitchen sport)
231
323
  Tree.expects(:categories).with(array).returns(Tree)
232
324
  Tree.expects(:all).returns([mock_tree])
233
- get :index, :categories => array
325
+
326
+ get :index, params: { categories: array }
327
+
234
328
  assert_equal([mock_tree], assigns(:@trees))
235
- assert_equal({ :categories => array }, current_scopes)
329
+ assert_equal({ categories: array }, current_scopes)
236
330
  end
237
331
 
238
332
  def test_array_of_blank_values_is_ignored
239
333
  Tree.expects(:categories).never
240
334
  Tree.expects(:all).returns([mock_tree])
241
- get :index, :categories => [""]
335
+
336
+ get :index, params: { categories: [""] }
337
+
242
338
  assert_equal([mock_tree], assigns(:@trees))
243
339
  assert_equal({ }, current_scopes)
244
340
  end
245
341
 
246
342
  def test_scope_of_invalid_type_silently_fails
247
343
  Tree.expects(:all).returns([mock_tree])
248
- get :index, :paginate => "1"
344
+
345
+ get :index, params: { paginate: "1" }
346
+
249
347
  assert_equal([mock_tree], assigns(:@trees))
250
348
  assert_equal({ }, current_scopes)
251
349
  end
252
350
 
253
351
  def test_scope_is_called_with_default_value
254
352
  Tree.expects(:shadown_range).with(10).returns(Tree).in_sequence
353
+ Tree.expects(:paginate_default).with('page' => 1, 'per_page' => 10).returns(Tree).in_sequence
354
+ Tree.expects(:args_paginate_default).with(1, 10).returns(Tree).in_sequence
355
+ Tree.expects(:metadata_default).with('default').returns(Tree).in_sequence
255
356
  Tree.expects(:find).with('42').returns(mock_tree).in_sequence
256
- get :edit, :id => '42'
357
+
358
+ get :edit, params: { id: '42' }
359
+
257
360
  assert_equal(mock_tree, assigns(:@tree))
258
- assert_equal({ :shadown_range => 10 }, current_scopes)
361
+ assert_equal({
362
+ shadown_range: 10,
363
+ paginate_default: { 'page' => 1, 'per_page' => 10 },
364
+ args_paginate_default: { 'page' => 1, 'per_page' => 10 },
365
+ q: { 'metadata_default' => 'default' }
366
+ }, current_scopes)
259
367
  end
260
368
 
261
369
  def test_default_scope_value_can_be_overwritten
262
370
  Tree.expects(:shadown_range).with('20').returns(Tree).in_sequence
371
+ Tree.expects(:paginate_default).with('page' => '2', 'per_page' => '20').returns(Tree).in_sequence
372
+ Tree.expects(:args_paginate_default).with('3', '15').returns(Tree).in_sequence
373
+ Tree.expects(:metadata_blank).with(nil).returns(Tree).in_sequence
374
+ Tree.expects(:metadata_default).with('other').returns(Tree).in_sequence
263
375
  Tree.expects(:find).with('42').returns(mock_tree).in_sequence
264
- get :edit, :id => '42', :shadown_range => '20'
376
+
377
+ get :edit, params: {
378
+ id: '42',
379
+ shadown_range: '20',
380
+ paginate_default: { page: 2, per_page: 20 },
381
+ args_paginate_default: { page: 3, per_page: 15},
382
+ q: { metadata_default: 'other' }
383
+ }
384
+
265
385
  assert_equal(mock_tree, assigns(:@tree))
266
- assert_equal({ :shadown_range => '20' }, current_scopes)
386
+ assert_equal({
387
+ shadown_range: '20',
388
+ paginate_default: { 'page' => '2', 'per_page' => '20' },
389
+ args_paginate_default: { 'page' => '3', 'per_page' => '15' },
390
+ q: { 'metadata_default' => 'other' }
391
+ }, current_scopes)
267
392
  end
268
393
 
269
394
  def test_scope_with_different_key
270
395
  Tree.expects(:root_type).with('outside').returns(Tree).in_sequence
271
396
  Tree.expects(:find).with('42').returns(mock_tree).in_sequence
272
- get :show, :id => '42', :root => 'outside'
397
+
398
+ get :show, params: { id: '42', root: 'outside' }
399
+
273
400
  assert_equal(mock_tree, assigns(:@tree))
274
- assert_equal({ :root => 'outside' }, current_scopes)
401
+ assert_equal({ root: 'outside' }, current_scopes)
275
402
  end
276
403
 
277
404
  def test_scope_with_default_value_as_a_proc_without_argument
278
405
  Date.expects(:today).returns("today")
279
406
  Tree.expects(:planted_before).with("today").returns(Tree)
280
407
  Tree.expects(:all).returns([mock_tree])
408
+
281
409
  get :index
410
+
282
411
  assert_equal([mock_tree], assigns(:@trees))
283
- assert_equal({ :planted_before => "today" }, current_scopes)
412
+ assert_equal({ planted_before: "today" }, current_scopes)
284
413
  end
285
414
 
286
415
  def test_scope_with_default_value_as_proc_with_argument
287
416
  session[:height] = 100
288
417
  Tree.expects(:calculate_height).with(100).returns(Tree).in_sequence
289
418
  Tree.expects(:new).returns(mock_tree).in_sequence
419
+
290
420
  get :new
421
+
291
422
  assert_equal(mock_tree, assigns(:@tree))
292
- assert_equal({ :calculate_height => 100 }, current_scopes)
423
+ assert_equal({ calculate_height: 100 }, current_scopes)
293
424
  end
294
425
 
295
426
  def test_scope_with_custom_type
296
427
  parsed = Date.civil(2014,11,11)
297
428
  Tree.expects(:planted_after).with(parsed).returns(Tree)
298
429
  Tree.expects(:all).returns([mock_tree])
299
- get :index, :planted_after => "2014-11-11"
430
+
431
+ get :index, params: { planted_after: "2014-11-11" }
432
+
300
433
  assert_equal([mock_tree], assigns(:@trees))
301
- assert_equal({ :planted_after => parsed }, current_scopes)
434
+ assert_equal({ planted_after: parsed }, current_scopes)
302
435
  end
303
436
 
304
437
  def test_scope_with_boolean_block
305
438
  Tree.expects(:only_really_short!).with(@controller.object_id).returns(Tree)
306
439
  Tree.expects(:all).returns([mock_tree])
307
- get :index, :only_short => 'true'
440
+
441
+ get :index, params: { only_short: 'true' }
442
+
308
443
  assert_equal([mock_tree], assigns(:@trees))
309
- assert_equal({ :only_short => true }, current_scopes)
444
+ assert_equal({ only_short: true }, current_scopes)
310
445
  end
311
446
 
312
447
  def test_scope_with_other_block_types
313
448
  Tree.expects(:by_given_category).with(@controller.object_id, 'for_id').returns(Tree)
314
449
  Tree.expects(:all).returns([mock_tree])
315
- get :index, :by_category => 'for'
450
+
451
+ get :index, params: { by_category: 'for' }
452
+
316
453
  assert_equal([mock_tree], assigns(:@trees))
317
- assert_equal({ :by_category => 'for' }, current_scopes)
454
+ assert_equal({ by_category: 'for' }, current_scopes)
318
455
  end
319
456
 
320
457
  def test_scope_with_nested_hash_and_in_option
321
458
  hash = { 'title' => 'the-title', 'content' => 'the-content' }
322
459
  Tree.expects(:title).with('the-title').returns(Tree)
323
460
  Tree.expects(:content).with('the-content').returns(Tree)
461
+ Tree.expects(:metadata).never
462
+ Tree.expects(:metadata_blank).with(nil).returns(Tree)
324
463
  Tree.expects(:all).returns([mock_tree])
325
- get :index, q: hash
464
+
465
+ get :index, params: { q: hash }
466
+
326
467
  assert_equal([mock_tree], assigns(:@trees))
327
468
  assert_equal({ q: hash }, current_scopes)
328
469
  end
@@ -334,14 +475,7 @@ class HasScopeTest < ActionController::TestCase
334
475
 
335
476
  protected
336
477
 
337
- if ActionPack::VERSION::MAJOR == 5
338
- # TODO: Remove this when we only support Rails 5.
339
- def get(action, params = {})
340
- super action, params: params
341
- end
342
- end
343
-
344
- def mock_tree(stubs={})
478
+ def mock_tree(stubs = {})
345
479
  @mock_tree ||= mock(stubs)
346
480
  end
347
481
 
@@ -360,16 +494,14 @@ class TreeHugger
360
494
  has_scope :color
361
495
 
362
496
  def by_color
363
- apply_scopes(Tree, :color => 'blue')
497
+ apply_scopes(Tree, color: 'blue')
364
498
  end
365
-
366
499
  end
367
500
 
368
501
  class HasScopeOutsideControllerTest < ActiveSupport::TestCase
369
-
370
502
  def test_has_scope_usable_outside_controller
371
503
  Tree.expects(:color).with('blue')
504
+
372
505
  TreeHugger.new.by_color
373
506
  end
374
-
375
507
  end
data/test/test_helper.rb CHANGED
@@ -7,17 +7,12 @@ require 'mocha/mini_test'
7
7
  # Configure Rails
8
8
  ENV['RAILS_ENV'] = 'test'
9
9
 
10
- require 'active_support'
11
- require 'active_support/core_ext/string/strip'
12
- require 'action_controller'
13
- require 'action_dispatch/middleware/flash'
14
-
15
10
  $:.unshift File.expand_path('../../lib', __FILE__)
16
11
  require 'has_scope'
17
12
 
18
13
  HasScope::Routes = ActionDispatch::Routing::RouteSet.new
19
14
  HasScope::Routes.draw do
20
- get '/:controller(/:action(/:id))'
15
+ resources :trees, only: %i[index new edit show]
21
16
  end
22
17
 
23
18
  class ApplicationController < ActionController::Base
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_scope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - José Valim
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-10 00:00:00.000000000 Z
11
+ date: 2021-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.1'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.1'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4.1'
33
+ version: '5.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '4.1'
40
+ version: '5.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -83,7 +83,7 @@ homepage: http://github.com/plataformatec/has_scope
83
83
  licenses:
84
84
  - MIT
85
85
  metadata: {}
86
- post_install_message:
86
+ post_install_message:
87
87
  rdoc_options:
88
88
  - "--charset=UTF-8"
89
89
  require_paths:
@@ -92,16 +92,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
- version: 2.1.7
95
+ version: 2.5.0
96
96
  required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  requirements:
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
100
  version: '0'
101
101
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.7.6
104
- signing_key:
102
+ rubygems_version: 3.2.6
103
+ signing_key:
105
104
  specification_version: 4
106
105
  summary: Maps controller filters to your resource scopes.
107
106
  test_files: