supernova-ts 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "supernova"
7
+ gem "thinking-sphinx", "2.0.3"
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "mysql2", "~> 0.2.7"
13
+ gem "geokit"
14
+ gem "rspec", "~> 2.3.0"
15
+ gem "bundler", "~> 1.0.0"
16
+ gem "jeweler", "~> 1.6.4"
17
+ gem "rcov", ">= 0"
18
+ gem "autotest"
19
+ gem "autotest-growl"
20
+ gem "ruby-debug"
21
+ end
@@ -0,0 +1,77 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ ZenTest (4.5.0)
5
+ activemodel (3.0.9)
6
+ activesupport (= 3.0.9)
7
+ builder (~> 2.1.2)
8
+ i18n (~> 0.5.0)
9
+ activerecord (3.0.9)
10
+ activemodel (= 3.0.9)
11
+ activesupport (= 3.0.9)
12
+ arel (~> 2.0.10)
13
+ tzinfo (~> 0.3.23)
14
+ activesupport (3.0.9)
15
+ arel (2.0.10)
16
+ autotest (4.4.6)
17
+ ZenTest (>= 4.4.1)
18
+ autotest-growl (0.2.9)
19
+ builder (2.1.2)
20
+ columnize (0.3.4)
21
+ diff-lcs (1.1.2)
22
+ geokit (1.6.0)
23
+ git (1.2.5)
24
+ i18n (0.5.0)
25
+ jeweler (1.6.4)
26
+ bundler (~> 1.0)
27
+ git (>= 1.2.5)
28
+ rake
29
+ json (1.5.3)
30
+ linecache (0.46)
31
+ rbx-require-relative (> 0.0.4)
32
+ mysql2 (0.2.11)
33
+ rake (0.9.2)
34
+ rbx-require-relative (0.0.5)
35
+ rcov (0.9.9)
36
+ riddle (1.3.3)
37
+ rsolr (1.0.2)
38
+ builder (>= 2.1.2)
39
+ rspec (2.3.0)
40
+ rspec-core (~> 2.3.0)
41
+ rspec-expectations (~> 2.3.0)
42
+ rspec-mocks (~> 2.3.0)
43
+ rspec-core (2.3.1)
44
+ rspec-expectations (2.3.0)
45
+ diff-lcs (~> 1.1.2)
46
+ rspec-mocks (2.3.0)
47
+ ruby-debug (0.10.4)
48
+ columnize (>= 0.1)
49
+ ruby-debug-base (~> 0.10.4.0)
50
+ ruby-debug-base (0.10.4)
51
+ linecache (>= 0.3)
52
+ supernova (0.3.13)
53
+ json
54
+ rsolr
55
+ thinking-sphinx (= 2.0.3)
56
+ will_paginate
57
+ thinking-sphinx (2.0.3)
58
+ activerecord (>= 3.0.3)
59
+ riddle (>= 1.2.2)
60
+ tzinfo (0.3.29)
61
+ will_paginate (2.3.15)
62
+
63
+ PLATFORMS
64
+ ruby
65
+
66
+ DEPENDENCIES
67
+ autotest
68
+ autotest-growl
69
+ bundler (~> 1.0.0)
70
+ geokit
71
+ jeweler (~> 1.6.4)
72
+ mysql2 (~> 0.2.7)
73
+ rcov
74
+ rspec (~> 2.3.0)
75
+ ruby-debug
76
+ supernova
77
+ thinking-sphinx (= 2.0.3)
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "supernova"
7
+ gem "thinking-sphinx", "2.0.3"
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "rspec", "~> 2.3.0"
13
+ gem "bundler", "~> 1.0.0"
14
+ gem "jeweler", "~> 1.6.4"
15
+ gem "rcov", ">= 0"
16
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Tobias Schwab
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = supernova-ts
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to supernova-ts
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Tobias Schwab. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "supernova-ts"
18
+ gem.homepage = "http://github.com/tobstarr/supernova-ts"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{ThinkingSphinx support for Supernova}
21
+ gem.description = %Q{ThinkingSphinx support for Supernova}
22
+ gem.email = "tobias.schwab@dynport.de"
23
+ gem.authors = ["Tobias Schwab"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "supernova-ts #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,46 @@
1
+ indexer
2
+ {
3
+ }
4
+
5
+ searchd
6
+ {
7
+ listen = 127.0.0.1:9312
8
+ log = /Users/tobias/Projects/supernova-ts/log/searchd.log
9
+ query_log = /Users/tobias/Projects/supernova-ts/log/searchd.query.log
10
+ pid_file = /Users/tobias/Projects/supernova-ts/log/searchd.development.pid
11
+ }
12
+
13
+ source offer_core_0
14
+ {
15
+ type = mysql
16
+ sql_host = localhost
17
+ sql_user = root
18
+ sql_pass =
19
+ sql_db = supernova_test
20
+ sql_query_pre = SET NAMES utf8
21
+ sql_query_pre = SET TIME_ZONE = '+0:00'
22
+ sql_query = SELECT SQL_NO_CACHE `offers`.`id` * 1 + 0 AS `id` , `offers`.`text` AS `text`, `offers`.`id` AS `sphinx_internal_id`, 3893864506 AS `class_crc`, 0 AS `sphinx_deleted`, `offers`.`user_id` AS `user_id`, `offers`.`enabled` AS `enabled`, `offers`.`popularity` AS `popularity`, RADIANS(lat) AS `lat`, RADIANS(lng) AS `lng` FROM `offers` WHERE (`offers`.`id` >= $start AND `offers`.`id` <= $end) GROUP BY `offers`.`id`, `offers`.`text`, `offers`.`id`, `offers`.`user_id`, `offers`.`enabled`, `offers`.`popularity` ORDER BY NULL
23
+ sql_query_range = SELECT IFNULL(MIN(`id`), 1), IFNULL(MAX(`id`), 1) FROM `offers`
24
+ sql_attr_uint = class_crc
25
+ sql_attr_uint = sphinx_deleted
26
+ sql_attr_uint = user_id
27
+ sql_attr_uint = popularity
28
+ sql_attr_bool = enabled
29
+ sql_attr_bigint = sphinx_internal_id
30
+ sql_attr_float = lat
31
+ sql_attr_float = lng
32
+ sql_query_info = SELECT * FROM `offers` WHERE `id` = (($id - 0) / 1)
33
+ }
34
+
35
+ index offer_core
36
+ {
37
+ source = offer_core_0
38
+ path = /Users/tobias/Projects/supernova-ts/db/sphinx/development/offer_core
39
+ charset_type = utf-8
40
+ }
41
+
42
+ index offer
43
+ {
44
+ type = distributed
45
+ local = offer_core
46
+ }
@@ -0,0 +1 @@
1
+ require "supernova"
@@ -0,0 +1,8 @@
1
+ require "supernova/thinking_sphinx_criteria"
2
+
3
+ module Supernova::ThinkingSphinx
4
+ def self.included(base)
5
+ base.extend(Supernova::ClassMethods)
6
+ base.criteria_class = Supernova::ThinkingSphinxCriteria
7
+ end
8
+ end
@@ -0,0 +1,49 @@
1
+ require "thinking_sphinx"
2
+ require "zlib"
3
+
4
+ class Supernova::ThinkingSphinxCriteria < Supernova::Criteria
5
+ def self.index_statement_for(field_name, column = nil)
6
+ column ||= field_name
7
+ [%(CONCAT("#{field_name}_", #{column})), { :as => :"indexed_#{field_name}" }]
8
+ end
9
+
10
+ def normalize_with_filter(attributes)
11
+ attributes.inject({}) do |hash, (key, value)|
12
+ value = Zlib.crc32(value.to_s) if value.is_a?(String) || value.is_a?(Class)
13
+ hash.merge!(key => value)
14
+ end
15
+ end
16
+
17
+ def to_params
18
+ sphinx_options = { :match_mode => :boolean, :with => {}, :conditions => {}, :without => {} }
19
+ sphinx_options[:order] = self.search_options[:order] if self.search_options[:order]
20
+ sphinx_options[:limit] = self.search_options[:limit] if self.search_options[:limit]
21
+ sphinx_options[:select] = self.search_options[:select] if self.search_options[:select]
22
+ sphinx_options[:group_by] = self.search_options[:group_by] if self.search_options[:group_by]
23
+ sphinx_options.merge!(self.search_options[:pagination]) if self.search_options[:pagination].is_a?(Hash)
24
+ sphinx_options[:classes] = self.filters[:classes] if self.filters[:classes]
25
+ sphinx_options[:classes] = [self.clazz] if self.clazz
26
+ sphinx_options[:conditions].merge!(self.filters[:conditions]) if self.filters[:conditions]
27
+ sphinx_options[:with].merge!(normalize_with_filter(self.filters[:with])) if self.filters[:with]
28
+ sphinx_options[:without].merge!(normalize_with_filter(self.filters[:without])) if self.filters[:without]
29
+ sphinx_options.merge!(self.search_options[:custom_options]) if self.search_options[:custom_options]
30
+ if self.search_options[:geo_center] && self.search_options[:geo_distance]
31
+ sphinx_options[:geo] = [self.search_options[:geo_center][:lat].to_radians, self.search_options[:geo_center][:lng].to_radians]
32
+ sphinx_options[:with]["@geodist"] = self.search_options[:geo_distance].is_a?(Range) ? self.search_options[:geo_distance] : Range.new(0.0, self.search_options[:geo_distance])
33
+ end
34
+ [(self.search_options[:search] || Array.new).join(" "), sphinx_options]
35
+ end
36
+
37
+ def execute
38
+ ThinkingSphinx.search(*self.to_params)
39
+ end
40
+
41
+ def ids
42
+ params = *self.to_params
43
+ ThinkingSphinx.search_for_ids(*params)
44
+ end
45
+
46
+ def total_entries
47
+ ids.total_entries
48
+ end
49
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require "active_record"
3
+ require "thinking_sphinx"
4
+ require "mysql2"
5
+ require "fileutils"
6
+
7
+ describe "ThinkingSphinx" do
8
+ let(:ts) { ThinkingSphinx::Configuration.instance }
9
+
10
+ before(:each) do
11
+ ts.build
12
+ ts.controller.index
13
+ ts.controller.start
14
+
15
+
16
+ ThinkingSphinx.deltas_enabled = true
17
+ ThinkingSphinx.updates_enabled = true
18
+ ThinkingSphinx.suppress_delta_output = true
19
+
20
+ Offer.connection.execute "TRUNCATE offers"
21
+ root = Geokit::LatLng.new(47, 11)
22
+ endpoint = root.endpoint(90, 50, :units => :kms)
23
+ @offer1 = Offer.create!(:id => 1, :user_id => 1, :enabled => false, :text => "Hans Meyer", :popularity => 10, :lat => root.lat, :lng => root.lng)
24
+ @offer2 = Offer.create!(:id => 2, :user_id => 2, :enabled => true, :text => "Marek Mintal", :popularity => 1, :lat => endpoint.lat, :lng => endpoint.lng)
25
+ ts.controller.index
26
+ sleep 0.3
27
+ end
28
+
29
+ it "finds the correct objects" do
30
+ Offer.for_user_ids(2).to_a.to_a.should == [@offer2]
31
+ Offer.for_user_ids(2, 1).to_a.to_a.sort_by(&:id) == [@offer1, @offer2]
32
+ end
33
+
34
+ it "correctly filters out unwanted records" do
35
+ Offer.search_scope.without(:user_id => 2).to_a.to_a.sort_by(&:id).should == [@offer1]
36
+ Offer.search_scope.without(:user_id => 1).to_a.to_a.sort_by(&:id).should == [@offer2]
37
+ Offer.search_scope.without(:user_id => 1).without(:user_id => 2).to_a.to_a.sort_by(&:id).should == []
38
+ end
39
+
40
+ it "returns the corect ids" do
41
+ Offer.for_user_ids(2).ids.to_a.to_a.should == [2]
42
+ end
43
+
44
+ it "filters by enabled" do
45
+ Offer.search_scope.with(:enabled => true).to_a.to_a.should == [@offer2]
46
+ Offer.search_scope.with(:enabled => false).to_a.to_a.should == [@offer1]
47
+ end
48
+
49
+ it "combines searches" do
50
+ Offer.search_scope.with(:enabled => false).with(:user_id => 2).to_a.should be_empty
51
+ end
52
+
53
+ it "searches for names" do
54
+ Offer.search_scope.search("Marek").map(&:id).should == [2]
55
+ Offer.search_scope.search("Hans").map(&:id).should == [1]
56
+ end
57
+
58
+ it "sorty by popularity" do
59
+ Offer.search_scope.order("popularity desc").map(&:id).should == [1, 2]
60
+ end
61
+
62
+ describe "geo search" do
63
+ it "finds the correct offers" do
64
+ Offer.search_scope.near(47, 11).within(25.kms).to_a.to_a.should == [@offer1]
65
+ end
66
+
67
+ it "finds more offers when radius is bigger" do
68
+ Offer.search_scope.near(47, 11).within(49.kms).to_a.should_not include(@offer2)
69
+ Offer.search_scope.near(47, 11).within(51.kms).to_a.should include(@offer2)
70
+ end
71
+
72
+ it "finds offers around other offers" do
73
+ Offer.search_scope.near(@offer1).within(49.kms).to_a.to_a.should == [@offer1]
74
+ Offer.search_scope.near(@offer1).within(51.kms).order("@geodist desc").to_a.to_a.should == [@offer2, @offer1]
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,70 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'supernova-ts'
5
+ require "mysql2"
6
+ require "logger"
7
+ require "fileutils"
8
+ require "ruby-debug"
9
+ require "geokit"
10
+
11
+ if defined?(Debugger) && Debugger.respond_to?(:settings)
12
+ Debugger.settings[:autolist] = 1
13
+ Debugger.settings[:autoeval] = true
14
+ end
15
+
16
+
17
+ # Requires supporting files with custom matchers and macros, etc,
18
+ # in ./support/ and its subdirectories.
19
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
20
+
21
+ RSpec.configure do |config|
22
+ config.before(:each) do
23
+ ActiveRecord::Base.connection.execute("TRUNCATE offers")
24
+ end
25
+ end
26
+
27
+ ActiveRecord::Base.establish_connection(
28
+ :adapter => "mysql2",
29
+ :host => "localhost",
30
+ :database => "supernova_test",
31
+ :username => "root",
32
+ :encoding => "utf8"
33
+ )
34
+
35
+ PROJECT_ROOT = Pathname.new(File.expand_path("..", File.dirname(__FILE__)))
36
+ FileUtils.mkdir_p(PROJECT_ROOT.join("db/sphinx/development"))
37
+ FileUtils.mkdir_p(PROJECT_ROOT.join("log"))
38
+ FileUtils.mkdir_p(PROJECT_ROOT.join("config"))
39
+
40
+ ThinkingSphinx::ActiveRecord::LogSubscriber.logger = Logger.new(
41
+ open(File.expand_path("../log/active_record.log", File.dirname(__FILE__)), "a")
42
+ )
43
+
44
+ ActiveRecord::Base.send(:include, ThinkingSphinx::ActiveRecord)
45
+
46
+ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS offers")
47
+ ActiveRecord::Base.connection.execute("CREATE TABLE offers (id SERIAL, text TEXT, user_id INTEGER, enabled BOOLEAN, popularity INTEGER, lat FLOAT, lng FLOAT)")
48
+
49
+ class Offer < ActiveRecord::Base
50
+ include Supernova::ThinkingSphinx
51
+
52
+ define_index do
53
+ indexes text
54
+
55
+ has :user_id
56
+ has :enabled
57
+ has :popularity, :sort => true
58
+
59
+ has "RADIANS(lat)", :as => :lat, :type => :float
60
+ has "RADIANS(lng)", :as => :lng, :type => :float
61
+ end
62
+
63
+ named_search_scope :for_user_ids do |*ids|
64
+ with(:user_id => ids.flatten)
65
+ end
66
+ end
67
+
68
+ class Host
69
+ attr_accessor :id
70
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "SupernovaTs" do
4
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Supernova::ThinkingSphinxCriteria" do
4
+ let(:scope) { Supernova::ThinkingSphinxCriteria.new }
5
+
6
+ describe "#to_params" do
7
+ it "returns an array" do
8
+ scope.to_params.should be_an_instance_of(Array)
9
+ end
10
+
11
+ it "sets the correct order query" do
12
+ scope.order("title desc").to_params.at(1)[:order].should == "title desc"
13
+ end
14
+
15
+ it "sets the correct group_by statement" do
16
+ scope.group_by("title").to_params.at(1)[:group_by].should == "title"
17
+ end
18
+
19
+ it "sets the match_mode to boolean" do
20
+ scope.to_params.at(1)[:match_mode].should == :boolean
21
+ end
22
+
23
+ it "does not set the classes field by default" do
24
+ scope.to_params.at(1).should_not have_key(:classes)
25
+ end
26
+
27
+ it "sets the classes field when classes set" do
28
+ scope.for_classes(Offer).to_params.at(1)[:classes].should == [Offer]
29
+ end
30
+
31
+ it "sets the classes to the clazz when intialized with the class" do
32
+ Supernova::ThinkingSphinxCriteria.new(Offer).to_params.at(1)[:classes].should == [Offer]
33
+ end
34
+
35
+ it "sets the search query when present" do
36
+ scope.search("some test").to_params.at(0).should == "some test"
37
+ end
38
+
39
+ it "sets a set limit" do
40
+ scope.limit(88).to_params.at(1)[:limit].should == 88
41
+ end
42
+
43
+ it "sets the correct without parameters" do
44
+ scope.without(:user_id => 9).to_params.at(1)[:without].should == { :user_id => [9] }
45
+ scope.without(:user_id => 9).without(:user_id => 9).without(:user_id => 1).to_params.at(1)[:without].should == { :user_id => [9, 1] }
46
+ end
47
+
48
+ it "calls sphinx with select fields" do
49
+ scope.select(%w(id title name)).to_params.at(1)[:select].should == %w(id title name)
50
+ end
51
+
52
+ it "sets the correct with filters" do
53
+ scope.with(:a => 1).with(:b => 2).to_params.at(1)[:with].should == {
54
+ :a => 1,
55
+ :b => 2
56
+ }
57
+ end
58
+
59
+ it "uses the crc32 value of strings when used in with" do
60
+ scope.with(:a => Offer).to_params.at(1)[:with].should == {
61
+ :a => 3893864506, # crc32 of Offer string
62
+ }
63
+ end
64
+
65
+ it "sets the correct geo option filter" do
66
+ scope.near(53.5748, 10.0347).within(5.kms).to_params.at(1)[:geo].map(&:to_s).should == ["0.935056656097458", "0.175138554449875"]
67
+ end
68
+
69
+ it "merges correct with options" do
70
+ scope.near(53.5748, 10.0347).within(5.kms).with(:filter => true).to_params.at(1)[:with].should == {
71
+ "@geodist" => Range.new(0.0, 5_000.0),
72
+ :filter => true
73
+ }
74
+ end
75
+
76
+ it "sets the correct geo distance filter when single value given" do
77
+ # @geodist
78
+ scope.near(53.5748, 10.0347).within(7.kms).to_params.at(1)[:with]["@geodist"].should == Range.new(0.0, 7_000.0)
79
+ end
80
+
81
+ it "sets the correct geo distance filter when range given value given" do
82
+ # @geodist
83
+ scope.near(53.5748, 10.0347).within(7.kms..10.kms).to_params.at(1)[:with]["@geodist"].should == Range.new(7_000.0, 10_000.0)
84
+ end
85
+
86
+ { :page => 8, :per_page => 1 }.each do |key, value|
87
+ it "sets pagination pagination #{key} to #{value}" do
88
+ scope.paginate(key => value).to_params.at(1)[key].should == value
89
+ end
90
+ end
91
+
92
+ it "adds custom options to the sphinx search" do
93
+ scope.options(:star => true).to_params.at(1)[:star].should == true
94
+ end
95
+ end
96
+
97
+ describe "#normalize_with_filter" do
98
+ it "does not change booleans and integers" do
99
+ range = 1..10
100
+ scope.normalize_with_filter(:a => 1, :enabled => true, :range => range).should == { :a => 1, :enabled => true, :range => range }
101
+ end
102
+
103
+ it "uses crc32 of strings" do
104
+ scope.normalize_with_filter(:a => "Test").should == { :a => 2018365746 } # crc32 of "Test"
105
+ end
106
+ end
107
+
108
+ describe "with to_params mockes" do
109
+ let(:query) { double("query") }
110
+ let(:options) { double("options") }
111
+ let(:sphinx_response) { double("sphinx_respons") }
112
+
113
+ before(:each) do
114
+ scope.stub!(:to_params).and_return([query, options])
115
+ end
116
+
117
+ describe "#to_a" do
118
+ it "returns the sphinx search" do
119
+ ThinkingSphinx.stub!(:search).and_return sphinx_response
120
+ scope.to_a.should == sphinx_response
121
+ end
122
+
123
+ it "calls ThinkingSphinx with what to_params returns" do
124
+ ThinkingSphinx.should_receive(:search).with(query, options).and_return sphinx_response
125
+ scope.to_a.should == sphinx_response
126
+ end
127
+ end
128
+
129
+ it "forwards ids to search_for_ids" do
130
+ ids_response = double("id response")
131
+ ThinkingSphinx.should_receive(:search_for_ids).with(query, options).and_return ids_response
132
+ scope.ids
133
+ end
134
+
135
+ it "forwards total_entries to search_for_ids" do
136
+ ids_response = double("id response")
137
+ ThinkingSphinx.should_receive(:search_for_ids).with(query, options).and_return ids_response
138
+ ids_response.should_receive(:total_entries).and_return 88
139
+ scope.total_entries.should == 88
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,88 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{supernova-ts}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tobias Schwab"]
12
+ s.date = %q{2011-07-18}
13
+ s.description = %q{ThinkingSphinx support for Supernova}
14
+ s.email = %q{tobias.schwab@dynport.de}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "Gemfile.orig",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "autotest/discover.rb",
30
+ "config/development.sphinx.conf",
31
+ "lib/supernova-ts.rb",
32
+ "lib/supernova/thinking_sphinx.rb",
33
+ "lib/supernova/thinking_sphinx_criteria.rb",
34
+ "spec/integration/thinking_sphinx_spec.rb",
35
+ "spec/spec_helper.rb",
36
+ "spec/supernova-ts_spec.rb",
37
+ "spec/supernova/thinking_sphinx_criteria_spec.rb",
38
+ "supernova-ts.gemspec"
39
+ ]
40
+ s.homepage = %q{http://github.com/tobstarr/supernova-ts}
41
+ s.licenses = ["MIT"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.7.2}
44
+ s.summary = %q{ThinkingSphinx support for Supernova}
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<supernova>, [">= 0"])
51
+ s.add_runtime_dependency(%q<thinking-sphinx>, ["= 2.0.3"])
52
+ s.add_development_dependency(%q<mysql2>, ["~> 0.2.7"])
53
+ s.add_development_dependency(%q<geokit>, [">= 0"])
54
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
55
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
56
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
57
+ s.add_development_dependency(%q<rcov>, [">= 0"])
58
+ s.add_development_dependency(%q<autotest>, [">= 0"])
59
+ s.add_development_dependency(%q<autotest-growl>, [">= 0"])
60
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
61
+ else
62
+ s.add_dependency(%q<supernova>, [">= 0"])
63
+ s.add_dependency(%q<thinking-sphinx>, ["= 2.0.3"])
64
+ s.add_dependency(%q<mysql2>, ["~> 0.2.7"])
65
+ s.add_dependency(%q<geokit>, [">= 0"])
66
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
67
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
68
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
69
+ s.add_dependency(%q<rcov>, [">= 0"])
70
+ s.add_dependency(%q<autotest>, [">= 0"])
71
+ s.add_dependency(%q<autotest-growl>, [">= 0"])
72
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
73
+ end
74
+ else
75
+ s.add_dependency(%q<supernova>, [">= 0"])
76
+ s.add_dependency(%q<thinking-sphinx>, ["= 2.0.3"])
77
+ s.add_dependency(%q<mysql2>, ["~> 0.2.7"])
78
+ s.add_dependency(%q<geokit>, [">= 0"])
79
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
80
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
81
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
82
+ s.add_dependency(%q<rcov>, [">= 0"])
83
+ s.add_dependency(%q<autotest>, [">= 0"])
84
+ s.add_dependency(%q<autotest-growl>, [">= 0"])
85
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
86
+ end
87
+ end
88
+
metadata ADDED
@@ -0,0 +1,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: supernova-ts
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Tobias Schwab
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-18 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ version_requirements: *id001
31
+ name: supernova
32
+ prerelease: false
33
+ type: :runtime
34
+ - !ruby/object:Gem::Dependency
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - "="
39
+ - !ruby/object:Gem::Version
40
+ hash: 9
41
+ segments:
42
+ - 2
43
+ - 0
44
+ - 3
45
+ version: 2.0.3
46
+ version_requirements: *id002
47
+ name: thinking-sphinx
48
+ prerelease: false
49
+ type: :runtime
50
+ - !ruby/object:Gem::Dependency
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ hash: 25
57
+ segments:
58
+ - 0
59
+ - 2
60
+ - 7
61
+ version: 0.2.7
62
+ version_requirements: *id003
63
+ name: mysql2
64
+ prerelease: false
65
+ type: :development
66
+ - !ruby/object:Gem::Dependency
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ version_requirements: *id004
77
+ name: geokit
78
+ prerelease: false
79
+ type: :development
80
+ - !ruby/object:Gem::Dependency
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 2
89
+ - 3
90
+ - 0
91
+ version: 2.3.0
92
+ version_requirements: *id005
93
+ name: rspec
94
+ prerelease: false
95
+ type: :development
96
+ - !ruby/object:Gem::Dependency
97
+ requirement: &id006 !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ hash: 23
103
+ segments:
104
+ - 1
105
+ - 0
106
+ - 0
107
+ version: 1.0.0
108
+ version_requirements: *id006
109
+ name: bundler
110
+ prerelease: false
111
+ type: :development
112
+ - !ruby/object:Gem::Dependency
113
+ requirement: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ hash: 7
119
+ segments:
120
+ - 1
121
+ - 6
122
+ - 4
123
+ version: 1.6.4
124
+ version_requirements: *id007
125
+ name: jeweler
126
+ prerelease: false
127
+ type: :development
128
+ - !ruby/object:Gem::Dependency
129
+ requirement: &id008 !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ version_requirements: *id008
139
+ name: rcov
140
+ prerelease: false
141
+ type: :development
142
+ - !ruby/object:Gem::Dependency
143
+ requirement: &id009 !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ hash: 3
149
+ segments:
150
+ - 0
151
+ version: "0"
152
+ version_requirements: *id009
153
+ name: autotest
154
+ prerelease: false
155
+ type: :development
156
+ - !ruby/object:Gem::Dependency
157
+ requirement: &id010 !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ hash: 3
163
+ segments:
164
+ - 0
165
+ version: "0"
166
+ version_requirements: *id010
167
+ name: autotest-growl
168
+ prerelease: false
169
+ type: :development
170
+ - !ruby/object:Gem::Dependency
171
+ requirement: &id011 !ruby/object:Gem::Requirement
172
+ none: false
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ hash: 3
177
+ segments:
178
+ - 0
179
+ version: "0"
180
+ version_requirements: *id011
181
+ name: ruby-debug
182
+ prerelease: false
183
+ type: :development
184
+ description: ThinkingSphinx support for Supernova
185
+ email: tobias.schwab@dynport.de
186
+ executables: []
187
+
188
+ extensions: []
189
+
190
+ extra_rdoc_files:
191
+ - LICENSE.txt
192
+ - README.rdoc
193
+ files:
194
+ - .document
195
+ - .rspec
196
+ - Gemfile
197
+ - Gemfile.lock
198
+ - Gemfile.orig
199
+ - LICENSE.txt
200
+ - README.rdoc
201
+ - Rakefile
202
+ - VERSION
203
+ - autotest/discover.rb
204
+ - config/development.sphinx.conf
205
+ - lib/supernova-ts.rb
206
+ - lib/supernova/thinking_sphinx.rb
207
+ - lib/supernova/thinking_sphinx_criteria.rb
208
+ - spec/integration/thinking_sphinx_spec.rb
209
+ - spec/spec_helper.rb
210
+ - spec/supernova-ts_spec.rb
211
+ - spec/supernova/thinking_sphinx_criteria_spec.rb
212
+ - supernova-ts.gemspec
213
+ homepage: http://github.com/tobstarr/supernova-ts
214
+ licenses:
215
+ - MIT
216
+ post_install_message:
217
+ rdoc_options: []
218
+
219
+ require_paths:
220
+ - lib
221
+ required_ruby_version: !ruby/object:Gem::Requirement
222
+ none: false
223
+ requirements:
224
+ - - ">="
225
+ - !ruby/object:Gem::Version
226
+ hash: 3
227
+ segments:
228
+ - 0
229
+ version: "0"
230
+ required_rubygems_version: !ruby/object:Gem::Requirement
231
+ none: false
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ hash: 3
236
+ segments:
237
+ - 0
238
+ version: "0"
239
+ requirements: []
240
+
241
+ rubyforge_project:
242
+ rubygems_version: 1.7.2
243
+ signing_key:
244
+ specification_version: 3
245
+ summary: ThinkingSphinx support for Supernova
246
+ test_files: []
247
+