rapidash 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a24e88b9990655513929505bdfded740ae3bc5d0
4
- data.tar.gz: 10b580d030b0db97f695b353bdcbc8f4f5046fa9
3
+ metadata.gz: a317197b608c00d1116ad4be65b62238b0a98034
4
+ data.tar.gz: cdc69d6da7a4e33c58d83d0fc89e1b0a70cfb72c
5
5
  SHA512:
6
- metadata.gz: 737c8447bca4d1c56110fa957f7cfe5fa0e8752baf9a7974f8a3e5cbec657e6f30bd0740a1ecbdffe17d0b1a57dc09a667e86243f5a69d511871713cea291fb8
7
- data.tar.gz: dcaa32a236b129363fc317b2219c69954e85216d10c9403b8431730b8dfd2e40b0d42014374497e4eaeba94532d318cf440405ef61416bedaed8914d4b962d09
6
+ metadata.gz: c85000a1ed1351fadcfc1567a4469d54c4920a23eb8e6aa6e60de579b2b6abdd4867179eb7bbc2c844c6c9d745d8ec95ef4114d6c05312c4abdb4e33a3a06751
7
+ data.tar.gz: 71ef9f5d5e1669de47f6681a86c9c541b7712d9cc29b57add9cc4cd86ac15acbb73f20fc0c972881bfebbd38088dc86c92e720f9476781c84cbe2766d1ed94cc
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  *.sw[a-z]
19
+ .idea
data/README.md CHANGED
@@ -25,6 +25,10 @@ A screencast on Rapidash is available to watch in mp4 and ogv formats.
25
25
  * [Rapidash Screencast mp4](http://screencasts.gazler.com/rapidash.mp4)
26
26
  * [Rapidash Screencast ogv](http://screencasts.gazler.com/rapidash.ogv)
27
27
 
28
+ ### Sample Rails app
29
+
30
+ A sample rails app is available at [https://github.com/Gazler/rapidash-tester](https://github.com/Gazler/rapidash-tester) it provides a rails server and a Rapidash client. Please note that the client is also used as a form of integration test for rapidash.
31
+
28
32
  ### Resources
29
33
 
30
34
  Resources can be defined as follows:
@@ -37,7 +41,7 @@ end
37
41
  The URL of the resource will be inferred from the class name. In this case Users. If you want to override that, you can with the url method.
38
42
 
39
43
  ```ruby
40
- class Users < Rapidash::Base
44
+ class User < Rapidash::Base
41
45
  url :members # or url "members" is also supported
42
46
  end
43
47
  ```
@@ -45,10 +49,10 @@ end
45
49
  Resources can exist inside other resources. For example, on Github, a user has repositories. The following could be how you build the resources:
46
50
 
47
51
  ```ruby
48
- class Repos < Rapidash::Base
52
+ class Repo < Rapidash::Base
49
53
  end
50
54
 
51
- class Users < Rapidash::Base
55
+ class User < Rapidash::Base
52
56
  resource :repos
53
57
  end
54
58
  ```
@@ -58,7 +62,7 @@ end
58
62
  A root element can be set for create and post actions
59
63
 
60
64
  ```ruby
61
- class Posts < Rapidash::Base
65
+ class Post < Rapidash::Base
62
66
  end
63
67
 
64
68
  client.posts.create!({:post => {:name => "a post"}})
@@ -67,13 +71,28 @@ client.posts.create!({:post => {:name => "a post"}})
67
71
  With a root element, the code would look like this:
68
72
 
69
73
  ```ruby
70
- class Posts < Rapidash::Base
74
+ class Post < Rapidash::Base
71
75
  root :post
72
76
  end
73
77
 
74
78
  client.posts.create!(:name => "a post")
75
79
  ```
76
80
 
81
+ ### Class Names and Classes In Different Modules
82
+
83
+ If you wish to use a class in a different module or a class with a different name as the class for your resource then you can use the `:class_name` option.
84
+
85
+ ```ruby
86
+ module MyModule
87
+ class MyResource < Rapidash::Base
88
+ end
89
+ end
90
+
91
+ class AnotherResource < Rapidash::Base
92
+ resource :my_cool_resource, :class_name => "MyModule::MyResource"
93
+ end
94
+ ```
95
+
77
96
  ### Client
78
97
 
79
98
  The main thing a client must do is define a method, `oauth` and `http` are currently supported. You can also define resources which links a resource as defined above to the client.
@@ -115,6 +134,7 @@ client.users(1).delete! #DELETE requst to /users
115
134
  require 'rapidash'
116
135
 
117
136
  class Me < Rapidash::Base
137
+ url "me"
118
138
  end
119
139
 
120
140
  class Facebook < Rapidash::Client
@@ -136,9 +156,9 @@ p client.me!.first_name #Gary
136
156
  ```ruby
137
157
  require 'rapidash'
138
158
 
139
- class Repos < Rapidash::Base
159
+ class Repo < Rapidash::Base
140
160
 
141
- class Users < Rapidash::Base
161
+ class User < Rapidash::Base
142
162
  resource :repos
143
163
  end
144
164
 
@@ -153,13 +173,30 @@ p client.users!("Gazler").name #Gary Rennie
153
173
  p client.users("Gazler").repos![0].name #Githug
154
174
  ```
155
175
 
176
+ ### HTTP Authentication
177
+
178
+ ```ruby
179
+ require 'rapidash'
180
+
181
+ class Client < Rapidash::Client
182
+ method :http
183
+ site "your site"
184
+ end
185
+
186
+ client = Client.new({
187
+ :login => "your login",
188
+ :password => "your password",
189
+ })
190
+ ```
191
+
156
192
  ## Contributing
157
193
 
158
194
  1. Fork it
159
195
  2. Create your feature branch (`git checkout -b my-new-feature`)
160
196
  3. Commit your changes (`git commit -am 'Add some feature'`)
161
- 4. Push to the branch (`git push origin my-new-feature`)
162
- 5. Create new Pull Request
197
+ 4. Write your tests, start and check coverage: open file coverage/index.html in your browser. Must be 100.0% covered
198
+ 5. Push to the branch (`git push origin my-new-feature`)
199
+ 6. Create new Pull Request (into the development branch)
163
200
 
164
201
  ## Credits
165
202
 
@@ -1,23 +1,23 @@
1
1
  require 'rapidash'
2
2
 
3
- class Repos < Rapidash::Base
3
+ class Repo < Rapidash::Base
4
4
  def repo!(owner, repo)
5
5
  self.url += "/#{owner}/#{repo}"
6
6
  call!
7
7
  end
8
8
  end
9
9
 
10
- class Users < Rapidash::Base
10
+ class User < Rapidash::Base
11
11
  resource :repos
12
12
  end
13
13
 
14
- class Emojis < Rapidash::Base
14
+ class Emoji < Rapidash::Base
15
15
  end
16
16
 
17
- class Events < Rapidash::Base
17
+ class Event < Rapidash::Base
18
18
  end
19
19
 
20
- class Gists < Rapidash::Base
20
+ class Gist < Rapidash::Base
21
21
 
22
22
  def public!
23
23
  self.url += "/public"
@@ -26,7 +26,7 @@ class Gists < Rapidash::Base
26
26
 
27
27
  end
28
28
 
29
- class Organisations < Rapidash::Base
29
+ class Organisation < Rapidash::Base
30
30
  url "orgs"
31
31
  end
32
32
 
@@ -1,10 +1,12 @@
1
+ #Required for pluralization and camelcasing
2
+ require "active_support/core_ext/string"
3
+
1
4
  require "rapidash/version"
2
5
 
3
6
  require "rapidash/errors"
4
7
 
5
8
  require "rapidash/response"
6
9
 
7
- require "rapidash/clientable"
8
10
  require "rapidash/resourceable"
9
11
  require "rapidash/client"
10
12
 
@@ -1,6 +1,5 @@
1
1
  module Rapidash
2
2
  class Base
3
-
4
3
  include Urlable
5
4
  include Resourceable
6
5
 
@@ -24,7 +23,7 @@ module Rapidash
24
23
 
25
24
  @options ||= {}
26
25
  @options.merge!(options || {})
27
- @url = "#{base_url}#{self.class.to_s.split("::")[-1].downcase}"
26
+ @url = "#{base_url}#{resource_url}"
28
27
  @url += "/#{@id}" if @id
29
28
  end
30
29
 
@@ -55,21 +54,24 @@ module Rapidash
55
54
  client.send(method, url, options)
56
55
  end
57
56
 
57
+
58
58
  private
59
59
 
60
60
  def set_body!(params)
61
61
  if self.class.root_element
62
- options[:body] = {self.class.root_element => params}.to_json
62
+ options[:body] = {self.class.root_element => params}
63
63
  else
64
- options[:body] = params.to_json
64
+ options[:body] = params
65
65
  end
66
66
  end
67
67
 
68
68
  def base_url
69
- if old_url = self.options[:previous_url]
70
- return "#{old_url}/"
71
- end
72
- ""
69
+ old_url = self.options[:previous_url]
70
+ old_url ? "#{old_url}/" : ""
71
+ end
72
+
73
+ def resource_url
74
+ self.options[:url] || self.class.to_s.split("::")[-1].downcase.pluralize
73
75
  end
74
76
  end
75
77
  end
@@ -1,12 +1,65 @@
1
1
  module Rapidash
2
2
  class Client
3
- include Clientable
4
3
  include Resourceable
5
4
 
5
+ attr_accessor :extension
6
+
6
7
  def initialize
7
8
  raise ConfigurationError.new "Missing Method, define using `method` on your client"
8
9
  end
9
10
 
11
+ class << self
12
+ attr_accessor :patch, :raise_error
13
+
14
+ def method(method)
15
+ case method
16
+ when :http then include HTTPClient
17
+ when :oauth then include OAuthClient
18
+ when :test then include TestClient
19
+ else
20
+ raise ConfigurationError.new "Invalid API Authentication Method"
21
+ end
22
+ end
23
+
24
+ def use_patch
25
+ @patch = true
26
+ end
27
+
28
+ def extension(extension = nil)
29
+ @extension ||= extension
30
+ end
31
+
32
+ def site(site = nil)
33
+ @site ||= site
34
+ end
35
+
36
+ def raise_errors
37
+ @raise_error = true
38
+ end
39
+ end
40
+
41
+ # Instance methods
42
+
43
+ def site
44
+ return @site if @site
45
+ self.class.respond_to?(:site) && self.class.site
46
+ end
47
+
48
+ def site=(value)
49
+ @site = value
50
+ @connection = nil
51
+ end
52
+
53
+ def normalize_url(url)
54
+ if extension
55
+ "#{url}.#{extension}"
56
+ elsif self.class.respond_to?(:extension) && self.class.extension
57
+ "#{url}.#{self.class.extension}"
58
+ else
59
+ url
60
+ end
61
+ end
62
+
10
63
  def get(url, options = {})
11
64
  request(:get, url, options)
12
65
  end
@@ -26,6 +79,5 @@ module Rapidash
26
79
  def delete(url, options = {})
27
80
  request(:delete, url, options)
28
81
  end
29
-
30
82
  end
31
83
  end
@@ -2,37 +2,32 @@ require 'faraday'
2
2
 
3
3
  module Rapidash
4
4
  module HTTPClient
5
-
6
- def self.included(base)
7
- base.extend(ClassMethods)
8
- end
9
-
10
- attr_accessor :extension, :site
5
+ attr_accessor :login, :password
11
6
  attr_writer :connection
12
7
 
13
- def initialize
14
- end
15
-
16
- def site=(site)
17
- @site = site
18
- @connection = nil
8
+ def initialize(options = {})
9
+ [:login, :password].each do |key|
10
+ self.send("#{key.to_s}=".to_sym, options[key])
11
+ end
19
12
  end
20
13
 
21
14
  def connection
22
- @connection ||= Faraday.new(site || self.class.site_url)
15
+ raise ConfigurationError.new "Site is required" unless site
16
+ @connection ||= Faraday.new(site)
23
17
  end
24
18
 
25
19
  def request(verb, url, options = {})
26
- if extension
27
- url = "#{url}.#{(extension)}"
28
- elsif self.class.respond_to?(:url_extension) && self.class.url_extension
29
- url = "#{url}.#{(self.class.url_extension)}"
20
+ url = connection.build_url(normalize_url(url), options[:params]).to_s
21
+ response = connection.run_request verb, url, options[:body], options[:header] do |request|
22
+ request.headers.update(:Authorization => connection.basic_auth(login, password)) if login && password
30
23
  end
31
- url = connection.build_url(url, options[:params]).to_s
32
- response = connection.run_request(verb, url, options[:body], options[:headers])
33
24
 
25
+ process_response(response, verb, options)
26
+ end
27
+
28
+ def process_response(response, verb, options)
34
29
  # "foo"[0] does not work in 1.8.7, "foo"[0,1] is required
35
- case response.status.to_s[0,1]
30
+ case response.status.to_s[0, 1]
36
31
  when "5", "4"
37
32
  error = ResponseError.new(response)
38
33
  raise error if self.class.respond_to?(:raise_error) && self.class.raise_error
@@ -44,15 +39,5 @@ module Rapidash
44
39
  return Response.new(response)
45
40
  end
46
41
  end
47
-
48
-
49
-
50
- module ClassMethods
51
- attr_accessor :site_url
52
-
53
- def site(site)
54
- @site_url = site
55
- end
56
- end
57
42
  end
58
43
  end
@@ -3,29 +3,29 @@ require 'hashie'
3
3
 
4
4
  module Rapidash
5
5
  module OAuthClient
6
-
7
- attr_accessor :secret, :uid, :access_token, :site, :extension
6
+ attr_accessor :secret, :uid, :access_token, :site
8
7
 
9
8
  def initialize(options)
10
9
  [:uid, :secret, :site].each do |key|
11
10
  if options[key]
12
11
  self.send("#{key.to_s}=".to_sym, options[key])
13
12
  else
14
- raise ConfigurationError.new "Missing #{key} value"
13
+ unless self.class.respond_to?(key) && send(key)
14
+ raise ConfigurationError.new "Missing #{key} value"
15
+ end
15
16
  end
16
17
  end
18
+
17
19
  self.access_token = options[:access_token] if options[:access_token]
18
20
  end
19
21
 
20
22
  def request(verb, url, options = {})
21
- if extension
22
- url = "#{url}.#{(extension)}"
23
- elsif self.class.respond_to?(:url_extension) && self.class.url_extension
24
- url = "#{url}.#{(self.class.url_extension)}"
25
- end
26
- options[:raise_errors] = self.class.respond_to?(:raise_error) && self.class.raise_error
23
+ url = normalize_url(url)
24
+ options[:body] = options[:body].to_json if options[:body]
25
+ options[:raise_errors] = self.class.respond_to?(:raise_error) && self.class.raise_error
27
26
  response = oauth_access_token.send(verb.to_sym, "#{site}/#{url}", options)
28
- return Response.new(response)
27
+
28
+ Response.new(response)
29
29
  end
30
30
 
31
31
  def access_token_from_code(code, url)
@@ -1,30 +1,50 @@
1
1
  module Rapidash
2
2
  module Resourceable
3
-
4
3
  def self.included(base)
5
4
  base.extend ClassMethods
6
5
  end
7
6
 
8
- module ClassMethods
7
+ def resource(name, id = nil, options = {})
8
+ options[:url] ||= name
9
+ if self.respond_to?(:url)
10
+ options = {:previous_url => self.url}.merge!(options)
11
+ end
12
+ client = self
13
+ client = self.client if self.respond_to?(:client)
14
+ Rapidash::Base.new(client, id, options)
15
+ end
9
16
 
10
- def resource(*names)
11
- mod = self.to_s.split("::")[0...-1]
12
- if mod.empty?
13
- mod = Kernel
14
- else
15
- mod = Kernel.const_get(mod.join("::"))
16
- end
17
+ def resource!(*args)
18
+ self.resource(*args).call!
19
+ end
17
20
 
18
21
 
22
+ module ClassMethods
23
+ def resource(*names)
24
+ options = names.extract_options!
25
+
26
+ mod = self.to_s.split("::")[0...-1]
27
+ mod = mod.empty? ? Object : Object.const_get(mod.join("::"))
19
28
 
20
29
  names.each do |name|
21
- klass = mod.const_get(name.to_s.capitalize)
30
+ if options[:class_name]
31
+ class_name = options[:class_name]
32
+ else
33
+ class_name = name.to_s.camelcase.singularize
34
+ end
35
+
36
+ begin
37
+ klass = "#{mod}::#{class_name}".constantize
38
+ rescue NameError
39
+ Kernel.warn "[DEPRECATED] - RAPIDASH WARNING using #{class_name.pluralize} instead of #{class_name.singularize} - please either use `#{class_name.singularize}` or set the class name with `resource #{name}, :class_name => #{class_name.pluralize}` implicit plural naming will be deprecated in Rapidash 1.0"
40
+ klass = "#{mod}::#{class_name}".pluralize.constantize
41
+ end
22
42
 
23
43
  define_method(name) do |*args|
24
44
  if self.respond_to?(:url)
25
45
  options = {:previous_url => self.url}
26
- if args[args.length].is_a?(Hash)
27
- args[args.length].merge!(options)
46
+ if args[args.length - 1].is_a?(Hash)
47
+ args[args.length - 1].merge!(options)
28
48
  else
29
49
  args << options
30
50
  end
@@ -39,8 +59,6 @@ module Rapidash
39
59
  end
40
60
  end
41
61
  end
42
-
43
62
  end
44
-
45
63
  end
46
64
  end