tweetwine 0.2.5 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +30 -17
- data/README.rdoc +16 -17
- data/Rakefile +2 -0
- data/bin/tweetwine +3 -68
- data/example/example_helper.rb +31 -41
- data/example/fixtures/{statuses.json → home.json} +0 -0
- data/example/fixtures/mentions.json +1 -0
- data/example/fixtures/search.json +1 -0
- data/example/fixtures/update.json +1 -0
- data/example/fixtures/user.json +1 -0
- data/example/fixtures/users.json +1 -0
- data/example/search_statuses_example.rb +36 -0
- data/example/show_followers_example.rb +23 -0
- data/example/show_friends_example.rb +23 -0
- data/example/show_home_example.rb +51 -0
- data/example/show_mentions_example.rb +23 -0
- data/example/show_metadata_example.rb +54 -7
- data/example/show_user_example.rb +37 -0
- data/example/update_status_example.rb +65 -0
- data/lib/tweetwine/cli.rb +241 -0
- data/lib/tweetwine/client.rb +94 -57
- data/lib/tweetwine/io.rb +39 -28
- data/lib/tweetwine/meta.rb +1 -1
- data/lib/tweetwine/retrying_http.rb +93 -0
- data/lib/tweetwine/startup_config.rb +14 -15
- data/lib/tweetwine/url_shortener.rb +13 -8
- data/lib/tweetwine/util.rb +14 -0
- data/lib/tweetwine.rb +2 -1
- data/test/cli_test.rb +16 -0
- data/test/client_test.rb +275 -205
- data/test/fixtures/test_config.yaml +2 -1
- data/test/io_test.rb +89 -62
- data/test/retrying_http_test.rb +127 -0
- data/test/startup_config_test.rb +52 -27
- data/test/test_helper.rb +32 -17
- data/test/url_shortener_test.rb +18 -18
- data/test/util_test.rb +145 -47
- metadata +20 -7
- data/example/show_latest_statuses_example.rb +0 -45
- data/lib/tweetwine/rest_client_wrapper.rb +0 -37
- data/test/rest_client_wrapper_test.rb +0 -68
data/CHANGELOG.rdoc
CHANGED
@@ -1,15 +1,28 @@
|
|
1
|
+
=== 0.2.7 released 2009-12-22
|
2
|
+
|
3
|
+
* Formatted help texts so that they do not exceed 80 chars in width.
|
4
|
+
|
5
|
+
=== 0.2.6 released 2009-12-22
|
6
|
+
|
7
|
+
* Command <tt>search</tt> allows searching statuses.
|
8
|
+
* Renamed option <tt>--colorize</tt> to <tt>--colors</tt>.
|
9
|
+
* Command <tt>home</tt> shows home timeline instead of friends timeline.
|
10
|
+
* Command <tt>help</tt> accepts argument for showing help about a command.
|
11
|
+
* Acceptance tests in <tt>example</tt> directory cover all commands.
|
12
|
+
* Reimplemented how application starts executing a specific command.
|
13
|
+
|
1
14
|
=== 0.2.5 released 2009-10-14
|
2
15
|
|
3
16
|
* Improved username highlighting for colorization. For example, email
|
4
17
|
addresses are not highlighted as usernames anymore.
|
5
|
-
* Command line option
|
6
|
-
output.
|
18
|
+
* Command line option <tt>--no-colorize</tt> to (temporarily) disable colors
|
19
|
+
from the output.
|
7
20
|
* Added first set of acceptance tests under "example" directory.
|
8
21
|
|
9
22
|
=== 0.2.4 released 2009-09-16
|
10
23
|
|
11
24
|
* Retry connection upon connection reset, trying maximum of three times.
|
12
|
-
* Display proper version info on Ruby 1.8 when using option
|
25
|
+
* Display proper version info on Ruby 1.8 when using option <tt>-v</tt>.
|
13
26
|
* Minor code cleanups.
|
14
27
|
* Release 0.2.3 is skipped due to my error in tagging the wrong commit.
|
15
28
|
|
@@ -25,7 +38,7 @@
|
|
25
38
|
|
26
39
|
=== 0.2.1 released 2009-08-17
|
27
40
|
|
28
|
-
* Command line option
|
41
|
+
* Command line option <tt>-v</tt> shows version information.
|
29
42
|
* Slight implementation code cleaning.
|
30
43
|
|
31
44
|
=== 0.2.0 released 2009-08-17
|
@@ -44,8 +57,8 @@
|
|
44
57
|
|
45
58
|
=== 0.1.9 released 2009-07-15
|
46
59
|
|
47
|
-
* Added commands
|
48
|
-
* Removed dependency to the
|
60
|
+
* Added commands <tt>friends</tt> and <tt>followers</tt>.
|
61
|
+
* Removed dependency to the json gem. It is included in Ruby 1.9.
|
49
62
|
|
50
63
|
=== 0.1.8 released 2009-07-01
|
51
64
|
|
@@ -67,26 +80,26 @@
|
|
67
80
|
|
68
81
|
=== 0.1.4 released 2009-05-12
|
69
82
|
|
70
|
-
* Command line option
|
83
|
+
* Command line option <tt>--page N</tt> fetches a specific status page.
|
71
84
|
|
72
85
|
=== 0.1.3 released 2009-05-05
|
73
86
|
|
74
|
-
* Empty status update indicates cancellation of the command
|
75
|
-
* Other minor improvements
|
87
|
+
* Empty status update indicates cancellation of the command.
|
88
|
+
* Other minor improvements.
|
76
89
|
|
77
90
|
=== 0.1.2 released 2009-05-04
|
78
91
|
|
79
|
-
* Renamed command
|
80
|
-
* Added command
|
81
|
-
* When showing a status, indicate if it is a reply
|
82
|
-
* Improved command line argument and configuration file parsing
|
92
|
+
* Renamed command <tt>friends</tt> to <tt>home</tt>.
|
93
|
+
* Added command <tt>mentions</tt>.
|
94
|
+
* When showing a status, indicate if it is a reply.
|
95
|
+
* Improved command line argument and configuration file parsing.
|
83
96
|
|
84
97
|
=== 0.1.1 released 2009-04-23
|
85
98
|
|
86
|
-
* Renamed command
|
87
|
-
* If status update if longer than 140 characters, warn about it
|
99
|
+
* Renamed command <tt>msg</tt> to <tt>update</tt>.
|
100
|
+
* If status update if longer than 140 characters, warn about it.
|
88
101
|
|
89
102
|
=== 0.1.0 released 2009-04-22
|
90
103
|
|
91
|
-
* Initial release with minimal functionality
|
92
|
-
* Usable for quickly checking friends' statuses and sending status updates
|
104
|
+
* Initial release with minimal functionality.
|
105
|
+
* Usable for quickly checking friends' statuses and sending status updates.
|
data/README.rdoc
CHANGED
@@ -4,18 +4,19 @@ A simple but tasty Twitter agent for command line use, made for fun.
|
|
4
4
|
|
5
5
|
== Installation
|
6
6
|
|
7
|
-
Install Tweetwine as a RubyGem from
|
7
|
+
Install Tweetwine as a RubyGem from Gemcutter[http://gemcutter.org/]:
|
8
8
|
|
9
|
-
$ sudo gem install
|
9
|
+
$ sudo gem install tweetwine --source http://gemcutter.org
|
10
10
|
|
11
|
-
The program is compatible with Ruby 1.
|
12
|
-
|
11
|
+
The program is compatible with both Ruby 1.8 and 1.9.
|
12
|
+
|
13
|
+
The program requires <b>rest_client</b> gem to be installed. In addition, the program needs <b>json</b> gem on Ruby 1.8.
|
13
14
|
|
14
15
|
== Usage
|
15
16
|
|
16
17
|
In the command line, run the program by entering
|
17
18
|
|
18
|
-
$ tweetwine [
|
19
|
+
$ tweetwine [global_options...] [command] [command_options...]
|
19
20
|
|
20
21
|
The program needs the user's username and password for authentication. This
|
21
22
|
information can be supplied either via a configuration file or as an option
|
@@ -27,22 +28,20 @@ program recognizes the following basic settings:
|
|
27
28
|
|
28
29
|
username: <your_username>
|
29
30
|
password: <your_password>
|
30
|
-
|
31
|
+
colors: true|false
|
31
32
|
|
32
|
-
|
33
|
+
The program supports showing the home timeline of the authenticated user, the
|
34
|
+
latest statuses of friends and followers, and the latest statuses that mention
|
35
|
+
the user. If that's not enough, statuses can be searched with arbitrary terms.
|
36
|
+
In addition, new statuses can be sent.
|
33
37
|
|
34
|
-
|
35
|
-
<tt>mentions</tt>:: Fetch latest mentions for the authenticated user.
|
36
|
-
<tt>user [name]</tt>:: Fetch a specific user's latest statuses, identified by the argument; if given no argument, fetch the statuses of the authenticated user.
|
37
|
-
<tt>update [status]</tt>:: Send a status update, but confirm the action first before actually sending. The status update can either be given as an argument or via STDIN if no argument is given.
|
38
|
-
<tt>friends</tt>:: Fetch friends and their latest statuses.
|
39
|
-
<tt>followers</tt>:: Fetch followers and their latest statuses.
|
38
|
+
For all the global options and commands, see:
|
40
39
|
|
41
|
-
|
40
|
+
$ tweetwine help
|
42
41
|
|
43
|
-
For
|
42
|
+
For information about a specific command and its options, use:
|
44
43
|
|
45
|
-
$ tweetwine
|
44
|
+
$ tweetwine help command
|
46
45
|
|
47
46
|
=== URL shortening for status update
|
48
47
|
|
@@ -53,7 +52,7 @@ example:
|
|
53
52
|
|
54
53
|
username: spoonman
|
55
54
|
password: withyourhands
|
56
|
-
|
55
|
+
colors: true
|
57
56
|
shorten_urls:
|
58
57
|
enable: true
|
59
58
|
service_url: http://is.gd/create.php
|
data/Rakefile
CHANGED
@@ -45,10 +45,12 @@ task :gemspec do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
desc "Install the software as a gem"
|
48
49
|
task :install => [:package] do
|
49
50
|
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
50
51
|
end
|
51
52
|
|
53
|
+
desc "Uninstall the gem"
|
52
54
|
task :uninstall => [:clean] do
|
53
55
|
sh %{sudo gem uninstall #{name}}
|
54
56
|
end
|
data/bin/tweetwine
CHANGED
@@ -1,80 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
EXIT_HELP = 1
|
4
|
-
EXIT_VERSION = 2
|
5
3
|
EXIT_SIGINT = 6
|
6
|
-
EXIT_ERROR = 64
|
7
4
|
|
8
5
|
trap("INT") do
|
9
6
|
puts "\nAbort"
|
10
7
|
exit(EXIT_SIGINT)
|
11
8
|
end
|
12
9
|
|
13
|
-
require "optparse"
|
14
10
|
require "tweetwine"
|
15
11
|
|
16
|
-
|
12
|
+
exec_name = File.basename($0)
|
13
|
+
config_file = ENV["HOME"] + "/.#{exec_name}"
|
17
14
|
|
18
|
-
|
19
|
-
options = {}
|
20
|
-
begin
|
21
|
-
OptionParser.new do |opt|
|
22
|
-
executable_name = File.basename($0)
|
23
|
-
|
24
|
-
opt.banner =<<-END
|
25
|
-
Usage: #{executable_name} [options...] [command]
|
26
|
-
|
27
|
-
Commands: #{Client::COMMANDS.join(", ")}
|
28
|
-
|
29
|
-
Options:
|
30
|
-
|
31
|
-
END
|
32
|
-
opt.on("-a", "--auth USERNAME:PASSWORD", "Authentication") do |arg|
|
33
|
-
options[:username], options[:password] = arg.split(":", 2)
|
34
|
-
end
|
35
|
-
opt.on("-c", "--colorize", "Colorize output with ANSI escape codes") do
|
36
|
-
options[:colorize] = true
|
37
|
-
end
|
38
|
-
opt.on("-n", "--num N", Integer, "The number of statuses to fetch, defaults to #{Client::DEFAULT_NUM_STATUSES}") do |arg|
|
39
|
-
options[:num_statuses] = arg
|
40
|
-
end
|
41
|
-
opt.on("--no-colorize", "Do not colorize output with ANSI escape codes") do
|
42
|
-
options[:colorize] = false
|
43
|
-
end
|
44
|
-
opt.on("--no-url-shorten", "Do not shorten URLs for status update") do
|
45
|
-
options[:shorten_urls] = { :enable => false }
|
46
|
-
end
|
47
|
-
opt.on("-p", "--page N", Integer, "The page number of the statuses to fetch, defaults to #{Client::DEFAULT_PAGE_NUM}") do |arg|
|
48
|
-
options[:page_num] = arg
|
49
|
-
end
|
50
|
-
opt.on("-v", "--version", "Show version information and exit") do
|
51
|
-
puts "#{executable_name} #{Tweetwine::VERSION}"
|
52
|
-
exit(EXIT_VERSION)
|
53
|
-
end
|
54
|
-
opt.on_tail("-h", "--help", "Show this help message and exit") do
|
55
|
-
puts opt
|
56
|
-
exit(EXIT_HELP)
|
57
|
-
end
|
58
|
-
end.parse!(args)
|
59
|
-
rescue OptionParser::ParseError => e
|
60
|
-
raise ArgumentError, e.message
|
61
|
-
end
|
62
|
-
options
|
63
|
-
end
|
64
|
-
|
65
|
-
def create_dependencies(options)
|
66
|
-
io = Tweetwine::IO.new(options)
|
67
|
-
rest_client = RestClientWrapper.new(io)
|
68
|
-
url_shortener = lambda { |opts| UrlShortener.new(rest_client, opts) }
|
69
|
-
Client::Dependencies.new io, rest_client, url_shortener
|
70
|
-
end
|
71
|
-
|
72
|
-
begin
|
73
|
-
config = StartupConfig.new(Client::COMMANDS)
|
74
|
-
config.parse(ARGV, ENV["HOME"] + "/.tweetwine", &cmd_parser)
|
75
|
-
client = Client.new(create_dependencies(config.options), config.options)
|
76
|
-
client.send(config.command, *config.args)
|
77
|
-
rescue ArgumentError, ClientError => e
|
78
|
-
puts "Error: #{e.message}"
|
79
|
-
exit(EXIT_ERROR)
|
80
|
-
end
|
15
|
+
Tweetwine::CLI.launch(ARGV, exec_name, config_file)
|
data/example/example_helper.rb
CHANGED
@@ -1,59 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
%w{
|
2
|
+
coulda
|
3
|
+
matchy
|
4
|
+
fakeweb
|
5
|
+
open4
|
6
|
+
stringio
|
7
|
+
time
|
8
|
+
timecop
|
9
|
+
}.each { |lib| require lib }
|
5
10
|
|
6
|
-
module Tweetwine
|
7
|
-
module ExampleHelpers
|
8
|
-
DEFAULT_INJECTION =<<-END
|
9
|
-
require "fakeweb"
|
10
11
|
FakeWeb.allow_net_connect = false
|
11
|
-
|
12
|
-
require "date"
|
13
|
-
require "time"
|
14
|
-
require "timecop"
|
15
12
|
Timecop.freeze(Time.parse("2009-10-14 01:56:15 +0300"))
|
16
13
|
|
17
|
-
|
18
|
-
contents = nil
|
19
|
-
filepath = File.dirname(__FILE__) << "/example/fixtures/" << filename
|
20
|
-
File.open(filepath) do |f|
|
21
|
-
contents = f.readlines.join("\n")
|
22
|
-
end
|
23
|
-
contents
|
24
|
-
end
|
25
|
-
END
|
14
|
+
require "tweetwine"
|
26
15
|
|
27
|
-
|
16
|
+
module Tweetwine
|
17
|
+
module ExampleHelpers
|
18
|
+
TEST_USER = "fooman"
|
19
|
+
TEST_PASSWD = "barpwd"
|
20
|
+
TEST_AUTH = "#{TEST_USER}:#{TEST_PASSWD}"
|
21
|
+
|
22
|
+
def launch_app(args, &blk)
|
28
23
|
lib = File.dirname(__FILE__) << "/../lib"
|
29
24
|
executable = File.dirname(__FILE__) << "/../bin/tweetwine"
|
30
|
-
|
31
|
-
#{escape_injection_for_shell(DEFAULT_INJECTION)}
|
32
|
-
#{escape_injection_for_shell(injection_code)}
|
33
|
-
`cat #{executable}`
|
34
|
-
END
|
35
|
-
launch_cmd = "ruby -rubygems -I#{lib} -e \"#{code}\" -- #{args}"
|
25
|
+
launch_cmd = "ruby -rubygems -I#{lib} -- #{executable} #{args}"
|
36
26
|
Open4::popen4(launch_cmd, &blk)
|
37
27
|
end
|
38
28
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
code_dup.gsub!('"', '\\"')
|
45
|
-
code_dup
|
29
|
+
def launch_cli(args, *input)
|
30
|
+
input, output = StringIO.new(input.join("\n")), StringIO.new
|
31
|
+
extra_opts = { :input => input, :output => output }
|
32
|
+
CLI.launch(args, "test", nil, extra_opts)
|
33
|
+
output.string.split("\n")
|
46
34
|
end
|
47
|
-
end
|
48
|
-
end
|
49
35
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
36
|
+
def fixture(filename)
|
37
|
+
contents = nil
|
38
|
+
filepath = File.dirname(__FILE__) << "/fixtures/" << filename
|
39
|
+
File.open(filepath) do |f|
|
40
|
+
contents = f.readlines.join("\n")
|
41
|
+
end
|
42
|
+
contents
|
54
43
|
end
|
55
44
|
end
|
56
45
|
end
|
57
46
|
|
58
47
|
include Coulda
|
59
48
|
include Tweetwine
|
49
|
+
include Tweetwine::ExampleHelpers
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
[{"in_reply_to_screen_name":"fooman","geo":null,"in_reply_to_user_id":29706667,"in_reply_to_status_id":5917716667,"source":"<a href=\"http://apiwiki.twitter.com/\" rel=\"nofollow\">API</a>","user":{"profile_sidebar_fill_color":"ccf5cd","followers_count":32768,"description":null,"following":false,"time_zone":"GMT","friends_count":2,"profile_sidebar_border_color":"e0ffee","notifications":false,"favourites_count":0,"profile_text_color":"000000","url":null,"statuses_count":42,"profile_background_image_url":null,"profile_link_color":"1f6603","protected":false,"geo_enabled":false,"profile_background_tile":false,"created_at":"Fri Jul 24 15:18:06 +0000 2009","profile_image_url":null,"location":"Spain","name":"Jill Valentine","profile_background_color":"ffffff","id":59804598,"verified":false,"utc_offset":0,"screen_name":"jillv"},"truncated":false,"created_at":"Sat Oct 10 22:36:25 +0000 2009","id":5930046667,"favorited":false,"text":"@fooman, did you see their eyes glow yellow after sunset?"},{"in_reply_to_screen_name":"fooman","geo":null,"in_reply_to_user_id":29706667,"in_reply_to_status_id":5917726667,"source":"<a href=\"http://apiwiki.twitter.com/\" rel=\"nofollow\">API</a>","user":{"profile_sidebar_fill_color":"ccf5cd","followers_count":327,"description":null,"following":false,"time_zone":"GMT","friends_count":22,"profile_sidebar_border_color":"e0ffee","notifications":false,"favourites_count":0,"profile_text_color":"000000","url":null,"statuses_count":42,"profile_background_image_url":null,"profile_link_color":"1f6603","protected":false,"geo_enabled":false,"profile_background_tile":false,"created_at":"Fri Jul 25 15:18:06 +0000 2009","profile_image_url":null,"location":"Spain","name":"Chris Redfield","profile_background_color":"ffffff","id":59804333,"verified":false,"utc_offset":0,"screen_name":"redfield"},"truncated":false,"created_at":"Thu Oct 8 22:36:25 +0000 2009","id":5930056667,"favorited":false,"text":"sometimes it is just best to run, just like @fooman"}]
|
@@ -0,0 +1 @@
|
|
1
|
+
{"results":[{"profile_image_url":"","created_at":"Tue, 13 Oct 2009 18:18:44 +0000","from_user":"thatswhatshesaid","to_user_id":52166667,"text":"@hatguy braid, perhaps the best indie game of 2009","id":6900986667,"from_user_id":1216667,"to_user":"hatguy","geo":null,"iso_language_code":"en","source":""},{"profile_image_url":"","created_at":"Tue, 13 Oct 2009 11:44:27 +0000","from_user":"jillv","to_user_id":null,"text":"braid is even better than of the games i'm in, expect re4","id":6891036667,"from_user_id":3486667,"geo":null,"iso_language_code":"en","source":""}],"max_id":6902086667,"since_id":0,"refresh_url":"?since_id=6902084185&q=braid+game","next_page":"?page=2&max_id=6902084185&rpp=2&q=braid+game","results_per_page":2,"page":1,"completed_in":0.020717,"query":"braid+game"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"favorited":false,"geo":null,"in_reply_to_screen_name":null,"source":"<a href=\"http://apiwiki.twitter.com/\" rel=\"nofollow\">API</a>","in_reply_to_user_id":null,"in_reply_to_status_id":null,"user":{"profile_background_tile":false,"description":"just testing","verified":false,"profile_background_color":"1a1b1f","following":false,"profile_sidebar_fill_color":"24252b","profile_image_url":"","followers_count":0,"statuses_count":1,"time_zone":"Helsinki","profile_sidebar_border_color":"1a1b1f","url":"http://www.twitter.com/fooman","screen_name":"fooman","friends_count":0,"protected":false,"notifications":false,"favourites_count":0,"created_at":"Wed Oct 10 12:00:00 +0000 2009","profile_text_color":"6b6b6b","location":"Finland","name":"Fooman","profile_background_image_url":"http://s.twimg.com/a/1258674567/images/themes/theme5/bg.gif","id":29700570,"geo_enabled":false,"utc_offset":7200,"profile_link_color":"0070cc"},"created_at":"Sat Oct 13 14:23:41 +0000 2009","truncated":false,"id":5919326888,"text":"bored. going to sleep."}
|
@@ -0,0 +1 @@
|
|
1
|
+
[{"geo":null,"source":"web","truncated":false,"favorited":false,"user":{"profile_background_image_url":null,"description":"","profile_link_color":"0070cc","profile_background_tile":false,"statuses_count":2,"profile_background_color":"1a1b1f","following":false,"followers_count":2,"profile_sidebar_fill_color":"24252b","friends_count":2,"time_zone":null,"profile_sidebar_border_color":"1a1b1f","protected":false,"url":null,"notifications":false,"favourites_count":0,"profile_image_url":null,"location":null,"name":"Jill Valentine","id":29706667,"verified":false,"geo_enabled":false,"utc_offset":0,"created_at":"Wed Apr 08 12:12:22 +0000 2009","profile_text_color":"6b6b6b","screen_name":"jillv"},"in_reply_to_user_id":15506667,"in_reply_to_status_id":null,"in_reply_to_screen_name":"chris","id":679006667,"text":"@chris wait me until the garden","created_at":"Wed Oct 14 07:57:00 +0000 2009"},{"geo":null,"source":"web","truncated":false,"favorited":false,"user":{"profile_background_image_url":null,"description":"","profile_link_color":"0070cc","profile_background_tile":false,"statuses_count":2,"profile_background_color":"1a1b1f","following":false,"followers_count":2,"profile_sidebar_fill_color":"24252b","friends_count":2,"time_zone":null,"profile_sidebar_border_color":"1a1b1f","protected":false,"url":null,"notifications":false,"favourites_count":0,"profile_image_url":null,"location":null,"name":"Jill Valentine","id":29706667,"verified":false,"geo_enabled":false,"utc_offset":0,"created_at":"Wed Apr 08 12:12:22 +0000 2009","profile_text_color":"6b6b6b","screen_name":"jillv"},"in_reply_to_user_id":null,"in_reply_to_status_id":null,"in_reply_to_screen_name":null,"id":6766566667,"text":"so boring to wait","created_at":"Sat Oct 10 15:39:16 +0000 2009"}]
|
@@ -0,0 +1 @@
|
|
1
|
+
[{"profile_background_image_url":null,"description":"","profile_link_color":"1F98C7","status":{"source":"web","truncated":false,"favorited":false,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"in_reply_to_screen_name":null,"id":6626773208,"text":"choosing next target","created_at":"Sun Oct 13 11:22:34 +0000 2009"},"profile_background_tile":false,"statuses_count":1,"profile_background_color":"C6E2EE","following":true,"followers_count":1,"profile_sidebar_fill_color":"DAECF4","friends_count":2,"time_zone":null,"profile_sidebar_border_color":"C6E2EE","protected":false,"url":null,"notifications":false,"favourites_count":0,"profile_image_url":null,"location":null,"name":"Jill Valentine","id":85386667,"verified":false,"geo_enabled":false,"utc_offset":0,"created_at":"Thu Oct 1 18:43:52 +0000 2009","profile_text_color":"663B12","screen_name":"jillv"},{"profile_background_image_url":null,"description":"","verified":false,"profile_link_color":"990000","status":{"source":"web","truncated":false,"favorited":false,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"in_reply_to_screen_name":null,"id":689686667,"text":null,"created_at":null},"profile_background_tile":false,"profile_background_color":"EBEBEB","following":true,"statuses_count":0,"profile_sidebar_fill_color":"F3F3F3","followers_count":1,"time_zone":null,"profile_sidebar_border_color":"DFDFDF","protected":false,"url":null,"friends_count":1,"profile_image_url":null,"location":null,"name":"ham","id":15506667,"geo_enabled":false,"notifications":false,"utc_offset":7200,"favourites_count":0,"created_at":"Fri Oct 2 20:41:17 +0000 2008","profile_text_color":"333333","screen_name":"ham"}]
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "example_helper"
|
2
|
+
|
3
|
+
FakeWeb.register_uri(:get, "http://search.twitter.com/search.json?q=braid%20game&rpp=2&page=1", :body => fixture("search.json"))
|
4
|
+
|
5
|
+
Feature "search statuses" do
|
6
|
+
in_order_to "search statuses"
|
7
|
+
as_a "any user"
|
8
|
+
i_want_to "see latest statuses that match the search"
|
9
|
+
|
10
|
+
Scenario "see statuses that match the search" do
|
11
|
+
When "application is launched 'search' command and search words as extra arguments" do
|
12
|
+
@output = launch_cli(%W{-a anyuser:anypwd --no-colors -n 2 search braid game})
|
13
|
+
end
|
14
|
+
|
15
|
+
Then "the latest statuses that match the search are shown" do
|
16
|
+
@output[0].should == "thatswhatshesaid, in reply to hatguy, 5 hours ago:"
|
17
|
+
@output[1].should == "@hatguy braid, perhaps the best indie game of 2009"
|
18
|
+
@output[2].should == ""
|
19
|
+
@output[3].should == "jillv, 11 hours ago:"
|
20
|
+
@output[4].should == "braid is even better than of the games i'm in, expect re4"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Scenario "attempt searching without specifying search word" do
|
25
|
+
When "application is launched 'search' command without extra arguments" do
|
26
|
+
@status = launch_app("-a anyuser:anypwd --no-colors -n 2 search") do |pid, stdin, stdout|
|
27
|
+
@output = stdout.readlines
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Then "the latest statuses that match the search are shown" do
|
32
|
+
@output[0].should == "Error: No search word\n"
|
33
|
+
@status.exitstatus.should == CLI::EXIT_ERROR
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "example_helper"
|
2
|
+
|
3
|
+
FakeWeb.register_uri(:get, "https://#{TEST_AUTH}@twitter.com/statuses/followers/#{TEST_USER}.json", :body => fixture("users.json"))
|
4
|
+
|
5
|
+
Feature "show followers and their latest statuses" do
|
6
|
+
in_order_to "to see who follows me"
|
7
|
+
as_a "authenticated user"
|
8
|
+
i_want_to "see my followers and their latest statuses, if any"
|
9
|
+
|
10
|
+
Scenario "see followers and their latest statuses" do
|
11
|
+
When "application is launched 'followers' command" do
|
12
|
+
@output = launch_cli(%W{-a #{TEST_AUTH} --no-colors followers})
|
13
|
+
end
|
14
|
+
|
15
|
+
Then "my followers and their latest statuses are shown" do
|
16
|
+
@output[0].should == "jillv, 12 hours ago:"
|
17
|
+
@output[1].should == "choosing next target"
|
18
|
+
@output[2].should == ""
|
19
|
+
@output[3].should == "ham"
|
20
|
+
@output[4].should == nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "example_helper"
|
2
|
+
|
3
|
+
FakeWeb.register_uri(:get, "https://#{TEST_AUTH}@twitter.com/statuses/friends/#{TEST_USER}.json", :body => fixture("users.json"))
|
4
|
+
|
5
|
+
Feature "show friends and their latest statuses" do
|
6
|
+
in_order_to "to see who I follow"
|
7
|
+
as_a "authenticated user"
|
8
|
+
i_want_to "see my friends and their latest statuses, if any"
|
9
|
+
|
10
|
+
Scenario "see friends and their latest statuses" do
|
11
|
+
When "application is launched 'friends' command" do
|
12
|
+
@output = launch_cli(%W{-a #{TEST_AUTH} --no-colors friends})
|
13
|
+
end
|
14
|
+
|
15
|
+
Then "my friends and their latest statuses are shown" do
|
16
|
+
@output[0].should == "jillv, 12 hours ago:"
|
17
|
+
@output[1].should == "choosing next target"
|
18
|
+
@output[2].should == ""
|
19
|
+
@output[3].should == "ham"
|
20
|
+
@output[4].should == nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "example_helper"
|
2
|
+
|
3
|
+
FakeWeb.register_uri(:get, "https://#{TEST_AUTH}@twitter.com/statuses/home_timeline.json?count=20&page=1", :body => fixture("home.json"))
|
4
|
+
|
5
|
+
Feature "show the latest statuses in the home timeline for the user" do
|
6
|
+
in_order_to "stay up-to-date"
|
7
|
+
as_a "authenticated user"
|
8
|
+
i_want_to "see the latest statuses in the home view"
|
9
|
+
|
10
|
+
Scenario "see home with colorization disabled" do
|
11
|
+
When "application is launched with no command" do
|
12
|
+
@output = launch_cli(%W{-a #{TEST_AUTH} --no-colors})
|
13
|
+
end
|
14
|
+
|
15
|
+
Then "the latest statuses in the home view are shown" do
|
16
|
+
@output[0].should == "pelit, 11 days ago:"
|
17
|
+
@output[1].should == "F1-kausi alkaa marraskuussa http://bit.ly/1qQwjQ"
|
18
|
+
@output[2].should == ""
|
19
|
+
@output[58].should == "radar, 15 days ago:"
|
20
|
+
@output[59].should == "Four short links: 29 September 2009 http://bit.ly/dYxay"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Scenario "see home with colorization enabled" do
|
25
|
+
When "application is launched with no command" do
|
26
|
+
@output = launch_cli(%W{-a #{TEST_AUTH} --colors})
|
27
|
+
end
|
28
|
+
|
29
|
+
Then "the latest statuses in the home view are shown" do
|
30
|
+
@output[0].should == "\e[32mpelit\e[0m, 11 days ago:"
|
31
|
+
@output[1].should == "F1-kausi alkaa marraskuussa \e[36mhttp://bit.ly/1qQwjQ\e[0m"
|
32
|
+
@output[2].should == ""
|
33
|
+
@output[58].should == "\e[32mradar\e[0m, 15 days ago:"
|
34
|
+
@output[59].should == "Four short links: 29 September 2009 \e[36mhttp://bit.ly/dYxay\e[0m"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Scenario "the command for showing the home view is the default command" do
|
39
|
+
When "application is launched with 'home' command" do
|
40
|
+
@output = launch_cli(%W{-a #{TEST_AUTH} --no-colors home})
|
41
|
+
end
|
42
|
+
|
43
|
+
Then "the latest statuses in the home view are shown" do
|
44
|
+
@output[0].should == "pelit, 11 days ago:"
|
45
|
+
@output[1].should == "F1-kausi alkaa marraskuussa http://bit.ly/1qQwjQ"
|
46
|
+
@output[2].should == ""
|
47
|
+
@output[58].should == "radar, 15 days ago:"
|
48
|
+
@output[59].should == "Four short links: 29 September 2009 http://bit.ly/dYxay"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "example_helper"
|
2
|
+
|
3
|
+
FakeWeb.register_uri(:get, "https://#{TEST_AUTH}@twitter.com/statuses/mentions.json?count=20&page=1", :body => fixture("mentions.json"))
|
4
|
+
|
5
|
+
Feature "show the latest statuses mentioning the user" do
|
6
|
+
in_order_to "know if someone has mention me"
|
7
|
+
as_a "authenticated user"
|
8
|
+
i_want_to "see the latest statuses that mention me"
|
9
|
+
|
10
|
+
Scenario "see the latest statuses that mention me" do
|
11
|
+
When "application is launched with 'mentions' command" do
|
12
|
+
@output = launch_cli(%W{-a #{TEST_AUTH} --no-colors mentions})
|
13
|
+
end
|
14
|
+
|
15
|
+
Then "the latest statuses that mention me are shown" do
|
16
|
+
@output[0].should == "jillv, in reply to fooman, 3 days ago:"
|
17
|
+
@output[1].should == "@fooman, did you see their eyes glow yellow after sunset?"
|
18
|
+
@output[2].should == ""
|
19
|
+
@output[3].should == "redfield, in reply to fooman, 5 days ago:"
|
20
|
+
@output[4].should == "sometimes it is just best to run, just like @fooman"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -5,7 +5,7 @@ Feature "show metadata" do
|
|
5
5
|
as_a "user"
|
6
6
|
i_want_to "see application metadata"
|
7
7
|
|
8
|
-
Scenario "see version" do
|
8
|
+
Scenario "see version with designated exit status" do
|
9
9
|
When "application is launched with -v" do
|
10
10
|
@status = launch_app("-v") do |pid, stdin, stdout|
|
11
11
|
@output = stdout.gets
|
@@ -14,11 +14,11 @@ Feature "show metadata" do
|
|
14
14
|
|
15
15
|
Then "version is shown" do
|
16
16
|
@output.should =~ /\d\.\d\.\d$/
|
17
|
-
@status.exitstatus.should ==
|
17
|
+
@status.exitstatus.should == CLI::EXIT_VERSION
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
Scenario "see help" do
|
21
|
+
Scenario "see help with designated exit status" do
|
22
22
|
When "application is launched with -h" do
|
23
23
|
@status = launch_app("-h") do |pid, stdin, stdout|
|
24
24
|
@output = stdout.readlines
|
@@ -26,10 +26,57 @@ Feature "show metadata" do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
Then "help is shown" do
|
29
|
-
@output
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
@output.join.should == <<-END
|
30
|
+
A simple but tasty Twitter agent for command line use, made for fun.
|
31
|
+
|
32
|
+
Usage: tweetwine [global_options...] [command] [command_options...]
|
33
|
+
|
34
|
+
[command] is one of
|
35
|
+
* followers,
|
36
|
+
* friends,
|
37
|
+
* home,
|
38
|
+
* mentions,
|
39
|
+
* search,
|
40
|
+
* update, or
|
41
|
+
* user.
|
42
|
+
|
43
|
+
The default command is home.
|
44
|
+
|
45
|
+
[global_options]:
|
46
|
+
-a, --auth USERNAME:PASSWORD Authentication
|
47
|
+
-c, --colors Colorize output with ANSI escape codes
|
48
|
+
-n, --num N The number of statuses in page, default 20
|
49
|
+
--no-colors Do not use ANSI colors
|
50
|
+
--no-url-shorten Do not shorten URLs for status update
|
51
|
+
-p, --page N The page number for statuses, default 1
|
52
|
+
-v, --version Show version information and exit
|
53
|
+
-h, --help Show this help message and exit
|
54
|
+
END
|
55
|
+
@status.exitstatus.should == CLI::EXIT_HELP
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
Scenario "upon invalid option, use designated exit status" do
|
60
|
+
When "application is launched with -X" do
|
61
|
+
@status = launch_app("-X") do |pid, stdin, stdout|
|
62
|
+
@output = stdout.readlines
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Then "designated exit status is returned" do
|
67
|
+
@status.exitstatus.should == CLI::EXIT_ERROR
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
Scenario "upon invalid command, use designated exit status" do
|
72
|
+
When "application is launched with 'unknown'" do
|
73
|
+
@status = launch_app("unknown") do |pid, stdin, stdout|
|
74
|
+
@output = stdout.readlines
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
Then "designated exit status is returned" do
|
79
|
+
@status.exitstatus.should == CLI::EXIT_ERROR
|
33
80
|
end
|
34
81
|
end
|
35
82
|
end
|