picky 4.0.0pre1 → 4.0.0pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/aux/picky/cli.rb +6 -2
- data/lib/picky.rb +10 -8
- data/lib/picky/backends/backend.rb +37 -0
- data/lib/picky/backends/file.rb +0 -20
- data/lib/picky/backends/memory.rb +0 -29
- data/lib/picky/backends/redis.rb +74 -15
- data/lib/picky/backends/redis/list.rb +1 -1
- data/lib/picky/backends/sqlite.rb +0 -27
- data/lib/picky/bundle.rb +2 -2
- data/lib/picky/bundle_indexed.rb +1 -1
- data/lib/picky/bundle_indexing.rb +1 -1
- data/lib/picky/categories_indexed.rb +1 -11
- data/lib/picky/category.rb +4 -4
- data/lib/picky/category/location.rb +25 -0
- data/lib/picky/category_realtime.rb +4 -3
- data/lib/picky/console.rb +1 -1
- data/lib/picky/constants.rb +1 -1
- data/lib/picky/ext/maybe_compile.rb +2 -2
- data/lib/picky/extensions/object.rb +3 -2
- data/lib/picky/generators/aliases.rb +7 -2
- data/lib/picky/generators/partial/default.rb +1 -0
- data/lib/picky/generators/similarity/default.rb +1 -0
- data/lib/picky/generators/similarity/phonetic.rb +13 -2
- data/lib/picky/generators/strategy.rb +0 -2
- data/lib/picky/generators/weights/constant.rb +1 -2
- data/lib/picky/generators/weights/default.rb +1 -0
- data/lib/picky/generators/weights/dynamic.rb +1 -1
- data/lib/picky/generators/weights/logarithmic.rb +1 -1
- data/lib/picky/generators/weights/{runtime.rb → stub.rb} +1 -3
- data/lib/picky/index.rb +3 -3
- data/lib/picky/index_indexing.rb +0 -2
- data/lib/picky/index_realtime.rb +1 -1
- data/lib/picky/indexers/base.rb +7 -0
- data/lib/picky/indexers/parallel.rb +2 -4
- data/lib/picky/indexers/serial.rb +2 -0
- data/lib/picky/indexes_indexing.rb +1 -1
- data/lib/picky/interfaces/live_parameters/master_child.rb +175 -0
- data/lib/picky/interfaces/live_parameters/unicorn.rb +37 -0
- data/lib/picky/loader.rb +238 -259
- data/lib/picky/query/allocation.rb +19 -10
- data/lib/picky/query/combination.rb +7 -1
- data/lib/picky/query/combinations.rb +1 -6
- data/lib/picky/query/token.rb +26 -36
- data/lib/picky/results.rb +18 -17
- data/lib/picky/scheduler.rb +2 -1
- data/lib/picky/search.rb +1 -1
- data/lib/picky/sinatra.rb +6 -6
- data/lib/picky/statistics.rb +2 -0
- data/lib/picky/tokenizer.rb +8 -8
- data/lib/picky/wrappers/bundle/calculation.rb +4 -4
- data/lib/picky/wrappers/bundle/location.rb +1 -2
- data/lib/tasks/framework.rake +1 -1
- data/lib/tasks/statistics.rake +1 -1
- data/lib/tasks/try.rake +1 -1
- data/lib/tasks/try.rb +1 -1
- data/spec/aux/picky/cli_spec.rb +12 -12
- data/spec/ext/performant_spec.rb +16 -16
- data/spec/functional/backends/file_spec.rb +78 -7
- data/spec/functional/backends/memory_spec.rb +78 -7
- data/spec/functional/backends/redis_spec.rb +73 -13
- data/spec/functional/dynamic_weights_spec.rb +3 -4
- data/spec/functional/realtime_spec.rb +2 -2
- data/spec/functional/speed_spec.rb +2 -2
- data/spec/functional/terminate_early_spec.rb +3 -3
- data/spec/lib/analytics_spec.rb +1 -1
- data/spec/lib/analyzer_spec.rb +5 -3
- data/spec/lib/categories_indexed_spec.rb +38 -20
- data/spec/lib/category/location_spec.rb +30 -0
- data/spec/lib/character_substituters/west_european_spec.rb +1 -0
- data/spec/lib/extensions/hash_spec.rb +6 -5
- data/spec/lib/extensions/module_spec.rb +6 -6
- data/spec/lib/extensions/object_spec.rb +9 -8
- data/spec/lib/extensions/string_spec.rb +1 -1
- data/spec/lib/generators/similarity/phonetic_spec.rb +11 -0
- data/spec/lib/index_realtime_spec.rb +5 -5
- data/spec/lib/interfaces/{live_parameters_spec.rb → live_parameters/master_child_spec.rb} +26 -26
- data/spec/lib/interfaces/live_parameters/unicorn_spec.rb +160 -0
- data/spec/lib/loader_spec.rb +65 -25
- data/spec/lib/query/allocation_spec.rb +25 -22
- data/spec/lib/query/combinations_spec.rb +13 -36
- data/spec/lib/query/token_spec.rb +144 -131
- data/spec/lib/query/tokens_spec.rb +14 -0
- data/spec/lib/results_spec.rb +14 -8
- data/spec/lib/search_spec.rb +1 -1
- data/spec/lib/sinatra_spec.rb +8 -8
- metadata +28 -91
- data/lib/picky/adapters/rack.rb +0 -34
- data/lib/picky/adapters/rack/base.rb +0 -27
- data/lib/picky/adapters/rack/live_parameters.rb +0 -37
- data/lib/picky/adapters/rack/search.rb +0 -67
- data/lib/picky/application.rb +0 -268
- data/lib/picky/frontend_adapters/rack.rb +0 -161
- data/lib/picky/interfaces/live_parameters.rb +0 -187
- data/lib/picky/sources/base.rb +0 -92
- data/lib/picky/sources/couch.rb +0 -76
- data/lib/picky/sources/csv.rb +0 -83
- data/lib/picky/sources/db.rb +0 -189
- data/lib/picky/sources/delicious.rb +0 -63
- data/lib/picky/sources/mongo.rb +0 -80
- data/lib/picky/wrappers/category/location.rb +0 -38
- data/lib/tasks/routes.rake +0 -8
- data/spec/lib/adapters/rack/base_spec.rb +0 -24
- data/spec/lib/adapters/rack/live_parameters_spec.rb +0 -26
- data/spec/lib/adapters/rack/query_spec.rb +0 -39
- data/spec/lib/application_spec.rb +0 -155
- data/spec/lib/frontend_adapters/rack_spec.rb +0 -294
- data/spec/lib/sources/base_spec.rb +0 -53
- data/spec/lib/sources/couch_spec.rb +0 -114
- data/spec/lib/sources/csv_spec.rb +0 -89
- data/spec/lib/sources/db_spec.rb +0 -125
- data/spec/lib/sources/delicious_spec.rb +0 -94
- data/spec/lib/sources/mongo_spec.rb +0 -50
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
module Picky
|
|
2
|
-
|
|
3
|
-
module Sources
|
|
4
|
-
|
|
5
|
-
# Describes a Delicious (http://deli.cio.us) source.
|
|
6
|
-
#
|
|
7
|
-
# This source has a fixed set of categories:
|
|
8
|
-
# * title
|
|
9
|
-
# * tags
|
|
10
|
-
# * url
|
|
11
|
-
#
|
|
12
|
-
# Examples:
|
|
13
|
-
# Sources::CSV.new('usrnam', 'paswrd')
|
|
14
|
-
#
|
|
15
|
-
class Delicious < Base
|
|
16
|
-
|
|
17
|
-
def initialize username, password
|
|
18
|
-
check_gem
|
|
19
|
-
@username = username
|
|
20
|
-
@password = password
|
|
21
|
-
end
|
|
22
|
-
def check_gem # :nodoc:
|
|
23
|
-
require 'www/delicious'
|
|
24
|
-
rescue LoadError
|
|
25
|
-
warn_gem_missing 'www-delicious', 'the delicious source'
|
|
26
|
-
exit 1
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def to_s
|
|
30
|
-
"#{self.class.name}(#{@username})"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Harvests the data to index.
|
|
34
|
-
#
|
|
35
|
-
def harvest category
|
|
36
|
-
get_data do |indexed_id, data|
|
|
37
|
-
text = data[category.from]
|
|
38
|
-
next unless text
|
|
39
|
-
yield indexed_id, text
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
def get_data # :nodoc:
|
|
46
|
-
@generated_id ||= 0
|
|
47
|
-
@posts ||= WWW::Delicious.new(@username, @password).posts_recent(count: 100)
|
|
48
|
-
@posts.each do |post|
|
|
49
|
-
data = {
|
|
50
|
-
title: post.title,
|
|
51
|
-
tags: post.tags.join(' '),
|
|
52
|
-
url: post.url.to_s
|
|
53
|
-
}
|
|
54
|
-
@generated_id += 1
|
|
55
|
-
yield @generated_id, data
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
end
|
data/lib/picky/sources/mongo.rb
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
module Picky
|
|
2
|
-
|
|
3
|
-
module Sources
|
|
4
|
-
|
|
5
|
-
# Important note: We're not sure if this works already.
|
|
6
|
-
#
|
|
7
|
-
# A Mongo database source.
|
|
8
|
-
#
|
|
9
|
-
# Options:
|
|
10
|
-
# * url, db
|
|
11
|
-
# Example:
|
|
12
|
-
# Sources::Mongo.new(:collection1, :collection2, :url => 'localhost:28017', :db => 'testdatabase')
|
|
13
|
-
# Be sure to escape the URL properly, e.g. # => %23 in the databasename if needed
|
|
14
|
-
#
|
|
15
|
-
# and all the options of a <tt>RestClient::Resource</tt>.
|
|
16
|
-
# See http://github.com/archiloque/rest-client.
|
|
17
|
-
#
|
|
18
|
-
class Mongo < Base
|
|
19
|
-
|
|
20
|
-
# Raised when a Mongo source is instantiated without a valid uri.
|
|
21
|
-
#
|
|
22
|
-
# Important!
|
|
23
|
-
# You have to start your mongodb with --rest in order to use
|
|
24
|
-
# the rest / http interface
|
|
25
|
-
#
|
|
26
|
-
class NoDBGiven < StandardError; end
|
|
27
|
-
|
|
28
|
-
@@id_key = '_id'
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
def initialize *category_names, options
|
|
32
|
-
check_gem
|
|
33
|
-
|
|
34
|
-
unless options[:url] && options[:db]
|
|
35
|
-
raise_no_db_given(category_names)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
@db = RestClient::Resource.new options.delete(:url), options
|
|
39
|
-
@database = options.delete(:db)
|
|
40
|
-
@key_format = options[:key_format] && options[:key_format].intern || :to_s
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Tries to require the rest_client gem.
|
|
44
|
-
#
|
|
45
|
-
def check_gem # :nodoc:
|
|
46
|
-
require 'rest_client'
|
|
47
|
-
rescue LoadError
|
|
48
|
-
warn_gem_missing 'rest-client', 'the MongoDB source'
|
|
49
|
-
exit 1
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Fetches the data, @limit=0 will return all records
|
|
53
|
-
#
|
|
54
|
-
# Limit is set to 0 by default - all collection entries will be send
|
|
55
|
-
# If want to limit the results, set to to any other number, e.g. limit=15
|
|
56
|
-
# to return only 15 entries
|
|
57
|
-
#
|
|
58
|
-
def harvest category
|
|
59
|
-
collection = (category.from || category.index_name).to_s
|
|
60
|
-
resp = @db["/#{@database}/#{category.index_name}/?@limit=0"].get
|
|
61
|
-
JSON.parse(resp)['rows'].each do |row|
|
|
62
|
-
text = row[collection].to_s
|
|
63
|
-
next unless text
|
|
64
|
-
index_key = row.delete @@id_key # Note: I removed .values
|
|
65
|
-
yield index_key, text
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def raise_no_db_given category_names # :nodoc:
|
|
70
|
-
raise NoDBGiven.new(category_names.join(', '))
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def to_s
|
|
74
|
-
self.class.name
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
module Picky
|
|
2
|
-
module Wrappers
|
|
3
|
-
module Category
|
|
4
|
-
|
|
5
|
-
module Location
|
|
6
|
-
|
|
7
|
-
# THINK Is this the best way to do this?
|
|
8
|
-
#
|
|
9
|
-
def self.wrap category, grid, precision = 1, anchor = 0.0
|
|
10
|
-
wrapped_exact = Wrappers::Bundle::Location.new category.exact, grid: grid, precision: precision, anchor: anchor
|
|
11
|
-
|
|
12
|
-
category.class_eval do
|
|
13
|
-
|
|
14
|
-
# Uses a basic tokenizer.
|
|
15
|
-
#
|
|
16
|
-
def tokenizer
|
|
17
|
-
@tokenizer ||= Tokenizer.new
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Both use the exact index.
|
|
21
|
-
#
|
|
22
|
-
# TODO Necessary to wrap?
|
|
23
|
-
#
|
|
24
|
-
define_method :exact do
|
|
25
|
-
wrapped_exact
|
|
26
|
-
end
|
|
27
|
-
define_method :partial do
|
|
28
|
-
wrapped_exact
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
data/lib/tasks/routes.rake
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Picky::Adapters::Rack::Base do
|
|
6
|
-
|
|
7
|
-
before(:each) do
|
|
8
|
-
@adapter = described_class.new
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
describe 'respond_with' do
|
|
12
|
-
describe 'by default' do
|
|
13
|
-
it 'uses json' do
|
|
14
|
-
@adapter.respond_with('response').should ==
|
|
15
|
-
[200, { 'Content-Type' => 'application/json', 'Content-Length' => '8' }, ['response']]
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
it 'adapts the content length' do
|
|
19
|
-
@adapter.respond_with('123').should ==
|
|
20
|
-
[200, { 'Content-Type' => 'application/json', 'Content-Length' => '3' }, ['123']]
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Picky::Adapters::Rack::LiveParameters do
|
|
6
|
-
|
|
7
|
-
let(:live_parameters) { stub :live_parameters }
|
|
8
|
-
let(:adapter) { described_class.new live_parameters }
|
|
9
|
-
|
|
10
|
-
describe 'to_app' do
|
|
11
|
-
it 'works' do
|
|
12
|
-
lambda { adapter.to_app }.should_not raise_error
|
|
13
|
-
end
|
|
14
|
-
it 'returns the right thing' do
|
|
15
|
-
adapter.to_app.should respond_to(:call)
|
|
16
|
-
end
|
|
17
|
-
it 'returned lambda should call parameters on the live parameters' do
|
|
18
|
-
env = { 'rack.input' => 'some input' }
|
|
19
|
-
|
|
20
|
-
live_parameters.should_receive(:parameters).once.with({}).and_return Hash.new
|
|
21
|
-
|
|
22
|
-
adapter.to_app.call env
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Picky::Adapters::Rack::Search do
|
|
6
|
-
|
|
7
|
-
before(:each) do
|
|
8
|
-
@query = stub :query
|
|
9
|
-
@adapter = described_class.new @query
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
describe 'to_app' do
|
|
13
|
-
it 'works' do
|
|
14
|
-
lambda { @adapter.to_app }.should_not raise_error
|
|
15
|
-
end
|
|
16
|
-
it 'returns the right thing' do
|
|
17
|
-
@adapter.to_app.should respond_to(:call)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe 'extracted' do
|
|
22
|
-
it 'extracts the query' do
|
|
23
|
-
@adapter.extracted('query' => 'some_query')[0].should == 'some_query'
|
|
24
|
-
end
|
|
25
|
-
it 'extracts the default ids amount' do
|
|
26
|
-
@adapter.extracted('query' => 'some_query')[1].should == 20
|
|
27
|
-
end
|
|
28
|
-
it 'extracts the default offset' do
|
|
29
|
-
@adapter.extracted('query' => 'some_query')[2].should == 0
|
|
30
|
-
end
|
|
31
|
-
it 'extracts a given ids amount' do
|
|
32
|
-
@adapter.extracted('query' => 'some_query', 'ids' => '123')[1].should == 123
|
|
33
|
-
end
|
|
34
|
-
it 'extracts a given offset' do
|
|
35
|
-
@adapter.extracted('query' => 'some_query', 'offset' => '123')[2].should == 123
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
end
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Picky::Application do
|
|
6
|
-
|
|
7
|
-
describe "integration" do
|
|
8
|
-
it "should run ok" do
|
|
9
|
-
lambda {
|
|
10
|
-
class MinimalTestApplication < described_class
|
|
11
|
-
books = Picky::Index.new :books do
|
|
12
|
-
source Picky::Sources::DB.new(
|
|
13
|
-
'SELECT id, title FROM books',
|
|
14
|
-
:file => 'app/db.yml'
|
|
15
|
-
)
|
|
16
|
-
end
|
|
17
|
-
books.category :title
|
|
18
|
-
|
|
19
|
-
rack_adapter.stub! :exclaim # Stopping it from exclaiming.
|
|
20
|
-
|
|
21
|
-
route %r{^/books} => Picky::Search.new(books)
|
|
22
|
-
end
|
|
23
|
-
Picky::Tokenizer.index_default.tokenize 'some text'
|
|
24
|
-
Picky::Tokenizer.query_default.tokenize 'some text'
|
|
25
|
-
}.should_not raise_error
|
|
26
|
-
end
|
|
27
|
-
it "should run ok" do
|
|
28
|
-
lambda {
|
|
29
|
-
# Here we just test if the API can be called ok.
|
|
30
|
-
#
|
|
31
|
-
class TestApplication < described_class
|
|
32
|
-
indexing removes_characters: /[^a-zA-Z0-9\s\/\-\"\&\.]/,
|
|
33
|
-
stopwords: /\b(and|the|of|it|in|for)\b/,
|
|
34
|
-
splits_text_on: /[\s\/\-\"\&\.]/,
|
|
35
|
-
removes_characters_after_splitting: /[\.]/,
|
|
36
|
-
normalizes_words: [[/\$(\w+)/i, '\1 dollars']],
|
|
37
|
-
rejects_token_if: lambda { |token| token.blank? || token == :amistad }
|
|
38
|
-
|
|
39
|
-
searching removes_characters: /[^a-zA-Z0-9äöü\s\/\-\,\&\"\~\*\:]/,
|
|
40
|
-
stopwords: /\b(and|the|of|it|in|for)\b/,
|
|
41
|
-
splits_text_on: /[\s\/\-\,\&]+/,
|
|
42
|
-
normalizes_words: [[/Deoxyribonucleic Acid/i, 'DNA']],
|
|
43
|
-
|
|
44
|
-
substitutes_characters_with: Picky::CharacterSubstituters::WestEuropean.new,
|
|
45
|
-
maximum_tokens: 5
|
|
46
|
-
|
|
47
|
-
books_index = Picky::Index.new :books do
|
|
48
|
-
source Picky::Sources::DB.new(
|
|
49
|
-
'SELECT id, title, author, isbn13 as isbn FROM books',
|
|
50
|
-
:file => 'app/db.yml'
|
|
51
|
-
)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
books_index.category :title,
|
|
55
|
-
similarity: Picky::Similarity::DoubleMetaphone.new(3) # Up to three similar title word indexed.
|
|
56
|
-
books_index.category :author,
|
|
57
|
-
similarity: Picky::Similarity::Soundex.new(2)
|
|
58
|
-
books_index.category :isbn,
|
|
59
|
-
partial: Picky::Partial::None.new # Partially searching on an ISBN makes not much sense.
|
|
60
|
-
|
|
61
|
-
geo_index = Picky::Index.new :geo do
|
|
62
|
-
source Picky::Sources::CSV.new(:location, :north, :east, file: 'data/ch.csv', col_sep: ',')
|
|
63
|
-
indexing removes_characters: /[^a-z]/
|
|
64
|
-
category :location,
|
|
65
|
-
similarity: Picky::Similarity::Metaphone.new(4)
|
|
66
|
-
ranged_category :north1, 1, precision: 3, from: :north
|
|
67
|
-
ranged_category :east1, 1, precision: 3, from: :east
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
rack_adapter.stub! :exclaim # Stopping it from exclaiming.
|
|
71
|
-
|
|
72
|
-
route %r{^/books} => Picky::Search.new(books_index)
|
|
73
|
-
|
|
74
|
-
buks_search = Picky::Search.new(books_index) do
|
|
75
|
-
searching removes_characters: /[buks]/
|
|
76
|
-
ignore :author
|
|
77
|
-
end
|
|
78
|
-
route %r{^/buks} => buks_search
|
|
79
|
-
end
|
|
80
|
-
}.should_not raise_error
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
describe 'finalize' do
|
|
85
|
-
before(:each) do
|
|
86
|
-
described_class.stub! :check
|
|
87
|
-
end
|
|
88
|
-
it 'checks if all is ok' do
|
|
89
|
-
described_class.should_receive(:check).once.with
|
|
90
|
-
|
|
91
|
-
described_class.finalize
|
|
92
|
-
end
|
|
93
|
-
it 'tells the rack adapter to finalize' do
|
|
94
|
-
described_class.rack_adapter.should_receive(:finalize).once.with
|
|
95
|
-
|
|
96
|
-
described_class.finalize
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
describe 'check' do
|
|
101
|
-
it 'does something' do
|
|
102
|
-
described_class.should_receive(:warn).once.with "\nWARNING: No routes defined for application configuration in Class.\n\n"
|
|
103
|
-
|
|
104
|
-
described_class.check
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
describe 'delegation' do
|
|
109
|
-
it "should delegate route" do
|
|
110
|
-
described_class.rack_adapter.should_receive(:route).once.with :path => :query
|
|
111
|
-
|
|
112
|
-
described_class.route :path => :query
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
describe 'rack_adapter' do
|
|
117
|
-
it 'should be there' do
|
|
118
|
-
lambda { described_class.rack_adapter }.should_not raise_error
|
|
119
|
-
end
|
|
120
|
-
it "should return a new FrontendAdapters::Rack instance" do
|
|
121
|
-
described_class.rack_adapter.should be_kind_of(Picky::FrontendAdapters::Rack)
|
|
122
|
-
end
|
|
123
|
-
it "should cache the instance" do
|
|
124
|
-
described_class.rack_adapter.should == described_class.rack_adapter
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
describe 'route' do
|
|
129
|
-
it 'is delegated' do
|
|
130
|
-
described_class.rack_adapter.should_receive(:route).once.with :some_options
|
|
131
|
-
|
|
132
|
-
described_class.route(:some_options)
|
|
133
|
-
end
|
|
134
|
-
it 'raises on block' do
|
|
135
|
-
expect {
|
|
136
|
-
described_class.route :quack => Hash.new do # Anything with a block.
|
|
137
|
-
# do something
|
|
138
|
-
end
|
|
139
|
-
}.to raise_error("Warning: block passed into #route method, not into Search.new!")
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
describe 'call' do
|
|
144
|
-
before(:each) do
|
|
145
|
-
@routes = stub :routes
|
|
146
|
-
described_class.stub! :rack_adapter => @routes
|
|
147
|
-
end
|
|
148
|
-
it 'should delegate' do
|
|
149
|
-
@routes.should_receive(:call).once.with :env
|
|
150
|
-
|
|
151
|
-
described_class.call :env
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
end
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Picky::FrontendAdapters::Rack do
|
|
6
|
-
|
|
7
|
-
before(:each) do
|
|
8
|
-
@rack_adapter = described_class.new
|
|
9
|
-
@rack_adapter.stub! :exclaim
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def rack_defaults_for url
|
|
13
|
-
url, query_string = url.split ??
|
|
14
|
-
|
|
15
|
-
{ "GATEWAY_INTERFACE"=>"CGI/1.1",
|
|
16
|
-
"PATH_INFO"=>"#{url}",
|
|
17
|
-
"QUERY_STRING"=>"#{query_string}",
|
|
18
|
-
"REMOTE_ADDR"=>"127.0.0.1",
|
|
19
|
-
"REMOTE_HOST"=>"localhost",
|
|
20
|
-
"REQUEST_METHOD"=>"GET",
|
|
21
|
-
"REQUEST_URI"=>"http://localhost:3001#{url}",
|
|
22
|
-
"SCRIPT_NAME"=>"",
|
|
23
|
-
"SERVER_NAME"=>"localhost",
|
|
24
|
-
"SERVER_PORT"=>"3001",
|
|
25
|
-
"SERVER_PROTOCOL"=>"HTTP/1.1",
|
|
26
|
-
"SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/1.9.2/2010-07-11)",
|
|
27
|
-
"HTTP_HOST"=>"localhost:3001",
|
|
28
|
-
"HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/533.16 (KHTML like Gecko) Version/5.0 Safari/533.16",
|
|
29
|
-
"HTTP_ACCEPT"=>"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
|
|
30
|
-
"HTTP_CACHE_CONTROL"=>"max-age=0",
|
|
31
|
-
"HTTP_ACCEPT_LANGUAGE"=>"en-us",
|
|
32
|
-
"HTTP_ACCEPT_ENCODING"=>"gzip,
|
|
33
|
-
deflate",
|
|
34
|
-
"HTTP_COOKIE"=>"__utma=111872281.1536032598.1255697925.1255697925.1255697925.1; _jsuid=8971917605087477351; locale=de",
|
|
35
|
-
"HTTP_CONNECTION"=>"keep-alive",
|
|
36
|
-
"rack.input"=>'' }
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
context 'empty?' do
|
|
40
|
-
context 'no routes' do
|
|
41
|
-
before(:each) do
|
|
42
|
-
@rack_adapter.reset_routes
|
|
43
|
-
end
|
|
44
|
-
it 'returns the right answer' do
|
|
45
|
-
@rack_adapter.empty?.should == true
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
context 'with routes' do
|
|
49
|
-
before(:each) do
|
|
50
|
-
@rack_adapter.route %r{something} => Picky::Search.new
|
|
51
|
-
end
|
|
52
|
-
it 'returns the right answer' do
|
|
53
|
-
@rack_adapter.empty?.should == false
|
|
54
|
-
end
|
|
55
|
-
describe 'to_s' do
|
|
56
|
-
it 'outputs correctly' do
|
|
57
|
-
@rack_adapter.to_s.should == "Note: Anchored (✓) regexps are faster, e.g. /\\A.*\\Z/ or /^.*$/.\n\n something => Picky::Search(weights: Picky::Query::Weights({}))"
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
context 'real routes' do
|
|
64
|
-
before(:each) do
|
|
65
|
-
@rack_adapter.reset_routes
|
|
66
|
-
Picky.logger.stub! :info
|
|
67
|
-
end
|
|
68
|
-
it 'should route correctly' do
|
|
69
|
-
env = {}
|
|
70
|
-
|
|
71
|
-
@rack_adapter.routes.freeze
|
|
72
|
-
@rack_adapter.call(env).should == [404, {"Content-Type" => "text/html", "X-Cascade" => "pass"}, ["Not Found"]]
|
|
73
|
-
end
|
|
74
|
-
it 'should route correctly' do
|
|
75
|
-
env = rack_defaults_for '/'
|
|
76
|
-
|
|
77
|
-
@rack_adapter.root 200
|
|
78
|
-
|
|
79
|
-
@rack_adapter.routes.freeze
|
|
80
|
-
@rack_adapter.call(env).should == [200, {"Content-Type"=>"text/html", "Content-Length"=>"0"}, ['']]
|
|
81
|
-
end
|
|
82
|
-
it 'should route correctly' do
|
|
83
|
-
env = rack_defaults_for '/blarf'
|
|
84
|
-
|
|
85
|
-
@rack_adapter.default 200
|
|
86
|
-
|
|
87
|
-
@rack_adapter.routes.freeze
|
|
88
|
-
@rack_adapter.call(env).should == [200, {"Content-Type"=>"text/html", "Content-Length"=>"0"}, ['']]
|
|
89
|
-
end
|
|
90
|
-
it 'should route correctly' do
|
|
91
|
-
env = rack_defaults_for '/gurk'
|
|
92
|
-
|
|
93
|
-
@rack_adapter.answer %r{/gurk}, lambda { |env| [333, {}, ['this is gurk']] }
|
|
94
|
-
|
|
95
|
-
@rack_adapter.routes.freeze
|
|
96
|
-
@rack_adapter.call(env).should == [333, {}, ['this is gurk']]
|
|
97
|
-
end
|
|
98
|
-
it 'should route correctly' do
|
|
99
|
-
env = rack_defaults_for '/gurk'
|
|
100
|
-
|
|
101
|
-
@rack_adapter.answer '/gurk', lambda { |env| [333, {}, ['this is gurk']] }
|
|
102
|
-
|
|
103
|
-
@rack_adapter.routes.freeze
|
|
104
|
-
@rack_adapter.call(env).should == [333, {}, ['this is gurk']]
|
|
105
|
-
end
|
|
106
|
-
it 'should route correctly' do
|
|
107
|
-
env = rack_defaults_for '/searches/some_route?query=some_query'
|
|
108
|
-
|
|
109
|
-
search = stub :search
|
|
110
|
-
search.should_receive(:search).once.with(anything, 20, 0).and_return(Picky::Results.new)
|
|
111
|
-
Picky::Search.stub! :new => search
|
|
112
|
-
|
|
113
|
-
@rack_adapter.route '/searches/some_route' => Picky::Search.new(:some_index, :some_other_index)
|
|
114
|
-
|
|
115
|
-
@rack_adapter.routes.freeze
|
|
116
|
-
@rack_adapter.call(env).should == [200, {"Content-Type"=>"application/json", "Content-Length"=>"52"}, ["{\"allocations\":[],\"offset\":0,\"duration\":0,\"total\":0}"]]
|
|
117
|
-
end
|
|
118
|
-
it 'should route correctly' do
|
|
119
|
-
env = rack_defaults_for '/searches/some_route?query=some_query&type=some_type'
|
|
120
|
-
|
|
121
|
-
search = stub :search
|
|
122
|
-
search.should_receive(:search).once.with(anything, 20, 0).and_return(Picky::Results.new)
|
|
123
|
-
Picky::Search.stub! :new => search
|
|
124
|
-
|
|
125
|
-
@rack_adapter.route '/searches/some_route' => Picky::Search.new(:some_index, :some_other_index), :query => { :type => :some_type }
|
|
126
|
-
|
|
127
|
-
@rack_adapter.routes.freeze
|
|
128
|
-
@rack_adapter.call(env).should == [200, {"Content-Type"=>"application/json", "Content-Length"=>"52"}, ["{\"allocations\":[],\"offset\":0,\"duration\":0,\"total\":0}"]]
|
|
129
|
-
end
|
|
130
|
-
it 'should route correctly' do
|
|
131
|
-
env = rack_defaults_for '/searches/some_wrong_route?query=some_query'
|
|
132
|
-
|
|
133
|
-
search = stub :search
|
|
134
|
-
search.should_receive(:search).never
|
|
135
|
-
Picky::Search.stub! :new => search
|
|
136
|
-
|
|
137
|
-
@rack_adapter.route '/searches/some_route' => Picky::Search.new(:some_index, :some_other_index)
|
|
138
|
-
|
|
139
|
-
@rack_adapter.routes.freeze
|
|
140
|
-
@rack_adapter.call(env).should == [404, {"Content-Type"=>"text/html", "X-Cascade"=>"pass"}, ["Not Found"]]
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
describe 'to_s' do
|
|
145
|
-
context 'no routes' do
|
|
146
|
-
it 'outputs correctly' do
|
|
147
|
-
@rack_adapter.to_s.should == "Note: Anchored (✓) regexps are faster, e.g. /\\A.*\\Z/ or /^.*$/.\n\n"
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
context 'stubbed routes' do
|
|
153
|
-
before(:each) do
|
|
154
|
-
@routes = stub :routes
|
|
155
|
-
@rack_adapter.stub! :routes => @routes
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
describe 'generate_query_string' do
|
|
159
|
-
it 'should not allow an empty query condition' do
|
|
160
|
-
lambda {
|
|
161
|
-
@rack_adapter.generate_query_string({}).should == 'this=must_be'
|
|
162
|
-
}.should raise_error "At least one query string condition is needed."
|
|
163
|
-
end
|
|
164
|
-
it 'should handle a single condition' do
|
|
165
|
-
@rack_adapter.generate_query_string(:this => :must_be).should == 'this=must_be'
|
|
166
|
-
end
|
|
167
|
-
it 'should not allow multiple query strings' do
|
|
168
|
-
lambda {
|
|
169
|
-
@rack_adapter.generate_query_string(:this => :must_be, :that => :should_be).should == 'this=must_be|that=should_be'
|
|
170
|
-
}.should raise_error "Too many query param conditions (only 1 allowed): {:this=>:must_be, :that=>:should_be}"
|
|
171
|
-
end
|
|
172
|
-
it 'should be sanity checked' do
|
|
173
|
-
'/searches/some_route?query=some_query&type=some_type'.should match(%r{#{"type=some_type"}})
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
describe "route" do
|
|
178
|
-
it "should delegate correctly" do
|
|
179
|
-
@rack_adapter.should_receive(:route_one).once.with %r{regexp1}, :query1, {}
|
|
180
|
-
@rack_adapter.should_receive(:route_one).once.with %r{regexp2}, :query2, {}
|
|
181
|
-
|
|
182
|
-
@rack_adapter.route %r{regexp1} => :query1, %r{regexp2} => :query2
|
|
183
|
-
end
|
|
184
|
-
it "should split options correctly" do
|
|
185
|
-
@rack_adapter.should_receive(:route_one).once.with %r{regexp1}, :query1, :some => :option
|
|
186
|
-
@rack_adapter.should_receive(:route_one).once.with %r{regexp2}, :query2, :some => :option
|
|
187
|
-
|
|
188
|
-
@rack_adapter.route %r{regexp1} => :query1, %r{regexp2} => :query2, :some => :option
|
|
189
|
-
end
|
|
190
|
-
it 'does not accept nil queries' do
|
|
191
|
-
lambda { @rack_adapter.route %r{some/regexp} => nil }.should raise_error(Picky::FrontendAdapters::Rack::RouteTargetNilError, /Routing for \/some\\\/regexp\/ was defined with a nil target object, i.e. \/some\\\/regexp\/ => nil./)
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
describe 'finalize' do
|
|
196
|
-
before(:each) do
|
|
197
|
-
@rack_adapter.routes.should_receive(:freeze).once.with
|
|
198
|
-
|
|
199
|
-
@rack_adapter.finalize
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
describe 'route_one' do
|
|
204
|
-
before(:each) do
|
|
205
|
-
Picky::Adapters::Rack.stub! :app_for => :some_query_app
|
|
206
|
-
end
|
|
207
|
-
it 'should add the right route' do
|
|
208
|
-
@routes.should_receive(:add_route).once.with :some_query_app, { :request_method => "GET", :path_info => /some_url/ }, {}, "some_query"
|
|
209
|
-
|
|
210
|
-
@rack_adapter.route_one %r{some_url}, :some_query, {}
|
|
211
|
-
end
|
|
212
|
-
it 'should add the right route' do
|
|
213
|
-
@routes.should_receive(:add_route).once.with :some_query_app, { :request_method => "GET", :path_info => /some_url/ }, {}, "some_query"
|
|
214
|
-
|
|
215
|
-
@rack_adapter.route_one 'some_url', :some_query, {}
|
|
216
|
-
end
|
|
217
|
-
it 'should add the right route' do
|
|
218
|
-
@routes.should_receive(:add_route).once.with :some_query_app, { :request_method => "GET", :glarf => :blarf, :path_info => /some_url/ }, {}, "some_query"
|
|
219
|
-
|
|
220
|
-
@rack_adapter.route_one 'some_url', :some_query, { :glarf => :blarf }
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
describe 'default' do
|
|
225
|
-
it 'should call answer' do
|
|
226
|
-
@rack_adapter.should_receive(:answer).once.with nil, Picky::FrontendAdapters::Rack::STATUSES[200]
|
|
227
|
-
|
|
228
|
-
@rack_adapter.default 200
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
describe 'STATUSES' do
|
|
233
|
-
it 'is a lambda' do
|
|
234
|
-
Picky::FrontendAdapters::Rack::STATUSES[200].respond_to?(:call).should == true
|
|
235
|
-
end
|
|
236
|
-
it 'is a lambda' do
|
|
237
|
-
Picky::FrontendAdapters::Rack::STATUSES[404].respond_to?(:call).should == true
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
describe 'root' do
|
|
242
|
-
it 'should call answer' do
|
|
243
|
-
@rack_adapter.should_receive(:answer).once.with %r{^/$}, Picky::FrontendAdapters::Rack::STATUSES[200]
|
|
244
|
-
|
|
245
|
-
@rack_adapter.root 200
|
|
246
|
-
end
|
|
247
|
-
it 'should call answer' do
|
|
248
|
-
@rack_adapter.should_receive(:answer).once.with %r{^/$}, Picky::FrontendAdapters::Rack::STATUSES[404]
|
|
249
|
-
|
|
250
|
-
@rack_adapter.root 404
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
describe 'answer' do
|
|
255
|
-
context 'with app' do
|
|
256
|
-
before(:each) do
|
|
257
|
-
@app = stub :app
|
|
258
|
-
end
|
|
259
|
-
context 'with url' do
|
|
260
|
-
it 'should use the app with default_options from the url' do
|
|
261
|
-
@routes.should_receive(:add_route).once.with @app, { :request_method => "GET", :path_info => /some_url/ }
|
|
262
|
-
|
|
263
|
-
@rack_adapter.answer 'some_url', @app
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
|
-
context 'without url' do
|
|
267
|
-
it 'should use the app with default_options' do
|
|
268
|
-
@routes.should_receive(:add_route).once.with @app, { :request_method => "GET" }
|
|
269
|
-
|
|
270
|
-
@rack_adapter.answer nil, @app
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
context 'without app' do
|
|
275
|
-
context 'with url' do
|
|
276
|
-
it 'should use the 200 with default_options from the url' do
|
|
277
|
-
@routes.should_receive(:add_route).once.with Picky::FrontendAdapters::Rack::STATUSES[200], { :request_method => "GET", :path_info => /some_url/ }
|
|
278
|
-
|
|
279
|
-
@rack_adapter.answer 'some_url'
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
context 'without url' do
|
|
283
|
-
it 'should use the 200 with default_options' do
|
|
284
|
-
@routes.should_receive(:add_route).once.with Picky::FrontendAdapters::Rack::STATUSES[200], { :request_method => "GET" }
|
|
285
|
-
|
|
286
|
-
@rack_adapter.answer
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
end
|