ruby-resty 0.0.1.pre → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  Ruby-Resty is a ruby port of [Resty][1], which provides a simple way to interact with RESTful services. Ruby-Resty was
6
6
  ported to be shell agnostic and for easier community development.
7
7
 
8
- The resty REPL is built on top of [Pry][2] for built-in niceties like history, state management, shell interaction,
9
- etc.
8
+ The resty REPL is built on top of [Pry][2] for niceties like [Custom Commands][3], history management, interactive
9
+ help system, and most importantly, using plain old Ruby.
10
10
 
11
11
  # Installation
12
12
 
@@ -36,20 +36,20 @@ If you would like headers to be attached with every request, you can do so:
36
36
  ruby-resty --host http://nyan.cat --headers X-NYAN-CAT-SECRET-KEY=nyan_nyan X-NYAN-TYPE=octo
37
37
  ```
38
38
 
39
- ### REPL Options
39
+ ### Options
40
40
 
41
41
  The REPL accepts the following options that are attached to each request. This provides an easier way to make multiple
42
42
  requests without having to specify headers everytime.
43
43
 
44
44
  ```
45
- --alias, -a <s>: The per-host entry to use in ~/.ruby_resty.yml
46
- --host, -h: The hostname of the REST service. Ex: http://nyan.cat
47
- --headers, -H: The headers attached to each request. Ex: X-NYAN-CAT-SECRET-KEY=nyan_nyan
48
- --verbose, -v: Verbose mode
49
- --config, -c : Use host information from ~/.ruby_resty.yml
45
+ --alias, -a : The per-host entry to use in ~/.ruby_resty.yml
46
+ --host, -h : The hostname of the REST service. Ex: http://nyan.cat
47
+ --headers, -H : The headers attached to each request. Ex: X-NYAN-CAT-SECRET-KEY=nyan_nyan
48
+ --verbose, -v : Verbose mode
49
+ --config, -c : Use host information from ~/.ruby_resty.yml
50
50
  ```
51
51
 
52
- ### Making Requests
52
+ ### Requests
53
53
 
54
54
  Requests can be sent to services by specifying a path and any associated JSON data. The following methods are
55
55
  supported:
@@ -58,6 +58,7 @@ supported:
58
58
  GET [path]
59
59
  PUT [path] [data]
60
60
  POST [path] [data]
61
+ PATH [path] [data]
61
62
  HEAD [path]
62
63
  DELETE [path]
63
64
  OPTIONS [path]
@@ -79,7 +80,7 @@ resty> GET /api/cats/1
79
80
  Or you can send a `POST` request, which does require a body:
80
81
 
81
82
  ```
82
- resty> POST /api/cats '{"nyan_cat": {"name": "oliver", "color": "blue"} }'
83
+ resty> POST /api/cats {"nyan_cat": {"name": "oliver", "color": "blue"} }
83
84
  {
84
85
  "nyan_cat": {
85
86
  "name": "oliver"
@@ -88,12 +89,44 @@ resty> POST /api/cats '{"nyan_cat": {"name": "oliver", "color": "blue"} }'
88
89
  }
89
90
  ```
90
91
 
91
- ### REPL Commands
92
+ Ruby hashes are also accepted:
93
+ ```
94
+ resty> POST /api/cats {nyan_cat: {name: "oliver", color: "blue"} }
95
+ ```
96
+
97
+ As are ruby variables:
98
+ ```
99
+ resty> data = {nyan_cat: {name: "oliver", color: "blue"} }
100
+ resty> POST /api/cats data
101
+ ```
102
+
103
+ ### Responses
104
+
105
+ After a request is returned, the resulting JSON response is parsed into a ruby hash and stored in `response`:
106
+
107
+ ```
108
+ resty> POST /api/cats {nyan_cat: {name: "oliver", color: "blue"} }
109
+ resty> response
110
+ {
111
+ "nyan_cat" => {
112
+ "name" => "oliver"
113
+ "color" => "blue"
114
+ }
115
+ }
116
+ ```
92
117
 
93
- There are also REPL specific commands ruby-resty is aware of. For example, you can type `exit` to quit the REPL.
118
+ Since the response object is a ruby hash, the values can be changed and sent on another request:
94
119
 
95
120
  ```
96
- exit: Quits the REPL
121
+ resty> response
122
+ {
123
+ "nyan_cat" => {
124
+ "name" => "oliver"
125
+ "color" => "blue"
126
+ }
127
+ }
128
+ resty> response["nyan_cat"]["name"] = "grumpy"
129
+ resty> PUT /api/cats response
97
130
  ```
98
131
 
99
132
  ## Per Host Configuration
@@ -141,3 +174,4 @@ Don't forget to run the tests with `rake`
141
174
 
142
175
  [1]: https://github.com/micha/resty
143
176
  [2]: https://github.com/pry/pry
177
+ [3]: https://github.com/pry/pry/wiki/Custom-commands
@@ -1,30 +1,99 @@
1
- Pry::Commands.create_command /(get|put|post|delete|head|option|patch|trace)/i do
2
- description "Echo the input: echo [ARGS]"
1
+ Pry::Commands.create_command /(get|put|post|delete|head|option|patch|trace)/i, listing: "method-command" do
2
+ description "Performs an HTTP request to the specified path: METHOD PATH [DATA]"
3
+
4
+ banner <<-BANNER
5
+ Performs an HTTP request to the specified path with optional data: METHOD PATH [DATA]
6
+
7
+ Examples:
8
+ ---------
9
+ GET /api/nyan
10
+ DELETE /api/nyan
11
+ PUT /api/nyan {"name": "Jan"}
12
+ POST /api/nyan {"name": "Jeff"}
13
+
14
+ Ruby hashes can also be used:
15
+ -----------------------------
16
+ PUT /api/nyan {name: "Jan"}
17
+
18
+ And even ruby variables:
19
+ ------------------------
20
+ data = {name: "j3"}
21
+ PUT /api/nyan data
22
+
23
+ BANNER
24
+
25
+ command_options(
26
+ shellwords: false
27
+ )
3
28
 
4
29
  def process
5
- params = { method: args[0], path: args[1], data: data(args) }
6
-
7
- Resty::Request.new(cli_options, params).tap do |request|
8
- if !request.path_valid?
9
- output.puts("A path must be included. Ex: http://nyan.cat/<path>")
10
- elsif request.data_required? && !request.data_valid?
11
- output.puts("Invalid data. Check if you have valid JSON at: http://jsonlint.com/")
12
- else
13
- request.send_request do |response, request|
14
- method_output = Resty::Commands::MethodOutput.new(cli_options.verbose?, response, request)
15
- output.puts(method_output.generate)
16
- end
30
+ if path_missing?
31
+ output.puts("Missing path\n\n")
32
+ run("help method-command")
33
+ elsif data_invalid?
34
+ output.puts("Invalid data\n\n")
35
+ run("help method-command")
36
+ else
37
+ params = { method: http_method, path: path, data: data }
38
+ request = Resty::Request.new(cli_options, params)
39
+ request.send_request do |response, request|
40
+ method_output = Resty::Commands::MethodOutput.new(cli_options.verbose?, response, request)
41
+ output.puts(method_output.generate)
42
+ eval_response(response)
17
43
  end
18
44
  end
19
45
  end
20
46
 
21
47
  private
22
48
 
23
- def data(args)
24
- args[2] ? args[2..-1].join(" ") : ""
49
+ def path_missing?
50
+ path.nil?
51
+ end
52
+
53
+ def data_invalid?
54
+ data.nil? && Resty::Request.data_required?(http_method)
55
+ end
56
+
57
+ def eval_response(response)
58
+ target.eval("response = #{JSON.parse(response)}")
59
+ rescue
60
+ target.eval("response = nil")
61
+ end
62
+
63
+ def build_data
64
+ return nil unless args[2]
65
+
66
+ input = args[2..-1].join(" ")
67
+ parse_json(input) || eval_ruby(input) || nil
68
+ end
69
+
70
+ def eval_ruby(input)
71
+ parsed_input = target.eval(input)
72
+ if parsed_input.is_a?(String)
73
+ JSON.parse(parsed_input)
74
+ else
75
+ parsed_input
76
+ end
77
+ rescue
78
+ end
79
+
80
+ def parse_json(input)
81
+ JSON.parse(input) rescue nil
25
82
  end
26
83
 
27
84
  def cli_options
28
85
  @cli_options ||= eval "self", target
29
86
  end
87
+
88
+ def http_method
89
+ args[0]
90
+ end
91
+
92
+ def path
93
+ args[1]
94
+ end
95
+
96
+ def data
97
+ @data ||= build_data
98
+ end
30
99
  end
@@ -18,6 +18,8 @@ module Resty
18
18
 
19
19
  output += build_line("Response Code: #{response.code}")
20
20
  response.headers.each { |key, value| output += build_line("#{key}: #{value}") }
21
+ else
22
+ output += build_line("Response Code: #{response.code}")
21
23
  end
22
24
 
23
25
  output += pretty_json(response)
data/lib/resty/request.rb CHANGED
@@ -3,33 +3,22 @@ require 'json'
3
3
  module Resty
4
4
  class Request
5
5
 
6
- attr_accessor :data, :data_valid
7
- attr_reader :params, :printer, :cli_options
6
+ attr_reader :params, :cli_options
8
7
 
9
8
  def initialize(cli_options, params)
10
9
  @cli_options = cli_options
11
10
  @params = params
12
- @data_valid = false
13
- load_data
14
11
  end
15
12
 
16
13
  def send_request
17
- if data_required?
14
+ if Resty::Request.data_required?(method)
18
15
  RestClient.send(method, url, data, cli_options.headers) { |*params| yield params }
19
16
  else
20
17
  RestClient.send(method, url, cli_options.headers) { |*params| yield params }
21
18
  end
22
19
  end
23
20
 
24
- def path_valid?
25
- path.nil? ? false : true
26
- end
27
-
28
- def data_valid?
29
- data_valid
30
- end
31
-
32
- def data_required?
21
+ def self.data_required?(method)
33
22
  (method =~ %r{put|post|patch}) == 0
34
23
  end
35
24
 
@@ -47,11 +36,8 @@ module Resty
47
36
  params[:path]
48
37
  end
49
38
 
50
- def load_data
51
- self.data = JSON.parse(params[:data]) || {}
52
- self.data_valid = true
53
- rescue => e
54
- self.data = {}
39
+ def data
40
+ params[:data]
55
41
  end
56
42
  end
57
43
  end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Resty
2
- VERSION = "0.0.1.pre"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -86,6 +86,7 @@ describe Resty::CliOptions do
86
86
 
87
87
  context "alias doesn't exist" do
88
88
  it "raises ConfigFileError" do
89
+ YAML.stubs(:load_file).returns({"ice_cream" => {} } )
89
90
  File.stubs(:exist?).returns(true)
90
91
  expect { Resty::CliOptions.new(alias: "nyan") }.to raise_error(Resty::ConfigFileError)
91
92
  end
@@ -2,69 +2,156 @@ require 'spec_helper'
2
2
  require 'json'
3
3
 
4
4
  describe "MethodCommand" do
5
+ let(:request) { stub }
6
+ let(:response) { stub }
7
+ let(:returned_request) { stub }
8
+
5
9
  before(:each) do
6
10
  Resty::Request.stubs(:new).returns(request)
11
+ Object.any_instance.stubs(:verbose?).returns(false)
7
12
  end
8
13
 
9
14
  context "command regex" do
10
- let(:request) { stub(path_valid?: false) }
15
+ before(:each) do
16
+ request.stubs(:send_request)
17
+ end
11
18
 
12
19
  it "responds lower case method" do
13
20
  %w{get put post delete head option patch trace}.each do |method|
14
- pry_eval(method)
21
+ pry_eval("#{method}").start_with?("Missing").should be_true
15
22
  end
16
- Resty::Request.should have_received(:new).times(8)
17
23
  end
18
24
 
19
25
  it "responds to case-insentivity" do
20
26
  %w{GET Put PoSt delete head option patch trace}.each do |method|
21
- pry_eval(method)
27
+ pry_eval("#{method}").start_with?("Missing").should be_true
22
28
  end
23
- Resty::Request.should have_received(:new).times(8)
24
29
  end
25
30
  end
26
31
 
27
- context "process" do
28
- context "invalid path" do
29
- let(:request) { stub(path_valid?: false) }
32
+ context "invalid path" do
33
+ it "doesn't send request" do
34
+ pry_eval("get")
35
+ request.should have_received(:send_request).never
36
+ end
37
+ end
38
+
39
+ context "invalid data" do
40
+ context "request requires data" do
41
+ before(:each) do
42
+ pry_eval("post /api/nyan")
43
+ end
44
+
45
+ it "never sends request" do
46
+ Resty::Request.should have_received(:new).never
47
+ end
48
+ end
30
49
 
31
- it "doesn't send request" do
32
- pry_eval("get")
33
- request.should have_received(:send_request).never
50
+ context "request doesn't require data" do
51
+ before(:each) do
52
+ Resty::Commands::MethodOutput.stubs(:new).returns(stub(:generate))
53
+ Resty::Request.stubs(:new).returns(request)
54
+ request.stubs(:send_request).yields(response, request)
55
+ pry_eval("get /api/nyan")
56
+ end
57
+
58
+ it "returns sends request with nil data" do
59
+ params = { method: "get", path: "/api/nyan", data: nil }
60
+ Resty::Request.should have_received(:new).with(anything, params)
34
61
  end
35
62
  end
63
+ end
64
+
65
+ context "process" do
66
+ let(:method_output) { stub(generate: "")}
67
+
68
+ before(:each) do
69
+ Resty::Commands::MethodOutput.stubs(:new).returns(method_output)
70
+ request.stubs(:send_request).yields(response, request)
71
+ end
72
+
73
+ context "with data" do
74
+ context "as json string" do
75
+ before(:each) do
76
+ pry_eval("get /api/nyan {\"foo\": \"bar\"}")
77
+ end
36
78
 
37
- context "invalid data" do
38
- let(:request) { stub(path_valid?: :true, data_valid?: false, data_required?: true) }
79
+ it "creates request" do
80
+ params = { method: "get", path: "/api/nyan", data: {"foo" => "bar"} }
81
+ Resty::Request.should have_received(:new).with(anything, params)
82
+ end
39
83
 
40
- it "doesn't send request" do
41
- pry_eval("get")
42
- request.should have_received(:send_request).never
84
+ it "sends request" do
85
+ Resty::Commands::MethodOutput.should have_received(:new).with(false, response,request)
86
+ method_output.should have_received(:generate)
87
+ end
43
88
  end
44
89
  end
45
-
46
- context "valid arguments" do
47
- let(:response) { stub }
48
- let(:request) { stub(path_valid?: :true, data_valid?: true, data_required?: true) }
49
- let(:params) { { method: "get", path: "/api/nyan", data: "#{JSON.dump(foo: 'bar')}"} }
50
- let(:method_output) { stub(generate: "")}
51
90
 
91
+ context "as ruby hash" do
52
92
  before(:each) do
53
- Resty::Commands::MethodOutput.stubs(:new).returns(method_output)
54
- Object.any_instance.stubs(:verbose?).returns(false)
55
- request.stubs(:send_request).yields(response, request)
56
- pry_eval("get /api/nyan '#{JSON.dump(foo: 'bar')}'")
93
+ pry_eval("get /api/nyan {foo: 'bar'}")
57
94
  end
58
95
 
59
96
  it "creates request" do
97
+ params = { method: "get", path: "/api/nyan", data: {foo: "bar"} }
60
98
  Resty::Request.should have_received(:new).with(anything, params)
61
99
  end
62
100
 
63
101
  it "sends request" do
64
102
  Resty::Commands::MethodOutput.should have_received(:new).with(false, response,request)
103
+ method_output.should have_received(:generate)
65
104
  end
105
+ end
66
106
 
67
- it "generates output" do
107
+ context "as variable" do
108
+ context "with ruby hash" do
109
+ before(:each) do
110
+ Object.any_instance.stubs(:foo).returns(foo: "bar")
111
+ pry_eval("get /api/nyan foo")
112
+ end
113
+
114
+ it "creates request" do
115
+ params = { method: "get", path: "/api/nyan", data: {foo: "bar"} }
116
+ Resty::Request.should have_received(:new).with(anything, params)
117
+ end
118
+
119
+ it "sends request" do
120
+ Resty::Commands::MethodOutput.should have_received(:new).with(false, response,request)
121
+ method_output.should have_received(:generate)
122
+ end
123
+ end
124
+
125
+ context "with json string" do
126
+ before(:each) do
127
+ Object.any_instance.stubs(:foo).returns('{"foo": "bar"}')
128
+ pry_eval("get /api/nyan foo")
129
+ end
130
+
131
+ it "creates request" do
132
+ params = { method: "get", path: "/api/nyan", data: {"foo" => "bar"} }
133
+ Resty::Request.should have_received(:new).with(anything, params)
134
+ end
135
+
136
+ it "sends request" do
137
+ Resty::Commands::MethodOutput.should have_received(:new).with(false, response,request)
138
+ method_output.should have_received(:generate)
139
+ end
140
+ end
141
+ end
142
+
143
+ context "without data" do
144
+ before(:each) do
145
+ pry_eval("get /api/nyan")
146
+ end
147
+
148
+ it "creates request" do
149
+ params = { method: "get", path: "/api/nyan", data: nil }
150
+ Resty::Request.should have_received(:new).with(anything, params)
151
+ end
152
+
153
+ it "sends request" do
154
+ Resty::Commands::MethodOutput.should have_received(:new).with(false, response,request)
68
155
  method_output.should have_received(:generate)
69
156
  end
70
157
  end
@@ -6,9 +6,8 @@ describe Resty::Commands::MethodOutput do
6
6
  let(:response) { JSON.dump({foo: "bar"}) }
7
7
 
8
8
  context "#print" do
9
- it "returns empty string with no json output" do
10
- method_output = Resty::Commands::MethodOutput.new(false, "", request)
11
- method_output.generate.should eq("")
9
+ before(:each) do
10
+ response.stubs(:code).returns(200)
12
11
  end
13
12
 
14
13
  context "non-verbose" do
@@ -16,6 +15,7 @@ describe Resty::Commands::MethodOutput do
16
15
 
17
16
  it "returns output" do
18
17
  output = <<-eos.unindent
18
+ > Response Code: 200
19
19
  {
20
20
  "foo": "bar"
21
21
  }
@@ -33,7 +33,6 @@ describe Resty::Commands::MethodOutput do
33
33
  request.stubs(:method).returns("get")
34
34
  request.stubs(:url).returns("foo.com")
35
35
  request.stubs(:processed_headers).returns(header: "value", header2: "value2")
36
- response.stubs(:code).returns(200)
37
36
  response.stubs(:headers).returns(response_header: "value", response_header2: "value2")
38
37
  end
39
38
 
@@ -61,7 +61,7 @@ describe Resty::Request do
61
61
  end
62
62
 
63
63
  context "PUT" do
64
- let(:params) { { method: "put", path: "/api/merchants", data: JSON.dump(foo: "bar") } }
64
+ let(:params) { { method: "put", path: "/api/merchants", data: {"foo" => "bar"} } }
65
65
 
66
66
  before(:each) do
67
67
  Resty::Request.new(cli_options, params).send_request
@@ -74,7 +74,7 @@ describe Resty::Request do
74
74
  end
75
75
 
76
76
  context "POST" do
77
- let(:params) { { method: "post", path: "/api/merchants", data: JSON.dump(foo: "bar") } }
77
+ let(:params) { { method: "post", path: "/api/merchants", data: {"foo" => "bar"} } }
78
78
 
79
79
  before(:each) do
80
80
  Resty::Request.new(cli_options, params).send_request
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-resty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre
5
- prerelease: 6
4
+ version: 0.1.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Austen Ito
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-01 00:00:00.000000000 Z
12
+ date: 2013-07-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: active_support
@@ -232,7 +232,6 @@ files:
232
232
  - spec/lib/resty/cli_options_spec.rb
233
233
  - spec/lib/resty/commands/method_command_spec.rb
234
234
  - spec/lib/resty/commands/method_output_spec.rb
235
- - spec/lib/resty/repl_spec.rb
236
235
  - spec/lib/resty/request_spec.rb
237
236
  - spec/spec_helper.rb
238
237
  - templates/ruby_resty.yml
@@ -251,9 +250,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
251
250
  required_rubygems_version: !ruby/object:Gem::Requirement
252
251
  none: false
253
252
  requirements:
254
- - - ! '>'
253
+ - - ! '>='
255
254
  - !ruby/object:Gem::Version
256
- version: 1.3.1
255
+ version: '0'
257
256
  requirements: []
258
257
  rubyforge_project:
259
258
  rubygems_version: 1.8.24
@@ -264,6 +263,5 @@ test_files:
264
263
  - spec/lib/resty/cli_options_spec.rb
265
264
  - spec/lib/resty/commands/method_command_spec.rb
266
265
  - spec/lib/resty/commands/method_output_spec.rb
267
- - spec/lib/resty/repl_spec.rb
268
266
  - spec/lib/resty/request_spec.rb
269
267
  - spec/spec_helper.rb
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Resty::Repl do
4
- let(:printer) { stub(write: "") }
5
-
6
- end