dambalah-twitter4r 0.3.2 → 0.3.3

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.
data/CHANGES CHANGED
@@ -3,6 +3,11 @@
3
3
  Catalog(ue) of changes for Twitter4R 0.1.x releases including Retrospectiva ticket cross-reference numbers. Refer to http://retro.tautology.net/projects/twitter4r/tickets for more information.
4
4
 
5
5
  == 0.3.1 Changes
6
+
7
+ * Added specs for Twitter::Client#profile (:info, :colors and :device cases)
8
+ * Added Twitter4R shell
9
+ * Improved code coverage for twitter/ext/stdlib code and removed hard coded extension in GET request path for retrieving account information
10
+ * Changed Twitter::RESTError super class to be RuntimeError instead of Exception
6
11
  * Added URI.encode => CGI.escape fix
7
12
  * Added block methods
8
13
  * Added Twitter::Client#inspect method to XXXX out passwords
data/README CHANGED
@@ -7,10 +7,15 @@
7
7
  * {Susan Potter}[http://SusanPotter.NET] <me at susanpotter dot net>
8
8
 
9
9
  == Contributors
10
+ Code:
10
11
  * Kaiichi Matsunaga <ma2 at lifemedia dot co dot jp> - proxy code suggestion
11
12
  * Sergio Santos <> - message paging code suggestion
12
13
  * Adam Stiles <adam at stilesoft dot com> - URI.encode => CGI.escape fix
13
14
  * Carl Crawley <cwcrawley at gmail dot com> - Friendship get => post fix
15
+ * Christian Johansen <christian at cjohansen dot no> - in_reply_to attributes in Twitter::Status
16
+
17
+ Design Suggestions:
18
+ * Bosco So <rubymeetup at boscoso dot com> - making Twitter::Error a RuntimeError instead of an Exception to prevent irb from crashing out.
14
19
 
15
20
  == Description
16
21
  Twitter4R provides an object based API to query or update your Twitter account via pure Ruby. It hides the ugly HTTP/REST code from your code.
data/TODO CHANGED
@@ -1,9 +1,7 @@
1
1
 
2
2
  0.3.1 TODO:
3
3
  * Add specs for :page, :lite and :since options support in Twitter::Client#my(...), Twitter::Client#user(....) and Twitter::User#followers calls
4
- * Add specs for Kernel#gem_present? extension
5
- * Add spec to test that warning is given to Rails 2.0+ users requiring 'twitter/rails'
6
4
  * Add specs for :replies support in Twitter::Client#status(...) and Twitter::Client#timeline_for(...)
7
5
  * Add RDoc for :replies support
8
6
  * Add better RDoc for Twitter::Client.account_info(:rate_limit_status)
9
- * Add specs for Twitter::Client.account_info(:rate_limit_status)
7
+ * Add specs for Twitter::Client.account_info(:rate_limit_status)
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require("irb")
4
+ require("irb/completion")
5
+ require("rubygems")
6
+
7
+ begin
8
+ gem('twitter4r', '>0.3.0')
9
+ require("twitter")
10
+ require("twitter/console")
11
+ rescue Gem::LoadError
12
+ begin
13
+ gem("mbbx6spp-twitter4r", '>=0.3.1')
14
+ require("twitter")
15
+ require("twitter/console")
16
+ rescue Gem::LoadError
17
+ abort("Error: You must install either twitter4r gem from Rubyforge with version 0.3.1 or greater or the mbbx6spp-twitter4r gem from GitHub's servers with version 0.3.1 or greater (and make sure it is a recent version of the gem).")
18
+ end
19
+ end
20
+
21
+ module Twitter
22
+ class Console
23
+ class << self
24
+ @@OPTIONS = { :debugger => false, :config => "~/.twitter4r/accounts.yml" }
25
+ def parse_options
26
+ OptionParser.new do |opt|
27
+ opt.banner = "Usage: t4rsh [environment] [options]"
28
+ opt.on("--config=[~/.twitter4r/accounts.yml]", 'Use a specific config file.') { |v| @@OPTIONS[:config] = v }
29
+ opt.parse!(ARGV)
30
+ end
31
+ end
32
+
33
+ def config_file
34
+ result = ENV["T4R_CONFIG"]
35
+ file_name = File.expand_path('twitter.yml')
36
+ result ||= file_name if File.exists?(file_name)
37
+ file_name = File.expand_path('twitter.yml', 'config')
38
+ result ||= file_name if File.exists?(file_name)
39
+ file_name = File.expand_path('~/.twitter.yml')
40
+ result ||= file_name if File.exists?(file_name)
41
+ result
42
+ end
43
+
44
+ def account
45
+ ENV["T4R_ENV"] || ENV["MERB_ENV"] || ENV["RAILS_ENV"]
46
+ end
47
+
48
+ def run(file)
49
+ IRB.init_config(nil)
50
+ # configuration...
51
+ IRB.conf[:IRB_NAME] = "t4rsh"
52
+ IRB.conf[:VERSION] = Twitter::Version.to_version
53
+ IRB.conf[:USE_READLINE] = true
54
+ IRB.conf[:PROMPT_MODE] = :T4RSH
55
+ IRB.conf[:PROMPT][:T4RSH] = {
56
+ :PROMPT_I => "%N[%3n:%i]> ", # top level prompt
57
+ :PROMPT_C => "%N[%3n:%i]* ", # after conditional like "if"
58
+ :PROMPT_S => "%N[%3n:%i]* ", # during continuing string
59
+ :RETURN => "=> %s\n", # return value
60
+ }
61
+ IRB.start(file)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ #if __FILE__ == $0
68
+ @twitter = nil
69
+ config_file = Twitter::Console.config_file
70
+ account = Twitter::Console.account
71
+
72
+ if config_file && account
73
+ @twitter = Twitter::Client.from_config(config_file, account)
74
+ puts "Used #{config_file} to create client for #{account} account."
75
+ puts "Access @twitter for instantiated client."
76
+ Twitter::Console.run(__FILE__)
77
+ else
78
+ abort("Please make sure #{config_file} exists and contains your Twitter credentials (separated by account/environment) and that you specify the account/environment to use, e.g. if you have a 'test' section in your configuration file that you want to use set/export T4R_ENV=test as an environment variable or RAILS_ENV=test or MERB_ENV=test")
79
+ end
80
+ #end
@@ -1,4 +1,5 @@
1
- #
1
+ #
2
+ require('rubygems')
2
3
 
3
4
  module Twitter; end
4
5
 
@@ -6,9 +7,11 @@ def require_local(suffix)
6
7
  require(File.expand_path(File.join(File.dirname(__FILE__), suffix)))
7
8
  end
8
9
 
9
- # For better unicode support
10
- $KCODE = 'u'
11
- require 'jcode'
10
+ # For better unicode support in 1.8
11
+ if RUBY_VERSION < '1.9'
12
+ $KCODE = 'u'
13
+ require 'jcode'
14
+ end
12
15
 
13
16
  # External requires
14
17
  require('yaml')
@@ -9,13 +9,16 @@ class Twitter::Client
9
9
  include Twitter::ClassUtilMixin
10
10
  end
11
11
 
12
- require('twitter/client/base.rb')
13
- require('twitter/client/timeline.rb')
14
- require('twitter/client/status.rb')
15
- require('twitter/client/friendship.rb')
16
- require('twitter/client/messaging.rb')
17
- require('twitter/client/user.rb')
18
- require('twitter/client/auth.rb')
19
- require('twitter/client/favorites.rb')
20
- require('twitter/client/blocks.rb')
21
- require('twitter/client/account.rb')
12
+ require('twitter/client/base')
13
+ require('twitter/client/timeline')
14
+ require('twitter/client/status')
15
+ require('twitter/client/friendship')
16
+ require('twitter/client/messaging')
17
+ require('twitter/client/user')
18
+ require('twitter/client/auth')
19
+ require('twitter/client/favorites')
20
+ require('twitter/client/blocks')
21
+ require('twitter/client/account')
22
+ require('twitter/client/graph')
23
+ require('twitter/client/profile')
24
+ require('twitter/client/search')
@@ -3,22 +3,22 @@ class Twitter::Client
3
3
  :rate_limit_status => '/account/rate_limit_status',
4
4
  }
5
5
 
6
- # Provides access to the Twitter rate limit status API.
7
- #
8
- # You can find out information about your account status. Currently the only
9
- # supported type of account status is the <tt>:rate_limit_status</tt> which
10
- # returns a <tt>Twitter::RateLimitStatus</tt> object.
6
+ # Provides access to the Twitter rate limit status API.
11
7
  #
12
- # Example:
13
- # account_status = client.account_info
14
- # puts account_status.remaining_hits
15
- def account_info(type = :rate_limit_status)
16
- connection = create_http_connection
17
- connection.start do |connection|
18
- response = http_connect do |conn|
19
- create_http_get_request("#{@@ACCOUNT_URIS[type]}.json")
20
- end
21
- bless_models(Twitter::RateLimitStatus.unmarshal(response.body))
8
+ # You can find out information about your account status. Currently the only
9
+ # supported type of account status is the <tt>:rate_limit_status</tt> which
10
+ # returns a <tt>Twitter::RateLimitStatus</tt> object.
11
+ #
12
+ # Example:
13
+ # account_status = client.account_info
14
+ # puts account_status.remaining_hits
15
+ def account_info(type = :rate_limit_status)
16
+ connection = create_http_connection
17
+ connection.start do |connection|
18
+ response = http_connect do |conn|
19
+ create_http_get_request(@@ACCOUNT_URIS[type])
20
+ end
21
+ bless_models(Twitter::RateLimitStatus.unmarshal(response.body))
22
22
  end
23
- end
23
+ end
24
24
  end
@@ -8,9 +8,9 @@ class Twitter::Client
8
8
  attr_accessor :login, :password
9
9
 
10
10
  # Returns the response of the HTTP connection.
11
- def http_connect(body = nil, require_auth = true, &block)
11
+ def http_connect(body = nil, require_auth = true, service = :rest, &block)
12
12
  require_block(block_given?)
13
- connection = create_http_connection
13
+ connection = create_http_connection(service)
14
14
  connection.start do |connection|
15
15
  request = yield connection if block_given?
16
16
  request.basic_auth(@login, @password) if require_auth
@@ -45,11 +45,17 @@ class Twitter::Client
45
45
  end
46
46
  end
47
47
 
48
- def create_http_connection
49
- conn = Net::HTTP.new(@@config.host, @@config.port,
48
+ def create_http_connection(service = :rest)
49
+ case service
50
+ when :rest
51
+ protocol, host, port = @@config.protocol, @@config.host, @@config.port
52
+ when :search
53
+ protocol, host, port = @@config.search_protocol, @@config.search_host, @@config.search_port
54
+ end
55
+ conn = Net::HTTP.new(host, port,
50
56
  @@config.proxy_host, @@config.proxy_port,
51
57
  @@config.proxy_user, @@config.proxy_pass)
52
- if @@config.protocol == :ssl
58
+ if protocol == :ssl
53
59
  conn.use_ssl = true
54
60
  conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
55
61
  end
@@ -1,9 +1,9 @@
1
1
  class Twitter::Client
2
2
  # Why Twitter.com developers can't correctly document their API, I do not know!
3
- @@FAVORITES_URIS = {
4
- :add => '/favourings/create',
5
- :remove => '/favourings/destroy',
6
- }
3
+ @@FAVORITES_URIS = {
4
+ :add => '/favourings/create',
5
+ :remove => '/favourings/destroy',
6
+ }
7
7
 
8
8
  # Provides access to the Twitter list favorites API.
9
9
  #
@@ -13,41 +13,41 @@ class Twitter::Client
13
13
  # To get a previous page you can provide options to this method. For example,
14
14
  # statuses = client.favorites(:page => 2)
15
15
  # The above one-liner will get the second page of favorites for the authenticated user.
16
- def favorites(options = nil)
17
- def uri_suffix(opts); opts && opts[:page] ? "?page=#{opts[:page]}" : ""; end
16
+ def favorites(options = nil)
17
+ def uri_suffix(opts); opts && opts[:page] ? "?page=#{opts[:page]}" : ""; end
18
18
  uri = '/favorites.json' + uri_suffix(options)
19
19
  response = http_connect {|conn| create_http_get_request(uri) }
20
20
  bless_models(Twitter::Status.unmarshal(response.body))
21
- end
21
+ end
22
22
 
23
- # Provides access to the Twitter add/remove favorite API.
24
- #
25
- # You can add and remove favorite status using this method.
26
- #
27
- # <tt>action</tt> can be any of the following values:
28
- # * <tt>:add</tt> - to add a status to your favorites, you would use this <tt>action</tt> value
29
- # * <tt>:remove</tt> - to remove an status from your existing favorites list use this.
30
- #
31
- # The <tt>value</tt> must be either the status object to add or remove or
32
- # the integer unique status ID.
33
- #
34
- # Examples:
35
- # id = 126006103423
36
- # client.favorite(:add, id)
37
- # client.favorite(:remove, id)
38
- # status = Twitter::Status.find(id, client)
39
- # client.favorite(:add, status)
40
- # client.favorite(:remove, status)
41
- def favorite(action, value)
42
- raise ArgumentError, "Invalid favorite action provided: #{action}" unless @@FAVORITES_URIS.keys.member?(action)
43
- value = value.to_i.to_s unless value.is_a?(String)
44
- uri = "#{@@FAVORITES_URIS[action]}/#{value}.json"
45
- case action
46
- when :add
47
- response = http_connect {|conn| create_http_post_request(uri) }
48
- when :remove
49
- response = http_connect {|conn| create_http_delete_request(uri) }
50
- end
51
- bless_model(Twitter::Status.unmarshal(response.body))
52
- end
23
+ # Provides access to the Twitter add/remove favorite API.
24
+ #
25
+ # You can add and remove favorite status using this method.
26
+ #
27
+ # <tt>action</tt> can be any of the following values:
28
+ # * <tt>:add</tt> - to add a status to your favorites, you would use this <tt>action</tt> value
29
+ # * <tt>:remove</tt> - to remove an status from your existing favorites list use this.
30
+ #
31
+ # The <tt>value</tt> must be either the status object to add or remove or
32
+ # the integer unique status ID.
33
+ #
34
+ # Examples:
35
+ # id = 126006103423
36
+ # client.favorite(:add, id)
37
+ # client.favorite(:remove, id)
38
+ # status = Twitter::Status.find(id, client)
39
+ # client.favorite(:add, status)
40
+ # client.favorite(:remove, status)
41
+ def favorite(action, value)
42
+ raise ArgumentError, "Invalid favorite action provided: #{action}" unless @@FAVORITES_URIS.keys.member?(action)
43
+ value = value.to_i.to_s unless value.is_a?(String)
44
+ uri = "#{@@FAVORITES_URIS[action]}/#{value}.json"
45
+ case action
46
+ when :add
47
+ response = http_connect {|conn| create_http_post_request(uri) }
48
+ when :remove
49
+ response = http_connect {|conn| create_http_delete_request(uri) }
50
+ end
51
+ bless_model(Twitter::Status.unmarshal(response.body))
52
+ end
53
53
  end
@@ -0,0 +1,37 @@
1
+ class Twitter::Client
2
+ @@GRAPH_URIS = {
3
+ :friends => '/friends/ids',
4
+ :followers => '/followers/ids',
5
+ }
6
+
7
+ # Provides access to the Twitter Social Graphing API.
8
+ #
9
+ # You can retrieve the full graph of a user's friends or followers in one method call.
10
+ #
11
+ # <tt>action</tt> can be any of the following values:
12
+ # * <tt>:friends</tt> - retrieves ids of all friends of a given user.
13
+ # * <tt>:followers</tt> - retrieves ids of all followers of a given user.
14
+ #
15
+ # The <tt>value</tt> must be either the user screen name, integer unique user ID or Twitter::User
16
+ # object representation.
17
+ #
18
+ # Examples:
19
+ # screen_name = 'dictionary'
20
+ # client.graph(:friends, 'dictionary')
21
+ # client.graph(:followers, 'dictionary')
22
+ # id = 1260061
23
+ # client.graph(:friends, id)
24
+ # client.graph(:followers, id)
25
+ # user = Twitter::User.find(id, client)
26
+ # client.graph(:friends, user)
27
+ # client.graph(:followers, user)
28
+ def graph(action, value = nil)
29
+ raise ArgumentError, "Invalid friend action provided: #{action}" unless @@GRAPH_URIS.keys.member?(action)
30
+ id = value.to_i unless value.nil? || value.is_a?(String)
31
+ id ||= value
32
+ id ||= @login
33
+ uri = "#{@@GRAPH_URIS[action]}.json"
34
+ response = http_connect {|conn| create_http_get_request(uri, :id => id) }
35
+ JSON.parse(response.body)
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ class Twitter::Client
2
+ @@PROFILE_URIS = {
3
+ :info => '/account/update_profile',
4
+ :colors => '/account/update_profile_colors',
5
+ :device => '/account/update_delivery_device',
6
+ }
7
+
8
+ # Provides access to the Twitter Profile API.
9
+ #
10
+ # You can update profile information. You can update the types of profile
11
+ # information:
12
+ # * :info (name, email, url, location, description)
13
+ # * :colors (background_color, text_color, link_color, sidebar_fill_color,
14
+ # sidebar_border_color)
15
+ # * :device (set device to either "sms", "im" or "none")
16
+ #
17
+ # Example:
18
+ # user = client.profile(:info, :location => "University Library")
19
+ # puts user.inspect
20
+ def profile(action, attributes)
21
+ connection = create_http_connection
22
+ connection.start do |connection|
23
+ response = http_connect(attributes.to_http_str) do |conn|
24
+ create_http_post_request(@@PROFILE_URIS[action])
25
+ end
26
+ bless_models(Twitter::User.unmarshal(response.body))
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ class Twitter::Client
2
+
3
+ @@SEARCH_URIS = {
4
+ :basic => "/search.json",
5
+ }
6
+
7
+ # Provides access to Twitter's Search API.
8
+ #
9
+ # Example:
10
+ # # For keyword search
11
+ # iterator = @twitter.search(:q => "coworking")
12
+ # while (tweet = iterator.next)
13
+ # puts tweet.text
14
+ # end
15
+ #
16
+ # An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt>
17
+ # is given. Valid actions are:
18
+ # * +:received+
19
+ # * +:sent+
20
+ def search(options = {})
21
+ # raise ArgumentError, "Invalid messaging action: #{action}"
22
+ uri = @@SEARCH_URIS[:basic]
23
+ response = http_connect(nil, false, :search) {|conn| create_http_get_request(uri, options) }
24
+ json = JSON.parse(response.body)
25
+ bless_models(Twitter::Status.unmarshal(JSON.dump(json["results"])))
26
+ end
27
+ end
@@ -22,6 +22,9 @@ module Twitter
22
22
  :protocol,
23
23
  :host,
24
24
  :port,
25
+ :search_protocol,
26
+ :search_host,
27
+ :search_port,
25
28
  :proxy_host,
26
29
  :proxy_port,
27
30
  :proxy_user,
@@ -49,6 +52,9 @@ module Twitter
49
52
  @@defaults = { :host => 'twitter.com',
50
53
  :port => 443,
51
54
  :protocol => :ssl,
55
+ :search_host => 'search.twitter.com',
56
+ :search_port => 80,
57
+ :search_protocol => :http,
52
58
  :proxy_host => nil,
53
59
  :proxy_port => nil,
54
60
  :user_agent => "default",
@@ -1,5 +1,7 @@
1
1
  # Contains hooks for the twitter console
2
2
 
3
+ require('optparse')
4
+
3
5
  module Twitter
4
6
  class Client
5
7
  class << self
@@ -26,3 +28,4 @@ module Twitter
26
28
  end # class << self
27
29
  end
28
30
  end
31
+
@@ -99,7 +99,7 @@ module Twitter
99
99
  # 404
100
100
  # Resource Not Found
101
101
  # /i_am_crap.json
102
- class RESTError < Exception
102
+ class RESTError < RuntimeError
103
103
  include ClassUtilMixin
104
104
  @@ATTRIBUTES = [:code, :message, :uri]
105
105
  attr_accessor :code, :message, :uri
@@ -42,9 +42,10 @@ module Kernel
42
42
  def gem_present?(gem_name, version = nil)
43
43
  present = false
44
44
  begin
45
- present = gem(gem_name, version)
45
+ present = !!(version ? gem(gem_name, version) : gem(gem_name))
46
46
  rescue Gem::LoadError => le
47
- warn("Gem load error: Couldn't load #{gem_name} with version requirement #{version}: #{le.to_s}")
47
+ present = false
48
+ warn("Gem load error: Couldn't load #{gem_name} #{version ? "with version requirement #{version}: #{le.to_s}": ""}")
48
49
  end
49
50
  present
50
51
  end
@@ -158,7 +158,13 @@ module Twitter
158
158
  # Represents a <tt>Twitter</tt> user
159
159
  class User
160
160
  include ModelMixin
161
- @@ATTRIBUTES = [:id, :name, :description, :location, :screen_name, :url, :profile_image_url, :protected]
161
+ @@ATTRIBUTES = [:id, :name, :description, :location, :screen_name, :url,
162
+ :protected, :profile_image_url, :profile_background_color,
163
+ :profile_text_color, :profile_link_color, :profile_sidebar_fill_color,
164
+ :profile_sidebar_border_color, :profile_background_image_url,
165
+ :profile_background_tile, :utc_offset, :time_zone,
166
+ :following, :notifications, :favourites_count, :followers_count,
167
+ :friends_count, :statuses_count, :created_at, ]
162
168
  attr_accessor *@@ATTRIBUTES
163
169
 
164
170
  class << self
@@ -219,7 +225,9 @@ module Twitter
219
225
  # Represents a status posted to <tt>Twitter</tt> by a <tt>Twitter</tt> user.
220
226
  class Status
221
227
  include ModelMixin
222
- @@ATTRIBUTES = [:id, :text, :created_at, :user]
228
+ @@ATTRIBUTES = [:id, :text, :source, :truncated, :created_at, :user,
229
+ :favorited, :in_reply_to_status_id, :in_reply_to_user_id,
230
+ :in_reply_to_screen_name]
223
231
  attr_accessor *@@ATTRIBUTES
224
232
 
225
233
  class << self
@@ -260,6 +268,10 @@ module Twitter
260
268
  client.status(:post, text)
261
269
  end
262
270
  end
271
+
272
+ def reply?
273
+ !!@in_reply_to_status_id
274
+ end
263
275
 
264
276
  protected
265
277
  # Constructor callback
@@ -0,0 +1,28 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#account_info" do
4
+ before(:each) do
5
+ @uri = Twitter::Client.class_eval("@@ACCOUNT_URIS[:rate_limit_status]")
6
+ @request = mas_net_http_get(:basic_auth => nil)
7
+ @twitter = client_context
8
+ @default_header = @twitter.send(:http_header)
9
+ @response = mas_net_http_response(:success)
10
+ @connection = mas_net_http(@response)
11
+ @response.stub!(:body).and_return("{}")
12
+ Net::HTTP.stub!(:new).and_return(@connection)
13
+ @rate_limit_status = mock(Twitter::RateLimitStatus)
14
+ @twitter.stub!(:bless_models).and_return({})
15
+ end
16
+
17
+ it "should create expected HTTP GET request" do
18
+ @twitter.should_receive(:create_http_get_request).with(@uri).and_return(@request)
19
+ @twitter.account_info
20
+ end
21
+
22
+ it "should raise Twitter::RESTError when 500 HTTP response received when giving page options" do
23
+ @connection = mas_net_http(mas_net_http_response(:server_error))
24
+ lambda {
25
+ @twitter.account_info
26
+ }.should raise_error(Twitter::RESTError)
27
+ end
28
+ end
@@ -0,0 +1,67 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#graph(:friends...)" do
4
+ before(:each) do
5
+ @twitter = client_context
6
+ @id = 1234567
7
+ @screen_name = 'dummylogin'
8
+ @friend = Twitter::User.new(:id => @id, :screen_name => @screen_name)
9
+ @uris = Twitter::Client.class_eval("@@GRAPH_URIS")
10
+ @request = mas_net_http_get(:basic_auth => nil)
11
+ @response = mas_net_http_response(:success)
12
+ @response.stub!(:body).and_return("[1, 2, 3, 4, 5, 6]")
13
+ @connection = mas_net_http(@response)
14
+ Net::HTTP.stub!(:new).and_return(@connection)
15
+ Twitter::User.stub!(:unmarshal).and_return(@friend)
16
+ end
17
+
18
+ def create_uri(action)
19
+ "#{@uris[action]}.json"
20
+ end
21
+
22
+ it "should create expected HTTP GET request for :friends case using integer user ID" do
23
+ # the integer user ID scenario...
24
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:friends), :id => @id).and_return(@request)
25
+ @twitter.graph(:friends, @id)
26
+ end
27
+
28
+ it "should create expected HTTP GET request for :friends case using screen name" do
29
+ # the screen name scenario...
30
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:friends), :id => @screen_name).and_return(@request)
31
+ @twitter.graph(:friends, @screen_name)
32
+ end
33
+
34
+ it "should create expected HTTP GET request for :friends case using Twitter::User object" do
35
+ # the Twitter::User object scenario...
36
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:friends), :id => @friend.to_i).and_return(@request)
37
+ @twitter.graph(:friends, @friend)
38
+ end
39
+
40
+ it "should create expected HTTP GET request for :followers case using integer user ID" do
41
+ # the integer user ID scenario...
42
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:followers), :id => @id).and_return(@request)
43
+ @twitter.graph(:followers, @id)
44
+ end
45
+
46
+ it "should create expected HTTP GET request for :followers case using screen name" do
47
+ # the screen name scenario...
48
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:followers), :id => @screen_name).and_return(@request)
49
+ @twitter.graph(:followers, @screen_name)
50
+ end
51
+
52
+ it "should create expected HTTP GET request for :followers case using Twitter::User object" do
53
+ # the Twitter::User object scenario...
54
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:followers), :id => @friend.to_i).and_return(@request)
55
+ @twitter.graph(:followers, @friend)
56
+ end
57
+
58
+ it "should raise ArgumentError if action given is not valid" do
59
+ lambda {
60
+ @twitter.graph(:crap, @friend)
61
+ }.should raise_error(ArgumentError)
62
+ end
63
+
64
+ after(:each) do
65
+ nilize(@twitter, @id, @uris, @request, @response, @connection)
66
+ end
67
+ end
@@ -0,0 +1,91 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#profile" do
4
+ before(:each) do
5
+ @twitter = client_context
6
+ @user_attrs = {
7
+ :id => "JaneEyre",
8
+ :login => "Jane Eyre",
9
+ :url => "http://janeeyrerocks.co.uk",
10
+ :location => "Thornfield Manor",
11
+ }
12
+ # name, email, url, location, description
13
+ @info_attrs = {
14
+ :name => "Jane Eyre",
15
+ :email => "jane.eyre@gmail.co.uk",
16
+ :url => "http://janeeyrerocks.co.uk",
17
+ :location => "Thornfield Manor",
18
+ :description => "Governess who falls for slave-trade aristocrat with French lovechild he doesn't acknowledge & wife locked in damp attic with keeper.",
19
+ }
20
+ # background_color, text_color, link_color, sidebar_fill_color, sidebar_border_color
21
+ @colors_attrs = {
22
+ :background_color => "#ffffff",
23
+ :text_color => "#101010",
24
+ :link_color => "#990000",
25
+ }
26
+ # value
27
+ @device_attrs = {
28
+ :value => "sms",
29
+ }
30
+ @user = Twitter::User.new
31
+ @uris = Twitter::Client.class_eval("@@PROFILE_URIS")
32
+ @request = mas_net_http_get(:basic_auth => nil)
33
+ @json = JSON.unparse(@user_attrs)
34
+ @response = mas_net_http_response(:success, @json)
35
+ @connection = mas_net_http(@response)
36
+
37
+ Net::HTTP.stub!(:new).and_return(@connection)
38
+ Twitter::User.stub!(:unmarshal).and_return(@user)
39
+ end
40
+
41
+ it "should invoke #http_connect with expected arguments for :info case" do
42
+ @twitter.should_receive(:http_connect).with(@info_attrs.to_http_str).and_return(@response)
43
+ @twitter.profile(:info, @info_attrs)
44
+ end
45
+
46
+ it "should invoke #http_connect with expected arguments for :colors case" do
47
+ @twitter.should_receive(:http_connect).with(@colors_attrs.to_http_str).and_return(@response)
48
+ @twitter.profile(:colors, @colors_attrs)
49
+ end
50
+
51
+ it "should invoke #http_connect with expected arguments for :device case" do
52
+ @twitter.should_receive(:http_connect).with(@device_attrs.to_http_str).and_return(@response)
53
+ @twitter.profile(:info, @device_attrs)
54
+ end
55
+
56
+ it "should create expected HTTP POST request for :info case" do
57
+ @twitter.should_receive(:create_http_post_request).with(@uris[:info]).and_return(@request)
58
+ @twitter.profile(:info, @info_attrs)
59
+ end
60
+
61
+ it "should create expected HTTP POST request for :colors case" do
62
+ @twitter.should_receive(:create_http_post_request).with(@uris[:colors]).and_return(@request)
63
+ @twitter.profile(:colors, @colors_attrs)
64
+ end
65
+
66
+ it "should create expected HTTP POST request for :device case" do
67
+ @twitter.should_receive(:create_http_post_request).with(@uris[:device]).and_return(@request)
68
+ @twitter.profile(:device, @device_attrs)
69
+ end
70
+
71
+ it "should bless returned Twitter::User object for :info case" do
72
+ @twitter.should_receive(:bless_model).with(@user)
73
+ @twitter.profile(:info, @info_attrs)
74
+ end
75
+
76
+ it "should bless returned Twitter::User object for :colors case" do
77
+ @twitter.should_receive(:bless_model).with(@user)
78
+ @twitter.profile(:colors, @colors_attrs)
79
+ end
80
+
81
+ it "should bless returned Twitter::User object for :device case" do
82
+ @twitter.should_receive(:bless_model).with(@user)
83
+ @twitter.profile(:device, @device_attrs)
84
+ end
85
+
86
+ it "should raise an ArgumentError when giving an invalid profile action"
87
+
88
+ after(:each) do
89
+ nilize(@twitter, @uris, @request, @response, @connection, @sender, @recipient, @user, @attributes)
90
+ end
91
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe :rest_api_request, :shared => true do
4
+ before(:each) do
5
+
6
+ end
7
+ it "should invoke #http_connect with expected arguments"
8
+ it "should create HTTP request of expected method"
9
+ it "should bless returned model of expected type"
10
+ end
11
+
12
+ describe Twitter::Client, "#end" do
13
+ describe "keywords case" do
14
+ def expected_http_method; :get; end
15
+ def expected_model; Twitter::Status; end
16
+ def expected_model_in_array?; true; end
17
+ def expected_http_connect_arguments; {}; end
18
+ # should_behave_like :rest_api_request
19
+ end
20
+
21
+ describe "invalid" do
22
+ it "should raise an ArgumentError when giving an invalid search action"
23
+ end
24
+ end
@@ -40,3 +40,20 @@ describe Time, "#to_s" do
40
40
  nilize(@time, @expected_string)
41
41
  end
42
42
  end
43
+
44
+ # TODO: figure out how to stub the gem method to do what we want rather than this monstrousity. It is dependent on the system installation, which is always a bad thing. For now it will do so we can ship with 100% C0 coverage.
45
+ describe Kernel, "#gem_present?" do
46
+ before(:each) do
47
+ @present_gem = "rake"
48
+ @uninstalled_gem = "uninstalled-gem-crap"
49
+ end
50
+
51
+ it "should return true when a gem isn't present on system" do
52
+ gem_present?(@present_gem).should eql(true)
53
+ end
54
+
55
+ it "should return false when a gem isn't present on system" do
56
+ gem_present?(@uninstalled_gem).should eql(false)
57
+ end
58
+ end
59
+
@@ -433,9 +433,32 @@ describe Twitter::User, "#defriend" do
433
433
  end
434
434
  end
435
435
 
436
+ describe Twitter::Status, "#reply?" do
437
+ before(:each) do
438
+ @status = Twitter::Status.new(
439
+ :id => 123456789,
440
+ :text => "Wazzup?",
441
+ :user => mock(Twitter::User)
442
+ )
443
+ @reply = Twitter::Status.new(
444
+ :text => "No much bro. You?",
445
+ :user => mock(Twitter::User),
446
+ :in_reply_to_status_id => @status.id
447
+ )
448
+ end
449
+
450
+ it "should return false for the original status" do
451
+ @status.reply?.should be(false)
452
+ end
453
+
454
+ it "should return true for the reply to the original status" do
455
+ @reply.reply?.should be(true)
456
+ end
457
+ end
458
+
436
459
  describe Twitter::Status, "#to_s" do
437
460
  before(:each) do
438
- @text = 'Aloha'
461
+ @text = 'Aloha'
439
462
  @status = Twitter::Status.new(:text => @text)
440
463
  end
441
464
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dambalah-twitter4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Susan Potter
@@ -24,8 +24,8 @@ dependencies:
24
24
  version:
25
25
  description:
26
26
  email: twitter4r-users@googlegroups.com
27
- executables: []
28
-
27
+ executables:
28
+ - t4rsh
29
29
  extensions: []
30
30
 
31
31
  extra_rdoc_files:
@@ -34,47 +34,52 @@ extra_rdoc_files:
34
34
  - TODO
35
35
  - MIT-LICENSE
36
36
  files:
37
+ - lib/twitter.rb
37
38
  - lib/twitter/extras.rb
38
- - lib/twitter/config.rb
39
- - lib/twitter/core.rb
40
- - lib/twitter/client/blocks.rb
39
+ - lib/twitter/ext/stdlib.rb
40
+ - lib/twitter/console.rb
41
+ - lib/twitter/meta.rb
42
+ - lib/twitter/version.rb
43
+ - lib/twitter/client/graph.rb
41
44
  - lib/twitter/client/account.rb
42
- - lib/twitter/client/timeline.rb
43
45
  - lib/twitter/client/messaging.rb
44
- - lib/twitter/client/base.rb
45
- - lib/twitter/client/favorites.rb
46
46
  - lib/twitter/client/status.rb
47
- - lib/twitter/client/friendship.rb
47
+ - lib/twitter/client/timeline.rb
48
+ - lib/twitter/client/favorites.rb
48
49
  - lib/twitter/client/auth.rb
50
+ - lib/twitter/client/friendship.rb
51
+ - lib/twitter/client/search.rb
52
+ - lib/twitter/client/profile.rb
53
+ - lib/twitter/client/blocks.rb
49
54
  - lib/twitter/client/user.rb
50
- - lib/twitter/rails.rb
55
+ - lib/twitter/client/base.rb
56
+ - lib/twitter/core.rb
51
57
  - lib/twitter/client.rb
52
- - lib/twitter/console.rb
53
- - lib/twitter/version.rb
54
58
  - lib/twitter/model.rb
55
- - lib/twitter/meta.rb
56
59
  - lib/twitter/ext.rb
57
- - lib/twitter/ext/stdlib.rb
58
- - lib/twitter.rb
59
- - spec/twitter/config_spec.rb
60
+ - lib/twitter/config.rb
61
+ - spec/twitter/ext/stdlib_spec.rb
60
62
  - spec/twitter/core_spec.rb
61
- - spec/twitter/model_spec.rb
63
+ - spec/twitter/meta_spec.rb
64
+ - spec/twitter/version_spec.rb
62
65
  - spec/twitter/client/status_spec.rb
63
- - spec/twitter/client/timeline_spec.rb
66
+ - spec/twitter/client/graph_spec.rb
67
+ - spec/twitter/client/favorites_spec.rb
68
+ - spec/twitter/client/blocks_spec.rb
64
69
  - spec/twitter/client/auth_spec.rb
65
- - spec/twitter/client/user_spec.rb
70
+ - spec/twitter/client/profile_spec.rb
71
+ - spec/twitter/client/timeline_spec.rb
72
+ - spec/twitter/client/account_spec.rb
73
+ - spec/twitter/client/friendship_spec.rb
74
+ - spec/twitter/client/search_spec.rb
66
75
  - spec/twitter/client/messaging_spec.rb
67
76
  - spec/twitter/client/base_spec.rb
68
- - spec/twitter/client/favorites_spec.rb
69
- - spec/twitter/client/friendship_spec.rb
70
- - spec/twitter/client/blocks_spec.rb
71
- - spec/twitter/version_spec.rb
72
- - spec/twitter/rails_spec.rb
77
+ - spec/twitter/client/user_spec.rb
73
78
  - spec/twitter/client_spec.rb
74
- - spec/twitter/meta_spec.rb
75
79
  - spec/twitter/console_spec.rb
80
+ - spec/twitter/config_spec.rb
76
81
  - spec/twitter/extras_spec.rb
77
- - spec/twitter/ext/stdlib_spec.rb
82
+ - spec/twitter/model_spec.rb
78
83
  - README
79
84
  - CHANGES
80
85
  - TODO
@@ -104,6 +109,6 @@ rubyforge_project: twitter4r
104
109
  rubygems_version: 1.2.0
105
110
  signing_key:
106
111
  specification_version: 2
107
- summary: A clean Twitter client API in pure Ruby. Will include Twitter add-ons also in Ruby. (This version has changes made by Luc Castera)
112
+ summary: A clean Twitter client API in pure Ruby. Will include Twitter add-ons also in Ruby.
108
113
  test_files: []
109
114
 
@@ -1,92 +0,0 @@
1
- # File that contains extensions to the Twitter4R library directly related to providing
2
- # seamless Rails integration.
3
-
4
- if gem_present?('rails', '<= 1.2.6')
5
-
6
- require('active_record/xml_serialization')
7
- require('active_support')
8
-
9
- # Extend +String+ with +#xmlize+ method for convenience.
10
- class String
11
- def xmlize
12
- # Forget module/namespace for now as this is totally broken in Rails 1.2.x
13
- # (search for namespaced models on the Rails Trac site)
14
- cls = self.split('::').pop
15
- cls.dasherize.downcase
16
- end
17
- end
18
-
19
- # Parent mixin module that defines +InstanceMethods+ for Twitter4R model classes.
20
- #
21
- # Defines/overrides the following methods for:
22
- # * Twitter::RailsPatch::InstanceMethods#to_param
23
- # * Twitter::RailsPatch::InstanceMethods#to_xml
24
- # * Twitter::RailsPatch::InstanceMethods#to_json
25
- module Twitter::RailsPatch
26
- class << self
27
- def included(base)
28
- base.send(:include, InstanceMethods)
29
- base.extend ClassMethods
30
- end
31
-
32
- module ClassMethods
33
- # Dummy method to satisfy ActiveRecord's XmlSerializer.
34
- def inheritance_column
35
- nil
36
- end
37
-
38
- # Returns Hash of name-column pairs
39
- def columns_hash
40
- {}
41
- end
42
- end
43
-
44
- module InstanceMethods
45
- # Returns an Array of attribute names of the model
46
- def attribute_names
47
- self.class.class_eval("@@ATTRIBUTES").collect {|att| att.to_s }
48
- end
49
-
50
- # Override default +#to_param+ implementation.
51
- def to_param
52
- self.id.to_s
53
- end
54
-
55
- # Returns XML representation of model.
56
- def to_xml(options = {})
57
- ActiveRecord::XmlSerializer.new(self, options.merge(:root => self.class.name.xmlize)).to_s
58
- end
59
-
60
- # Returns JSON representation of model.
61
- #
62
- # The current implementation basically ignoring +options+, so reopen and override
63
- # this implementation or live with it for the moment:)
64
- def to_json(options = {})
65
- JSON.unparse(self.to_hash)
66
- end
67
- end
68
- end
69
- end
70
-
71
- class Twitter::User
72
- include Twitter::RailsPatch
73
- end
74
-
75
- class Twitter::Status
76
- include Twitter::RailsPatch
77
- end
78
-
79
- class Twitter::Message
80
- include Twitter::RailsPatch
81
- end
82
-
83
- class Twitter::RESTError
84
- include Twitter::RailsPatch
85
- alias :id :code
86
- def to_hash
87
- { :code => @code, :message => @message, :uri => @uri }
88
- end
89
- end
90
- else
91
- warn("WARNING: Twiter4R patch for ActiveRecord defects only supported for Rails 1.2.x currently")
92
- end
@@ -1,110 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
-
3
- describe String, "representing a class name" do
4
-
5
- before(:each) do
6
- @class_name = Twitter::User.class.name
7
- @xmlized_name = @class_name.downcase # simple case for the moment...since Rails' support for namespaced models sucks!
8
- end
9
-
10
- it "should be downcased (minus module namespaces) when xmlized" do
11
- @class_name.xmlize.should eql(@xmlized_name)
12
- end
13
-
14
- after(:each) do
15
- nilize(@class_name, @xmlized_name)
16
- end
17
- end
18
-
19
- describe "Rails model extensions for model classes", :shared => true do
20
-
21
- before(:each) do
22
- @id = 3242334
23
- @id_s = @id.to_s
24
- @model = model(@id)
25
- @model_hash = @model.to_hash
26
- @json = JSON.unparse(@model_hash)
27
- @serializer = ActiveRecord::XmlSerializer.new(@model, {:root => @model.class.name.downcase})
28
- @xml = @serializer.to_s
29
- end
30
-
31
- it "should invoke #to_param as expected" do
32
- @model.should_receive(:id).and_return(@id)
33
- @model.to_param
34
- end
35
-
36
- it "should return string representation for id for #to_param" do
37
- @model.to_param.class.should eql(String)
38
- end
39
-
40
- it "should return output from JSON.unparse for #to_json" do
41
- @model.should_receive(:to_hash).and_return(@model_hash)
42
- JSON.should_receive(:unparse).and_return(@json)
43
- @model.to_json
44
- end
45
-
46
- it "should return XmlSerializer string output for #to_xml" do
47
- ActiveRecord::XmlSerializer.should_receive(:new).and_return(@serializer)
48
- @serializer.should_receive(:to_s).and_return(@xml)
49
- @model.to_xml
50
- end
51
-
52
- after(:each) do
53
- nilize(@id, @model)
54
- end
55
- end
56
-
57
- describe Twitter::User, "Rails extensions" do
58
-
59
- def model(id)
60
- Twitter::User.new(:id => id)
61
- end
62
-
63
- it_should_behave_like "Rails model extensions for model classes"
64
- end
65
-
66
- describe Twitter::Status, "Rails extensions" do
67
-
68
- def model(id)
69
- Twitter::Status.new(:id => id)
70
- end
71
-
72
- it_should_behave_like "Rails model extensions for model classes"
73
- end
74
-
75
- describe Twitter::Message, "Rails extensions" do
76
-
77
- def model(id)
78
- Twitter::Message.new(:id => id)
79
- end
80
-
81
- it_should_behave_like "Rails model extensions for model classes"
82
- end
83
-
84
- describe Twitter::RESTError, "Rails extensions" do
85
-
86
- before(:each) do
87
- @attributes = { :code => 200, :message => 'Success', :uri => 'http://twitter.com/statuses' }
88
- @model = Twitter::RESTError.new(@attributes)
89
- @json = "JSON" # doesn't really matter what the value is
90
- end
91
-
92
- it "should return a Hash of attribute name-value pairs for #to_hash" do
93
- @model.to_hash.should === @attributes
94
- end
95
-
96
- it "should invoke XmlSerializer for #to_xml" do
97
-
98
- @model.to_xml
99
- end
100
-
101
- it "should return expected JSON for #to_json" do
102
- @model.to_hash
103
- JSON.should_receive(:unparse).and_return(@json)
104
- @model.to_json
105
- end
106
-
107
- after(:each) do
108
- nilize(@attributes, @model)
109
- end
110
- end