miscellany 0.1.18 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/miscellany/controller/sliced_response.rb +1 -1
- data/lib/miscellany/sort_lang.rb +31 -17
- data/lib/miscellany/version.rb +1 -1
- data/spec/miscellany/sort_lang_spec.rb +124 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e919c60e03780d5fab1a21ae6d528482db21d5a4fcfbc176b4808cc1d9acdc77
|
4
|
+
data.tar.gz: c9ecbbbb69e28e8fbef7aa9efe93db1cab9576634ede5ad2dc698180c1743dda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7468e0d150c79e5ebfb5760648e97699c7b88340c68b7eaa530c58e512ee982eb1d2b44c2599b374a7348a5b9cefe7d7037603a98aa5a8a895f18bac6d4efe84
|
7
|
+
data.tar.gz: 0a7dfb9250e3f686d88f7c2932cbd1a8b07f0a38ae4d3e491e98ee4c14a22126bcf3defd58227130fe3a43f8cd7d0b5dbaf002f6ded24fd187706b445fcce28e
|
data/lib/miscellany/sort_lang.rb
CHANGED
@@ -23,6 +23,21 @@ module Miscellany
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.sqlize(sorts)
|
26
|
+
seen_sorts = Set.new
|
27
|
+
|
28
|
+
# Only include each sort key/"column" once
|
29
|
+
sorts = sorts.select do |sort|
|
30
|
+
sid = sort[:key] || sort[:column]
|
31
|
+
next true unless sid.present?
|
32
|
+
|
33
|
+
if seen_sorts.include?(sid)
|
34
|
+
false
|
35
|
+
else
|
36
|
+
seen_sorts << sid
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
26
41
|
sorts.map do |sort|
|
27
42
|
order = sort[:order] || 'ASC'
|
28
43
|
if sort[:column].is_a?(Proc)
|
@@ -45,12 +60,20 @@ module Miscellany
|
|
45
60
|
class Parser
|
46
61
|
class SortParsingError < StandardError; end
|
47
62
|
|
63
|
+
attr_reader :default_sorts
|
64
|
+
|
48
65
|
def initialize(valid_sorts, default: nil)
|
49
|
-
@sorts_map = normalize_sort_options(valid_sorts
|
50
|
-
|
66
|
+
@sorts_map = normalize_sort_options(valid_sorts)
|
67
|
+
|
68
|
+
@default_sorts = []
|
51
69
|
|
52
|
-
|
53
|
-
|
70
|
+
parsed_defaults = normalize_sort_options(Array(default))
|
71
|
+
parsed_defaults.each do |k,v|
|
72
|
+
@sorts_map[k] ||= v
|
73
|
+
end
|
74
|
+
@default_sorts = parsed_defaults.keys.map do |k|
|
75
|
+
@sorts_map[k]
|
76
|
+
end
|
54
77
|
end
|
55
78
|
|
56
79
|
def valid?(sortstr)
|
@@ -80,14 +103,16 @@ module Miscellany
|
|
80
103
|
sort
|
81
104
|
end
|
82
105
|
|
83
|
-
|
106
|
+
if default == :append || default && !sorts.compact.present?
|
107
|
+
sorts.push(*self.default_sorts)
|
108
|
+
end
|
84
109
|
|
85
110
|
sorts.compact.presence
|
86
111
|
end
|
87
112
|
|
88
113
|
protected
|
89
114
|
|
90
|
-
def normalize_sort_options(sorts
|
115
|
+
def normalize_sort_options(sorts)
|
91
116
|
norm_sorts = { }
|
92
117
|
|
93
118
|
sorts.each do |s|
|
@@ -100,20 +125,9 @@ module Miscellany
|
|
100
125
|
else
|
101
126
|
sort_hash = normalize_sort(s)
|
102
127
|
norm_sorts[sort_hash[:column]] = sort_hash
|
103
|
-
# default ||= sort_hash
|
104
128
|
end
|
105
129
|
end
|
106
130
|
|
107
|
-
if default.present?
|
108
|
-
norm_default = normalize_sort(default)
|
109
|
-
reference = norm_sorts[norm_default[:key].to_s] || norm_default
|
110
|
-
norm_sorts[:default] = {
|
111
|
-
key: reference[:key],
|
112
|
-
column: reference[:column],
|
113
|
-
order: norm_default[:order] || reference[:order],
|
114
|
-
}
|
115
|
-
end
|
116
|
-
|
117
131
|
norm_sorts
|
118
132
|
end
|
119
133
|
|
data/lib/miscellany/version.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Miscellany::SortLang do
|
5
|
+
|
6
|
+
describe ".normalize_sort" do
|
7
|
+
it "accepts Hash KV pairs" do
|
8
|
+
expect(Miscellany::SortLang.normalize_sort(["key", { column: "created_at", order: "ASC" }])).to eql({
|
9
|
+
column: "created_at", force_order: false, key: "created_at", order: "ASC"
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
it "accepts strings" do
|
14
|
+
expect(Miscellany::SortLang.normalize_sort("created_at")).to eql({
|
15
|
+
column: "created_at", force_order: false, key: "created_at"
|
16
|
+
})
|
17
|
+
expect(Miscellany::SortLang.normalize_sort("created_at ASC")).to eql({
|
18
|
+
column: "created_at", force_order: false, key: "created_at", order: "ASC"
|
19
|
+
})
|
20
|
+
expect(Miscellany::SortLang.normalize_sort("created_at ASC!")).to eql({
|
21
|
+
column: "created_at", force_order: true, key: "created_at", order: "ASC"
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "accepts Procs" do
|
26
|
+
logic = ->(x) { "created_at #{x}" }
|
27
|
+
expect(Miscellany::SortLang.normalize_sort(logic, key: "k")).to eql({
|
28
|
+
column: logic, key: "k"
|
29
|
+
})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".sqlize" do
|
34
|
+
it "only includes each sort key once" do
|
35
|
+
expect(Miscellany::SortLang.sqlize([
|
36
|
+
{ column: "created_at", order: "ASC" },
|
37
|
+
{ column: "created_at", order: "DESC" },
|
38
|
+
])).to eql "created_at ASC NULLS FIRST"
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "nulls: option" do
|
42
|
+
it "accepts a nulls: option" do
|
43
|
+
expect(Miscellany::SortLang.sqlize([
|
44
|
+
{ column: "created_at", order: "ASC", nulls: :last },
|
45
|
+
])).to eql "created_at ASC NULLS LAST"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "nulls: :high works" do
|
49
|
+
expect(Miscellany::SortLang.sqlize([
|
50
|
+
{ column: "created_at", order: "ASC", nulls: :high },
|
51
|
+
])).to eql "created_at ASC NULLS LAST"
|
52
|
+
expect(Miscellany::SortLang.sqlize([
|
53
|
+
{ column: "created_at", order: "DESC", nulls: :high },
|
54
|
+
])).to eql "created_at DESC NULLS FIRST"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "nulls: :low works" do
|
58
|
+
expect(Miscellany::SortLang.sqlize([
|
59
|
+
{ column: "created_at", order: "ASC", nulls: :low },
|
60
|
+
])).to eql "created_at ASC NULLS FIRST"
|
61
|
+
expect(Miscellany::SortLang.sqlize([
|
62
|
+
{ column: "created_at", order: "DESC", nulls: :low },
|
63
|
+
])).to eql "created_at DESC NULLS LAST"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe Miscellany::SortLang::Parser do
|
69
|
+
let(:valid_sorts) {[
|
70
|
+
"title", "created_at"
|
71
|
+
]}
|
72
|
+
let(:default_sort) { "title" }
|
73
|
+
|
74
|
+
let(:subject) { Miscellany::SortLang::Parser.new(valid_sorts, default: default_sort) }
|
75
|
+
|
76
|
+
context "with multiple default sorts" do
|
77
|
+
let(:default_sort) { ["title", "created_at"] }
|
78
|
+
|
79
|
+
it "includes each" do
|
80
|
+
expect(subject.parse(nil)).to eql [
|
81
|
+
{:column=>"title", :force_order=>false, :key=>"title"},
|
82
|
+
{:column=>"created_at", :force_order=>false, :key=>"created_at"},
|
83
|
+
]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#parse" do
|
88
|
+
it "excludes uknown sorts" do
|
89
|
+
expect(subject.parse("updated_at")).to eql [
|
90
|
+
{:column=>"title", :force_order=>false, :key=>"title"},
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "considers force_order" do
|
95
|
+
subject = Miscellany::SortLang::Parser.new([ "title ASC!" ])
|
96
|
+
expect(subject.parse("title DESC")).to eql [
|
97
|
+
{:column=>"title", :force_order=>true, :key=>"title", :order=>"ASC"},
|
98
|
+
]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns the default sort if no sort is given" do
|
102
|
+
expect(subject.parse("")).to eql [
|
103
|
+
{:column=>"title", :force_order=>false, :key=>"title"},
|
104
|
+
]
|
105
|
+
expect(subject.parse("", default: true)).to eql [
|
106
|
+
{:column=>"title", :force_order=>false, :key=>"title"},
|
107
|
+
]
|
108
|
+
end
|
109
|
+
|
110
|
+
it "appends the default sort" do
|
111
|
+
expect(subject.parse("created_at", default: :append)).to eql [
|
112
|
+
{:column=>"created_at", :force_order=>false, :key=>"created_at"},
|
113
|
+
{:column=>"title", :force_order=>false, :key=>"title"},
|
114
|
+
]
|
115
|
+
end
|
116
|
+
|
117
|
+
it "excludes the default sort" do
|
118
|
+
expect(subject.parse("created_at", default: false)).to eql [
|
119
|
+
{:column=>"created_at", :force_order=>false, :key=>"created_at"},
|
120
|
+
]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miscellany
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan Knapp
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- spec/miscellany/goldiload_value_spec.rb
|
150
150
|
- spec/miscellany/param_validator_spec.rb
|
151
151
|
- spec/miscellany/sliced_response_spec.rb
|
152
|
+
- spec/miscellany/sort_lang_spec.rb
|
152
153
|
- spec/spec_helper.rb
|
153
154
|
homepage: https://instructure.com
|
154
155
|
licenses: []
|
@@ -174,6 +175,7 @@ specification_version: 4
|
|
174
175
|
summary: Gem for a bunch of random, re-usable Rails Concerns & Helpers
|
175
176
|
test_files:
|
176
177
|
- spec/db/database.yml
|
178
|
+
- spec/miscellany/sort_lang_spec.rb
|
177
179
|
- spec/miscellany/arbitrary_prefetch_spec.rb
|
178
180
|
- spec/miscellany/sliced_response_spec.rb
|
179
181
|
- spec/miscellany/param_validator_spec.rb
|