t 0.0.2 → 0.1.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/.rspec +1 -0
- data/.travis.yml +1 -1
- data/README.md +24 -14
- data/bin/t +34 -1
- data/lib/t/cli.rb +203 -121
- data/lib/t/core_ext/string.rb +7 -0
- data/lib/t/delete.rb +101 -0
- data/lib/t/set.rb +25 -17
- data/lib/t/version.rb +2 -2
- data/spec/cli_spec.rb +587 -0
- data/spec/delete_spec.rb +251 -0
- data/spec/fixtures/.trc +4 -4
- data/spec/fixtures/access_token +1 -0
- data/spec/fixtures/checkip.html +1 -0
- data/spec/fixtures/direct_message.json +1 -0
- data/spec/fixtures/direct_messages.json +1 -0
- data/spec/fixtures/favorites.json +1 -0
- data/spec/fixtures/recommendations.json +1 -0
- data/spec/fixtures/request_token +1 -0
- data/spec/fixtures/retweet.json +1 -0
- data/spec/fixtures/settings.json +1 -0
- data/spec/fixtures/sferik.json +1 -0
- data/spec/fixtures/status.json +1 -0
- data/spec/fixtures/statuses.json +1 -0
- data/spec/fixtures/xml.gp +17 -0
- data/spec/helper.rb +42 -2
- data/spec/rcfile_spec.rb +17 -16
- data/spec/set_spec.rb +125 -0
- data/t.gemspec +5 -3
- metadata +95 -36
data/lib/t/delete.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 't/rcfile'
|
2
|
+
require 'thor'
|
3
|
+
require 'twitter'
|
4
|
+
|
5
|
+
module T
|
6
|
+
class Delete < Thor
|
7
|
+
DEFAULT_HOST = 'api.twitter.com'
|
8
|
+
DEFAULT_PROTOCOL = 'https'
|
9
|
+
|
10
|
+
check_unknown_options!
|
11
|
+
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@rcfile = RCFile.instance
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "block USERNAME", "Unblock a user."
|
18
|
+
def block(username)
|
19
|
+
username = username.strip_at
|
20
|
+
user = client.unblock(username)
|
21
|
+
say "@#{@rcfile.default_profile[0]} unblocked @#{user.screen_name}"
|
22
|
+
say
|
23
|
+
say "Run `#{$0} block #{user.screen_name}` to block."
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "dm", "Delete the last Direct Message sent."
|
27
|
+
def dm
|
28
|
+
direct_message = client.direct_messages_sent(:count => 1).first
|
29
|
+
if direct_message
|
30
|
+
unless parent_options['force']
|
31
|
+
exit unless yes?("Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: #{direct_message.text}?")
|
32
|
+
end
|
33
|
+
direct_message = client.direct_message_destroy(direct_message.id)
|
34
|
+
say "@#{direct_message.sender.screen_name} deleted the direct message sent to @#{direct_message.recipient.screen_name}: #{direct_message.text}"
|
35
|
+
else
|
36
|
+
raise Thor::Error, "Direct Message not found"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
map %w(m) => :dm
|
40
|
+
|
41
|
+
desc "favorite", "Deletes the last favorite."
|
42
|
+
def favorite
|
43
|
+
status = client.favorites(:count => 1).first
|
44
|
+
if status
|
45
|
+
unless parent_options['force']
|
46
|
+
exit unless yes?("Are you sure you want to delete the favorite of @#{status.user.screen_name}: #{status.text}?")
|
47
|
+
end
|
48
|
+
client.unfavorite(status.id)
|
49
|
+
say "@#{@rcfile.default_profile[0]} unfavorited @#{status.user.screen_name}'s latest status: #{status.text}"
|
50
|
+
say
|
51
|
+
say "Run `#{$0} favorite #{status.user.screen_name}` to favorite."
|
52
|
+
else
|
53
|
+
raise Thor::Error, "Tweet not found"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
map %w(fave) => :favorite
|
57
|
+
|
58
|
+
desc "status", "Delete a Tweet."
|
59
|
+
def status
|
60
|
+
user = client.user
|
61
|
+
if user.status
|
62
|
+
unless parent_options['force']
|
63
|
+
exit unless yes?("Are you sure you want to permanently delete the status: #{user.status.text}?")
|
64
|
+
end
|
65
|
+
status = client.status_destroy(user.status.id)
|
66
|
+
say "@#{@rcfile.default_profile[0]} deleted the status: #{status.text}"
|
67
|
+
else
|
68
|
+
raise Thor::Error, "Tweet not found"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
map %w(post tweet update) => :status
|
72
|
+
|
73
|
+
no_tasks do
|
74
|
+
|
75
|
+
def base_url
|
76
|
+
"#{protocol}://#{host}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def client
|
80
|
+
return @client if @client
|
81
|
+
@rcfile.path = parent_options['profile'] if parent_options['profile']
|
82
|
+
@client = Twitter::Client.new(
|
83
|
+
:endpoint => base_url,
|
84
|
+
:consumer_key => @rcfile.default_consumer_key,
|
85
|
+
:consumer_secret => @rcfile.default_consumer_secret,
|
86
|
+
:oauth_token => @rcfile.default_token,
|
87
|
+
:oauth_token_secret => @rcfile.default_secret
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
def host
|
92
|
+
parent_options['host'] || DEFAULT_HOST
|
93
|
+
end
|
94
|
+
|
95
|
+
def protocol
|
96
|
+
parent_options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/t/set.rb
CHANGED
@@ -7,42 +7,49 @@ module T
|
|
7
7
|
DEFAULT_HOST = 'api.twitter.com'
|
8
8
|
DEFAULT_PROTOCOL = 'https'
|
9
9
|
|
10
|
+
check_unknown_options!
|
11
|
+
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@rcfile = RCFile.instance
|
15
|
+
end
|
16
|
+
|
10
17
|
desc "bio DESCRIPTION", "Edits your Bio information on your Twitter profile."
|
11
18
|
def bio(description)
|
12
19
|
client.update_profile(:description => description)
|
13
|
-
say "
|
20
|
+
say "@#{@rcfile.default_profile[0]}'s bio has been updated."
|
14
21
|
end
|
15
22
|
|
16
|
-
desc "default USERNAME
|
23
|
+
desc "default USERNAME [CONSUMER_KEY]", "Set your default account."
|
17
24
|
def default(username, consumer_key=nil)
|
18
|
-
rcfile =
|
25
|
+
@rcfile.path = parent_options['profile'] if parent_options['profile']
|
19
26
|
consumer_key = rcfile[username].keys.last if consumer_key.nil?
|
20
|
-
rcfile.default_profile = {'username' => username, 'consumer_key' => consumer_key}
|
21
|
-
say "Default account has been
|
27
|
+
@rcfile.default_profile = {'username' => username, 'consumer_key' => consumer_key}
|
28
|
+
say "Default account has been updated."
|
22
29
|
end
|
23
30
|
|
24
31
|
desc "language LANGUAGE_NAME", "Selects the language you'd like to receive notifications in."
|
25
32
|
def language(language_name)
|
26
|
-
client.settings(:
|
27
|
-
say "
|
33
|
+
client.settings(:lang => language_name)
|
34
|
+
say "@#{@rcfile.default_profile[0]}'s language has been updated."
|
28
35
|
end
|
29
36
|
|
30
37
|
desc "location PLACE_NAME", "Updates the location field in your profile."
|
31
38
|
def location(place_name)
|
32
39
|
client.update_profile(:location => place_name)
|
33
|
-
say "
|
40
|
+
say "@#{@rcfile.default_profile[0]}'s location has been updated."
|
34
41
|
end
|
35
42
|
|
36
43
|
desc "name NAME", "Sets the name field on your Twitter profile."
|
37
44
|
def name(name)
|
38
45
|
client.update_profile(:name => name)
|
39
|
-
say "
|
46
|
+
say "@#{@rcfile.default_profile[0]}'s name has been updated."
|
40
47
|
end
|
41
48
|
|
42
49
|
desc "url URL", "Sets the URL field on your profile."
|
43
50
|
def url(url)
|
44
51
|
client.update_profile(:url => url)
|
45
|
-
say "URL has been
|
52
|
+
say "@#{@rcfile.default_profile[0]}'s URL has been updated."
|
46
53
|
end
|
47
54
|
|
48
55
|
no_tasks do
|
@@ -52,13 +59,14 @@ module T
|
|
52
59
|
end
|
53
60
|
|
54
61
|
def client
|
55
|
-
|
56
|
-
|
62
|
+
return @client if @client
|
63
|
+
@rcfile.path = parent_options['profile'] if parent_options['profile']
|
64
|
+
@client = Twitter::Client.new(
|
57
65
|
:endpoint => base_url,
|
58
|
-
:consumer_key => rcfile.default_consumer_key,
|
59
|
-
:consumer_secret => rcfile.default_consumer_secret,
|
60
|
-
:oauth_token => rcfile.default_token,
|
61
|
-
:oauth_token_secret => rcfile.default_secret
|
66
|
+
:consumer_key => @rcfile.default_consumer_key,
|
67
|
+
:consumer_secret => @rcfile.default_consumer_secret,
|
68
|
+
:oauth_token => @rcfile.default_token,
|
69
|
+
:oauth_token_secret => @rcfile.default_secret
|
62
70
|
)
|
63
71
|
end
|
64
72
|
|
@@ -67,7 +75,7 @@ module T
|
|
67
75
|
end
|
68
76
|
|
69
77
|
def protocol
|
70
|
-
parent_options['
|
78
|
+
parent_options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
|
71
79
|
end
|
72
80
|
|
73
81
|
end
|
data/lib/t/version.rb
CHANGED
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,587 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
describe T::CLI do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@t = T::CLI.new
|
8
|
+
Timecop.freeze(Time.local(2011, 11, 24, 16, 20, 0))
|
9
|
+
@old_stderr = $stderr
|
10
|
+
$stderr = StringIO.new
|
11
|
+
@old_stdout = $stdout
|
12
|
+
$stdout = StringIO.new
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
$stderr = @old_stderr
|
17
|
+
$stdout = @old_stdout
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#account" do
|
21
|
+
before do
|
22
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
23
|
+
end
|
24
|
+
it "should have the correct output" do
|
25
|
+
@t.accounts
|
26
|
+
$stdout.string.should == <<-eos.gsub(/^ {8}/, '')
|
27
|
+
testcli
|
28
|
+
abc123 (default)
|
29
|
+
eos
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#authorize" do
|
34
|
+
before do
|
35
|
+
@t.options = @t.options.merge(:profile => File.expand_path('/tmp/trc', __FILE__), :consumer_key => "abc123", :consumer_secret => "asdfasd223sd2", :prompt => true, :dry_run => true)
|
36
|
+
stub_post("/oauth/request_token").
|
37
|
+
to_return(:body => fixture("request_token"))
|
38
|
+
stub_post("/oauth/access_token").
|
39
|
+
to_return(:body => fixture("access_token"))
|
40
|
+
stub_get("/1/account/verify_credentials.json").
|
41
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
42
|
+
end
|
43
|
+
it "should request the correct resource" do
|
44
|
+
$stdout.should_receive(:print).with("Press [Enter] to open the Twitter app authorization page. ")
|
45
|
+
$stdin.should_receive(:gets).and_return("\n")
|
46
|
+
$stdout.should_receive(:print).with("Paste in the supplied PIN: ")
|
47
|
+
$stdin.should_receive(:gets).and_return("1234567890")
|
48
|
+
@t.authorize
|
49
|
+
a_post("/oauth/request_token").
|
50
|
+
should have_been_made
|
51
|
+
a_post("/oauth/access_token").
|
52
|
+
should have_been_made
|
53
|
+
a_get("/1/account/verify_credentials.json").
|
54
|
+
should have_been_made
|
55
|
+
end
|
56
|
+
it "should not raise error" do
|
57
|
+
lambda do
|
58
|
+
$stdout.should_receive(:print).with("Press [Enter] to open the Twitter app authorization page. ")
|
59
|
+
$stdin.should_receive(:gets).and_return("\n")
|
60
|
+
$stdout.should_receive(:print).with("Paste in the supplied PIN: ")
|
61
|
+
$stdin.should_receive(:gets).and_return("1234567890")
|
62
|
+
@t.authorize
|
63
|
+
end.should_not raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#block" do
|
68
|
+
before do
|
69
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
70
|
+
stub_post("/1/blocks/create.json").
|
71
|
+
with(:body => {:screen_name => "sferik"}).
|
72
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
73
|
+
end
|
74
|
+
it "should request the correct resource" do
|
75
|
+
@t.block("sferik")
|
76
|
+
a_post("/1/blocks/create.json").
|
77
|
+
with(:body => {:screen_name => "sferik"}).
|
78
|
+
should have_been_made
|
79
|
+
end
|
80
|
+
it "should have the correct output" do
|
81
|
+
@t.block("sferik")
|
82
|
+
$stdout.string.should =~ /^@testcli blocked @sferik/
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#direct_messages" do
|
87
|
+
before do
|
88
|
+
stub_get("/1/direct_messages.json").
|
89
|
+
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
90
|
+
end
|
91
|
+
it "should request the correct resource" do
|
92
|
+
@t.direct_messages
|
93
|
+
a_get("/1/direct_messages.json").
|
94
|
+
should have_been_made
|
95
|
+
end
|
96
|
+
it "should have the correct output" do
|
97
|
+
@t.direct_messages
|
98
|
+
$stdout.string.should == <<-eos.gsub(/^/, ' ' * 6)
|
99
|
+
sferik: Sounds good. Meeting Tuesday is fine. (about 1 year ago)
|
100
|
+
sferik: if you want to add me to your GroupMe group, my phone number is 415-312-2382 (about 1 year ago)
|
101
|
+
sferik: That's great news! Let's plan to chat around 8 AM tomorrow Pacific time. Does that work for you? (about 1 year ago)
|
102
|
+
sferik: I asked Yehuda about the stipend. I believe it has already been sent. Glad you're feeling better. (about 1 year ago)
|
103
|
+
sferik: Just checking in. How's everything going? (about 1 year ago)
|
104
|
+
sferik: 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)
|
105
|
+
sferik: 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)
|
106
|
+
sferik: 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)
|
107
|
+
sferik: How are the graph enhancements coming? (about 1 year ago)
|
108
|
+
sferik: Changes pushed. You should pull and re-bundle when you have a minute. (about 1 year ago)
|
109
|
+
sferik: Glad to hear the new graphs are coming along. Can't wait to see them! (about 1 year ago)
|
110
|
+
sferik: 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)
|
111
|
+
sferik: After the upgrade 54/80 specs are failing. I'm working on fixing them now. (about 1 year ago)
|
112
|
+
sferik: 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)
|
113
|
+
sferik: How are the graphs coming? I'm really looking forward to seeing what you do with Raphaël. (about 1 year ago)
|
114
|
+
sferik: Awesome! Any luck duplicating the Gemfile.lock error with Ruby 1.9.2 final? (about 1 year ago)
|
115
|
+
sferik: 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)
|
116
|
+
sferik: 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)
|
117
|
+
sferik: 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)
|
118
|
+
sferik: 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)
|
119
|
+
eos
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#dm" do
|
124
|
+
before do
|
125
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
126
|
+
stub_post("/1/direct_messages/new.json").
|
127
|
+
with(:body => {:screen_name => "pengwynn", :text => "Creating a fixture for the Twitter gem"}).
|
128
|
+
to_return(:body => fixture("direct_message.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
129
|
+
end
|
130
|
+
it "should request the correct resource" do
|
131
|
+
@t.dm("pengwynn", "Creating a fixture for the Twitter gem")
|
132
|
+
a_post("/1/direct_messages/new.json").
|
133
|
+
with(:body => {:screen_name => "pengwynn", :text => "Creating a fixture for the Twitter gem"}).
|
134
|
+
should have_been_made
|
135
|
+
end
|
136
|
+
it "should have the correct output" do
|
137
|
+
@t.dm("pengwynn", "Creating a fixture for the Twitter gem")
|
138
|
+
$stdout.string.chomp.should == "Direct Message sent from @testcli to @pengwynn (about 1 year ago)"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#favorite" do
|
143
|
+
before do
|
144
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
145
|
+
end
|
146
|
+
context "not found" do
|
147
|
+
before do
|
148
|
+
stub_get("/1/users/show.json").
|
149
|
+
with(:query => {:screen_name => "sferik"}).
|
150
|
+
to_return(:body => '{}', :headers => {:content_type => "application/json; charset=utf-8"})
|
151
|
+
end
|
152
|
+
it "should exit" do
|
153
|
+
lambda do
|
154
|
+
@t.favorite("sferik")
|
155
|
+
end.should raise_error(Thor::Error, "Tweet not found")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
context "forbidden" do
|
159
|
+
before do
|
160
|
+
stub_get("/1/users/show.json").
|
161
|
+
with(:query => {:screen_name => "sferik"}).
|
162
|
+
to_return(:body => '{"error":"Forbidden"}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
163
|
+
end
|
164
|
+
it "should exit" do
|
165
|
+
lambda do
|
166
|
+
@t.favorite("sferik")
|
167
|
+
end.should raise_error(Twitter::Error::Forbidden, "Forbidden")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
context "duplicate" do
|
171
|
+
before do
|
172
|
+
stub_get("/1/users/show.json").
|
173
|
+
with(:query => {:screen_name => "sferik"}).
|
174
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
175
|
+
stub_post("/1/favorites/create/26755176471724032.json").
|
176
|
+
to_return(:body => '{"error":"You have already favorited this status."}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
177
|
+
end
|
178
|
+
it "should have the correct output" do
|
179
|
+
@t.favorite("sferik")
|
180
|
+
$stdout.string.should =~ /^@testcli favorited @sferik's latest status: RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3$/
|
181
|
+
end
|
182
|
+
end
|
183
|
+
context "found" do
|
184
|
+
before do
|
185
|
+
stub_get("/1/users/show.json").
|
186
|
+
with(:query => {:screen_name => "sferik"}).
|
187
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
188
|
+
stub_post("/1/favorites/create/26755176471724032.json").
|
189
|
+
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
190
|
+
end
|
191
|
+
it "should request the correct resource" do
|
192
|
+
@t.favorite("sferik")
|
193
|
+
a_get("/1/users/show.json").
|
194
|
+
with(:query => {:screen_name => "sferik"}).
|
195
|
+
should have_been_made
|
196
|
+
a_post("/1/favorites/create/26755176471724032.json").
|
197
|
+
should have_been_made
|
198
|
+
end
|
199
|
+
it "should have the correct output" do
|
200
|
+
@t.favorite("sferik")
|
201
|
+
$stdout.string.should =~ /^@testcli favorited @sferik's latest status: RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3$/
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "#follow" do
|
207
|
+
before do
|
208
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
209
|
+
stub_post("/1/friendships/create.json").
|
210
|
+
with(:body => {:screen_name => "sferik"}).
|
211
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
212
|
+
end
|
213
|
+
it "should request the correct resource" do
|
214
|
+
@t.follow("sferik")
|
215
|
+
a_post("/1/friendships/create.json").
|
216
|
+
with(:body => {:screen_name => "sferik"}).
|
217
|
+
should have_been_made
|
218
|
+
end
|
219
|
+
it "should have the correct output" do
|
220
|
+
@t.follow("sferik")
|
221
|
+
$stdout.string.should =~ /^@testcli is now following @sferik\.$/
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe "#get" do
|
226
|
+
context "not found" do
|
227
|
+
before do
|
228
|
+
stub_get("/1/users/show.json").
|
229
|
+
with(:query => {:screen_name => "sferik"}).
|
230
|
+
to_return(:body => '{}', :headers => {:content_type => "application/json; charset=utf-8"})
|
231
|
+
end
|
232
|
+
it "should exit" do
|
233
|
+
lambda do
|
234
|
+
@t.get("sferik")
|
235
|
+
end.should raise_error(Thor::Error, "Tweet not found")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
context "found" do
|
239
|
+
before do
|
240
|
+
stub_get("/1/users/show.json").
|
241
|
+
with(:query => {:screen_name => "sferik"}).
|
242
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
243
|
+
end
|
244
|
+
it "should request the correct resource" do
|
245
|
+
@t.get("sferik")
|
246
|
+
a_get("/1/users/show.json").
|
247
|
+
with(:query => {:screen_name => "sferik"}).
|
248
|
+
should have_been_made
|
249
|
+
end
|
250
|
+
it "should have the correct output" do
|
251
|
+
@t.get("sferik")
|
252
|
+
$stdout.string.chomp.should == "RT @tenderlove: [ANN] sqlite3-ruby => sqlite3 (10 months ago)"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe "#mentions" do
|
258
|
+
before do
|
259
|
+
stub_get("/1/statuses/mentions.json").
|
260
|
+
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
261
|
+
end
|
262
|
+
it "should request the correct resource" do
|
263
|
+
@t.mentions
|
264
|
+
a_get("/1/statuses/mentions.json").
|
265
|
+
should have_been_made
|
266
|
+
end
|
267
|
+
it "should have the correct output" do
|
268
|
+
@t.mentions
|
269
|
+
$stdout.string.should == <<-eos.gsub(/^/, ' ' * 6)
|
270
|
+
sferik: Ruby is the best programming language for hiding the ugly bits. (about 1 year ago)
|
271
|
+
sferik: There are 1.3 billion people in China; when people say there are 1 billion they are rounding off the entire population of the United States. (about 1 year ago)
|
272
|
+
sferik: The new Windows Phone campaign is the best advertising from Microsoft since "Start Me Up" (1995). Great work by CP+B. http://t.co/tIzxopI (about 1 year ago)
|
273
|
+
sferik: Fear not to sow seeds because of the birds. http://twitpic.com/2wg621 (about 1 year ago)
|
274
|
+
sferik: Speaking of things that are maddening: the interview with the Wall Street guys on the most recent This American Life http://bit.ly/af9pSD (about 1 year ago)
|
275
|
+
sferik: Holy cow! RailsAdmin is up to 200 watchers (from 100 yesterday). http://github.com/sferik/rails_admin (about 1 year ago)
|
276
|
+
sferik: Kind of cool that Facebook acts as a mirror for open-source projects that they use or like http://mirror.facebook.net/ (about 1 year ago)
|
277
|
+
sferik: RailsAdmin already has 100 watchers, 12 forks, and 6 contributors in less than 2 months. Let's keep the momentum going! http://bit.ly/cCMMqD (about 1 year ago)
|
278
|
+
sferik: This week's This American Life is amazing. @JoeLipari is an American hero. http://bit.ly/d9RbnB (about 1 year ago)
|
279
|
+
sferik: RT @polyseme: OH: shofars should be called jewvuzelas. (about 1 year ago)
|
280
|
+
sferik: Spent this morning fixing broken windows in RailsAdmin http://github.com/sferik/rails_admin/compare/ab6c598...0e3770f (about 1 year ago)
|
281
|
+
sferik: I'm a big believer that the broken windows theory applies to software development http://en.wikipedia.org/wiki/Broken_windows_theory (about 1 year ago)
|
282
|
+
sferik: I hope you idiots are happy with your piece of shit Android phones. http://www.apple.com/pr/library/2010/09/09statement.html (about 1 year ago)
|
283
|
+
sferik: Ping: kills MySpace dead. (about 1 year ago)
|
284
|
+
sferik: Crazy that iTunes Ping didn't leak a drop. (about 1 year ago)
|
285
|
+
sferik: The plot thickens http://twitpic.com/2k5lt2 (about 1 year ago)
|
286
|
+
sferik: 140 Proof Provides A Piece Of The Twitter Advertising Puzzle http://t.co/R2cUSDe via @techcrunch (about 1 year ago)
|
287
|
+
sferik: Try as you may http://www.thedoghousediaries.com/?p=1940 (about 1 year ago)
|
288
|
+
sferik: I know @SarahPalinUSA has a right to use Twitter, but should she? (over 1 year ago)
|
289
|
+
eos
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "#open" do
|
294
|
+
before do
|
295
|
+
@t.options = @t.options.merge(:dry_run => true)
|
296
|
+
end
|
297
|
+
it "should not raise error" do
|
298
|
+
lambda do
|
299
|
+
@t.open("sferik")
|
300
|
+
end.should_not raise_error
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe "#reply" do
|
305
|
+
before do
|
306
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__), :location => true)
|
307
|
+
stub_get("/1/users/show.json").
|
308
|
+
with(:query => {:screen_name => "sferik"}).
|
309
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
310
|
+
stub_post("/1/statuses/update.json").
|
311
|
+
with(:body => {:in_reply_to_status_id => "26755176471724032", :status => "@sferik Testing", :lat => "37.76969909668", :long => "-122.39330291748"}).
|
312
|
+
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
313
|
+
stub_request(:get, "http://checkip.dyndns.org/").
|
314
|
+
to_return(:body => fixture("checkip.html"), :headers => {:content_type => "text/html"})
|
315
|
+
stub_request(:get, "http://www.geoplugin.net/xml.gp?ip=50.131.22.169").
|
316
|
+
to_return(:body => fixture("xml.gp"), :headers => {:content_type => "application/xml"})
|
317
|
+
end
|
318
|
+
it "should request the correct resource" do
|
319
|
+
@t.reply("sferik", "Testing")
|
320
|
+
a_get("/1/users/show.json").
|
321
|
+
with(:query => {:screen_name => "sferik"}).
|
322
|
+
should have_been_made
|
323
|
+
a_post("/1/statuses/update.json").
|
324
|
+
with(:body => {:in_reply_to_status_id => "26755176471724032", :status => "@sferik Testing", :lat => "37.76969909668", :long => "-122.39330291748"}).
|
325
|
+
should have_been_made
|
326
|
+
a_request(:get, "http://checkip.dyndns.org/").
|
327
|
+
should have_been_made
|
328
|
+
a_request(:get, "http://www.geoplugin.net/xml.gp?ip=50.131.22.169").
|
329
|
+
should have_been_made
|
330
|
+
end
|
331
|
+
it "should have the correct output" do
|
332
|
+
@t.reply("sferik", "Testing")
|
333
|
+
$stdout.string.should =~ /^Reply created by @testcli to @sferik \(about 1 year ago\)$/
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe "#retweet" do
|
338
|
+
before do
|
339
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
340
|
+
end
|
341
|
+
context "not found" do
|
342
|
+
before do
|
343
|
+
stub_get("/1/users/show.json").
|
344
|
+
with(:query => {:screen_name => "sferik"}).
|
345
|
+
to_return(:body => '{}', :headers => {:content_type => "application/json; charset=utf-8"})
|
346
|
+
end
|
347
|
+
it "should exit" do
|
348
|
+
lambda do
|
349
|
+
@t.retweet("sferik")
|
350
|
+
end.should raise_error(Thor::Error, "Tweet not found")
|
351
|
+
end
|
352
|
+
end
|
353
|
+
context "forbidden" do
|
354
|
+
before do
|
355
|
+
stub_get("/1/users/show.json").
|
356
|
+
with(:query => {:screen_name => "sferik"}).
|
357
|
+
to_return(:body => '{"error":"Forbidden"}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
358
|
+
end
|
359
|
+
it "should exit" do
|
360
|
+
lambda do
|
361
|
+
@t.retweet("sferik")
|
362
|
+
end.should raise_error(Twitter::Error::Forbidden, "Forbidden")
|
363
|
+
end
|
364
|
+
end
|
365
|
+
context "duplicate" do
|
366
|
+
before do
|
367
|
+
stub_get("/1/users/show.json").
|
368
|
+
with(:query => {:screen_name => "sferik"}).
|
369
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
370
|
+
stub_post("/1/statuses/retweet/26755176471724032.json").
|
371
|
+
to_return(:body => '{"error":"sharing is not permissable for this status (Share validations failed)"}', :headers => {:content_type => "application/json; charset=utf-8"}, :status => 403)
|
372
|
+
end
|
373
|
+
it "should have the correct output" do
|
374
|
+
@t.retweet("sferik")
|
375
|
+
$stdout.string.should =~ /^@testcli retweeted @sferik's latest status: RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3$/
|
376
|
+
end
|
377
|
+
end
|
378
|
+
context "found" do
|
379
|
+
before do
|
380
|
+
stub_get("/1/users/show.json").
|
381
|
+
with(:query => {:screen_name => "sferik"}).
|
382
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
383
|
+
stub_post("/1/statuses/retweet/26755176471724032.json").
|
384
|
+
to_return(:body => fixture("retweet.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
385
|
+
end
|
386
|
+
it "should request the correct resource" do
|
387
|
+
@t.retweet("sferik")
|
388
|
+
a_get("/1/users/show.json").
|
389
|
+
with(:query => {:screen_name => "sferik"}).
|
390
|
+
should have_been_made
|
391
|
+
a_post("/1/statuses/retweet/26755176471724032.json").
|
392
|
+
should have_been_made
|
393
|
+
end
|
394
|
+
it "should have the correct output" do
|
395
|
+
@t.retweet("sferik")
|
396
|
+
$stdout.string.should =~ /^@testcli retweeted @sferik's latest status: RT @tenderlove: \[ANN\] sqlite3-ruby => sqlite3$/
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
describe "#sent_messages" do
|
402
|
+
before do
|
403
|
+
stub_get("/1/direct_messages/sent.json").
|
404
|
+
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
405
|
+
end
|
406
|
+
it "should request the correct resource" do
|
407
|
+
@t.sent_messages
|
408
|
+
a_get("/1/direct_messages/sent.json").
|
409
|
+
should have_been_made
|
410
|
+
end
|
411
|
+
it "should have the correct output" do
|
412
|
+
@t.sent_messages
|
413
|
+
$stdout.string.should == <<-eos.gsub(/^/, ' ' * 3)
|
414
|
+
hurrycane: Sounds good. Meeting Tuesday is fine. (about 1 year ago)
|
415
|
+
technoweenie: if you want to add me to your GroupMe group, my phone number is 415-312-2382 (about 1 year ago)
|
416
|
+
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)
|
417
|
+
hurrycane: I asked Yehuda about the stipend. I believe it has already been sent. Glad you're feeling better. (about 1 year ago)
|
418
|
+
hurrycane: Just checking in. How's everything going? (about 1 year ago)
|
419
|
+
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)
|
420
|
+
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)
|
421
|
+
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)
|
422
|
+
hurrycane: How are the graph enhancements coming? (about 1 year ago)
|
423
|
+
hurrycane: Changes pushed. You should pull and re-bundle when you have a minute. (about 1 year ago)
|
424
|
+
hurrycane: Glad to hear the new graphs are coming along. Can't wait to see them! (about 1 year ago)
|
425
|
+
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)
|
426
|
+
hurrycane: After the upgrade 54/80 specs are failing. I'm working on fixing them now. (about 1 year ago)
|
427
|
+
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)
|
428
|
+
hurrycane: How are the graphs coming? I'm really looking forward to seeing what you do with Raphaël. (about 1 year ago)
|
429
|
+
hurrycane: Awesome! Any luck duplicating the Gemfile.lock error with Ruby 1.9.2 final? (about 1 year ago)
|
430
|
+
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)
|
431
|
+
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)
|
432
|
+
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)
|
433
|
+
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)
|
434
|
+
eos
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
describe "#stats" do
|
439
|
+
before do
|
440
|
+
stub_get("/1/users/show.json").
|
441
|
+
with(:query => {:screen_name => "sferik"}).
|
442
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
443
|
+
end
|
444
|
+
it "should request the correct resource" do
|
445
|
+
@t.stats("sferik")
|
446
|
+
a_get("/1/users/show.json").
|
447
|
+
with(:query => {:screen_name => "sferik"}).
|
448
|
+
should have_been_made
|
449
|
+
end
|
450
|
+
it "should have the correct output" do
|
451
|
+
@t.stats("sferik")
|
452
|
+
$stdout.string.should =~ /^Followers: 1,048$/
|
453
|
+
$stdout.string.should =~ /^Following: 197$/
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
describe "#status" do
|
458
|
+
before do
|
459
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__), :location => true)
|
460
|
+
stub_post("/1/statuses/update.json").
|
461
|
+
with(:body => {:status => "Testing", :lat => "37.76969909668", :long => "-122.39330291748"}).
|
462
|
+
to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
463
|
+
stub_request(:get, "http://checkip.dyndns.org/").
|
464
|
+
to_return(:body => fixture("checkip.html"), :headers => {:content_type => "text/html"})
|
465
|
+
stub_request(:get, "http://www.geoplugin.net/xml.gp?ip=50.131.22.169").
|
466
|
+
to_return(:body => fixture("xml.gp"), :headers => {:content_type => "application/xml"})
|
467
|
+
end
|
468
|
+
it "should request the correct resource" do
|
469
|
+
@t.status("Testing")
|
470
|
+
a_post("/1/statuses/update.json").
|
471
|
+
with(:body => {:status => "Testing", :lat => "37.76969909668", :long => "-122.39330291748"}).
|
472
|
+
should have_been_made
|
473
|
+
a_request(:get, "http://checkip.dyndns.org/").
|
474
|
+
should have_been_made
|
475
|
+
a_request(:get, "http://www.geoplugin.net/xml.gp?ip=50.131.22.169").
|
476
|
+
should have_been_made
|
477
|
+
end
|
478
|
+
it "should have the correct output" do
|
479
|
+
@t.status("Testing")
|
480
|
+
$stdout.string.should =~ /^Tweet created by @testcli \(about 1 year ago\)$/
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
describe "#suggest" do
|
485
|
+
before do
|
486
|
+
stub_get("/1/users/recommendations.json").
|
487
|
+
with(:query => {:limit => "1"}).
|
488
|
+
to_return(:body => fixture("recommendations.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
489
|
+
end
|
490
|
+
it "should request the correct resource" do
|
491
|
+
@t.suggest
|
492
|
+
a_get("/1/users/recommendations.json").
|
493
|
+
with(:query => {:limit => "1"}).
|
494
|
+
should have_been_made
|
495
|
+
end
|
496
|
+
it "should have the correct output" do
|
497
|
+
@t.suggest
|
498
|
+
$stdout.string.should =~ /^Try following @jtrupiano\.$/
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
describe "#timeline" do
|
503
|
+
before do
|
504
|
+
stub_get("/1/statuses/home_timeline.json").
|
505
|
+
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
506
|
+
end
|
507
|
+
it "should request the correct resource" do
|
508
|
+
@t.timeline
|
509
|
+
a_get("/1/statuses/home_timeline.json").
|
510
|
+
should have_been_made
|
511
|
+
end
|
512
|
+
it "should have the correct output" do
|
513
|
+
@t.timeline
|
514
|
+
$stdout.string.should == <<-eos.gsub(/^/, ' ' * 6)
|
515
|
+
sferik: Ruby is the best programming language for hiding the ugly bits. (about 1 year ago)
|
516
|
+
sferik: There are 1.3 billion people in China; when people say there are 1 billion they are rounding off the entire population of the United States. (about 1 year ago)
|
517
|
+
sferik: The new Windows Phone campaign is the best advertising from Microsoft since "Start Me Up" (1995). Great work by CP+B. http://t.co/tIzxopI (about 1 year ago)
|
518
|
+
sferik: Fear not to sow seeds because of the birds. http://twitpic.com/2wg621 (about 1 year ago)
|
519
|
+
sferik: Speaking of things that are maddening: the interview with the Wall Street guys on the most recent This American Life http://bit.ly/af9pSD (about 1 year ago)
|
520
|
+
sferik: Holy cow! RailsAdmin is up to 200 watchers (from 100 yesterday). http://github.com/sferik/rails_admin (about 1 year ago)
|
521
|
+
sferik: Kind of cool that Facebook acts as a mirror for open-source projects that they use or like http://mirror.facebook.net/ (about 1 year ago)
|
522
|
+
sferik: RailsAdmin already has 100 watchers, 12 forks, and 6 contributors in less than 2 months. Let's keep the momentum going! http://bit.ly/cCMMqD (about 1 year ago)
|
523
|
+
sferik: This week's This American Life is amazing. @JoeLipari is an American hero. http://bit.ly/d9RbnB (about 1 year ago)
|
524
|
+
sferik: RT @polyseme: OH: shofars should be called jewvuzelas. (about 1 year ago)
|
525
|
+
sferik: Spent this morning fixing broken windows in RailsAdmin http://github.com/sferik/rails_admin/compare/ab6c598...0e3770f (about 1 year ago)
|
526
|
+
sferik: I'm a big believer that the broken windows theory applies to software development http://en.wikipedia.org/wiki/Broken_windows_theory (about 1 year ago)
|
527
|
+
sferik: I hope you idiots are happy with your piece of shit Android phones. http://www.apple.com/pr/library/2010/09/09statement.html (about 1 year ago)
|
528
|
+
sferik: Ping: kills MySpace dead. (about 1 year ago)
|
529
|
+
sferik: Crazy that iTunes Ping didn't leak a drop. (about 1 year ago)
|
530
|
+
sferik: The plot thickens http://twitpic.com/2k5lt2 (about 1 year ago)
|
531
|
+
sferik: 140 Proof Provides A Piece Of The Twitter Advertising Puzzle http://t.co/R2cUSDe via @techcrunch (about 1 year ago)
|
532
|
+
sferik: Try as you may http://www.thedoghousediaries.com/?p=1940 (about 1 year ago)
|
533
|
+
sferik: I know @SarahPalinUSA has a right to use Twitter, but should she? (over 1 year ago)
|
534
|
+
eos
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
describe "#unfollow" do
|
539
|
+
before do
|
540
|
+
@t.options = @t.options.merge(:profile => File.expand_path('../fixtures/.trc', __FILE__))
|
541
|
+
stub_delete("/1/friendships/destroy.json").
|
542
|
+
with(:query => {:screen_name => "sferik"}).
|
543
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
544
|
+
end
|
545
|
+
it "should request the correct resource" do
|
546
|
+
@t.unfollow("sferik")
|
547
|
+
a_delete("/1/friendships/destroy.json").
|
548
|
+
with(:query => {:screen_name => "sferik"}).
|
549
|
+
should have_been_made
|
550
|
+
end
|
551
|
+
it "should have the correct output" do
|
552
|
+
@t.unfollow("sferik")
|
553
|
+
$stdout.string.should =~ /^@testcli is no longer following @sferik\.$/
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
describe "#version" do
|
558
|
+
it "should have the correct output" do
|
559
|
+
@t.version
|
560
|
+
$stdout.string.chomp.should == T::Version.to_s
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
describe "#whois" do
|
565
|
+
before do
|
566
|
+
stub_get("/1/users/show.json").
|
567
|
+
with(:query => {:screen_name => "sferik"}).
|
568
|
+
to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
569
|
+
end
|
570
|
+
it "should request the correct resource" do
|
571
|
+
@t.whois("sferik")
|
572
|
+
a_get("/1/users/show.json").
|
573
|
+
with(:query => {:screen_name => "sferik"}).
|
574
|
+
should have_been_made
|
575
|
+
end
|
576
|
+
it "should have the correct output" do
|
577
|
+
@t.whois("sferik")
|
578
|
+
$stdout.string.should == <<-eos.gsub(/^ {8}/, '')
|
579
|
+
Erik Michaels-Ober, since Jul 2007.
|
580
|
+
bio: A mind forever voyaging through strange seas of thought, alone.
|
581
|
+
location: San Francisco
|
582
|
+
web: https://github.com/sferik
|
583
|
+
eos
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
end
|