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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml +101 -0
- data/.rubocop.yml +3 -43
- data/.rubocop_todo.yml +42 -196
- data/.travis.yml +5 -8
- data/Gemfile +2 -2
- data/LICENSE.txt +7 -21
- data/README.md +177 -292
- data/Rakefile +12 -12
- data/lib/trailblazer/finder.rb +48 -23
- data/lib/trailblazer/finder/activity/find.rb +57 -0
- data/lib/trailblazer/finder/activity/prepare.rb +29 -0
- data/lib/trailblazer/finder/activity/prepare/adapters.rb +66 -0
- data/lib/trailblazer/finder/activity/prepare/entity.rb +32 -0
- data/lib/trailblazer/finder/activity/prepare/filters.rb +36 -0
- data/lib/trailblazer/finder/activity/prepare/paging.rb +49 -0
- data/lib/trailblazer/finder/activity/prepare/params.rb +33 -0
- data/lib/trailblazer/finder/activity/prepare/properties.rb +47 -0
- data/lib/trailblazer/finder/activity/prepare/sorting.rb +57 -0
- data/lib/trailblazer/finder/activity/process.rb +18 -0
- data/lib/trailblazer/finder/activity/process/adapters.rb +48 -0
- data/lib/trailblazer/finder/activity/process/filters.rb +28 -0
- data/lib/trailblazer/finder/activity/process/paging.rb +26 -0
- data/lib/trailblazer/finder/activity/process/predicates.rb +30 -0
- data/lib/trailblazer/finder/activity/process/sorting.rb +26 -0
- data/lib/trailblazer/finder/adapters/active_record/paging.rb +9 -8
- data/lib/trailblazer/finder/adapters/active_record/predicates.rb +78 -17
- data/lib/trailblazer/finder/adapters/active_record/sorting.rb +14 -12
- data/lib/trailblazer/finder/adapters/basic/paging.rb +21 -0
- data/lib/trailblazer/finder/adapters/basic/predicates.rb +115 -0
- data/lib/trailblazer/finder/adapters/basic/sorting.rb +40 -0
- data/lib/trailblazer/finder/adapters/kaminari/paging.rb +21 -0
- data/lib/trailblazer/finder/adapters/sequel/paging.rb +9 -8
- data/lib/trailblazer/finder/adapters/sequel/predicates.rb +78 -17
- data/lib/trailblazer/finder/adapters/sequel/sorting.rb +17 -15
- data/lib/trailblazer/finder/adapters/will_paginate/paging.rb +21 -0
- data/lib/trailblazer/finder/base.rb +20 -83
- data/lib/trailblazer/finder/dsl.rb +56 -0
- data/lib/trailblazer/finder/find.rb +28 -15
- data/lib/trailblazer/finder/helpers/basic.rb +44 -0
- data/lib/trailblazer/finder/helpers/sorting.rb +54 -0
- data/lib/trailblazer/finder/utils/array.rb +20 -0
- data/lib/trailblazer/finder/utils/extra.rb +10 -20
- data/lib/trailblazer/finder/utils/hash.rb +36 -0
- data/lib/trailblazer/finder/utils/splitter.rb +16 -17
- data/lib/trailblazer/finder/utils/string.rb +20 -10
- data/lib/trailblazer/finder/version.rb +3 -1
- data/lib/trailblazer/operation/finder.rb +20 -19
- data/spec/spec_helper.rb +5 -11
- data/spec/spec_helper_active_record.rb +11 -12
- data/spec/spec_helper_sequel.rb +4 -4
- data/spec/spec_helper_will_paginate.rb +13 -0
- data/spec/trailblazer/finder/adapters/active_record_spec.rb +267 -0
- data/spec/trailblazer/finder/adapters/basic_spec.rb +251 -0
- data/spec/trailblazer/finder/adapters/kaminari_spec.rb +78 -32
- data/spec/trailblazer/finder/adapters/sequel_spec.rb +267 -0
- data/spec/trailblazer/finder/adapters/will_paginate_spec.rb +81 -40
- data/spec/trailblazer/finder/base_spec.rb +292 -204
- data/spec/trailblazer/finder/dsl_spec.rb +213 -0
- data/spec/trailblazer/finder/utils/hash_spec.rb +26 -0
- data/spec/trailblazer/finder/utils/splitter_spec.rb +39 -0
- data/spec/trailblazer/finder/utils/string_spec.rb +52 -9
- data/spec/trailblazer/operation/finder_spec.rb +35 -32
- data/trailblazer-finder.gemspec +31 -30
- metadata +119 -137
- data/lib/trailblazer/finder/adapters.rb +0 -26
- data/lib/trailblazer/finder/adapters/active_record.rb +0 -32
- data/lib/trailblazer/finder/adapters/data_mapper.rb +0 -32
- data/lib/trailblazer/finder/adapters/data_mapper/paging.rb +0 -20
- data/lib/trailblazer/finder/adapters/data_mapper/predicates.rb +0 -42
- data/lib/trailblazer/finder/adapters/data_mapper/sorting.rb +0 -38
- data/lib/trailblazer/finder/adapters/friendly_id.rb +0 -31
- data/lib/trailblazer/finder/adapters/kaminari.rb +0 -18
- data/lib/trailblazer/finder/adapters/sequel.rb +0 -32
- data/lib/trailblazer/finder/adapters/will_paginate.rb +0 -18
- data/lib/trailblazer/finder/errors/block_ignored.rb +0 -11
- data/lib/trailblazer/finder/errors/invalid_defined_by_value.rb +0 -11
- data/lib/trailblazer/finder/errors/invalid_number.rb +0 -16
- data/lib/trailblazer/finder/errors/missing_entity_type.rb +0 -11
- data/lib/trailblazer/finder/errors/with_ignored.rb +0 -11
- data/lib/trailblazer/finder/features.rb +0 -23
- data/lib/trailblazer/finder/features/paging.rb +0 -55
- data/lib/trailblazer/finder/features/predicate.rb +0 -32
- data/lib/trailblazer/finder/features/sorting.rb +0 -108
- data/lib/trailblazer/finder/filter.rb +0 -66
- data/lib/trailblazer/finder/predicates.rb +0 -39
- data/lib/trailblazer/finder/utils/deep_locate.rb +0 -30
- data/lib/trailblazer/finder/utils/params.rb +0 -28
- data/lib/trailblazer/finder/utils/parse.rb +0 -25
- data/spec/spec_helper_data_mapper.rb +0 -35
- data/spec/support/paging_shared_example.rb +0 -65
- data/spec/support/sorting_shared_example.rb +0 -125
- data/spec/trailblazer/finder/adapters/active_record/base_spec.rb +0 -112
- data/spec/trailblazer/finder/adapters/active_record/paging_spec.rb +0 -64
- data/spec/trailblazer/finder/adapters/active_record/predicates_spec.rb +0 -101
- data/spec/trailblazer/finder/adapters/active_record/sorting_spec.rb +0 -99
- data/spec/trailblazer/finder/adapters/data_mapper/base_spec.rb +0 -112
- data/spec/trailblazer/finder/adapters/data_mapper/paging_spec.rb +0 -64
- data/spec/trailblazer/finder/adapters/data_mapper/predicates_spec.rb +0 -100
- data/spec/trailblazer/finder/adapters/data_mapper/sorting_spec.rb +0 -97
- data/spec/trailblazer/finder/adapters/friendly_id_spec.rb +0 -46
- data/spec/trailblazer/finder/adapters/sequel/base_spec.rb +0 -125
- data/spec/trailblazer/finder/adapters/sequel/paging_spec.rb +0 -64
- data/spec/trailblazer/finder/adapters/sequel/predicates_spec.rb +0 -89
- data/spec/trailblazer/finder/adapters/sequel/sorting_spec.rb +0 -110
- data/spec/trailblazer/finder/adapters_spec.rb +0 -110
- data/spec/trailblazer/finder/features/paging_spec.rb +0 -104
- data/spec/trailblazer/finder/features/predicates_spec.rb +0 -99
- data/spec/trailblazer/finder/features/sorting_spec.rb +0 -96
- data/spec/trailblazer/finder/features_spec.rb +0 -55
- data/spec/trailblazer/finder/filter_spec.rb +0 -133
- data/spec/trailblazer/finder/find_spec.rb +0 -72
- data/spec/trailblazer/finder/utils/extra_spec.rb +0 -41
- data/spec/trailblazer/finder/utils/params_spec.rb +0 -39
- data/spec/trailblazer/finder/utils/parse_spec.rb +0 -33
- data/spec/trailblazer/operation/paging_spec.rb +0 -68
- data/spec/trailblazer/operation/predicates_spec.rb +0 -127
- data/spec/trailblazer/operation/sorting_spec.rb +0 -80
- 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
|