diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e6088338..79b850124 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,14 +4,13 @@ on: [push, pull_request] jobs: sphinx: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: - os: [ 'ubuntu-18.04' ] ruby: [ '2.7', '3.0', '3.1', '3.2' ] - rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0' ] + rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0', '7_1' ] database: [ 'mysql2', 'postgresql' ] sphinx_version: [ '2.2.11', '3.4.1' ] sphinx_engine: [ 'sphinx' ] @@ -58,7 +57,7 @@ jobs: options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: ./.github/actions/test with: ruby-version: ${{ matrix.ruby }} @@ -69,15 +68,15 @@ jobs: timeout-minutes: 12 manticore: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: ruby: [ '2.7', '3.0', '3.1', '3.2' ] - rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0' ] + rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0', '7_1' ] database: [ 'mysql2', 'postgresql' ] - sphinx_version: [ '3.5.4', '4.0.2' ] + sphinx_version: [ '4.0.2', '6.0.0' ] sphinx_engine: [ 'manticore' ] exclude: - ruby: '3.0' diff --git a/Appraisals b/Appraisals index 1dc1d01f7..59cda54c2 100644 --- a/Appraisals +++ b/Appraisals @@ -45,3 +45,9 @@ appraise 'rails_7_0' do gem 'mysql2', '~> 0.5.0', :platform => :ruby gem 'pg', '~> 1.0', :platform => :ruby end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7 + +appraise 'rails_7_1' do + gem 'rails', '~> 7.1.0' + gem 'mysql2', '~> 0.5.0', :platform => :ruby + gem 'pg', '~> 1.0', :platform => :ruby +end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7 diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 507e55920..5ed4d753a 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -2,6 +2,25 @@ All notable changes to this project (at least, from v3.0.0 onwards) are documented in this file. +## 5.6.0 - 2024-07-07 + +### Added + +* Support for Manticore 6.0 ([#1242](https://github.com/pat/thinking-sphinx/pull/1242)) +* `sphinx`-prefixed search methods, in case the standard `search` is overridden from something unrelated. ([#1265](https://github.com/pat/thinking-sphinx/pull/1265)) +* `none` / `search_none` scopes that can be chained to searches and will return no results. +* Added `ThinkingSphinx::Processor#sync` to synchronise updates/deletions based on a real-time index's scope, by @akostadinov in [@1258](https://github.com/pat/thinking-sphinx/pull/1258). + +### Changed + +* Improved Rails 7.1 support, by @jdelstrother in [#1252](https://github.com/pat/thinking-sphinx/pull/1252). + +### Fixed + +* Handle both SQL and RT indices correctly for inheritance column checks, by @akostadinov in [#1249](https://github.com/pat/thinking-sphinx/pull/1249). +* Ensure tests and CI work with recent Manticore versions, by @jdelstrother in [#1263](https://github.com/pat/thinking-sphinx/pull/1263). +* Use `rm -rf` to delete test and temporary directories (instead of `rm -r`). + ## 5.5.1 - 2022-12-31 [Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.5.1) diff --git a/README.textile b/README.textile index f66545629..b24088cb0 100644 --- a/README.textile +++ b/README.textile @@ -1,6 +1,6 @@ h1. Thinking Sphinx -Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v5.5.1. +Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v5.6.0. h2. Upgrading @@ -31,7 +31,7 @@ The current release of Thinking Sphinx works with the following versions of its |_. Library |_. Minimum |_. Tested Against | | Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2 | | Sphinx | v2.2.11 | v2.2.11, v3.4.1 | -| Manticore | v2.8 | v3.5, v4.0 | +| Manticore | v2.8 | v4.0, v6.0 | | ActiveRecord | v4.2 | v4.2..v7.0 | It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release. @@ -42,7 +42,7 @@ h3. Sphinx or Manticore If you're using Sphinx, v2.2.11 is recommended even though it's quite old, as it works well with PostgreSQL databases (but if you're using MySQL - or real-time indices - then v3.3.1 should also be fine). -If you're opting for Manticore instead, v2.8 or newer works, but v3 or newer is recommended as that's what is actively tested against. +If you're opting for Manticore instead, v2.8 or newer works, but v4 or newer is recommended as that's what is actively tested against. The v4.2 and 5.0 releases had bugs with facet searching, but that's been fixed in Manticore v6.0. h3. Rails and ActiveRecord @@ -81,4 +81,4 @@ You can then run the unit tests with @rake spec:unit@, the acceptance tests with h2. Licence -Copyright (c) 2007-2022, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors. +Copyright (c) 2007-2024, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors. diff --git a/bin/loadsphinx b/bin/loadsphinx index 371beea6b..946e54e2a 100755 --- a/bin/loadsphinx +++ b/bin/loadsphinx @@ -70,15 +70,26 @@ load_manticore () { url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_3.5.4-210107-f70faec5_amd64.deb";; 4.0.2) url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.0.2-210921-af497f245_amd64.deb";; + 4.2.0) + url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.2.0-211223-15e927b28_amd64.deb";; + 6.0.0) + url="skipped";; *) echo "No Manticore version $version available" exit 1;; esac - sudo apt-get install default-libmysqlclient-dev - curl --location $url -o manticore.deb - sudo dpkg -i ./manticore.deb - sudo apt-get install -f + if [ "$version" == "6.0.0" ]; then + curl --location https://repo.manticoresearch.com/manticore-repo.noarch.deb -o repo.deb + sudo dpkg -i repo.deb + sudo apt update + sudo apt install manticore + else + sudo apt-get install default-libmysqlclient-dev + curl --location $url -o manticore.deb + sudo dpkg -i ./manticore.deb + sudo apt-get install -f + fi } if [ "$engine" == "sphinx" ]; then diff --git a/lib/thinking_sphinx.rb b/lib/thinking_sphinx.rb index 60a378313..89de63a2a 100644 --- a/lib/thinking_sphinx.rb +++ b/lib/thinking_sphinx.rb @@ -34,6 +34,10 @@ def self.search_for_ids(query = '', options = {}) ThinkingSphinx::Search::Merger.new(search).merge! nil, :ids_only => true end + def self.none + ThinkingSphinx::Search.new nil, :none => true + end + def self.before_index_hooks @before_index_hooks end diff --git a/lib/thinking_sphinx/active_record/base.rb b/lib/thinking_sphinx/active_record/base.rb index 6d6c882ea..a093e0628 100644 --- a/lib/thinking_sphinx/active_record/base.rb +++ b/lib/thinking_sphinx/active_record/base.rb @@ -4,6 +4,21 @@ module ThinkingSphinx::ActiveRecord::Base extend ActiveSupport::Concern included do + # Avoid method collisions for public Thinking Sphinx methods added to all + # ActiveRecord models. The `sphinx_`-prefixed versions will always exist, + # and the non-prefixed versions will be added if a method of that name + # doesn't already exist. + # + # If a method is overwritten later by something else, that's also fine - the + # prefixed versions will still be there. + class_module = ThinkingSphinx::ActiveRecord::Base::ClassMethods + class_module.public_instance_methods.each do |method_name| + short_method = method_name.to_s.delete_prefix("sphinx_").to_sym + next if methods.include?(short_method) + + define_singleton_method(short_method, method(method_name)) + end + if ActiveRecord::VERSION::STRING.to_i >= 5 [ ::ActiveRecord::Reflection::HasManyReflection, @@ -25,24 +40,28 @@ def extensions end module ClassMethods - def facets(query = nil, options = {}) + def sphinx_facets(query = nil, options = {}) merge_search ThinkingSphinx.facets, query, options end - def search(query = nil, options = {}) + def sphinx_search(query = nil, options = {}) merge_search ThinkingSphinx.search, query, options end - def search_count(query = nil, options = {}) + def sphinx_search_count(query = nil, options = {}) search_for_ids(query, options).total_entries end - def search_for_ids(query = nil, options = {}) + def sphinx_search_for_ids(query = nil, options = {}) ThinkingSphinx::Search::Merger.new( search(query, options) ).merge! nil, :ids_only => true end + def sphinx_search_none + merge_search ThinkingSphinx.search, nil, none: true + end + private def default_sphinx_scope? diff --git a/lib/thinking_sphinx/active_record/filter_reflection.rb b/lib/thinking_sphinx/active_record/filter_reflection.rb index d72f42218..816520b0e 100644 --- a/lib/thinking_sphinx/active_record/filter_reflection.rb +++ b/lib/thinking_sphinx/active_record/filter_reflection.rb @@ -2,7 +2,7 @@ class ThinkingSphinx::ActiveRecord::FilterReflection ReflectionGenerator = case ActiveRecord::VERSION::STRING.to_f - when 5.2..7.0 + when 5.2..7.1 ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection when 4.1..5.1 ThinkingSphinx::ActiveRecord::Depolymorph::AssociationReflection diff --git a/lib/thinking_sphinx/active_record/log_subscriber.rb b/lib/thinking_sphinx/active_record/log_subscriber.rb index c610ec982..7187b6ce3 100644 --- a/lib/thinking_sphinx/active_record/log_subscriber.rb +++ b/lib/thinking_sphinx/active_record/log_subscriber.rb @@ -2,24 +2,36 @@ class ThinkingSphinx::ActiveRecord::LogSubscriber < ActiveSupport::LogSubscriber def guard(event) - identifier = color 'Sphinx', GREEN, true + identifier = colored_text "Sphinx" warn " #{identifier} #{event.payload[:guard]}" end def message(event) - identifier = color 'Sphinx', GREEN, true + identifier = colored_text "Sphinx" debug " #{identifier} #{event.payload[:message]}" end def query(event) - identifier = color('Sphinx Query (%.1fms)' % event.duration, GREEN, true) + identifier = colored_text("Sphinx Query (%.1fms)" % event.duration) debug " #{identifier} #{event.payload[:query]}" end def caution(event) - identifier = color 'Sphinx', GREEN, true + identifier = colored_text "Sphinx" warn " #{identifier} #{event.payload[:caution]}" end + + private + + if Rails.gem_version >= Gem::Version.new("7.1.0") + def colored_text(text) + color text, GREEN, bold: true + end + else + def colored_text(text) + color text, GREEN, true + end + end end ThinkingSphinx::ActiveRecord::LogSubscriber.attach_to :thinking_sphinx diff --git a/lib/thinking_sphinx/commands/clear_real_time.rb b/lib/thinking_sphinx/commands/clear_real_time.rb index c9a71b474..9312e6caf 100644 --- a/lib/thinking_sphinx/commands/clear_real_time.rb +++ b/lib/thinking_sphinx/commands/clear_real_time.rb @@ -7,7 +7,7 @@ def call Dir["#{index.path}.*"].each { |path| FileUtils.rm path } end - FileUtils.rm_r(binlog_path) if File.exist?(binlog_path) + FileUtils.rm_rf(binlog_path) if File.exist?(binlog_path) end private diff --git a/lib/thinking_sphinx/commands/clear_sql.rb b/lib/thinking_sphinx/commands/clear_sql.rb index 39b1552ac..512c97d04 100644 --- a/lib/thinking_sphinx/commands/clear_sql.rb +++ b/lib/thinking_sphinx/commands/clear_sql.rb @@ -7,7 +7,7 @@ def call Dir["#{index.path}.*"].each { |path| FileUtils.rm path } end - FileUtils.rm_r Dir["#{configuration.indices_location}/ts-*.tmp"] + FileUtils.rm_rf Dir["#{configuration.indices_location}/ts-*.tmp"] end private diff --git a/lib/thinking_sphinx/configuration/minimum_fields.rb b/lib/thinking_sphinx/configuration/minimum_fields.rb index 31383a2dd..b96824caf 100644 --- a/lib/thinking_sphinx/configuration/minimum_fields.rb +++ b/lib/thinking_sphinx/configuration/minimum_fields.rb @@ -18,19 +18,19 @@ def reconcile attr_reader :indices def field_collections - plain_indices_without_inheritance.collect(&:sources).flatten + - indices_of_type('rt') - end - - def indices_of_type(type) - indices.select { |index| index.type == type } + indices_without_inheritance_of_type('plain').collect(&:sources).flatten + + indices_without_inheritance_of_type('rt') end def inheritance_columns?(index) index.model.table_exists? && index.model.column_names.include?(index.model.inheritance_column) end - def plain_indices_without_inheritance - indices_of_type('plain').reject(&method(:inheritance_columns?)) + def indices_without_inheritance_of_type(type) + indices_without_inheritance.select { |index| index.type == type } + end + + def indices_without_inheritance + indices.reject(&method(:inheritance_columns?)) end end diff --git a/lib/thinking_sphinx/masks/scopes_mask.rb b/lib/thinking_sphinx/masks/scopes_mask.rb index 92aa20b4e..2dd773d8b 100644 --- a/lib/thinking_sphinx/masks/scopes_mask.rb +++ b/lib/thinking_sphinx/masks/scopes_mask.rb @@ -26,6 +26,12 @@ def search_for_ids(query = nil, options = {}) search query, options.merge(:ids_only => true) end + def none + ThinkingSphinx::Search::Merger.new(@search).merge! nil, :none => true + end + + alias_method :search_none, :none + private def apply_scope(scope, *args) diff --git a/lib/thinking_sphinx/processor.rb b/lib/thinking_sphinx/processor.rb index b2ad823d8..db440ccf9 100644 --- a/lib/thinking_sphinx/processor.rb +++ b/lib/thinking_sphinx/processor.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class ThinkingSphinx::Processor + # @param instance [ActiveRecord::Base] an ActiveRecord object + # @param model [Class] the ActiveRecord model of the instance + # @param id [Integer] the instance indices primary key (might be different from model primary key) def initialize(instance: nil, model: nil, id: nil) raise ArgumentError if instance.nil? && (model.nil? || id.nil?) @@ -12,16 +15,27 @@ def initialize(instance: nil, model: nil, id: nil) def delete return if instance&.new_record? - indices.each { |index| - ThinkingSphinx::Deletion.perform( - index, id || instance.public_send(index.primary_key) - ) - } + indices.each { |index| perform_deletion(index) } end + # Will insert instance into all matching indices def upsert real_time_indices.each do |index| - ThinkingSphinx::RealTime::Transcriber.new(index).copy loaded_instance + found = loaded_instance(index) + ThinkingSphinx::RealTime::Transcriber.new(index).copy found if found + end + end + + # Will upsert or delete instance into all matching indices based on index scope + def sync + real_time_indices.each do |index| + found = find_in(index) + + if found + ThinkingSphinx::RealTime::Transcriber.new(index).copy found + else + ThinkingSphinx::Deletion.perform(index, index_id(index)) + end end end @@ -35,11 +49,23 @@ def indices ).to_a end - def loaded_instance - @loaded_instance ||= instance || model.find(id) + def find_in(index) + index.scope.find_by(index.primary_key => index_id(index)) + end + + def loaded_instance(index) + instance || find_in(index) end def real_time_indices indices.select { |index| index.is_a? ThinkingSphinx::RealTime::Index } end + + def perform_deletion(index) + ThinkingSphinx::Deletion.perform(index, index_id(index)) + end + + def index_id(index) + id || instance.public_send(index.primary_key) + end end diff --git a/lib/thinking_sphinx/search.rb b/lib/thinking_sphinx/search.rb index 617e721f2..97b1799c9 100644 --- a/lib/thinking_sphinx/search.rb +++ b/lib/thinking_sphinx/search.rb @@ -12,7 +12,7 @@ class ThinkingSphinx::Search < Array [ :classes, :conditions, :excerpts, :geo, :group_by, :ids_only, :ignore_scopes, :indices, :limit, :masks, :max_matches, :middleware, - :offset, :order, :order_group_by, :page, :per_page, :populate, + :none, :offset, :order, :order_group_by, :page, :per_page, :populate, :retry_stale, :select, :skip_sti, :sql, :star, :with, :with_all, :without, :without_ids ] + @@ -92,7 +92,7 @@ def per_page(value = nil) def populate return self if @populated - middleware.call [context] + middleware.call [context] unless options[:none] @populated = true self diff --git a/lib/thinking_sphinx/search/context.rb b/lib/thinking_sphinx/search/context.rb index 8d3e692dd..b1f051b3a 100644 --- a/lib/thinking_sphinx/search/context.rb +++ b/lib/thinking_sphinx/search/context.rb @@ -7,6 +7,7 @@ def initialize(search, configuration = nil) @search = search @configuration = configuration || ThinkingSphinx::Configuration.instance @memory = { + :raw => [], :results => [], :panes => ThinkingSphinx::Configuration::Defaults::PANES.clone } diff --git a/lib/thinking_sphinx/test.rb b/lib/thinking_sphinx/test.rb index d1442fda1..8e4abdcc4 100644 --- a/lib/thinking_sphinx/test.rb +++ b/lib/thinking_sphinx/test.rb @@ -42,7 +42,7 @@ def self.clear config.indices_location, config.searchd.binlog_path ].each do |path| - FileUtils.rm_r(path) if File.exist?(path) + FileUtils.rm_rf(path) if File.exist?(path) end end diff --git a/spec/acceptance/attribute_access_spec.rb b/spec/acceptance/attribute_access_spec.rb index c79633a1b..10d4ef775 100644 --- a/spec/acceptance/attribute_access_spec.rb +++ b/spec/acceptance/attribute_access_spec.rb @@ -4,17 +4,17 @@ describe 'Accessing attributes directly via search results', :live => true do it "allows access to attribute values" do - Book.create! :title => 'American Gods', :year => 2001 + Book.create! :title => 'American Gods', :publishing_year => 2001 index search = Book.search('gods') search.context[:panes] << ThinkingSphinx::Panes::AttributesPane - expect(search.first.sphinx_attributes['year']).to eq(2001) + expect(search.first.sphinx_attributes['publishing_year']).to eq(2001) end it "provides direct access to the search weight/relevance scores" do - Book.create! :title => 'American Gods', :year => 2001 + Book.create! :title => 'American Gods', :publishing_year => 2001 index search = Book.search 'gods', :select => "*, weight()" @@ -37,7 +37,7 @@ end it "can enumerate with the weight" do - gods = Book.create! :title => 'American Gods', :year => 2001 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 index search = Book.search 'gods', :select => "*, weight()" diff --git a/spec/acceptance/excerpts_spec.rb b/spec/acceptance/excerpts_spec.rb index 127c5b66f..10aa5b982 100644 --- a/spec/acceptance/excerpts_spec.rb +++ b/spec/acceptance/excerpts_spec.rb @@ -5,7 +5,7 @@ describe 'Accessing excerpts for methods on a search result', :live => true do it "returns excerpts for a given method" do - Book.create! :title => 'American Gods', :year => 2001 + Book.create! :title => 'American Gods', :publishing_year => 2001 index search = Book.search('gods') @@ -16,7 +16,7 @@ end it "handles UTF-8 text for excerpts" do - Book.create! :title => 'Война и миръ', :year => 1869 + Book.create! :title => 'Война и миръ', :publishing_year => 1869 index search = Book.search 'миръ' diff --git a/spec/acceptance/grouping_by_attributes_spec.rb b/spec/acceptance/grouping_by_attributes_spec.rb index 09e295faf..8481f9dca 100644 --- a/spec/acceptance/grouping_by_attributes_spec.rb +++ b/spec/acceptance/grouping_by_attributes_spec.rb @@ -4,36 +4,36 @@ describe 'Grouping search results by attributes', :live => true do it "groups by the provided attribute" do - snuff = Book.create! :title => 'Snuff', :year => 2011 - earth = Book.create! :title => 'The Long Earth', :year => 2012 - dodger = Book.create! :title => 'Dodger', :year => 2012 + snuff = Book.create! :title => 'Snuff', :publishing_year => 2011 + earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012 + dodger = Book.create! :title => 'Dodger', :publishing_year => 2012 index - expect(Book.search(:group_by => :year).to_a).to eq([snuff, earth]) + expect(Book.search(:group_by => :publishing_year).to_a).to eq([snuff, earth]) end it "allows sorting within the group" do - snuff = Book.create! :title => 'Snuff', :year => 2011 - earth = Book.create! :title => 'The Long Earth', :year => 2012 - dodger = Book.create! :title => 'Dodger', :year => 2012 + snuff = Book.create! :title => 'Snuff', :publishing_year => 2011 + earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012 + dodger = Book.create! :title => 'Dodger', :publishing_year => 2012 index - expect(Book.search(:group_by => :year, :order_group_by => 'title ASC').to_a). + expect(Book.search(:group_by => :publishing_year, :order_group_by => 'title ASC').to_a). to eq([snuff, dodger]) end it "allows enumerating by count" do - snuff = Book.create! :title => 'Snuff', :year => 2011 - earth = Book.create! :title => 'The Long Earth', :year => 2012 - dodger = Book.create! :title => 'Dodger', :year => 2012 + snuff = Book.create! :title => 'Snuff', :publishing_year => 2011 + earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012 + dodger = Book.create! :title => 'Dodger', :publishing_year => 2012 index expectations = [[snuff, 1], [earth, 2]] - Book.search(:group_by => :year).each_with_count do |book, count| + Book.search(:group_by => :publishing_year).each_with_count do |book, count| expectation = expectations.shift expect(book).to eq(expectation.first) @@ -42,15 +42,15 @@ end it "allows enumerating by group" do - snuff = Book.create! :title => 'Snuff', :year => 2011 - earth = Book.create! :title => 'The Long Earth', :year => 2012 - dodger = Book.create! :title => 'Dodger', :year => 2012 + snuff = Book.create! :title => 'Snuff', :publishing_year => 2011 + earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012 + dodger = Book.create! :title => 'Dodger', :publishing_year => 2012 index expectations = [[snuff, 2011], [earth, 2012]] - Book.search(:group_by => :year).each_with_group do |book, group| + Book.search(:group_by => :publishing_year).each_with_group do |book, group| expectation = expectations.shift expect(book).to eq(expectation.first) @@ -59,14 +59,14 @@ end it "allows enumerating by group and count" do - snuff = Book.create! :title => 'Snuff', :year => 2011 - earth = Book.create! :title => 'The Long Earth', :year => 2012 - dodger = Book.create! :title => 'Dodger', :year => 2012 + snuff = Book.create! :title => 'Snuff', :publishing_year => 2011 + earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012 + dodger = Book.create! :title => 'Dodger', :publishing_year => 2012 index expectations = [[snuff, 2011, 1], [earth, 2012, 2]] - search = Book.search(:group_by => :year) + search = Book.search(:group_by => :publishing_year) search.each_with_group_and_count do |book, group, count| expectation = expectations.shift diff --git a/spec/acceptance/real_time_updates_spec.rb b/spec/acceptance/real_time_updates_spec.rb index 7a51c91ca..8eca41b6c 100644 --- a/spec/acceptance/real_time_updates_spec.rb +++ b/spec/acceptance/real_time_updates_spec.rb @@ -28,7 +28,7 @@ expect(Admin::Person.search('Mort').to_a).to eq([person]) end - it "can use a direct interface for processing records" do + it "can use direct interface for upserting records" do Admin::Person.connection.execute <<~SQL INSERT INTO admin_people (name, created_at, updated_at) VALUES ('Pat', now(), now()); @@ -52,4 +52,64 @@ expect(Admin::Person.search('Patrick').to_a).to eq([instance]) end + + it "can use direct interface for processing records outside scope" do + Article.connection.execute <<~SQL + INSERT INTO articles (title, published, created_at, updated_at) + VALUES ('Nice Title', TRUE, now(), now()); + SQL + + article = Article.last + + ThinkingSphinx::Processor.new(model: article.class, id: article.id).sync + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article) + + Article.connection.execute <<~SQL + UPDATE articles SET published = FALSE WHERE title = 'Nice Title'; + SQL + ThinkingSphinx::Processor.new(model: article.class, id: article.id).sync + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty + end + + it "can use direct interface for processing deleted records" do + Article.connection.execute <<~SQL + INSERT INTO articles (title, published, created_at, updated_at) + VALUES ('Nice Title', TRUE, now(), now()); + SQL + + article = Article.last + ThinkingSphinx::Processor.new(:instance => article).sync + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article) + + Article.connection.execute <<~SQL + DELETE FROM articles where title = 'Nice Title'; + SQL + + ThinkingSphinx::Processor.new(:instance => article).sync + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty + end + + it "syncs records in real-time index with alternate ids" do + Album.connection.execute <<~SQL + INSERT INTO albums (id, name, artist, integer_id) + VALUES ('#{("a".."z").to_a.sample}', 'Sing to the Moon', 'Laura Mvula', #{rand(10000)}); + SQL + + album = Album.last + ThinkingSphinx::Processor.new(:model => Album, id: album.integer_id).sync + + expect(ThinkingSphinx.search('Laura', :indices => ["album_real_core"])).to include(album) + + Article.connection.execute <<~SQL + DELETE FROM albums where id = '#{album.id}'; + SQL + + ThinkingSphinx::Processor.new(:instance => album).sync + + expect(ThinkingSphinx.search('Laura', :indices => ["album_real_core"])).to be_empty + end end diff --git a/spec/acceptance/searching_across_models_spec.rb b/spec/acceptance/searching_across_models_spec.rb index ab0d9ce5a..e471fcd71 100644 --- a/spec/acceptance/searching_across_models_spec.rb +++ b/spec/acceptance/searching_across_models_spec.rb @@ -37,4 +37,11 @@ expect(ThinkingSphinx.search(:classes => [User, Article]).to_a). to match_array([article, user]) end + + it "has a 'none' default scope" do + article = Article.create! :title => 'Pancakes' + index + + expect(ThinkingSphinx.none).to be_empty + end end diff --git a/spec/acceptance/searching_with_filters_spec.rb b/spec/acceptance/searching_with_filters_spec.rb index 691cf7d29..199cce20f 100644 --- a/spec/acceptance/searching_with_filters_spec.rb +++ b/spec/acceptance/searching_with_filters_spec.rb @@ -12,12 +12,12 @@ end it "limits results by an array of values" do - gods = Book.create! :title => 'American Gods', :year => 2001 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 index - expect(Book.search(:with => {:year => [2001, 2005]}).to_a).to match_array([gods, boys]) + expect(Book.search(:with => {:publishing_year => [2001, 2005]}).to_a).to match_array([gods, boys]) end it "limits results by a ranged filter" do @@ -43,12 +43,12 @@ end it "limits results by exclusive filters on arrays of values" do - gods = Book.create! :title => 'American Gods', :year => 2001 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 index - expect(Book.search(:without => {:year => [2001, 2005]}).to_a).to eq([grave]) + expect(Book.search(:without => {:publishing_year => [2001, 2005]}).to_a).to eq([grave]) end it "limits results by ranged filters on timestamp MVAs" do diff --git a/spec/acceptance/searching_within_a_model_spec.rb b/spec/acceptance/searching_within_a_model_spec.rb index d95167067..45cb79b74 100644 --- a/spec/acceptance/searching_within_a_model_spec.rb +++ b/spec/acceptance/searching_within_a_model_spec.rb @@ -92,6 +92,20 @@ expect(Album.search(:indices => ['album_real_core']).first). to eq(album) end + + it "is available via a sphinx-prefixed method" do + article = Article.create! :title => 'Pancakes' + index + + expect(Article.sphinx_search.first).to eq(article) + end + + it "has a 'none' default scope" do + article = Article.create! :title => 'Pancakes' + index + + expect(Article.search_none).to be_empty + end end describe 'Searching within a model with a realtime index', :live => true do diff --git a/spec/acceptance/sorting_search_results_spec.rb b/spec/acceptance/sorting_search_results_spec.rb index c70ae1487..20f2799ac 100644 --- a/spec/acceptance/sorting_search_results_spec.rb +++ b/spec/acceptance/sorting_search_results_spec.rb @@ -4,27 +4,27 @@ describe 'Sorting search results', :live => true do it "sorts by a given clause" do - gods = Book.create! :title => 'American Gods', :year => 2001 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 index - expect(Book.search(:order => 'year ASC').to_a).to eq([gods, boys, grave]) + expect(Book.search(:order => 'publishing_year ASC').to_a).to eq([gods, boys, grave]) end it "sorts by a given attribute in ascending order" do - gods = Book.create! :title => 'American Gods', :year => 2001 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 index - expect(Book.search(:order => :year).to_a).to eq([gods, boys, grave]) + expect(Book.search(:order => :publishing_year).to_a).to eq([gods, boys, grave]) end it "sorts by a given sortable field" do - gods = Book.create! :title => 'American Gods', :year => 2001 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 index expect(Book.search(:order => :title).to_a).to eq([gods, boys, grave]) @@ -38,13 +38,13 @@ end it "can sort with a provided expression" do - gods = Book.create! :title => 'American Gods', :year => 2001 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 index expect(Book.search( - :select => '*, year MOD 2004 as mod_year', :order => 'mod_year ASC' + :select => '*, publishing_year MOD 2004 as mod_year', :order => 'mod_year ASC' ).to_a).to eq([boys, grave, gods]) end end diff --git a/spec/acceptance/sphinx_scopes_spec.rb b/spec/acceptance/sphinx_scopes_spec.rb index 4d945ce73..c47d11ee0 100644 --- a/spec/acceptance/sphinx_scopes_spec.rb +++ b/spec/acceptance/sphinx_scopes_spec.rb @@ -4,39 +4,39 @@ describe 'Sphinx scopes', :live => true do it "allows calling sphinx scopes from models" do - gods = Book.create! :title => 'American Gods', :year => 2001 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 index - expect(Book.by_year(2009).to_a).to eq([grave]) + expect(Book.by_publishing_year(2009).to_a).to eq([grave]) end it "allows scopes to return both query and options" do - gods = Book.create! :title => 'American Gods', :year => 2001 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 index - expect(Book.by_query_and_year('Graveyard', 2009).to_a).to eq([grave]) + expect(Book.by_query_and_publishing_year('Graveyard', 2009).to_a).to eq([grave]) end it "allows chaining of scopes" do - gods = Book.create! :title => 'American Gods', :year => 2001 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 index - expect(Book.by_year(2001..2005).ordered.to_a).to eq([boys, gods]) + expect(Book.by_publishing_year(2001..2005).ordered.to_a).to eq([boys, gods]) end it "allows chaining of scopes that include queries" do - gods = Book.create! :title => 'American Gods', :year => 2001 - boys = Book.create! :title => 'Anansi Boys', :year => 2005 - grave = Book.create! :title => 'The Graveyard Book', :year => 2009 + gods = Book.create! :title => 'American Gods', :publishing_year => 2001 + boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005 + grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009 index - expect(Book.by_year(2001).by_query_and_year('Graveyard', 2009).to_a). + expect(Book.by_publishing_year(2001).by_query_and_publishing_year('Graveyard', 2009).to_a). to eq([grave]) end @@ -77,4 +77,11 @@ ThinkingSphinx::PopulatedResultsError ) end + + it "handles a chainable 'none' scope and returns nothing" do + Book.create! :title => 'Small Gods' + index + + expect(Book.by_query('gods').none).to be_empty + end end diff --git a/spec/internal/app/indices/article_index.rb b/spec/internal/app/indices/article_index.rb index c8f611f1b..a0c456218 100644 --- a/spec/internal/app/indices/article_index.rb +++ b/spec/internal/app/indices/article_index.rb @@ -23,3 +23,9 @@ set_property :morphology => 'stem_en' end + +ThinkingSphinx::Index.define :article, :name => :published_articles, :with => :real_time do + indexes title, content + + scope { Article.where :published => true } +end diff --git a/spec/internal/app/indices/book_index.rb b/spec/internal/app/indices/book_index.rb index a55b633ea..d1c2dc5de 100644 --- a/spec/internal/app/indices/book_index.rb +++ b/spec/internal/app/indices/book_index.rb @@ -6,6 +6,6 @@ indexes [title, author], :as => :info indexes blurb_file, :file => true - has year + has publishing_year has created_at, :type => :timestamp end diff --git a/spec/internal/app/models/book.rb b/spec/internal/app/models/book.rb index da8c590b8..a2cd0639e 100644 --- a/spec/internal/app/models/book.rb +++ b/spec/internal/app/models/book.rb @@ -8,11 +8,11 @@ class Book < ActiveRecord::Base ThinkingSphinx::Callbacks.append(self, :behaviours => [:sql, :deltas]) sphinx_scope(:by_query) { |query| query } - sphinx_scope(:by_year) do |year| - {:with => {:year => year}} + sphinx_scope(:by_publishing_year) do |year| + {:with => {:publishing_year => year}} end - sphinx_scope(:by_query_and_year) do |query, year| - [query, {:with => {:year =>year}}] + sphinx_scope(:by_query_and_publishing_year) do |query, year| + [query, {:with => {:publishing_year =>year}}] end - sphinx_scope(:ordered) { {:order => 'year DESC'} } + sphinx_scope(:ordered) { {:order => 'publishing_year DESC'} } end diff --git a/spec/internal/db/schema.rb b/spec/internal/db/schema.rb index bc0ee8df9..3aede6ba5 100644 --- a/spec/internal/db/schema.rb +++ b/spec/internal/db/schema.rb @@ -39,7 +39,7 @@ create_table(:books, :force => true) do |t| t.string :title t.string :author - t.integer :year + t.integer :publishing_year t.string :blurb_file t.boolean :delta, :default => true, :null => false t.string :type, :default => 'Book', :null => false diff --git a/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb b/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb index d13a40e50..9186683b1 100644 --- a/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +++ b/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb @@ -60,7 +60,7 @@ module Callbacks; end it "builds an update query with only updateable attributes that have changed" do expect(Riddle::Query).to receive(:update). - with('article_core', 3, 'bar' => 7).and_return('SphinxQL') + with('article_core', 3, { 'bar' => 7 }).and_return('SphinxQL') callbacks.after_update end diff --git a/spec/thinking_sphinx/active_record/interpreter_spec.rb b/spec/thinking_sphinx/active_record/interpreter_spec.rb index d408324df..68d61f19e 100644 --- a/spec/thinking_sphinx/active_record/interpreter_spec.rb +++ b/spec/thinking_sphinx/active_record/interpreter_spec.rb @@ -93,7 +93,7 @@ it "passes through options to the attribute" do expect(ThinkingSphinx::ActiveRecord::Attribute).to receive(:new). - with(model, column, :as => :other_name).and_return(attribute) + with(model, column, { :as => :other_name }).and_return(attribute) instance.has column, :as => :other_name end @@ -141,7 +141,7 @@ it "passes through options to the field" do expect(ThinkingSphinx::ActiveRecord::Field).to receive(:new). - with(model, column, :as => :other_name).and_return(field) + with(model, column, { :as => :other_name }).and_return(field) instance.indexes column, :as => :other_name end @@ -230,19 +230,19 @@ end it "sends through a hash if provided" do - expect(source).to receive(:set_database_settings).with(:foo => :bar) + expect(source).to receive(:set_database_settings).with({ :foo => :bar }) instance.set_database :foo => :bar end it "finds the environment settings if given a string key" do - expect(source).to receive(:set_database_settings).with(:baz => 'qux') + expect(source).to receive(:set_database_settings).with({ :baz => 'qux' }) instance.set_database 'other' end it "finds the environment settings if given a symbol key" do - expect(source).to receive(:set_database_settings).with(:baz => 'qux') + expect(source).to receive(:set_database_settings).with({ :baz => 'qux' }) instance.set_database :other end diff --git a/spec/thinking_sphinx/commands/clear_real_time_spec.rb b/spec/thinking_sphinx/commands/clear_real_time_spec.rb index 7c09a4360..df20c5840 100644 --- a/spec/thinking_sphinx/commands/clear_real_time_spec.rb +++ b/spec/thinking_sphinx/commands/clear_real_time_spec.rb @@ -17,7 +17,7 @@ allow(Dir).to receive(:[]).with('/path/to/my/index/parts.*'). and_return(['parts.a', 'parts.b']) - allow(FileUtils).to receive_messages :rm_r => true, + allow(FileUtils).to receive_messages :rm_rf => true, :rm => true allow(File).to receive_messages :exist? => true end @@ -30,7 +30,7 @@ end it "removes the directory for the binlog files" do - expect(FileUtils).to receive(:rm_r).with('/path/to/binlog') + expect(FileUtils).to receive(:rm_rf).with('/path/to/binlog') command.call end diff --git a/spec/thinking_sphinx/commands/clear_sql_spec.rb b/spec/thinking_sphinx/commands/clear_sql_spec.rb index 38fab2b3c..a5e0a83d8 100644 --- a/spec/thinking_sphinx/commands/clear_sql_spec.rb +++ b/spec/thinking_sphinx/commands/clear_sql_spec.rb @@ -24,7 +24,7 @@ allow(Dir).to receive(:[]).with('/path/to/indices/ts-*.tmp'). and_return(['/path/to/indices/ts-foo.tmp']) - allow(FileUtils).to receive_messages :rm_r => true, :rm => true + allow(FileUtils).to receive_messages :rm_rf => true, :rm => true allow(File).to receive_messages :exist? => true end @@ -45,7 +45,7 @@ end it "removes any indexing guard files" do - expect(FileUtils).to receive(:rm_r).with(["/path/to/indices/ts-foo.tmp"]) + expect(FileUtils).to receive(:rm_rf).with(["/path/to/indices/ts-foo.tmp"]) command.call end diff --git a/spec/thinking_sphinx/configuration/minimum_fields_spec.rb b/spec/thinking_sphinx/configuration/minimum_fields_spec.rb index a748a920d..9c85db788 100644 --- a/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +++ b/spec/thinking_sphinx/configuration/minimum_fields_spec.rb @@ -6,7 +6,7 @@ let(:indices) { [index_a, index_b] } let(:index_a) { double 'Index A', :model => model_a, :type => 'plain', :sources => [double(:fields => [field_a1, field_a2])] } - let(:index_b) { double 'Index B', :model => model_a, :type => 'rt', + let(:index_b) { double 'Index B', :model => model_b, :type => 'rt', :fields => [field_b1, field_b2] } let(:field_a1) { double :name => 'sphinx_internal_class_name' } let(:field_a2) { double :name => 'name' } @@ -38,7 +38,7 @@ expect(index_b.fields).to eq([field_b2]) end - it 'removes the class name fields only for the indices without type column' do + it 'removes the class name fields only for the rt indices without type column' do allow(model_a).to receive(:column_names).and_return(['id', 'name', 'type']) allow(model_b).to receive(:column_names).and_return(['id', 'name']) @@ -47,4 +47,14 @@ expect(index_a.sources.first.fields).to eq([field_a1, field_a2]) expect(index_b.fields).to eq([field_b2]) end + + it 'removes the class name fields only for the plain indices without type column' do + allow(model_a).to receive(:column_names).and_return(['id', 'name']) + allow(model_b).to receive(:column_names).and_return(['id', 'name', 'type']) + + subject.reconcile + + expect(index_a.sources.first.fields).to eq([field_a2]) + expect(index_b.fields).to eq([field_b1, field_b2]) + end end diff --git a/spec/thinking_sphinx/excerpter_spec.rb b/spec/thinking_sphinx/excerpter_spec.rb index f27a626b9..abb6e0ae7 100644 --- a/spec/thinking_sphinx/excerpter_spec.rb +++ b/spec/thinking_sphinx/excerpter_spec.rb @@ -28,9 +28,10 @@ :before_match => '', :chunk_separator => ' -- ') expect(Riddle::Query).to receive(:snippets). - with('all of the words', 'index', 'all words', + with('all of the words', 'index', 'all words', { :before_match => '', :after_match => '', - :chunk_separator => ' -- '). + :chunk_separator => ' -- ' + }). and_return('CALL SNIPPETS') excerpter.excerpt!('all of the words') diff --git a/spec/thinking_sphinx/index_spec.rb b/spec/thinking_sphinx/index_spec.rb index 0fd41eb67..7d16e2767 100644 --- a/spec/thinking_sphinx/index_spec.rb +++ b/spec/thinking_sphinx/index_spec.rb @@ -19,7 +19,7 @@ it "creates an ActiveRecord index" do expect(ThinkingSphinx::ActiveRecord::Index).to receive(:new). - with(:user, :with => :active_record).and_return index + with(:user, { :with => :active_record }).and_return index ThinkingSphinx::Index.define(:user, :with => :active_record) end @@ -100,7 +100,7 @@ it "creates a real-time index" do expect(ThinkingSphinx::RealTime::Index).to receive(:new). - with(:user, :with => :real_time).and_return index + with(:user, { :with => :real_time }).and_return index ThinkingSphinx::Index.define(:user, :with => :real_time) end diff --git a/spec/thinking_sphinx/middlewares/sphinxql_spec.rb b/spec/thinking_sphinx/middlewares/sphinxql_spec.rb index ff966d51c..96f1d7605 100644 --- a/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +++ b/spec/thinking_sphinx/middlewares/sphinxql_spec.rb @@ -61,7 +61,7 @@ class SphinxQLSubclass allow(index_set.first).to receive_messages :reference => :user expect(set_class).to receive(:new). - with(:classes => [klass], :indices => ['user_core']). + with({ :classes => [klass], :indices => ['user_core'] }). and_return(index_set) middleware.call [context] @@ -215,7 +215,7 @@ def self.table_name; 'cats'; end end it "filters out deleted values by default" do - expect(sphinx_sql).to receive(:where).with(:sphinx_deleted => false). + expect(sphinx_sql).to receive(:where).with({ :sphinx_deleted => false }). and_return(sphinx_sql) middleware.call [context] @@ -253,7 +253,7 @@ def self.table_name; 'cats'; end search.options[:with_all] = {:tag_ids => [1, 7]} expect(sphinx_sql).to receive(:where_all). - with(:tag_ids => [1, 7]).and_return(sphinx_sql) + with({ :tag_ids => [1, 7] }).and_return(sphinx_sql) middleware.call [context] end @@ -262,7 +262,7 @@ def self.table_name; 'cats'; end search.options[:without_all] = {:tag_ids => [1, 7]} expect(sphinx_sql).to receive(:where_not_all). - with(:tag_ids => [1, 7]).and_return(sphinx_sql) + with({ :tag_ids => [1, 7] }).and_return(sphinx_sql) middleware.call [context] end diff --git a/spec/thinking_sphinx/panes/excerpts_pane_spec.rb b/spec/thinking_sphinx/panes/excerpts_pane_spec.rb index 1c3d2cbf3..3adf50b89 100644 --- a/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +++ b/spec/thinking_sphinx/panes/excerpts_pane_spec.rb @@ -45,7 +45,7 @@ module Panes; end search.options[:excerpts] = {:before_match => 'foo'} expect(ThinkingSphinx::Excerpter).to receive(:new). - with(anything, anything, :before_match => 'foo').and_return(excerpter) + with(anything, anything, { :before_match => 'foo' }).and_return(excerpter) pane.excerpts end diff --git a/spec/thinking_sphinx/real_time/interpreter_spec.rb b/spec/thinking_sphinx/real_time/interpreter_spec.rb index 44b3d6727..eb6f789dd 100644 --- a/spec/thinking_sphinx/real_time/interpreter_spec.rb +++ b/spec/thinking_sphinx/real_time/interpreter_spec.rb @@ -49,7 +49,7 @@ it "passes through options to the attribute" do expect(ThinkingSphinx::RealTime::Attribute).to receive(:new). - with(column, :as => :other_name).and_return(attribute) + with(column, { :as => :other_name }).and_return(attribute) instance.has column, :as => :other_name end @@ -84,7 +84,7 @@ it "passes through options to the field" do expect(ThinkingSphinx::RealTime::Field).to receive(:new). - with(column, :as => :other_name).and_return(field) + with(column, { :as => :other_name }).and_return(field) instance.indexes column, :as => :other_name end @@ -112,7 +112,7 @@ it "adds the _sort suffix to the field's name" do expect(ThinkingSphinx::RealTime::Attribute).to receive(:new). - with(column, :as => :col_sort, :type => :string). + with(column, { :as => :col_sort, :type => :string }). and_return(attribute) instance.indexes column, :sortable => true @@ -120,7 +120,7 @@ it "respects given aliases" do expect(ThinkingSphinx::RealTime::Attribute).to receive(:new). - with(column, :as => :other_sort, :type => :string). + with(column, { :as => :other_sort, :type => :string }). and_return(attribute) instance.indexes column, :sortable => true, :as => :other @@ -128,7 +128,7 @@ it "respects symbols instead of columns" do expect(ThinkingSphinx::RealTime::Attribute).to receive(:new). - with(:title, :as => :title_sort, :type => :string). + with(:title, { :as => :title_sort, :type => :string }). and_return(attribute) instance.indexes :title, :sortable => true diff --git a/spec/thinking_sphinx_spec.rb b/spec/thinking_sphinx_spec.rb index b0ed5bb53..775966e77 100644 --- a/spec/thinking_sphinx_spec.rb +++ b/spec/thinking_sphinx_spec.rb @@ -16,7 +16,7 @@ end it "passes through the given query and options" do - expect(ThinkingSphinx::Search).to receive(:new).with('foo', :bar => :baz). + expect(ThinkingSphinx::Search).to receive(:new).with('foo', { :bar => :baz }). and_return(search) ThinkingSphinx.count('foo', :bar => :baz) @@ -35,7 +35,7 @@ end it "passes through the given query and options" do - expect(ThinkingSphinx::Search).to receive(:new).with('foo', :bar => :baz). + expect(ThinkingSphinx::Search).to receive(:new).with('foo', { :bar => :baz }). and_return(search) ThinkingSphinx.search('foo', :bar => :baz) diff --git a/thinking-sphinx.gemspec b/thinking-sphinx.gemspec index 358b0afb1..a4e0587bb 100644 --- a/thinking-sphinx.gemspec +++ b/thinking-sphinx.gemspec @@ -5,7 +5,7 @@ $:.push File.expand_path('../lib', __FILE__) Gem::Specification.new do |s| s.name = 'thinking-sphinx' - s.version = '5.5.1' + s.version = '5.6.0' s.platform = Gem::Platform::RUBY s.authors = ["Pat Allan"] s.email = ["pat@freelancing-gods.com"] @@ -30,7 +30,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'appraisal', '~> 1.0.2' s.add_development_dependency 'combustion', '~> 1.1' - s.add_development_dependency 'database_cleaner', '~> 1.6.0' - s.add_development_dependency 'rspec', '~> 3.7.0' + s.add_development_dependency 'database_cleaner', '~> 2.0.2' + s.add_development_dependency 'rspec', '~> 3.12.0' s.add_development_dependency 'rspec-retry', '~> 0.5.6' end