Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teach have_db_index about expression indexes #1211

Merged
merged 3 commits into from
May 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ Style/CharacterLiteral:
Style/ClassAndModuleChildren:
Enabled: false
Style/CollectionMethods:
Enabled: true
PreferredMethods:
find: detect
reduce: inject
Expand Down
42 changes: 22 additions & 20 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -111,24 +111,26 @@ appraise 'rails_5_2' do
gem 'pg', '~> 1.1', platform: :ruby
end

appraise 'rails_6_0' do
instance_eval(&shared_dependencies)

gem 'rails', '~> 6.0.0.beta3'
gem 'puma', '~> 3.11'
gem 'bootsnap', '>= 1.4.1', require: false
gem 'sass-rails', '~> 5.0'
gem 'webpacker', '>= 4.0.0.rc3'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bcrypt', '~> 3.1.7'
gem 'capybara', '>= 2.15'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'selenium-webdriver'
gem 'chromedriver-helper'

# Other dependencies
gem 'rails-controller-testing', '>= 1.0.1'
gem 'pg', '~> 1.1', platform: :ruby
if Gem::Requirement.new('>= 2.5.0').satisfied_by?(Gem::Version.new(RUBY_VERSION))
appraise 'rails_6_0' do
instance_eval(&shared_dependencies)

gem 'rails', '~> 6.0.0.beta3'
gem 'puma', '~> 3.11'
gem 'bootsnap', '>= 1.4.1', require: false
gem 'sass-rails', '~> 5.0'
gem 'webpacker', '>= 4.0.0.rc3'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bcrypt', '~> 3.1.7'
gem 'capybara', '>= 2.15'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'selenium-webdriver'
gem 'chromedriver-helper'

# Other dependencies
gem 'rails-controller-testing', '>= 1.0.1'
gem 'pg', '~> 1.1', platform: :ruby
end
end
71 changes: 36 additions & 35 deletions bin/setup
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set -euo pipefail

RUBY_VERSION=$(script/supported_ruby_versions | xargs -n 1 echo | sort -V | tail -n 1)
required_ruby_version=$(cat .ruby-version)

cd "$(dirname "$(dirname "$0")")"

Expand Down Expand Up @@ -30,6 +31,10 @@ error() {
echo -e "\033[31m$@\033[0m"
}

echo-wrapped() {
echo "$@" | fmt -w 80 | cat
}

has-executable() {
type "$1" &>/dev/null
}
Expand All @@ -38,6 +43,14 @@ is-running() {
pgrep "$1" >/dev/null
}

start() {
if has-executable brew; then
brew services start "$1"
else
sudo service "${2:-$1}" start
fi
}

install() {
local apt_package=""
local rpm_package=""
Expand Down Expand Up @@ -90,20 +103,23 @@ check-for-build-tools() {
if [[ $platform == "linux" ]]; then
if ! has-executable apt-get; then
error "You don't seem to have a package manager installed."
echo "The setup script assumes you're using Debian or a Debian-derived flavor of Linux"
echo "(i.e. something with Apt). If this is not the case, then we would gladly take a"
echo "PR fixing this!"
echo-wrapped "\
The setup script assumes you're using Debian or a Debian-derived flavor of
Linux (i.e. something with Apt). If this is not the case, then we would
gladly take a PR fixing this!"
exit 1
fi

# TODO: Check if build-essential is installed on Debian?
else
if ! has-executable brew; then
error "You don't seem to have Homebrew installed."
echo
echo "Follow the instructions here to do this:"
echo
echo "http://brew.sh"
echo-wrapped "\
Follow the instructions here to do this:

http://brew.sh

Then re-run this script."
exit 1
fi

Expand Down Expand Up @@ -145,44 +161,29 @@ install-dependencies() {
rbenv install --skip-existing "$RUBY_VERSION"
fi
elif has-executable rvm; then
if ! (rvm ls | grep $RUBY_VERSION'\>' &>/dev/null); then
banner "Installing Ruby $RUBY_VERSION with rvm"
error "You don't seem to have Ruby $RUBY_VERSION installed."
echo
echo "Use RVM to do so, and then re-run this command."
echo
if ! (rvm list | grep $required_ruby_version'\>' &>/dev/null); then
banner "Installing Ruby $required_ruby_version with rvm"
rvm install $required_ruby_version
rvm use $required_ruby_version
fi
else
error "You don't seem to have a Ruby manager installed."
echo
echo 'We recommend using rbenv. You can find installation instructions here:'
echo
echo 'http://github.com/rbenv/rbenv'
echo
echo "When you're done, simply re-run this script!"
echo-wrapped "\
We recommend using rbenv. You can find instructions to install it here:

https://github.com/rbenv/rbenv#installation

Make sure to follow the instructions to configure your shell so that rbenv is
automatically loaded.

When you're done, open up a new terminal tab and re-run this script."
exit 1
fi

banner 'Installing Ruby dependencies'
gem install bundler -v '~> 1.0' --conservative
bundle check || bundle install
bundle exec appraisal install

if ! has-executable node; then
banner 'Installing Node'

if [[ $platform == 'linux' ]]; then
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -

install nodejs

if ! has-executable npm; then
install npm
fi
else
install nodejs
fi
fi
}

check-for-build-tools
Expand Down
37 changes: 34 additions & 3 deletions lib/shoulda/matchers/active_record/have_db_index_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,30 @@ module ActiveRecord
# should have_db_index([:user_id, :name])
# end
#
# Finally, if you're using Rails 5 and PostgreSQL, you can also specify an
# expression:
#
# class CreateLoggedErrors < ActiveRecord::Migration
# def change
# create_table :logged_errors do |t|
# t.string :code
# t.jsonb :content
# end
#
# add_index :logged_errors, 'lower(code)::text'
# end
# end
#
# # RSpec
# RSpec.describe LoggedError, type: :model do
# it { should have_db_index('lower(code)::text') }
# end
#
# # Minitest (Shoulda)
# class LoggedErrorTest < ActiveSupport::TestCase
# should have_db_index('lower(code)::text')
# end
#
# #### Qualifiers
#
# ##### unique
Expand Down Expand Up @@ -171,9 +195,16 @@ def correct_unique?
end

def matched_index
@_matched_index ||= actual_indexes.find do |index|
index.columns == expected_columns
end
@_matched_index ||=
if expected_columns.one?
actual_indexes.detect do |index|
Array.wrap(index.columns) == expected_columns
end
else
actual_indexes.detect do |index|
index.columns == expected_columns
end
end
end

def actual_indexes
Expand Down
4 changes: 4 additions & 0 deletions spec/support/unit/helpers/active_record_versions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,9 @@ def active_record_uniqueness_supports_array_columns?
def active_record_supports_optional_for_associations?
active_record_version >= 5
end

def active_record_supports_expression_indexes?
active_record_version >= 5
end
end
end
1 change: 1 addition & 0 deletions spec/support/unit/helpers/database_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ def postgresql?
alias_method :database_supports_array_columns?, :postgresql?
alias_method :database_supports_uuid_columns?, :postgresql?
alias_method :database_supports_money_columns?, :postgresql?
alias_method :database_supports_expression_indexes?, :postgresql?
end
end
Loading