elasticshell 0.0.2 → 0.0.4

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.
Files changed (52) hide show
  1. data/README.rdoc +119 -55
  2. data/VERSION +1 -1
  3. data/bin/es +0 -2
  4. data/lib/elasticshell.rb +30 -25
  5. data/lib/elasticshell/client.rb +34 -13
  6. data/lib/elasticshell/command.rb +14 -170
  7. data/lib/elasticshell/commands/blank.rb +14 -0
  8. data/lib/elasticshell/commands/cd.rb +27 -0
  9. data/lib/elasticshell/commands/connect.rb +31 -0
  10. data/lib/elasticshell/commands/df.rb +23 -0
  11. data/lib/elasticshell/commands/help.rb +77 -0
  12. data/lib/elasticshell/commands/ls.rb +66 -0
  13. data/lib/elasticshell/commands/pretty.rb +21 -0
  14. data/lib/elasticshell/commands/pwd.rb +17 -0
  15. data/lib/elasticshell/commands/request.rb +81 -0
  16. data/lib/elasticshell/commands/request_parser.rb +77 -0
  17. data/lib/elasticshell/commands/set_verb.rb +23 -0
  18. data/lib/elasticshell/commands/unknown.rb +17 -0
  19. data/lib/elasticshell/scopes.rb +81 -50
  20. data/lib/elasticshell/scopes/cluster.rb +8 -16
  21. data/lib/elasticshell/scopes/global.rb +22 -23
  22. data/lib/elasticshell/scopes/index.rb +35 -29
  23. data/lib/elasticshell/scopes/mapping.rb +8 -28
  24. data/lib/elasticshell/scopes/nodes.rb +6 -15
  25. data/lib/elasticshell/shell.rb +155 -93
  26. data/lib/elasticshell/utils.rb +10 -0
  27. data/lib/elasticshell/{error.rb → utils/error.rb} +1 -0
  28. data/lib/elasticshell/utils/has_name.rb +14 -0
  29. data/lib/elasticshell/utils/has_verb.rb +15 -0
  30. data/lib/elasticshell/{log.rb → utils/log.rb} +1 -1
  31. data/lib/elasticshell/utils/recognizes_verb.rb +25 -0
  32. data/spec/elasticshell/client_spec.rb +55 -0
  33. data/spec/elasticshell/commands/blank_spec.rb +14 -0
  34. data/spec/elasticshell/commands/cd_spec.rb +23 -0
  35. data/spec/elasticshell/commands/connect_spec.rb +21 -0
  36. data/spec/elasticshell/commands/df_spec.rb +18 -0
  37. data/spec/elasticshell/commands/help_spec.rb +21 -0
  38. data/spec/elasticshell/commands/ls_spec.rb +24 -0
  39. data/spec/elasticshell/commands/pretty_spec.rb +19 -0
  40. data/spec/elasticshell/commands/pwd_spec.rb +14 -0
  41. data/spec/elasticshell/commands/request_parser_spec.rb +4 -0
  42. data/spec/elasticshell/commands/request_spec.rb +60 -0
  43. data/spec/elasticshell/commands/set_verb_spec.rb +14 -0
  44. data/spec/elasticshell/scopes_spec.rb +79 -0
  45. data/spec/elasticshell/shell_spec.rb +19 -0
  46. data/spec/elasticshell/utils/has_name_spec.rb +15 -0
  47. data/spec/elasticshell/utils/has_verb_spec.rb +24 -0
  48. data/spec/elasticshell/utils/recognizes_verb_spec.rb +23 -0
  49. data/spec/spec_helper.rb +4 -5
  50. data/spec/support/data.yml +45 -0
  51. data/spec/support/fake_output.rb +27 -0
  52. metadata +73 -4
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Client do
4
+
5
+ before do
6
+ @client = Client.new
7
+ end
8
+
9
+ describe "before connecting" do
10
+
11
+ it "should not be connected on initialization" do
12
+ expect(@client.connected?).to be_false
13
+ end
14
+
15
+ it "should raise an error when attempting to make a request before connecting" do
16
+ expect { @client.request("GET") }.to raise_error(ClientError)
17
+ end
18
+ end
19
+
20
+ describe "when connected" do
21
+
22
+ before do
23
+ @client.stub!(:connected?).and_return(true)
24
+ @client.stub!(:log_request)
25
+ @client.stub!(:perform_request)
26
+ @verb = "GET"
27
+ @params = {:op => "/foobar"}
28
+ end
29
+
30
+ it "should log all requests by default" do
31
+ @client.should_receive(:log_request).with(@verb, @params, {})
32
+ @client.request(@verb, @params)
33
+ end
34
+
35
+ it "should allow skipping request logging when asked" do
36
+ @client.should_not_receive(:log_request)
37
+ @client.request(@verb, @params, {:log => false})
38
+ end
39
+
40
+ it "wrap client library errors in its own custom error class" do
41
+ @client.stub!(:perform_request).and_raise(ElasticSearch::RequestError)
42
+ expect { @client.request(@verb, @params) }.to raise_error(ClientError)
43
+ end
44
+
45
+ it "should return safely from a client library error if asked" do
46
+ @client.stub!(:perform_request).and_raise(ElasticSearch::RequestError)
47
+ expect(@client.request(@verb, @params, {:safely => true, :return => 3})).to eq(3)
48
+ expect(@client.safely(@verb, @params)).to be_nil
49
+ end
50
+
51
+
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Blank do
4
+
5
+ before do
6
+ @shell = Shell.new
7
+ end
8
+
9
+ it "should do nothing" do
10
+ @shell.eval_line("")
11
+ expect(@shell.line).to eq(1)
12
+ end
13
+
14
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Cd do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new, :error => FakeOutput.new)
7
+ end
8
+
9
+ it "should change scope when given an argument" do
10
+ expect(@shell.eval_line("cd /foo").path).to eq("/foo")
11
+ end
12
+
13
+ it "should change to the global scope when given no argument" do
14
+ expect(@shell.eval_line("cd /foo").eval_line("cd").path).to eq("/")
15
+ end
16
+
17
+ it "should properly interpret relative path names" do
18
+ expect(@shell.eval_line("cd /foo").eval_line("cd ..").path).to eq("/")
19
+ expect(@shell.eval_line("cd /foo/bar").eval_line("cd ..").path).to eq("/foo")
20
+ expect(@shell.eval_line("cd /foo/bar").eval_line("cd ../baz").path).to eq("/foo/baz")
21
+ end
22
+
23
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Connect do
4
+
5
+
6
+ before do
7
+ @shell = Shell.new
8
+ end
9
+
10
+ it "should start a connection to the default servers" do
11
+ @shell.client.should_receive(:connect).with()
12
+ expect(@shell.eval_line("connect"))
13
+ end
14
+
15
+ it "should start a connection to the given comma-separated servers" do
16
+ @shell.client.should_receive(:connect).with(:servers => %w[http://123.123.123.123:9200 http://321.321.321.321:9200])
17
+ expect(@shell.eval_line("connect http://123.123.123.123:9200 http://321.321.321.321:9200"))
18
+ end
19
+
20
+
21
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Df do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new)
7
+ end
8
+
9
+ it "should produce a summary of disk usage by index" do
10
+ @global = mock("Global scope")
11
+ @shell.stub!(:connected?).and_return(true)
12
+ @shell.stub!(:scope_from_path).with("/").and_return(@global)
13
+ @global.stub!(:status).and_return({"indices"=>{"foo"=>{"index"=>{"size"=>"986b", "size_in_bytes"=>"986"}}}})
14
+ @shell.eval_line("df")
15
+ expect(@shell.output.read).to match(/986.+986b.+foo/)
16
+ end
17
+
18
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Help do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new)
7
+ end
8
+
9
+ it "should output some help text" do
10
+ @shell.eval_line("help")
11
+ expect(@shell.line).to eq(1)
12
+ end
13
+
14
+ it "should output some extra help text when asked" do
15
+ @shell.eval_line("help")
16
+ help = @shell.output.read.size
17
+ @shell.eval_line("help help")
18
+ expect(@shell.output.read.size).to be > help
19
+ end
20
+
21
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Ls do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new)
7
+ @shell.stub!(:connected?).and_return(true)
8
+ end
9
+
10
+ it "should provide a listing of the current scope's contents" do
11
+ @shell.scope.should_receive(:refresh!)
12
+ @shell.scope.stub!(:scopes).and_return(["snap", "crackle"])
13
+ @shell.eval_line("ls")
14
+ expect(@shell.output.read).to match(/crackle.+snap/)
15
+ end
16
+
17
+ it "should provide a long listing of the current scope's contents" do
18
+ @shell.scope.should_receive(:refresh!)
19
+ @shell.scope.stub!(:scopes).and_return(["snap", "crackle"])
20
+ @shell.eval_line("ll")
21
+ expect(@shell.output.read).to match(/^s.+crackle.*$\ns.+snap.*$/)
22
+ end
23
+
24
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Pretty do
4
+
5
+ before do
6
+ @shell = Shell.new
7
+ end
8
+
9
+ it "should set the shell to pretty when it's not pretty" do
10
+ @shell.eval_line("pretty")
11
+ expect(@shell.pretty?).to be_true
12
+ end
13
+
14
+ it "should set the shell to pretty when it's not pretty" do
15
+ @shell.eval_line("pretty").eval_line("pretty")
16
+ expect(@shell.pretty?).to be_false
17
+ end
18
+
19
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Pwd do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new)
7
+ end
8
+
9
+ it "should print the current scope" do
10
+ @shell.eval_line("pwd")
11
+ expect(@shell.output.read).to match(%r{/})
12
+ end
13
+
14
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Request::Parser do
4
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::Request do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new, :error => FakeOutput.new, :input => FakeOutput.new )
7
+ @shell.stub!(:connected?).and_return(true)
8
+ end
9
+
10
+ it "should recognize a simple request" do
11
+ @shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
12
+ @shell.eval_line("_simple")
13
+ end
14
+
15
+ it "should recognize a simple request with a different verb" do
16
+ @shell.client.should_receive(:request).with("POST", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
17
+ @shell.eval_line("POST _simple")
18
+ end
19
+
20
+ it "should recognize a request with an absolute path" do
21
+ @shell.client.should_receive(:request).with("GET", { :op => "/some/thing" }, kind_of(Hash), "").and_return('{}')
22
+ @shell.eval_line("/some/thing")
23
+ end
24
+
25
+ it "should recognize a request with a query string" do
26
+ @shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, {"foo" => "bar", "baz" => "booz what", :log => true}, "").and_return('{}')
27
+ @shell.eval_line("_simple?foo=bar&baz=booz+what")
28
+ end
29
+
30
+ it "should recognize a request with an inline body" do
31
+ @shell.client.should_receive(:request).with("POST", { :op => "/_simple" }, kind_of(Hash), "{}").and_return('{}')
32
+ @shell.eval_line("POST _simple {}")
33
+ end
34
+
35
+ it "should recognize a request with a body read from a local file" do
36
+ File.should_receive(:exist?).with("/some/file.json").and_return(true)
37
+ File.should_receive(:read).with("/some/file.json").and_return("{}")
38
+ @shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "{}").and_return('{}')
39
+ @shell.eval_line("_simple /some/file.json")
40
+ end
41
+
42
+ it "should recognize a request with a body read from STDIN" do
43
+ @shell.input_stream.stub!(:gets).and_return("{}")
44
+ @shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "{}").and_return('{}')
45
+ @shell.eval_line("_simple -")
46
+ end
47
+
48
+ it "should be able to pipe the output of a request to Ruby inline" do
49
+ @shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
50
+ @shell.eval_line("_simple | response")
51
+ end
52
+
53
+ it "should be able to pipe the output of a request to a RIPL session" do
54
+ @shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
55
+ require 'ripl'
56
+ Ripl.should_receive(:start)
57
+ @shell.eval_line("_simple |")
58
+ end
59
+
60
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Commands::SetVerb do
4
+
5
+ before do
6
+ @shell = Shell.new
7
+ end
8
+
9
+ it "set the shell's default verb" do
10
+ @shell.eval_line("put")
11
+ expect(@shell.verb).to eql("PUT")
12
+ end
13
+
14
+ end
@@ -18,5 +18,84 @@ describe Scopes do
18
18
  Scopes::Mapping.should_receive(:new).with(index, 'baz', kind_of(Hash))
19
19
  Scopes.from_path("/foobar/baz")
20
20
  end
21
+
22
+ end
23
+
24
+ describe Scope do
25
+
26
+ before do
27
+ @klass = Class.new(Scope) do
28
+ def self.requests
29
+ {
30
+ "GET" => {
31
+ '_a1' => "Request a1",
32
+ '_a2' => "Request a2",
33
+ 'foo' => "Request foo"
34
+ },
35
+ "POST" => {
36
+ '_b' => "Request b",
37
+ }
38
+ }
39
+ end
40
+
41
+ def initial_scopes
42
+ ["joe", "mary"]
43
+ end
44
+
45
+ def fetch_scopes
46
+ self.scopes.concat(["sue", "mark"])
47
+ end
48
+
49
+ end
50
+ @scope = @klass.new("/path/seg", {})
51
+ end
52
+
53
+ it "should restrict available requests to those matching its current verb" do
54
+ expect(@scope.requests).to include("_a1", "_a2")
55
+ @scope.verb = "POST"
56
+ expect(@scope.requests).to include("_b")
57
+ end
58
+
59
+ it "should reset and fetch new scopes when refreshing, but only once" do
60
+ @scope.should_receive(:reset!)
61
+ @scope.should_receive(:fetch_scopes)
62
+ 3.times { @scope.refresh }
63
+ end
64
+
65
+ it "should suggest matches against requests" do
66
+ expect(@scope.requests_matching('_a')).to eql(['_a1', '_a2'])
67
+ expect(@scope.requests_matching('f')).to eql(['foo'])
68
+ expect(@scope.requests_matching('s')).to be_empty
69
+ end
70
+
71
+ it "should suggest matches against scopes" do
72
+ expect(@scope.scopes_matching('j')).to eql(['/path/seg/joe/'])
73
+ expect(@scope.scopes_matching('m')).to eql(['/path/seg/mary/'])
74
+ end
75
+
76
+ [
77
+ %w[ / / _ ],
78
+ %w[ /foo / foo ],
79
+ %w[ /foo/ /foo _ ],
80
+ %w[ /foo/bar /foo bar ],
81
+ %w[ /foo/bar/ /foo/bar _ ],
82
+ %w[ /foo/bar/ba /foo/bar ba ],
83
+ %w[ _ /path/seg/ _ ],
84
+ %w[ foo /path/seg/ foo ],
85
+ %w[ foo/ /path/seg/foo _ ],
86
+ %w[ foo/bar /path/seg/foo bar ],
87
+ %w[ foo/bar/ /path/seg/foo/bar _ ],
88
+ %w[ foo/bar/ba /path/seg/foo/bar ba ]
89
+ ].each do |prefix, completing_scope_path, prefix_within_completing_scope|
90
+ prefix = '' if prefix == '_'
91
+ prefix_within_completing_scope = '' if prefix_within_completing_scope == '_'
92
+ it "should properly parse the cd-prefix '#{prefix}' into a completion of the scope-prefix '#{prefix_within_completing_scope}' within the scope '#{completing_scope_path}'" do
93
+ expect(@scope.completing_scope_path_and_prefix(prefix)).to eql([completing_scope_path, prefix_within_completing_scope])
94
+ end
95
+ end
96
+
21
97
 
98
+
22
99
  end
100
+
101
+
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shell do
4
+
5
+ before do
6
+ @shell = Shell.new(:output => FakeOutput.new)
7
+ end
8
+
9
+ it "should cache scopes with the same path" do
10
+ Scopes.should_receive(:from_path).with("/foo", kind_of(Hash))
11
+ @shell.scope_from_path("/foo")
12
+ end
13
+
14
+ describe "printing output" do
15
+
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe HasName do
4
+
5
+ before do
6
+ @obj = Class.new { include HasName }.new
7
+ end
8
+
9
+ it "will not allow setting a name with a space or a '/'" do
10
+ expect { @obj.name = "I have spaces" }.to raise_error(Elasticshell::ArgumentError)
11
+ expect { @obj.name = "I have /" }.to raise_error(Elasticshell::ArgumentError)
12
+ end
13
+
14
+ end
15
+
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe HasVerb do
4
+
5
+ before do
6
+ @obj = Class.new { include HasVerb }.new
7
+ end
8
+
9
+ it "sets 'GET' as the default verb" do
10
+ expect(@obj.verb).to eq("GET")
11
+ end
12
+
13
+ it "will allow setting a new verb" do
14
+ @obj.verb = "POST"
15
+ expect(@obj.verb).to eq("POST")
16
+ end
17
+
18
+ it "will not allow setting an invalid verb" do
19
+ @obj.verb = "SUCK"
20
+ expect(@obj.verb).to eq("GET")
21
+ end
22
+
23
+ end
24
+