order_as_specified 1.5 → 1.6

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: c11fb5ed7165ea2a50cdab0cdb421ac0faa8a187539b0c1f661d6f64fe8107ed
4
- data.tar.gz: 975e533ab7a733c8f3f68c7b6363dab96ac1d90a08f4223ba7bcc067443d21a8
3
+ metadata.gz: 119668cc688124610b87036f0f929c0fbcc35ef4acea5e1c2a1cdc48c1101241
4
+ data.tar.gz: a17df8766bfe178cac883311d8ba4b165b4e43a9c4afd1d8e4b8af0e099d5010
5
5
  SHA512:
6
- metadata.gz: 8b56240f7f9527be2dfb266583ffcccd7aa8992da08139e1824f19c1ea2b82266b5a88bcbbe87db740571d07cd53b4c20bad5d67d4bd4c56d2d3fa0fc132c0cc
7
- data.tar.gz: cc12430e2ef88f18225235de1900a0e1662a908da3f2f411cb64fcf9336a82f6fad886ceb99f840c718d140b832002f47aafaebc807844cdcd5cfe51ba1e8a90
6
+ metadata.gz: 1a53e19dc18fb420fbf88f1fb535b46a0a5c5b13a84158c237a350243f8cfefa5f78ae048087bcc939ea7ecab12e4b7aec5c62bae7960d921a83704f9a53a45e
7
+ data.tar.gz: 0ca1d4697d3634f442edb58173cf4d7f6199571ae1a69415cb6cb2d8b93079ff588023e5549f99ca998979cfeff93ee3ea1f2f0810afd90c8501df829d41e104
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  *.a
14
14
  mkmf.log
15
15
  *.gem
16
+ .rubocop-https---raw-githubusercontent-com-panorama-ed-code-conventions-master-rubocop-yml
@@ -1,17 +1,5 @@
1
- require:
2
- - rubocop/rspec/focused
1
+ inherit_from:
2
+ - https://raw.githubusercontent.com/panorama-ed/code-conventions/master/rubocop.yml
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 2.3
6
-
7
- AbcSize:
8
- Enabled: false
9
-
10
- DotPosition:
11
- EnforcedStyle: trailing
12
-
13
- MethodLength:
14
- Enabled: false
15
-
16
- StringLiterals:
17
- EnforcedStyle: double_quotes
5
+ TargetRubyVersion: 2.4 # Keep this in sync with .travis.yml
@@ -1,28 +1,41 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.5
4
- - 2.5.1
3
+ - 2.6
4
+ - 2.5
5
+ - 2.4 # Keep this in sync with .rubocop.yml
6
+ # We test up to the latest version of Ruby here, and test these Ruby versions
7
+ # against all support ActiveRecord versions. One test will be "duplicated"
8
+ # below when we calculate code coverage, but I don't know how to avoid that and
9
+ # still test all combinations of Ruby and ActiveRecord.
5
10
  before_script:
6
- - psql -c 'create database order_as_specified_test;' -U postgres
7
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
8
- - chmod +x ./cc-test-reporter
9
- - ./cc-test-reporter before-build
11
+ - psql -c 'create database order_as_specified_test;' -U postgres
12
+ - mysql -e 'CREATE DATABASE order_as_specified_test;'
10
13
  script:
11
- - bundle exec rspec
12
- - bundle exec rubocop
13
- after_script:
14
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
- addons:
16
- postgresql: "9.3"
14
+ - bundle exec rspec
15
+ services:
16
+ - mysql
17
+ - postgresql
17
18
  env:
18
- global:
19
- CC_TEST_REPORTER_ID=781c439d68cbb928316deaec1c7136f98423e1db87238f99cbc95183de94df9e
20
19
  matrix:
21
- - AR_VERSION="~> 5.0.0"
22
- - AR_VERSION="~> 5.1.0"
23
- - AR_VERSION="~> 5.2.0"
20
+ - ACTIVERECORD_VERSION="~> 5.2.0"
21
+ - ACTIVERECORD_VERSION="~> 5.1.0"
22
+ - ACTIVERECORD_VERSION="~> 5.0.0"
23
+ matrix:
24
+ include:
25
+ - rvm: 2.6
26
+ script:
27
+ - bundle exec rspec
28
+ - gem install --no-document rubocop rubocop-rspec-focused && rubocop
29
+ env:
30
+ - CODE_COVERAGE=true
31
+ - ACTIVERECORD_VERSION="~> 5.2.0"
32
+ branches:
33
+ only:
34
+ # We always run tests for PRs. This prevents running PR tests twice (once "for
35
+ # the PR" and once "for the branch"), though we do want tests to run always
36
+ # run on master.
37
+ - master
24
38
  notifications:
25
39
  email: false
26
- hipchat:
27
- rooms:
28
- secure: pLL6WXsWnvigZNgcYYwr0el3AG3WbRXOV4zAoBx/pAD/y51/KOjWboUO5szOqIicdSBJTIY5el7wK4uUi5elseumjl1jvOQSG7izvCGzDekuJuOTj9f6MdLtigbIaWO5/NWtXw0/JGHDQJpB4HyOv1mGAjQ3Y6MKxMNv+RUsgRI=
40
+ slack:
41
+ secure: lVaScxPymqeYlTh+KlprWDK+O18BkQTyNSBTfzsLFzWF3Dy+p1rp2aeh0AhuLVYQDrlmFZ7cDMZ1ZYDyV2Y6lLtt+4ii7rATagI8R9WUVYb90C97tu1M6v5tpIjoTEOLx9hGc66heyvq1hNCKXbTqsqmrD69FYdjuXnOfrIs6J4=
@@ -1,3 +1,13 @@
1
+ # Unreleased (`master`)
2
+
3
+ # 1.6
4
+
5
+ We are dropping official support for Ruby 2.3 and below, though they may
6
+ continue to work.
7
+
8
+ This release adds support for ordering by `Range`s. Big thanks to
9
+ [Karl-Aksel Puulmann](https://github.com/macobo) for adding this functionality!
10
+
1
11
  # 1.5
2
12
 
3
13
  This release improves performance by switching to use `CASE` statements. Huge
data/Gemfile CHANGED
@@ -5,4 +5,6 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in order_as_specified.gemspec
6
6
  gemspec
7
7
 
8
- gem "activerecord", ENV["AR_VERSION"] if ENV["AR_VERSION"]
8
+ if ENV["TRAVIS"] == "true" && ENV["ACTIVERECORD_VERSION"]
9
+ gem "activerecord", ENV["ACTIVERECORD_VERSION"]
10
+ end
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- [![Code Climate](https://codeclimate.com/github/panorama-ed/order_as_specified/badges/gpa.svg)](https://codeclimate.com/github/panorama-ed/order_as_specified) [![Test Coverage](https://codeclimate.com/github/panorama-ed/order_as_specified/badges/coverage.svg)](https://codeclimate.com/github/panorama-ed/order_as_specified) [![Build Status](https://travis-ci.org/panorama-ed/order_as_specified.svg)](https://travis-ci.org/panorama-ed/order_as_specified) [![Inline docs](http://inch-ci.org/github/panorama-ed/order_as_specified.png)](http://inch-ci.org/github/panorama-ed/order_as_specified) [![Gem Version](https://badge.fury.io/rb/order_as_specified.svg)](http://badge.fury.io/rb/order_as_specified)
1
+ [![Code Coverage](https://codecov.io/gh/panorama-ed/order_as_specified/branch/master/graph/badge.svg)](https://codecov.io/gh/panorama-ed/order_as_specified)
2
+ [![Build Status](https://travis-ci.com/panorama-ed/order_as_specified.svg)](https://travis-ci.com/panorama-ed/order_as_specified)
3
+ [![Inline docs](http://inch-ci.org/github/panorama-ed/order_as_specified.png)](http://inch-ci.org/github/panorama-ed/order_as_specified)
4
+ [![Gem Version](https://badge.fury.io/rb/order_as_specified.svg)](http://badge.fury.io/rb/order_as_specified)
2
5
 
3
6
  # OrderAsSpecified
4
7
 
@@ -0,0 +1,14 @@
1
+ # Releasing
2
+
3
+ ## These are steps for the maintainer to take to release a new version of this gem.
4
+
5
+ 1. Create a new branch for bumping the version.
6
+ 1. On the new branch, update the VERSION constant in `lib/order_as_specified/version.rb`.
7
+ 1. Update the Changelog.
8
+ 1. Commit the change: `git add -A && git commit -m 'Bump to vX.X'`.
9
+ 1. Add a tag: `git tag -am "vX.X" vX.X`.
10
+ 1. Push the branch and tag: `git push --follow-tags`
11
+ 1. Make a PR.
12
+ 1. Merge the PR.
13
+ 1. Push to rubygems: `gem build order_as_specified.gemspec && gem push *.gem && rm *.gem`
14
+ 1. Celebrate!
@@ -18,15 +18,15 @@ module OrderAsSpecified
18
18
  table = connection.quote_table_name(params[:table])
19
19
  attribute = connection.quote_column_name(params[:attribute])
20
20
 
21
- # We have to explicitly quote for now because SQL sanitization for ORDER BY
22
- # queries isn't in less current versions of Rails.
23
- # See: https://github.com/rails/rails/pull/13008
24
- db_connection = ActiveRecord::Base.connection
25
21
  conditions = params[:values].map do |value|
26
22
  raise OrderAsSpecified::Error, "Cannot order by `nil`" if value.nil?
27
23
 
28
- # Sanitize each value to reduce the risk of SQL injection.
29
- "#{table}.#{attribute}=#{db_connection.quote(value)}"
24
+ if value.is_a? Range
25
+ range_clause("#{table}.#{attribute}", value)
26
+ else
27
+ # Sanitize each value to reduce the risk of SQL injection.
28
+ "#{table}.#{attribute}=#{quote(value)}"
29
+ end
30
30
  end
31
31
 
32
32
  when_queries = conditions.map.with_index do |cond, index|
@@ -53,7 +53,9 @@ module OrderAsSpecified
53
53
  # @param hash [Hash] the ActiveRecord-style arguments, such as:
54
54
  # { other_objects: { id: [1, 5, 3] } }
55
55
  def extract_params(hash, table = table_name)
56
- raise "Could not parse params" unless hash.size == 1
56
+ unless hash.size == 1
57
+ raise OrderAsSpecified::Error, "Could not parse params"
58
+ end
57
59
 
58
60
  key, val = hash.first
59
61
 
@@ -67,4 +69,20 @@ module OrderAsSpecified
67
69
  }
68
70
  end
69
71
  end
72
+
73
+ def range_clause(col, range)
74
+ if range.first >= range.last
75
+ raise OrderAsSpecified::Error, "Range needs to be increasing"
76
+ end
77
+
78
+ op = range.exclude_end? ? "<" : "<="
79
+ "#{col} >= #{quote(range.first)} AND #{col} #{op} #{quote(range.last)}"
80
+ end
81
+
82
+ def quote(value)
83
+ # We have to explicitly quote for now because SQL sanitization for ORDER BY
84
+ # queries isn't in less current versions of Rails.
85
+ # See: https://github.com/rails/rails/pull/13008
86
+ ActiveRecord::Base.connection.quote(value)
87
+ end
70
88
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OrderAsSpecified
4
- VERSION = "1.5"
4
+ VERSION = "1.6"
5
5
  end
@@ -23,11 +23,10 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency "activerecord", ">= 5.0.0"
24
24
 
25
25
  spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "codecov"
27
+ spec.add_development_dependency "mysql2"
26
28
  spec.add_development_dependency "pg"
27
29
  spec.add_development_dependency "rspec"
28
30
  spec.add_development_dependency "rspec-rails"
29
- spec.add_development_dependency "rubocop"
30
- spec.add_development_dependency "rubocop-rspec-focused"
31
- spec.add_development_dependency "simplecov"
32
- spec.add_development_dependency "sqlite3"
31
+ spec.add_development_dependency "sqlite3", "~> 1.3.13"
33
32
  end
@@ -7,3 +7,9 @@ postgresql_test:
7
7
  adapter: postgresql
8
8
  database: order_as_specified_test
9
9
  username: postgres
10
+
11
+ mysql_test:
12
+ adapter: mysql2
13
+ database: order_as_specified_test
14
+ username: travis
15
+ encoding: utf8
@@ -9,6 +9,7 @@ class TestSetupMigration < VersionedMigration
9
9
 
10
10
  create_table :test_classes do |t|
11
11
  t.string :field
12
+ t.float :number_field
12
13
  end
13
14
 
14
15
  create_table :association_test_classes do |t|
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "shared/order_as_specified_examples"
5
+ require "config/test_setup_migration"
6
+
7
+ RSpec.describe "MySQL" do
8
+ before :all do
9
+ ActiveRecord::Base.establish_connection(:mysql_test)
10
+ TestSetupMigration.migrate(:up)
11
+ end
12
+
13
+ after(:all) { ActiveRecord::Base.remove_connection }
14
+
15
+ include_examples ".order_as_specified"
16
+ end
@@ -4,7 +4,6 @@ require "spec_helper"
4
4
  require "shared/order_as_specified_examples"
5
5
  require "config/test_setup_migration"
6
6
 
7
- # rubocop:disable Metrics/BlockLength
8
7
  RSpec.describe "PostgreSQL" do
9
8
  before :all do
10
9
  ActiveRecord::Base.establish_connection(:postgresql_test)
@@ -68,4 +67,3 @@ RSpec.describe "PostgreSQL" do
68
67
  end
69
68
  end
70
69
  end
71
- # rubocop:enable Metrics/BlockLength
@@ -4,7 +4,6 @@ require "support/application_record"
4
4
  require "support/test_class"
5
5
  require "support/association_test_class"
6
6
 
7
- # rubocop:disable Metrics/BlockLength
8
7
  RSpec.shared_examples ".order_as_specified" do
9
8
  # Clean up after each test. This is a lot lighter for these few tests than
10
9
  # trying to wrangle with RSpec-Rails to get transactional tests to work.
@@ -81,6 +80,54 @@ RSpec.shared_examples ".order_as_specified" do
81
80
  end
82
81
  end
83
82
 
83
+ context "when the order is a range" do
84
+ subject do
85
+ TestClass.order_as_specified(number_field: ranges).order(:number_field)
86
+ end
87
+
88
+ let(:ranges) { [(3..4), (0..2)] }
89
+ let(:numbers) { [0, 1, 2, 3, 4] }
90
+
91
+ let!(:test_objects) do
92
+ numbers.each do |i|
93
+ TestClass.create(number_field: i)
94
+ end
95
+ end
96
+
97
+ it "sorts according to range" do
98
+ expect(subject.map(&:number_field)).to eq [
99
+ *numbers.drop(3),
100
+ *numbers.take(3)
101
+ ]
102
+ end
103
+
104
+ context "exclusive ranges" do
105
+ let(:numbers) { [0, 1, 2, 3, 4, 0.9, 1.5] }
106
+
107
+ let(:ranges) { [(1...2), (0...1), (2...5)] }
108
+
109
+ it "sorts according to range" do
110
+ expect(subject.map(&:number_field)).to eq [
111
+ 1,
112
+ 1.5,
113
+ 0,
114
+ 0.9,
115
+ 2,
116
+ 3,
117
+ 4
118
+ ]
119
+ end
120
+ end
121
+
122
+ context "reverse ranges" do
123
+ let(:ranges) { [(5..0)] }
124
+
125
+ it "raises an error" do
126
+ expect { subject }.to raise_error(OrderAsSpecified::Error)
127
+ end
128
+ end
129
+ end
130
+
84
131
  context "with another table name specified" do
85
132
  subject do
86
133
  TestClass.
@@ -149,5 +196,12 @@ RSpec.shared_examples ".order_as_specified" do
149
196
  expect(sql).to include(pattern)
150
197
  end
151
198
  end
199
+
200
+ context "invalid hash input" do
201
+ subject { TestClass.order_as_specified({}) }
202
+
203
+ it "raises an error" do
204
+ expect { subject }.to raise_error(OrderAsSpecified::Error)
205
+ end
206
+ end
152
207
  end
153
- # rubocop:enable Metrics/BlockLength
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if ENV["TRAVIS"] == "true"
3
+ if ENV["TRAVIS"] == "true" && ENV["CODE_COVERAGE"] == "true"
4
4
  require "simplecov"
5
- SimpleCov.start
5
+ require "codecov"
6
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
6
7
  SimpleCov.start do
7
8
  # Omit the spec directory from being counted in code coverage calculations.
8
9
  add_filter "/spec/"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: order_as_specified
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.5'
4
+ version: '1.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Evelyn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-01 00:00:00.000000000 Z
11
+ date: 2019-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: pg
42
+ name: codecov
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec
56
+ name: mysql2
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,21 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec-rails
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
70
+ name: pg
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
@@ -95,7 +81,7 @@ dependencies:
95
81
  - !ruby/object:Gem::Version
96
82
  version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
- name: rubocop-rspec-focused
84
+ name: rspec
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
87
  - - ">="
@@ -109,7 +95,7 @@ dependencies:
109
95
  - !ruby/object:Gem::Version
110
96
  version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
- name: simplecov
98
+ name: rspec-rails
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - ">="
@@ -126,16 +112,16 @@ dependencies:
126
112
  name: sqlite3
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
- - - ">="
115
+ - - "~>"
130
116
  - !ruby/object:Gem::Version
131
- version: '0'
117
+ version: 1.3.13
132
118
  type: :development
133
119
  prerelease: false
134
120
  version_requirements: !ruby/object:Gem::Requirement
135
121
  requirements:
136
- - - ">="
122
+ - - "~>"
137
123
  - !ruby/object:Gem::Version
138
- version: '0'
124
+ version: 1.3.13
139
125
  description: Obtain ActiveRecord results with a custom ordering with no need to store
140
126
  anything in the database.
141
127
  email:
@@ -151,12 +137,14 @@ files:
151
137
  - Gemfile
152
138
  - LICENSE.txt
153
139
  - README.md
140
+ - RELEASING.md
154
141
  - lib/order_as_specified.rb
155
142
  - lib/order_as_specified/error.rb
156
143
  - lib/order_as_specified/version.rb
157
144
  - order_as_specified.gemspec
158
145
  - spec/config/database.yml
159
146
  - spec/config/test_setup_migration.rb
147
+ - spec/mysql_spec.rb
160
148
  - spec/order_as_specified_spec.rb
161
149
  - spec/postgresql_spec.rb
162
150
  - spec/shared/order_as_specified_examples.rb
@@ -192,6 +180,7 @@ summary: Add arbitrary ordering to ActiveRecord queries.
192
180
  test_files:
193
181
  - spec/config/database.yml
194
182
  - spec/config/test_setup_migration.rb
183
+ - spec/mysql_spec.rb
195
184
  - spec/order_as_specified_spec.rb
196
185
  - spec/postgresql_spec.rb
197
186
  - spec/shared/order_as_specified_examples.rb