has_sunspot_scope 0.1
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.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +66 -0
- data/Rakefile +42 -0
- data/init.rb +1 -0
- data/lib/has_scope.rb +192 -0
- data/test/has_scope_test.rb +235 -0
- data/test/test_helper.rb +31 -0
- metadata +74 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
== HasScope
|
2
|
+
|
3
|
+
== Block usage
|
4
|
+
|
5
|
+
This fork works only for sunspot_rails and i have only used the block variants
|
6
|
+
|
7
|
+
class GraduationsController < ApplicationController
|
8
|
+
|
9
|
+
has_scope :query do |controller, search, value|
|
10
|
+
search.keywords(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
has_scope :category do |controller, search, value|
|
14
|
+
search.with(:category_id, value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def index
|
18
|
+
@search = Graduation.search do |search|
|
19
|
+
apply_scopes(search)
|
20
|
+
search.facet(:category_id, :exclude => scope_return_values[:category] #multi-facet search
|
21
|
+
end
|
22
|
+
@graduations = @search.results
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
You can retrieve all the scopes applied in one action with <tt>current_scopes</tt> method.
|
27
|
+
|
28
|
+
== Installation
|
29
|
+
|
30
|
+
HasScope is available as gem on Gemcutter, so just run the following:
|
31
|
+
|
32
|
+
sudo gem install has_scope
|
33
|
+
|
34
|
+
If you want it as plugin, just do:
|
35
|
+
|
36
|
+
script/plugin install git://github.com/plataformatec/has_scope.git
|
37
|
+
|
38
|
+
== Options
|
39
|
+
|
40
|
+
HasScope supports several options:
|
41
|
+
|
42
|
+
* <tt>:type</tt> - Checks the type of the parameter sent. If set to :boolean it just calls the named scope, without any argument. By default, it does not allow hashes or arrays to be given, except if type :hash or :array are set.
|
43
|
+
|
44
|
+
* <tt>:only</tt> - In which actions the scope is applied.
|
45
|
+
|
46
|
+
* <tt>:except</tt> - In which actions the scope is not applied.
|
47
|
+
|
48
|
+
* <tt>:as</tt> - The key in the params hash expected to find the scope. Defaults to the scope name.
|
49
|
+
|
50
|
+
* <tt>:using</tt> - The subkeys to be used as args when type is a hash.
|
51
|
+
|
52
|
+
* <tt>:if</tt> - Specifies a method, proc or string to call to determine if the scope should apply.
|
53
|
+
|
54
|
+
* <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the scope should NOT apply.
|
55
|
+
|
56
|
+
* <tt>:default</tt> - Default value for the scope. Whenever supplied the scope is always called.
|
57
|
+
|
58
|
+
* <tt>:allow_blank</tt> - Blank values are not sent to scopes by default. Set to true to overwrite.
|
59
|
+
|
60
|
+
== Bugs and Feedback
|
61
|
+
|
62
|
+
If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
|
63
|
+
|
64
|
+
http://github.com/plataformatec/has_scope/issues
|
65
|
+
|
66
|
+
MIT License. Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
desc 'Test HasScope'
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << 'lib'
|
12
|
+
t.libs << 'test'
|
13
|
+
t.pattern = 'test/**/*_test.rb'
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generate documentation for HasScope'
|
18
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
19
|
+
rdoc.rdoc_dir = 'rdoc'
|
20
|
+
rdoc.title = 'HasScope'
|
21
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
22
|
+
rdoc.rdoc_files.include('README.rdoc')
|
23
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require 'jeweler'
|
28
|
+
Jeweler::Tasks.new do |s|
|
29
|
+
s.name = "has_scope"
|
30
|
+
s.version = "0.5.0"
|
31
|
+
s.summary = "Maps controller filters to your resource scopes"
|
32
|
+
s.email = "contact@plataformatec.com.br"
|
33
|
+
s.homepage = "http://github.com/plataformatec/has_scope"
|
34
|
+
s.description = "Maps controller filters to your resource scopes"
|
35
|
+
s.authors = ['José Valim']
|
36
|
+
s.files = FileList["[A-Z]*", "lib/**/*", "init.rb"]
|
37
|
+
end
|
38
|
+
|
39
|
+
Jeweler::GemcutterTasks.new
|
40
|
+
rescue LoadError
|
41
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
|
42
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'has_scope'
|
data/lib/has_scope.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
module HasScope
|
2
|
+
TRUE_VALUES = ["true", true, "1", 1]
|
3
|
+
|
4
|
+
ALLOWED_TYPES = {
|
5
|
+
:array => [ Array ],
|
6
|
+
:hash => [ Hash ],
|
7
|
+
:boolean => [ Object ],
|
8
|
+
:default => [ String, Numeric ]
|
9
|
+
}
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
extend ClassMethods
|
14
|
+
helper_method :current_scopes
|
15
|
+
class_inheritable_hash :scopes_configuration, :instance_writer => false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
# Detects params from url and apply as scopes to your classes.
|
21
|
+
#
|
22
|
+
# == Options
|
23
|
+
#
|
24
|
+
# * <tt>:type</tt> - Checks the type of the parameter sent. If set to :boolean
|
25
|
+
# it just calls the named scope, without any argument. By default,
|
26
|
+
# it does not allow hashes or arrays to be given, except if type
|
27
|
+
# :hash or :array are set.
|
28
|
+
#
|
29
|
+
# * <tt>:only</tt> - In which actions the scope is applied. By default is :all.
|
30
|
+
#
|
31
|
+
# * <tt>:except</tt> - In which actions the scope is not applied. By default is :none.
|
32
|
+
#
|
33
|
+
# * <tt>:as</tt> - The key in the params hash expected to find the scope.
|
34
|
+
# Defaults to the scope name.
|
35
|
+
#
|
36
|
+
# * <tt>:using</tt> - If type is a hash, you can provide :using to convert the hash to
|
37
|
+
# a named scope call with several arguments.
|
38
|
+
#
|
39
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
40
|
+
# if the scope should apply
|
41
|
+
#
|
42
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
|
43
|
+
# if the scope should NOT apply.
|
44
|
+
#
|
45
|
+
# * <tt>:default</tt> - Default value for the scope. Whenever supplied the scope
|
46
|
+
# is always called.
|
47
|
+
#
|
48
|
+
# * <tt>:allow_blank</tt> - Blank values are not sent to scopes by default. Set to true to overwrite.
|
49
|
+
#
|
50
|
+
# == Block usage
|
51
|
+
#
|
52
|
+
# has_scope also accepts a block. The controller, current scope and value are yielded
|
53
|
+
# to the block so the user can apply the scope on its own. This is useful in case we
|
54
|
+
# need to manipulate the given value:
|
55
|
+
#
|
56
|
+
# has_scope :category do |controller, scope, value|
|
57
|
+
# value != "all" ? scope.by_category(value) : scope
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# has_scope :not_voted_by_me, :type => :boolean do |controller, scope|
|
61
|
+
# scope.not_voted_by(controller.current_user.id)
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
def has_scope(*scopes, &block)
|
65
|
+
options = scopes.extract_options!
|
66
|
+
options.symbolize_keys!
|
67
|
+
options.assert_valid_keys(:type, :only, :except, :if, :unless, :default, :as, :using, :allow_blank)
|
68
|
+
|
69
|
+
if options.key?(:using)
|
70
|
+
if options.key?(:type) && options[:type] != :hash
|
71
|
+
raise "You cannot use :using with another :type different than :hash"
|
72
|
+
else
|
73
|
+
options[:type] = :hash
|
74
|
+
end
|
75
|
+
|
76
|
+
options[:using] = Array(options[:using])
|
77
|
+
end
|
78
|
+
|
79
|
+
options[:only] = Array(options[:only])
|
80
|
+
options[:except] = Array(options[:except])
|
81
|
+
|
82
|
+
self.scopes_configuration ||= {}
|
83
|
+
|
84
|
+
scopes.each do |scope|
|
85
|
+
self.scopes_configuration[scope] ||= { :as => scope, :type => :default, :block => block }
|
86
|
+
self.scopes_configuration[scope].merge!(options)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
# Receives an object where scopes will be applied to.
|
94
|
+
#
|
95
|
+
# class GraduationsController < InheritedResources::Base
|
96
|
+
# has_scope :featured, :type => true, :only => :index
|
97
|
+
# has_scope :by_degree, :only => :index
|
98
|
+
#
|
99
|
+
# def index
|
100
|
+
# @graduations = apply_scopes(Graduation).all
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
def apply_scopes(target, hash=params)
|
105
|
+
return target unless scopes_configuration
|
106
|
+
|
107
|
+
self.scopes_configuration.each do |scope, options|
|
108
|
+
next unless apply_scope_to_action?(options)
|
109
|
+
key = options[:as]
|
110
|
+
|
111
|
+
if hash.key?(key)
|
112
|
+
value, call_scope = hash[key], true
|
113
|
+
elsif options.key?(:default)
|
114
|
+
value, call_scope = options[:default], true
|
115
|
+
value = value.call(self) if value.is_a?(Proc)
|
116
|
+
end
|
117
|
+
|
118
|
+
value = parse_value(options[:type], key, value)
|
119
|
+
|
120
|
+
if call_scope && (value.present? || options[:allow_blank])
|
121
|
+
current_scopes[key] = value
|
122
|
+
scope_return_values[scope] = call_scope_by_type(options[:type], scope, target, value, options)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
target
|
127
|
+
end
|
128
|
+
|
129
|
+
# Set the real value for the current scope if type check.
|
130
|
+
def parse_value(type, key, value) #:nodoc:
|
131
|
+
if type == :boolean
|
132
|
+
TRUE_VALUES.include?(value)
|
133
|
+
elsif value && ALLOWED_TYPES[type].none?{ |klass| value.is_a?(klass) }
|
134
|
+
raise "Expected type :#{type} in params[:#{key}], got #{value.class}"
|
135
|
+
else
|
136
|
+
value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Call the scope taking into account its type.
|
141
|
+
def call_scope_by_type(type, scope, target, value, options) #:nodoc:
|
142
|
+
block = options[:block]
|
143
|
+
|
144
|
+
if type == :boolean
|
145
|
+
block ? block.call(self, target) : target.send(scope)
|
146
|
+
elsif value && options.key?(:using)
|
147
|
+
value = value.values_at(*options[:using])
|
148
|
+
block ? block.call(self, target, value) : target.send(scope, *value)
|
149
|
+
else
|
150
|
+
block ? block.call(self, target, value) : target.send(scope, value)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Given an options with :only and :except arrays, check if the scope
|
155
|
+
# can be performed in the current action.
|
156
|
+
def apply_scope_to_action?(options) #:nodoc:
|
157
|
+
return false unless applicable?(options[:if], true) && applicable?(options[:unless], false)
|
158
|
+
|
159
|
+
if options[:only].empty?
|
160
|
+
options[:except].empty? || !options[:except].include?(action_name.to_sym)
|
161
|
+
else
|
162
|
+
options[:only].include?(action_name.to_sym)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Evaluates the scope options :if or :unless. Returns true if the proc
|
167
|
+
# method, or string evals to the expected value.
|
168
|
+
def applicable?(string_proc_or_symbol, expected) #:nodoc:
|
169
|
+
case string_proc_or_symbol
|
170
|
+
when String
|
171
|
+
eval(string_proc_or_symbol) == expected
|
172
|
+
when Proc
|
173
|
+
string_proc_or_symbol.call(self) == expected
|
174
|
+
when Symbol
|
175
|
+
send(string_proc_or_symbol) == expected
|
176
|
+
else
|
177
|
+
true
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns the scopes used in this action.
|
182
|
+
def current_scopes
|
183
|
+
@current_scopes ||= {}
|
184
|
+
end
|
185
|
+
|
186
|
+
# Returns the return-values of the applied scopes in this action.
|
187
|
+
def scope_return_values
|
188
|
+
@scope_return_values ||= {}
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
ActionController::Base.send :include, HasScope
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class Tree
|
4
|
+
end
|
5
|
+
|
6
|
+
class TreesController < ApplicationController
|
7
|
+
has_scope :color, :unless => :show_all_colors?
|
8
|
+
has_scope :only_tall, :type => :boolean, :only => :index, :if => :restrict_to_only_tall_trees?
|
9
|
+
has_scope :shadown_range, :default => 10, :except => [ :index, :show, :new ]
|
10
|
+
has_scope :root_type, :as => :root, :allow_blank => true
|
11
|
+
has_scope :calculate_height, :default => proc {|c| c.session[:height] || 20 }, :only => :new
|
12
|
+
has_scope :paginate, :type => :hash
|
13
|
+
has_scope :args_paginate, :type => :hash, :using => [:page, :per_page]
|
14
|
+
has_scope :categories, :type => :array
|
15
|
+
|
16
|
+
has_scope :only_short, :type => :boolean do |controller, scope|
|
17
|
+
scope.only_really_short!(controller.object_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
has_scope :by_category do |controller, scope, value|
|
21
|
+
scope.by_given_category(controller.object_id, value + "_id")
|
22
|
+
end
|
23
|
+
|
24
|
+
def index
|
25
|
+
@trees = apply_scopes(Tree).all
|
26
|
+
end
|
27
|
+
|
28
|
+
def new
|
29
|
+
@tree = apply_scopes(Tree).new
|
30
|
+
end
|
31
|
+
|
32
|
+
def show
|
33
|
+
@tree = apply_scopes(Tree).find(params[:id])
|
34
|
+
end
|
35
|
+
alias :edit :show
|
36
|
+
|
37
|
+
protected
|
38
|
+
def restrict_to_only_tall_trees?
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def show_all_colors?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_render
|
47
|
+
render :text => action_name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class HasScopeTest < ActionController::TestCase
|
52
|
+
tests TreesController
|
53
|
+
|
54
|
+
def test_boolean_scope_is_called_when_boolean_param_is_true
|
55
|
+
Tree.expects(:only_tall).with().returns(Tree).in_sequence
|
56
|
+
Tree.expects(:all).returns([mock_tree]).in_sequence
|
57
|
+
get :index, :only_tall => 'true'
|
58
|
+
assert_equal([mock_tree], assigns(:trees))
|
59
|
+
assert_equal({ :only_tall => true }, current_scopes)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_boolean_scope_is_not_called_when_boolean_param_is_false
|
63
|
+
Tree.expects(:only_tall).never
|
64
|
+
Tree.expects(:all).returns([mock_tree])
|
65
|
+
get :index, :only_tall => 'false'
|
66
|
+
assert_equal([mock_tree], assigns(:trees))
|
67
|
+
assert_equal({}, current_scopes)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_scope_is_called_only_on_index
|
71
|
+
Tree.expects(:only_tall).never
|
72
|
+
Tree.expects(:find).with('42').returns(mock_tree)
|
73
|
+
get :show, :only_tall => 'true', :id => '42'
|
74
|
+
assert_equal(mock_tree, assigns(:tree))
|
75
|
+
assert_equal({ }, current_scopes)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_scope_is_skipped_when_if_option_is_false
|
79
|
+
@controller.stubs(:restrict_to_only_tall_trees?).returns(false)
|
80
|
+
Tree.expects(:only_tall).never
|
81
|
+
Tree.expects(:all).returns([mock_tree])
|
82
|
+
get :index, :only_tall => 'true'
|
83
|
+
assert_equal([mock_tree], assigns(:trees))
|
84
|
+
assert_equal({ }, current_scopes)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_scope_is_skipped_when_unless_option_is_true
|
88
|
+
@controller.stubs(:show_all_colors?).returns(true)
|
89
|
+
Tree.expects(:color).never
|
90
|
+
Tree.expects(:all).returns([mock_tree])
|
91
|
+
get :index, :color => 'blue'
|
92
|
+
assert_equal([mock_tree], assigns(:trees))
|
93
|
+
assert_equal({ }, current_scopes)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_scope_is_called_except_on_index
|
97
|
+
Tree.expects(:shadown_range).with().never
|
98
|
+
Tree.expects(:all).returns([mock_tree])
|
99
|
+
get :index, :shadown_range => 20
|
100
|
+
assert_equal([mock_tree], assigns(:trees))
|
101
|
+
assert_equal({ }, current_scopes)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_scope_is_called_with_arguments
|
105
|
+
Tree.expects(:color).with('blue').returns(Tree).in_sequence
|
106
|
+
Tree.expects(:all).returns([mock_tree]).in_sequence
|
107
|
+
get :index, :color => 'blue'
|
108
|
+
assert_equal([mock_tree], assigns(:trees))
|
109
|
+
assert_equal({ :color => 'blue' }, current_scopes)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_scope_is_not_called_if_blank
|
113
|
+
Tree.expects(:color).never
|
114
|
+
Tree.expects(:all).returns([mock_tree]).in_sequence
|
115
|
+
get :index, :color => ''
|
116
|
+
assert_equal([mock_tree], assigns(:trees))
|
117
|
+
assert_equal({ }, current_scopes)
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_scope_is_called_when_blank_if_allow_blank_is_given
|
121
|
+
Tree.expects(:root_type).with('').returns(Tree)
|
122
|
+
Tree.expects(:all).returns([mock_tree]).in_sequence
|
123
|
+
get :index, :root => ''
|
124
|
+
assert_equal([mock_tree], assigns(:trees))
|
125
|
+
assert_equal({ :root => '' }, current_scopes)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_multiple_scopes_are_called
|
129
|
+
Tree.expects(:only_tall).with().returns(Tree)
|
130
|
+
Tree.expects(:color).with('blue').returns(Tree)
|
131
|
+
Tree.expects(:all).returns([mock_tree])
|
132
|
+
get :index, :color => 'blue', :only_tall => 'true'
|
133
|
+
assert_equal([mock_tree], assigns(:trees))
|
134
|
+
assert_equal({ :color => 'blue', :only_tall => true }, current_scopes)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_scope_of_type_hash
|
138
|
+
hash = { "page" => "1", "per_page" => "10" }
|
139
|
+
Tree.expects(:paginate).with(hash).returns(Tree)
|
140
|
+
Tree.expects(:all).returns([mock_tree])
|
141
|
+
get :index, :paginate => hash
|
142
|
+
assert_equal([mock_tree], assigns(:trees))
|
143
|
+
assert_equal({ :paginate => hash }, current_scopes)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_scope_of_type_hash_with_using
|
147
|
+
hash = { "page" => "1", "per_page" => "10" }
|
148
|
+
Tree.expects(:args_paginate).with("1", "10").returns(Tree)
|
149
|
+
Tree.expects(:all).returns([mock_tree])
|
150
|
+
get :index, :args_paginate => hash
|
151
|
+
assert_equal([mock_tree], assigns(:trees))
|
152
|
+
assert_equal({ :args_paginate => hash }, current_scopes)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_scope_of_type_array
|
156
|
+
array = %w(book kitchen sport)
|
157
|
+
Tree.expects(:categories).with(array).returns(Tree)
|
158
|
+
Tree.expects(:all).returns([mock_tree])
|
159
|
+
get :index, :categories => array
|
160
|
+
assert_equal([mock_tree], assigns(:trees))
|
161
|
+
assert_equal({ :categories => array }, current_scopes)
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_invalid_type_hash_for_default_type_scope
|
165
|
+
assert_raise RuntimeError do
|
166
|
+
get :index, :color => { :blue => :red }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_invalid_type_string_for_hash_type_scope
|
171
|
+
assert_raise RuntimeError do
|
172
|
+
get :index, :paginate => "1"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_scope_is_called_with_default_value
|
177
|
+
Tree.expects(:shadown_range).with(10).returns(Tree).in_sequence
|
178
|
+
Tree.expects(:find).with('42').returns(mock_tree).in_sequence
|
179
|
+
get :edit, :id => '42'
|
180
|
+
assert_equal(mock_tree, assigns(:tree))
|
181
|
+
assert_equal({ :shadown_range => 10 }, current_scopes)
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_default_scope_value_can_be_overwritten
|
185
|
+
Tree.expects(:shadown_range).with('20').returns(Tree).in_sequence
|
186
|
+
Tree.expects(:find).with('42').returns(mock_tree).in_sequence
|
187
|
+
get :edit, :id => '42', :shadown_range => '20'
|
188
|
+
assert_equal(mock_tree, assigns(:tree))
|
189
|
+
assert_equal({ :shadown_range => '20' }, current_scopes)
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_scope_with_different_key
|
193
|
+
Tree.expects(:root_type).with('outside').returns(Tree).in_sequence
|
194
|
+
Tree.expects(:find).with('42').returns(mock_tree).in_sequence
|
195
|
+
get :show, :id => '42', :root => 'outside'
|
196
|
+
assert_equal(mock_tree, assigns(:tree))
|
197
|
+
assert_equal({ :root => 'outside' }, current_scopes)
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_scope_with_default_value_as_proc
|
201
|
+
session[:height] = 100
|
202
|
+
Tree.expects(:calculate_height).with(100).returns(Tree).in_sequence
|
203
|
+
Tree.expects(:new).returns(mock_tree).in_sequence
|
204
|
+
get :new
|
205
|
+
assert_equal(mock_tree, assigns(:tree))
|
206
|
+
assert_equal({ :calculate_height => 100 }, current_scopes)
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_scope_with_boolean_block
|
210
|
+
Tree.expects(:only_really_short!).with(@controller.object_id).returns(Tree)
|
211
|
+
Tree.expects(:all).returns([mock_tree])
|
212
|
+
get :index, :only_short => 'true'
|
213
|
+
assert_equal([mock_tree], assigns(:trees))
|
214
|
+
assert_equal({ :only_short => true }, current_scopes)
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_scope_with_other_block_types
|
218
|
+
Tree.expects(:by_given_category).with(@controller.object_id, 'for_id').returns(Tree)
|
219
|
+
Tree.expects(:all).returns([mock_tree])
|
220
|
+
get :index, :by_category => 'for'
|
221
|
+
assert_equal([mock_tree], assigns(:trees))
|
222
|
+
assert_equal({ :by_category => 'for' }, current_scopes)
|
223
|
+
end
|
224
|
+
|
225
|
+
protected
|
226
|
+
|
227
|
+
def mock_tree(stubs={})
|
228
|
+
@mock_tree ||= mock(stubs)
|
229
|
+
end
|
230
|
+
|
231
|
+
def current_scopes
|
232
|
+
@controller.send :current_scopes
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.setup
|
5
|
+
require 'test/unit'
|
6
|
+
require 'mocha'
|
7
|
+
|
8
|
+
# Configure Rails
|
9
|
+
ENV["RAILS_ENV"] = "test"
|
10
|
+
|
11
|
+
require 'active_support'
|
12
|
+
require 'action_controller'
|
13
|
+
require 'action_dispatch/middleware/flash'
|
14
|
+
|
15
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
16
|
+
require 'has_scope'
|
17
|
+
|
18
|
+
HasScope::Routes = ActionDispatch::Routing::RouteSet.new
|
19
|
+
HasScope::Routes.draw do
|
20
|
+
match '/:controller(/:action(/:id))'
|
21
|
+
end
|
22
|
+
|
23
|
+
class ApplicationController < ActionController::Base
|
24
|
+
include HasScope::Routes.url_helpers
|
25
|
+
end
|
26
|
+
|
27
|
+
class ActiveSupport::TestCase
|
28
|
+
setup do
|
29
|
+
@routes = HasScope::Routes
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has_sunspot_scope
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- "Jos\xC3\xA9 Valim"
|
13
|
+
- Sebastian Korfmann
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-03-23 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Forked from github.com/platformatec/has_scope - Slightly modified to map controller filters to your sunspot search (solr)
|
23
|
+
email: korfmann.sebastian@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- MIT-LICENSE
|
32
|
+
- README.rdoc
|
33
|
+
- Rakefile
|
34
|
+
- init.rb
|
35
|
+
- lib/has_scope.rb
|
36
|
+
- test/has_scope_test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/skorfmann/has_scope
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
hash: 3
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.7
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Forked from github.com/platformatec/has_scope - Slightly modified to map controller filters to your sunspot search (solr)
|
72
|
+
test_files:
|
73
|
+
- test/has_scope_test.rb
|
74
|
+
- test/test_helper.rb
|