sortability 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +2 -2
- data/lib/sortability/active_record/base.rb +19 -16
- data/lib/sortability/version.rb +1 -1
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/container.rb +5 -0
- data/spec/dummy/app/models/item.rb +3 -0
- data/spec/dummy/config/application.rb +3 -0
- data/spec/dummy/db/migrate/20190523235417_create_containers.rb +9 -0
- data/spec/dummy/db/migrate/20190523235430_create_items.rb +12 -0
- data/spec/dummy/db/schema.rb +29 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +2485 -0
- data/spec/lib/sortability/active_record/base_spec.rb +202 -1
- data/spec/lib/sortability/active_record/connection_adapters/table_definition_spec.rb +21 -1
- data/spec/lib/sortability/active_record/migration_spec.rb +44 -1
- metadata +35 -32
- data/spec/dummy/log/development.log +0 -0
@@ -3,7 +3,208 @@ require "rails_helper"
|
|
3
3
|
module Sortability
|
4
4
|
module ActiveRecord
|
5
5
|
RSpec.describe Base do
|
6
|
-
|
6
|
+
context 'unscoped' do
|
7
|
+
let(:container_1) { Container.new }
|
8
|
+
let(:container_2) { Container.new }
|
9
|
+
|
10
|
+
it 'can return the sort peers for a record' do
|
11
|
+
expect(container_1.sort_position_peers).to be_empty
|
12
|
+
expect(container_2.sort_position_peers).to be_empty
|
13
|
+
|
14
|
+
container_1.save!
|
15
|
+
expect(container_1.sort_position_peers).to eq [ container_1 ]
|
16
|
+
expect(container_2.sort_position_peers).to eq [ container_1 ]
|
17
|
+
|
18
|
+
container_2.save!
|
19
|
+
expect(container_1.sort_position_peers).to eq [ container_1, container_2 ]
|
20
|
+
expect(container_2.sort_position_peers).to eq [ container_1, container_2 ]
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'automatically assigns sequential sort_positions to created records' do
|
24
|
+
expect(container_1.sort_position).to be_nil
|
25
|
+
expect(container_2.sort_position).to be_nil
|
26
|
+
|
27
|
+
container_1.save!
|
28
|
+
expect(container_1.sort_position).to eq 1
|
29
|
+
expect(container_2.sort_position).to be_nil
|
30
|
+
|
31
|
+
container_2.save!
|
32
|
+
expect(container_1.sort_position).to eq 1
|
33
|
+
expect(container_2.sort_position).to eq 2
|
34
|
+
end
|
35
|
+
|
36
|
+
it "automatically increases other records' sort_positions to avoid conflicts" do
|
37
|
+
container_1.save!
|
38
|
+
container_2.save!
|
39
|
+
container_3 = Container.create! sort_position: 1
|
40
|
+
|
41
|
+
expect(container_1.reload.sort_position).to eq 2
|
42
|
+
expect(container_2.reload.sort_position).to eq 3
|
43
|
+
expect(container_3.sort_position).to eq 1
|
44
|
+
expect(container_3.reload.sort_position).to eq 1
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can return the next record by sort_position' do
|
48
|
+
container_1.save!
|
49
|
+
container_2.save!
|
50
|
+
|
51
|
+
expect(container_1.next_by_sort_position).to eq container_2
|
52
|
+
expect(container_2.next_by_sort_position).to be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can return the previous record by sort_position' do
|
56
|
+
container_1.save!
|
57
|
+
container_2.save!
|
58
|
+
|
59
|
+
expect(container_1.previous_by_sort_position).to be_nil
|
60
|
+
expect(container_2.previous_by_sort_position).to eq container_1
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'can compact the sort peers to make their numbers sequential' do
|
64
|
+
container_1.sort_position = 21
|
65
|
+
container_1.save!
|
66
|
+
container_2.sort_position = 42
|
67
|
+
container_2.save!
|
68
|
+
|
69
|
+
expect(container_1.reload.sort_position).to eq 21
|
70
|
+
expect(container_2.reload.sort_position).to eq 42
|
71
|
+
|
72
|
+
container_1.compact_sort_position_peers!
|
73
|
+
|
74
|
+
expect(container_1.sort_position).to eq 1
|
75
|
+
expect(container_1.reload.sort_position).to eq 1
|
76
|
+
expect(container_2.reload.sort_position).to eq 2
|
77
|
+
|
78
|
+
container_2.compact_sort_position_peers!
|
79
|
+
|
80
|
+
expect(container_1.reload.sort_position).to eq 1
|
81
|
+
expect(container_2.sort_position).to eq 2
|
82
|
+
expect(container_2.reload.sort_position).to eq 2
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'scoped' do
|
87
|
+
let(:container_1) { Container.create }
|
88
|
+
let(:container_2) { Container.create }
|
89
|
+
let(:item_1) { Item.new(container: container_1) }
|
90
|
+
let(:item_2) { Item.new(container: container_1) }
|
91
|
+
let(:item_3) { Item.new(container: container_2) }
|
92
|
+
|
93
|
+
it 'can return the sort peers for a record' do
|
94
|
+
expect(item_1.sort_position_peers).to be_empty
|
95
|
+
expect(item_2.sort_position_peers).to be_empty
|
96
|
+
expect(item_3.sort_position_peers).to be_empty
|
97
|
+
|
98
|
+
item_1.save!
|
99
|
+
expect(item_1.sort_position_peers).to eq [ item_1 ]
|
100
|
+
expect(item_2.sort_position_peers).to eq [ item_1 ]
|
101
|
+
expect(item_3.sort_position_peers).to be_empty
|
102
|
+
|
103
|
+
container_1.reload
|
104
|
+
container_2.reload
|
105
|
+
|
106
|
+
item_2.save!
|
107
|
+
expect(item_1.sort_position_peers).to eq [ item_1, item_2 ]
|
108
|
+
expect(item_2.sort_position_peers).to eq [ item_1, item_2 ]
|
109
|
+
expect(item_3.sort_position_peers).to be_empty
|
110
|
+
|
111
|
+
container_1.reload
|
112
|
+
container_2.reload
|
113
|
+
|
114
|
+
item_3.save!
|
115
|
+
expect(item_1.sort_position_peers).to eq [ item_1, item_2 ]
|
116
|
+
expect(item_2.sort_position_peers).to eq [ item_1, item_2 ]
|
117
|
+
expect(item_3.sort_position_peers).to eq [ item_3 ]
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'automatically assigns sequential sort_positions to created records in each scope' do
|
121
|
+
expect(item_1.sort_position).to be_nil
|
122
|
+
expect(item_2.sort_position).to be_nil
|
123
|
+
expect(item_3.sort_position).to be_nil
|
124
|
+
|
125
|
+
item_1.save!
|
126
|
+
expect(item_1.sort_position).to eq 1
|
127
|
+
expect(item_2.sort_position).to be_nil
|
128
|
+
expect(item_3.sort_position).to be_nil
|
129
|
+
|
130
|
+
item_2.save!
|
131
|
+
expect(item_1.sort_position).to eq 1
|
132
|
+
expect(item_2.sort_position).to eq 2
|
133
|
+
expect(item_3.sort_position).to be_nil
|
134
|
+
|
135
|
+
item_3.save!
|
136
|
+
expect(item_1.sort_position).to eq 1
|
137
|
+
expect(item_2.sort_position).to eq 2
|
138
|
+
expect(item_3.sort_position).to eq 1
|
139
|
+
end
|
140
|
+
|
141
|
+
it "automatically increases other records' sort_positions to avoid conflicts" do
|
142
|
+
item_1.save!
|
143
|
+
item_2.save!
|
144
|
+
item_3.save!
|
145
|
+
item_4 = Item.create! container: container_1, sort_position: 1
|
146
|
+
|
147
|
+
expect(item_1.reload.sort_position).to eq 2
|
148
|
+
expect(item_2.reload.sort_position).to eq 3
|
149
|
+
expect(item_3.reload.sort_position).to eq 1
|
150
|
+
expect(item_4.sort_position).to eq 1
|
151
|
+
expect(item_4.reload.sort_position).to eq 1
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'can return the next record by sort_position' do
|
155
|
+
item_1.save!
|
156
|
+
item_2.save!
|
157
|
+
item_3.save!
|
158
|
+
|
159
|
+
expect(item_1.next_by_sort_position).to eq item_2
|
160
|
+
expect(item_2.next_by_sort_position).to be_nil
|
161
|
+
expect(item_3.next_by_sort_position).to be_nil
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'can return the previous record by sort_position' do
|
165
|
+
item_1.save!
|
166
|
+
item_2.save!
|
167
|
+
item_3.save!
|
168
|
+
|
169
|
+
expect(item_1.previous_by_sort_position).to be_nil
|
170
|
+
expect(item_2.previous_by_sort_position).to eq item_1
|
171
|
+
expect(item_3.previous_by_sort_position).to be_nil
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'can compact the sort peers to make their numbers sequential' do
|
175
|
+
item_1.sort_position = 21
|
176
|
+
item_1.save!
|
177
|
+
item_2.sort_position = 42
|
178
|
+
item_2.save!
|
179
|
+
item_3.sort_position = 84
|
180
|
+
item_3.save!
|
181
|
+
|
182
|
+
expect(item_1.reload.sort_position).to eq 21
|
183
|
+
expect(item_2.reload.sort_position).to eq 42
|
184
|
+
expect(item_3.reload.sort_position).to eq 84
|
185
|
+
|
186
|
+
item_1.compact_sort_position_peers!
|
187
|
+
|
188
|
+
expect(item_1.sort_position).to eq 1
|
189
|
+
expect(item_1.reload.sort_position).to eq 1
|
190
|
+
expect(item_2.reload.sort_position).to eq 2
|
191
|
+
expect(item_3.reload.sort_position).to eq 84
|
192
|
+
|
193
|
+
item_2.compact_sort_position_peers!
|
194
|
+
|
195
|
+
expect(item_1.reload.sort_position).to eq 1
|
196
|
+
expect(item_2.sort_position).to eq 2
|
197
|
+
expect(item_2.reload.sort_position).to eq 2
|
198
|
+
expect(item_3.reload.sort_position).to eq 84
|
199
|
+
|
200
|
+
item_3.compact_sort_position_peers!
|
201
|
+
|
202
|
+
expect(item_1.reload.sort_position).to eq 1
|
203
|
+
expect(item_2.reload.sort_position).to eq 2
|
204
|
+
expect(item_3.sort_position).to eq 1
|
205
|
+
expect(item_3.reload.sort_position).to eq 1
|
206
|
+
end
|
207
|
+
end
|
7
208
|
end
|
8
209
|
end
|
9
210
|
end
|
@@ -4,7 +4,27 @@ module Sortability
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
6
|
RSpec.describe TableDefinition do
|
7
|
-
|
7
|
+
let(:table_definition) { ::ActiveRecord::ConnectionAdapters::TableDefinition.new nil, :test }
|
8
|
+
|
9
|
+
context 'without :on and :null' do
|
10
|
+
let(:options) { { something: :else } }
|
11
|
+
|
12
|
+
it '#sortable calls the #integer method, adding defaults' do
|
13
|
+
expect(table_definition).to(
|
14
|
+
receive(:integer).with(:sort_position, options.merge(null: false))
|
15
|
+
)
|
16
|
+
table_definition.sortable options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with :on and :null' do
|
21
|
+
let(:options) { { something: :else, on: :pos, null: true } }
|
22
|
+
|
23
|
+
it '#sortable calls the #integer method with the given options' do
|
24
|
+
expect(table_definition).to receive(:integer).with(:pos, options.except(:on))
|
25
|
+
table_definition.sortable options
|
26
|
+
end
|
27
|
+
end
|
8
28
|
end
|
9
29
|
end
|
10
30
|
end
|
@@ -3,7 +3,50 @@ require "rails_helper"
|
|
3
3
|
module Sortability
|
4
4
|
module ActiveRecord
|
5
5
|
RSpec.describe Migration do
|
6
|
-
|
6
|
+
let(:migration) { ::ActiveRecord::Migration.new }
|
7
|
+
let(:table) { :test }
|
8
|
+
|
9
|
+
context 'without some options' do
|
10
|
+
let(:options) { { something: :else } }
|
11
|
+
|
12
|
+
it '#add_sortable_column can add a sortable column, adding defaults' do
|
13
|
+
expect(migration).to receive(:method_missing).with(
|
14
|
+
:add_column, table, :sort_position, :integer, options.merge(null: false)
|
15
|
+
)
|
16
|
+
|
17
|
+
migration.add_sortable_column table, options
|
18
|
+
end
|
19
|
+
|
20
|
+
it '#add_sortable_index can add a sortable index, adding defaults' do
|
21
|
+
expect(migration).to receive(:method_missing).with(
|
22
|
+
:add_index, table, [ :sort_position ], options.merge(unique: true)
|
23
|
+
)
|
24
|
+
|
25
|
+
migration.add_sortable_index table, options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with all options' do
|
30
|
+
let(:options) do
|
31
|
+
{ something: :else, on: :pos, null: true, unique: false, scope: :container_id }
|
32
|
+
end
|
33
|
+
|
34
|
+
it '#add_sortable_column can add a sortable column with the given options' do
|
35
|
+
expect(migration).to receive(:method_missing).with(
|
36
|
+
:add_column, table, :pos, :integer, options.except(:on)
|
37
|
+
)
|
38
|
+
|
39
|
+
migration.add_sortable_column table, options
|
40
|
+
end
|
41
|
+
|
42
|
+
it '#add_sortable_index can add a sortable index with the given options' do
|
43
|
+
expect(migration).to receive(:method_missing).with(
|
44
|
+
:add_index, table, [ :container_id, :pos ], options.except(:on, :scope)
|
45
|
+
)
|
46
|
+
|
47
|
+
migration.add_sortable_index table, options
|
48
|
+
end
|
49
|
+
end
|
7
50
|
end
|
8
51
|
end
|
9
52
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sortability
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dante Soares
|
8
8
|
- JP Slavinsky
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-08-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -17,56 +17,48 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
21
|
-
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ">="
|
20
|
+
version: '5'
|
21
|
+
- - "<"
|
26
22
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: squeel
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
requirements:
|
32
|
-
- - ">="
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '0'
|
23
|
+
version: '7'
|
35
24
|
type: :runtime
|
36
25
|
prerelease: false
|
37
26
|
version_requirements: !ruby/object:Gem::Requirement
|
38
27
|
requirements:
|
39
28
|
- - ">="
|
40
29
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
30
|
+
version: '5'
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '7'
|
42
34
|
- !ruby/object:Gem::Dependency
|
43
35
|
name: sqlite3
|
44
36
|
requirement: !ruby/object:Gem::Requirement
|
45
37
|
requirements:
|
46
|
-
- - "
|
38
|
+
- - "<"
|
47
39
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0'
|
40
|
+
version: '2.0'
|
49
41
|
type: :development
|
50
42
|
prerelease: false
|
51
43
|
version_requirements: !ruby/object:Gem::Requirement
|
52
44
|
requirements:
|
53
|
-
- - "
|
45
|
+
- - "<"
|
54
46
|
- !ruby/object:Gem::Version
|
55
|
-
version: '0'
|
47
|
+
version: '2.0'
|
56
48
|
- !ruby/object:Gem::Dependency
|
57
49
|
name: rspec-rails
|
58
50
|
requirement: !ruby/object:Gem::Requirement
|
59
51
|
requirements:
|
60
52
|
- - ">="
|
61
53
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
54
|
+
version: '0'
|
63
55
|
type: :development
|
64
56
|
prerelease: false
|
65
57
|
version_requirements: !ruby/object:Gem::Requirement
|
66
58
|
requirements:
|
67
59
|
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
61
|
+
version: '0'
|
70
62
|
description: Provides ActiveRecord methods that make it easy to allow users to sort
|
71
63
|
and reorder records in a list
|
72
64
|
email:
|
@@ -85,10 +77,14 @@ files:
|
|
85
77
|
- lib/sortability/version.rb
|
86
78
|
- spec/dummy/README.md
|
87
79
|
- spec/dummy/Rakefile
|
80
|
+
- spec/dummy/app/assets/config/manifest.js
|
88
81
|
- spec/dummy/app/assets/javascripts/application.js
|
89
82
|
- spec/dummy/app/assets/stylesheets/application.css
|
90
83
|
- spec/dummy/app/controllers/application_controller.rb
|
91
84
|
- spec/dummy/app/helpers/application_helper.rb
|
85
|
+
- spec/dummy/app/models/application_record.rb
|
86
|
+
- spec/dummy/app/models/container.rb
|
87
|
+
- spec/dummy/app/models/item.rb
|
92
88
|
- spec/dummy/app/views/layouts/application.html.erb
|
93
89
|
- spec/dummy/bin/bundle
|
94
90
|
- spec/dummy/bin/rails
|
@@ -112,8 +108,10 @@ files:
|
|
112
108
|
- spec/dummy/config/locales/en.yml
|
113
109
|
- spec/dummy/config/routes.rb
|
114
110
|
- spec/dummy/config/secrets.yml
|
111
|
+
- spec/dummy/db/migrate/20190523235417_create_containers.rb
|
112
|
+
- spec/dummy/db/migrate/20190523235430_create_items.rb
|
113
|
+
- spec/dummy/db/schema.rb
|
115
114
|
- spec/dummy/db/test.sqlite3
|
116
|
-
- spec/dummy/log/development.log
|
117
115
|
- spec/dummy/log/test.log
|
118
116
|
- spec/dummy/public/404.html
|
119
117
|
- spec/dummy/public/422.html
|
@@ -128,7 +126,7 @@ homepage: https://github.com/openstax/sortability
|
|
128
126
|
licenses:
|
129
127
|
- MIT
|
130
128
|
metadata: {}
|
131
|
-
post_install_message:
|
129
|
+
post_install_message:
|
132
130
|
rdoc_options: []
|
133
131
|
require_paths:
|
134
132
|
- lib
|
@@ -143,16 +141,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
141
|
- !ruby/object:Gem::Version
|
144
142
|
version: '0'
|
145
143
|
requirements: []
|
146
|
-
|
147
|
-
|
148
|
-
signing_key:
|
144
|
+
rubygems_version: 3.5.17
|
145
|
+
signing_key:
|
149
146
|
specification_version: 4
|
150
147
|
summary: Rails gem that provides easy to use ordered records
|
151
148
|
test_files:
|
149
|
+
- spec/dummy/README.md
|
150
|
+
- spec/dummy/Rakefile
|
151
|
+
- spec/dummy/app/assets/config/manifest.js
|
152
152
|
- spec/dummy/app/assets/javascripts/application.js
|
153
153
|
- spec/dummy/app/assets/stylesheets/application.css
|
154
154
|
- spec/dummy/app/controllers/application_controller.rb
|
155
155
|
- spec/dummy/app/helpers/application_helper.rb
|
156
|
+
- spec/dummy/app/models/application_record.rb
|
157
|
+
- spec/dummy/app/models/container.rb
|
158
|
+
- spec/dummy/app/models/item.rb
|
156
159
|
- spec/dummy/app/views/layouts/application.html.erb
|
157
160
|
- spec/dummy/bin/bundle
|
158
161
|
- spec/dummy/bin/rails
|
@@ -176,15 +179,15 @@ test_files:
|
|
176
179
|
- spec/dummy/config/routes.rb
|
177
180
|
- spec/dummy/config/secrets.yml
|
178
181
|
- spec/dummy/config.ru
|
182
|
+
- spec/dummy/db/migrate/20190523235417_create_containers.rb
|
183
|
+
- spec/dummy/db/migrate/20190523235430_create_items.rb
|
184
|
+
- spec/dummy/db/schema.rb
|
179
185
|
- spec/dummy/db/test.sqlite3
|
180
|
-
- spec/dummy/log/development.log
|
181
186
|
- spec/dummy/log/test.log
|
182
187
|
- spec/dummy/public/404.html
|
183
188
|
- spec/dummy/public/422.html
|
184
189
|
- spec/dummy/public/500.html
|
185
190
|
- spec/dummy/public/favicon.ico
|
186
|
-
- spec/dummy/Rakefile
|
187
|
-
- spec/dummy/README.md
|
188
191
|
- spec/lib/sortability/active_record/base_spec.rb
|
189
192
|
- spec/lib/sortability/active_record/connection_adapters/table_definition_spec.rb
|
190
193
|
- spec/lib/sortability/active_record/migration_spec.rb
|
File without changes
|