cage 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,9 @@
1
1
  require "pry"
2
2
  require "awesome_print"
3
3
  require "faraday"
4
+ require "multi_json"
5
+ require "nokogiri"
4
6
 
5
7
  require "cage/version"
8
+ require "cage/response"
6
9
  require "cage/console"
@@ -1,38 +1,47 @@
1
1
  module Cage
2
2
  class Console
3
3
  CONNECTION_VARIABLES = [:scheme, :domain, :prefix, :headers]
4
+ HTTP_METHOD_REGEX = /^(?:get|post|put|delete)$/i
4
5
 
5
6
  attr_reader :connection, :last_response, *CONNECTION_VARIABLES
6
7
 
8
+
7
9
  def initialize
8
10
  @scheme = "http"
9
- @domain = "duckduckgo.com"
10
- @prefix = "?q="
11
+ @domain = "rubygems.org"
12
+ @prefix = "api/v1/gems/"
13
+ @headers = {}
11
14
  reinitialize_connection
12
15
  end
13
16
 
14
17
  def reinitialize_connection
15
- @connection = Faraday::Connection.new "#{scheme}://#{domain}/#{prefix}"
18
+ @connection = Faraday::Connection.new "#{scheme}://#{domain}/#{prefix}",
19
+ :headers => @headers
16
20
  end
17
21
 
18
22
  def method_missing sym, *args, &block
19
- if sym =~ /^(?:get|post|put|delete)$/i
23
+ if sym =~ HTTP_METHOD_REGEX
20
24
  http sym, *args, &block
21
25
  else
22
26
  super
23
27
  end
24
28
  end
25
29
 
26
- def print_response
27
- ap [ last_response.status, last_response.headers, last_response.body ]
30
+ def respond_to? method
31
+ if method =~ HTTP_METHOD_REGEX
32
+ true
33
+ else
34
+ super
35
+ end
28
36
  end
29
37
 
30
38
  def http method, *args, &block
31
- @last_response = connection.send method, *args, &block
32
- print_response
39
+ @last_response = Cage::Response.new connection.send method, *args, &block
33
40
  end
34
41
 
35
42
  def set convar, value
43
+ raise ArgumentError, "#{convar} isn't a connection variable" unless
44
+ CONNECTION_VARIABLES.include? convar
36
45
  instance_variable_set :"@#{convar}", value
37
46
  reinitialize_connection
38
47
  value
@@ -0,0 +1,58 @@
1
+ module Cage
2
+ class Response
3
+ JSON_MIME_REGEX = %r{(?:application/json|application/x-javascript|
4
+ text/javascript|text/x-javascript|text/x-json)}x
5
+ XML_MIME_REGEX = %r{(?:application/xml|text/xml|application/atom)}x
6
+
7
+ def initialize faraday_response
8
+ @faraday_response = faraday_response
9
+ end
10
+
11
+ def body
12
+ @body ||= parsed_body
13
+ end
14
+
15
+ def status
16
+ @faraday_response.status
17
+ end
18
+
19
+ def headers
20
+ @faraday_response.headers
21
+ end
22
+
23
+ def parsed_body
24
+ case format_for @faraday_response.headers["content-type"]
25
+ when :json
26
+ MultiJson.decode @faraday_response.body
27
+ when :xml
28
+ Nokogiri::XML::Document.new @faraday_response.body
29
+ else
30
+ @faraday_response.body
31
+ end
32
+ end
33
+
34
+ def format_for content_type_string
35
+ case content_type_string
36
+ when JSON_MIME_REGEX
37
+ :json
38
+ when XML_MIME_REGEX
39
+ :xml
40
+ end
41
+ end
42
+
43
+ def inspect
44
+ <<-PRETTY
45
+
46
+ Status: #{@faraday_response.status}
47
+
48
+ Headers:
49
+ #{@faraday_response.headers.map { |k, v| " #{k}: #{v}" }.join "\n"}
50
+
51
+ Body:
52
+ #{body}
53
+
54
+ #<Cage::Response>
55
+ PRETTY
56
+ end
57
+ end
58
+ end
@@ -1,3 +1,3 @@
1
1
  module Cage
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,9 @@
1
+ <?xml version='1.0' encoding='UTF-8'?><entry xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:gd='http://schemas.google.com/g/2005' xmlns:yt='http://gdata.youtube.com/schemas/2007'><id>http://gdata.youtube.com/feeds/api/users/day9tv</id><published>2010-04-22T14:48:11.000-07:00</published><updated>2012-01-26T18:50:49.000-08:00</updated><category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#userProfile'/><category scheme='http://gdata.youtube.com/schemas/2007/channeltypes.cat' term='Guru'/><title type='text'>day9tv</title><content type='text'>I've qualified for the WCG USA finals 7 times, the WCG Grand Finals 3 times, and won the Pan American Championship in 2007 for StarCraft. In StarCraft 2 I play as random.
2
+
3
+ I grew up playing Starcraft with my brother, Nick (Tasteless). With the launch of Starcraft 2, I'm dedicated to helping the eSports movement grow in popularity around the world.
4
+
5
+ Watch my video autobiography here: http://www.youtube.com/watch?v=NJztfsXKcPQ</content><link rel='alternate' type='text/html' href='http://www.youtube.com/profile?user=day9tv'/><link rel='http://gdata.youtube.com/schemas/2007#featured-video' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/iCqwwTfXr1Q'/><link rel='related' type='text/html' href='http://day9.tv'/><link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/users/day9tv'/><author><name>day9tv</name><uri>http://gdata.youtube.com/feeds/api/users/day9tv</uri></author><yt:age>26</yt:age><yt:description>I've qualified for the WCG USA finals 7 times, the WCG Grand Finals 3 times, and won the Pan American Championship in 2007 for StarCraft. In StarCraft 2 I play as random.
6
+
7
+ I grew up playing Starcraft with my brother, Nick (Tasteless). With the launch of Starcraft 2, I'm dedicated to helping the eSports movement grow in popularity around the world.
8
+
9
+ Watch my video autobiography here: http://www.youtube.com/watch?v=NJztfsXKcPQ</yt:description><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.favorites' href='http://gdata.youtube.com/feeds/api/users/day9tv/favorites' countHint='3'/><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.contacts' href='http://gdata.youtube.com/feeds/api/users/day9tv/contacts' countHint='1'/><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.inbox' href='http://gdata.youtube.com/feeds/api/users/day9tv/inbox'/><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.playlists' href='http://gdata.youtube.com/feeds/api/users/day9tv/playlists'/><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.subscriptions' href='http://gdata.youtube.com/feeds/api/users/day9tv/subscriptions' countHint='12'/><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.uploads' href='http://gdata.youtube.com/feeds/api/users/day9tv/uploads' countHint='1210'/><gd:feedLink rel='http://gdata.youtube.com/schemas/2007#user.newsubscriptionvideos' href='http://gdata.youtube.com/feeds/api/users/day9tv/newsubscriptionvideos'/><yt:firstName>Sean Day[9]</yt:firstName><yt:gender>m</yt:gender><yt:hobbies>Starcraft 2, Diablo 3, and other video games!</yt:hobbies><yt:hometown>Leawood, KS</yt:hometown><yt:lastName>Plott</yt:lastName><yt:location>Los Angeles, CA, US</yt:location><yt:occupation>Starcraft 2 Player and Commentator</yt:occupation><yt:school>Harvey Mudd College, USC</yt:school><yt:statistics lastWebAccess='2012-01-18T21:25:07.000-08:00' subscriberCount='250349' videoWatchCount='0' viewCount='12971336' totalUploadViews='38997604'/><media:thumbnail url='http://i2.ytimg.com/i/axar6TBM-94_ezoS00fLkA/1.jpg?v=4f172453'/><yt:username>day9tv</yt:username></entry>
@@ -0,0 +1 @@
1
+ {"name":"rails","downloads":7400862,"version":"3.2.1","version_downloads":1836,"authors":"David Heinemeier Hansson","info":"Ruby on Rails is a full-stack web framework optimized for programmer happiness and sustainable productivity. It encourages beautiful code by favoring convention over configuration.","project_uri":"http://rubygems.org/gems/rails","gem_uri":"http://rubygems.org/gems/rails-3.2.1.gem","homepage_uri":"http://www.rubyonrails.org","wiki_uri":"http://wiki.rubyonrails.org","documentation_uri":"http://api.rubyonrails.org","mailing_list_uri":"http://groups.google.com/group/rubyonrails-talk","source_code_uri":"http://github.com/rails/rails","bug_tracker_uri":"http://github.com/rails/rails/issues","dependencies":{"development":[],"runtime":[{"name":"actionmailer","requirements":"= 3.2.1"},{"name":"actionpack","requirements":"= 3.2.1"},{"name":"activerecord","requirements":"= 3.2.1"},{"name":"activeresource","requirements":"= 3.2.1"},{"name":"activesupport","requirements":"= 3.2.1"},{"name":"bundler","requirements":"~> 1.0"},{"name":"railties","requirements":"= 3.2.1"}]}}
@@ -0,0 +1,72 @@
1
+ require "minitest/autorun"
2
+ require "minitest/pride"
3
+ require "multi_json"
4
+ require "nokogiri"
5
+ require "cage/response"
6
+
7
+ describe Cage::Response do
8
+ let(:faraday_response) do
9
+ MiniTest::Mock.new
10
+ end
11
+ subject { Cage::Response.new faraday_response }
12
+
13
+ it "is created with a response as the constructor argument" do
14
+ subject.must_be_kind_of Cage::Response
15
+ end
16
+
17
+ describe "detects format from content type header" do
18
+ it "detects json" do
19
+ %w[application/json application/x-javascript text/javascript
20
+ text/x-javascript text/x-json].each do |json_content_type|
21
+ subject.format_for(json_content_type).must_equal :json
22
+ end
23
+ end
24
+
25
+ it "detects xml" do
26
+ %w[application/xml text/xml application/atom+xml].each do |xml_content_type|
27
+ subject.format_for(xml_content_type).must_equal :xml
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "parses body text for known body types" do
33
+ let(:json_response) do
34
+ m = MiniTest::Mock.new
35
+ m.expect :headers, { "content-type" => "application/json" }
36
+ m.expect :body, File.read("test/rails-gem.json")
37
+ end
38
+
39
+ let(:xml_response) do
40
+ m = MiniTest::Mock.new
41
+ m.expect :headers, { "content-type" => "application/atom+xml; charset=UTF-8" }
42
+ m.expect :body, File.read("test/day9.xml")
43
+ m
44
+ end
45
+
46
+ let(:html_response) do
47
+ m = MiniTest::Mock.new
48
+ m.expect :headers, { "content-type" => "text/html" }
49
+ m.expect :body, <<-HTML
50
+ <html>
51
+ <head><title>Win</title></head>
52
+ <body>Win</body>
53
+ </html>
54
+ HTML
55
+ m
56
+ end
57
+
58
+ it "parses JSON into a hash" do
59
+ Cage::Response.new(json_response).body.must_be_instance_of Hash
60
+ end
61
+
62
+ it "parses XML into a Nokogiri::XML::Document" do
63
+ Cage::Response.new(xml_response).body.must_be_instance_of(
64
+ Nokogiri::XML::Document)
65
+ end
66
+
67
+ it "keeps the original body string when the filetype isn't detected" do
68
+ Cage::Response.new(html_response).body.must_be_instance_of String
69
+ end
70
+ end
71
+ end
72
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-26 00:00:00.000000000 Z
12
+ date: 2012-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &7681480 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *7681480
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: minitest
16
- requirement: &10129200 !ruby/object:Gem::Requirement
27
+ requirement: &7681040 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ! '>='
@@ -21,10 +32,32 @@ dependencies:
21
32
  version: '0'
22
33
  type: :development
23
34
  prerelease: false
24
- version_requirements: *10129200
35
+ version_requirements: *7681040
36
+ - !ruby/object:Gem::Dependency
37
+ name: mustache
38
+ requirement: &7680620 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *7680620
25
47
  - !ruby/object:Gem::Dependency
26
48
  name: faraday
27
- requirement: &10126820 !ruby/object:Gem::Requirement
49
+ requirement: &7680200 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *7680200
58
+ - !ruby/object:Gem::Dependency
59
+ name: multi_json
60
+ requirement: &7679780 !ruby/object:Gem::Requirement
28
61
  none: false
29
62
  requirements:
30
63
  - - ! '>='
@@ -32,10 +65,21 @@ dependencies:
32
65
  version: '0'
33
66
  type: :runtime
34
67
  prerelease: false
35
- version_requirements: *10126820
68
+ version_requirements: *7679780
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: &7679360 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *7679360
36
80
  - !ruby/object:Gem::Dependency
37
81
  name: pry
38
- requirement: &10125360 !ruby/object:Gem::Requirement
82
+ requirement: &7678940 !ruby/object:Gem::Requirement
39
83
  none: false
40
84
  requirements:
41
85
  - - ! '>='
@@ -43,10 +87,10 @@ dependencies:
43
87
  version: '0'
44
88
  type: :runtime
45
89
  prerelease: false
46
- version_requirements: *10125360
90
+ version_requirements: *7678940
47
91
  - !ruby/object:Gem::Dependency
48
92
  name: awesome_print
49
- requirement: &10124020 !ruby/object:Gem::Requirement
93
+ requirement: &7678520 !ruby/object:Gem::Requirement
50
94
  none: false
51
95
  requirements:
52
96
  - - ! '>='
@@ -54,7 +98,7 @@ dependencies:
54
98
  version: '0'
55
99
  type: :runtime
56
100
  prerelease: false
57
- version_requirements: *10124020
101
+ version_requirements: *7678520
58
102
  description: ! 'Curl can be a bit unfriendly, especially to developers just starting
59
103
  out. Cage
60
104
 
@@ -70,15 +114,14 @@ executables:
70
114
  extensions: []
71
115
  extra_rdoc_files: []
72
116
  files:
73
- - .gitignore
74
- - Gemfile
75
- - README.md
76
- - Rakefile
77
- - bin/cage
78
- - cage.gemspec
79
117
  - lib/cage.rb
80
118
  - lib/cage/console.rb
81
119
  - lib/cage/version.rb
120
+ - lib/cage/response.rb
121
+ - test/day9.xml
122
+ - test/rails-gem.json
123
+ - test/response_test.rb
124
+ - bin/cage
82
125
  homepage: https://github.com/nuclearsandwich/cage
83
126
  licenses: []
84
127
  post_install_message:
@@ -103,4 +146,7 @@ rubygems_version: 1.8.10
103
146
  signing_key:
104
147
  specification_version: 3
105
148
  summary: A Faraday Cage for your HTTP Interactions.
106
- test_files: []
149
+ test_files:
150
+ - test/day9.xml
151
+ - test/rails-gem.json
152
+ - test/response_test.rb
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in cage.gemspec
4
- gemspec
data/README.md DELETED
@@ -1,75 +0,0 @@
1
- Cage
2
- ====
3
-
4
- *A Faraday Cage for your HTTP Interactions.*
5
-
6
-
7
- Getting It
8
- ----------
9
-
10
- Once Cage hits 0.1.0, it will be released as a gem. Then you can install it
11
- globally with `gem install cage`. Better still, add it to the `Gemfile` of your
12
- project.
13
-
14
- ```ruby
15
- group :development do
16
- gem "cage"
17
- end
18
- ```
19
-
20
- Using It
21
- --------
22
-
23
- Running `cage` will begin a console session. Cage is like a specialized IRB, but
24
- for HTTP interactions. Imagine that you are working on an API. [Rack::Test][rt]
25
- is an awesome tool but when you try to use it interactively you get an
26
- interesting display of fireworks(read: stacktraces). Cage is based on a utility
27
- script I wrote while working on a REST API. Some days, you just want to monkey
28
- around with your work.
29
-
30
- When you run Cage, you're dropped into a special Pry terminal with HTTP related
31
- commands available.
32
-
33
- ```
34
- [
35
- [0] 200,
36
- [1] {
37
- "server" => "nginx",
38
- "date" => "Thu, 26 Jan 2012 19:56:30 GMT",
39
- "content-type" => "application/x-javascript; charset=UTF-8",
40
- "transfer-encoding" => "chunked",
41
- "connection" => "close",
42
- "expires" => "Thu, 26 Jan 2012 19:56:31 GMT",
43
- "cache-control" => "max-age=1"
44
- },
45
- [2] "{\"Definition\":\"Hackers do *not* generally use this to mean FUBAR..."
46
- ]
47
- ```
48
-
49
- Configuring It
50
- --------------
51
-
52
- Cage will look first for a global `~/.cagerc.rb` file, then for a localr
53
- `./cagerc.rb` in the working directory. Both are essentially instance_eval'd
54
- into your new Cage console so anything that works in Cage will work in a config.
55
- The global one is run first, so you can overload it with a local config. The
56
- local config is for setting up project defaults, you can even automate your
57
- initial authentication if you want.
58
-
59
- Roadmap
60
- -------
61
-
62
- - 0.0.1 Have a working, if ugly and hacky console.
63
-
64
- - 0.0.2 Write tests for whatever I can.
65
-
66
- - 0.1.0 Clean up the prompt and solidify the command set. Support .cagerc files.
67
-
68
- - 0.2.0 Use decorators to pretty print responses.
69
-
70
- - 0.3.0 Auto detect and parse incoming body types like XML, JSON, wwwurlencode.
71
-
72
- - 0.4.0 Make it easier to send XML, YAML, and JSON formatted bodies.
73
-
74
- - 0.5.0 ???
75
-
data/Rakefile DELETED
@@ -1 +0,0 @@
1
- require "bundler/gem_tasks"
@@ -1,27 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "cage/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "cage"
7
- s.version = Cage::VERSION
8
- s.authors = ["Steven! Ragnarök"]
9
- s.email = ["steven@nuclearsandwich.com"]
10
- s.homepage = "https://github.com/nuclearsandwich/cage"
11
- s.summary = "A Faraday Cage for your HTTP Interactions."
12
- s.description = <<-DESC
13
- Curl can be a bit unfriendly, especially to developers just starting out. Cage
14
- wraps Faraday and Pry in order to provide an attractive and helpful interface to
15
- the web APIs in your life.
16
- DESC
17
-
18
- s.files = `git ls-files`.split("\n")
19
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
- s.require_paths = ["lib"]
22
-
23
- s.add_development_dependency "minitest"
24
- s.add_runtime_dependency "faraday"
25
- s.add_runtime_dependency "pry"
26
- s.add_runtime_dependency "awesome_print"
27
- end