t 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.travis.yml +0 -1
- data/README.md +28 -99
- data/lib/t.rb +0 -13
- data/lib/t/cli.rb +385 -147
- data/lib/t/collectable.rb +1 -1
- data/lib/t/delete.rb +84 -0
- data/lib/t/list.rb +103 -0
- data/lib/t/search.rb +133 -0
- data/lib/t/set.rb +57 -0
- data/lib/t/version.rb +1 -1
- data/spec/cli_spec.rb +330 -201
- data/spec/{cli/delete_spec.rb → delete_spec.rb} +86 -124
- data/spec/fixtures/recommendations.json +1 -1
- data/spec/fixtures/users.json +1 -0
- data/spec/helper.rb +0 -1
- data/spec/{cli/list_spec.rb → list_spec.rb} +77 -6
- data/spec/rcfile_spec.rb +0 -4
- data/spec/{cli/search_spec.rb → search_spec.rb} +1 -1
- data/spec/{cli/set_spec.rb → set_spec.rb} +1 -1
- data/t.gemspec +2 -2
- metadata +26 -36
- data/lib/t/cli/delete.rb +0 -85
- data/lib/t/cli/follow.rb +0 -78
- data/lib/t/cli/list.rb +0 -58
- data/lib/t/cli/list/add.rb +0 -144
- data/lib/t/cli/list/remove.rb +0 -136
- data/lib/t/cli/search.rb +0 -124
- data/lib/t/cli/set.rb +0 -59
- data/lib/t/cli/unfollow.rb +0 -121
- data/spec/cli/follow_spec.rb +0 -240
- data/spec/cli/list/add_spec.rb +0 -518
- data/spec/cli/list/remove_spec.rb +0 -422
- data/spec/cli/unfollow_spec.rb +0 -410
data/lib/t/collectable.rb
CHANGED
@@ -4,7 +4,7 @@ module T
|
|
4
4
|
def collect_with_cursor(collection=[], cursor=-1, &block)
|
5
5
|
object = yield cursor
|
6
6
|
collection += object.collection
|
7
|
-
object.
|
7
|
+
object.last? ? collection : collect_with_cursor(collection, object.next_cursor, &block)
|
8
8
|
end
|
9
9
|
|
10
10
|
end
|
data/lib/t/delete.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 't/core_ext/string'
|
2
|
+
require 't/rcfile'
|
3
|
+
require 't/requestable'
|
4
|
+
require 'thor'
|
5
|
+
|
6
|
+
module T
|
7
|
+
class Delete < Thor
|
8
|
+
include T::Requestable
|
9
|
+
|
10
|
+
check_unknown_options!
|
11
|
+
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@rcfile = RCFile.instance
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "block SCREEN_NAME [SCREEN_NAME...]", "Unblock users."
|
18
|
+
def block(screen_name, *screen_names)
|
19
|
+
screen_names.unshift(screen_name)
|
20
|
+
screen_names.threaded_each do |screen_name|
|
21
|
+
screen_name.strip_at
|
22
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
23
|
+
client.unblock(screen_name, :include_entities => false)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
say "@#{@rcfile.default_profile[0]} unblocked @#{screen_names.join(' ')}."
|
27
|
+
say
|
28
|
+
say "Run `#{File.basename($0)} block #{screen_names.join(' ')}` to block."
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "dm", "Delete the last Direct Message sent."
|
32
|
+
def dm
|
33
|
+
direct_message = client.direct_messages_sent(:count => 1, :include_entities => false).first
|
34
|
+
if direct_message
|
35
|
+
unless parent_options['force']
|
36
|
+
return unless yes? "Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\"? [y/N]"
|
37
|
+
end
|
38
|
+
direct_message = client.direct_message_destroy(direct_message.id, :include_entities => false)
|
39
|
+
say "@#{direct_message.sender.screen_name} deleted the direct message sent to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\""
|
40
|
+
else
|
41
|
+
raise Thor::Error, "Direct Message not found"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
map %w(m) => :dm
|
45
|
+
|
46
|
+
desc "favorite STATUS_ID [STATUS_ID...]", "Delete favorites."
|
47
|
+
def favorite(status_id, *status_ids)
|
48
|
+
status_ids.unshift(status_id)
|
49
|
+
status_ids.each do |status_id|
|
50
|
+
unless parent_options['force']
|
51
|
+
status = client.status(status_id, :include_entities => false, :include_my_retweet => false, :trim_user => true)
|
52
|
+
return unless yes? "Are you sure you want to delete the favorite of @#{status.user.screen_name}'s status: \"#{status.text}\"? [y/N]"
|
53
|
+
end
|
54
|
+
status = client.unfavorite(status_id, :include_entities => false)
|
55
|
+
say "@#{@rcfile.default_profile[0]} unfavorited @#{status.user.screen_name}'s status: \"#{status.text}\""
|
56
|
+
end
|
57
|
+
end
|
58
|
+
map %w(post tweet update) => :status
|
59
|
+
|
60
|
+
desc "list LIST_NAME", "Delete a list."
|
61
|
+
def list(list_name)
|
62
|
+
unless parent_options['force']
|
63
|
+
return unless yes? "Are you sure you want to permanently delete the list \"#{list_name}\"? [y/N]"
|
64
|
+
end
|
65
|
+
status = client.list_destroy(list_name)
|
66
|
+
say "@#{@rcfile.default_profile[0]} deleted the list \"#{list_name}\"."
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "status STATUS_ID [STATUS_ID...]", "Delete Tweets."
|
70
|
+
def status(status_id, *status_ids)
|
71
|
+
status_ids.unshift(status_id)
|
72
|
+
status_ids.each do |status_id|
|
73
|
+
unless parent_options['force']
|
74
|
+
status = client.status(status_id, :include_entities => false, :include_my_retweet => false, :trim_user => true)
|
75
|
+
return unless yes? "Are you sure you want to permanently delete @#{status.user.screen_name}'s status: \"#{status.text}\"? [y/N]"
|
76
|
+
end
|
77
|
+
status = client.status_destroy(status_id, :include_entities => false, :trim_user => true)
|
78
|
+
say "@#{@rcfile.default_profile[0]} deleted the status: \"#{status.text}\""
|
79
|
+
end
|
80
|
+
end
|
81
|
+
map %w(post tweet update) => :status
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
data/lib/t/list.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
require 'active_support/core_ext/array/grouping'
|
3
|
+
require 'retryable'
|
4
|
+
require 't/core_ext/enumerable'
|
5
|
+
require 't/core_ext/string'
|
6
|
+
require 't/rcfile'
|
7
|
+
require 't/requestable'
|
8
|
+
require 'thor'
|
9
|
+
|
10
|
+
module T
|
11
|
+
class List < Thor
|
12
|
+
include ActionView::Helpers::DateHelper
|
13
|
+
include T::Requestable
|
14
|
+
|
15
|
+
DEFAULT_NUM_RESULTS = 20
|
16
|
+
MAX_SCREEN_NAME_SIZE = 20
|
17
|
+
MAX_USERS_PER_LIST = 500
|
18
|
+
MAX_USERS_PER_REQUEST = 100
|
19
|
+
|
20
|
+
check_unknown_options!
|
21
|
+
|
22
|
+
def initialize(*)
|
23
|
+
super
|
24
|
+
@rcfile = RCFile.instance
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "add LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Add users to a list."
|
28
|
+
def add(list_name, screen_name, *screen_names)
|
29
|
+
screen_names.unshift(screen_name)
|
30
|
+
screen_names.map!(&:strip_at)
|
31
|
+
screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
|
32
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
33
|
+
client.list_add_members(list_name, user_id_group)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
number = screen_names.length
|
37
|
+
say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'user' : 'users'} to the list \"#{list_name}\"."
|
38
|
+
say
|
39
|
+
say "Run `#{File.basename($0)} list remove users #{list_name} #{screen_names.join(' ')}` to undo."
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "create LIST_NAME [DESCRIPTION]", "Create a new list."
|
43
|
+
method_option :private, :aliases => "-p", :type => :boolean
|
44
|
+
def create(list_name, description="")
|
45
|
+
opts = description.blank? ? {} : {:description => description}
|
46
|
+
opts.merge!(:mode => 'private') if options['private']
|
47
|
+
client.list_create(list_name, opts)
|
48
|
+
say "@#{@rcfile.default_profile[0]} created the list \"#{list_name}\"."
|
49
|
+
end
|
50
|
+
|
51
|
+
# Remove
|
52
|
+
desc "remove LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Remove users from a list."
|
53
|
+
def remove(list_name, screen_name, *screen_names)
|
54
|
+
screen_names.unshift(screen_name)
|
55
|
+
screen_names.map!(&:strip_at)
|
56
|
+
screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
|
57
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
58
|
+
client.list_remove_members(list_name, user_id_group)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
number = screen_names.length
|
62
|
+
say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'user' : 'users'} from the list \"#{list_name}\"."
|
63
|
+
say
|
64
|
+
say "Run `#{File.basename($0)} list add users #{list_name} #{screen_names.join(' ')}` to undo."
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "timeline [SCREEN_NAME] LIST_NAME", "Show tweet timeline for members of the specified list."
|
68
|
+
method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
|
69
|
+
method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
|
70
|
+
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
|
71
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
72
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
73
|
+
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
74
|
+
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
|
75
|
+
method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
|
76
|
+
method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
|
77
|
+
method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
|
78
|
+
def timeline(*args)
|
79
|
+
list = args.pop
|
80
|
+
owner = args.pop || @rcfile.default_profile[0]
|
81
|
+
per_page = options['number'] || DEFAULT_NUM_RESULTS
|
82
|
+
statuses = client.list_timeline(owner, list, :include_entities => false, :per_page => per_page)
|
83
|
+
statuses.reverse! if options['reverse']
|
84
|
+
if options['long']
|
85
|
+
array = statuses.map do |status|
|
86
|
+
created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
|
87
|
+
[status.id.to_s, created_at, status.user.screen_name, status.text.gsub(/\n+/, ' ')]
|
88
|
+
end
|
89
|
+
if STDOUT.tty?
|
90
|
+
headings = ["ID", "Created at", "Screen name", "Text"]
|
91
|
+
array.unshift(headings)
|
92
|
+
end
|
93
|
+
print_table(array)
|
94
|
+
else
|
95
|
+
statuses.each do |status|
|
96
|
+
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(status.created_at)} ago)"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
map %w(tl) => :timeline
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
data/lib/t/search.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
require 'retryable'
|
3
|
+
require 't/core_ext/enumerable'
|
4
|
+
require 't/rcfile'
|
5
|
+
require 't/requestable'
|
6
|
+
require 'thor'
|
7
|
+
|
8
|
+
module T
|
9
|
+
class Search < Thor
|
10
|
+
include ActionView::Helpers::DateHelper
|
11
|
+
include T::Requestable
|
12
|
+
|
13
|
+
DEFAULT_NUM_RESULTS = 20
|
14
|
+
MAX_PAGES = 16
|
15
|
+
MAX_NUM_RESULTS = 200
|
16
|
+
MAX_SCREEN_NAME_SIZE = 20
|
17
|
+
|
18
|
+
check_unknown_options!
|
19
|
+
|
20
|
+
def initialize(*)
|
21
|
+
super
|
22
|
+
@rcfile = RCFile.instance
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "all QUERY", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets that match a specified query."
|
26
|
+
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
27
|
+
def all(query)
|
28
|
+
rpp = options['number'] || DEFAULT_NUM_RESULTS
|
29
|
+
statuses = client.search(query, :include_entities => false, :rpp => rpp)
|
30
|
+
if parent_options['long']
|
31
|
+
array = statuses.map do |status|
|
32
|
+
created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
|
33
|
+
[status.id.to_s, created_at, status.from_user, status.text.gsub(/\n+/, ' ')]
|
34
|
+
end
|
35
|
+
if STDOUT.tty?
|
36
|
+
headings = ["ID", "Created at", "Screen name", "Text"]
|
37
|
+
array.unshift(headings)
|
38
|
+
end
|
39
|
+
print_table(array)
|
40
|
+
else
|
41
|
+
statuses.each do |status|
|
42
|
+
say "#{status.from_user.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(status.created_at)} ago)"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "favorites QUERY", "Returns Tweets you've favorited that mach a specified query."
|
48
|
+
def favorites(query)
|
49
|
+
statuses = 1.upto(MAX_PAGES).threaded_map do |page|
|
50
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
51
|
+
client.favorites(:page => page, :count => MAX_NUM_RESULTS).select do |status|
|
52
|
+
/#{query}/i.match(status.text)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end.flatten.compact
|
56
|
+
print_status_list(statuses)
|
57
|
+
end
|
58
|
+
map %w(faves) => :favorites
|
59
|
+
|
60
|
+
desc "mentions QUERY", "Returns Tweets mentioning you that mach a specified query."
|
61
|
+
def mentions(query)
|
62
|
+
statuses = 1.upto(MAX_PAGES).threaded_map do |page|
|
63
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
64
|
+
client.mentions(:page => page, :count => MAX_NUM_RESULTS).select do |status|
|
65
|
+
/#{query}/i.match(status.text)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end.flatten.compact
|
69
|
+
print_status_list(statuses)
|
70
|
+
end
|
71
|
+
map %w(replies) => :mentions
|
72
|
+
|
73
|
+
desc "retweets QUERY", "Returns Tweets you've retweeted that mach a specified query."
|
74
|
+
def retweets(query)
|
75
|
+
statuses = 1.upto(MAX_PAGES).threaded_map do |page|
|
76
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
77
|
+
client.retweeted_by(:page => page, :count => MAX_NUM_RESULTS).select do |status|
|
78
|
+
/#{query}/i.match(status.text)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end.flatten.compact
|
82
|
+
print_status_list(statuses)
|
83
|
+
end
|
84
|
+
map %w(rts) => :retweets
|
85
|
+
|
86
|
+
desc "timeline QUERY", "Returns Tweets in your timeline that match a specified query."
|
87
|
+
def timeline(query)
|
88
|
+
statuses = 1.upto(MAX_PAGES).threaded_map do |page|
|
89
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
90
|
+
client.home_timeline(:page => page, :count => MAX_NUM_RESULTS).select do |status|
|
91
|
+
/#{query}/i.match(status.text)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end.flatten.compact
|
95
|
+
print_status_list(statuses)
|
96
|
+
end
|
97
|
+
map %w(tl) => :timeline
|
98
|
+
|
99
|
+
desc "user SCREEN_NAME QUERY", "Returns Tweets in a user's timeline that match a specified query."
|
100
|
+
def user(screen_name, query)
|
101
|
+
screen_name = screen_name.strip_at
|
102
|
+
statuses = 1.upto(MAX_PAGES).threaded_map do |page|
|
103
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
104
|
+
client.user_timeline(screen_name, :page => page, :count => MAX_NUM_RESULTS).select do |status|
|
105
|
+
/#{query}/i.match(status.text)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end.flatten.compact
|
109
|
+
print_status_list(statuses)
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def print_status_list(statuses)
|
115
|
+
if parent_options['long']
|
116
|
+
array = statuses.map do |status|
|
117
|
+
created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
|
118
|
+
[status.id.to_s, created_at, status.user.screen_name, status.text.gsub(/\n+/, ' ')]
|
119
|
+
end
|
120
|
+
if STDOUT.tty?
|
121
|
+
headings = ["ID", "Created at", "Screen name", "Text"]
|
122
|
+
array.unshift(headings)
|
123
|
+
end
|
124
|
+
print_table(array)
|
125
|
+
else
|
126
|
+
statuses.each do |status|
|
127
|
+
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(status.created_at)} ago)"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
data/lib/t/set.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 't/core_ext/string'
|
2
|
+
require 't/rcfile'
|
3
|
+
require 't/requestable'
|
4
|
+
require 'thor'
|
5
|
+
|
6
|
+
module T
|
7
|
+
class Set < Thor
|
8
|
+
include T::Requestable
|
9
|
+
|
10
|
+
check_unknown_options!
|
11
|
+
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@rcfile = RCFile.instance
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "bio DESCRIPTION", "Edits your Bio information on your Twitter profile."
|
18
|
+
def bio(description)
|
19
|
+
client.update_profile(:description => description, :include_entities => false)
|
20
|
+
say "@#{@rcfile.default_profile[0]}'s bio has been updated."
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "default SCREEN_NAME [CONSUMER_KEY]", "Set your default account."
|
24
|
+
def default(screen_name, consumer_key=nil)
|
25
|
+
screen_name = screen_name.strip_at
|
26
|
+
@rcfile.path = parent_options['profile'] if parent_options['profile']
|
27
|
+
consumer_key = @rcfile[screen_name].keys.last if consumer_key.nil?
|
28
|
+
@rcfile.default_profile = {'username' => screen_name, 'consumer_key' => consumer_key}
|
29
|
+
say "Default account has been updated."
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "language LANGUAGE_NAME", "Selects the language you'd like to receive notifications in."
|
33
|
+
def language(language_name)
|
34
|
+
client.settings(:lang => language_name)
|
35
|
+
say "@#{@rcfile.default_profile[0]}'s language has been updated."
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "location PLACE_NAME", "Updates the location field in your profile."
|
39
|
+
def location(place_name)
|
40
|
+
client.update_profile(:location => place_name, :include_entities => false)
|
41
|
+
say "@#{@rcfile.default_profile[0]}'s location has been updated."
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "name NAME", "Sets the name field on your Twitter profile."
|
45
|
+
def name(name)
|
46
|
+
client.update_profile(:name => name, :include_entities => false)
|
47
|
+
say "@#{@rcfile.default_profile[0]}'s name has been updated."
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "url URL", "Sets the URL field on your profile."
|
51
|
+
def url(url)
|
52
|
+
client.update_profile(:url => url, :include_entities => false)
|
53
|
+
say "@#{@rcfile.default_profile[0]}'s URL has been updated."
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/t/version.rb
CHANGED
data/spec/cli_spec.rb
CHANGED
@@ -89,13 +89,13 @@ describe T::CLI do
|
|
89
89
|
describe "#direct_messages" do
|
90
90
|
before do
|
91
91
|
stub_get("/1/direct_messages.json").
|
92
|
-
with(:query => {:include_entities => "false"}).
|
92
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
93
93
|
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
94
94
|
end
|
95
95
|
it "should request the correct resource" do
|
96
96
|
@t.direct_messages
|
97
97
|
a_get("/1/direct_messages.json").
|
98
|
-
with(:query => {:include_entities => "false"}).
|
98
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
99
99
|
should have_been_made
|
100
100
|
end
|
101
101
|
it "should have the correct output" do
|
@@ -125,6 +125,45 @@ describe T::CLI do
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
+
describe "#direct_messages_sent" do
|
129
|
+
before do
|
130
|
+
stub_get("/1/direct_messages/sent.json").
|
131
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
132
|
+
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
133
|
+
end
|
134
|
+
it "should request the correct resource" do
|
135
|
+
@t.direct_messages_sent
|
136
|
+
a_get("/1/direct_messages/sent.json").
|
137
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
138
|
+
should have_been_made
|
139
|
+
end
|
140
|
+
it "should have the correct output" do
|
141
|
+
@t.direct_messages_sent
|
142
|
+
$stdout.string.should == <<-eos.gsub(/^/, ' ' * 3)
|
143
|
+
hurrycane: Sounds good. Meeting Tuesday is fine. (about 1 year ago)
|
144
|
+
technoweenie: if you want to add me to your GroupMe group, my phone number is 415-312-2382 (about 1 year ago)
|
145
|
+
hurrycane: That's great news! Let's plan to chat around 8 AM tomorrow Pacific time. Does that work for you? (about 1 year ago)
|
146
|
+
hurrycane: I asked Yehuda about the stipend. I believe it has already been sent. Glad you're feeling better. (about 1 year ago)
|
147
|
+
hurrycane: Just checking in. How's everything going? (about 1 year ago)
|
148
|
+
hurrycane: Any luck completing graphs this weekend? There have been lots of commits to RailsAdmin since summer ended but none from you. How's it going? (about 1 year ago)
|
149
|
+
hurrycane: Not sure about the payment. Feel free to ask Leah or Yehuda directly. Think you'll be able to finish up your work on graphs this weekend? (about 1 year ago)
|
150
|
+
hurrycane: Looks good to me. I'm going to pull in the change now. My only concern is that we don't have any tests for auth. (about 1 year ago)
|
151
|
+
hurrycane: How are the graph enhancements coming? (about 1 year ago)
|
152
|
+
hurrycane: Changes pushed. You should pull and re-bundle when you have a minute. (about 1 year ago)
|
153
|
+
hurrycane: Glad to hear the new graphs are coming along. Can't wait to see them! (about 1 year ago)
|
154
|
+
hurrycane: I figured out what was wrong with the tests: I accidentally unbundled webrat. The problem had nothing to do with rspec-rails. (about 1 year ago)
|
155
|
+
hurrycane: After the upgrade 54/80 specs are failing. I'm working on fixing them now. (about 1 year ago)
|
156
|
+
hurrycane: a new version of rspec-rails just shipped with some nice features and fixes http://github.com/rspec/rspec-rails/blob/master/History.md (about 1 year ago)
|
157
|
+
hurrycane: How are the graphs coming? I'm really looking forward to seeing what you do with Raphaël. (about 1 year ago)
|
158
|
+
hurrycane: Awesome! Any luck duplicating the Gemfile.lock error with Ruby 1.9.2 final? (about 1 year ago)
|
159
|
+
hurrycane: I just committed a bunch of cleanup and fixes to RailsAdmin that touched many of files. Make sure you pull to avoid conflicts. (about 1 year ago)
|
160
|
+
hurrycane: Can you try upgrading to 1.9.2 final, re-installing Bundler 1.0.0.rc.6 (don't remove 1.0.0) and see if you can reproduce the problem? (about 1 year ago)
|
161
|
+
hurrycane: I'm trying to debug the issue you were having with the Bundler Gemfile.lock shortref. What version of Ruby and RubyGems are you running? (about 1 year ago)
|
162
|
+
hurrycane: Let's try to debug that problem during our session in 1.5 hours. In the mean time, try working on the graphs or internationalization. (about 1 year ago)
|
163
|
+
eos
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
128
167
|
describe "#dm" do
|
129
168
|
before do
|
130
169
|
@t.options = @t.options.merge(:profile => fixture_path + "/.trc")
|
@@ -140,84 +179,37 @@ describe T::CLI do
|
|
140
179
|
end
|
141
180
|
it "should have the correct output" do
|
142
181
|
@t.dm("pengwynn", "Creating a fixture for the Twitter gem")
|
143
|
-
$stdout.string.chomp.should == "Direct Message sent from @testcli to @pengwynn (about 1 year ago)"
|
182
|
+
$stdout.string.chomp.should == "Direct Message sent from @testcli to @pengwynn (about 1 year ago)."
|
144
183
|
end
|
145
184
|
end
|
146
185
|
|
147
186
|
describe "#favorite" do
|
148
187
|
before do
|
149
188
|
@t.options = @t.options.merge(:profile => fixture_path + "/.trc")
|
189
|
+
stub_post("/1/favorites/create/26755176471724032.json").
|
190
|
+
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
150
191
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
to_return(:body => '{}', :headers => {:content_type => "application/json; charset=utf-8"})
|
156
|
-
end
|
157
|
-
it "should exit" do
|
158
|
-
lambda do
|
159
|
-
@t.favorite("sferik")
|
160
|
-
end.should raise_error(Thor::Error, "Tweet not found")
|
161
|
-
end
|
162
|
-
end
|
163
|
-
context "forbidden" do
|
164
|
-
before do
|
165
|
-
stub_get("/1/users/show.json").
|
166
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
167
|
-
to_return(:body => '{"error":"Forbidden"}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
168
|
-
end
|
169
|
-
it "should exit" do
|
170
|
-
lambda do
|
171
|
-
@t.favorite("sferik")
|
172
|
-
end.should raise_error(Twitter::Error::Forbidden, "Forbidden")
|
173
|
-
end
|
174
|
-
end
|
175
|
-
context "duplicate" do
|
176
|
-
before do
|
177
|
-
stub_get("/1/users/show.json").
|
178
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
179
|
-
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
180
|
-
stub_post("/1/favorites/create/26755176471724032.json").
|
181
|
-
to_return(:body => '{"error":"You have already favorited this status."}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
182
|
-
end
|
183
|
-
it "should have the correct output" do
|
184
|
-
@t.favorite("sferik")
|
185
|
-
$stdout.string.should =~ /^@testcli favorited @sferik's latest status: "RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3"$/
|
186
|
-
end
|
192
|
+
it "should request the correct resource" do
|
193
|
+
@t.favorite("26755176471724032")
|
194
|
+
a_post("/1/favorites/create/26755176471724032.json").
|
195
|
+
should have_been_made
|
187
196
|
end
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
192
|
-
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
193
|
-
stub_post("/1/favorites/create/26755176471724032.json").
|
194
|
-
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
195
|
-
end
|
196
|
-
it "should request the correct resource" do
|
197
|
-
@t.favorite("sferik")
|
198
|
-
a_get("/1/users/show.json").
|
199
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
200
|
-
should have_been_made
|
201
|
-
a_post("/1/favorites/create/26755176471724032.json").
|
202
|
-
should have_been_made
|
203
|
-
end
|
204
|
-
it "should have the correct output" do
|
205
|
-
@t.favorite("sferik")
|
206
|
-
$stdout.string.should =~ /^@testcli favorited @sferik's latest status: "RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3"$/
|
207
|
-
end
|
197
|
+
it "should have the correct output" do
|
198
|
+
@t.favorite("26755176471724032")
|
199
|
+
$stdout.string.should =~ /^@testcli favorited @sferik's status: "@noradio working on implementing #NewTwitter API methods in the twitter gem\. Twurl is making it easy\. Thank you!"$/
|
208
200
|
end
|
209
201
|
end
|
210
202
|
|
211
203
|
describe "#favorites" do
|
212
204
|
before do
|
213
205
|
stub_get("/1/favorites.json").
|
214
|
-
with(:query => {:include_entities => "false"}).
|
206
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
215
207
|
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
216
208
|
end
|
217
209
|
it "should request the correct resource" do
|
218
210
|
@t.favorites
|
219
211
|
a_get("/1/favorites.json").
|
220
|
-
with(:query => {:include_entities => "false"}).
|
212
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
221
213
|
should have_been_made
|
222
214
|
end
|
223
215
|
it "should have the correct output" do
|
@@ -246,16 +238,180 @@ describe T::CLI do
|
|
246
238
|
end
|
247
239
|
end
|
248
240
|
|
241
|
+
describe "#follow" do
|
242
|
+
before do
|
243
|
+
@t.options = @t.options.merge(:profile => fixture_path + "/.trc")
|
244
|
+
end
|
245
|
+
context "no users" do
|
246
|
+
it "should exit" do
|
247
|
+
lambda do
|
248
|
+
@t.follow
|
249
|
+
end.should raise_error
|
250
|
+
end
|
251
|
+
end
|
252
|
+
context "one user" do
|
253
|
+
it "should request the correct resource" do
|
254
|
+
stub_post("/1/friendships/create.json").
|
255
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
256
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
257
|
+
@t.follow("sferik")
|
258
|
+
a_post("/1/friendships/create.json").
|
259
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
260
|
+
should have_been_made
|
261
|
+
end
|
262
|
+
it "should have the correct output" do
|
263
|
+
stub_post("/1/friendships/create.json").
|
264
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
265
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
266
|
+
@t.follow("sferik")
|
267
|
+
$stdout.string.should =~ /^@testcli is now following 1 more user\.$/
|
268
|
+
end
|
269
|
+
context "Twitter is down" do
|
270
|
+
it "should retry 3 times and then raise an error" do
|
271
|
+
stub_post("/1/friendships/create.json").
|
272
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
273
|
+
to_return(:status => 502)
|
274
|
+
lambda do
|
275
|
+
@t.follow("sferik")
|
276
|
+
end.should raise_error("Twitter is down or being upgraded.")
|
277
|
+
a_post("/1/friendships/create.json").
|
278
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
279
|
+
should have_been_made.times(3)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "#followings" do
|
286
|
+
before do
|
287
|
+
stub_get("/1/friends/ids.json").
|
288
|
+
with(:query => {:cursor => "-1"}).
|
289
|
+
to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
290
|
+
stub_get("/1/users/lookup.json").
|
291
|
+
with(:query => {:user_id => "7505382", :include_entities => "false"}).
|
292
|
+
to_return(:body => fixture("users.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
293
|
+
end
|
294
|
+
it "should request the correct resource" do
|
295
|
+
@t.followings
|
296
|
+
a_get("/1/friends/ids.json").
|
297
|
+
with(:query => {:cursor => "-1"}).
|
298
|
+
should have_been_made
|
299
|
+
a_get("/1/users/lookup.json").
|
300
|
+
with(:query => {:user_id => "7505382", :include_entities => "false"}).
|
301
|
+
should have_been_made
|
302
|
+
end
|
303
|
+
it "should have the correct output" do
|
304
|
+
@t.followings
|
305
|
+
$stdout.string.chomp.rstrip.should == "pengwynn sferik"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
describe "#followers" do
|
310
|
+
before do
|
311
|
+
stub_get("/1/followers/ids.json").
|
312
|
+
with(:query => {:cursor => "-1"}).
|
313
|
+
to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
314
|
+
stub_get("/1/users/lookup.json").
|
315
|
+
with(:query => {:user_id => "7505382", :include_entities => "false"}).
|
316
|
+
to_return(:body => fixture("users.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
317
|
+
end
|
318
|
+
it "should request the correct resource" do
|
319
|
+
@t.followers
|
320
|
+
a_get("/1/followers/ids.json").
|
321
|
+
with(:query => {:cursor => "-1"}).
|
322
|
+
should have_been_made
|
323
|
+
a_get("/1/users/lookup.json").
|
324
|
+
with(:query => {:user_id => "7505382", :include_entities => "false"}).
|
325
|
+
should have_been_made
|
326
|
+
end
|
327
|
+
it "should have the correct output" do
|
328
|
+
@t.followers
|
329
|
+
$stdout.string.chomp.rstrip.should == "pengwynn sferik"
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe "#friends" do
|
334
|
+
before do
|
335
|
+
stub_get("/1/friends/ids.json").
|
336
|
+
with(:query => {:cursor => "-1"}).
|
337
|
+
to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
338
|
+
stub_get("/1/followers/ids.json").
|
339
|
+
with(:query => {:cursor => "-1"}).
|
340
|
+
to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
341
|
+
stub_get("/1/users/lookup.json").
|
342
|
+
with(:query => {:user_id => "7505382", :include_entities => "false"}).
|
343
|
+
to_return(:body => fixture("users.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
344
|
+
end
|
345
|
+
it "should request the correct resource" do
|
346
|
+
@t.friends
|
347
|
+
a_get("/1/friends/ids.json").
|
348
|
+
with(:query => {:cursor => "-1"}).
|
349
|
+
should have_been_made
|
350
|
+
a_get("/1/followers/ids.json").
|
351
|
+
with(:query => {:cursor => "-1"}).
|
352
|
+
should have_been_made
|
353
|
+
a_get("/1/users/lookup.json").
|
354
|
+
with(:query => {:user_id => "7505382", :include_entities => "false"}).
|
355
|
+
should have_been_made
|
356
|
+
end
|
357
|
+
it "should have the correct output" do
|
358
|
+
@t.friends
|
359
|
+
$stdout.string.chomp.rstrip.should == "pengwynn sferik"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
describe "#leaders" do
|
364
|
+
before do
|
365
|
+
stub_get("/1/friends/ids.json").
|
366
|
+
with(:query => {:cursor => "-1"}).
|
367
|
+
to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
368
|
+
stub_get("/1/followers/ids.json").
|
369
|
+
with(:query => {:cursor => "-1"}).
|
370
|
+
to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
371
|
+
end
|
372
|
+
it "should request the correct resource" do
|
373
|
+
@t.leaders
|
374
|
+
a_get("/1/friends/ids.json").
|
375
|
+
with(:query => {:cursor => "-1"}).
|
376
|
+
should have_been_made
|
377
|
+
a_get("/1/followers/ids.json").
|
378
|
+
with(:query => {:cursor => "-1"}).
|
379
|
+
should have_been_made
|
380
|
+
end
|
381
|
+
it "should have the correct output" do
|
382
|
+
@t.leaders
|
383
|
+
$stdout.string.chomp.rstrip.should == ""
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
describe "#members" do
|
388
|
+
before do
|
389
|
+
stub_get("/1/lists/members.json").
|
390
|
+
with(:query => {:cursor => "-1", :include_entities => "false", :owner_screen_name => "sferik", :skip_status => "true", :slug => "presidents"}).
|
391
|
+
to_return(:body => fixture("empty_cursor.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
392
|
+
end
|
393
|
+
it "should request the correct resource" do
|
394
|
+
@t.members("sferik", "presidents")
|
395
|
+
a_get("/1/lists/members.json").
|
396
|
+
with(:query => {:cursor => "-1", :include_entities => "false", :owner_screen_name => "sferik", :skip_status => "true", :slug => "presidents"}).
|
397
|
+
should have_been_made
|
398
|
+
end
|
399
|
+
it "should have the correct output" do
|
400
|
+
@t.members("sferik", "presidents")
|
401
|
+
$stdout.string.chomp.should == ""
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
249
405
|
describe "#mentions" do
|
250
406
|
before do
|
251
407
|
stub_get("/1/statuses/mentions.json").
|
252
|
-
with(:query => {:include_entities => "false"}).
|
408
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
253
409
|
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
254
410
|
end
|
255
411
|
it "should request the correct resource" do
|
256
412
|
@t.mentions
|
257
413
|
a_get("/1/statuses/mentions.json").
|
258
|
-
with(:query => {:include_entities => "false"}).
|
414
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
259
415
|
should have_been_made
|
260
416
|
end
|
261
417
|
it "should have the correct output" do
|
@@ -298,11 +454,11 @@ describe T::CLI do
|
|
298
454
|
describe "#reply" do
|
299
455
|
before do
|
300
456
|
@t.options = @t.options.merge(:profile => fixture_path + "/.trc", :location => true)
|
301
|
-
stub_get("/1/
|
302
|
-
with(:query => {:
|
303
|
-
to_return(:body => fixture("
|
457
|
+
stub_get("/1/statuses/show/25938088801.json").
|
458
|
+
with(:query => {:include_entities => "false", :include_my_retweet => "false", :trim_user => "true"}).
|
459
|
+
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
304
460
|
stub_post("/1/statuses/update.json").
|
305
|
-
with(:body => {:in_reply_to_status_id => "
|
461
|
+
with(:body => {:in_reply_to_status_id => "25938088801", :status => "@sferik Testing", :lat => "37.76969909668", :long => "-122.39330291748", :include_entities => "false", :trim_user => "true"}).
|
306
462
|
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
307
463
|
stub_request(:get, "http://checkip.dyndns.org/").
|
308
464
|
to_return(:body => fixture("checkip.html"), :headers => {:content_type => "text/html"})
|
@@ -310,12 +466,12 @@ describe T::CLI do
|
|
310
466
|
to_return(:body => fixture("xml.gp"), :headers => {:content_type => "application/xml"})
|
311
467
|
end
|
312
468
|
it "should request the correct resource" do
|
313
|
-
@t.reply("
|
314
|
-
a_get("/1/
|
315
|
-
with(:query => {:
|
469
|
+
@t.reply("25938088801", "Testing")
|
470
|
+
a_get("/1/statuses/show/25938088801.json").
|
471
|
+
with(:query => {:include_entities => "false", :include_my_retweet => "false", :trim_user => "true"}).
|
316
472
|
should have_been_made
|
317
473
|
a_post("/1/statuses/update.json").
|
318
|
-
with(:body => {:in_reply_to_status_id => "
|
474
|
+
with(:body => {:in_reply_to_status_id => "25938088801", :status => "@sferik Testing", :lat => "37.76969909668", :long => "-122.39330291748", :include_entities => "false", :trim_user => "true"}).
|
319
475
|
should have_been_made
|
320
476
|
a_request(:get, "http://checkip.dyndns.org/").
|
321
477
|
should have_been_made
|
@@ -323,72 +479,44 @@ describe T::CLI do
|
|
323
479
|
should have_been_made
|
324
480
|
end
|
325
481
|
it "should have the correct output" do
|
326
|
-
@t.reply("
|
327
|
-
$stdout.string.should =~ /^Reply created by @testcli to @sferik \(about 1 year ago\)
|
482
|
+
@t.reply("25938088801", "Testing")
|
483
|
+
$stdout.string.should =~ /^Reply created by @testcli to @sferik \(about 1 year ago\)\.$/
|
328
484
|
end
|
329
485
|
end
|
330
486
|
|
331
|
-
describe "#
|
487
|
+
describe "#report_spam" do
|
332
488
|
before do
|
333
489
|
@t.options = @t.options.merge(:profile => fixture_path + "/.trc")
|
490
|
+
stub_post("/1/report_spam.json").
|
491
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
492
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
334
493
|
end
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
end
|
341
|
-
it "should exit" do
|
342
|
-
lambda do
|
343
|
-
@t.retweet("sferik")
|
344
|
-
end.should raise_error(Thor::Error, "Tweet not found")
|
345
|
-
end
|
494
|
+
it "should request the correct resource" do
|
495
|
+
@t.report_spam("sferik")
|
496
|
+
a_post("/1/report_spam.json").
|
497
|
+
with(:body => {:screen_name => "sferik", :include_entities => "false"}).
|
498
|
+
should have_been_made
|
346
499
|
end
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
351
|
-
to_return(:body => '{"error":"Forbidden"}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
352
|
-
end
|
353
|
-
it "should exit" do
|
354
|
-
lambda do
|
355
|
-
@t.retweet("sferik")
|
356
|
-
end.should raise_error(Twitter::Error::Forbidden, "Forbidden")
|
357
|
-
end
|
500
|
+
it "should have the correct output" do
|
501
|
+
@t.report_spam("sferik")
|
502
|
+
$stdout.string.should =~ /^@testcli reported @sferik/
|
358
503
|
end
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
end
|
367
|
-
it "should have the correct output" do
|
368
|
-
@t.retweet("sferik")
|
369
|
-
$stdout.string.should =~ /^@testcli retweeted @sferik's latest status: "RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3"$/
|
370
|
-
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe "#retweet" do
|
507
|
+
before do
|
508
|
+
@t.options = @t.options.merge(:profile => fixture_path + "/.trc")
|
509
|
+
stub_post("/1/statuses/retweet/26755176471724032.json").
|
510
|
+
to_return(:body => fixture("retweet.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
371
511
|
end
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
it "should request the correct resource" do
|
381
|
-
@t.retweet("sferik")
|
382
|
-
a_get("/1/users/show.json").
|
383
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
384
|
-
should have_been_made
|
385
|
-
a_post("/1/statuses/retweet/26755176471724032.json").
|
386
|
-
should have_been_made
|
387
|
-
end
|
388
|
-
it "should have the correct output" do
|
389
|
-
@t.retweet("sferik")
|
390
|
-
$stdout.string.should =~ /^@testcli retweeted @sferik's latest status: "RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3"$/
|
391
|
-
end
|
512
|
+
it "should request the correct resource" do
|
513
|
+
@t.retweet("26755176471724032")
|
514
|
+
a_post("/1/statuses/retweet/26755176471724032.json").
|
515
|
+
should have_been_made
|
516
|
+
end
|
517
|
+
it "should have the correct output" do
|
518
|
+
@t.retweet("26755176471724032")
|
519
|
+
$stdout.string.should =~ /^@testcli retweeted @gruber's status: "As for the Series, I'm for the Giants\. Fuck Texas, fuck Nolan Ryan, fuck George Bush\."$/
|
392
520
|
end
|
393
521
|
end
|
394
522
|
|
@@ -396,13 +524,13 @@ describe T::CLI do
|
|
396
524
|
context "without arguments" do
|
397
525
|
before do
|
398
526
|
stub_get("/1/statuses/retweeted_by_me.json").
|
399
|
-
with(:query => {:include_entities => "false"}).
|
527
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
400
528
|
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
401
529
|
end
|
402
530
|
it "should request the correct resource" do
|
403
531
|
@t.retweets
|
404
532
|
a_get("/1/statuses/retweeted_by_me.json").
|
405
|
-
with(:query => {:include_entities => "false"}).
|
533
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
406
534
|
should have_been_made
|
407
535
|
end
|
408
536
|
it "should have the correct output" do
|
@@ -433,13 +561,13 @@ describe T::CLI do
|
|
433
561
|
context "with a screen name passed" do
|
434
562
|
before do
|
435
563
|
stub_get("/1/statuses/retweeted_by_user.json").
|
436
|
-
with(:query => {:
|
564
|
+
with(:query => {:count => "20", :include_entities => "false", :screen_name => "sferik"}).
|
437
565
|
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
438
566
|
end
|
439
567
|
it "should request the correct resource" do
|
440
568
|
@t.retweets("sferik")
|
441
569
|
a_get("/1/statuses/retweeted_by_user.json").
|
442
|
-
with(:query => {:
|
570
|
+
with(:query => {:count => "20", :include_entities => "false", :screen_name => "sferik"}).
|
443
571
|
should have_been_made
|
444
572
|
end
|
445
573
|
it "should have the correct output" do
|
@@ -469,67 +597,6 @@ describe T::CLI do
|
|
469
597
|
end
|
470
598
|
end
|
471
599
|
|
472
|
-
describe "#sent_messages" do
|
473
|
-
before do
|
474
|
-
stub_get("/1/direct_messages/sent.json").
|
475
|
-
with(:query => {:include_entities => "false"}).
|
476
|
-
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
477
|
-
end
|
478
|
-
it "should request the correct resource" do
|
479
|
-
@t.sent_messages
|
480
|
-
a_get("/1/direct_messages/sent.json").
|
481
|
-
with(:query => {:include_entities => "false"}).
|
482
|
-
should have_been_made
|
483
|
-
end
|
484
|
-
it "should have the correct output" do
|
485
|
-
@t.sent_messages
|
486
|
-
$stdout.string.should == <<-eos.gsub(/^/, ' ' * 3)
|
487
|
-
hurrycane: Sounds good. Meeting Tuesday is fine. (about 1 year ago)
|
488
|
-
technoweenie: if you want to add me to your GroupMe group, my phone number is 415-312-2382 (about 1 year ago)
|
489
|
-
hurrycane: That's great news! Let's plan to chat around 8 AM tomorrow Pacific time. Does that work for you? (about 1 year ago)
|
490
|
-
hurrycane: I asked Yehuda about the stipend. I believe it has already been sent. Glad you're feeling better. (about 1 year ago)
|
491
|
-
hurrycane: Just checking in. How's everything going? (about 1 year ago)
|
492
|
-
hurrycane: Any luck completing graphs this weekend? There have been lots of commits to RailsAdmin since summer ended but none from you. How's it going? (about 1 year ago)
|
493
|
-
hurrycane: Not sure about the payment. Feel free to ask Leah or Yehuda directly. Think you'll be able to finish up your work on graphs this weekend? (about 1 year ago)
|
494
|
-
hurrycane: Looks good to me. I'm going to pull in the change now. My only concern is that we don't have any tests for auth. (about 1 year ago)
|
495
|
-
hurrycane: How are the graph enhancements coming? (about 1 year ago)
|
496
|
-
hurrycane: Changes pushed. You should pull and re-bundle when you have a minute. (about 1 year ago)
|
497
|
-
hurrycane: Glad to hear the new graphs are coming along. Can't wait to see them! (about 1 year ago)
|
498
|
-
hurrycane: I figured out what was wrong with the tests: I accidentally unbundled webrat. The problem had nothing to do with rspec-rails. (about 1 year ago)
|
499
|
-
hurrycane: After the upgrade 54/80 specs are failing. I'm working on fixing them now. (about 1 year ago)
|
500
|
-
hurrycane: a new version of rspec-rails just shipped with some nice features and fixes http://github.com/rspec/rspec-rails/blob/master/History.md (about 1 year ago)
|
501
|
-
hurrycane: How are the graphs coming? I'm really looking forward to seeing what you do with Raphaël. (about 1 year ago)
|
502
|
-
hurrycane: Awesome! Any luck duplicating the Gemfile.lock error with Ruby 1.9.2 final? (about 1 year ago)
|
503
|
-
hurrycane: I just committed a bunch of cleanup and fixes to RailsAdmin that touched many of files. Make sure you pull to avoid conflicts. (about 1 year ago)
|
504
|
-
hurrycane: Can you try upgrading to 1.9.2 final, re-installing Bundler 1.0.0.rc.6 (don't remove 1.0.0) and see if you can reproduce the problem? (about 1 year ago)
|
505
|
-
hurrycane: I'm trying to debug the issue you were having with the Bundler Gemfile.lock shortref. What version of Ruby and RubyGems are you running? (about 1 year ago)
|
506
|
-
hurrycane: Let's try to debug that problem during our session in 1.5 hours. In the mean time, try working on the graphs or internationalization. (about 1 year ago)
|
507
|
-
eos
|
508
|
-
end
|
509
|
-
end
|
510
|
-
|
511
|
-
describe "#stats" do
|
512
|
-
before do
|
513
|
-
stub_get("/1/users/show.json").
|
514
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
515
|
-
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
516
|
-
end
|
517
|
-
it "should request the correct resource" do
|
518
|
-
@t.stats("sferik")
|
519
|
-
a_get("/1/users/show.json").
|
520
|
-
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
521
|
-
should have_been_made
|
522
|
-
end
|
523
|
-
it "should have the correct output" do
|
524
|
-
@t.stats("sferik")
|
525
|
-
$stdout.string.should =~ /^Tweets: 3,479$/
|
526
|
-
$stdout.string.should =~ /^Following: 197$/
|
527
|
-
$stdout.string.should =~ /^Followers: 1,048$/
|
528
|
-
$stdout.string.should =~ /^Favorites: 1,040$/
|
529
|
-
$stdout.string.should =~ /^Listed: 41$/
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
600
|
describe "#status" do
|
534
601
|
before do
|
535
602
|
@t.options = @t.options.merge(:profile => fixture_path + "/.trc", :location => true)
|
@@ -553,25 +620,25 @@ describe T::CLI do
|
|
553
620
|
end
|
554
621
|
it "should have the correct output" do
|
555
622
|
@t.status("Testing")
|
556
|
-
$stdout.string.should =~ /^Tweet created by @testcli \(about 1 year ago\)
|
623
|
+
$stdout.string.should =~ /^Tweet created by @testcli \(about 1 year ago\)\.$/
|
557
624
|
end
|
558
625
|
end
|
559
626
|
|
560
627
|
describe "#suggest" do
|
561
628
|
before do
|
562
629
|
stub_get("/1/users/recommendations.json").
|
563
|
-
with(:query => {:limit => "
|
630
|
+
with(:query => {:limit => "20", :include_entities => "false"}).
|
564
631
|
to_return(:body => fixture("recommendations.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
565
632
|
end
|
566
633
|
it "should request the correct resource" do
|
567
634
|
@t.suggest
|
568
635
|
a_get("/1/users/recommendations.json").
|
569
|
-
with(:query => {:limit => "
|
636
|
+
with(:query => {:limit => "20", :include_entities => "false"}).
|
570
637
|
should have_been_made
|
571
638
|
end
|
572
639
|
it "should have the correct output" do
|
573
640
|
@t.suggest
|
574
|
-
$stdout.string.should
|
641
|
+
$stdout.string.chomp.rstrip.should == "antpires jtrupiano maccman mlroach stuntmann82"
|
575
642
|
end
|
576
643
|
end
|
577
644
|
|
@@ -579,13 +646,13 @@ describe T::CLI do
|
|
579
646
|
context "without user" do
|
580
647
|
before do
|
581
648
|
stub_get("/1/statuses/home_timeline.json").
|
582
|
-
with(:query => {:include_entities => "false"}).
|
649
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
583
650
|
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
584
651
|
end
|
585
652
|
it "should request the correct resource" do
|
586
653
|
@t.timeline
|
587
654
|
a_get("/1/statuses/home_timeline.json").
|
588
|
-
with(:query => {:include_entities => "false"}).
|
655
|
+
with(:query => {:count => "20", :include_entities => "false"}).
|
589
656
|
should have_been_made
|
590
657
|
end
|
591
658
|
it "should have the correct output" do
|
@@ -616,13 +683,13 @@ describe T::CLI do
|
|
616
683
|
context "with user" do
|
617
684
|
before do
|
618
685
|
stub_get("/1/statuses/user_timeline.json").
|
619
|
-
with(:query => {:
|
686
|
+
with(:query => {:count => "20", :include_entities => "false", :screen_name => "sferik"}).
|
620
687
|
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
621
688
|
end
|
622
689
|
it "should request the correct resource" do
|
623
690
|
@t.timeline("sferik")
|
624
691
|
a_get("/1/statuses/user_timeline.json").
|
625
|
-
with(:query => {:
|
692
|
+
with(:query => {:count => "20", :include_entities => "false", :screen_name => "sferik"}).
|
626
693
|
should have_been_made
|
627
694
|
end
|
628
695
|
it "should have the correct output" do
|
@@ -652,6 +719,68 @@ describe T::CLI do
|
|
652
719
|
end
|
653
720
|
end
|
654
721
|
|
722
|
+
describe "#unfollow" do
|
723
|
+
before do
|
724
|
+
@t.options = @t.options.merge(:profile => fixture_path + "/.trc")
|
725
|
+
end
|
726
|
+
context "no users" do
|
727
|
+
it "should exit" do
|
728
|
+
lambda do
|
729
|
+
@t.unfollow
|
730
|
+
end.should raise_error
|
731
|
+
end
|
732
|
+
end
|
733
|
+
context "one user" do
|
734
|
+
it "should request the correct resource" do
|
735
|
+
stub_delete("/1/friendships/destroy.json").
|
736
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
737
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
738
|
+
@t.unfollow("sferik")
|
739
|
+
a_delete("/1/friendships/destroy.json").
|
740
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
741
|
+
should have_been_made
|
742
|
+
end
|
743
|
+
it "should have the correct output" do
|
744
|
+
stub_delete("/1/friendships/destroy.json").
|
745
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
746
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
747
|
+
@t.unfollow("sferik")
|
748
|
+
$stdout.string.should =~ /^@testcli is no longer following 1 user\.$/
|
749
|
+
end
|
750
|
+
context "Twitter is down" do
|
751
|
+
it "should retry 3 times and then raise an error" do
|
752
|
+
stub_delete("/1/friendships/destroy.json").
|
753
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
754
|
+
to_return(:status => 502)
|
755
|
+
lambda do
|
756
|
+
@t.unfollow("sferik")
|
757
|
+
end.should raise_error("Twitter is down or being upgraded.")
|
758
|
+
a_delete("/1/friendships/destroy.json").
|
759
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
760
|
+
should have_been_made.times(3)
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
describe "#users" do
|
767
|
+
before do
|
768
|
+
stub_get("/1/users/lookup.json").
|
769
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
770
|
+
to_return(:body => fixture("users.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
771
|
+
end
|
772
|
+
it "should request the correct resource" do
|
773
|
+
@t.users("sferik")
|
774
|
+
a_get("/1/users/lookup.json").
|
775
|
+
with(:query => {:screen_name => "sferik", :include_entities => "false"}).
|
776
|
+
should have_been_made
|
777
|
+
end
|
778
|
+
it "should have the correct output" do
|
779
|
+
@t.users("sferik")
|
780
|
+
$stdout.string.chomp.rstrip.should == "pengwynn sferik"
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
655
784
|
describe "#version" do
|
656
785
|
it "should have the correct output" do
|
657
786
|
@t.version
|