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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1dea6efd8728954e80a8a249f749dd8133ecfcf71fb6b4a3b3acf248b662fca8
4
- data.tar.gz: bd567ce813d303ca03d8d87f8faa4a312d2417b934bb1ee8c3d2781b99126f88
3
+ metadata.gz: e919c60e03780d5fab1a21ae6d528482db21d5a4fcfbc176b4808cc1d9acdc77
4
+ data.tar.gz: c9ecbbbb69e28e8fbef7aa9efe93db1cab9576634ede5ad2dc698180c1743dda
5
5
  SHA512:
6
- metadata.gz: 66f32e979d580c4297c1155f6bc87203ec808420856636724a257d07ca062ffe5d5ecd073aaa0fa0b09efb781f033affce87faa579b0007bd7f4ffe46c82fda3
7
- data.tar.gz: 54210f971ad74cd8d14b4934cb36d155943626b5e66190c682c294fdcd30f3b315cf2b5dbae268ce70a1213726e294978c80b080fdf8422bd1256a4f47dd3f37
6
+ metadata.gz: 7468e0d150c79e5ebfb5760648e97699c7b88340c68b7eaa530c58e512ee982eb1d2b44c2599b374a7348a5b9cefe7d7037603a98aa5a8a895f18bac6d4efe84
7
+ data.tar.gz: 0a7dfb9250e3f686d88f7c2932cbd1a8b07f0a38ae4d3e491e98ee4c14a22126bcf3defd58227130fe3a43f8cd7d0b5dbaf002f6ded24fd187706b445fcce28e
@@ -219,7 +219,7 @@ module Miscellany
219
219
 
220
220
  def sort_sql
221
221
  sorts = [ *Array(self.sort) ]
222
- sorts << options[:sort_parser]&.default
222
+ sorts.push(*options[:sort_parser]&.default_sorts)
223
223
  sorts.compact!
224
224
 
225
225
  return nil unless sorts.present?
@@ -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, default: default)
50
- end
66
+ @sorts_map = normalize_sort_options(valid_sorts)
67
+
68
+ @default_sorts = []
51
69
 
52
- def default
53
- @sorts_map[:default]
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
- sorts << self.default if default == :append || default && !sorts.compact.present?
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, default: nil)
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
 
@@ -1,3 +1,3 @@
1
1
  module Miscellany
2
- VERSION = "0.1.18".freeze
2
+ VERSION = "0.1.19".freeze
3
3
  end
@@ -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.18
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