lexster 0.0.1

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.
@@ -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