thinking-sphinx 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +29 -20
  4. data/Appraisals +9 -5
  5. data/Gemfile +8 -3
  6. data/HISTORY +24 -0
  7. data/README.textile +5 -4
  8. data/bin/console +14 -0
  9. data/bin/literals +9 -0
  10. data/bin/loadsphinx +38 -0
  11. data/lib/thinking_sphinx.rb +15 -2
  12. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +2 -3
  13. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +11 -1
  14. data/lib/thinking_sphinx/active_record/index.rb +1 -1
  15. data/lib/thinking_sphinx/active_record/join_association.rb +3 -1
  16. data/lib/thinking_sphinx/active_record/log_subscriber.rb +5 -0
  17. data/lib/thinking_sphinx/active_record/sql_source.rb +1 -1
  18. data/lib/thinking_sphinx/attribute_types.rb +70 -0
  19. data/lib/thinking_sphinx/commands/base.rb +41 -0
  20. data/lib/thinking_sphinx/commands/configure.rb +13 -0
  21. data/lib/thinking_sphinx/commands/index.rb +11 -0
  22. data/lib/thinking_sphinx/commands/start_attached.rb +20 -0
  23. data/lib/thinking_sphinx/commands/start_detached.rb +19 -0
  24. data/lib/thinking_sphinx/commands/stop.rb +22 -0
  25. data/lib/thinking_sphinx/configuration.rb +36 -28
  26. data/lib/thinking_sphinx/configuration/minimum_fields.rb +11 -8
  27. data/lib/thinking_sphinx/connection.rb +5 -122
  28. data/lib/thinking_sphinx/connection/client.rb +48 -0
  29. data/lib/thinking_sphinx/connection/jruby.rb +53 -0
  30. data/lib/thinking_sphinx/connection/mri.rb +28 -0
  31. data/lib/thinking_sphinx/core/index.rb +11 -0
  32. data/lib/thinking_sphinx/deletion.rb +6 -2
  33. data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
  34. data/lib/thinking_sphinx/deltas/delete_job.rb +14 -4
  35. data/lib/thinking_sphinx/distributed/index.rb +10 -0
  36. data/lib/thinking_sphinx/errors.rb +1 -1
  37. data/lib/thinking_sphinx/index_set.rb +14 -2
  38. data/lib/thinking_sphinx/interfaces/daemon.rb +32 -0
  39. data/lib/thinking_sphinx/interfaces/real_time.rb +41 -0
  40. data/lib/thinking_sphinx/interfaces/sql.rb +41 -0
  41. data/lib/thinking_sphinx/middlewares.rb +5 -3
  42. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +13 -6
  43. data/lib/thinking_sphinx/middlewares/attribute_typer.rb +48 -0
  44. data/lib/thinking_sphinx/middlewares/valid_options.rb +23 -0
  45. data/lib/thinking_sphinx/rake_interface.rb +10 -124
  46. data/lib/thinking_sphinx/search.rb +11 -0
  47. data/lib/thinking_sphinx/search/query.rb +7 -1
  48. data/lib/thinking_sphinx/tasks.rb +80 -21
  49. data/lib/thinking_sphinx/with_output.rb +11 -0
  50. data/spec/acceptance/connection_spec.rb +4 -4
  51. data/spec/acceptance/searching_within_a_model_spec.rb +7 -0
  52. data/spec/acceptance/specifying_sql_spec.rb +26 -8
  53. data/spec/acceptance/sql_deltas_spec.rb +12 -0
  54. data/spec/internal/app/indices/album_index.rb +3 -0
  55. data/spec/internal/app/models/album.rb +19 -0
  56. data/spec/internal/db/schema.rb +8 -0
  57. data/spec/spec_helper.rb +4 -0
  58. data/spec/support/json_column.rb +5 -1
  59. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +5 -1
  60. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +6 -0
  61. data/spec/thinking_sphinx/attribute_types_spec.rb +50 -0
  62. data/spec/thinking_sphinx/commands/configure_spec.rb +29 -0
  63. data/spec/thinking_sphinx/commands/index_spec.rb +26 -0
  64. data/spec/thinking_sphinx/commands/start_detached_spec.rb +55 -0
  65. data/spec/thinking_sphinx/commands/stop_spec.rb +54 -0
  66. data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +36 -0
  67. data/spec/thinking_sphinx/deletion_spec.rb +2 -5
  68. data/spec/thinking_sphinx/deltas/default_delta_spec.rb +1 -1
  69. data/spec/thinking_sphinx/errors_spec.rb +7 -0
  70. data/spec/thinking_sphinx/index_set_spec.rb +30 -7
  71. data/spec/thinking_sphinx/interfaces/daemon_spec.rb +52 -0
  72. data/spec/thinking_sphinx/interfaces/real_time_spec.rb +109 -0
  73. data/spec/thinking_sphinx/interfaces/sql_spec.rb +98 -0
  74. data/spec/thinking_sphinx/middlewares/attribute_typer_spec.rb +42 -0
  75. data/spec/thinking_sphinx/middlewares/valid_options_spec.rb +49 -0
  76. data/spec/thinking_sphinx/rake_interface_spec.rb +13 -246
  77. data/spec/thinking_sphinx/search/query_spec.rb +7 -0
  78. data/thinking-sphinx.gemspec +5 -4
  79. metadata +72 -16
  80. data/gemfiles/.gitignore +0 -1
  81. data/gemfiles/rails_3_2.gemfile +0 -13
  82. data/gemfiles/rails_4_0.gemfile +0 -13
  83. data/gemfiles/rails_4_1.gemfile +0 -13
  84. data/gemfiles/rails_4_2.gemfile +0 -13
  85. data/gemfiles/rails_5_0.gemfile +0 -12
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ThinkingSphinx::Interfaces::Daemon do
4
+ let(:configuration) { double 'configuration', :controller => controller }
5
+ let(:controller) { double 'controller', :running? => false }
6
+ let(:stream) { double 'stream', :puts => true }
7
+ let(:interface) {
8
+ ThinkingSphinx::Interfaces::Daemon.new(configuration, {}, stream)
9
+ }
10
+
11
+ describe '#start' do
12
+ let(:command) { double 'command', :call => true }
13
+
14
+ before :each do
15
+ stub_const 'ThinkingSphinx::Commands::StartDetached', command
16
+ end
17
+
18
+ it "starts the daemon" do
19
+ expect(command).to receive(:call)
20
+
21
+ interface.start
22
+ end
23
+
24
+ it "raises an error if the daemon is already running" do
25
+ allow(controller).to receive_messages :running? => true
26
+
27
+ expect {
28
+ interface.start
29
+ }.to raise_error(ThinkingSphinx::SphinxAlreadyRunning)
30
+ end
31
+ end
32
+
33
+ describe '#status' do
34
+ it "reports when the daemon is running" do
35
+ allow(controller).to receive_messages :running? => true
36
+
37
+ expect(stream).to receive(:puts).
38
+ with('The Sphinx daemon searchd is currently running.')
39
+
40
+ interface.status
41
+ end
42
+
43
+ it "reports when the daemon is not running" do
44
+ allow(controller).to receive_messages :running? => false
45
+
46
+ expect(stream).to receive(:puts).
47
+ with('The Sphinx daemon searchd is not currently running.')
48
+
49
+ interface.status
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ThinkingSphinx::Interfaces::SQL do
4
+ let(:interface) { ThinkingSphinx::Interfaces::RealTime.new(
5
+ configuration, {}, stream
6
+ ) }
7
+ let(:configuration) { double 'configuration', :controller => controller,
8
+ :render => true, :indices_location => '/path/to/indices',
9
+ :preload_indices => true }
10
+ let(:controller) { double 'controller', :running? => true }
11
+ let(:stream) { double :puts => nil }
12
+
13
+ describe '#clear' do
14
+ let(:plain_index) { double(:type => 'plain') }
15
+ let(:users_index) { double(:name => 'users', :type => 'rt', :render => true,
16
+ :path => '/path/to/my/index/users') }
17
+ let(:parts_index) { double(:name => 'parts', :type => 'rt', :render => true,
18
+ :path => '/path/to/my/index/parts') }
19
+
20
+ before :each do
21
+ allow(configuration).to receive_messages(
22
+ :indices => [plain_index, users_index, parts_index],
23
+ :searchd => double(:binlog_path => '/path/to/binlog')
24
+ )
25
+
26
+ allow(Dir).to receive(:[]).with('/path/to/my/index/users.*').
27
+ and_return(['users.a', 'users.b'])
28
+ allow(Dir).to receive(:[]).with('/path/to/my/index/parts.*').
29
+ and_return(['parts.a', 'parts.b'])
30
+
31
+ allow(FileUtils).to receive_messages :mkdir_p => true, :rm_r => true,
32
+ :rm => true
33
+ allow(File).to receive_messages :exists? => true
34
+ end
35
+
36
+ it 'finds each file for real-time indices' do
37
+ expect(Dir).to receive(:[]).with('/path/to/my/index/users.*').
38
+ and_return([])
39
+
40
+ interface.clear
41
+ end
42
+
43
+ it "removes the directory for the binlog files" do
44
+ expect(FileUtils).to receive(:rm_r).with('/path/to/binlog')
45
+
46
+ interface.clear
47
+ end
48
+
49
+ it "removes each file for real-time indices" do
50
+ expect(FileUtils).to receive(:rm).with('users.a')
51
+ expect(FileUtils).to receive(:rm).with('users.b')
52
+ expect(FileUtils).to receive(:rm).with('parts.a')
53
+ expect(FileUtils).to receive(:rm).with('parts.b')
54
+
55
+ interface.clear
56
+ end
57
+
58
+ context "with options[:index_filter]" do
59
+ let(:interface) { ThinkingSphinx::Interfaces::RealTime.new(
60
+ configuration, {:index_filter => 'users'}, stream
61
+ ) }
62
+
63
+ it "removes each file for real-time indices that match :index_filter" do
64
+ expect(FileUtils).to receive(:rm).with('users.a')
65
+ expect(FileUtils).to receive(:rm).with('users.b')
66
+ expect(FileUtils).not_to receive(:rm).with('parts.a')
67
+ expect(FileUtils).not_to receive(:rm).with('parts.b')
68
+
69
+ interface.clear
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#index' do
75
+ let(:plain_index) { double(:type => 'plain') }
76
+ let(:users_index) { double(name: 'users', :type => 'rt') }
77
+ let(:parts_index) { double(name: 'parts', :type => 'rt') }
78
+
79
+ before :each do
80
+ allow(configuration).to receive_messages(
81
+ :indices => [plain_index, users_index, parts_index]
82
+ )
83
+
84
+ allow(FileUtils).to receive_messages :mkdir_p => true
85
+ end
86
+
87
+ it 'populates each real-index' do
88
+ expect(ThinkingSphinx::RealTime::Populator).to receive(:populate).with(users_index)
89
+ expect(ThinkingSphinx::RealTime::Populator).to receive(:populate).with(parts_index)
90
+ expect(ThinkingSphinx::RealTime::Populator).not_to receive(:populate).with(plain_index)
91
+
92
+ interface.index
93
+ end
94
+
95
+ context "with options[:index_filter]" do
96
+ let(:interface) { ThinkingSphinx::Interfaces::RealTime.new(
97
+ configuration, {:index_filter => 'users'}, stream
98
+ ) }
99
+
100
+ it 'populates each real-index that matches :index_filter' do
101
+ expect(ThinkingSphinx::RealTime::Populator).to receive(:populate).with(users_index)
102
+ expect(ThinkingSphinx::RealTime::Populator).not_to receive(:populate).with(parts_index)
103
+ expect(ThinkingSphinx::RealTime::Populator).not_to receive(:populate).with(plain_index)
104
+
105
+ interface.index
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ThinkingSphinx::Interfaces::SQL do
4
+ let(:interface) { ThinkingSphinx::Interfaces::SQL.new(
5
+ configuration, {:verbose => true}, stream
6
+ ) }
7
+ let(:configuration) { double 'configuration', :preload_indices => true,
8
+ :render => true, :indices => [double(:index, :type => 'plain')],
9
+ :indices_location => '/path/to/indices' }
10
+ let(:stream) { double :puts => nil }
11
+
12
+ describe '#clear' do
13
+ let(:users_index) { double(:name => 'users', :type => 'plain',
14
+ :render => true, :path => '/path/to/my/index/users') }
15
+ let(:parts_index) { double(:name => 'users', :type => 'plain',
16
+ :render => true, :path => '/path/to/my/index/parts') }
17
+ let(:rt_index) { double(:type => 'rt') }
18
+
19
+ before :each do
20
+ allow(configuration).to receive_messages(
21
+ :indices => [users_index, parts_index, rt_index]
22
+ )
23
+
24
+ allow(Dir).to receive(:[]).with('/path/to/my/index/users.*').
25
+ and_return(['users.a', 'users.b'])
26
+ allow(Dir).to receive(:[]).with('/path/to/my/index/parts.*').
27
+ and_return(['parts.a', 'parts.b'])
28
+
29
+ allow(FileUtils).to receive_messages :mkdir_p => true, :rm_r => true,
30
+ :rm => true
31
+ allow(File).to receive_messages :exists? => true
32
+ end
33
+
34
+ it 'finds each file for sql-backed indices' do
35
+ expect(Dir).to receive(:[]).with('/path/to/my/index/users.*').
36
+ and_return([])
37
+
38
+ interface.clear
39
+ end
40
+
41
+ it "removes each file for real-time indices" do
42
+ expect(FileUtils).to receive(:rm).with('users.a')
43
+ expect(FileUtils).to receive(:rm).with('users.b')
44
+ expect(FileUtils).to receive(:rm).with('parts.a')
45
+ expect(FileUtils).to receive(:rm).with('parts.b')
46
+
47
+ interface.clear
48
+ end
49
+ end
50
+
51
+ describe '#index' do
52
+ let(:index_command) { double :call => true }
53
+ let(:configure_command) { double :call => true }
54
+
55
+ before :each do
56
+ stub_const 'ThinkingSphinx::Commands::Index', index_command
57
+ stub_const 'ThinkingSphinx::Commands::Configure', configure_command
58
+
59
+ allow(ThinkingSphinx).to receive_messages :before_index_hooks => []
60
+ allow(FileUtils).to receive_messages :mkdir_p => true
61
+ end
62
+
63
+ it "renders the configuration to a file by default" do
64
+ expect(configure_command).to receive(:call)
65
+
66
+ interface.index
67
+ end
68
+
69
+ it "does not render the configuration if requested" do
70
+ expect(configure_command).not_to receive(:call)
71
+
72
+ interface.index false
73
+ end
74
+
75
+ it "creates the directory for the index files" do
76
+ expect(FileUtils).to receive(:mkdir_p).with('/path/to/indices')
77
+
78
+ interface.index
79
+ end
80
+
81
+ it "calls all registered hooks" do
82
+ called = false
83
+ ThinkingSphinx.before_index_hooks << Proc.new { called = true }
84
+
85
+ interface.index
86
+
87
+ expect(called).to be_truthy
88
+ end
89
+
90
+ it "executes the index command" do
91
+ expect(index_command).to receive(:call).with(
92
+ configuration, {:verbose => true}, stream
93
+ )
94
+
95
+ interface.index
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ThinkingSphinx::Middlewares::AttributeTyper do
4
+ let(:app) { double('app', :call => true) }
5
+ let(:middleware) { ThinkingSphinx::Middlewares::AttributeTyper.new app }
6
+ let(:attributes) { {} }
7
+ let(:context) { double('context', :search => search) }
8
+ let(:search) { double('search', :options => {}) }
9
+
10
+ before :each do
11
+ allow(ThinkingSphinx::AttributeTypes).to receive(:call).
12
+ and_return(attributes)
13
+ allow(ActiveSupport::Deprecation).to receive(:warn)
14
+ end
15
+
16
+ it 'warns when providing a string value for an integer attribute' do
17
+ attributes['user_id'] = [:uint]
18
+ search.options[:with] = {:user_id => '1'}
19
+
20
+ expect(ActiveSupport::Deprecation).to receive(:warn)
21
+
22
+ middleware.call [context]
23
+ end
24
+
25
+ it 'warns when providing a string value for a float attribute' do
26
+ attributes['price'] = [:float]
27
+ search.options[:without] = {:price => '1.0'}
28
+
29
+ expect(ActiveSupport::Deprecation).to receive(:warn)
30
+
31
+ middleware.call [context]
32
+ end
33
+
34
+ it 'proceeds when providing a string value for a string attribute' do
35
+ attributes['status'] = [:string]
36
+ search.options[:with] = {:status => 'completed'}
37
+
38
+ expect(ActiveSupport::Deprecation).not_to receive(:warn)
39
+
40
+ middleware.call [context]
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ThinkingSphinx::Middlewares::ValidOptions do
4
+ let(:app) { double 'app', :call => true }
5
+ let(:middleware) { ThinkingSphinx::Middlewares::ValidOptions.new app }
6
+ let(:context) { double 'context', :search => search }
7
+ let(:search) { double 'search', :options => {} }
8
+
9
+ before :each do
10
+ allow(ThinkingSphinx::Logger).to receive(:log)
11
+ end
12
+
13
+ context 'with unknown options' do
14
+ before :each do
15
+ search.options[:foo] = :bar
16
+ end
17
+
18
+ it "adds a warning" do
19
+ expect(ThinkingSphinx::Logger).to receive(:log).
20
+ with(:warn, "Unexpected search options: [:foo]")
21
+
22
+ middleware.call [context]
23
+ end
24
+
25
+ it 'continues on' do
26
+ expect(app).to receive(:call).with([context])
27
+
28
+ middleware.call [context]
29
+ end
30
+ end
31
+
32
+ context "with known options" do
33
+ before :each do
34
+ search.options[:ids_only] = true
35
+ end
36
+
37
+ it "is silent" do
38
+ expect(ThinkingSphinx::Logger).to_not receive(:log)
39
+
40
+ middleware.call [context]
41
+ end
42
+
43
+ it 'continues on' do
44
+ expect(app).to receive(:call).with([context])
45
+
46
+ middleware.call [context]
47
+ end
48
+ end
49
+ end
@@ -1,270 +1,37 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::RakeInterface do
4
- let(:configuration) { double('configuration', :controller => controller) }
5
4
  let(:interface) { ThinkingSphinx::RakeInterface.new }
6
5
 
7
- before :each do
8
- allow(ThinkingSphinx::Configuration).to receive_messages :instance => configuration
9
- allow(interface).to receive_messages(:puts => nil)
10
- end
11
-
12
- describe '#clear_all' do
13
- let(:controller) { double 'controller' }
14
-
15
- before :each do
16
- allow(configuration).to receive_messages(
17
- :indices_location => '/path/to/indices',
18
- :searchd => double(:binlog_path => '/path/to/binlog')
19
- )
20
-
21
- allow(FileUtils).to receive_messages :rm_r => true
22
- allow(File).to receive_messages :exists? => true
23
- end
24
-
25
- it "removes the directory for the index files" do
26
- expect(FileUtils).to receive(:rm_r).with('/path/to/indices')
27
-
28
- interface.clear_all
29
- end
30
-
31
- it "removes the directory for the binlog files" do
32
- expect(FileUtils).to receive(:rm_r).with('/path/to/binlog')
33
-
34
- interface.clear_all
35
- end
36
- end
37
-
38
- describe '#clear_real_time' do
39
- let(:controller) { double 'controller' }
40
- let(:index) {
41
- double(:type => 'rt', :render => true, :path => '/path/to/my/index')
42
- }
43
-
44
- before :each do
45
- allow(configuration).to receive_messages(
46
- :indices => [double(:type => 'plain'), index],
47
- :searchd => double(:binlog_path => '/path/to/binlog'),
48
- :preload_indices => true
49
- )
50
-
51
- allow(Dir).to receive_messages :[] => ['foo.a', 'foo.b']
52
- allow(FileUtils).to receive_messages :rm_r => true, :rm => true
53
- allow(File).to receive_messages :exists? => true
54
- end
55
-
56
- it 'finds each file for real-time indices' do
57
- expect(Dir).to receive(:[]).with('/path/to/my/index.*').and_return([])
58
-
59
- interface.clear_real_time
60
- end
61
-
62
- it "removes each file for real-time indices" do
63
- expect(FileUtils).to receive(:rm).with('foo.a')
64
- expect(FileUtils).to receive(:rm).with('foo.b')
65
-
66
- interface.clear_real_time
67
- end
68
-
69
- it "removes the directory for the binlog files" do
70
- expect(FileUtils).to receive(:rm_r).with('/path/to/binlog')
71
-
72
- interface.clear_real_time
73
- end
74
- end
75
-
76
6
  describe '#configure' do
77
- let(:controller) { double('controller') }
7
+ let(:command) { double 'command', :call => true }
78
8
 
79
9
  before :each do
80
- allow(configuration).to receive_messages(
81
- :configuration_file => '/path/to/foo.conf',
82
- :render_to_file => true
83
- )
84
- end
85
-
86
- it "renders the configuration to a file" do
87
- expect(configuration).to receive(:render_to_file)
88
-
89
- interface.configure
10
+ stub_const 'ThinkingSphinx::Commands::Configure', command
90
11
  end
91
12
 
92
- it "prints a message stating the file is being generated" do
93
- expect(interface).to receive(:puts).
94
- with('Generating configuration to /path/to/foo.conf')
13
+ it 'sends the configure command' do
14
+ expect(command).to receive(:call)
95
15
 
96
16
  interface.configure
97
17
  end
98
18
  end
99
19
 
100
- describe '#index' do
101
- let(:controller) { double('controller', :index => true) }
102
-
103
- before :each do
104
- allow(ThinkingSphinx).to receive_messages :before_index_hooks => []
105
- allow(configuration).to receive_messages(
106
- :configuration_file => '/path/to/foo.conf',
107
- :render_to_file => true,
108
- :indices_location => '/path/to/indices'
109
- )
110
-
111
- allow(FileUtils).to receive_messages :mkdir_p => true
112
- end
113
-
114
- it "renders the configuration to a file by default" do
115
- expect(configuration).to receive(:render_to_file)
116
-
117
- interface.index
118
- end
119
-
120
- it "does not render the configuration if requested" do
121
- expect(configuration).not_to receive(:render_to_file)
122
-
123
- interface.index false
124
- end
125
-
126
- it "creates the directory for the index files" do
127
- expect(FileUtils).to receive(:mkdir_p).with('/path/to/indices')
128
-
129
- interface.index
130
- end
131
-
132
- it "calls all registered hooks" do
133
- called = false
134
- ThinkingSphinx.before_index_hooks << Proc.new { called = true }
135
-
136
- interface.index
137
-
138
- expect(called).to be_truthy
139
- end
140
-
141
- it "indexes all indices verbosely" do
142
- expect(controller).to receive(:index).with(:verbose => true)
143
-
144
- interface.index
145
- end
146
-
147
- it "does not index verbosely if requested" do
148
- expect(controller).to receive(:index).with(:verbose => false)
149
-
150
- interface.index true, false
151
- end
152
- end
153
-
154
- describe '#start' do
155
- let(:controller) { double('controller', :start => result, :pid => 101) }
156
- let(:result) { double 'result', :command => 'start', :status => 1,
157
- :output => '' }
158
-
159
- before :each do
160
- allow(controller).to receive(:running?).and_return(false, true)
161
- allow(configuration).to receive_messages(
162
- :indices_location => 'my/index/files',
163
- :searchd => double(:log => '/path/to/log')
164
- )
165
-
166
- allow(FileUtils).to receive_messages :mkdir_p => true
167
- end
168
-
169
- it "creates the index files directory" do
170
- expect(FileUtils).to receive(:mkdir_p).with('my/index/files')
171
-
172
- interface.start
173
- end
174
-
175
- it "starts the daemon" do
176
- expect(controller).to receive(:start)
177
-
178
- interface.start
179
- end
180
-
181
- it "raises an error if the daemon is already running" do
182
- allow(controller).to receive_messages :running? => true
183
-
184
- expect {
185
- interface.start
186
- }.to raise_error(ThinkingSphinx::SphinxAlreadyRunning)
187
- end
188
-
189
- it "prints a success message if the daemon has started" do
190
- allow(controller).to receive(:running?).and_return(false, true)
191
-
192
- expect(interface).to receive(:puts).
193
- with('Started searchd successfully (pid: 101).')
194
-
195
- interface.start
196
- end
197
-
198
- it "prints a failure message if the daemon does not start" do
199
- allow(controller).to receive(:running?).and_return(false, false)
200
- allow(interface).to receive(:exit)
201
-
202
- expect(interface).to receive(:puts) do |string|
203
- expect(string).to match('The Sphinx start command failed')
204
- end
205
-
206
- interface.start
20
+ describe '#daemon' do
21
+ it 'returns a daemon interface' do
22
+ expect(interface.daemon.class).to eq(ThinkingSphinx::Interfaces::Daemon)
207
23
  end
208
24
  end
209
25
 
210
- describe '#stop' do
211
- let(:controller) { double('controller', :stop => true, :pid => 101) }
212
- let(:result) { double 'result', :command => 'start', :status => 1,
213
- :output => '' }
214
-
215
- before :each do
216
- allow(controller).to receive(:running?).and_return(true, true, false)
217
- end
218
-
219
- it "prints a message if the daemon is not already running" do
220
- allow(controller).to receive_messages :running? => false
221
-
222
- expect(interface).to receive(:puts).with('searchd is not currently running.')
223
-
224
- interface.stop
225
- end
226
-
227
- it "stops the daemon" do
228
- expect(controller).to receive(:stop)
229
-
230
- interface.stop
231
- end
232
-
233
- it "prints a message informing the daemon has stopped" do
234
- expect(interface).to receive(:puts).with('Stopped searchd daemon (pid: 101).')
235
-
236
- interface.stop
237
- end
238
-
239
- it "should retry stopping the daemon until it stops" do
240
- allow(controller).to receive(:running?).
241
- and_return(true, true, true, false)
242
-
243
- expect(controller).to receive(:stop).twice
244
-
245
- interface.stop
26
+ describe '#rt' do
27
+ it 'returns a real-time interface' do
28
+ expect(interface.rt.class).to eq(ThinkingSphinx::Interfaces::RealTime)
246
29
  end
247
30
  end
248
31
 
249
- describe '#status' do
250
- let(:controller) { double('controller') }
251
-
252
- it "reports when the daemon is running" do
253
- allow(controller).to receive_messages :running? => true
254
-
255
- expect(interface).to receive(:puts).
256
- with('The Sphinx daemon searchd is currently running.')
257
-
258
- interface.status
259
- end
260
-
261
- it "reports when the daemon is not running" do
262
- allow(controller).to receive_messages :running? => false
263
-
264
- expect(interface).to receive(:puts).
265
- with('The Sphinx daemon searchd is not currently running.')
266
-
267
- interface.status
32
+ describe '#sql' do
33
+ it 'returns an SQL interface' do
34
+ expect(interface.sql.class).to eq(ThinkingSphinx::Interfaces::SQL)
268
35
  end
269
36
  end
270
37
  end