Skip to content

Commit

Permalink
Merge pull request #1 from assaydepot/specs
Browse files Browse the repository at this point in the history
Added some specs
  • Loading branch information
cpetersen authored Jul 16, 2024
2 parents e75226a + cf4cdab commit ab6993e
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 14 deletions.
20 changes: 20 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,26 @@ GEM
specs:
ast (2.4.2)
diff-lcs (1.5.1)
elastic-transport (8.3.5)
faraday (< 3)
multi_json
elasticsearch (8.14.0)
elastic-transport (~> 8.3)
elasticsearch-api (= 8.14.0)
elasticsearch-api (8.14.0)
multi_json
faraday (2.10.0)
faraday-net_http (>= 2.0, < 3.2)
logger
faraday-net_http (3.1.0)
net-http
json (2.7.2)
language_server-protocol (3.17.0.3)
lint_roller (1.1.0)
logger (1.6.0)
multi_json (1.15.0)
net-http (0.4.1)
uri
parallel (1.25.1)
parser (3.3.4.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -65,12 +82,15 @@ GEM
rubocop-performance (~> 1.21.0)
strscan (3.1.0)
unicode-display_width (2.5.0)
uri (0.13.0)

PLATFORMS
arm64-darwin-23
ruby

DEPENDENCIES
elasticsearch
faraday
rake (~> 13.0)
rrf!
rspec (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion lib/rrf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def fuse(*result_sets, limit: 10)

# Sort by score and limit results
top_record_ids = record_scores.sort_by { |_id, result| -result[:score] }.to_h.keys.first(limit)

# Load actual records from ActiveRecord
self.where(id: top_record_ids).index_by(&:id).values_at(*top_record_ids).each do |record|
record.define_singleton_method(:_rrf_score) { record_scores[record.id][:score] }
Expand Down
3 changes: 3 additions & 0 deletions rrf.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ Gem::Specification.new do |spec|

# Uncomment to register a new dependency of your gem
# spec.add_dependency "example-gem", "~> 1.0"
spec.add_development_dependency "rspec"
spec.add_development_dependency "elasticsearch"
spec.add_development_dependency "faraday"

# For more information and examples about making a new gem, check out our
# guide at: https://bundler.io/guides/creating_gem.html
Expand Down
76 changes: 70 additions & 6 deletions spec/rrf_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,75 @@
# frozen_string_literal: true

RSpec.describe RRF do
it "has a version number" do
expect(RRF::VERSION).not_to be nil
end
require "spec_helper"

RSpec.describe RRF::Model do
describe ".fuse" do
let!(:chunk1) { Chunk.create!(body: "hello world") }
let!(:chunk2) { Chunk.create!(body: "hi there") }
let!(:chunk3) { Chunk.create!(body: "hello again") }

it "fuses results from ActiveRecord and Searchkick" do
# Mocking Searchkick results
search_hits = [
{ "_id" => chunk1.id },
{ "_id" => chunk2.id }
]
search_results = instance_double(Searchkick::Relation)
search_results.define_singleton_method(:hits) { search_hits }
allow(search_results).to receive(:is_a?).with(ActiveRecord::Relation).and_return(false)
allow(search_results).to receive(:is_a?).with(Searchkick::Relation).and_return(true)
allow(Chunk).to receive(:search).and_return(search_results)

ar_result = Chunk.where("body like ?", "%hello%")
es_result = Chunk.search("hello", load: false)

fused_results = Chunk.fuse(ar_result, es_result, limit: 2)

expect(fused_results.size).to eq(2)
expect(fused_results).to include(chunk1)
expect(fused_results).to include(chunk3)
end

it "limits the number of results" do
search_hits = [
{ "_id" => chunk1.id },
{ "_id" => chunk2.id }
]
search_results = instance_double(Searchkick::Relation)
search_results.define_singleton_method(:hits) { search_hits }
allow(search_results).to receive(:is_a?).with(ActiveRecord::Relation).and_return(false)
allow(search_results).to receive(:is_a?).with(Searchkick::Relation).and_return(true)
allow(Chunk).to receive(:search).and_return(search_results)

ar_result = Chunk.where("body like ?", "%hello%")
es_result = Chunk.search("hello", load: false)

fused_results = Chunk.fuse(ar_result, es_result, limit: 1)
expect(fused_results.size).to eq(1)
end

it "raises an error for unsupported result set types" do
expect {
Chunk.fuse(["unsupported"], limit: 1)
}.to raise_error(RRF::Error, "Unsupported result set type: Array")
end

it "correctly calculates and assigns scores" do
search_hits = [
{ "_id" => chunk1.id },
{ "_id" => chunk2.id }
]
search_results = instance_double(Searchkick::Relation)
search_results.define_singleton_method(:hits) { search_hits }
allow(search_results).to receive(:is_a?).with(ActiveRecord::Relation).and_return(false)
allow(search_results).to receive(:is_a?).with(Searchkick::Relation).and_return(true)
allow(Chunk).to receive(:search).and_return(search_results)

ar_result = Chunk.where("body like ?", "%hello%")
es_result = Chunk.search("hello", load: false)

it "does something useful" do
expect(false).to eq(true)
fused_results = Chunk.fuse(ar_result, es_result, limit: 2)
expect(fused_results.first._rrf_score).to be > 0
end
end
end
39 changes: 32 additions & 7 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
# frozen_string_literal: true

require "active_record"
require "searchkick"
require "faraday"
require "elasticsearch"
require "rrf"
require "rspec"

# Mock ActiveRecord and Searchkick models
class MockRecord < ActiveRecord::Base
self.abstract_class = true
include RRF::Model
end

RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = ".rspec_status"
# Enable :focus tag and run focused tests
config.filter_run_when_matching :focus

config.before(:suite) do
ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: ":memory:"
)

# Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching!
ActiveRecord::Schema.define do
create_table :chunks, force: true do |t|
t.string :body
t.timestamps
end
end

config.expect_with :rspec do |c|
c.syntax = :expect
class Chunk < MockRecord
end
end
end

config.before(:each) do
Chunk.delete_all
end
end

0 comments on commit ab6993e

Please sign in to comment.