tweetwine 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGELOG.rdoc +9 -0
- data/Gemfile +5 -13
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/Rakefile +8 -2
- data/lib/tweetwine/character_encoding.rb +1 -1
- data/lib/tweetwine/cli.rb +9 -3
- data/lib/tweetwine/config.rb +3 -3
- data/lib/tweetwine/exceptions.rb +54 -0
- data/lib/tweetwine/http.rb +1 -1
- data/lib/tweetwine/{util.rb → support.rb} +19 -12
- data/lib/tweetwine/tweet.rb +69 -0
- data/lib/tweetwine/twitter.rb +70 -72
- data/lib/tweetwine/ui.rb +36 -41
- data/lib/tweetwine/uri.rb +31 -0
- data/lib/tweetwine/version.rb +15 -0
- data/lib/tweetwine.rb +6 -64
- data/man/tweetwine.7 +4 -3
- data/man/tweetwine.7.ronn +3 -2
- data/release-script.txt +10 -0
- data/test/example/authorization_example.rb +40 -0
- data/test/example/example_helper.rb +1 -1
- data/test/example/global_options_example.rb +64 -0
- data/test/example/search_statuses_example.rb +36 -31
- data/test/example/show_followers_example.rb +1 -1
- data/test/example/show_friends_example.rb +1 -1
- data/test/example/show_home_example.rb +17 -29
- data/test/example/show_mentions_example.rb +2 -2
- data/test/example/show_user_example.rb +14 -12
- data/test/example/update_status_example.rb +9 -9
- data/test/example/use_http_proxy_example.rb +7 -6
- data/test/example/{application_behavior_example.rb → user_help_example.rb} +6 -39
- data/test/unit/config_test.rb +1 -1
- data/test/unit/http_test.rb +1 -21
- data/test/unit/oauth_test.rb +11 -11
- data/test/unit/{util_test.rb → support_test.rb} +37 -38
- data/test/unit/tweet_helper.rb +83 -0
- data/test/unit/tweet_test.rb +153 -0
- data/test/unit/twitter_test.rb +240 -248
- data/test/unit/ui_test.rb +174 -78
- data/test/unit/unit_helper.rb +18 -6
- data/test/unit/uri_test.rb +41 -0
- data/test/unit/url_shortener_test.rb +7 -7
- data/tweetwine.gemspec +12 -22
- metadata +52 -73
data/lib/tweetwine/ui.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require "uri"
|
4
|
-
|
5
3
|
module Tweetwine
|
6
4
|
class UI
|
7
5
|
COLOR_CODES = {
|
@@ -14,10 +12,11 @@ module Tweetwine
|
|
14
12
|
USERNAME_REGEX = /^(@\w+)|\s+(@\w+)/
|
15
13
|
|
16
14
|
def initialize(options = {})
|
17
|
-
@in
|
18
|
-
@out
|
19
|
-
@err
|
20
|
-
@colors
|
15
|
+
@in = options[:in] || $stdin
|
16
|
+
@out = options[:out] || $stdout
|
17
|
+
@err = options[:err] || $stderr
|
18
|
+
@colors = options[:colors] || false
|
19
|
+
@reverse = options[:show_reverse] || false
|
21
20
|
end
|
22
21
|
|
23
22
|
def info(start_msg = "\n", end_msg = " done.")
|
@@ -57,41 +56,32 @@ module Tweetwine
|
|
57
56
|
END
|
58
57
|
end
|
59
58
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
def show_tweets(tweets)
|
60
|
+
tweets = tweets.reverse if @reverse
|
61
|
+
tweets.each { |t| show_tweet(t) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def show_tweet(tweet)
|
65
|
+
if tweet.status?
|
66
|
+
show_regular_tweet(tweet)
|
64
67
|
else
|
65
|
-
|
68
|
+
show_user_info_tweet(tweet)
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
69
72
|
private
|
70
73
|
|
71
|
-
def
|
72
|
-
record.each_pair do |key, value|
|
73
|
-
if value.is_a? Hash
|
74
|
-
clean_record(value)
|
75
|
-
else
|
76
|
-
unless value.nil?
|
77
|
-
value = value.to_s
|
78
|
-
record[key] = value.empty? ? nil : value
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def show_record_as_user(record)
|
74
|
+
def show_user_info_tweet(tweet)
|
85
75
|
@out.puts <<-END
|
86
|
-
#{format_user(
|
76
|
+
#{format_user(tweet.from_user)}
|
87
77
|
|
88
78
|
END
|
89
79
|
end
|
90
80
|
|
91
|
-
def
|
81
|
+
def show_regular_tweet(tweet)
|
92
82
|
@out.puts <<-END
|
93
|
-
#{
|
94
|
-
#{format_status(
|
83
|
+
#{format_header(tweet)}
|
84
|
+
#{format_status(tweet.status)}
|
95
85
|
|
96
86
|
END
|
97
87
|
end
|
@@ -102,26 +92,31 @@ module Tweetwine
|
|
102
92
|
end
|
103
93
|
|
104
94
|
def format_status(status)
|
105
|
-
status =
|
95
|
+
status = Support.unescape_html(status)
|
106
96
|
if @colors
|
107
|
-
status = colorize_matching(:yellow,
|
108
|
-
status = colorize_matching(:magenta,
|
109
|
-
status = colorize_matching(:cyan,
|
97
|
+
status = colorize_matching(:yellow, status, USERNAME_REGEX)
|
98
|
+
status = colorize_matching(:magenta, status, HASHTAG_REGEX)
|
99
|
+
status = colorize_matching(:cyan, status, Uri.extract(status, %w{http https}).uniq)
|
110
100
|
end
|
111
101
|
status
|
112
102
|
end
|
113
103
|
|
114
|
-
def
|
115
|
-
|
104
|
+
def format_header(tweet)
|
105
|
+
from_user = tweet.from_user
|
106
|
+
to_user = tweet.to_user if tweet.reply?
|
107
|
+
rt_user = tweet.rt_user if tweet.retweet?
|
116
108
|
if @colors
|
117
109
|
from_user = colorize(:green, from_user)
|
118
|
-
to_user
|
110
|
+
to_user = colorize(:green, to_user) if tweet.reply?
|
111
|
+
rt_user = colorize(:green, rt_user) if tweet.retweet?
|
119
112
|
end
|
120
|
-
if
|
121
|
-
|
122
|
-
else
|
123
|
-
"#{from_user}, #{time_diff_value} #{time_diff_unit} ago:"
|
113
|
+
if tweet.timestamped?
|
114
|
+
time_diff_value, time_diff_unit = Support.humanize_time_diff(tweet.created_at, Time.now)
|
124
115
|
end
|
116
|
+
from_part = tweet.retweet? ? "#{rt_user} RT #{from_user}" : from_user
|
117
|
+
to_part = tweet.reply? ? ", in reply to #{to_user}" : ''
|
118
|
+
time_part = tweet.timestamped? ? ", #{time_diff_value} #{time_diff_unit} ago" : ''
|
119
|
+
"#{from_part}#{to_part}#{time_part}:"
|
125
120
|
end
|
126
121
|
|
127
122
|
def colorize_matching(color, str, pattern)
|
@@ -133,7 +128,7 @@ module Tweetwine
|
|
133
128
|
else
|
134
129
|
raise "unknown kind of pattern"
|
135
130
|
end
|
136
|
-
|
131
|
+
Support.str_gsub_by_group(str, regexp) { |s| colorize(color, s) }
|
137
132
|
end
|
138
133
|
|
139
134
|
def colorize(color, str)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Tweetwine
|
6
|
+
module Uri
|
7
|
+
UNSAFE_CHARS_REGEXP = /[^#{URI::PATTERN::UNRESERVED}]/
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def parser
|
11
|
+
if ::URI.const_defined? :Parser
|
12
|
+
@parser ||= ::URI::Parser.new
|
13
|
+
else
|
14
|
+
::URI
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract(*args)
|
19
|
+
parser.extract(*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse(*args)
|
23
|
+
parser.parse(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def percent_encode(str)
|
27
|
+
parser.escape(str.to_s, UNSAFE_CHARS_REGEXP)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/tweetwine.rb
CHANGED
@@ -8,72 +8,12 @@ end unless defined? JSON
|
|
8
8
|
|
9
9
|
gem 'oauth', '~> 0.4.4'
|
10
10
|
|
11
|
-
|
12
|
-
VERSION = '0.3.2'.freeze
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def version
|
16
|
-
VERSION
|
17
|
-
end
|
18
|
-
|
19
|
-
def summary
|
20
|
-
'Tweetwine shows the latest tweets from the command line quickly.'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class Error < StandardError
|
25
|
-
@status_code = 42
|
26
|
-
|
27
|
-
# Idea got from Bundler.
|
28
|
-
def self.status_code(code = nil)
|
29
|
-
return @status_code unless code
|
30
|
-
@status_code = code
|
31
|
-
end
|
32
|
-
|
33
|
-
def status_code
|
34
|
-
self.class.status_code
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class CommandLineError < Error; status_code(13); end
|
39
|
-
class UnknownCommandError < Error; status_code(14); end
|
40
|
-
|
41
|
-
class RequiredOptionError < Error
|
42
|
-
status_code(15)
|
43
|
-
|
44
|
-
attr_reader :key, :owner
|
45
|
-
|
46
|
-
def initialize(key, owner)
|
47
|
-
@key, @owner = key, owner
|
48
|
-
end
|
49
|
-
|
50
|
-
def to_s
|
51
|
-
"#{key} is required for #{owner}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class ConnectionError < Error; status_code(21); end
|
56
|
-
class TimeoutError < Error; status_code(22); end
|
57
|
-
|
58
|
-
class HttpError < Error
|
59
|
-
status_code(25)
|
60
|
-
|
61
|
-
attr_reader :http_code, :http_message
|
62
|
-
|
63
|
-
def initialize(code, message)
|
64
|
-
@http_code, @http_message = code.to_i, message
|
65
|
-
end
|
66
|
-
|
67
|
-
def to_s
|
68
|
-
"#{http_code} #{http_message}"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
class TranscodeError < Error; status_code(31); end
|
73
|
-
class AuthorizationError < Error; status_code(32); end
|
11
|
+
require 'tweetwine/version'
|
74
12
|
|
13
|
+
module Tweetwine
|
75
14
|
lib_path = File.expand_path(File.dirname(__FILE__))
|
76
15
|
|
16
|
+
require "#{lib_path}/tweetwine/exceptions"
|
77
17
|
require "#{lib_path}/tweetwine/basic_object"
|
78
18
|
|
79
19
|
autoload :CharacterEncoding, "#{lib_path}/tweetwine/character_encoding"
|
@@ -84,8 +24,10 @@ module Tweetwine
|
|
84
24
|
autoload :Obfuscate, "#{lib_path}/tweetwine/obfuscate"
|
85
25
|
autoload :OptionParser, "#{lib_path}/tweetwine/option_parser"
|
86
26
|
autoload :Promise, "#{lib_path}/tweetwine/promise"
|
27
|
+
autoload :Support, "#{lib_path}/tweetwine/support"
|
28
|
+
autoload :Tweet, "#{lib_path}/tweetwine/tweet"
|
87
29
|
autoload :Twitter, "#{lib_path}/tweetwine/twitter"
|
88
30
|
autoload :UI, "#{lib_path}/tweetwine/ui"
|
31
|
+
autoload :Uri, "#{lib_path}/tweetwine/uri"
|
89
32
|
autoload :UrlShortener, "#{lib_path}/tweetwine/url_shortener"
|
90
|
-
autoload :Util, "#{lib_path}/tweetwine/util"
|
91
33
|
end
|
data/man/tweetwine.7
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
.\" generated with Ronn/v0.7.3
|
2
2
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
3
|
.
|
4
|
-
.TH "TWEETWINE" "7" "
|
4
|
+
.TH "TWEETWINE" "7" "February 2011" "Tuomas Kareinen" "Tweetwine Manual"
|
5
5
|
.
|
6
6
|
.SH "DESCRIPTION"
|
7
7
|
Tweetwine shows the latest tweets from the command line quickly\.
|
@@ -126,6 +126,7 @@ Before actually sending a new status update, it is possible for the software to
|
|
126
126
|
|
127
127
|
username: spoonman
|
128
128
|
colors: true
|
129
|
+
show_reverse: true
|
129
130
|
shorten_urls:
|
130
131
|
service_url: http://is\.gd/create\.php
|
131
132
|
method: post
|
@@ -181,7 +182,7 @@ fi
|
|
181
182
|
.IP "" 0
|
182
183
|
.
|
183
184
|
.SH "COPYRIGHT"
|
184
|
-
Tweetwine is
|
185
|
+
Tweetwine is copyright \(co 2009\-2011 Tuomas Kareinen\. See \fBLICENSE\.txt\fR\.
|
185
186
|
.
|
186
187
|
.SH "SEE ALSO"
|
187
|
-
\fIhttps://github\.com/
|
188
|
+
\fIhttps://github\.com/tkareine/tweetwine\fR
|
data/man/tweetwine.7.ronn
CHANGED
@@ -77,6 +77,7 @@ enabled via `shorten_urls` field in the configuration file; for example:
|
|
77
77
|
|
78
78
|
username: spoonman
|
79
79
|
colors: true
|
80
|
+
show_reverse: true
|
80
81
|
shorten_urls:
|
81
82
|
service_url: http://is.gd/create.php
|
82
83
|
method: post
|
@@ -124,8 +125,8 @@ snippet to your Bash initialization script (such as `~/.bashrc`):
|
|
124
125
|
|
125
126
|
## COPYRIGHT
|
126
127
|
|
127
|
-
Tweetwine is
|
128
|
+
Tweetwine is copyright © 2009-2011 Tuomas Kareinen. See `LICENSE.txt`.
|
128
129
|
|
129
130
|
## SEE ALSO
|
130
131
|
|
131
|
-
<https://github.com/
|
132
|
+
<https://github.com/tkareine/tweetwine>
|
data/release-script.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
In order to release, do
|
2
|
+
|
3
|
+
$EDITOR lib/tweetwine/version.rb # update version number
|
4
|
+
$EDITOR CHANGELOG.rdoc # describe history summary
|
5
|
+
git diff # review the changes
|
6
|
+
rake gem:build # check that tests pass
|
7
|
+
git commit -am "Bump to release-<version>"
|
8
|
+
git tag release-<version>
|
9
|
+
git push --tags origin master
|
10
|
+
gem push tweetwine-<version>.gem
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "example_helper"
|
4
|
+
require "fixture/oauth"
|
5
|
+
|
6
|
+
include Tweetwine::Test::Fixture::OAuth
|
7
|
+
|
8
|
+
Feature "authorization" do
|
9
|
+
as_a "user"
|
10
|
+
i_want_to "see authorize myself"
|
11
|
+
in_order_to "use the service"
|
12
|
+
|
13
|
+
Scenario "authorize user with OAuth and save access token" do
|
14
|
+
When "I start the application with 'home' command and the command fails due to me being unauthorized" do
|
15
|
+
@command_url = "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1"
|
16
|
+
stub_http_request(METHOD, REQUEST_TOKEN_URL).to_return(:body => REQUEST_TOKEN_RESPONSE)
|
17
|
+
stub_http_request(METHOD, ACCESS_TOKEN_URL).to_return(:body => ACCESS_TOKEN_RESPONSE)
|
18
|
+
stub_http_request(:get, @command_url).
|
19
|
+
to_return(:status => [401, 'Unauthorized']).then.
|
20
|
+
to_return(:body => fixture_file('home.json'))
|
21
|
+
in_temp_dir do
|
22
|
+
config_file = 'tweetwine.tmp'
|
23
|
+
@output = start_cli %W{--no-colors -f #{config_file} home}, [PIN], {}
|
24
|
+
@config_contents = YAML.load_file(config_file)
|
25
|
+
@config_mode = file_mode(config_file)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Then "the application authorizes me, saves access token to config file, and tries the command again" do
|
30
|
+
assert_requested(METHOD, REQUEST_TOKEN_URL)
|
31
|
+
assert_requested(METHOD, ACCESS_TOKEN_URL)
|
32
|
+
assert_requested(:get, @command_url, :headers => {'Authorization' => /^OAuth /}, :times => 2)
|
33
|
+
@output[0].should == "Please authorize: #{AUTHORIZE_URL}"
|
34
|
+
@output[1].should =~ /^Enter PIN:/
|
35
|
+
@output[2].should == "F1-kausi alkaa marraskuussa http://bit.ly/1qQwjQ"
|
36
|
+
@config_contents['oauth_access'].empty?.should == false
|
37
|
+
@config_mode.should == 0600
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "example_helper"
|
4
|
+
|
5
|
+
Feature "global options" do
|
6
|
+
as_a "user"
|
7
|
+
i_want_to "set global options"
|
8
|
+
in_order_to "affect general application behavior"
|
9
|
+
|
10
|
+
def setup
|
11
|
+
super
|
12
|
+
stub_http_request(:get, %r{https://api.twitter.com/1/statuses/home_timeline\.json\?count=\d+&page=\d+}).to_return(:body => fixture_file('home.json'))
|
13
|
+
end
|
14
|
+
|
15
|
+
Scenario "colors" do
|
16
|
+
When "I start the application with '--colors' option" do
|
17
|
+
@output = start_cli %w{--colors}
|
18
|
+
end
|
19
|
+
|
20
|
+
Then "the application shows tweets with colors" do
|
21
|
+
@output[0].should == "\e[32mpelit\e[0m, 11 days ago:"
|
22
|
+
@output[1].should == "F1-kausi alkaa marraskuussa \e[36mhttp://bit.ly/1qQwjQ\e[0m"
|
23
|
+
@output[2].should == ""
|
24
|
+
@output[58].should == "\e[32mradar\e[0m, 15 days ago:"
|
25
|
+
@output[59].should == "Four short links: 29 September 2009 \e[36mhttp://bit.ly/dYxay\e[0m"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Scenario "show reverse" do
|
30
|
+
When "I start the application with '--reverse' option" do
|
31
|
+
@output = start_cli %w{--reverse}
|
32
|
+
end
|
33
|
+
|
34
|
+
Then "the application shows tweets in reverse order" do
|
35
|
+
@output[0].should == "radar, 15 days ago:"
|
36
|
+
@output[1].should == "Four short links: 29 September 2009 http://bit.ly/dYxay"
|
37
|
+
@output[2].should == ""
|
38
|
+
@output[58].should == "pelit, 11 days ago:"
|
39
|
+
@output[59].should == "F1-kausi alkaa marraskuussa http://bit.ly/1qQwjQ"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Scenario "num" do
|
44
|
+
When "I start the application with '--num <n>' option" do
|
45
|
+
@num = 2
|
46
|
+
@output = start_cli %W{--num #{@num}}
|
47
|
+
end
|
48
|
+
|
49
|
+
Then "the application requests the specified number of tweets" do
|
50
|
+
assert_requested(:get, %r{/home_timeline\.json\?count=#{@num}&page=\d+})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Scenario "page" do
|
55
|
+
When "I start the application with '--page <p>' option" do
|
56
|
+
@page = 2
|
57
|
+
@output = start_cli %W{--page #{@page}}
|
58
|
+
end
|
59
|
+
|
60
|
+
Then "the application requests the specified page number for tweets" do
|
61
|
+
assert_requested(:get, %r{/home_timeline\.json\?count=\d+&page=#{@page}})
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -3,56 +3,51 @@
|
|
3
3
|
require "example_helper"
|
4
4
|
|
5
5
|
Feature "search tweets" do
|
6
|
-
in_order_to "search statuses"
|
7
6
|
as_a "authenticated user"
|
8
|
-
i_want_to "
|
7
|
+
i_want_to "search tweets with keywords"
|
8
|
+
in_order_to "see tweets that interest me"
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
SEARCH_BASE_URL = "http://search.twitter.com/search.json"
|
11
|
+
SEARCH_OR_URL = "#{SEARCH_BASE_URL}?q=braid%20OR%20game&rpp=2&page=1"
|
12
|
+
SEARCH_AND_URL = "#{SEARCH_BASE_URL}?q=braid%20game&rpp=2&page=1"
|
12
13
|
SEARCH_FIXTURE = fixture_file('search.json')
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
Then "the application shows tweets matching all the words" do
|
21
|
-
@output[0].should == "thatswhatshesaid, in reply to hatguy, 5 hours ago:"
|
22
|
-
@output[1].should == "@hatguy braid, perhaps the best indie game of 2009"
|
23
|
-
@output[2].should == ""
|
24
|
-
@output[3].should == "jillv, 11 hours ago:"
|
25
|
-
@output[4].should == "braid is even better than of the games i'm in, expect re4"
|
26
|
-
end
|
15
|
+
def setup
|
16
|
+
super
|
17
|
+
stub_http_request(:get, SEARCH_AND_URL).to_return(:body => SEARCH_FIXTURE)
|
18
|
+
stub_http_request(:get, SEARCH_OR_URL).to_return(:body => SEARCH_FIXTURE)
|
27
19
|
end
|
28
20
|
|
29
21
|
Scenario "search tweets matching all words" do
|
30
22
|
When "I start the application with command 'search', option '-a', and search words" do
|
31
|
-
stub_http_request(:get, SEARCH_OR_URL).to_return(:body => SEARCH_FIXTURE)
|
32
23
|
@output = start_cli %w{-n 2 search -a braid game}
|
33
24
|
end
|
34
25
|
|
35
|
-
Then "the application
|
36
|
-
|
37
|
-
|
38
|
-
@output[2].should == ""
|
39
|
-
@output[3].should == "jillv, 11 hours ago:"
|
40
|
-
@output[4].should == "braid is even better than of the games i'm in, expect re4"
|
26
|
+
Then "the application requests tweets matching all the words and shows them" do
|
27
|
+
assert_requested(:get, SEARCH_AND_URL)
|
28
|
+
should_output_tweets
|
41
29
|
end
|
42
30
|
end
|
43
31
|
|
44
32
|
Scenario "search tweets matching any words" do
|
45
33
|
When "I start the application with command 'search', option '-o', and search words" do
|
46
|
-
stub_http_request(:get, SEARCH_AND_URL).to_return(:body => SEARCH_FIXTURE)
|
47
34
|
@output = start_cli %w{-n 2 search -o braid game}
|
48
35
|
end
|
49
36
|
|
50
|
-
Then "the application
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
37
|
+
Then "the application requests tweets matching any of the words and shows them" do
|
38
|
+
assert_requested(:get, SEARCH_OR_URL)
|
39
|
+
should_output_tweets
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Scenario "option '-a' is implied unless specified" do
|
44
|
+
When "I start the application with command 'search' and search words" do
|
45
|
+
@output = start_cli %w{-n 2 search braid game}
|
46
|
+
end
|
47
|
+
|
48
|
+
Then "the application requests tweets matching all the words and shows them" do
|
49
|
+
assert_requested(:get, SEARCH_AND_URL)
|
50
|
+
should_output_tweets
|
56
51
|
end
|
57
52
|
end
|
58
53
|
|
@@ -68,4 +63,14 @@ Feature "search tweets" do
|
|
68
63
|
@status.exitstatus.should == CommandLineError.status_code
|
69
64
|
end
|
70
65
|
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def should_output_tweets
|
70
|
+
@output[0].should == "thatswhatshesaid, in reply to hatguy, 5 hours ago:"
|
71
|
+
@output[1].should == "@hatguy braid, perhaps the best indie game of 2009"
|
72
|
+
@output[2].should == ""
|
73
|
+
@output[3].should == "jillv, 11 hours ago:"
|
74
|
+
@output[4].should == "braid is even better than of the games i'm in, expect re4"
|
75
|
+
end
|
71
76
|
end
|
@@ -3,9 +3,9 @@
|
|
3
3
|
require "example_helper"
|
4
4
|
|
5
5
|
Feature "show followers" do
|
6
|
-
in_order_to "to see who follows me"
|
7
6
|
as_a "authenticated user"
|
8
7
|
i_want_to "see my followers"
|
8
|
+
in_order_to "to see who follows me"
|
9
9
|
|
10
10
|
Scenario "show followers" do
|
11
11
|
When "I start the application with 'followers' command" do
|
@@ -3,9 +3,9 @@
|
|
3
3
|
require "example_helper"
|
4
4
|
|
5
5
|
Feature "show friends" do
|
6
|
-
in_order_to "to see who I follow"
|
7
6
|
as_a "authenticated user"
|
8
7
|
i_want_to "see my friends"
|
8
|
+
in_order_to "to see who I follow"
|
9
9
|
|
10
10
|
Scenario "show friends" do
|
11
11
|
When "I start the application with 'followers' command" do
|
@@ -3,54 +3,42 @@
|
|
3
3
|
require "example_helper"
|
4
4
|
|
5
5
|
Feature "show tweets from home timeline" do
|
6
|
-
in_order_to "stay up-to-date of other people's doings"
|
7
6
|
as_a "authenticated user"
|
8
7
|
i_want_to "see my home timeline"
|
8
|
+
in_order_to "stay up-to-date of other people's doings"
|
9
9
|
|
10
10
|
def setup
|
11
11
|
super
|
12
12
|
stub_http_request(:get, "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1").to_return(:body => fixture_file('home.json'))
|
13
13
|
end
|
14
14
|
|
15
|
-
Scenario "
|
16
|
-
When "I start the application with
|
17
|
-
@output = start_cli %w{--no-colors}
|
15
|
+
Scenario "show home timeline" do
|
16
|
+
When "I start the application with 'home' command" do
|
17
|
+
@output = start_cli %w{--no-colors home}
|
18
18
|
end
|
19
19
|
|
20
|
-
Then "the application shows tweets from home timeline
|
21
|
-
|
22
|
-
@output[1].should == "F1-kausi alkaa marraskuussa http://bit.ly/1qQwjQ"
|
23
|
-
@output[2].should == ""
|
24
|
-
@output[58].should == "radar, 15 days ago:"
|
25
|
-
@output[59].should == "Four short links: 29 September 2009 http://bit.ly/dYxay"
|
20
|
+
Then "the application shows tweets from home timeline" do
|
21
|
+
should_output_tweets
|
26
22
|
end
|
27
23
|
end
|
28
24
|
|
29
|
-
Scenario "
|
25
|
+
Scenario "show home timeline is default command" do
|
30
26
|
When "I start the application with no command" do
|
31
|
-
@output = start_cli %w{--colors}
|
27
|
+
@output = start_cli %w{--no-colors}
|
32
28
|
end
|
33
29
|
|
34
|
-
Then "the application shows tweets from home timeline
|
35
|
-
|
36
|
-
@output[1].should == "F1-kausi alkaa marraskuussa \e[36mhttp://bit.ly/1qQwjQ\e[0m"
|
37
|
-
@output[2].should == ""
|
38
|
-
@output[58].should == "\e[32mradar\e[0m, 15 days ago:"
|
39
|
-
@output[59].should == "Four short links: 29 September 2009 \e[36mhttp://bit.ly/dYxay\e[0m"
|
30
|
+
Then "the application shows tweets from home timeline" do
|
31
|
+
should_output_tweets
|
40
32
|
end
|
41
33
|
end
|
42
34
|
|
43
|
-
|
44
|
-
When "I start the application with 'home' command" do
|
45
|
-
@output = start_cli %w{--no-colors home}
|
46
|
-
end
|
35
|
+
private
|
47
36
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
37
|
+
def should_output_tweets
|
38
|
+
@output[0].should == "pelit, 11 days ago:"
|
39
|
+
@output[1].should == "F1-kausi alkaa marraskuussa http://bit.ly/1qQwjQ"
|
40
|
+
@output[2].should == ""
|
41
|
+
@output[58].should == "radar, 15 days ago:"
|
42
|
+
@output[59].should == "Four short links: 29 September 2009 http://bit.ly/dYxay"
|
55
43
|
end
|
56
44
|
end
|
@@ -3,9 +3,9 @@
|
|
3
3
|
require "example_helper"
|
4
4
|
|
5
5
|
Feature "show tweets mentioning the user" do
|
6
|
-
in_order_to "know if someone has mentioned me"
|
7
6
|
as_a "authenticated user"
|
8
|
-
i_want_to "see
|
7
|
+
i_want_to "see tweets mentioning me"
|
8
|
+
in_order_to "know if someone has replied or otherwise mentioned me"
|
9
9
|
|
10
10
|
Scenario "show tweets mentioning me" do
|
11
11
|
When "I start the application with 'mentions' command" do
|