tweetwine 0.2.5 → 0.2.7

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.
Files changed (41) hide show
  1. data/CHANGELOG.rdoc +30 -17
  2. data/README.rdoc +16 -17
  3. data/Rakefile +2 -0
  4. data/bin/tweetwine +3 -68
  5. data/example/example_helper.rb +31 -41
  6. data/example/fixtures/{statuses.json → home.json} +0 -0
  7. data/example/fixtures/mentions.json +1 -0
  8. data/example/fixtures/search.json +1 -0
  9. data/example/fixtures/update.json +1 -0
  10. data/example/fixtures/user.json +1 -0
  11. data/example/fixtures/users.json +1 -0
  12. data/example/search_statuses_example.rb +36 -0
  13. data/example/show_followers_example.rb +23 -0
  14. data/example/show_friends_example.rb +23 -0
  15. data/example/show_home_example.rb +51 -0
  16. data/example/show_mentions_example.rb +23 -0
  17. data/example/show_metadata_example.rb +54 -7
  18. data/example/show_user_example.rb +37 -0
  19. data/example/update_status_example.rb +65 -0
  20. data/lib/tweetwine/cli.rb +241 -0
  21. data/lib/tweetwine/client.rb +94 -57
  22. data/lib/tweetwine/io.rb +39 -28
  23. data/lib/tweetwine/meta.rb +1 -1
  24. data/lib/tweetwine/retrying_http.rb +93 -0
  25. data/lib/tweetwine/startup_config.rb +14 -15
  26. data/lib/tweetwine/url_shortener.rb +13 -8
  27. data/lib/tweetwine/util.rb +14 -0
  28. data/lib/tweetwine.rb +2 -1
  29. data/test/cli_test.rb +16 -0
  30. data/test/client_test.rb +275 -205
  31. data/test/fixtures/test_config.yaml +2 -1
  32. data/test/io_test.rb +89 -62
  33. data/test/retrying_http_test.rb +127 -0
  34. data/test/startup_config_test.rb +52 -27
  35. data/test/test_helper.rb +32 -17
  36. data/test/url_shortener_test.rb +18 -18
  37. data/test/util_test.rb +145 -47
  38. metadata +20 -7
  39. data/example/show_latest_statuses_example.rb +0 -45
  40. data/lib/tweetwine/rest_client_wrapper.rb +0 -37
  41. 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 "--no-colorize" to (temporarily) disable colors from the
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 "-v".
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 "-v" show version information.
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 "friends" and "followers"
48
- * Removed dependency to the "json" gem. It is included in Ruby 1.9.
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 "--page N" fetches a specific status page
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 "friends" to "home"
80
- * Added command "mentions"
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 "msg" to "update"
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 GitHub:
7
+ Install Tweetwine as a RubyGem from Gemcutter[http://gemcutter.org/]:
8
8
 
9
- $ sudo gem install tuomas-tweetwine --source http://gems.github.com
9
+ $ sudo gem install tweetwine --source http://gemcutter.org
10
10
 
11
- The program is compatible with Ruby 1.9.1, and it requires <b>rest_client</b>
12
- gem to be installed. In addition, <b>json</b> gem is needed for Ruby 1.8.6.
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 [options...] [command]
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
- colorize: true|false
31
+ colors: true|false
31
32
 
32
- When invoking the program, the supported commands are
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
- <tt>home</tt>:: Fetch friends' latest statuses (the contents of the authenticated user's home).
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
- If no <tt>[command]</tt> is given, the default action is <tt>home</tt>.
40
+ $ tweetwine help
42
41
 
43
- For all the options, see:
42
+ For information about a specific command and its options, use:
44
43
 
45
- $ tweetwine -h
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
- colorize: true
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
- include Tweetwine
12
+ exec_name = File.basename($0)
13
+ config_file = ENV["HOME"] + "/.#{exec_name}"
17
14
 
18
- cmd_parser = lambda do |args|
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)
@@ -1,59 +1,49 @@
1
- require "coulda"
2
- require "matchy"
3
- require "open4"
4
- require "tweetwine"
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
- def fixture(filename)
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
- def launch_app(args, injection_code = "", &blk)
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
- code =<<-END
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
- private
40
-
41
- def escape_injection_for_shell(code)
42
- code_dup = code.dup
43
- code_dup.gsub!('\'', '\\\'')
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
- module Test
51
- module Unit
52
- class TestCase
53
- include Tweetwine::ExampleHelpers
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 == 2
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[0].should =~ /^Usage:.* \[options\.\.\.\] \[command\]/
30
- @output[2].should =~ /Commands: #{Client::COMMANDS.join(", ")}/
31
- @output[4].should =~ /Options:$/
32
- @status.exitstatus.should == 1
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