trailblazer-finder 0.1.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml +101 -0
  4. data/.rubocop.yml +3 -43
  5. data/.rubocop_todo.yml +42 -196
  6. data/.travis.yml +5 -8
  7. data/Gemfile +2 -2
  8. data/LICENSE.txt +7 -21
  9. data/README.md +177 -292
  10. data/Rakefile +12 -12
  11. data/lib/trailblazer/finder.rb +48 -23
  12. data/lib/trailblazer/finder/activity/find.rb +57 -0
  13. data/lib/trailblazer/finder/activity/prepare.rb +29 -0
  14. data/lib/trailblazer/finder/activity/prepare/adapters.rb +66 -0
  15. data/lib/trailblazer/finder/activity/prepare/entity.rb +32 -0
  16. data/lib/trailblazer/finder/activity/prepare/filters.rb +36 -0
  17. data/lib/trailblazer/finder/activity/prepare/paging.rb +49 -0
  18. data/lib/trailblazer/finder/activity/prepare/params.rb +33 -0
  19. data/lib/trailblazer/finder/activity/prepare/properties.rb +47 -0
  20. data/lib/trailblazer/finder/activity/prepare/sorting.rb +57 -0
  21. data/lib/trailblazer/finder/activity/process.rb +18 -0
  22. data/lib/trailblazer/finder/activity/process/adapters.rb +48 -0
  23. data/lib/trailblazer/finder/activity/process/filters.rb +28 -0
  24. data/lib/trailblazer/finder/activity/process/paging.rb +26 -0
  25. data/lib/trailblazer/finder/activity/process/predicates.rb +30 -0
  26. data/lib/trailblazer/finder/activity/process/sorting.rb +26 -0
  27. data/lib/trailblazer/finder/adapters/active_record/paging.rb +9 -8
  28. data/lib/trailblazer/finder/adapters/active_record/predicates.rb +78 -17
  29. data/lib/trailblazer/finder/adapters/active_record/sorting.rb +14 -12
  30. data/lib/trailblazer/finder/adapters/basic/paging.rb +21 -0
  31. data/lib/trailblazer/finder/adapters/basic/predicates.rb +115 -0
  32. data/lib/trailblazer/finder/adapters/basic/sorting.rb +40 -0
  33. data/lib/trailblazer/finder/adapters/kaminari/paging.rb +21 -0
  34. data/lib/trailblazer/finder/adapters/sequel/paging.rb +9 -8
  35. data/lib/trailblazer/finder/adapters/sequel/predicates.rb +78 -17
  36. data/lib/trailblazer/finder/adapters/sequel/sorting.rb +17 -15
  37. data/lib/trailblazer/finder/adapters/will_paginate/paging.rb +21 -0
  38. data/lib/trailblazer/finder/base.rb +20 -83
  39. data/lib/trailblazer/finder/dsl.rb +56 -0
  40. data/lib/trailblazer/finder/find.rb +28 -15
  41. data/lib/trailblazer/finder/helpers/basic.rb +44 -0
  42. data/lib/trailblazer/finder/helpers/sorting.rb +54 -0
  43. data/lib/trailblazer/finder/utils/array.rb +20 -0
  44. data/lib/trailblazer/finder/utils/extra.rb +10 -20
  45. data/lib/trailblazer/finder/utils/hash.rb +36 -0
  46. data/lib/trailblazer/finder/utils/splitter.rb +16 -17
  47. data/lib/trailblazer/finder/utils/string.rb +20 -10
  48. data/lib/trailblazer/finder/version.rb +3 -1
  49. data/lib/trailblazer/operation/finder.rb +20 -19
  50. data/spec/spec_helper.rb +5 -11
  51. data/spec/spec_helper_active_record.rb +11 -12
  52. data/spec/spec_helper_sequel.rb +4 -4
  53. data/spec/spec_helper_will_paginate.rb +13 -0
  54. data/spec/trailblazer/finder/adapters/active_record_spec.rb +267 -0
  55. data/spec/trailblazer/finder/adapters/basic_spec.rb +251 -0
  56. data/spec/trailblazer/finder/adapters/kaminari_spec.rb +78 -32
  57. data/spec/trailblazer/finder/adapters/sequel_spec.rb +267 -0
  58. data/spec/trailblazer/finder/adapters/will_paginate_spec.rb +81 -40
  59. data/spec/trailblazer/finder/base_spec.rb +292 -204
  60. data/spec/trailblazer/finder/dsl_spec.rb +213 -0
  61. data/spec/trailblazer/finder/utils/hash_spec.rb +26 -0
  62. data/spec/trailblazer/finder/utils/splitter_spec.rb +39 -0
  63. data/spec/trailblazer/finder/utils/string_spec.rb +52 -9
  64. data/spec/trailblazer/operation/finder_spec.rb +35 -32
  65. data/trailblazer-finder.gemspec +31 -30
  66. metadata +119 -137
  67. data/lib/trailblazer/finder/adapters.rb +0 -26
  68. data/lib/trailblazer/finder/adapters/active_record.rb +0 -32
  69. data/lib/trailblazer/finder/adapters/data_mapper.rb +0 -32
  70. data/lib/trailblazer/finder/adapters/data_mapper/paging.rb +0 -20
  71. data/lib/trailblazer/finder/adapters/data_mapper/predicates.rb +0 -42
  72. data/lib/trailblazer/finder/adapters/data_mapper/sorting.rb +0 -38
  73. data/lib/trailblazer/finder/adapters/friendly_id.rb +0 -31
  74. data/lib/trailblazer/finder/adapters/kaminari.rb +0 -18
  75. data/lib/trailblazer/finder/adapters/sequel.rb +0 -32
  76. data/lib/trailblazer/finder/adapters/will_paginate.rb +0 -18
  77. data/lib/trailblazer/finder/errors/block_ignored.rb +0 -11
  78. data/lib/trailblazer/finder/errors/invalid_defined_by_value.rb +0 -11
  79. data/lib/trailblazer/finder/errors/invalid_number.rb +0 -16
  80. data/lib/trailblazer/finder/errors/missing_entity_type.rb +0 -11
  81. data/lib/trailblazer/finder/errors/with_ignored.rb +0 -11
  82. data/lib/trailblazer/finder/features.rb +0 -23
  83. data/lib/trailblazer/finder/features/paging.rb +0 -55
  84. data/lib/trailblazer/finder/features/predicate.rb +0 -32
  85. data/lib/trailblazer/finder/features/sorting.rb +0 -108
  86. data/lib/trailblazer/finder/filter.rb +0 -66
  87. data/lib/trailblazer/finder/predicates.rb +0 -39
  88. data/lib/trailblazer/finder/utils/deep_locate.rb +0 -30
  89. data/lib/trailblazer/finder/utils/params.rb +0 -28
  90. data/lib/trailblazer/finder/utils/parse.rb +0 -25
  91. data/spec/spec_helper_data_mapper.rb +0 -35
  92. data/spec/support/paging_shared_example.rb +0 -65
  93. data/spec/support/sorting_shared_example.rb +0 -125
  94. data/spec/trailblazer/finder/adapters/active_record/base_spec.rb +0 -112
  95. data/spec/trailblazer/finder/adapters/active_record/paging_spec.rb +0 -64
  96. data/spec/trailblazer/finder/adapters/active_record/predicates_spec.rb +0 -101
  97. data/spec/trailblazer/finder/adapters/active_record/sorting_spec.rb +0 -99
  98. data/spec/trailblazer/finder/adapters/data_mapper/base_spec.rb +0 -112
  99. data/spec/trailblazer/finder/adapters/data_mapper/paging_spec.rb +0 -64
  100. data/spec/trailblazer/finder/adapters/data_mapper/predicates_spec.rb +0 -100
  101. data/spec/trailblazer/finder/adapters/data_mapper/sorting_spec.rb +0 -97
  102. data/spec/trailblazer/finder/adapters/friendly_id_spec.rb +0 -46
  103. data/spec/trailblazer/finder/adapters/sequel/base_spec.rb +0 -125
  104. data/spec/trailblazer/finder/adapters/sequel/paging_spec.rb +0 -64
  105. data/spec/trailblazer/finder/adapters/sequel/predicates_spec.rb +0 -89
  106. data/spec/trailblazer/finder/adapters/sequel/sorting_spec.rb +0 -110
  107. data/spec/trailblazer/finder/adapters_spec.rb +0 -110
  108. data/spec/trailblazer/finder/features/paging_spec.rb +0 -104
  109. data/spec/trailblazer/finder/features/predicates_spec.rb +0 -99
  110. data/spec/trailblazer/finder/features/sorting_spec.rb +0 -96
  111. data/spec/trailblazer/finder/features_spec.rb +0 -55
  112. data/spec/trailblazer/finder/filter_spec.rb +0 -133
  113. data/spec/trailblazer/finder/find_spec.rb +0 -72
  114. data/spec/trailblazer/finder/utils/extra_spec.rb +0 -41
  115. data/spec/trailblazer/finder/utils/params_spec.rb +0 -39
  116. data/spec/trailblazer/finder/utils/parse_spec.rb +0 -33
  117. data/spec/trailblazer/operation/paging_spec.rb +0 -68
  118. data/spec/trailblazer/operation/predicates_spec.rb +0 -127
  119. data/spec/trailblazer/operation/sorting_spec.rb +0 -80
  120. data/spec/trailblazer/test_spec.rb +0 -41
@@ -1,32 +0,0 @@
1
- module Trailblazer
2
- class Finder
3
- module Features
4
- module Predicate
5
- PREDICATES = %w[eq not_eq blank not_blank lt lte gt gte].freeze
6
-
7
- def self.included(base)
8
- base.extend ClassMethods
9
- base.instance_eval do
10
- include Predicates
11
- end
12
- end
13
-
14
- module ClassMethods
15
- def predicate_filter(attribute, predicate)
16
- filter_by "#{attribute}_#{predicate}" do |entity_type, value|
17
- splitter = Utils::Splitter.new "#{attribute}_#{predicate}", value
18
- splitter.split_key predicate.to_sym
19
- send splitter.op, splitter.field, splitter.value, entity_type
20
- end
21
- end
22
-
23
- def predicates_for(*attributes)
24
- attributes.each do |attribute|
25
- PREDICATES.each { |predicate| predicate_filter(attribute, predicate) }
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,108 +0,0 @@
1
- module Trailblazer
2
- class Finder
3
- module Features
4
- module Sorting
5
- def self.included(base)
6
- base.extend ClassMethods
7
- base.instance_eval do
8
- filter_by :sort do |entity_type, value|
9
- next sort_it(entity_type, [sort_orders(sort_attribute(value), sort_direction(value))]) if value.nil?
10
- sort_attributes = value.split(',')
11
- sorters = []
12
- sort_attributes.each do |sort_attr|
13
- sorters << sort_orders(sort_attribute(sort_attr), sort_direction(sort_attr))
14
- end
15
- sort_it(entity_type, sorters)
16
- end
17
- end
18
- end
19
-
20
- def sort?(attribute)
21
- sort.include?(attribute.to_s)
22
- end
23
-
24
- def sort_direction_for(attribute)
25
- return 'asc' if !sort.nil? && sort.include?("#{attribute} asc")
26
- 'desc'
27
- end
28
-
29
- def reverse_sort_direction_for(attribute)
30
- return 'desc' if sort_direction_for(attribute) == 'asc'
31
- 'asc'
32
- end
33
-
34
- def sort_params_for(attribute, options = {})
35
- options['sort'] = if sort.nil?
36
- "#{attribute} #{sort_direction_for(attribute)}"
37
- elsif sort.include?(attribute.to_s)
38
- sort
39
- else
40
- "#{attribute} #{sort_direction_for(attribute)}"
41
- end
42
- params options
43
- end
44
-
45
- def new_sort_params_for(attribute, options = {})
46
- options['sort'] = "#{attribute} #{sort_direction_for(attribute)}"
47
- params options
48
- end
49
-
50
- def add_sort_params_for(attribute, options = {})
51
- options['sort'] = if sort.nil?
52
- "#{attribute} #{sort_direction_for(attribute)}"
53
- elsif sort.include?(attribute.to_s)
54
- sort.gsub(/#{attribute} #{sort_direction_for(attribute)}/, "#{attribute} #{reverse_sort_direction_for(attribute)}")
55
- else
56
- "#{sort}, #{attribute} #{sort_direction_for(attribute)}"
57
- end
58
- params options
59
- end
60
-
61
- private
62
-
63
- # ORM Adapters will overwite this method
64
- def sort_it(entity_type, sort_attributes)
65
- entity_type.sort do |this, that|
66
- sort_attributes.reduce(0) do |diff, order|
67
- next diff if diff != 0 # this and that have differed at an earlier order entry
68
- key, direction = order
69
- # deal with nil cases
70
- next 0 if this[key].nil? && that[key].nil?
71
- next 1 if this[key].nil?
72
- next -1 if that[key].nil?
73
- # do the actual comparison
74
- comparison = this[key] <=> that[key]
75
- comparison * direction
76
- end
77
- end
78
- end
79
-
80
- # ORM Adapters will overwite this method
81
- def sort_orders(sort_attr, sort_dir)
82
- [sort_attr.to_sym, (sort_dir.to_sym == :asc ? 1 : -1)]
83
- end
84
-
85
- def sort_attribute(attribute)
86
- result = Utils::Extra.ensure_included attribute.to_s.split(' ', 2).first, self.class.sort_attributes
87
- result
88
- end
89
-
90
- def sort_direction(attribute)
91
- return Utils::Extra.ensure_included attribute.to_s.split(' ', 2).last, %w[desc asc] unless attribute.nil?
92
- 'desc'
93
- end
94
-
95
- module ClassMethods
96
- attr_accessor :sorted_attributes
97
- def sortable_by(*attributes)
98
- config[:sort_attributes] = attributes.map(&:to_s)
99
- end
100
-
101
- def sort_attributes
102
- config[:sort_attributes] ||= []
103
- end
104
- end
105
- end
106
- end
107
- end
108
- end
@@ -1,66 +0,0 @@
1
- module Trailblazer
2
- class Finder
3
- module Filter
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
7
-
8
- module ClassMethods
9
- def filter_by(name, options = nil, &block)
10
- return super unless options.is_a?(Hash) && options[:defined_by]
11
-
12
- raise Error::BlockIgnored if block
13
- raise Error::WithIgnored if options[:with]
14
-
15
- handler = Handler.build(name, options[:defined_by])
16
-
17
- super(name, options, &handler)
18
- end
19
- end
20
-
21
- module Handler
22
- module_function
23
-
24
- def build(name, defined_bys)
25
- defined_bys = defined_bys.map(&:to_s)
26
- handler = self
27
- lambda do |entity_type, value|
28
- handler.apply_filter(
29
- object: self,
30
- filter_by: name,
31
- defined_bys: defined_bys,
32
- entity_type: entity_type,
33
- value: value
34
- )
35
- end
36
- end
37
-
38
- def apply_filter(object:, filter_by:, defined_bys:, entity_type:, value:)
39
- return if value.nil? || value == ''
40
-
41
- unless defined_bys.include? value
42
- return handle_invalid_value(
43
- object: object,
44
- filter_by: filter_by,
45
- defined_bys: defined_bys,
46
- entity_type: entity_type,
47
- value: value
48
- )
49
- end
50
-
51
- object.send("apply_#{filter_by}_with_#{Utils::String.underscore(value)}", entity_type)
52
- end
53
-
54
- def handle_invalid_value(object:, filter_by:, defined_bys:, entity_type:, value:)
55
- specific = "handle_invalid_#{filter_by}"
56
- return object.send(specific, entity_type, value) if object.respond_to? specific, true
57
-
58
- catch_all = 'handle_invalid_defined_by'
59
- return object.send(catch_all, filter_by, entity_type, value) if object.respond_to? catch_all, true
60
-
61
- raise Error::InvalidDefinedByValue.new(filter_by, defined_bys, value)
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,39 +0,0 @@
1
- module Trailblazer
2
- class Finder
3
- module Predicates
4
- def not_eq(attribute, value, entity_type)
5
- return if Utils::String.blank?(value.to_s)
6
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && v.to_s != value.to_s && v != nil }, entity_type
7
- end
8
-
9
- def eq(attribute, value, entity_type)
10
- return if Utils::String.blank?(value.to_s)
11
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && v.to_s == value.to_s && v != nil }, entity_type
12
- end
13
-
14
- def blank(attribute, _value, entity_type)
15
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && Utils::String.blank?(v.to_s) }, entity_type
16
- end
17
-
18
- def not_blank(attribute, _value, entity_type)
19
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && !Utils::String.blank?(v.to_s) }, entity_type
20
- end
21
-
22
- def gt(attribute, value, entity_type)
23
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && v.to_i > value.to_f }, entity_type
24
- end
25
-
26
- def gte(attribute, value, entity_type)
27
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && v.to_i >= value.to_f }, entity_type
28
- end
29
-
30
- def lt(attribute, value, entity_type)
31
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && v.to_i < value.to_f }, entity_type
32
- end
33
-
34
- def lte(attribute, value, entity_type)
35
- Utils::DeepLocate.deep_locate ->(k, v, _object) { k == attribute.to_sym && v.to_i <= value.to_f }, entity_type
36
- end
37
- end
38
- end
39
- end
@@ -1,30 +0,0 @@
1
- module Trailblazer
2
- class Finder
3
- module Utils
4
- module DeepLocate
5
- def self.deep_locate(comparator, object, result = [])
6
- if object.is_a?(::Enumerable)
7
- if object.any? { |value| match_comparator?(value, comparator, object) }
8
- result.push object
9
- end
10
- (object.respond_to?(:values) ? object.values : object.entries).each do |value|
11
- deep_locate(comparator, value, result)
12
- end
13
- end
14
-
15
- result
16
- end
17
-
18
- def self.match_comparator?(value, comparator, object)
19
- if object.is_a?(::Hash)
20
- key, value = value
21
- else
22
- key = nil
23
- end
24
-
25
- comparator.call(key, value, object)
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,28 +0,0 @@
1
- # TODO: Clean this shit up
2
- module Trailblazer
3
- class Finder
4
- # Helper module
5
- module Utils
6
- module Params
7
- module_function
8
-
9
- def stringify_keys(hash)
10
- hash = hash.to_unsafe_h if hash.respond_to? :to_unsafe_h
11
- Hash[(hash || {}).map { |k, v| [k.to_s, v] }]
12
- end
13
-
14
- def slice_keys(hash, keys)
15
- keys.each_with_object({}) do |key, memo|
16
- memo[key] = hash[key] if hash.key? key
17
- end
18
- end
19
-
20
- def normalize_params(defaults, filters, keys)
21
- (defaults || {}).merge(
22
- slice_keys(stringify_keys(filters || {}), keys || [])
23
- )
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,25 +0,0 @@
1
- require 'date'
2
-
3
- module Trailblazer
4
- class Finder
5
- # Helper module
6
- module Utils
7
- class Parse
8
- # Need a replacement for this
9
- def self.date(value)
10
- return unless valid_date(value)
11
- Date.parse(value).strftime('%Y-%m-%d')
12
- end
13
-
14
- def self.valid_date(date)
15
- date_hash = Date._parse(date.to_s)
16
- Date.valid_date?(date_hash[:year].to_i, date_hash[:mon].to_i, date_hash[:mday].to_i)
17
- end
18
-
19
- def self.term(value)
20
- "%#{value.gsub(/\s+/, '%')}%"
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,35 +0,0 @@
1
- require_relative 'spec_helper'
2
- require_relative 'support/paging_shared_example'
3
- require 'data_mapper'
4
-
5
- DataMapper.setup(:default, 'sqlite::memory:')
6
-
7
- class DProduct
8
- include DataMapper::Resource
9
-
10
- property :id, Serial
11
- property :name, String
12
- property :slug, String
13
- property :d_category_id, Integer
14
- property :price, Integer
15
- property :created_at, DateTime
16
- property :updated_at, DateTime
17
-
18
- belongs_to :d_category
19
- end
20
-
21
- class DCategory
22
- include DataMapper::Resource
23
-
24
- property :id, Serial
25
- property :title, String
26
- property :slug, String
27
- property :created_at, DateTime
28
- property :updated_at, DateTime
29
-
30
- has n, :d_product
31
- end
32
-
33
- DataMapper.finalize
34
- require 'dm-migrations'
35
- DataMapper.auto_migrate!
@@ -1,65 +0,0 @@
1
- shared_examples_for 'a paging feature' do
2
- describe '#page' do
3
- it 'treats nil page as 0' do
4
- finder = finder_with_page nil
5
- expect(finder.page).to eq 0
6
- end
7
-
8
- it 'treats negative page numbers as positive' do
9
- finder = finder_with_page(-1)
10
- expect(finder.page).to eq 0
11
- end
12
- end
13
-
14
- describe '#per_page' do
15
- it 'returns the class defined per page' do
16
- finder = finder_class.new
17
- expect(finder.per_page).to eq 2
18
- end
19
-
20
- it 'can be overwritten as option' do
21
- finder = finder_class.new per_page: 3
22
- expect(finder.per_page).to eq 3
23
- end
24
-
25
- it 'respects min per page' do
26
- finder = finder_class.new per_page: 1
27
- expect(finder.per_page).to eq 2
28
- end
29
-
30
- it 'respects max per page' do
31
- finder = finder_class.new per_page: 100
32
- expect(finder.per_page).to eq 10
33
- end
34
- end
35
-
36
- describe '.per_page' do
37
- it 'does not accept 0' do
38
- expect { define_finder_class { per_page(0) } }.to raise_error Trailblazer::Finder::Error::InvalidNumber
39
- end
40
-
41
- it 'does not accept negative number' do
42
- expect { define_finder_class { per_page(-1) } }.to raise_error Trailblazer::Finder::Error::InvalidNumber
43
- end
44
- end
45
-
46
- describe '.min_per_page' do
47
- it 'does not accept 0' do
48
- expect { define_finder_class { min_per_page(0) } }.to raise_error Trailblazer::Finder::Error::InvalidNumber
49
- end
50
-
51
- it 'does not accept negative number' do
52
- expect { define_finder_class { min_per_page(-1) } }.to raise_error Trailblazer::Finder::Error::InvalidNumber
53
- end
54
- end
55
-
56
- describe '.max_per_page' do
57
- it 'does not accept 0' do
58
- expect { define_finder_class { max_per_page(0) } }.to raise_error Trailblazer::Finder::Error::InvalidNumber
59
- end
60
-
61
- it 'does not accept negative number' do
62
- expect { define_finder_class { max_per_page(-1) } }.to raise_error Trailblazer::Finder::Error::InvalidNumber
63
- end
64
- end
65
- end
@@ -1,125 +0,0 @@
1
- shared_examples_for 'a sorting feature' do
2
- describe '#sort?' do
3
- it 'says if the requested item is sorted on, for single sort' do
4
- finder = finder_with_sort 'price desc'
5
-
6
- expect(finder).to be_sort :price
7
- expect(finder).not_to be_sort :name
8
- end
9
-
10
- it 'says if the requested item is sorted on for multiple sorts' do
11
- finder = finder_with_sort 'price desc, name asc, id desc'
12
-
13
- expect(finder).to be_sort :price
14
- expect(finder).to be_sort :name
15
- expect(finder).to be_sort :id
16
- expect(finder).not_to be_sort :created_at
17
- end
18
-
19
- it 'matches string also, for single sort' do
20
- finder = finder_with_sort 'price desc'
21
-
22
- expect(finder).to be_sort 'price'
23
- expect(finder).not_to be_sort 'name'
24
- end
25
-
26
- it 'matches string also, for multiple sorts' do
27
- finder = finder_with_sort 'price desc, name asc, id desc'
28
-
29
- expect(finder).to be_sort 'price'
30
- expect(finder).to be_sort 'name'
31
- expect(finder).to be_sort 'id'
32
- expect(finder).not_to be_sort 'created_at'
33
- end
34
-
35
- it 'matches exact strings, for single sort' do
36
- finder = finder_with_sort 'price desc'
37
-
38
- expect(finder).to be_sort 'price desc'
39
- expect(finder).not_to be_sort 'price asc'
40
- end
41
-
42
- it 'matches exact strings, for multiple sort' do
43
- finder = finder_with_sort 'price desc, name asc'
44
-
45
- expect(finder).to be_sort 'price desc'
46
- expect(finder).to be_sort 'name asc'
47
- expect(finder).not_to be_sort 'name desc'
48
- end
49
- end
50
-
51
- describe '#sort_direction_for' do
52
- it 'returns desc if current sort attribute is not the given attribute' do
53
- expect(finder_with_sort('price desc').sort_direction_for('name')).to eq 'desc'
54
- end
55
-
56
- it 'returns asc if current sort attribute is the given attribute' do
57
- expect(finder_with_sort('name desc').sort_direction_for('name')).to eq 'desc'
58
- end
59
-
60
- it 'returns desc if current sort attribute is the given attribute, but asc with direction' do
61
- expect(finder_with_sort('name asc').sort_direction_for('name')).to eq 'asc'
62
- end
63
- end
64
-
65
- describe '#reverse_sort_direction_for' do
66
- it 'returns desc if current sort attribute is not the given attribute' do
67
- expect(finder_with_sort('price desc').reverse_sort_direction_for('name')).to eq 'asc'
68
- end
69
-
70
- it 'returns asc if current sort attribute is the given attribute' do
71
- expect(finder_with_sort('name desc').reverse_sort_direction_for('name')).to eq 'asc'
72
- end
73
-
74
- it 'returns desc if current sort attribute is the given attribute, but asc with direction' do
75
- expect(finder_with_sort('name asc').reverse_sort_direction_for('name')).to eq 'desc'
76
- end
77
- end
78
-
79
- describe '#new_sort_params_for' do
80
- it 'adds new sort parmas when none are present' do
81
- finder = finder_with_sort
82
- expect(finder.new_sort_params_for(:price)).to eq 'sort' => 'price desc'
83
- end
84
-
85
- it 'adds new sort params when multiple ones exists (replaces them all)' do
86
- finder = finder_with_sort 'name desc, price desc, id asc', name: 'test'
87
- expect(finder.new_sort_params_for(:name)).to eq 'sort' => 'name desc', 'name' => 'test'
88
- end
89
- end
90
-
91
- describe '#sort_params_for' do
92
- it 'adds sort direction' do
93
- finder = finder_with_sort 'name', name: 'test'
94
- expect(finder.sort_params_for(:price)).to eq 'sort' => 'price desc', 'name' => 'test'
95
- end
96
-
97
- it 'finds params for multiple sorts' do
98
- finder = finder_with_sort 'name desc, price desc, id asc', name: 'test'
99
- expect(finder.sort_params_for(:name)).to eq 'sort' => 'name desc, price desc, id asc', 'name' => 'test'
100
- expect(finder.sort_params_for(:price)).to eq 'sort' => 'name desc, price desc, id asc', 'name' => 'test'
101
- end
102
-
103
- it 'accepts additional options' do
104
- finder = finder_with_sort
105
- expect(finder.sort_params_for(:price, name: 'value')).to eq 'sort' => 'price desc', 'name' => 'value'
106
- end
107
- end
108
-
109
- describe '#add_sort_params_for' do
110
- it 'adds sort params when none exists' do
111
- finder = finder_with_sort
112
- expect(finder.add_sort_params_for(:price)).to eq 'sort' => 'price desc'
113
- end
114
-
115
- it 'adds sort params when one already exists' do
116
- finder = finder_with_sort 'name', name: 'test'
117
- expect(finder.add_sort_params_for(:price)).to eq 'sort' => 'name, price desc', 'name' => 'test'
118
- end
119
-
120
- it 'adds sort params when current attribute already exists, but change it' do
121
- finder = finder_with_sort 'name asc, price asc', name: 'test'
122
- expect(finder.add_sort_params_for(:price)).to eq 'sort' => 'name asc, price desc', 'name' => 'test'
123
- end
124
- end
125
- end