sorted 0.3.8 → 0.3.9
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/.document +0 -2
- data/README.rdoc +67 -45
- data/lib/sorted.rb +1 -2
- data/lib/sorted/orms/active_record.rb +17 -0
- data/lib/sorted/parser.rb +79 -0
- data/lib/sorted/railtie.rb +2 -2
- data/lib/sorted/toggler.rb +8 -1
- data/lib/sorted/version.rb +1 -1
- data/lib/sorted/view_helpers/action_view.rb +19 -4
- data/sorted.gemspec +1 -2
- data/spec/sorted/orms/active_record_spec.rb +11 -0
- data/spec/sorted/parser_spec.rb +90 -0
- data/spec/sorted/toggler_spec.rb +57 -0
- data/spec/sorted/view_helpers/action_view_spec.rb +37 -0
- data/spec/spec_helper.rb +2 -2
- metadata +17 -17
- data/.watchr +0 -24
- data/lib/sorted/finders/active_record.rb +0 -41
- data/lib/sorted/sorter.rb +0 -122
- data/spec/sorted_spec.rb +0 -122
- data/spec/sorter_spec.rb +0 -65
- data/spec/toggler_spec.rb +0 -39
data/.document
CHANGED
data/README.rdoc
CHANGED
@@ -1,87 +1,109 @@
|
|
1
1
|
= sorted
|
2
2
|
|
3
|
-
Sorted is a simple object that will take an sql order string and a url
|
3
|
+
Sorted is a simple object that will take an sql order string and a url
|
4
|
+
sort string to let you sort large datasets over many pages (using
|
5
|
+
{will_paginate}[http://github.com/mislav/will_paginatea] or
|
6
|
+
{kaminari}[https://github.com/amatsuda/kaminari]) without loosing state.
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
== Example
|
8
|
+
If you would like to see it in action clone the
|
9
|
+
{example app}[https://github.com/mynameisrufus/sorted_app]
|
8
10
|
|
9
11
|
=== Gemfile
|
10
12
|
|
11
|
-
gem sorted
|
13
|
+
gem 'sorted' '~> 0.3.9'
|
12
14
|
|
13
15
|
=== View
|
14
16
|
|
15
17
|
link_to_sorted "Email", :email
|
16
18
|
|
17
|
-
This will
|
19
|
+
This will generate a link with a url like this:
|
18
20
|
|
19
21
|
http://myapp/users?sort=email_asc
|
20
22
|
|
21
|
-
|
23
|
+
and on the next page load when you then sort by something else....
|
22
24
|
|
23
25
|
http://myapp/users?sort=name_asc!email_asc
|
24
26
|
|
25
27
|
=== Model
|
26
28
|
|
27
|
-
This will initially sort by email ascending
|
29
|
+
This will initially sort by email ascending with the optional second
|
30
|
+
default order argument:
|
31
|
+
|
32
|
+
@users = User.sort(params[:sort], "email ASC").page(params[:page])
|
33
|
+
|
34
|
+
==== Joins and includes
|
35
|
+
|
36
|
+
If you want to sort by a belongs to relationship add the table name to
|
37
|
+
the order argument. For example assuming a user belongs to a company:
|
38
|
+
|
39
|
+
@users = User.joins(:company).sort(params[:sort], "companies.name ASC").page(params[:page])
|
40
|
+
|
41
|
+
When generating links using the +link_to_sorted+ method you should
|
42
|
+
specify the table for every attribute you use as well otherwise you
|
43
|
+
will probably get an ambiguous column name error.
|
44
|
+
|
45
|
+
<th class="ui-state-default"><%= link_to_sorted "Company name", 'companies.name' %></th>
|
46
|
+
<th class="ui-state-default"><%= link_to_sorted "Users name", 'users.name' %></th>
|
47
|
+
|
48
|
+
==== Typecasting and DB functions
|
28
49
|
|
29
|
-
|
50
|
+
Do your type casting and function calls in your select statement with an
|
51
|
+
alias, for example:
|
30
52
|
|
31
|
-
|
53
|
+
# controller
|
54
|
+
@users = User.select("income::BigInt as bg_income").sort(params[:sort], "bg_income ASC")
|
55
|
+
|
56
|
+
# view
|
57
|
+
<th class="ui-state-default"><%= link_to_sorted "Income", 'bg_income' %></th>
|
32
58
|
|
33
|
-
|
34
|
-
RELATIONS is the name of the relationship table and COLUMN is an attribute in that table. For example,
|
35
|
-
assuming the User model belongs_to a :company.
|
59
|
+
or using a DB function:
|
36
60
|
|
37
|
-
|
61
|
+
# controller
|
62
|
+
@users = User.select("inet_aton(`ip_address`) AS in_ip").sort(params[:sort], "in_ip ASC")
|
63
|
+
|
64
|
+
# view
|
65
|
+
<th class="ui-state-default"><%= link_to_sorted "IP address", 'in_ip' %></th>
|
38
66
|
|
39
67
|
== Presentation
|
40
68
|
|
41
|
-
You might want to roll your own link_to_sorted method to use jQuery ui
|
69
|
+
You might want to roll your own +link_to_sorted+ method to use jQuery ui
|
70
|
+
css classes for example, all you need is the sorted object.
|
42
71
|
|
43
72
|
def link_to_sorted(name, order)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
73
|
+
dup_params = (request.get? && !params.nil?) ? params.dup : nil
|
74
|
+
sorter = ActionView::Base::SortedViewHelper.new(order, dup_params)
|
75
|
+
css_class = case sorter.css
|
76
|
+
when "sorted asc"
|
77
|
+
"ui-icon ui-icon-triangle-1-n"
|
78
|
+
when "sorted desc"
|
79
|
+
"ui-icon ui-icon-triangle-1-s"
|
80
|
+
when "sorted"
|
81
|
+
"ui-icon ui-icon-carat-2-n-s"
|
82
|
+
end
|
53
83
|
link_to(content_tag(:span, nil, {:class => css_class}) + name.to_s, sorter.params)
|
54
84
|
end
|
55
85
|
|
56
|
-
Tables are best displayed with alternating shades for each row, so
|
57
|
-
|
58
|
-
def odd_even
|
59
|
-
@odd_even ||= 0
|
60
|
-
@odd_even += 1
|
61
|
-
(@odd_even % 2) == 1 ? 'odd' : 'even'
|
62
|
-
end
|
63
|
-
|
64
|
-
Then in your table do something like this:
|
86
|
+
Tables are best displayed with alternating shades for each row, so add
|
87
|
+
an alternating class to you table rows using the rails +cycle+ method:
|
65
88
|
|
66
|
-
<tr class="<%=
|
89
|
+
<tr class="<%= cycle 'odd', 'even' %>">
|
67
90
|
|
68
91
|
== Rails 2.3.x
|
69
92
|
|
70
|
-
|
93
|
+
Sorted works with rails 2.3.x but you will have to roll your own scope
|
94
|
+
and view helper.
|
71
95
|
|
72
96
|
Here is the named scope for your model(s):
|
73
97
|
|
74
|
-
named_scope :
|
75
|
-
{ :order => Sorted::
|
98
|
+
named_scope :sort, lambda { |sort, order|
|
99
|
+
{ :order => Sorted::Parser.new(sort, order).to_sql }
|
76
100
|
}
|
77
101
|
|
78
|
-
and the
|
102
|
+
and the application helper method:
|
79
103
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
sorter = sorted(order)
|
86
|
-
link_to(name, sorter.params, {:class => sorter.to_css})
|
104
|
+
def link_to_sorted(name, order, options = {})
|
105
|
+
dup_params = (request.get? && !params.nil?) ? params.dup : nil
|
106
|
+
sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new(order, dup_params)
|
107
|
+
options[:class] = [options[:class], sorter.css].join(' ').strip
|
108
|
+
link_to(name.to_s, sorter.params, options)
|
87
109
|
end
|
data/lib/sorted.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'sorted'
|
3
|
+
|
4
|
+
module Sorted
|
5
|
+
module Orms
|
6
|
+
module ActiveRecord
|
7
|
+
def self.enable!
|
8
|
+
::ActiveRecord::Base.class_eval do
|
9
|
+
def self.sort(sort, order = nil)
|
10
|
+
sorter = ::Sorted::Parser.new(sort, order)
|
11
|
+
order sorter.to_sql
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'sorted/toggler'
|
2
|
+
|
3
|
+
module Sorted
|
4
|
+
# Takes a sort query string and an SQL order string and parses the
|
5
|
+
# values to produce key value pairs.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# Sorted::Parser.new('phone_desc', 'name ASC').to_s #-> "phone_desc!name_asc"
|
9
|
+
class Parser
|
10
|
+
attr_reader :sort, :order, :sorts, :orders
|
11
|
+
|
12
|
+
# Regex to make sure we only get valid names and not injected code.
|
13
|
+
SORTED_QUERY_REGEX = /([a-zA-Z0-9._]+)_(asc|desc)$/
|
14
|
+
SQL_REGEX = /(([a-z0-9._]+)\s([asc|desc]+)|[a-z0-9._]+)/i
|
15
|
+
|
16
|
+
def initialize(sort, order = nil)
|
17
|
+
@sort = sort
|
18
|
+
@order = order
|
19
|
+
@sorts = parse_sort
|
20
|
+
@orders = parse_order
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_sort
|
24
|
+
sort.to_s.split(/!/).map do |sort_string|
|
25
|
+
if m = sort_string.match(SORTED_QUERY_REGEX)
|
26
|
+
[m[1], m[2].downcase]
|
27
|
+
end
|
28
|
+
end.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_order
|
32
|
+
order.to_s.split(/,/).map do |order_string|
|
33
|
+
if m = order_string.match(SQL_REGEX)
|
34
|
+
[(m[2].nil? ? m[1] : m[2]),(m[3].nil? ? "asc" : m[3].downcase)]
|
35
|
+
end
|
36
|
+
end.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_hash
|
40
|
+
array.inject({}){|h,a| h.merge(Hash[a[0],a[1]])}
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_sql
|
44
|
+
array.map{|a| "#{a[0]} #{a[1].upcase}" }.join(', ')
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
array.map{|a| a.join('_') }.join('!')
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_a
|
52
|
+
array
|
53
|
+
end
|
54
|
+
|
55
|
+
def toggle
|
56
|
+
@array = Toggler.new(sorts, orders).to_a
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def reset
|
61
|
+
@array = default
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def array
|
68
|
+
@array ||= default
|
69
|
+
end
|
70
|
+
|
71
|
+
def default
|
72
|
+
sorts_new = sorts.dup
|
73
|
+
orders.each do |o|
|
74
|
+
sorts_new << o unless sorts_new.flatten.include?(o[0])
|
75
|
+
end
|
76
|
+
sorts_new
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/sorted/railtie.rb
CHANGED
@@ -4,8 +4,8 @@ module Sorted
|
|
4
4
|
class Railtie < Rails::Railtie
|
5
5
|
initializer "sorted.active_record" do |app|
|
6
6
|
if defined? ::ActiveRecord
|
7
|
-
require 'sorted/
|
8
|
-
Sorted::
|
7
|
+
require 'sorted/orms/active_record'
|
8
|
+
Sorted::Orms::ActiveRecord.enable!
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
data/lib/sorted/toggler.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
module Sorted
|
2
|
+
# Takes a parsed arrays of sorts and orders, it then will reorder the
|
3
|
+
# pairs and flip the assendance of the first sort pair.
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# sorts = [['name', 'asc'], ['phone', 'desc']]
|
7
|
+
# oredrs = [['name', 'asc']]
|
8
|
+
# Sorted::Toggler.new(sorts, orders).to_a #-> [['name', 'desc'], ['phone', 'desc']]
|
2
9
|
class Toggler
|
3
|
-
def initialize(
|
10
|
+
def initialize(sorts, orders)
|
4
11
|
@array = []
|
5
12
|
@sorts = sorts
|
6
13
|
@orders = orders
|
data/lib/sorted/version.rb
CHANGED
@@ -4,13 +4,28 @@ require 'sorted'
|
|
4
4
|
module Sorted
|
5
5
|
module ViewHelpers
|
6
6
|
module ActionView
|
7
|
-
|
8
|
-
|
7
|
+
class SortedViewHelper
|
8
|
+
attr_reader :params
|
9
|
+
|
10
|
+
def initialize(order, params)
|
11
|
+
sort = params.delete :sort
|
12
|
+
@params = params
|
13
|
+
@parser = ::Sorted::Parser.new(sort, order).toggle
|
14
|
+
@params[:sort] = @parser.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def css
|
18
|
+
if @parser.sorts.flatten.include? @parser.orders[0][0]
|
19
|
+
"sorted #{@parser.sorts.assoc(@parser.orders[0][0]).last}"
|
20
|
+
else
|
21
|
+
"sorted"
|
22
|
+
end
|
23
|
+
end
|
9
24
|
end
|
10
25
|
|
11
26
|
def link_to_sorted(name, order, options = {})
|
12
|
-
sorter =
|
13
|
-
options[:class] = [options[:class], sorter.
|
27
|
+
sorter = SortedViewHelper.new(order, ((request.get? && !params.nil?) ? params.dup : nil))
|
28
|
+
options[:class] = [options[:class], sorter.css].join(' ').strip
|
14
29
|
link_to(name.to_s, sorter.params, options)
|
15
30
|
end
|
16
31
|
end
|
data/sorted.gemspec
CHANGED
@@ -15,10 +15,9 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "sorted"
|
16
16
|
|
17
17
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
18
|
-
s.add_development_dependency "rails", ">= 3.
|
18
|
+
s.add_development_dependency "rails", ">= 3.1.2"
|
19
19
|
s.add_development_dependency "rspec", ">= 2.0.0"
|
20
20
|
|
21
|
-
|
22
21
|
s.files = `git ls-files`.split("\n")
|
23
22
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
24
23
|
s.require_path = 'lib'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sorted::Parser, "params parsing" do
|
4
|
+
it "should not raise if pased nil arguments" do
|
5
|
+
lambda { Sorted::Parser.new(nil, nil).toggle }.should_not raise_error
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should return a nice array from the order sql" do
|
9
|
+
sort = nil
|
10
|
+
order = "email ASC, phone ASC, name DESC"
|
11
|
+
result = [["email", "asc"], ["phone", "asc"], ["name", "desc"]]
|
12
|
+
|
13
|
+
sorter = Sorted::Parser.new(sort, order)
|
14
|
+
sorter.orders.should eq result
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return a nice array from the sort params" do
|
18
|
+
sort = "email_desc!name_desc"
|
19
|
+
order = nil
|
20
|
+
result = [["email", "desc"], ["name", "desc"]]
|
21
|
+
|
22
|
+
sorter = Sorted::Parser.new(sort, order)
|
23
|
+
sorter.sorts.should eq result
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should combine sort and order params with sort params being of higer importance" do
|
27
|
+
sort = "email_desc!name_desc"
|
28
|
+
order = "email ASC, phone ASC, name DESC"
|
29
|
+
result = [["email", "desc"], ["name", "desc"], ["phone", "asc"]]
|
30
|
+
|
31
|
+
sorter = Sorted::Parser.new(sort, order)
|
32
|
+
sorter.to_a.should eq result
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should allow numbers, underscores and full stops in sort params" do
|
36
|
+
sort = "assessmentsTable.name_desc!users_300.name_5_desc"
|
37
|
+
order = nil
|
38
|
+
result = [["assessmentsTable.name", "desc"], ["users_300.name_5", "desc"]]
|
39
|
+
|
40
|
+
sorter = Sorted::Parser.new(sort, order)
|
41
|
+
sorter.sorts.should eq result
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should allow numbers, underscores and full stops in order params" do
|
45
|
+
sort = nil
|
46
|
+
order = "assessmentsTable.name ASC, users_300.name_5 ASC"
|
47
|
+
result = [["assessmentsTable.name", "asc"], ["users_300.name_5", "asc"]]
|
48
|
+
|
49
|
+
sorter = Sorted::Parser.new(sort, order)
|
50
|
+
sorter.orders.should eq result
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should default to asc if sort params order is ommited" do
|
54
|
+
sort = nil
|
55
|
+
order = :email
|
56
|
+
result = [["email", "asc"]]
|
57
|
+
|
58
|
+
sorter = Sorted::Parser.new(sort, order)
|
59
|
+
sorter.orders.should eq result
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Sorted::Parser, "return types" do
|
64
|
+
it "should return an sql sort string" do
|
65
|
+
sort = "email_desc!name_desc"
|
66
|
+
order = "email ASC, phone ASC, name DESC"
|
67
|
+
result = "email DESC, name DESC, phone ASC"
|
68
|
+
|
69
|
+
sorter = Sorted::Parser.new(sort, order)
|
70
|
+
sorter.to_sql.should eq result
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should return an hash" do
|
74
|
+
sort = "email_desc!name_desc"
|
75
|
+
order = "email ASC, phone ASC, name DESC"
|
76
|
+
result = {"email" => "desc", "name" => "desc", "phone" => "asc"}
|
77
|
+
|
78
|
+
sorter = Sorted::Parser.new(sort, order)
|
79
|
+
sorter.to_hash.should eq result
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should return an the encoded sort string" do
|
83
|
+
sort = "email_desc!name_desc"
|
84
|
+
order = "email ASC, phone ASC, name DESC"
|
85
|
+
result = "email_desc!name_desc!phone_asc"
|
86
|
+
|
87
|
+
sorter = Sorted::Parser.new(sort, order)
|
88
|
+
sorter.to_s.should eq result
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sorted::Toggler do
|
4
|
+
it "should bring phone to first order importance but not toggle ascendance" do
|
5
|
+
orders = [["email", "asc"], ["phone", "asc"]]
|
6
|
+
sorts = [["phone", "asc"]]
|
7
|
+
result = [["phone", "asc"], ["email", "asc"]]
|
8
|
+
|
9
|
+
toggler = Sorted::Toggler.new(sorts, orders)
|
10
|
+
toggler.to_a.should eq result
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should toggle ascendance of email" do
|
14
|
+
orders = [["email", "desc"]]
|
15
|
+
sorts = [["email", "asc"]]
|
16
|
+
result = [["email", "desc"]]
|
17
|
+
|
18
|
+
toggler = Sorted::Toggler.new(sorts, orders)
|
19
|
+
toggler.to_a.should eq result
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return both order params un-toggled with no sort param" do
|
23
|
+
orders = [["email", "asc"], ["phone", "asc"]]
|
24
|
+
sorts = []
|
25
|
+
result = [["email", "asc"], ["phone", "asc"]]
|
26
|
+
|
27
|
+
toggler = Sorted::Toggler.new(sorts, orders)
|
28
|
+
toggler.to_a.should eq result
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should toggle the email ascendance" do
|
32
|
+
orders = [["email", "asc"]]
|
33
|
+
sorts = [["email", "asc"], ["phone", "asc"]]
|
34
|
+
result = [["email", "desc"], ["phone", "asc"]]
|
35
|
+
|
36
|
+
toggler = Sorted::Toggler.new(sorts, orders)
|
37
|
+
toggler.to_a.should eq result
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should toggle the email ascendance" do
|
41
|
+
orders = [["email", "desc"]]
|
42
|
+
sorts = [["email", "asc"], ["phone", "asc"]]
|
43
|
+
result = [["email", "desc"], ["phone", "asc"]]
|
44
|
+
|
45
|
+
toggler = Sorted::Toggler.new(sorts, orders)
|
46
|
+
toggler.to_a.should eq result
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should toggle two 1..n sort values" do
|
50
|
+
orders = [["email", "asc"], ["phone", "asc"]]
|
51
|
+
sorts = [["email", "asc"], ["phone", "asc"]]
|
52
|
+
result = [["email", "desc"], ["phone", "desc"]]
|
53
|
+
|
54
|
+
toggler = Sorted::Toggler.new(sorts, orders)
|
55
|
+
toggler.to_a.should eq result
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sorted::ViewHelpers::ActionView do
|
4
|
+
it "should integrate with ActiveRecord::Base" do
|
5
|
+
ActionView::Base.send(:include, Sorted::ViewHelpers::ActionView)
|
6
|
+
ActionView::Base.new.should respond_to(:link_to_sorted)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Sorted::ViewHelpers::ActionView::SortedViewHelper do
|
11
|
+
it "should return the default sort order and preserve the existing params" do
|
12
|
+
order = :email
|
13
|
+
params = { :page => 10 }
|
14
|
+
result = { :page => 10, :sort => "email_asc" }
|
15
|
+
|
16
|
+
sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
|
17
|
+
sorter.params.should eq result
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should only return the sorted css class if email has not yet been sorted" do
|
21
|
+
order = :email
|
22
|
+
params = {}
|
23
|
+
result = "sorted"
|
24
|
+
|
25
|
+
sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
|
26
|
+
sorter.css.should eq result
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should only return the sorted css class if email has not yet been sorted" do
|
30
|
+
order = :email
|
31
|
+
params = { :sort => "email_asc" }
|
32
|
+
result = "sorted asc"
|
33
|
+
|
34
|
+
sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
|
35
|
+
sorter.css.should eq result
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
-
require 'sorted
|
3
|
+
require 'sorted'
|
4
|
+
require 'sorted/orms/active_record'
|
4
5
|
require 'sorted/view_helpers/action_view'
|
5
6
|
require 'rspec'
|
6
|
-
require 'rspec/autorun'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sorted
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
|
-
requirement: &
|
16
|
+
requirement: &70134746957060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,21 @@ dependencies:
|
|
21
21
|
version: 1.0.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70134746957060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &70134746956600 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 3.
|
32
|
+
version: 3.1.2
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70134746956600
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70134746956100 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 2.0.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70134746956100
|
47
47
|
description: lets you sort large data sets using view helpers and a scope
|
48
48
|
email:
|
49
49
|
- rufuspost@gmail.com
|
@@ -53,23 +53,23 @@ extra_rdoc_files: []
|
|
53
53
|
files:
|
54
54
|
- .document
|
55
55
|
- .gitignore
|
56
|
-
- .watchr
|
57
56
|
- Gemfile
|
58
57
|
- LICENSE
|
59
58
|
- README.rdoc
|
60
59
|
- Rakefile
|
61
60
|
- lib/sorted.rb
|
62
|
-
- lib/sorted/
|
61
|
+
- lib/sorted/orms/active_record.rb
|
62
|
+
- lib/sorted/parser.rb
|
63
63
|
- lib/sorted/railtie.rb
|
64
|
-
- lib/sorted/sorter.rb
|
65
64
|
- lib/sorted/toggler.rb
|
66
65
|
- lib/sorted/version.rb
|
67
66
|
- lib/sorted/view_helpers/action_view.rb
|
68
67
|
- sorted.gemspec
|
69
|
-
- spec/
|
70
|
-
- spec/
|
68
|
+
- spec/sorted/orms/active_record_spec.rb
|
69
|
+
- spec/sorted/parser_spec.rb
|
70
|
+
- spec/sorted/toggler_spec.rb
|
71
|
+
- spec/sorted/view_helpers/action_view_spec.rb
|
71
72
|
- spec/spec_helper.rb
|
72
|
-
- spec/toggler_spec.rb
|
73
73
|
homepage: http://rubygems.org/gems/sorted
|
74
74
|
licenses: []
|
75
75
|
post_install_message:
|
@@ -84,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
84
|
version: '0'
|
85
85
|
segments:
|
86
86
|
- 0
|
87
|
-
hash:
|
87
|
+
hash: -354722037037653326
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
93
|
version: 1.3.6
|
94
94
|
requirements: []
|
95
95
|
rubyforge_project: sorted
|
96
|
-
rubygems_version: 1.8.
|
96
|
+
rubygems_version: 1.8.11
|
97
97
|
signing_key:
|
98
98
|
specification_version: 3
|
99
99
|
summary: sort data with a database
|
data/.watchr
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module WatchrActions
|
2
|
-
def self.run_spec(file)
|
3
|
-
unless File.exist?(file)
|
4
|
-
puts "#{file} does not exist"
|
5
|
-
return
|
6
|
-
end
|
7
|
-
|
8
|
-
puts "Running #{file}"
|
9
|
-
system "rspec #{file}"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
watch(/^lib\/(?:sorted\/)?(.*).rb/) do |m|
|
14
|
-
WatchrActions.run_spec("spec/#{m[1]}_spec.rb")
|
15
|
-
end
|
16
|
-
|
17
|
-
watch(/^spec\/.*_spec.rb/) do |m|
|
18
|
-
WatchrActions.run_spec(m[0])
|
19
|
-
end
|
20
|
-
|
21
|
-
watch(/^lib\/sorted\/finders\/active_record.rb/) do |m|
|
22
|
-
WatchrActions.run_spec('spec/sorted_spec.rb')
|
23
|
-
end
|
24
|
-
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'sorted'
|
3
|
-
|
4
|
-
module Sorted
|
5
|
-
module Finders
|
6
|
-
module ActiveRecord
|
7
|
-
def self.enable!
|
8
|
-
::ActiveRecord::Base.class_eval do
|
9
|
-
# Define a symbolic sort column. This allows mapping a simple column name
|
10
|
-
# to a more complex sql order clause.
|
11
|
-
# class Model < ActiveRecord::Base
|
12
|
-
# symbolic_sort :ip_address, 'inet_aton(`ip_address`)'
|
13
|
-
# end
|
14
|
-
def self.symbolic_sort(key, sql)
|
15
|
-
symbolic_sorts[key] = sql
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.sorted(params)
|
19
|
-
sorter = ::Sorted::Sorter.new(params[:order], :sort => params[:sort], :symbolic_sorts => symbolic_sorts)
|
20
|
-
# Check if we parsed some relationship includes and apply them
|
21
|
-
# before applying the order
|
22
|
-
relation = self
|
23
|
-
if sorter.includes.size > 0
|
24
|
-
# Remove self.name from includes
|
25
|
-
my_name = self.name.to_sym
|
26
|
-
real_includes = sorter.includes.delete_if{|include_name| include_name == my_name}
|
27
|
-
relation = includes(real_includes) if real_includes.size > 0
|
28
|
-
end
|
29
|
-
relation.order(sorter.to_sql)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def self.symbolic_sorts
|
35
|
-
@symbolic_sorts ||= {}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/sorted/sorter.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
module Sorted
|
2
|
-
class Sorter
|
3
|
-
attr_reader :includes
|
4
|
-
def initialize(order, params = nil)
|
5
|
-
@includes = []
|
6
|
-
@symbolic_sorts = {}
|
7
|
-
|
8
|
-
if order.is_a?(String) || order.is_a?(Symbol)
|
9
|
-
parse_order(order)
|
10
|
-
end
|
11
|
-
if params.is_a?(Hash)
|
12
|
-
@params = params
|
13
|
-
if @params[:sort].is_a?(String)
|
14
|
-
parse_sort @params[:sort]
|
15
|
-
end
|
16
|
-
@symbolic_sorts = @params[:symbolic_sorts] || {}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def parse_sort(sort_string)
|
21
|
-
sort_string.split(/!/).each do |sort|
|
22
|
-
if parsed = parse_query(sort)
|
23
|
-
sorts << parsed
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def parse_order(order_string_or_symbol)
|
29
|
-
order_string_or_symbol.to_s.split(/,/).each do |order|
|
30
|
-
if parsed = parse_sql(order)
|
31
|
-
orders << parsed
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def parse_query(sort)
|
37
|
-
if m = sort.match(/([a-zA-Z0-9._]+)_(asc|desc)$/)
|
38
|
-
parse_include(m[1])
|
39
|
-
[m[1],m[2]]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def parse_sql(order)
|
44
|
-
if m = order.match(/(([a-zA-Z._:][a-zA-Z._:0-9]*)\s([asc|ASC|desc|DESC]+)|[a-zA-Z._:][a-zA-Z._:0-9]*)/)
|
45
|
-
sort_column = (m[2].nil? ? m[1] : m[2])
|
46
|
-
parse_include(sort_column)
|
47
|
-
[sort_column,(m[3].nil? ? "asc" : m[3].downcase)]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def parse_include(order)
|
52
|
-
if match_data = /^([^\.]+)\..+/.match(order)
|
53
|
-
include_name = match_data[1].singularize.to_sym
|
54
|
-
@includes << include_name unless @includes.include?(include_name)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def toggle
|
59
|
-
@array = Toggler.new(orders, sorts).to_a
|
60
|
-
self
|
61
|
-
end
|
62
|
-
|
63
|
-
def reset
|
64
|
-
@array = default
|
65
|
-
self
|
66
|
-
end
|
67
|
-
|
68
|
-
def to_hash
|
69
|
-
array.inject({}){|h,a| h.merge(Hash[a[0],a[1]])}
|
70
|
-
end
|
71
|
-
|
72
|
-
def to_sql
|
73
|
-
array.map do |a|
|
74
|
-
column = @symbolic_sorts[a[0].to_sym] || a[0]
|
75
|
-
"#{column} #{a[1].upcase}"
|
76
|
-
end.join(', ')
|
77
|
-
end
|
78
|
-
|
79
|
-
def to_s
|
80
|
-
array.map{|a| a.join('_')}.join('!')
|
81
|
-
end
|
82
|
-
|
83
|
-
def to_a
|
84
|
-
array
|
85
|
-
end
|
86
|
-
|
87
|
-
def to_css
|
88
|
-
if sorts.flatten.include?(orders[0][0])
|
89
|
-
"sorted #{sorts.assoc(orders[0][0]).last}"
|
90
|
-
else
|
91
|
-
"sorted"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def params
|
96
|
-
@params ||= {}
|
97
|
-
@params[:sort] = to_s
|
98
|
-
@params
|
99
|
-
end
|
100
|
-
|
101
|
-
def orders
|
102
|
-
@orders ||= []
|
103
|
-
end
|
104
|
-
|
105
|
-
def sorts
|
106
|
-
@sorts ||= []
|
107
|
-
end
|
108
|
-
|
109
|
-
private
|
110
|
-
def default
|
111
|
-
sorts_new = sorts.dup
|
112
|
-
orders.each do |order|
|
113
|
-
sorts_new << order unless sorts_new.flatten.include?(order[0])
|
114
|
-
end
|
115
|
-
sorts_new
|
116
|
-
end
|
117
|
-
|
118
|
-
def array
|
119
|
-
@array ||= default
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
data/spec/sorted_spec.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'action_controller'
|
3
|
-
require 'sorted'
|
4
|
-
|
5
|
-
describe Sorted::Finders::ActiveRecord do
|
6
|
-
before(:each) do
|
7
|
-
Sorted::Finders::ActiveRecord.enable!
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should integrate with ActiveRecord::Base" do
|
11
|
-
ActiveRecord::Base.should respond_to(:sorted)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should define a symbolic_sorts method" do
|
15
|
-
ActiveRecord::Base.should respond_to(:symbolic_sort)
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should define symbolic_sorts" do
|
19
|
-
a = Class.new(ActiveRecord::Base)
|
20
|
-
b = Class.new(ActiveRecord::Base)
|
21
|
-
|
22
|
-
a.symbolic_sort(:foo, 'foo')
|
23
|
-
b.symbolic_sort(:bar, 'bar')
|
24
|
-
|
25
|
-
a.instance_variable_get(:@symbolic_sorts).should == {:foo => 'foo'}
|
26
|
-
b.instance_variable_get(:@symbolic_sorts).should == {:bar => 'bar'}
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should add orders to the relation" do
|
30
|
-
a = Class.new(ActiveRecord::Base)
|
31
|
-
relation = a.sorted(:order => nil, :sort => 'a_asc')
|
32
|
-
relation.order_values.should == ["a ASC"]
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should add orders to the relation using symbolic_sorts" do
|
36
|
-
a = Class.new(ActiveRecord::Base)
|
37
|
-
a.symbolic_sort(:ip, 'inet_aton(`ip`)')
|
38
|
-
relation = a.sorted(:order => nil, :sort => 'ip_asc')
|
39
|
-
relation.order_values.should == ["inet_aton(`ip`) ASC"]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe Sorted::ViewHelpers::ActionView do
|
44
|
-
before(:each) do
|
45
|
-
class TestController
|
46
|
-
def params
|
47
|
-
@params ||= {}
|
48
|
-
end
|
49
|
-
|
50
|
-
def params=(params)
|
51
|
-
@params = params
|
52
|
-
end
|
53
|
-
|
54
|
-
def request
|
55
|
-
Request.new
|
56
|
-
end
|
57
|
-
|
58
|
-
def _prefixes
|
59
|
-
end
|
60
|
-
end
|
61
|
-
class Request
|
62
|
-
def get?; true end
|
63
|
-
end
|
64
|
-
@controller = TestController.new
|
65
|
-
ActionView::Base.send(:include, Sorted::ViewHelpers::ActionView)
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should integrate with ActionView::Base" do
|
69
|
-
ActionView::Base.new.should respond_to(:sorted)
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should integrate with ActionView::Base" do
|
73
|
-
ActionView::Base.new.should respond_to(:link_to_sorted)
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should not change the direction of name using view helper" do
|
77
|
-
@controller.params = {:sort => "name_desc!email_asc"}
|
78
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
79
|
-
sorter.toggle.to_a.should == [["email", "asc"], ["name", "desc"]]
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should reverse email direction using view helper" do
|
83
|
-
@controller.params = {:sort => "email_asc!name_desc"}
|
84
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
85
|
-
sorter.toggle.to_a.should == [["email", "desc"], ["name", "desc"]]
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should reverse email direction using view helper" do
|
89
|
-
@controller.params = {:sort => "email_desc!name_desc!phone_desc"}
|
90
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
91
|
-
sorter.toggle.params.should == {:sort => "email_asc!name_desc!phone_desc"}
|
92
|
-
@controller.params = sorter.params
|
93
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
94
|
-
sorter.toggle.params.should == {:sort => "email_desc!name_desc!phone_desc"}
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should not reverse order when made first again" do
|
98
|
-
@controller.params = {:sort => "phone_desc!name_desc!email_desc"}
|
99
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
100
|
-
sorter.toggle.params.should == {:sort => "email_desc!phone_desc!name_desc"}
|
101
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:name)
|
102
|
-
sorter.toggle.params.should == {:sort => "name_desc!phone_desc!email_desc"}
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should order correctly" do
|
106
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
107
|
-
sorter.toggle.params.should == {:sort => "email_asc"}
|
108
|
-
@controller.params = sorter.params
|
109
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:name)
|
110
|
-
sorter.toggle.params.should == {:sort => "name_asc!email_asc"}
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should return a hash of options for url builder with sorted query string" do
|
114
|
-
@controller.params = {:sort => "email_asc!name_desc", :page => 2}
|
115
|
-
ActionView::Base.new([], {}, @controller).sorted(:email).params.should == {:sort => "email_desc!name_desc", :page => 2}
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should not die if params nil" do
|
119
|
-
sorter = ActionView::Base.new([], {}, @controller).sorted(:email)
|
120
|
-
sorter.params.should == {:sort => "email_asc"}
|
121
|
-
end
|
122
|
-
end
|
data/spec/sorter_spec.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'action_controller'
|
3
|
-
require 'sorted'
|
4
|
-
|
5
|
-
describe Sorted::Sorter, "parse methods" do
|
6
|
-
it "should not die if pased dumb things" do
|
7
|
-
lambda { Sorted::Sorter.new(false, Time.now).should_not }.should_not raise_error
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should return a nice array from the order sql" do
|
11
|
-
sorter = Sorted::Sorter.new("email ASC, phone ASC, name DESC", {:sort => "email_desc!name_desc"})
|
12
|
-
sorter.orders.should == [["email", "asc"], ["phone", "asc"], ["name", "desc"]]
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should return a nice array from the sort params" do
|
16
|
-
sorter = Sorted::Sorter.new("email ASC, phone ASC, name DESC", {:sort => "email_desc!name_desc"})
|
17
|
-
sorter.sorts.should == [["email", "desc"], ["name", "desc"]]
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should allow numbers, underscores, full stops and colons in" do
|
21
|
-
sorter = Sorted::Sorter.new('users.email ASC, users.phone_number DESC, assessments.name ASC, assessments.number_as_string::BigInt, assessments.column_with_number_123', {:sort => "users.email_desc!users.first_name_desc"})
|
22
|
-
sorter.to_sql.should == "users.email DESC, users.first_name DESC, users.phone_number DESC, assessments.name ASC, assessments.number_as_string::BigInt ASC, assessments.column_with_number_123 ASC"
|
23
|
-
sorter.includes.size.should == 2
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe Sorted::Sorter, "logic:" do
|
28
|
-
it "should not toggle the sort order and include any sql orders not in sort params" do
|
29
|
-
sorter = Sorted::Sorter.new("email ASC, phone ASC, name DESC", {:sort => "email_desc!name_desc"})
|
30
|
-
sorter.to_a.should == [["email", "desc"], ["name", "desc"], ["phone", "asc"]]
|
31
|
-
sorter.includes.size.should == 0
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should return an sql sort string" do
|
35
|
-
Sorted::Sorter.new(:email).to_sql.should == "email ASC"
|
36
|
-
Sorted::Sorter.new(:email, {:sort => "name_desc!email_desc"}).to_sql.should == "name DESC, email DESC"
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should handle a large initial order string" do
|
40
|
-
sorter = Sorted::Sorter.new('email ASC, name DESC, phone ASC', {:sort => "email_desc!name_desc"})
|
41
|
-
sorter.to_sql.should == "email DESC, name DESC, phone ASC"
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should handle a large initial order string" do
|
45
|
-
sorter = Sorted::Sorter.new('email ASC, phone DESC, name ASC', {:sort => "email_desc!name_desc"})
|
46
|
-
sorter.to_sql.should == "email DESC, name DESC, phone DESC"
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should substitute symbolic sorts" do
|
50
|
-
sorter = Sorted::Sorter.new('ip_address', :symbolic_sorts => {:ip_address => 'inet_aton(`ip_address`)'})
|
51
|
-
sorter.to_sql.should == "inet_aton(`ip_address`) ASC"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe Sorted::Sorter, "to_css" do
|
56
|
-
it "should return css base class for to_css if not in sort params" do
|
57
|
-
sorter = Sorted::Sorter.new(:email)
|
58
|
-
sorter.to_css.should == "sorted"
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should return css class for to_css" do
|
62
|
-
sorter = Sorted::Sorter.new(:email, {:sort => "email_desc"})
|
63
|
-
sorter.to_css.should == "sorted desc"
|
64
|
-
end
|
65
|
-
end
|
data/spec/toggler_spec.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'action_controller'
|
3
|
-
require 'sorted'
|
4
|
-
|
5
|
-
describe Sorted::Toggler, "toggle sorts" do
|
6
|
-
it "should should fail becasue the sort order is incorect" do
|
7
|
-
sorter = Sorted::Sorter.new(:jsci_complete, {:sort => "parent_id_desc!non_vocational_complete_desc!jsci_complete_desc"})
|
8
|
-
sorter.toggle
|
9
|
-
sorter.to_s.should_not == "parent_id_desc!non_vocational_complete_desc!jsci_complete_desc"
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should toggle two order params at once" do
|
13
|
-
first = Sorted::Sorter.new("email ASC, phone ASC")
|
14
|
-
first.toggle.to_a.should == [["email", "asc"],["phone", "asc"]]
|
15
|
-
second = Sorted::Sorter.new(:name, {:sort => first.to_s})
|
16
|
-
second.toggle.to_a.should == [["name", "asc"], ["email", "asc"],["phone", "asc"]]
|
17
|
-
third = Sorted::Sorter.new("email ASC, phone ASC", {:sort => second.to_s})
|
18
|
-
third.toggle.to_a.should == [["email", "asc"],["phone", "asc"], ["name", "asc"]]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe Sorted::Toggler, "add remaining orders" do
|
23
|
-
it "should toggle the sort order and include any sql orders not in sort params" do
|
24
|
-
sorter = Sorted::Sorter.new("email DESC, phone ASC, name DESC", {:sort => "email_desc!name_desc"})
|
25
|
-
sorter.toggle.to_a.should == [["email", "desc"], ["name", "desc"], ["phone", "asc"]]
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should toggle the sort order and include any sql orders not in sort params" do
|
29
|
-
sorter = Sorted::Sorter.new("email DESC, phone ASC, name DESC", {:sort => "mobile_asc!email_desc!phone_asc!name_desc"})
|
30
|
-
sorter.toggle.to_a.should == [["email", "desc"], ["phone", "asc"], ["name", "desc"], ["mobile", "asc"]]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe Sorted::Toggler, "add remaining sorts" do
|
35
|
-
it "should toggle the sort order and include any sort orders not in order params" do
|
36
|
-
sorter = Sorted::Sorter.new("email DESC", {:sort => "email_desc!name_desc"})
|
37
|
-
sorter.toggle.to_a.should == [["email", "asc"], ["name", "desc"]]
|
38
|
-
end
|
39
|
-
end
|