sorted 1.0.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc893cb851e4226ef3548dcba99ae5e44592d9c6
4
- data.tar.gz: 9ee8b89780d7f29798643338f186846e58756508
3
+ metadata.gz: 1b665b8a96ecf9464b3c3845dae2edbdf3a8fef8
4
+ data.tar.gz: f698bb91b0fa131eef2928a89d8125f19813dde9
5
5
  SHA512:
6
- metadata.gz: 1f0d30cbf53dfabf7d54f46c391218dd81674758655decf875531c014111ec2f1c6841c0a6e73af56249b41d8538525f064744574ece3e4e717b96d59eb5de86
7
- data.tar.gz: 3f95d6fb84711892c6838a529f9caef5c006279322576c7dacd3ac2b0eb2e9167642880974f95983e82ebf64d8895828c3b303435fc22464610b68fac3148fca
6
+ metadata.gz: d4cd81b4bde74202c5ab1a6e4f6bce6696fc882c78392dcba6a59539e658819dcc8080683a2da19b939028a55f4c76be7f3533e35092944278151b4bde1c25b6
7
+ data.tar.gz: a5e122727f4e42a6756b5b08685e8cff49db754446bcd95f8e00d205fdf289a4699a46ee81d5d3e2d36846411532771b32a7b0d21b545f8a1a6a1b3dc1946474
data/.rubocop.yml ADDED
@@ -0,0 +1,7 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Style/Blocks:
4
+ Enabled: false
5
+
6
+ Style/WordArray:
7
+ MinSize: 2
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,50 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2014-12-14 20:28:26 +1100 using RuboCop version 0.28.0.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 5
9
+ Lint/UselessAssignment:
10
+ Enabled: false
11
+
12
+ # Offense count: 2
13
+ Lint/Void:
14
+ Enabled: false
15
+
16
+ # Offense count: 2
17
+ Metrics/AbcSize:
18
+ Max: 29
19
+
20
+ # Offense count: 1
21
+ Metrics/CyclomaticComplexity:
22
+ Max: 8
23
+
24
+ # Offense count: 22
25
+ # Configuration parameters: AllowURI, URISchemes.
26
+ Metrics/LineLength:
27
+ Max: 177
28
+
29
+ # Offense count: 2
30
+ # Configuration parameters: CountComments.
31
+ Metrics/MethodLength:
32
+ Max: 18
33
+
34
+ # Offense count: 1
35
+ Metrics/PerceivedComplexity:
36
+ Max: 9
37
+
38
+ # Offense count: 14
39
+ Style/Documentation:
40
+ Enabled: false
41
+
42
+ # Offense count: 5
43
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
44
+ Style/For:
45
+ Enabled: false
46
+
47
+ # Offense count: 1
48
+ # Configuration parameters: MaxLineLength.
49
+ Style/IfUnlessModifier:
50
+ Enabled: false
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.5
5
6
  - jruby-19mode
6
7
  - ruby-head
7
8
 
data/README.md CHANGED
@@ -1,9 +1,50 @@
1
1
  # sorted
2
2
 
3
- [![Build Status](https://travis-ci.org/mynameisrufus/sorted.png?branch=master)](https://travis-ci.org/mynameisrufus/sorted)
3
+ [![Build Status](https://travis-ci.org/mynameisrufus/sorted.svg?branch=master)](https://travis-ci.org/mynameisrufus/sorted)
4
+ [![Gem Version](https://badge.fury.io/rb/sorted.svg)](http://badge.fury.io/rb/sorted)
4
5
 
5
- Sorted is a simple object that will take an sql order string and a url
6
- sort string to let you sort large datasets over many pages (using
6
+ Sorted at it's core is a set of objects that let you sort many different
7
+ attributes in weird and wonderful ways.
8
+
9
+ ## Example
10
+
11
+ The secret sauce is the `Sorted::Set` object, in this example we 'toggle' email:
12
+
13
+ ```ruby
14
+ a = Sorted::Set.new([['email', 'asc'], ['name', 'asc']])
15
+ b = Sorted::Set.new([['email', 'asc'], ['phone', 'asc']])
16
+
17
+ s = a.direction_intersect(b)
18
+
19
+ s.uniq.to_a #=> [['email', 'desc'], ['phone', 'asc'], ['name', 'asc']]
20
+ ```
21
+
22
+ The best way to think about this is to imagine a spreed sheet and what happens
23
+ when you sort by various columns, `Sorted::Set` pretty much just does that.
24
+
25
+ ## Parsers/Encoders
26
+
27
+ Parsers return a `Sorted::Set` that can then be used by an encoder:
28
+
29
+ ```ruby
30
+ set = Sorted::URIQuery.parse('name_asc!email_asc')
31
+ Sorted::SQLQuery.encode(set) #=> 'name ASC email ASC'
32
+ ```
33
+
34
+ Currently implemented:
35
+
36
+ * `Sorted::SQLQuery`
37
+ * `Sorted::URIQuery`
38
+
39
+ TODO:
40
+
41
+ * `Sorted::JSONQuery` (Mongoid)
42
+
43
+ ## Rails
44
+
45
+ Sorted comes with `ActionView` helpers and ORM scopes out of the box.
46
+
47
+ The ORM scopes will let you sort large datasets over many pages (using
7
48
  [will_paginate](https://github.com/mislav/will_paginate) or
8
49
  [kaminari](https://github.com/amatsuda/kaminari)) without losing state.
9
50
 
@@ -18,12 +59,6 @@ link_to_sorted "Email", :email
18
59
  Works the same as the `link_to` method except a second argument for the
19
60
  sort attribute is needed.
20
61
 
21
- ### Ruby 1.8.7 Rails 3.x
22
-
23
- ```ruby
24
- gem 'sorted', '~> 0.4.3'
25
- ```
26
-
27
62
  ### Model
28
63
 
29
64
  Using the `sorted` method with the optional default order argument:
@@ -32,12 +67,14 @@ Using the `sorted` method with the optional default order argument:
32
67
  @users = User.sorted(params[:sort], "email ASC").page(params[:page])
33
68
  ```
34
69
 
35
- ### Rubies
70
+ A `resorted` method is also available and works the same way as the `reorder` method in Rails.
71
+ It forces the order to be the one passed in:
36
72
 
37
- * MRI 1.9.3, 2.0.0.
38
- * JRuby 1.9 mode
73
+ ```ruby
74
+ @users = User.order(:id).sorted(nil, 'name DESC').resorted(params[:sort], 'email ASC')
75
+ ```
39
76
 
40
- ### ORMs
77
+ ## Supported ORMs
41
78
 
42
79
  * ActiveRecord
43
80
  * Mongoid
data/Rakefile CHANGED
@@ -1,18 +1,18 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
1
+ require 'bundler/gem_tasks'
2
+ require 'bundler/setup'
3
+ require 'rubocop/rake_task'
4
4
  require 'rspec/core'
5
5
  require 'rspec/core/rake_task'
6
+ require 'rdoc/task'
7
+ require 'sorted'
8
+
6
9
  RSpec::Core::RakeTask.new(:spec) do |spec|
7
10
  spec.pattern = FileList['spec/**/*_spec.rb']
8
11
  end
9
12
 
10
- task :default => "spec:all"
13
+ RuboCop::RakeTask.new
11
14
 
12
- require 'rdoc/task'
13
15
  Rake::RDocTask.new do |rdoc|
14
- require 'sorted/version'
15
-
16
16
  rdoc.rdoc_dir = 'rdoc'
17
17
  rdoc.title = "sorted #{Sorted::VERSION}"
18
18
  rdoc.rdoc_files.include('README*')
@@ -20,7 +20,7 @@ Rake::RDocTask.new do |rdoc|
20
20
  end
21
21
 
22
22
  namespace :spec do
23
- desc "Run Tests against all ORMs"
23
+ desc 'Run Tests against all ORMs'
24
24
  task :all do
25
25
  %w(active_record_40 mongoid_30).each do |gemfile|
26
26
  sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle --quiet"
@@ -28,3 +28,21 @@ namespace :spec do
28
28
  end
29
29
  end
30
30
  end
31
+
32
+ task :benchmark do
33
+ require 'benchmark'
34
+
35
+ sort = 'email_desc!name_desc'
36
+ order = 'email ASC, phone ASC, name DESC'
37
+
38
+ n = 50_000
39
+ Benchmark.bm do |x|
40
+ x.report(:lazy) { for i in 1..n; Sorted::Parser.new(sort, order); end }
41
+ x.report(:to_hash) { for i in 1..n; Sorted::Parser.new(sort, order).to_hash; end }
42
+ x.report(:to_sql) { for i in 1..n; Sorted::Parser.new(sort, order).to_sql; end }
43
+ x.report(:to_a) { for i in 1..n; Sorted::Parser.new(sort, order).to_a; end }
44
+ x.report(:toggle) { for i in 1..n; Sorted::Parser.new(sort, order).toggle; end }
45
+ end
46
+ end
47
+
48
+ task default: ['rubocop', 'spec:all']
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/rufuspost/Projects/ruby/gems/sorted
3
3
  specs:
4
- sorted (1.0.0)
4
+ sorted (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -33,6 +33,9 @@ GEM
33
33
  thread_safe (~> 0.1)
34
34
  tzinfo (~> 0.3.37)
35
35
  arel (4.0.1)
36
+ ast (2.0.0)
37
+ astrolabe (1.3.0)
38
+ parser (>= 2.2.0.pre.3, < 3.0)
36
39
  atomic (1.1.14)
37
40
  atomic (1.1.14-java)
38
41
  builder (3.1.4)
@@ -42,6 +45,10 @@ GEM
42
45
  jdbc-sqlite3 (3.7.2.1)
43
46
  minitest (4.7.5)
44
47
  multi_json (1.8.2)
48
+ parser (2.2.0.pre.8)
49
+ ast (>= 1.1, < 3.0)
50
+ slop (~> 3.4, >= 3.4.5)
51
+ powerpack (0.0.9)
45
52
  rack (1.5.2)
46
53
  rack-test (0.6.2)
47
54
  rack (>= 1.0)
@@ -50,6 +57,7 @@ GEM
50
57
  activesupport (= 4.0.0)
51
58
  rake (>= 0.8.7)
52
59
  thor (>= 0.18.1, < 2.0)
60
+ rainbow (2.0.0)
53
61
  rake (10.1.0)
54
62
  rspec (2.14.1)
55
63
  rspec-core (~> 2.14.0)
@@ -66,6 +74,14 @@ GEM
66
74
  rspec-core (~> 2.14.0)
67
75
  rspec-expectations (~> 2.14.0)
68
76
  rspec-mocks (~> 2.14.0)
77
+ rubocop (0.28.0)
78
+ astrolabe (~> 1.3)
79
+ parser (>= 2.2.0.pre.7, < 3.0)
80
+ powerpack (~> 0.0.6)
81
+ rainbow (>= 1.99.1, < 3.0)
82
+ ruby-progressbar (~> 1.4)
83
+ ruby-progressbar (1.7.0)
84
+ slop (3.6.0)
69
85
  sqlite3 (1.3.8)
70
86
  thor (0.18.1)
71
87
  thread_safe (0.1.3)
@@ -88,5 +104,6 @@ DEPENDENCIES
88
104
  rake
89
105
  rspec (>= 2.0.0)
90
106
  rspec-rails (>= 2.0)
107
+ rubocop (>= 0.28)
91
108
  sorted!
92
109
  sqlite3 (>= 1.3.5)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- sorted (1.0.0)
4
+ sorted (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -24,6 +24,9 @@ GEM
24
24
  minitest (~> 5.1)
25
25
  thread_safe (~> 0.1)
26
26
  tzinfo (~> 1.1)
27
+ ast (2.0.0)
28
+ astrolabe (1.3.0)
29
+ parser (>= 2.2.0.pre.3, < 3.0)
27
30
  bson (2.3.0)
28
31
  bson (2.3.0-java)
29
32
  builder (3.2.2)
@@ -45,6 +48,10 @@ GEM
45
48
  optionable (~> 0.2.0)
46
49
  optionable (0.2.0)
47
50
  origin (2.1.1)
51
+ parser (2.2.0.pre.8)
52
+ ast (>= 1.1, < 3.0)
53
+ slop (~> 3.4, >= 3.4.5)
54
+ powerpack (0.0.9)
48
55
  rack (1.5.2)
49
56
  rack-test (0.6.2)
50
57
  rack (>= 1.0)
@@ -53,6 +60,7 @@ GEM
53
60
  activesupport (= 4.1.4)
54
61
  rake (>= 0.8.7)
55
62
  thor (>= 0.18.1, < 2.0)
63
+ rainbow (2.0.0)
56
64
  rake (10.3.2)
57
65
  rspec (3.0.0)
58
66
  rspec-core (~> 3.0.0)
@@ -74,6 +82,14 @@ GEM
74
82
  rspec-mocks (~> 3.0.0)
75
83
  rspec-support (~> 3.0.0)
76
84
  rspec-support (3.0.2)
85
+ rubocop (0.28.0)
86
+ astrolabe (~> 1.3)
87
+ parser (>= 2.2.0.pre.7, < 3.0)
88
+ powerpack (~> 0.0.6)
89
+ rainbow (>= 1.99.1, < 3.0)
90
+ ruby-progressbar (~> 1.4)
91
+ ruby-progressbar (1.7.0)
92
+ slop (3.6.0)
77
93
  thor (0.19.1)
78
94
  thread_safe (0.3.4)
79
95
  thread_safe (0.3.4-java)
@@ -93,4 +109,5 @@ DEPENDENCIES
93
109
  rake
94
110
  rspec (>= 2.0.0)
95
111
  rspec-rails (>= 2.0)
112
+ rubocop (>= 0.28)
96
113
  sorted!
data/lib/sorted.rb CHANGED
@@ -1,8 +1,189 @@
1
1
  require 'sorted/parser'
2
2
 
3
3
  module Sorted
4
+ class Set
5
+ include Enumerable
6
+
7
+ def initialize(set = [])
8
+ @set = set
9
+ end
10
+
11
+ def each(&block)
12
+ @set.each(&block)
13
+ end
14
+
15
+ ##
16
+ # Gets the keys from the array pairs
17
+ #
18
+ # set = [["email", "name"], ["desc", "desc"]]
19
+ # set.transpose #=> [["email", "name"], ["desc", "desc"]]
20
+ # set.transpose.first #=> ["email", "name"]
21
+
22
+ def keys
23
+ @set.transpose.first || []
24
+ end
25
+
26
+ ##
27
+ # Returns a resulting set with specific keys flipped
28
+ #
29
+ # a = Sorted::Set.new([['email', 'asc'], ['name', 'asc']])
30
+ # b = Sorted::Set.new([['email', 'asc'], ['phone', 'asc']])
31
+ # s = a.direction_intersect(b)
32
+ # s.to_a #=> [['email', 'desc'], ['phone', 'asc'], ['name', 'asc']]
33
+
34
+ def direction_intersect(other)
35
+ self.class.new.tap do |memo|
36
+ unless other.keys.empty?
37
+ a(memo, other)
38
+ b(memo, other)
39
+ end
40
+ c(memo)
41
+ d(memo, other)
42
+ end
43
+ end
44
+
45
+ def -(other)
46
+ self.class.new.tap do |memo|
47
+ each do |a|
48
+ b = other.assoc(a.first)
49
+ next if b
50
+ memo << a
51
+ end
52
+ end
53
+ end
54
+
55
+ def +(other)
56
+ self.class.new(@set + other.to_a)
57
+ end
58
+
59
+ def <<(a)
60
+ self.class.new(@set << a)
61
+ end
62
+
63
+ def uniq
64
+ self.class.new(@set.uniq)
65
+ end
66
+
67
+ def assoc(o)
68
+ @set.assoc(o)
69
+ end
70
+
71
+ def at(i)
72
+ @set.at(i)
73
+ end
74
+
75
+ def to_a
76
+ @set
77
+ end
78
+
79
+ def to_hash
80
+ @set.inject({}) { |a, e| a.merge(Hash[e[0], e[1]]) }
81
+ end
82
+
83
+ private
84
+
85
+ # If the order of keys match upto the size of the set then flip them
86
+ def a(memo, other)
87
+ if keys == other.keys.take(keys.size)
88
+ keys.each do |order|
89
+ if other.keys.include?(order)
90
+ memo << [order, flip_direction(other.assoc(order).last)]
91
+ end
92
+ end
93
+ else
94
+ keys.each do |order|
95
+ if other.keys.include?(order)
96
+ memo << other.assoc(order)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ # Add items from other that are common and not already added
103
+ def b(memo, other)
104
+ other.keys.each do |sort|
105
+ if keys.include?(sort) && !memo.keys.include?(sort)
106
+ memo << other.assoc(sort)
107
+ end
108
+ end
109
+ end
110
+
111
+ # Add items not in memo
112
+ def c(memo)
113
+ each do |order|
114
+ unless memo.keys.include?(order[0])
115
+ memo << order
116
+ end
117
+ end
118
+ end
119
+
120
+ # Add items from other not in memo
121
+ def d(memo, other)
122
+ other.each do |sort|
123
+ unless memo.keys.include?(sort[0])
124
+ memo << sort
125
+ end
126
+ end
127
+ end
128
+
129
+ def flip_direction(direction)
130
+ case direction
131
+ when 'asc' then 'desc'
132
+ when 'desc'then 'asc'
133
+ end
134
+ end
135
+ end
136
+
137
+ module Parse
138
+ def split(raw, delim, &block)
139
+ return Set.new if raw.nil?
140
+ raw.to_s.split(delim).inject(Set.new, &block)
141
+ end
142
+ end
143
+
144
+ class URIQuery
145
+ extend Parse
146
+
147
+ REGEXP = /([a-zA-Z0-9._]+)_(asc|desc)$/
148
+
149
+ def self.parse(raw)
150
+ split(raw, /!/) do |set, part|
151
+ m = part.match(REGEXP)
152
+ return set unless m
153
+ set << [m[1], m[2].downcase]
154
+ end
155
+ end
156
+
157
+ def self.encode(set)
158
+ set.map { |a| a.join('_') }.join('!')
159
+ end
160
+ end
161
+
162
+ class SQLQuery
163
+ extend Parse
164
+
165
+ REGEXP = /(([a-z0-9._]+)\s([asc|desc]+)|[a-z0-9._]+)/i
166
+
167
+ def self.parse(raw)
168
+ split(raw, /,/) do |set, part|
169
+ m = part.match(REGEXP)
170
+ return set unless m
171
+ set << [(m[2].nil? ? m[1] : m[2]), (m[3].nil? ? 'asc' : m[3].downcase)]
172
+ end
173
+ end
174
+
175
+ def self.encode(set, quote_proc = ->(f) { f })
176
+ set.map { |a| "#{column(a[0], quote_proc)} #{a[1].upcase}" }.join(', ')
177
+ end
178
+
179
+ def self.column(parts, quote_proc)
180
+ parts.split('.').map { |frag| quote_proc.call(frag) }.join('.')
181
+ end
182
+ private_class_method :column
183
+ end
4
184
  end
5
185
 
6
186
  if defined?(::Rails::Railtie)
187
+ ActiveSupport::Deprecation.warn('Rails helpers will be removed in version 2.0 of the sorted gem, use sorted-rails instead.')
7
188
  require 'sorted/railtie'
8
189
  end
@@ -5,12 +5,12 @@ module Sorted
5
5
  module Orms
6
6
  module Mongoid
7
7
  extend ActiveSupport::Concern
8
- SQL_TO_MONGO = { "asc" => 1, "desc" => -1 }
8
+ SQL_TO_MONGO = { 'asc' => 1, 'desc' => -1 }
9
9
 
10
10
  included do
11
11
  def self.sorted(sort, default_order = nil)
12
12
  sorter = ::Sorted::Parser.new(sort, default_order)
13
- order_by sorter.to_hash.merge(sorter) { |key, val| SQL_TO_MONGO[val] }
13
+ order_by sorter.to_hash.merge(sorter) { |_key, val| SQL_TO_MONGO[val] }
14
14
  end
15
15
  end
16
16
  end
data/lib/sorted/parser.rb CHANGED
@@ -1,82 +1,68 @@
1
1
  require 'sorted/toggler'
2
2
 
3
3
  module Sorted
4
+ ##
4
5
  # Takes a sort query string and an SQL order string and parses the
6
+ #
5
7
  # values to produce key value pairs.
6
8
  #
7
9
  # 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
10
+ # Sorted::Parser.new('phone_desc', 'name ASC').to_s #=> "phone_desc!name_asc"
11
+ #
12
+ # TODO A more helpfull name than `Parser` because it only deals with URI and
13
+ # SQL. Shoud be refactored before 2.x
11
14
 
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
+ Parser = Struct.new(:sort, :order) do
16
+ def uri
17
+ URIQuery.parse(sort)
18
+ end
15
19
 
16
- def initialize(sort, order = nil)
17
- @sort = sort
18
- @order = order
19
- @sorts = parse_sort
20
- @orders = parse_order
20
+ def sql
21
+ SQLQuery.parse(order)
21
22
  end
22
23
 
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
24
+ def sorts
25
+ uri.to_a
29
26
  end
30
27
 
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
28
+ def orders
29
+ sql.to_a
37
30
  end
38
31
 
39
32
  def to_hash
40
- array.inject({}){|h,a| h.merge(Hash[a[0],a[1]])}
33
+ set.to_hash
41
34
  end
42
35
 
43
- def to_sql(quoter = ->(frag) { frag })
44
- array.map do |a|
45
- column = a[0].split('.').map{ |frag| quoter.call(frag) }.join('.')
46
- "#{column} #{a[1].upcase}"
47
- end.join(', ')
36
+ def to_sql(quote_proc = ->(f) { f })
37
+ SQLQuery.encode(set, quote_proc)
48
38
  end
49
39
 
50
40
  def to_s
51
- array.map{|a| a.join('_') }.join('!')
41
+ URIQuery.encode(set)
52
42
  end
53
43
 
54
44
  def to_a
55
- array
45
+ set.to_a
56
46
  end
57
47
 
58
48
  def toggle
59
- @array = Toggler.new(sorts, orders).to_a
49
+ @set = Toggler.new(sorts, orders).toggle
60
50
  self
61
51
  end
62
52
 
63
53
  def reset
64
- @array = default
54
+ @set = default
65
55
  self
66
56
  end
67
57
 
68
58
  private
69
59
 
70
- def array
71
- @array ||= default
60
+ def set
61
+ @set ||= default
72
62
  end
73
63
 
74
64
  def default
75
- sorts_new = sorts.dup
76
- orders.each do |o|
77
- sorts_new << o unless sorts_new.flatten.include?(o[0])
78
- end
79
- sorts_new
65
+ uri + (sql - uri)
80
66
  end
81
67
  end
82
68
  end
@@ -2,7 +2,7 @@ require 'sorted'
2
2
 
3
3
  module Sorted
4
4
  class Railtie < Rails::Railtie
5
- initializer "sorted.configure" do |app|
5
+ initializer 'sorted.configure' do |_app|
6
6
  if defined? ::ActiveRecord
7
7
  ActiveSupport.on_load :active_record do
8
8
  require 'sorted/orms/active_record'
@@ -1,62 +1,27 @@
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.
2
+ ##
3
+ # Takes a parsed arrays of sorts and orders, it then will reorder the pairs
4
+ # and flip the ascendance of the first sort pair.
4
5
  #
5
6
  # Example:
6
7
  # sorts = [['name', 'asc'], ['phone', 'desc']]
7
8
  # orders = [['name', 'asc']]
8
- # Sorted::Toggler.new(sorts, orders).to_a #-> [['name', 'desc'], ['phone', 'desc']]
9
+ # Sorted::Toggler.new(sorts, orders).to_a
10
+ #
11
+ # TODO Remove this in 2.x, it's only here for backwards compatibility.
12
+
9
13
  class Toggler
10
14
  def initialize(sorts, orders)
11
- @array = []
12
- @sorts = sorts
13
- @orders = orders
14
- @sort_keys = sorts.transpose.first
15
- @order_keys = orders.transpose.first
16
- toggle_sorts unless @sort_keys.nil?
17
- add_remaining_orders
18
- add_remaining_sorts
19
- end
20
-
21
- def to_a
22
- @array
23
- end
24
-
25
- def toggle_sorts
26
- if @order_keys == @sort_keys.take(@order_keys.size)
27
- @order_keys.select do |order|
28
- @sort_keys.include?(order)
29
- end.each do |order|
30
- @array << [order, (case @sorts.assoc(order).last; when "asc"; "desc"; when "desc"; "asc" end)]
31
- end
32
- else
33
- @order_keys.select do |order|
34
- @sort_keys.include?(order)
35
- end.each do |order|
36
- @array << [order, @sorts.assoc(order).last]
37
- end
38
- end
39
- @sort_keys.select do |sort|
40
- @order_keys.include?(sort) && !@array.flatten.include?(sort)
41
- end.each do |sort|
42
- @array << [sort, @sorts.assoc(sort).last]
43
- end
15
+ @sorts = Set.new(sorts)
16
+ @orders = Set.new(orders)
44
17
  end
45
18
 
46
- def add_remaining_orders
47
- @orders.select do |order|
48
- !@array.flatten.include?(order[0])
49
- end.each do |order|
50
- @array << order
51
- end
19
+ def toggle
20
+ @orders.direction_intersect(@sorts)
52
21
  end
53
22
 
54
- def add_remaining_sorts
55
- @sorts.select do |sort|
56
- !@array.flatten.include?(sort[0])
57
- end.each do |sort|
58
- @array << sort
59
- end
23
+ def to_a
24
+ toggle.to_a
60
25
  end
61
26
  end
62
27
  end
@@ -1,3 +1,3 @@
1
1
  module Sorted
2
- VERSION = "1.0.1"
2
+ VERSION = '1.1.1'
3
3
  end
@@ -18,7 +18,7 @@ module Sorted
18
18
  if @parser.sorts.flatten.include? @parser.orders[0][0]
19
19
  "sorted #{@parser.sorts.assoc(@parser.orders[0][0]).last}"
20
20
  else
21
- "sorted"
21
+ 'sorted'
22
22
  end
23
23
  end
24
24
  end
@@ -71,10 +71,10 @@ module Sorted
71
71
  # sortable_by :author_name, :title, ["Date of Publication", :published_at]
72
72
  #
73
73
  def sortable_by(*columns)
74
- links = content_tag :span, "Sort by: "
74
+ links = content_tag :span, 'Sort by: '
75
75
  columns.each do |c|
76
76
  if c.is_a? Array
77
- links += link_to_sorted(c[0],c[1].to_sym)
77
+ links += link_to_sorted(c[0], c[1].to_sym)
78
78
  else
79
79
  links += link_to_sorted(c.to_s.titleize, c.to_sym)
80
80
  end
data/sorted.gemspec CHANGED
@@ -1,27 +1,28 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path("../lib/sorted/version", __FILE__)
2
+ require File.expand_path('../lib/sorted/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "sorted"
5
+ s.name = 'sorted'
6
6
  s.version = Sorted::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ["Rufus Post", "Daniel Leavitt"]
9
- s.email = ["rufuspost@gmail.com", "daniel.leavitt@gmail.com"]
10
- s.homepage = "http://rubygems.org/gems/sorted"
11
- s.summary = %q{Data sorting library}
12
- s.description = %q{Allows you to sort large datasets over many pages, without losing state.}
13
- s.license = "MIT"
8
+ s.authors = ['Rufus Post', 'Daniel Leavitt']
9
+ s.email = ['rufuspost@gmail.com', 'daniel.leavitt@gmail.com']
10
+ s.homepage = 'http://rubygems.org/gems/sorted'
11
+ s.summary = 'Data sorting library'
12
+ s.description = 'Allows you to sort large datasets over many pages, without losing state.'
13
+ s.license = 'MIT'
14
14
 
15
- s.required_rubygems_version = ">= 1.3.6"
16
- s.rubyforge_project = "sorted"
15
+ s.required_rubygems_version = '>= 1.3.6'
16
+ s.rubyforge_project = 'sorted'
17
17
 
18
- s.add_development_dependency "rake", ">= 0"
19
- s.add_development_dependency "bundler", ">= 1.0.0"
20
- s.add_development_dependency "rspec", ">= 2.0.0"
21
- s.add_development_dependency "activesupport", ">= 3.0.0"
22
- s.add_development_dependency "actionpack", ">= 3.0.0"
18
+ s.add_development_dependency 'rake', '>= 0'
19
+ s.add_development_dependency 'bundler', '>= 1.0.0'
20
+ s.add_development_dependency 'rspec', '>= 2.0.0'
21
+ s.add_development_dependency 'activesupport', '>= 3.0.0'
22
+ s.add_development_dependency 'actionpack', '>= 3.0.0'
23
+ s.add_development_dependency 'rubocop', '>= 0.28'
23
24
 
24
25
  s.files = `git ls-files`.split("\n")
25
- s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
26
+ s.executables = `git ls-files`.split("\n").map { |f| f =~ /^bin\/(.*)/ ? Regexp.last_match[1] : nil }.compact
26
27
  s.require_path = 'lib'
27
28
  end
@@ -14,20 +14,20 @@ if defined? ActiveRecord
14
14
  scope :page, -> { limit(50) }
15
15
  end
16
16
 
17
- it "should integrate with ActiveRecord::Base" do
17
+ it 'should integrate with ActiveRecord::Base' do
18
18
  SortedActiveRecordTest.should respond_to(:sorted)
19
19
  SortedActiveRecordTest.should respond_to(:resorted)
20
20
  end
21
21
 
22
- it "should play nice with other scopes" do
22
+ it 'should play nice with other scopes' do
23
23
  sql = "SELECT \"sorted_active_record_tests\".* FROM \"sorted_active_record_tests\" WHERE \"sorted_active_record_tests\".\"name\" = 'bob' ORDER BY \"name\" ASC LIMIT 50"
24
- SortedActiveRecordTest.where(:name => 'bob').page.sorted(nil, 'name ASC').to_sql.should == sql
25
- SortedActiveRecordTest.page.sorted(nil, 'name ASC').where(:name => 'bob').to_sql.should == sql
24
+ SortedActiveRecordTest.where(name: 'bob').page.sorted(nil, 'name ASC').to_sql.should == sql
25
+ SortedActiveRecordTest.page.sorted(nil, 'name ASC').where(name: 'bob').to_sql.should == sql
26
26
  end
27
27
 
28
- it "should override the provided order" do
28
+ it 'should override the provided order' do
29
29
  sql = "SELECT \"sorted_active_record_tests\".* FROM \"sorted_active_record_tests\" WHERE \"sorted_active_record_tests\".\"name\" = 'bob' ORDER BY \"name\" ASC LIMIT 50"
30
- SortedActiveRecordTest.page.where(:name => 'bob').order(:id).sorted(nil, 'name DESC').resorted(nil, 'name ASC').to_sql.should == sql
30
+ SortedActiveRecordTest.page.where(name: 'bob').order(:id).sorted(nil, 'name DESC').resorted(nil, 'name ASC').to_sql.should == sql
31
31
  end
32
32
  end
33
33
  end
@@ -15,16 +15,16 @@ if defined? Mongoid
15
15
  end
16
16
  end
17
17
 
18
- it "should integrate with Mongoid::Document" do
18
+ it 'should integrate with Mongoid::Document' do
19
19
  SortedMongoidTest.should respond_to(:sorted)
20
20
  end
21
21
 
22
- it "should integrate with Mongoid::Criteria" do
22
+ it 'should integrate with Mongoid::Criteria' do
23
23
  SortedMongoidTest.page.should respond_to(:sorted)
24
24
  end
25
25
 
26
- it "should play nice with other scopes" do
27
- query_options = { limit: 50, sort: { "name" => 1 } }
26
+ it 'should play nice with other scopes' do
27
+ query_options = { limit: 50, sort: { 'name' => 1 } }
28
28
  SortedMongoidTest.page.sorted(nil, 'name ASC').options.should == query_options
29
29
  SortedMongoidTest.page.sorted(nil, 'name ASC').options.should == query_options
30
30
  end
@@ -1,66 +1,66 @@
1
1
  require 'spec_helper'
2
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
3
+ describe Sorted::Parser, 'params parsing' do
4
+ it 'should not raise if pased nil arguments' do
5
+ -> { Sorted::Parser.new(nil, nil).toggle }.should_not raise_error
6
6
  end
7
7
 
8
- it "should return a nice array from the order sql" do
8
+ it 'should return a nice array from the order sql' do
9
9
  sort = nil
10
- order = "email ASC, phone ASC, name DESC"
11
- result = [["email", "asc"], ["phone", "asc"], ["name", "desc"]]
10
+ order = 'email ASC, phone ASC, name DESC'
11
+ result = [['email', 'asc'], ['phone', 'asc'], ['name', 'desc']]
12
12
 
13
13
  sorter = Sorted::Parser.new(sort, order)
14
14
  sorter.orders.should eq result
15
15
  end
16
16
 
17
- it "should return a nice array from the sort params" do
18
- sort = "email_desc!name_desc"
17
+ it 'should return a nice array from the sort params' do
18
+ sort = 'email_desc!name_desc'
19
19
  order = nil
20
- result = [["email", "desc"], ["name", "desc"]]
20
+ result = [['email', 'desc'], ['name', 'desc']]
21
21
 
22
22
  sorter = Sorted::Parser.new(sort, order)
23
23
  sorter.sorts.should eq result
24
24
  end
25
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"]]
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
30
 
31
31
  sorter = Sorted::Parser.new(sort, order)
32
32
  sorter.to_a.should eq result
33
33
  end
34
34
 
35
- it "should allow numbers, underscores and full stops in sort params" do
36
- sort = "assessmentsTable.name_desc!users_300.name_5_desc"
35
+ it 'should allow numbers, underscores and full stops in sort params' do
36
+ sort = 'assessmentsTable.name_desc!users_300.name_5_desc'
37
37
  order = nil
38
- result = [["assessmentsTable.name", "desc"], ["users_300.name_5", "desc"]]
38
+ result = [['assessmentsTable.name', 'desc'], ['users_300.name_5', 'desc']]
39
39
 
40
40
  sorter = Sorted::Parser.new(sort, order)
41
41
  sorter.sorts.should eq result
42
42
  end
43
43
 
44
- it "should allow numbers, underscores and full stops in order params" do
44
+ it 'should allow numbers, underscores and full stops in order params' do
45
45
  sort = nil
46
- order = "assessmentsTable.name ASC, users_300.name_5 ASC"
47
- result = [["assessmentsTable.name", "asc"], ["users_300.name_5", "asc"]]
46
+ order = 'assessmentsTable.name ASC, users_300.name_5 ASC'
47
+ result = [['assessmentsTable.name', 'asc'], ['users_300.name_5', 'asc']]
48
48
 
49
49
  sorter = Sorted::Parser.new(sort, order)
50
50
  sorter.orders.should eq result
51
51
  end
52
52
 
53
- it "should default to asc if sort params order is ommited" do
53
+ it 'should default to asc if sort params order is ommited' do
54
54
  sort = nil
55
55
  order = :email
56
- result = [["email", "asc"]]
56
+ result = [['email', 'asc']]
57
57
 
58
58
  sorter = Sorted::Parser.new(sort, order)
59
59
  sorter.orders.should eq result
60
60
  end
61
61
  end
62
62
 
63
- describe Sorted::Parser, "return types" do
63
+ describe Sorted::Parser, 'return types' do
64
64
  module FakeConnection
65
65
  def self.quote_column_name(column_name)
66
66
  "`#{column_name}`"
@@ -71,45 +71,45 @@ describe Sorted::Parser, "return types" do
71
71
  ->(frag) { FakeConnection.quote_column_name(frag) }
72
72
  }
73
73
 
74
- it "should properly escape sql column names" do
75
- order = "users.name DESC"
76
- result = "`users`.`name` DESC"
74
+ it 'should properly escape sql column names' do
75
+ order = 'users.name DESC'
76
+ result = '`users`.`name` DESC'
77
77
 
78
78
  sorter = Sorted::Parser.new(nil, order)
79
79
  sorter.to_sql(quoter).should eq result
80
80
  end
81
81
 
82
- it "should return an sql 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"
82
+ it 'should return an sql 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
86
 
87
87
  sorter = Sorted::Parser.new(sort, order)
88
88
  sorter.to_sql(quoter).should eq result
89
89
  end
90
90
 
91
- it "should return an hash" do
92
- sort = "email_desc!name_desc"
93
- order = "email ASC, phone ASC, name DESC"
94
- result = {"email" => "desc", "name" => "desc", "phone" => "asc"}
91
+ it 'should return an hash' do
92
+ sort = 'email_desc!name_desc'
93
+ order = 'email ASC, phone ASC, name DESC'
94
+ result = { 'email' => 'desc', 'name' => 'desc', 'phone' => 'asc' }
95
95
 
96
96
  sorter = Sorted::Parser.new(sort, order)
97
97
  sorter.to_hash.should eq result
98
98
  end
99
99
 
100
- it "should return an the encoded sort string" do
101
- sort = "email_desc!name_desc"
102
- order = "email ASC, phone ASC, name DESC"
103
- result = "email_desc!name_desc!phone_asc"
100
+ it 'should return an the encoded sort string' do
101
+ sort = 'email_desc!name_desc'
102
+ order = 'email ASC, phone ASC, name DESC'
103
+ result = 'email_desc!name_desc!phone_asc'
104
104
 
105
105
  sorter = Sorted::Parser.new(sort, order)
106
106
  sorter.to_s.should eq result
107
107
  end
108
108
 
109
- it "sql injection using order by clause should not work" do
110
- sort = "(case+when+((ASCII(SUBSTR((select+table_name+from+all_tables+where+rownum%3d1),1))>%3D128))+then+id+else+something+end)"
111
- order = "email ASC, phone ASC, name DESC"
112
- result = "`email` ASC, `phone` ASC, `name` DESC"
109
+ it 'sql injection using order by clause should not work' do
110
+ sort = '(case+when+((ASCII(SUBSTR((select+table_name+from+all_tables+where+rownum%3d1),1))>%3D128))+then+id+else+something+end)'
111
+ order = 'email ASC, phone ASC, name DESC'
112
+ result = '`email` ASC, `phone` ASC, `name` DESC'
113
113
 
114
114
  sorter = Sorted::Parser.new(sort, order)
115
115
  sorter.to_sql(quoter).should eq result
@@ -1,55 +1,73 @@
1
1
  require 'spec_helper'
2
2
 
3
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"]]
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
8
 
9
9
  toggler = Sorted::Toggler.new(sorts, orders)
10
10
  toggler.to_a.should eq result
11
11
  end
12
12
 
13
- it "should toggle ascendance of email" do
14
- orders = [["email", "desc"]]
15
- sorts = [["email", "asc"]]
16
- result = [["email", "desc"]]
13
+ it 'should toggle ascendance of email' do
14
+ orders = [['email', 'desc']]
15
+ sorts = [['email', 'asc']]
16
+ result = [['email', 'desc']]
17
17
 
18
18
  toggler = Sorted::Toggler.new(sorts, orders)
19
19
  toggler.to_a.should eq result
20
20
  end
21
21
 
22
- it "should return both order params un-toggled with no sort param" do
23
- orders = [["email", "asc"], ["phone", "asc"]]
22
+ it 'should return both order params un-toggled with no sort param' do
23
+ orders = [['email', 'asc'], ['phone', 'asc']]
24
24
  sorts = []
25
- result = [["email", "asc"], ["phone", "asc"]]
25
+ result = [['email', 'asc'], ['phone', 'asc']]
26
26
 
27
27
  toggler = Sorted::Toggler.new(sorts, orders)
28
28
  toggler.to_a.should eq result
29
29
  end
30
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"]]
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
35
 
36
36
  toggler = Sorted::Toggler.new(sorts, orders)
37
37
  toggler.to_a.should eq result
38
38
  end
39
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"]]
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
44
 
45
45
  toggler = Sorted::Toggler.new(sorts, orders)
46
46
  toggler.to_a.should eq result
47
47
  end
48
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"]]
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
+
58
+ it 'should toggle based on sorts and not orders' do
59
+ orders = [['email', 'desc'], ['phone', 'desc']]
60
+ sorts = [['email', 'asc'], ['phone', 'asc']]
61
+ result = [['email', 'desc'], ['phone', 'desc']]
62
+
63
+ toggler = Sorted::Toggler.new(sorts, orders)
64
+ toggler.to_a.should eq result
65
+ end
66
+
67
+ it 'should toggle based on sorts and not orders' do
68
+ orders = [['email', 'asc']]
69
+ sorts = [['name', 'asc']]
70
+ result = [['email', 'asc'], ['name', 'asc']]
53
71
 
54
72
  toggler = Sorted::Toggler.new(sorts, orders)
55
73
  toggler.to_a.should eq result
@@ -1,45 +1,63 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Sorted::ViewHelpers::ActionView do
4
- it "should integrate with ActiveRecord::Base" do
4
+ it 'should integrate with ActiveRecord::Base' do
5
5
  ActionView::Base.send(:include, Sorted::ViewHelpers::ActionView)
6
6
  ActionView::Base.new.should respond_to(:link_to_sorted)
7
7
  end
8
8
  end
9
9
 
10
10
  describe Sorted::ViewHelpers::ActionView::SortedViewHelper do
11
- it "should return the default sort order and preserve the existing params" do
11
+ it 'should return the default sort order and preserve the existing params' do
12
12
  order = :email
13
- params = { :page => 10 }
14
- result = { :page => 10, :sort => "email_asc" }
13
+ params = { page: 10 }
14
+ result = { page: 10, sort: 'email_asc' }
15
15
 
16
16
  sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
17
17
  sorter.params.should eq result
18
18
  end
19
19
 
20
- it "should only return the sorted css class if email has not yet been sorted" do
20
+ it 'should only return the sorted css class if email has not yet been sorted' do
21
21
  order = :email
22
22
  params = {}
23
- result = "sorted"
23
+ result = 'sorted'
24
24
 
25
25
  sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
26
26
  sorter.css.should eq result
27
27
  end
28
28
 
29
- it "should only return the sorted css class if email has not yet been sorted" do
29
+ it 'should only return the sorted css class if email has not yet been sorted' do
30
30
  order = :email
31
- params = { :sort => "email_asc" }
32
- result = "sorted asc"
31
+ params = { sort: 'email_asc' }
32
+ result = 'sorted asc'
33
33
 
34
34
  sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
35
35
  sorter.css.should eq result
36
36
  end
37
37
 
38
- it "should return the default order when params are empty" do
38
+ it 'should return the default order when params are empty' do
39
39
  order = :email
40
- result = { :sort => "email_asc" }
40
+ result = { sort: 'email_asc' }
41
41
 
42
42
  sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, {}
43
43
  sorter.params.should eq result
44
44
  end
45
+
46
+ it 'should correctly toggle multiple params' do
47
+ order = 'email DESC, name DESC'
48
+ params = { sort: 'email_asc!name_asc' }
49
+ result = { sort: 'email_desc!name_desc' }
50
+
51
+ sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
52
+ sorter.params.should eq result
53
+ end
54
+
55
+ it 'should have sort order over existing params' do
56
+ order = :email
57
+ params = { sort: 'name_asc' }
58
+ result = { sort: 'email_asc!name_asc' }
59
+
60
+ sorter = Sorted::ViewHelpers::ActionView::SortedViewHelper.new order, params
61
+ sorter.params.should eq result
62
+ end
45
63
  end
data/spec/spec_helper.rb CHANGED
@@ -1,14 +1,6 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
 
4
- begin
5
- require 'rails'
6
- rescue LoadError
7
- end
8
-
9
- require 'bundler/setup'
10
- Bundler.require
11
-
12
4
  require 'sorted'
13
5
  require 'sorted/orms/mongoid'
14
6
  require 'sorted/orms/active_record'
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: 1.0.1
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rufus Post
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-12 00:00:00.000000000 Z
12
+ date: 2015-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: 3.0.0
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0.28'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0.28'
84
98
  description: Allows you to sort large datasets over many pages, without losing state.
85
99
  email:
86
100
  - rufuspost@gmail.com
@@ -91,6 +105,8 @@ extra_rdoc_files: []
91
105
  files:
92
106
  - ".gitignore"
93
107
  - ".rspec"
108
+ - ".rubocop.yml"
109
+ - ".rubocop_todo.yml"
94
110
  - ".travis.yml"
95
111
  - Gemfile
96
112
  - LICENSE
@@ -135,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
151
  version: 1.3.6
136
152
  requirements: []
137
153
  rubyforge_project: sorted
138
- rubygems_version: 2.2.0
154
+ rubygems_version: 2.4.5
139
155
  signing_key:
140
156
  specification_version: 4
141
157
  summary: Data sorting library