indexers 4.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +313 -0
  4. data/Rakefile +19 -0
  5. data/lib/generators/indexers/indexer/indexer_generator.rb +23 -0
  6. data/lib/generators/indexers/indexer/templates/indexer.rb +12 -0
  7. data/lib/generators/indexers/install/install_generator.rb +19 -0
  8. data/lib/generators/indexers/install/templates/configuration.yml +15 -0
  9. data/lib/generators/indexers/install/templates/initializer.rb +6 -0
  10. data/lib/indexers/collection.rb +181 -0
  11. data/lib/indexers/computed_sorts.rb +19 -0
  12. data/lib/indexers/concern.rb +30 -0
  13. data/lib/indexers/configuration.rb +35 -0
  14. data/lib/indexers/definitions.rb +24 -0
  15. data/lib/indexers/dsl/api.rb +94 -0
  16. data/lib/indexers/dsl/mappings.rb +14 -0
  17. data/lib/indexers/dsl/search.rb +29 -0
  18. data/lib/indexers/dsl/serialization.rb +17 -0
  19. data/lib/indexers/dsl/traitable.rb +38 -0
  20. data/lib/indexers/extensions/active_record/base.rb +20 -0
  21. data/lib/indexers/indexer.rb +132 -0
  22. data/lib/indexers/pagination.rb +33 -0
  23. data/lib/indexers/proxy.rb +22 -0
  24. data/lib/indexers/railtie.rb +23 -0
  25. data/lib/indexers/version.rb +5 -0
  26. data/lib/indexers.rb +82 -0
  27. data/lib/tasks/indexers.rake +16 -0
  28. data/test/dsl_test.rb +127 -0
  29. data/test/dummy/Rakefile +5 -0
  30. data/test/dummy/app/assets/javascripts/application.js +13 -0
  31. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  32. data/test/dummy/app/controllers/application_controller.rb +5 -0
  33. data/test/dummy/app/helpers/application_helper.rb +2 -0
  34. data/test/dummy/app/indexers/product_indexer.rb +55 -0
  35. data/test/dummy/app/indexers/shop_indexer.rb +28 -0
  36. data/test/dummy/app/models/product.rb +5 -0
  37. data/test/dummy/app/models/shop.rb +5 -0
  38. data/test/dummy/app/views/layouts/application.html.erb +12 -0
  39. data/test/dummy/bin/bundle +4 -0
  40. data/test/dummy/bin/rails +5 -0
  41. data/test/dummy/bin/rake +5 -0
  42. data/test/dummy/bin/setup +30 -0
  43. data/test/dummy/config/application.rb +25 -0
  44. data/test/dummy/config/boot.rb +5 -0
  45. data/test/dummy/config/database.yml +10 -0
  46. data/test/dummy/config/database.yml.travis +3 -0
  47. data/test/dummy/config/elasticsearch.yml +15 -0
  48. data/test/dummy/config/environment.rb +5 -0
  49. data/test/dummy/config/environments/development.rb +41 -0
  50. data/test/dummy/config/environments/production.rb +79 -0
  51. data/test/dummy/config/environments/test.rb +42 -0
  52. data/test/dummy/config/initializers/assets.rb +11 -0
  53. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  54. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  55. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  56. data/test/dummy/config/initializers/indexers.rb +65 -0
  57. data/test/dummy/config/initializers/inflections.rb +16 -0
  58. data/test/dummy/config/initializers/mime_types.rb +4 -0
  59. data/test/dummy/config/initializers/session_store.rb +3 -0
  60. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  61. data/test/dummy/config/locales/en.yml +23 -0
  62. data/test/dummy/config/routes.rb +56 -0
  63. data/test/dummy/config/secrets.yml +22 -0
  64. data/test/dummy/config.ru +4 -0
  65. data/test/dummy/db/migrate/20161104164148_create_products.rb +14 -0
  66. data/test/dummy/db/migrate/20161104182219_create_shops.rb +9 -0
  67. data/test/dummy/db/schema.rb +36 -0
  68. data/test/dummy/log/development.log +114 -0
  69. data/test/dummy/log/test.log +20986 -0
  70. data/test/dummy/public/404.html +61 -0
  71. data/test/dummy/public/422.html +61 -0
  72. data/test/dummy/public/500.html +60 -0
  73. data/test/dummy/public/favicon.ico +0 -0
  74. data/test/generator_test.rb +26 -0
  75. data/test/index_test.rb +42 -0
  76. data/test/record_test.rb +25 -0
  77. data/test/search_test.rb +164 -0
  78. data/test/task_test.rb +31 -0
  79. data/test/test_helper.rb +14 -0
  80. metadata +237 -0
@@ -0,0 +1,61 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+ div.dialog {
15
+ width: 95%;
16
+ max-width: 33em;
17
+ margin: 4em auto 0;
18
+ }
19
+ div.dialog > div {
20
+ border: 1px solid #CCC;
21
+ border-right-color: #999;
22
+ border-left-color: #999;
23
+ border-bottom-color: #BBB;
24
+ border-top: #B00100 solid 4px;
25
+ border-top-left-radius: 9px;
26
+ border-top-right-radius: 9px;
27
+ background-color: white;
28
+ padding: 7px 12% 0;
29
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
30
+ }
31
+ h1 {
32
+ font-size: 100%;
33
+ color: #730E15;
34
+ line-height: 1.5em;
35
+ }
36
+ div.dialog > p {
37
+ margin: 0 0 1em;
38
+ padding: 1em;
39
+ background-color: #F7F7F7;
40
+ border: 1px solid #CCC;
41
+ border-right-color: #999;
42
+ border-left-color: #999;
43
+ border-bottom-color: #999;
44
+ border-bottom-left-radius: 4px;
45
+ border-bottom-right-radius: 4px;
46
+ border-top-color: #DADADA;
47
+ color: #666;
48
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <div class="dialog">
54
+ <div>
55
+ <h1>The page you were looking for doesn't exist.</h1>
56
+ <p>You may have mistyped the address or the page may have moved.</p>
57
+ </div>
58
+ <p>If you are the application owner check the logs for more information.</p>
59
+ </div>
60
+ </body>
61
+ </html>
@@ -0,0 +1,61 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+ div.dialog {
15
+ width: 95%;
16
+ max-width: 33em;
17
+ margin: 4em auto 0;
18
+ }
19
+ div.dialog > div {
20
+ border: 1px solid #CCC;
21
+ border-right-color: #999;
22
+ border-left-color: #999;
23
+ border-bottom-color: #BBB;
24
+ border-top: #B00100 solid 4px;
25
+ border-top-left-radius: 9px;
26
+ border-top-right-radius: 9px;
27
+ background-color: white;
28
+ padding: 7px 12% 0;
29
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
30
+ }
31
+ h1 {
32
+ font-size: 100%;
33
+ color: #730E15;
34
+ line-height: 1.5em;
35
+ }
36
+ div.dialog > p {
37
+ margin: 0 0 1em;
38
+ padding: 1em;
39
+ background-color: #F7F7F7;
40
+ border: 1px solid #CCC;
41
+ border-right-color: #999;
42
+ border-left-color: #999;
43
+ border-bottom-color: #999;
44
+ border-bottom-left-radius: 4px;
45
+ border-bottom-right-radius: 4px;
46
+ border-top-color: #DADADA;
47
+ color: #666;
48
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <div class="dialog">
54
+ <div>
55
+ <h1>The change you wanted was rejected.</h1>
56
+ <p>Maybe you tried to change something you didn't have access to.</p>
57
+ </div>
58
+ <p>If you are the application owner check the logs for more information.</p>
59
+ </div>
60
+ </body>
61
+ </html>
@@ -0,0 +1,60 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+ div.dialog {
15
+ width: 95%;
16
+ max-width: 33em;
17
+ margin: 4em auto 0;
18
+ }
19
+ div.dialog > div {
20
+ border: 1px solid #CCC;
21
+ border-right-color: #999;
22
+ border-left-color: #999;
23
+ border-bottom-color: #BBB;
24
+ border-top: #B00100 solid 4px;
25
+ border-top-left-radius: 9px;
26
+ border-top-right-radius: 9px;
27
+ background-color: white;
28
+ padding: 7px 12% 0;
29
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
30
+ }
31
+ h1 {
32
+ font-size: 100%;
33
+ color: #730E15;
34
+ line-height: 1.5em;
35
+ }
36
+ div.dialog > p {
37
+ margin: 0 0 1em;
38
+ padding: 1em;
39
+ background-color: #F7F7F7;
40
+ border: 1px solid #CCC;
41
+ border-right-color: #999;
42
+ border-left-color: #999;
43
+ border-bottom-color: #999;
44
+ border-bottom-left-radius: 4px;
45
+ border-bottom-right-radius: 4px;
46
+ border-top-color: #DADADA;
47
+ color: #666;
48
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <div class="dialog">
54
+ <div>
55
+ <h1>We're sorry, but something went wrong.</h1>
56
+ </div>
57
+ <p>If you are the application owner check the logs for more information.</p>
58
+ </div>
59
+ </body>
60
+ </html>
File without changes
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+ require 'rails/generators'
3
+ require 'generators/indexers/install/install_generator'
4
+ require 'generators/indexers/indexer/indexer_generator'
5
+
6
+ class GeneratorTest < Rails::Generators::TestCase
7
+ destination Rails.root.join('tmp')
8
+
9
+ teardown do
10
+ FileUtils.rm_rf destination_root
11
+ end
12
+
13
+ test 'install' do
14
+ self.class.tests Indexers::Generators::InstallGenerator
15
+ run_generator
16
+ assert_file 'config/initializers/indexers.rb'
17
+ assert_file 'config/elasticsearch.yml'
18
+ end
19
+
20
+ test 'index' do
21
+ self.class.tests Indexers::Generators::IndexerGenerator
22
+ run_generator %w(products)
23
+ assert_file 'app/indexers/products_indexer.rb'
24
+ end
25
+
26
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class IndexTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ Indexers.index
7
+ end
8
+
9
+ teardown do
10
+ Indexers.unindex
11
+ end
12
+
13
+ test 'namespace' do
14
+ assert_equal 'dummy_test', Indexers.namespace
15
+ end
16
+
17
+ test 'find' do
18
+ assert Indexers.definitions.find(:product)
19
+ end
20
+
21
+ test 'suggest' do
22
+ shop = Shop.create
23
+ ['Les Paul', 'Stratocaster'].each do |name|
24
+ product = shop.products.create(name: name)
25
+ product.run_callbacks :commit
26
+ end
27
+ sleep 2
28
+
29
+ assert_equal [], suggest('', shop)
30
+ assert_equal ['Les Paul'], suggest('les', shop)
31
+ assert_equal ['Stratocaster'], suggest('str', shop)
32
+ end
33
+
34
+ private
35
+
36
+ def suggest(term, shop)
37
+ Indexers.suggest(:product, term, shop: shop).map do |suggestion|
38
+ suggestion[:text]
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ class RecordTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ Indexers.index
7
+ end
8
+
9
+ teardown do
10
+ Indexers.unindex
11
+ end
12
+
13
+ test 'indexing' do
14
+ shop = Shop.create(name: 'Anderstons')
15
+ product = shop.products.create(name: 'Les Paul', category: 'Gibson')
16
+ product.run_callbacks :commit
17
+ sleep 2
18
+
19
+ assert_equal 1, Product.search.count
20
+ product.destroy
21
+ product.run_callbacks :commit
22
+ assert_equal 0, Product.search.count
23
+ end
24
+
25
+ end
@@ -0,0 +1,164 @@
1
+ require 'test_helper'
2
+
3
+ class SearchTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ Indexers.index
7
+ end
8
+
9
+ teardown do
10
+ Indexers.unindex
11
+ end
12
+
13
+ test 'order' do
14
+ shop = Shop.create
15
+ shop.run_callbacks :commit
16
+ (1..3).step do |id|
17
+ product = shop.products.create(
18
+ id: id,
19
+ name: id,
20
+ price: id,
21
+ position: id,
22
+ currency: 'UYU'
23
+ )
24
+ product.run_callbacks :commit
25
+ product
26
+ end
27
+ sleep 2
28
+
29
+ assert_equal [1, 2, 3], Product.search.order(id: :asc).map(&:id)
30
+ assert_equal [3, 2, 1], Product.search.order(id: :desc).map(&:id)
31
+
32
+ assert_equal [1, 2, 3], Product.search.order(name: :asc).map(&:id)
33
+ assert_equal [3, 2, 1], Product.search.order(name: :desc).map(&:id)
34
+
35
+ assert_equal [1, 2, 3], Product.search.order(price: :asc).map(&:id)
36
+ assert_equal [3, 2, 1], Product.search.order(price: :desc).map(&:id)
37
+
38
+ assert_equal [3, 2, 1], Product.search.order(position: :asc).map(&:id)
39
+ assert_equal [3, 2, 1], Product.search.order(position: :desc).map(&:id)
40
+ end
41
+
42
+ test 'with and without' do
43
+ (1..3).step do |id|
44
+ shop = Shop.create(id: id)
45
+ shop.run_callbacks :commit
46
+ end
47
+ Shop.create id: 4
48
+ sleep 2
49
+
50
+ assert_equal [4, 3], Shop.search.page(1, length: 2, with: 4).map(&:id)
51
+ assert_equal [2, 1], Shop.search.page(1, without: 3).map(&:id)
52
+ end
53
+
54
+ test 'includes' do
55
+ shop = Shop.create
56
+ product = shop.products.create(name: 'Test')
57
+ product.run_callbacks :commit
58
+ sleep 2
59
+
60
+ product = Product.search.includes(:shop).first
61
+ Shop.expects(:connection).never
62
+ assert_equal shop, product.shop
63
+ end
64
+
65
+ test 'pagination' do
66
+ (1..5).step do |id|
67
+ shop = Shop.create(id: id)
68
+ shop.run_callbacks :commit
69
+ end
70
+ sleep 2
71
+
72
+ collection = Shop.search.page(1, length: 2)
73
+ assert_equal 1, collection.first_page
74
+ assert_equal 3, collection.last_page
75
+ assert_equal 3, collection.total_pages
76
+ assert_equal 5, collection.total_count
77
+ assert_equal 1, collection.current_page
78
+ assert_equal 2, collection.page_length
79
+ assert_equal 0, collection.padding
80
+ assert_nil collection.previous_page
81
+ assert_equal 2, collection.next_page
82
+ assert_not collection.out_of_bounds?
83
+ assert_equal [5, 4], collection.map(&:id)
84
+
85
+ collection = Shop.search.page(2, length: 2)
86
+ assert_equal 1, collection.first_page
87
+ assert_equal 3, collection.last_page
88
+ assert_equal 3, collection.total_pages
89
+ assert_equal 5, collection.total_count
90
+ assert_equal 2, collection.current_page
91
+ assert_equal 2, collection.page_length
92
+ assert_equal 0, collection.padding
93
+ assert_equal 1, collection.previous_page
94
+ assert_equal 3, collection.next_page
95
+ assert_not collection.out_of_bounds?
96
+ assert_equal [3, 2], collection.map(&:id)
97
+
98
+ collection = Shop.search.page(3, length: 2)
99
+ assert_equal 1, collection.first_page
100
+ assert_equal 3, collection.last_page
101
+ assert_equal 3, collection.total_pages
102
+ assert_equal 5, collection.total_count
103
+ assert_equal 3, collection.current_page
104
+ assert_equal 2, collection.page_length
105
+ assert_equal 0, collection.padding
106
+ assert_equal 2, collection.previous_page
107
+ assert_nil collection.next_page
108
+ assert_not collection.out_of_bounds?
109
+ assert_equal [1], collection.map(&:id)
110
+
111
+ collection = Shop.search.page(4, length: 2)
112
+ assert_equal 1, collection.first_page
113
+ assert_equal 3, collection.last_page
114
+ assert_equal 3, collection.total_pages
115
+ assert_equal 5, collection.total_count
116
+ assert_equal 4, collection.current_page
117
+ assert_equal 2, collection.page_length
118
+ assert_equal 0, collection.padding
119
+ assert_equal 3, collection.previous_page
120
+ assert_nil collection.next_page
121
+ assert collection.out_of_bounds?
122
+ assert_equal [], collection.to_a
123
+
124
+ collection = Shop.search.page(1, length: 2, padding: 2)
125
+ assert_equal 1, collection.first_page
126
+ assert_equal 2, collection.last_page
127
+ assert_equal 2, collection.total_pages
128
+ assert_equal 3, collection.total_count
129
+ assert_equal 1, collection.current_page
130
+ assert_equal 2, collection.page_length
131
+ assert_equal 2, collection.padding
132
+ assert_nil collection.previous_page
133
+ assert_equal 2, collection.next_page
134
+ assert_not collection.out_of_bounds?
135
+ assert_equal [3, 2], collection.map(&:id)
136
+
137
+ collection = Shop.search.page(2, length: 2, padding: 2)
138
+ assert_equal 1, collection.first_page
139
+ assert_equal 2, collection.last_page
140
+ assert_equal 2, collection.total_pages
141
+ assert_equal 3, collection.total_count
142
+ assert_equal 2, collection.current_page
143
+ assert_equal 2, collection.page_length
144
+ assert_equal 2, collection.padding
145
+ assert_equal 1, collection.previous_page
146
+ assert_nil collection.next_page
147
+ assert_not collection.out_of_bounds?
148
+ assert_equal [1], collection.map(&:id)
149
+
150
+ collection = Shop.search.page(3, length: 2, padding: 2)
151
+ assert_equal 1, collection.first_page
152
+ assert_equal 2, collection.last_page
153
+ assert_equal 2, collection.total_pages
154
+ assert_equal 3, collection.total_count
155
+ assert_equal 3, collection.current_page
156
+ assert_equal 2, collection.page_length
157
+ assert_equal 2, collection.padding
158
+ assert_equal 2, collection.previous_page
159
+ assert_nil collection.next_page
160
+ assert collection.out_of_bounds?
161
+ assert_equal [], collection.to_a
162
+ end
163
+
164
+ end
data/test/task_test.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class TaskTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ Dummy::Application.load_tasks
7
+ end
8
+
9
+ teardown do
10
+ Indexers.unindex
11
+ end
12
+
13
+ test 'index' do
14
+ assert_nothing_raised do
15
+ Rake::Task['indexers:index'].invoke
16
+ end
17
+ end
18
+
19
+ test 'reindex' do
20
+ assert_nothing_raised do
21
+ Rake::Task['indexers:reindex'].invoke
22
+ end
23
+ end
24
+
25
+ test 'unindex' do
26
+ assert_nothing_raised do
27
+ Rake::Task['indexers:unindex'].invoke
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,14 @@
1
+ # Configure Rails Environment
2
+ ENV['RAILS_ENV'] = 'test'
3
+
4
+ require File.expand_path('../../test/dummy/config/environment.rb', __FILE__)
5
+ ActiveRecord::Migrator.migrations_paths = [File.expand_path('../../test/dummy/db/migrate', __FILE__)]
6
+ require 'rails/test_help'
7
+ require 'mocha/mini_test'
8
+
9
+ # Filter out Minitest backtrace while allowing backtrace from other libraries
10
+ # to be shown.
11
+ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
12
+
13
+ # Load support files
14
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }