magic_grid 0.10.4 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/assets/javascripts/magic_grid.js +2 -2
- data/lib/magic_grid.rb +1 -7
- data/lib/magic_grid/collection.rb +187 -0
- data/lib/magic_grid/definition.rb +45 -79
- data/lib/magic_grid/engine.rb +6 -0
- data/lib/magic_grid/helpers.rb +32 -40
- data/lib/magic_grid/logger.rb +8 -0
- data/lib/magic_grid/version.rb +1 -1
- data/spec/collection_spec.rb +44 -0
- data/spec/definition_spec.rb +111 -0
- data/spec/helpers_spec.rb +196 -26
- data/spec/logger_spec.rb +16 -0
- data/spec/spec_helper.rb +28 -16
- data/test/dummy/test/integration/spider_test.rb +2 -2
- metadata +10 -5
- data/lib/magic_grid/railtie.rb +0 -9
@@ -95,10 +95,10 @@ $(function () {
|
|
95
95
|
current = $input.data("current"),
|
96
96
|
value = $input.val(),
|
97
97
|
length = value.length,
|
98
|
-
|
98
|
+
base_url_path = base_url.split("?", 2)[0],
|
99
99
|
relevant = is_manual || (value != current && (length >= minLength || length == 0)),
|
100
100
|
pos = $input.getCursor(),
|
101
|
-
url =
|
101
|
+
url = base_url_path + '?' + $.param($grid.getGridParams());
|
102
102
|
clearTimeout(timer);
|
103
103
|
if (relevant) {
|
104
104
|
$grid.trigger("magic_grid:loading");
|
data/lib/magic_grid.rb
CHANGED
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
require 'magic_grid/logger'
|
3
|
+
|
4
|
+
module MagicGrid
|
5
|
+
class Collection
|
6
|
+
|
7
|
+
def initialize(collection, grid)
|
8
|
+
@collection = collection
|
9
|
+
@grid = grid
|
10
|
+
@current_page = 1
|
11
|
+
@sorts = []
|
12
|
+
@filter_callbacks = []
|
13
|
+
@filters = []
|
14
|
+
@searches = []
|
15
|
+
@post_filters = []
|
16
|
+
@post_filter_callbacks = []
|
17
|
+
@paginations = []
|
18
|
+
end
|
19
|
+
|
20
|
+
delegate :map, :count, :to => :collection
|
21
|
+
|
22
|
+
attr_accessor :grid
|
23
|
+
attr_reader :current_page, :original_count, :total_pages
|
24
|
+
|
25
|
+
def self.[](collection, grid)
|
26
|
+
if collection.is_a?(self)
|
27
|
+
collection.grid = grid
|
28
|
+
collection
|
29
|
+
else
|
30
|
+
Collection.new(collection, grid)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def quote_column_name(col)
|
35
|
+
@collection.connection.quote_column_name(col.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
def search_using_builtin(collection, q)
|
39
|
+
collection.__send__(@grid.options[:search_method], q)
|
40
|
+
end
|
41
|
+
|
42
|
+
def search_using_where(collection, q)
|
43
|
+
result = collection
|
44
|
+
search_cols = @grid.options[:searchable].map do |searchable|
|
45
|
+
case searchable
|
46
|
+
when Symbol
|
47
|
+
known = @grid.columns.find {|col| col[:col] == searchable}
|
48
|
+
if known and known.key?(:sql)
|
49
|
+
known[:sql]
|
50
|
+
else
|
51
|
+
"#{@collection.table_name}.#{quote_column_name(searchable)}"
|
52
|
+
end
|
53
|
+
when Integer
|
54
|
+
@grid.columns[searchable][:sql]
|
55
|
+
when String
|
56
|
+
searchable
|
57
|
+
else
|
58
|
+
raise "Searchable must be identifiable"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
unless search_cols.empty?
|
63
|
+
begin
|
64
|
+
clauses = search_cols.map {|c| c << " LIKE :search" }.join(" OR ")
|
65
|
+
result = collection.where(clauses, {:search => "%#{q}%"})
|
66
|
+
rescue
|
67
|
+
MagicGrid.logger.debug "Given collection doesn't respond to :where well"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
result
|
71
|
+
end
|
72
|
+
|
73
|
+
def sortable?
|
74
|
+
@collection.respond_to?(:order)
|
75
|
+
end
|
76
|
+
|
77
|
+
def apply_sort(col, dir)
|
78
|
+
@sorts << "#{col} #{dir}"
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def searchable?
|
83
|
+
filterable? or @collection.respond_to? @grid.options[:search_method]
|
84
|
+
end
|
85
|
+
|
86
|
+
def apply_search(q)
|
87
|
+
@searches << q
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def perform_search(collection, q)
|
92
|
+
search_using_builtin(collection, q)
|
93
|
+
rescue
|
94
|
+
MagicGrid.logger.debug "Given collection doesn't respond to #{@grid.options[:search_method]} well"
|
95
|
+
search_using_where(collection, q)
|
96
|
+
end
|
97
|
+
|
98
|
+
def filterable?
|
99
|
+
@collection.respond_to? :where
|
100
|
+
end
|
101
|
+
|
102
|
+
def apply_filter(filters = {})
|
103
|
+
if @collection.respond_to? :where
|
104
|
+
@filters << filters
|
105
|
+
end
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def apply_filter_callback(callback)
|
110
|
+
if callback.respond_to? :call
|
111
|
+
@filter_callbacks << callback
|
112
|
+
end
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
def has_post_filter?
|
117
|
+
@collection.respond_to? :post_filter
|
118
|
+
end
|
119
|
+
|
120
|
+
def apply_post_filter
|
121
|
+
@post_filters << :post_filter
|
122
|
+
self
|
123
|
+
end
|
124
|
+
|
125
|
+
def apply_pagination(current_page, per_page)
|
126
|
+
if per_page
|
127
|
+
@paginations << {:current_page => current_page, :per_page => per_page}
|
128
|
+
end
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
def perform_pagination(collection, current_page, per_page)
|
133
|
+
@original_count = @collection.count
|
134
|
+
@total_pages = @original_count / per_page
|
135
|
+
@current_page = current_page
|
136
|
+
if collection.respond_to? :paginate
|
137
|
+
collection = collection.paginate(:page => current_page,
|
138
|
+
:per_page => per_page)
|
139
|
+
elsif collection.respond_to? :page
|
140
|
+
collection = collection.page(current_page).per(per_page)
|
141
|
+
elsif collection.is_a?(Array) and Module.const_defined?(:Kaminari)
|
142
|
+
collection = Kaminari.paginate_array(collection).page(current_page).per(per_page)
|
143
|
+
else
|
144
|
+
collection = collection.to_enum
|
145
|
+
collection = collection.each_slice(per_page)
|
146
|
+
collection = collection.drop(current_page - 1)
|
147
|
+
collection = collection.first.to_a
|
148
|
+
class << collection
|
149
|
+
attr_accessor :current_page, :total_pages, :original_count
|
150
|
+
end
|
151
|
+
end
|
152
|
+
collection
|
153
|
+
end
|
154
|
+
|
155
|
+
def apply_all_operations(collection)
|
156
|
+
@sorts.each do |ordering|
|
157
|
+
collection = collection.order(ordering)
|
158
|
+
end
|
159
|
+
@filter_callbacks.each do |callback|
|
160
|
+
collection = callback.call(collection)
|
161
|
+
end
|
162
|
+
@filters.each do |hsh|
|
163
|
+
collection = collection.where(hsh)
|
164
|
+
end
|
165
|
+
@searches.each do |query|
|
166
|
+
collection = perform_search(collection, query)
|
167
|
+
end
|
168
|
+
@post_filters.each do |filter|
|
169
|
+
collection = collection.__send__(filter)
|
170
|
+
end
|
171
|
+
@post_filter_callbacks.each do |callback|
|
172
|
+
collection = callback.call(collection)
|
173
|
+
end
|
174
|
+
@paginations.each do |params|
|
175
|
+
collection = perform_pagination(collection, params[:current_page], params[:per_page])
|
176
|
+
end
|
177
|
+
collection
|
178
|
+
end
|
179
|
+
|
180
|
+
def collection
|
181
|
+
@reduced_collection ||= apply_all_operations(@collection)
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
@@ -1,18 +1,22 @@
|
|
1
|
-
|
1
|
+
require 'magic_grid/logger'
|
2
|
+
require 'magic_grid/collection'
|
2
3
|
|
3
4
|
module MagicGrid
|
4
5
|
class Definition
|
5
|
-
|
6
|
-
attr_accessor :columns, :collection, :magic_id, :options, :params,
|
6
|
+
attr_reader :columns, :magic_id, :options, :params,
|
7
7
|
:current_sort_col, :current_order, :default_order, :per_page
|
8
8
|
|
9
|
+
def collection
|
10
|
+
@collection.collection
|
11
|
+
end
|
12
|
+
|
9
13
|
DEFAULTS = {
|
10
14
|
:class => [],
|
11
15
|
:top_pager => false,
|
12
16
|
:bottom_pager => true,
|
13
17
|
:remote => false,
|
14
18
|
:per_page => 30,
|
15
|
-
:searchable =>
|
19
|
+
:searchable => [],
|
16
20
|
:search_method => :search,
|
17
21
|
:min_search_length => 3,
|
18
22
|
:id => false,
|
@@ -56,13 +60,13 @@ module MagicGrid
|
|
56
60
|
@default_order = @options[:default_order]
|
57
61
|
@params = controller && controller.params || {}
|
58
62
|
@per_page = @options[:per_page]
|
59
|
-
@collection = collection
|
63
|
+
@collection = Collection[collection, self]
|
60
64
|
begin
|
61
65
|
#if @collection.respond_to? :table
|
62
66
|
table_name = @collection.quoted_table_name
|
63
67
|
table_columns = @collection.table.columns.map {|c| c.name}
|
64
68
|
rescue
|
65
|
-
|
69
|
+
MagicGrid.logger.debug "Given collection doesn't respond to :table well"
|
66
70
|
table_name = nil
|
67
71
|
table_columns = @columns.each_index.to_a
|
68
72
|
end
|
@@ -90,107 +94,69 @@ module MagicGrid
|
|
90
94
|
@magic_id << @collection.to_sql.hash.abs.to_s(36) if @collection.respond_to? :to_sql
|
91
95
|
end
|
92
96
|
@current_sort_col = sort_col_i = param(:col, @options[:default_col]).to_i
|
93
|
-
if @collection.
|
97
|
+
if @collection.sortable? and @columns.count > sort_col_i and @columns[sort_col_i].has_key?(:sql)
|
94
98
|
sort_col = @columns[sort_col_i][:sql]
|
95
99
|
@current_order = order(param(:order, @default_order))
|
96
100
|
sort_dir = order_sql(@current_order)
|
97
|
-
@collection
|
101
|
+
@collection.apply_sort(sort_col, sort_dir)
|
98
102
|
else
|
99
|
-
|
103
|
+
MagicGrid.logger.debug "#{self.class.name}: Ignoring sorting on non-AR collection"
|
100
104
|
end
|
101
105
|
|
102
|
-
|
103
|
-
|
104
|
-
if @collection.respond_to?(:where) or @options[:listener_handler].respond_to?(:call)
|
106
|
+
if @collection.filterable? or @options[:listener_handler].respond_to?(:call)
|
105
107
|
if @options[:listener_handler].respond_to? :call
|
106
|
-
@collection
|
108
|
+
@collection.apply_filter_callback @options[:listener_handler]
|
107
109
|
else
|
108
110
|
@options[:listeners].each_pair do |key, value|
|
109
111
|
if @params[value] and not @params[value].to_s.empty?
|
110
|
-
@collection
|
112
|
+
@collection.apply_filter(value => @params[value])
|
111
113
|
end
|
112
114
|
end
|
113
115
|
end
|
114
116
|
else
|
115
117
|
unless @options[:listeners].empty?
|
116
|
-
|
118
|
+
MagicGrid.logger.warn "#{self.class.name}: Ignoring listener on dumb collection"
|
117
119
|
@options[:listeners] = {}
|
118
120
|
end
|
119
121
|
end
|
122
|
+
|
123
|
+
@options[:searchable] = Array(@options[:searchable])
|
120
124
|
@options[:current_search] ||= param(:q)
|
121
|
-
if
|
122
|
-
|
123
|
-
|
124
|
-
orig_collection = @collection
|
125
|
-
begin
|
126
|
-
@collection = @collection.__send__(@options[:search_method], param(:q))
|
127
|
-
rescue
|
128
|
-
Rails.logger.debug "Given collection doesn't respond to #{@options[:search_method]} well"
|
129
|
-
@collection = orig_collection
|
130
|
-
search_cols = @options[:searchable].map do |searchable|
|
131
|
-
case searchable
|
132
|
-
when Symbol
|
133
|
-
known = @columns.find {|col| col[:col] == searchable}
|
134
|
-
if known and known.key?(:sql)
|
135
|
-
known[:sql]
|
136
|
-
else
|
137
|
-
"#{table_name}.#{@collection.connection.quote_column_name(searchable.to_s)}"
|
138
|
-
end
|
139
|
-
when Integer
|
140
|
-
@columns[searchable][:sql]
|
141
|
-
when String
|
142
|
-
searchable
|
143
|
-
else
|
144
|
-
raise "Searchable must be identifiable"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
unless search_cols.empty?
|
148
|
-
begin
|
149
|
-
clauses = search_cols.map {|c| c << " LIKE :search" }.join(" OR ")
|
150
|
-
@collection = @collection.where(clauses, {:search => "%#{param(:q)}%"})
|
151
|
-
rescue
|
152
|
-
Rails.logger.debug "Given collection doesn't respond to :where well"
|
153
|
-
@collection = orig_collection
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
125
|
+
if @collection.searchable?
|
126
|
+
if param(:q) and not param(:q).empty? and not @options[:searchable].empty?
|
127
|
+
@collection.apply_search(param(:q))
|
157
128
|
end
|
158
129
|
else
|
159
|
-
if @options[:searchable] or param(:q)
|
160
|
-
|
130
|
+
if not @options[:searchable].empty? or param(:q)
|
131
|
+
MagicGrid.logger.warn "#{self.class.name}: Ignoring searchable fields on non-AR collection"
|
161
132
|
end
|
162
|
-
@options[:searchable] =
|
163
|
-
end
|
164
|
-
if not @options[:searcher] and @options[:searchable]
|
165
|
-
@options[:needs_searcher] = true
|
166
|
-
@options[:searcher] = param_key(:searcher)
|
133
|
+
@options[:searchable] = []
|
167
134
|
end
|
135
|
+
|
168
136
|
# Do collection filter first, may convert from AR to Array
|
169
|
-
if @options[:collection_post_filter?] and @collection.
|
170
|
-
@collection
|
137
|
+
if @options[:collection_post_filter?] and @collection.has_post_filter?
|
138
|
+
@collection.apply_post_filter
|
171
139
|
end
|
172
140
|
if @options[:post_filter] and @options[:post_filter].respond_to?(:call)
|
173
|
-
@collection
|
141
|
+
@collection.apply_filter_callback @options[:post_filter]
|
174
142
|
end
|
175
143
|
# Paginate at the very end, after all sorting, filtering, etc..
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
@collection.total_pages = original.count / @per_page
|
193
|
-
end
|
144
|
+
@collection.apply_pagination(current_page, @per_page)
|
145
|
+
end
|
146
|
+
|
147
|
+
def searchable?
|
148
|
+
@collection.searchable? and not @options[:searchable].empty?
|
149
|
+
end
|
150
|
+
|
151
|
+
def needs_searcher?
|
152
|
+
@options[:needs_searcher] or (searchable? and not @options[:searcher])
|
153
|
+
end
|
154
|
+
|
155
|
+
def searcher
|
156
|
+
if needs_searcher?
|
157
|
+
param_key(:searcher)
|
158
|
+
else
|
159
|
+
@options[:searcher]
|
194
160
|
end
|
195
161
|
end
|
196
162
|
|
data/lib/magic_grid/engine.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'magic_grid/logger'
|
2
|
+
|
1
3
|
module MagicGrid
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
# Once in production, on every page view in development
|
@@ -10,5 +12,9 @@ module MagicGrid
|
|
10
12
|
# Provide some fallback translations that users can override
|
11
13
|
app.config.i18n.load_path += Dir.glob(File.expand_path('../../locales/*.{rb,yml}', __FILE__))
|
12
14
|
end
|
15
|
+
|
16
|
+
initializer "Rails logger" do
|
17
|
+
MagicGrid.logger = Rails.logger
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
data/lib/magic_grid/helpers.rb
CHANGED
@@ -4,29 +4,23 @@ if Module.const_defined? :WillPaginate
|
|
4
4
|
require 'will_paginate/array'
|
5
5
|
end
|
6
6
|
|
7
|
+
def MagicGrid::compact_hash(hash)
|
8
|
+
hash.select {|_,v| v }
|
9
|
+
end
|
10
|
+
|
7
11
|
module MagicGrid
|
8
12
|
module Helpers
|
9
13
|
def normalize_magic(collection, columns = [], options = {})
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
columns
|
14
|
-
elsif options.is_a? MagicGrid::Definition
|
15
|
-
options
|
16
|
-
else
|
17
|
-
MagicGrid::Definition.new(columns, collection, controller, options)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def magic_collection(collection, cols, opts = {})
|
22
|
-
normalize_magic(collection, cols, opts).collection
|
14
|
+
args_enum = [collection, columns, options].to_enum
|
15
|
+
given_grid = args_enum.find {|e| e.is_a? MagicGrid::Definition }
|
16
|
+
given_grid || MagicGrid::Definition.new(columns, collection, controller, options)
|
23
17
|
end
|
24
18
|
|
25
19
|
def magic_grid(collection = nil, cols = nil, opts = {}, &block)
|
26
20
|
grid = normalize_magic(collection, cols, opts)
|
27
21
|
base_params = grid.base_params
|
28
22
|
data = {
|
29
|
-
:searcher => grid.
|
23
|
+
:searcher => grid.searcher,
|
30
24
|
:current => controller.request.fullpath,
|
31
25
|
:live_search => grid.options[:live_search],
|
32
26
|
:listeners => (grid.options[:listeners] unless grid.options[:listeners].empty?),
|
@@ -38,7 +32,7 @@ module MagicGrid
|
|
38
32
|
content_tag('table',
|
39
33
|
:class => classes.join(' '),
|
40
34
|
:id => grid.magic_id,
|
41
|
-
:data => data
|
35
|
+
:data => MagicGrid.compact_hash(data)
|
42
36
|
) do
|
43
37
|
table = content_tag('thead', :data => {:params => base_params}
|
44
38
|
) do
|
@@ -48,7 +42,7 @@ module MagicGrid
|
|
48
42
|
:id => (grid.magic_id.to_s + "_spinner"),
|
49
43
|
:class => "magic_grid_spinner"
|
50
44
|
)
|
51
|
-
if grid.
|
45
|
+
if grid.needs_searcher?
|
52
46
|
thead << content_tag('tr') do
|
53
47
|
content_tag('td', :class => 'searcher full-width ui-widget-header',
|
54
48
|
:colspan => grid.columns.count) do
|
@@ -62,18 +56,10 @@ module MagicGrid
|
|
62
56
|
end
|
63
57
|
end
|
64
58
|
if grid.options[:per_page] and grid.options[:top_pager]
|
65
|
-
thead <<
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
:param_name => grid.param_key(:page),
|
70
|
-
:params => base_params
|
71
|
-
)
|
72
|
-
unless has_spinner
|
73
|
-
has_spinner = true
|
74
|
-
pager << spinner
|
75
|
-
end
|
76
|
-
pager
|
59
|
+
thead << magic_pager(grid, base_params) do
|
60
|
+
unless has_spinner
|
61
|
+
has_spinner = true
|
62
|
+
spinner
|
77
63
|
end
|
78
64
|
end
|
79
65
|
end
|
@@ -96,15 +82,7 @@ module MagicGrid
|
|
96
82
|
table << content_tag('tfoot') do
|
97
83
|
tfoot = ''.html_safe
|
98
84
|
if grid.options[:per_page] and grid.options[:bottom_pager]
|
99
|
-
tfoot <<
|
100
|
-
content_tag('td', :class => 'full-width ui-widget-header',
|
101
|
-
:colspan => grid.columns.count) do
|
102
|
-
magic_paginate(grid.collection,
|
103
|
-
:param_name => grid.param_key(:page),
|
104
|
-
:params => base_params
|
105
|
-
)
|
106
|
-
end
|
107
|
-
end
|
85
|
+
tfoot << magic_pager(grid, base_params)
|
108
86
|
end
|
109
87
|
if tfoot.empty? and not grid.options[:empty_footer]
|
110
88
|
tfoot = content_tag 'tr' do
|
@@ -231,9 +209,9 @@ module MagicGrid
|
|
231
209
|
:min_length => grid.options[:min_search_length],
|
232
210
|
:current => grid.options[:current_search] || "",
|
233
211
|
}
|
234
|
-
searcher = label_tag(grid.
|
235
|
-
|
236
|
-
searcher << search_field_tag(grid.
|
212
|
+
searcher = label_tag(grid.searcher.to_sym,
|
213
|
+
grid.options[:searcher_label])
|
214
|
+
searcher << search_field_tag(grid.searcher.to_sym,
|
237
215
|
grid.param(:q),
|
238
216
|
:placeholder => grid.options[:searcher_tooltip],
|
239
217
|
:size => grid.options[:searcher_size],
|
@@ -261,6 +239,20 @@ module MagicGrid
|
|
261
239
|
end
|
262
240
|
end
|
263
241
|
|
242
|
+
def magic_pager(grid, base_params, &block)
|
243
|
+
content_tag('tr') do
|
244
|
+
content_tag('td', :class => 'full-width ui-widget-header magic-pager',
|
245
|
+
:colspan => grid.columns.count) do
|
246
|
+
pager = magic_paginate(grid.collection,
|
247
|
+
:param_name => grid.param_key(:page),
|
248
|
+
:params => base_params
|
249
|
+
)
|
250
|
+
pager << capture(&block) if block_given?
|
251
|
+
pager
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
264
256
|
::ActionView::Base.send :include, self
|
265
257
|
end
|
266
258
|
end
|
data/lib/magic_grid/version.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'magic_grid/collection'
|
3
|
+
|
4
|
+
describe MagicGrid::Collection do
|
5
|
+
|
6
|
+
context "via [] class method" do
|
7
|
+
context "when given a MagicGrid::Collection" do
|
8
|
+
let(:actual_collection) { [1,2,3,4] }
|
9
|
+
let(:magic_collection) { MagicGrid::Collection.new(actual_collection, :original_grid) }
|
10
|
+
subject { MagicGrid::Collection[magic_collection, :new_grid] }
|
11
|
+
its(:collection) { should eq(actual_collection) }
|
12
|
+
its(:grid) { should eq(:new_grid) }
|
13
|
+
end
|
14
|
+
context "when given a basic collection" do
|
15
|
+
let(:actual_collection) { [1,2,3,4] }
|
16
|
+
subject { MagicGrid::Collection[actual_collection, :original_grid] }
|
17
|
+
its(:collection) { should eq(actual_collection) }
|
18
|
+
its(:grid) { should eq(:original_grid) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when based on an array" do
|
23
|
+
let(:collection) { [1,2,3,4] }
|
24
|
+
subject { MagicGrid::Collection.new(collection, nil) }
|
25
|
+
its(:collection) { should eq(collection) }
|
26
|
+
its(:grid) { should be_nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when based on something sortable" do
|
30
|
+
data = [1,5,3,2,56,7]
|
31
|
+
let(:sortable_collection) {
|
32
|
+
data.tap do |d|
|
33
|
+
d.stub(:order) { d }
|
34
|
+
end
|
35
|
+
}
|
36
|
+
it "should send #order when sorted" do
|
37
|
+
ordered = [1,2,3,4,5]
|
38
|
+
collection = MagicGrid::Collection.new(sortable_collection, nil)
|
39
|
+
sortable_collection.should_receive(:order) { ordered }
|
40
|
+
collection.apply_sort("col", "order")
|
41
|
+
collection.collection.should == ordered
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/definition_spec.rb
CHANGED
@@ -67,6 +67,13 @@ describe MagicGrid::Definition do
|
|
67
67
|
its(:columns) { should == column_list }
|
68
68
|
end
|
69
69
|
|
70
|
+
context "when given a MagicGrid::Collection" do
|
71
|
+
actual_collection = [1,2,3]
|
72
|
+
let(:collection) { MagicGrid::Collection.new(actual_collection, nil) }
|
73
|
+
subject { MagicGrid::Definition.new(column_list, collection, controller) }
|
74
|
+
its(:collection) { should eq(actual_collection) }
|
75
|
+
end
|
76
|
+
|
70
77
|
context "when given a large collection and some options" do
|
71
78
|
let(:controller) {
|
72
79
|
controller = double()
|
@@ -87,6 +94,110 @@ describe MagicGrid::Definition do
|
|
87
94
|
subject.param_key(:hunkydory).should == :grid_hunkydory
|
88
95
|
subject.param(:page).should == 2
|
89
96
|
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "sorting" do
|
100
|
+
data = [1,56,7,21,1]
|
101
|
+
let(:controller) {
|
102
|
+
controller = double()
|
103
|
+
controller.stub(:params) { HashWithIndifferentAccess.new({grid_order: 1}) }
|
104
|
+
controller
|
105
|
+
}
|
106
|
+
let(:collection) { data }
|
107
|
+
it "should sort collection using #order" do
|
108
|
+
collection.should_receive(:order).with("foo DESC") { data.sort.reverse }
|
109
|
+
grid = MagicGrid::Definition.new([{:sql => "foo"}], collection, controller, id: :grid)
|
110
|
+
|
111
|
+
grid.collection.should == data.sort.reverse
|
112
|
+
end
|
113
|
+
pending "test #order_sql directly"
|
114
|
+
end
|
115
|
+
|
116
|
+
context "filtering with #where" do
|
117
|
+
data = [1,56,7,21,1]
|
118
|
+
let(:controller) {
|
119
|
+
controller = double.tap do |c|
|
120
|
+
c.stub(:params) { HashWithIndifferentAccess.new({f1: 1}) }
|
121
|
+
end
|
122
|
+
}
|
123
|
+
let(:collection) {
|
124
|
+
data.tap do |d|
|
125
|
+
d.stub(:where) do |h|
|
126
|
+
d.select { |d| d < 10 }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
}
|
130
|
+
subject { MagicGrid::Definition.new([{:sql => "foo"}],
|
131
|
+
collection,
|
132
|
+
controller,
|
133
|
+
id: :grid, listeners: {f1: :f1}) }
|
134
|
+
its(:collection) { should == [1, 7, 1] }
|
135
|
+
end
|
136
|
+
|
137
|
+
context "filtering with a callback" do
|
138
|
+
data = [1,56,7,21,1]
|
139
|
+
filter = Proc.new do |c|
|
140
|
+
c.select { |i| i > 10 }
|
141
|
+
end
|
142
|
+
let(:controller) {
|
143
|
+
controller = double.tap do |c|
|
144
|
+
c.stub(:params) { HashWithIndifferentAccess.new({f1: 1}) }
|
145
|
+
end
|
146
|
+
}
|
147
|
+
let(:collection) {
|
148
|
+
data
|
149
|
+
}
|
150
|
+
subject { MagicGrid::Definition.new([{:sql => "foo"}],
|
151
|
+
collection,
|
152
|
+
controller,
|
153
|
+
id: :grid, listener_handler: filter) }
|
154
|
+
its(:collection) { should == [56, 21] }
|
155
|
+
end
|
156
|
+
|
157
|
+
pending "test listening on a dumb collection"
|
158
|
+
|
159
|
+
context "post_filtering with a callable post_filter" do
|
160
|
+
data = [1,56,7,21,1]
|
161
|
+
filter = Proc.new do |c|
|
162
|
+
c.select { |i| i > 10 }
|
163
|
+
end
|
164
|
+
let(:controller) {
|
165
|
+
controller = double.tap do |c|
|
166
|
+
c.stub(:params) { HashWithIndifferentAccess.new({f1: 1}) }
|
167
|
+
end
|
168
|
+
}
|
169
|
+
let(:collection) {
|
170
|
+
data
|
171
|
+
}
|
172
|
+
subject { MagicGrid::Definition.new([{:sql => "foo"}],
|
173
|
+
collection,
|
174
|
+
controller,
|
175
|
+
id: :grid, post_filter: filter) }
|
176
|
+
its(:collection) { should == [56, 21] }
|
177
|
+
end
|
90
178
|
|
179
|
+
context "post_filtering with a collection post_filter" do
|
180
|
+
data = [1,56,7,21,1]
|
181
|
+
filter = Proc.new do |c|
|
182
|
+
c.select { |i| i > 10 }
|
183
|
+
end
|
184
|
+
let(:controller) {
|
185
|
+
controller = double.tap do |c|
|
186
|
+
c.stub(:params) { HashWithIndifferentAccess.new({f1: 1}) }
|
187
|
+
end
|
188
|
+
}
|
189
|
+
let(:collection) {
|
190
|
+
data.tap do |d|
|
191
|
+
d.stub(:post_filter) do |h|
|
192
|
+
d.select { |d| d > 10 }
|
193
|
+
end
|
194
|
+
end
|
195
|
+
}
|
196
|
+
subject { MagicGrid::Definition.new([{:sql => "foo"}],
|
197
|
+
collection,
|
198
|
+
controller,
|
199
|
+
id: :grid, collection_post_filter?: true) }
|
200
|
+
its(:collection) { should == [56, 21] }
|
91
201
|
end
|
202
|
+
|
92
203
|
end
|
data/spec/helpers_spec.rb
CHANGED
@@ -3,23 +3,44 @@ require 'magic_grid/helpers'
|
|
3
3
|
require 'action_controller'
|
4
4
|
require "active_support/core_ext"
|
5
5
|
|
6
|
+
def make_controller
|
7
|
+
request = double.tap { |r|
|
8
|
+
r.stub(:fullpath, "/foo?page=bar")
|
9
|
+
}
|
10
|
+
double.tap { |v|
|
11
|
+
v.stub(:render)
|
12
|
+
v.stub(:params) { {} }
|
13
|
+
v.stub(:request) { request }
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def fake_connection
|
18
|
+
double(:connection).tap do |c|
|
19
|
+
c.stub(:quote_column_name) { |col| col.to_s }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def fake_active_record_collection(table_name = 'some_table')
|
24
|
+
(1..1000).to_a.tap do |c|
|
25
|
+
c.stub(:connection => fake_connection)
|
26
|
+
c.stub(:table_name => table_name)
|
27
|
+
c.stub(:where) { c }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
6
32
|
describe MagicGrid::Helpers do
|
7
33
|
|
8
34
|
# Let's use the helpers the way they're meant to be used!
|
9
35
|
include MagicGrid::Helpers
|
10
36
|
|
11
37
|
let(:empty_collection) { [] }
|
38
|
+
|
12
39
|
let(:column_list) { [:name, :description] }
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
double.tap { |v|
|
18
|
-
v.stub(:render) { nil }
|
19
|
-
v.stub(:params) { {} }
|
20
|
-
v.stub(:request) { request }
|
21
|
-
}
|
22
|
-
}
|
40
|
+
|
41
|
+
let(:controller) { make_controller }
|
42
|
+
|
43
|
+
# Kaminari uses view_renderer instead of controller
|
23
44
|
let(:view_renderer) { controller }
|
24
45
|
|
25
46
|
describe "#normalize_magic" do
|
@@ -28,40 +49,32 @@ describe MagicGrid::Helpers do
|
|
28
49
|
expect(normalize_magic([])).to be_a(MagicGrid::Definition)
|
29
50
|
end
|
30
51
|
|
31
|
-
it "should give back the MagicGrid::Definition given, if given
|
52
|
+
it "should give back the MagicGrid::Definition given, if given as any argument" do
|
32
53
|
definition = normalize_magic([])
|
33
|
-
expect(normalize_magic(definition)).to be(definition)
|
54
|
+
expect(normalize_magic( definition )).to be(definition)
|
55
|
+
expect(normalize_magic( nil, definition )).to be(definition)
|
56
|
+
expect(normalize_magic( nil, nil, definition )).to be(definition)
|
34
57
|
end
|
35
58
|
end
|
36
59
|
|
37
|
-
describe "#magic_collection" do
|
38
|
-
pending "should probably be removed, it's not really used"
|
39
|
-
|
40
|
-
it "should give back a collection like the one given" do
|
41
|
-
my_empty_collection = empty_collection
|
42
|
-
expect(magic_collection(my_empty_collection, column_list)).to eq(my_empty_collection)
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
60
|
describe "#magic_grid" do
|
48
61
|
pending "DOES WAY TOO MUCH!!"
|
49
62
|
|
63
|
+
let(:emtpy_grid) { magic_grid empty_collection, column_list }
|
64
|
+
|
50
65
|
it "should barf without any arguments" do
|
51
66
|
expect { magic_grid }.to raise_error
|
52
67
|
end
|
53
68
|
|
54
|
-
let(:emtpy_grid) { magic_grid empty_collection, column_list }
|
55
|
-
|
56
69
|
it "should render a table" do
|
57
70
|
expect( emtpy_grid ).not_to be_empty
|
58
71
|
expect( emtpy_grid ).to match(/<\/table>/)
|
59
72
|
end
|
60
73
|
|
61
74
|
context "when given an empty collection" do
|
62
|
-
|
75
|
+
subject { magic_grid empty_collection, column_list }
|
63
76
|
it "should indicate there is no data" do
|
64
|
-
|
77
|
+
subject.should match(/"if-empty"/)
|
65
78
|
end
|
66
79
|
end
|
67
80
|
|
@@ -82,6 +95,163 @@ describe MagicGrid::Helpers do
|
|
82
95
|
}
|
83
96
|
it { should =~ /HOKY_POKY_ALAMO: 1/ }
|
84
97
|
end
|
98
|
+
|
99
|
+
context "renders top and bottom pagers as told" do
|
100
|
+
large_collection = (1..1000).to_a
|
101
|
+
|
102
|
+
if Module.const_defined? :Kaminari
|
103
|
+
def render(*args)
|
104
|
+
"<nav class='pagination'><!-- paginate! --></nav>".html_safe
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should render an actual pager" do
|
109
|
+
grid = magic_grid(large_collection, [:to_s])
|
110
|
+
if Module.const_defined? :WillPaginate
|
111
|
+
grid.should match_select("tfoot>tr>td.magic-pager>div.pagination", 1)
|
112
|
+
elsif Module.const_defined? :Kaminari
|
113
|
+
grid.should match_select("tfoot>tr>td.magic-pager>nav.pagination", 1)
|
114
|
+
else
|
115
|
+
grid.should match_select("tfoot>tr>td.magic-pager", /INSTALL/)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
it "should render only a bottom pager by default" do
|
119
|
+
grid = magic_grid( large_collection, [:to_s] )
|
120
|
+
grid.should match_select("thead>tr>td.magic-pager", 0)
|
121
|
+
grid.should match_select("tfoot>tr>td.magic-pager", 1)
|
122
|
+
end
|
123
|
+
it "should render a top and bottom pager when told" do
|
124
|
+
grid = magic_grid( large_collection, [:to_s], top_pager: true )
|
125
|
+
grid.should match_select("thead>tr>td.magic-pager", 1)
|
126
|
+
grid.should match_select("tfoot>tr>td.magic-pager", 1)
|
127
|
+
end
|
128
|
+
it "should render only a top pager when told" do
|
129
|
+
grid = magic_grid( large_collection, [:to_s], top_pager: true, bottom_pager: false )
|
130
|
+
grid.should match_select("thead>tr>td.magic-pager", 1)
|
131
|
+
grid.should match_select("tfoot>tr>td.magic-pager", 0)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "searching" do
|
136
|
+
let(:searchabe_collection) {
|
137
|
+
collection = [].tap do |c|
|
138
|
+
c.stub(:search) { collection }
|
139
|
+
end
|
140
|
+
}
|
141
|
+
it "should render a search bar when asked" do
|
142
|
+
grid = magic_grid(searchabe_collection, column_list, :searchable => [:some_col])
|
143
|
+
grid.should match_select('input[type=search]')
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when a search query is given" do
|
147
|
+
let(:search_param) { 'foobar' }
|
148
|
+
let(:controller) {
|
149
|
+
make_controller.tap { |c|
|
150
|
+
c.stub(:params) { {:grid_id_q => search_param} }
|
151
|
+
}
|
152
|
+
}
|
153
|
+
it "should search a searchable collection when there are search params" do
|
154
|
+
collection = (1..1000).to_a
|
155
|
+
collection.should_receive(:search).with(search_param) { collection }
|
156
|
+
grid = magic_grid(collection, column_list, :id => "grid_id", :searchable => [:some_col])
|
157
|
+
grid.should match_select('input[type=search]')
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when the collection responds to #where" do
|
161
|
+
it "should call where when there are search params" do
|
162
|
+
search_col = :some_col
|
163
|
+
table_name = "tbl"
|
164
|
+
search_sql = "tbl.some_col"
|
165
|
+
|
166
|
+
collection = fake_active_record_collection(table_name)
|
167
|
+
collection.should_receive(:where).
|
168
|
+
with("#{search_sql} LIKE :search", {:search=>"%#{search_param}%"})
|
169
|
+
|
170
|
+
grid = magic_grid(collection, column_list, :id => "grid_id", :searchable => [search_col])
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should use custom sql from column for call to where when given" do
|
174
|
+
search_col = :some_col
|
175
|
+
search_sql = "sql that doesn't necessarily match column name"
|
176
|
+
table_name = "table name not used in query"
|
177
|
+
|
178
|
+
collection = fake_active_record_collection(table_name)
|
179
|
+
collection.should_receive(:where).
|
180
|
+
with("#{search_sql} LIKE :search", {:search=>"%#{search_param}%"})
|
181
|
+
|
182
|
+
magic_grid(collection,
|
183
|
+
[ :name,
|
184
|
+
:description,
|
185
|
+
{:col => search_col, :sql => search_sql}
|
186
|
+
],
|
187
|
+
:id => "grid_id", :searchable => [search_col])
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should use column number to look up search column" do
|
191
|
+
search_col = :some_col
|
192
|
+
search_sql = "sql that doesn't necessarily match column name"
|
193
|
+
table_name = "table name not used in query"
|
194
|
+
|
195
|
+
collection = fake_active_record_collection(table_name)
|
196
|
+
collection.should_receive(:where).
|
197
|
+
with("#{search_sql} LIKE :search", {:search=>"%#{search_param}%"})
|
198
|
+
|
199
|
+
magic_grid(collection,
|
200
|
+
[ :name,
|
201
|
+
:description,
|
202
|
+
{:col => search_col, :sql => search_sql}
|
203
|
+
],
|
204
|
+
:id => "grid_id", :searchable => [2])
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should use custom sql for call to where when given" do
|
208
|
+
search_col = :some_col
|
209
|
+
custom_search_col = "some custom search column"
|
210
|
+
search_sql = custom_search_col
|
211
|
+
table_name = "table name not used in query"
|
212
|
+
|
213
|
+
collection = fake_active_record_collection(table_name)
|
214
|
+
collection.should_receive(:where).
|
215
|
+
with("#{search_sql} LIKE :search", {:search=>"%#{search_param}%"})
|
216
|
+
|
217
|
+
magic_grid(collection,
|
218
|
+
[ :name,
|
219
|
+
:description,
|
220
|
+
{:col => search_col, :sql => search_sql}
|
221
|
+
],
|
222
|
+
:id => "grid_id", :searchable => [custom_search_col])
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should fail when given bad searchable columns" do
|
226
|
+
collection = fake_active_record_collection()
|
227
|
+
collection.should_not_receive(:where)
|
228
|
+
|
229
|
+
expect {
|
230
|
+
magic_grid(collection,
|
231
|
+
[ :name, :description],
|
232
|
+
:id => "grid_id", :searchable => [nil])
|
233
|
+
}.to raise_error
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should not fail if #where fails" do
|
237
|
+
search_col = :some_col
|
238
|
+
table_name = "tbl"
|
239
|
+
search_sql = "tbl.some_col"
|
240
|
+
|
241
|
+
collection = fake_active_record_collection(table_name)
|
242
|
+
magic_collection = MagicGrid::Collection.new(collection, nil)
|
243
|
+
collection.should_receive(:where).and_raise("some failure")
|
244
|
+
MagicGrid.logger = double.tap do |l|
|
245
|
+
l.should_receive(:debug).at_least(:once)
|
246
|
+
end
|
247
|
+
|
248
|
+
expect {
|
249
|
+
magic_grid(collection, column_list, :id => "grid_id", :searchable => [search_col])
|
250
|
+
}.to_not raise_error
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
85
255
|
end
|
86
256
|
|
87
257
|
end
|
data/spec/logger_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'magic_grid/logger'
|
3
|
+
|
4
|
+
describe MagicGrid do
|
5
|
+
it "should user the specified logger" do
|
6
|
+
logger = double.tap do |l|
|
7
|
+
l.should_receive(:debug)
|
8
|
+
l.should_receive(:warn)
|
9
|
+
l.should_receive(:error)
|
10
|
+
end
|
11
|
+
MagicGrid.logger = logger
|
12
|
+
MagicGrid.logger.warn "Something is afoot"
|
13
|
+
MagicGrid.logger.error "Something is really wrong"
|
14
|
+
MagicGrid.logger.debug "Something is foo"
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -9,13 +9,16 @@ unless ENV['TRAVIS']
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
require 'magic_grid/logger'
|
12
13
|
require 'action_view'
|
13
14
|
require 'rails'
|
15
|
+
require 'test/unit'
|
16
|
+
require 'action_controller'
|
14
17
|
|
15
18
|
begin
|
16
19
|
require 'will_paginate'
|
17
20
|
require 'will_paginate/array'
|
18
|
-
require 'will_paginate/view_helpers'
|
21
|
+
require 'will_paginate/view_helpers/action_view'
|
19
22
|
puts "Testing with WillPaginate"
|
20
23
|
rescue LoadError
|
21
24
|
puts "skipping WillPaginate"
|
@@ -31,28 +34,33 @@ end
|
|
31
34
|
|
32
35
|
Rails.backtrace_cleaner.remove_silencers!
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
def
|
37
|
+
class NullObject
|
38
|
+
def method_missing(*args, &block) self; end
|
39
|
+
def nil?; true; end
|
37
40
|
end
|
38
41
|
|
39
42
|
module ActionFaker
|
40
|
-
|
41
|
-
|
43
|
+
attr_accessor :output_buffer
|
44
|
+
def url_for(*args)
|
45
|
+
"fake_url(#{args.inspect})"
|
42
46
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
end
|
48
|
+
|
49
|
+
class TextSelector
|
50
|
+
include ActionDispatch::Assertions::SelectorAssertions
|
51
|
+
include Test::Unit::Assertions
|
52
|
+
def initialize(text)
|
53
|
+
@selected = HTML::Document.new(text).root.children
|
48
54
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
end
|
56
|
+
|
57
|
+
RSpec::Matchers.define :match_select do |*expected|
|
58
|
+
match do |actual|
|
59
|
+
TextSelector.new(actual).assert_select(*expected)
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
63
|
+
|
56
64
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
57
65
|
RSpec.configure do |config|
|
58
66
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
@@ -60,10 +68,14 @@ RSpec.configure do |config|
|
|
60
68
|
config.filter_run :focus
|
61
69
|
|
62
70
|
config.include ActionView::Helpers
|
63
|
-
config.include WillPaginate::
|
71
|
+
config.include WillPaginate::ActionView if Module.const_defined? :WillPaginate
|
64
72
|
config.include Kaminari::ActionViewExtension if Module.const_defined? :Kaminari
|
65
73
|
config.include ActionFaker
|
66
74
|
|
75
|
+
config.before do
|
76
|
+
MagicGrid.logger = NullObject.new
|
77
|
+
end
|
78
|
+
|
67
79
|
# Run specs in random order to surface order dependencies. If you find an
|
68
80
|
# order dependency and want to debug it, you can fix the order by providing
|
69
81
|
# the seed, which is printed after each run.
|
@@ -11,7 +11,7 @@ class SpiderTest < ActionDispatch::IntegrationTest
|
|
11
11
|
def test_users
|
12
12
|
t = tarantula_crawler(self)
|
13
13
|
#t.handlers << Relevance::Tarantula::TidyHandler.new
|
14
|
-
t.crawl_timeout =
|
14
|
+
t.crawl_timeout = 5.seconds
|
15
15
|
t.skip_uri_patterns += @@to_skip
|
16
16
|
t.crawl '/users'
|
17
17
|
end
|
@@ -19,7 +19,7 @@ class SpiderTest < ActionDispatch::IntegrationTest
|
|
19
19
|
def test_posts
|
20
20
|
t = tarantula_crawler(self)
|
21
21
|
#t.handlers << Relevance::Tarantula::TidyHandler.new
|
22
|
-
t.crawl_timeout =
|
22
|
+
t.crawl_timeout = 5.seconds
|
23
23
|
t.skip_uri_patterns += @@to_skip
|
24
24
|
t.crawl '/posts'
|
25
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magic_grid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -106,14 +106,17 @@ files:
|
|
106
106
|
- lib/assets/javascripts/magic_grid.js
|
107
107
|
- lib/tasks/magic_grid_tasks.rake
|
108
108
|
- lib/magic_grid/version.rb
|
109
|
-
- lib/magic_grid/railtie.rb
|
110
109
|
- lib/magic_grid/helpers.rb
|
110
|
+
- lib/magic_grid/collection.rb
|
111
111
|
- lib/magic_grid/engine.rb
|
112
|
+
- lib/magic_grid/logger.rb
|
112
113
|
- lib/magic_grid/definition.rb
|
113
114
|
- lib/locales/en.yml
|
114
115
|
- MIT-LICENSE
|
115
116
|
- Rakefile
|
116
117
|
- README.md
|
118
|
+
- spec/collection_spec.rb
|
119
|
+
- spec/logger_spec.rb
|
117
120
|
- spec/spec_helper.rb
|
118
121
|
- spec/helpers_spec.rb
|
119
122
|
- spec/definition_spec.rb
|
@@ -208,7 +211,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
211
|
version: '0'
|
209
212
|
segments:
|
210
213
|
- 0
|
211
|
-
hash:
|
214
|
+
hash: 3180457643805959296
|
212
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
213
216
|
none: false
|
214
217
|
requirements:
|
@@ -217,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
220
|
version: '0'
|
218
221
|
segments:
|
219
222
|
- 0
|
220
|
-
hash:
|
223
|
+
hash: 3180457643805959296
|
221
224
|
requirements: []
|
222
225
|
rubyforge_project:
|
223
226
|
rubygems_version: 1.8.23
|
@@ -225,6 +228,8 @@ signing_key:
|
|
225
228
|
specification_version: 3
|
226
229
|
summary: Easy collection display grid with column sorting and pagination
|
227
230
|
test_files:
|
231
|
+
- spec/collection_spec.rb
|
232
|
+
- spec/logger_spec.rb
|
228
233
|
- spec/spec_helper.rb
|
229
234
|
- spec/helpers_spec.rb
|
230
235
|
- spec/definition_spec.rb
|
data/lib/magic_grid/railtie.rb
DELETED