t 0.4.0 → 0.5.0
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/.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
|