lexster 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexster::ModelAdditions do
4
+ context "search" do
5
+ let(:index_name) { "articles_search_index_#{Time.now.to_f.to_s.gsub('.', '')}" }
6
+
7
+ it "should index and find node in fulltext" do
8
+ Lexster.db.create_node_index(index_name, "fulltext", "lucene")
9
+
10
+ n = Neography::Node.create(name: "test hello world", year: 2012)
11
+ Lexster.db.add_node_to_index(index_name, "name", n.name, n)
12
+ Lexster.db.add_node_to_index(index_name, "year", n.year, n)
13
+
14
+ [
15
+ "name:test",
16
+ "year:2012",
17
+ "name:test AND year:2012"
18
+ ].each { |q|
19
+ results = Lexster.db.find_node_index(index_name, q)
20
+ results.length.should == 1
21
+ Lexster.db.send(:get_id, results).should == n.neo_id
22
+ }
23
+ end
24
+
25
+ it "should index item on save" do
26
+ r = rand(1000000)
27
+ article = Article.create!(title: "Hello world #{r}", body: "Lorem ipsum dolor sit amet", year: r)
28
+
29
+ [
30
+ "title:#{r}",
31
+ "year:#{r}",
32
+ "title:#{r} AND year:#{r}"
33
+ ].each do |q|
34
+ results = Lexster.db.find_node_index(Lexster::DEFAULT_FULLTEXT_SEARCH_INDEX_NAME, q)
35
+
36
+ results.should_not be_nil
37
+ results.length.should == 1
38
+ Lexster.db.send(:get_id, results).should == article.neo_node.neo_id
39
+ end
40
+ end
41
+
42
+ context "search session" do
43
+ it "should return a search session" do
44
+ Article.neo_search("hello").should be_a(Lexster::SearchSession)
45
+ end
46
+
47
+ it "should find hits" do
48
+ article = Article.create!(title: "Hello world", body: "Lorem ipsum dolor sit amet", year: 2012)
49
+
50
+ Article.neo_search("hello").hits.should == [ article.neo_node ]
51
+ end
52
+
53
+ it "should find results with a search string" do
54
+ article = Article.create!(title: "Hello world", body: "Lorem ipsum dolor sit amet", year: 2012)
55
+
56
+ Article.neo_search("hello").results.should == [ article ]
57
+ end
58
+
59
+ it "should find results with a hash" do
60
+ articles = [
61
+ Article.create!(title: "How to draw manga", body: "Lorem ipsum dolor sit amet", year: 2012),
62
+ Article.create!(title: "Manga x", body: "Lorem ipsum dolor sit amet", year: 2013)
63
+ ]
64
+
65
+
66
+ Article.neo_search(year: 2012).results.should == [ articles[0] ]
67
+ end
68
+ end
69
+
70
+ context "search in multiple types" do
71
+ before :each do
72
+ @articles = [
73
+ Article.create!(title: "How to draw manga", body: "Lorem ipsum dolor sit amet", year: 2012),
74
+ Article.create!(title: "Manga x", body: "Lorem ipsum dolor sit amet", year: 2012)
75
+ ]
76
+
77
+ @movies = [
78
+ Movie.create!(name: "Anime is not Manga", slug: "anime")
79
+ ]
80
+ end
81
+
82
+ it "should search in multiple types" do
83
+ Lexster.search([Article, Movie], "manga").results.should =~ @articles + @movies
84
+ end
85
+
86
+ it "should search in single type when specified" do
87
+ Lexster.search([Article], "manga").results.should =~ @articles
88
+ end
89
+ end
90
+
91
+ context "search matching types" do
92
+ before :each do
93
+ @articles = [
94
+ Article.create!(title: "Comics: How to draw manga", body: "Lorem ipsum dolor sit amet", year: 2012),
95
+ Article.create!(title: "Manga x", body: "Lorem ipsum dolor sit amet", year: 2012),
96
+ Article.create!(title: "hidden secrets of comics masters", body: "Lorem ipsum dolor sit amet", year: 2012),
97
+ Article.create!(title: "hidden secrets of manga comics artists", body: "Lorem ipsum dolor sit amet", year: 2012)
98
+ ]
99
+ end
100
+
101
+ it "should return search results only matches with AND" do
102
+ Lexster.search([Article],"manga comics").results.size.should eq(1)
103
+
104
+ Lexster.search([Article],"manga comics",{match_type: "AND"}).results.size.should eq(1)
105
+ end
106
+
107
+ it "should return search results all results with OR" do
108
+ Lexster.search([Article],"manga comics",{match_type: "OR"}).results.size.should eq(4)
109
+ end
110
+
111
+ it "should fail with wrong match_type" do
112
+ expect {Lexster.search([Article],"manga comics",{match_type: "MAYBE"})}.to raise_error("Invalid match_type option. Valid values are AND,OR")
113
+ end
114
+
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexster do
4
+ context "subrefs" do
5
+ it "should create all subrefs on initialization" do
6
+ Lexster.node_models.each do |klass|
7
+ klass.instance_variable_get(:@neo_subref_node).should_not be_nil
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ require 'lexster'
2
+ require 'active_record'
3
+ require 'neography'
4
+ require 'rest-client'
5
+
6
+ # ENV['NEOID_LOG'] = 'true'
7
+
8
+ uri = URI.parse(ENV["NEO4J_URL"] ? ENV["NEO4J_URL"] : ENV['TRAVIS'] ? "http://localhost:7474" : "http://localhost:7574")
9
+ $neo = Neography::Rest.new(uri.to_s)
10
+
11
+ Neography.configure do |c|
12
+ c.server = uri.host
13
+ c.port = uri.port
14
+
15
+ if uri.user && uri.password
16
+ c.authentication = 'basic'
17
+ c.username = uri.user
18
+ c.password = uri.password
19
+ end
20
+ end
21
+
22
+ Lexster.db = $neo
23
+
24
+ logger, ActiveRecord::Base.logger = ActiveRecord::Base.logger, Logger.new('/dev/null')
25
+ ActiveRecord::Base.configurations = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'support/database.yml')))
26
+ ActiveRecord::Base.establish_connection('sqlite3')
27
+
28
+ require 'support/schema'
29
+ require 'support/models'
30
+
31
+ ActiveRecord::Base.logger = logger
32
+
33
+ RSpec.configure do |config|
34
+ config.mock_with :rspec
35
+
36
+ config.before(:all) do
37
+ end
38
+
39
+ config.before(:each) do
40
+ Lexster.node_models.each(&:destroy_all)
41
+ Lexster.clean_db(:yes_i_am_sure)
42
+ Lexster.reset_cached_variables
43
+ end
44
+ end
45
+
46
+ Lexster.initialize_all
@@ -0,0 +1,6 @@
1
+ sqlite3:
2
+ adapter: sqlite3
3
+ database: ":memory:"
4
+ encoding: utf8
5
+ charset: utf8
6
+ timeout: 5000
@@ -0,0 +1,106 @@
1
+ class User < ActiveRecord::Base
2
+ include ActiveModel::Validations::Callbacks
3
+
4
+ has_many :likes
5
+ has_many :movies, through: :likes
6
+
7
+ has_many :user_follows
8
+
9
+ def likes?(movie)
10
+ likes.where(movie_id: movie.id).exists?
11
+ end
12
+
13
+ def like!(movie)
14
+ movies << movie unless likes?(movie)
15
+ likes.where(movie_id: movie.id).first
16
+ end
17
+
18
+ def unlike!(movie)
19
+ likes.where(movie_id: movie.id, user_id: self.id).destroy_all
20
+ end
21
+
22
+ include Lexster::Node
23
+
24
+ lexsterable do |c|
25
+ c.field :name
26
+ c.field :slug
27
+ end
28
+ end
29
+
30
+ class Movie < ActiveRecord::Base
31
+ include ActiveModel::Validations::Callbacks
32
+
33
+ has_many :likes
34
+ has_many :users, through: :likes
35
+
36
+ include Lexster::Node
37
+
38
+ lexsterable do |c|
39
+ c.field :name
40
+ c.field :slug
41
+ c.field :year
42
+
43
+ c.search do |s|
44
+ s.fulltext :name
45
+
46
+ s.index :name
47
+ s.index :slug
48
+ s.index :year
49
+ end
50
+ end
51
+ end
52
+
53
+ class UserFollow < ActiveRecord::Base
54
+ include ActiveModel::Validations::Callbacks
55
+
56
+ belongs_to :user
57
+ belongs_to :item, polymorphic: true
58
+
59
+ include Lexster::Relationship
60
+
61
+ lexsterable do |c|
62
+ c.relationship start_node: :user, end_node: :item, type: :follows
63
+ end
64
+ end
65
+
66
+ class Like < ActiveRecord::Base
67
+ include ActiveModel::Validations::Callbacks
68
+
69
+ belongs_to :user
70
+ belongs_to :movie
71
+
72
+ include Lexster::Relationship
73
+
74
+ lexsterable do |c|
75
+ c.relationship start_node: :user, end_node: :movie, type: :likes
76
+ c.field :rate
77
+ end
78
+ end
79
+
80
+ class Article < ActiveRecord::Base
81
+ include ActiveModel::Validations::Callbacks
82
+ include Lexster::Node
83
+ lexsterable do |c|
84
+ c.field :title
85
+ c.field :year
86
+ c.field :title_length do
87
+ self.title ? self.title.length : 0
88
+ end
89
+
90
+ c.search do |s|
91
+ s.fulltext :title
92
+
93
+ s.index :title
94
+ s.index :body
95
+ s.index :year
96
+ end
97
+ end
98
+ end
99
+
100
+ class NoAutoIndexNode < ActiveRecord::Base
101
+ include ActiveModel::Validations::Callbacks
102
+ include Lexster::Node
103
+ lexsterable auto_index: false do |c|
104
+ c.field :name
105
+ end
106
+ end
@@ -0,0 +1,44 @@
1
+ ActiveRecord::Schema.define :version => 0 do
2
+ create_table :users do |t|
3
+ t.string :name
4
+ t.string :slug
5
+
6
+ t.timestamps
7
+ end
8
+
9
+ create_table :movies do |t|
10
+ t.string :name
11
+ t.string :slug
12
+ t.integer :year
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ create_table :likes do |t|
18
+ t.integer :user_id
19
+ t.integer :movie_id
20
+ t.integer :rate
21
+
22
+ t.timestamps
23
+ end
24
+
25
+
26
+ create_table :articles do |t|
27
+ t.string :title
28
+ t.string :body
29
+ t.integer :year
30
+
31
+ t.timestamps
32
+ end
33
+
34
+ create_table :user_follows do |t|
35
+ t.belongs_to :user
36
+ t.belongs_to :item, polymorphic: true
37
+
38
+ t.timestamps
39
+ end
40
+
41
+ create_table :no_auto_index_nodes do |t|
42
+ t.string :name
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lexster
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nelson Wittwer, Elad Ossadon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: neography
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Extend Ruby on Rails ActiveRecord with Titan nodes. Keep RDBMS and utilize
98
+ the power of Gremlin queries. Fork of Neoid.
99
+ email:
100
+ - nelsonwittwer@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - .rspec
107
+ - .travis.yml
108
+ - CHANGELOG.md
109
+ - Gemfile
110
+ - LICENSE
111
+ - README.md
112
+ - Rakefile
113
+ - TODO.md
114
+ - lexster.gemspec
115
+ - lib/lexster.rb
116
+ - lib/lexster/batch.rb
117
+ - lib/lexster/config.rb
118
+ - lib/lexster/database_cleaner.rb
119
+ - lib/lexster/middleware.rb
120
+ - lib/lexster/model_additions.rb
121
+ - lib/lexster/model_config.rb
122
+ - lib/lexster/node.rb
123
+ - lib/lexster/railtie.rb
124
+ - lib/lexster/relationship.rb
125
+ - lib/lexster/search_session.rb
126
+ - lib/lexster/version.rb
127
+ - spec/lexster/batch_spec.rb
128
+ - spec/lexster/config_spec.rb
129
+ - spec/lexster/model_config_spec.rb
130
+ - spec/lexster/node_spec.rb
131
+ - spec/lexster/relationship_spec.rb
132
+ - spec/lexster/search_spec.rb
133
+ - spec/lexster_spec.rb
134
+ - spec/spec_helper.rb
135
+ - spec/support/database.yml
136
+ - spec/support/models.rb
137
+ - spec/support/schema.rb
138
+ homepage: ''
139
+ licenses: []
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project: lexster
157
+ rubygems_version: 2.1.9
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Titan for ActiveRecord
161
+ test_files:
162
+ - spec/lexster/batch_spec.rb
163
+ - spec/lexster/config_spec.rb
164
+ - spec/lexster/model_config_spec.rb
165
+ - spec/lexster/node_spec.rb
166
+ - spec/lexster/relationship_spec.rb
167
+ - spec/lexster/search_spec.rb
168
+ - spec/lexster_spec.rb
169
+ - spec/spec_helper.rb
170
+ - spec/support/database.yml
171
+ - spec/support/models.rb
172
+ - spec/support/schema.rb