tweetwine 0.4.2 → 0.4.3
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/CHANGELOG.rdoc +5 -0
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/Rakefile +5 -0
- data/benchmark/home_bm.rb +36 -0
- data/lib/tweetwine/character_encoding.rb +1 -1
- data/lib/tweetwine/http.rb +1 -1
- data/lib/tweetwine/support.rb +28 -26
- data/lib/tweetwine/twitter.rb +8 -5
- data/lib/tweetwine/version.rb +1 -1
- data/lib/tweetwine.rb +0 -2
- data/man/tweetwine.7 +3 -3
- data/man/tweetwine.7.ronn +2 -2
- data/project.rb +2 -0
- data/test/fixture/config_integration.yaml +1 -1
- data/test/integration/authorization_test.rb +1 -1
- data/test/integration/global_options_test.rb +1 -1
- data/test/integration/invalid_config_file_test.rb +1 -1
- data/test/integration/search_statuses_test.rb +1 -1
- data/test/integration/show_followers_test.rb +1 -1
- data/test/integration/show_friends_test.rb +1 -1
- data/test/integration/show_home_test.rb +1 -1
- data/test/integration/show_mentions_test.rb +1 -1
- data/test/integration/show_user_test.rb +1 -1
- data/test/integration/update_status_test.rb +42 -21
- data/test/integration/use_http_proxy_test.rb +6 -6
- data/test/integration/user_help_test.rb +2 -2
- data/test/support/assertions.rb +58 -0
- data/test/support/common.rb +10 -0
- data/test/support/common_helpers.rb +43 -0
- data/test/support/doubles.rb +35 -0
- data/test/{integration/helper.rb → support/integration_test_case.rb} +12 -7
- data/test/support/mocha_integration.rb +16 -0
- data/test/support/tweets.rb +95 -0
- data/test/support/unit_test_case.rb +28 -0
- data/test/support/webmock_integration.rb +16 -0
- data/test/unit/character_encoding_test.rb +1 -1
- data/test/unit/cli_test.rb +4 -4
- data/test/unit/config_test.rb +1 -1
- data/test/unit/http_test.rb +1 -1
- data/test/unit/oauth_test.rb +1 -1
- data/test/unit/obfuscate_test.rb +1 -1
- data/test/unit/option_parser_test.rb +1 -1
- data/test/unit/promise_test.rb +1 -1
- data/test/unit/support_test.rb +1 -1
- data/test/unit/tweet_test.rb +3 -3
- data/test/unit/twitter_test.rb +29 -27
- data/test/unit/ui_test.rb +3 -3
- data/test/unit/uri_test.rb +1 -1
- data/test/unit/url_shortener_test.rb +1 -1
- data/tweetwine.gemspec +5 -4
- metadata +122 -97
- data/test/helper.rb +0 -60
- data/test/unit/helper.rb +0 -108
- data/test/unit/tweet_helper.rb +0 -95
data/CHANGELOG.rdoc
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -24,7 +24,7 @@ Install Tweetwine with RubyGems:
|
|
24
24
|
|
25
25
|
$ gem install tweetwine
|
26
26
|
|
27
|
-
The program is tested with
|
27
|
+
The program is tested with MRI 1.8.7, 1.9.2, and 1.9.3.
|
28
28
|
|
29
29
|
The program requires [oauth](http://oauth.rubyforge.org/) gem to be installed.
|
30
30
|
In addition, the program needs a JSON parser library, such as
|
@@ -81,7 +81,7 @@ enabled via `shorten_urls` field in the configuration file; for example:
|
|
81
81
|
shorten_urls:
|
82
82
|
service_url: http://is.gd/create.php
|
83
83
|
method: post
|
84
|
-
url_param_name:
|
84
|
+
url_param_name: url
|
85
85
|
xpath_selector: //input[@id='short_url']/@value
|
86
86
|
disable: false # optional
|
87
87
|
|
data/Rakefile
CHANGED
@@ -80,6 +80,11 @@ namespace :test do
|
|
80
80
|
task :all => [:unit, :integration]
|
81
81
|
end
|
82
82
|
|
83
|
+
desc "Profile fetching home timeline"
|
84
|
+
task :profile do
|
85
|
+
sh %{bundle exec ruby -I lib -I test benchmark/home_bm.rb}
|
86
|
+
end
|
87
|
+
|
83
88
|
desc "Find code smells"
|
84
89
|
task :roodi do
|
85
90
|
sh %{roodi "**/*.rb"}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'tweetwine'
|
5
|
+
require 'perftools'
|
6
|
+
require 'support/common_helpers'
|
7
|
+
require 'webmock'
|
8
|
+
|
9
|
+
WebMock.disable_net_connect!
|
10
|
+
|
11
|
+
module Driver
|
12
|
+
extend WebMock::API
|
13
|
+
extend Tweetwine::Test::CommonHelpers
|
14
|
+
|
15
|
+
def self.run
|
16
|
+
stub_http_request(:get, "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1").to_return(:body => fixture_file('home.json'))
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
WebMock.reset!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Driver.run do
|
24
|
+
output_path = "/tmp/tweetwine_home_bm"
|
25
|
+
|
26
|
+
PerfTools::CpuProfiler.start(output_path) do
|
27
|
+
1_000.times do
|
28
|
+
Tweetwine::CLI.start %w{home}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
system %{pprof.rb --gif #{output_path} > #{output_path}.gif}
|
33
|
+
|
34
|
+
puts "Profiling output: #{output_path}"
|
35
|
+
puts "Visualization: #{output_path}.gif"
|
36
|
+
end
|
data/lib/tweetwine/http.rb
CHANGED
@@ -17,7 +17,7 @@ module Tweetwine
|
|
17
17
|
if retries < max_retries
|
18
18
|
retries += 1
|
19
19
|
timeout = retry_base_wait_timeout**retries
|
20
|
-
CLI.ui.warn
|
20
|
+
CLI.ui.warn "Could not connect -- retrying in #{timeout} seconds"
|
21
21
|
sleep timeout
|
22
22
|
retry
|
23
23
|
else
|
data/lib/tweetwine/support.rb
CHANGED
@@ -36,15 +36,15 @@ module Tweetwine
|
|
36
36
|
else [(difference/86400.0).round, "day"]
|
37
37
|
end
|
38
38
|
|
39
|
-
[value, pluralize_unit(value, unit)]
|
39
|
+
[value, Helper.pluralize_unit(value, unit)]
|
40
40
|
end
|
41
41
|
|
42
42
|
def stringify_hash_keys(hash)
|
43
|
-
recursive_copy_hash(hash) { |key, value| [key.to_s, value] }
|
43
|
+
Helper.recursive_copy_hash(hash) { |key, value| [key.to_s, value] }
|
44
44
|
end
|
45
45
|
|
46
46
|
def symbolize_hash_keys(hash)
|
47
|
-
recursive_copy_hash(hash) { |key, value| [key.to_sym, value] }
|
47
|
+
Helper.recursive_copy_hash(hash) { |key, value| [key.to_sym, value] }
|
48
48
|
end
|
49
49
|
|
50
50
|
def parse_int_gt(value, default, min, name_for_error)
|
@@ -64,7 +64,7 @@ module Tweetwine
|
|
64
64
|
dup_str = str.dup
|
65
65
|
str_pos, dup_pos = 0, 0
|
66
66
|
while str_pos < str.size && (match_data = regexp.match(str[str_pos..-1]))
|
67
|
-
matching_group_indexes = indexes_of_filled_matches(match_data)
|
67
|
+
matching_group_indexes = Helper.indexes_of_filled_matches(match_data)
|
68
68
|
|
69
69
|
matching_group_indexes.each do |i|
|
70
70
|
replacement = (yield match_data[i]).to_s
|
@@ -93,30 +93,32 @@ module Tweetwine
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
96
|
+
module Helper
|
97
|
+
class << self
|
98
|
+
def recursive_copy_hash(hash, &pair_modifier)
|
99
|
+
hash.inject({}) do |result, pair|
|
100
|
+
value = pair.last
|
101
|
+
value = recursive_copy_hash(value, &pair_modifier) if value.is_a? Hash
|
102
|
+
key, value = pair_modifier.call(pair.first, value)
|
103
|
+
result[key] = value
|
104
|
+
result
|
105
|
+
end
|
106
|
+
end
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
108
|
+
def pluralize_unit(value, unit)
|
109
|
+
if %w{hour day}.include?(unit) && value > 1
|
110
|
+
unit = unit + 's'
|
111
|
+
end
|
112
|
+
unit
|
113
|
+
end
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
def indexes_of_filled_matches(match_data)
|
116
|
+
if match_data.size > 1
|
117
|
+
(1...match_data.size).to_a.reject { |i| match_data[i].nil? }
|
118
|
+
else
|
119
|
+
[0]
|
120
|
+
end
|
121
|
+
end
|
120
122
|
end
|
121
123
|
end
|
122
124
|
end
|
data/lib/tweetwine/twitter.rb
CHANGED
@@ -184,8 +184,8 @@ module Tweetwine
|
|
184
184
|
status.dup
|
185
185
|
end
|
186
186
|
status.strip!
|
187
|
-
shorten_urls_in
|
188
|
-
truncate_status
|
187
|
+
shorten_urls_in status if CLI.config[:shorten_urls] && !CLI.config[:shorten_urls][:disable]
|
188
|
+
truncate_status status if status.length > MAX_STATUS_LENGTH
|
189
189
|
status
|
190
190
|
end
|
191
191
|
|
@@ -193,9 +193,12 @@ module Tweetwine
|
|
193
193
|
url_pairs = Uri.
|
194
194
|
extract(status, %w{http https}).
|
195
195
|
uniq.
|
196
|
-
map { |
|
197
|
-
|
198
|
-
|
196
|
+
map { |url| [ url, CLI.url_shortener.shorten(url) ] }
|
197
|
+
failed, succeeded = *url_pairs.partition do |(full_url, short_url)|
|
198
|
+
Support.blank? short_url or full_url == short_url
|
199
|
+
end
|
200
|
+
failed.each { |(full_url, _)| CLI.ui.warn "No short URL for #{full_url}" }
|
201
|
+
succeeded.each { |(full_url, short_url)| status.gsub! full_url, short_url }
|
199
202
|
rescue HttpError, LoadError => e
|
200
203
|
CLI.ui.warn "#{e}\nSkipping URL shortening..."
|
201
204
|
end
|
data/lib/tweetwine/version.rb
CHANGED
data/lib/tweetwine.rb
CHANGED
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" "November 2011" "Tuomas Kareinen" "Tweetwine Manual"
|
5
5
|
.
|
6
6
|
.SH "DESCRIPTION"
|
7
7
|
Tweetwine shows the latest tweets from the command line quickly\.
|
@@ -40,7 +40,7 @@ $ gem install tweetwine
|
|
40
40
|
.IP "" 0
|
41
41
|
.
|
42
42
|
.P
|
43
|
-
The program is tested with
|
43
|
+
The program is tested with MRI 1\.8\.7, 1\.9\.2, and 1\.9\.3\.
|
44
44
|
.
|
45
45
|
.P
|
46
46
|
The program requires oauth \fIhttp://oauth\.rubyforge\.org/\fR gem to be installed\. In addition, the program needs a JSON parser library, such as json \fIhttp://json\.rubyforge\.org/\fR gem, on Ruby 1\.8\.
|
@@ -130,7 +130,7 @@ show_reverse: true
|
|
130
130
|
shorten_urls:
|
131
131
|
service_url: http://is\.gd/create\.php
|
132
132
|
method: post
|
133
|
-
url_param_name:
|
133
|
+
url_param_name: url
|
134
134
|
xpath_selector: //input[@id=\'short_url\']/@value
|
135
135
|
disable: false # optional
|
136
136
|
.
|
data/man/tweetwine.7.ronn
CHANGED
@@ -24,7 +24,7 @@ Install Tweetwine with RubyGems:
|
|
24
24
|
|
25
25
|
$ gem install tweetwine
|
26
26
|
|
27
|
-
The program is tested with
|
27
|
+
The program is tested with MRI 1.8.7, 1.9.2, and 1.9.3.
|
28
28
|
|
29
29
|
The program requires [oauth](http://oauth.rubyforge.org/) gem to be installed.
|
30
30
|
In addition, the program needs a JSON parser library, such as
|
@@ -81,7 +81,7 @@ enabled via `shorten_urls` field in the configuration file; for example:
|
|
81
81
|
shorten_urls:
|
82
82
|
service_url: http://is.gd/create.php
|
83
83
|
method: post
|
84
|
-
url_param_name:
|
84
|
+
url_param_name: url
|
85
85
|
xpath_selector: //input[@id='short_url']/@value
|
86
86
|
disable: false # optional
|
87
87
|
|
data/project.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
name = 'tweetwine'
|
4
|
+
# Add lib dir to $LOAD_PATH so that `require 'tweetwine/version'`
|
5
|
+
# (executed in tests) loads the version file only once on MRI 1.8.7.
|
4
6
|
$LOAD_PATH.unshift File.expand_path('lib', File.dirname(__FILE__))
|
5
7
|
require "#{name}/version"
|
6
8
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'support/integration_test_case'
|
4
4
|
require 'yaml'
|
5
5
|
|
6
6
|
module Tweetwine::Test::Integration
|
@@ -8,17 +8,14 @@ module Tweetwine::Test::Integration
|
|
8
8
|
class UpdateStatusTest < TestCase
|
9
9
|
RUBYGEMS_FIXTURE = fixture_file 'shorten_rubygems.html'
|
10
10
|
RUBYGEMS_FULL_URL = 'http://rubygems.org/'
|
11
|
-
RUBYGEMS_FULL_URL_ENC = 'http%3a%2f%2frubygems.org%2f'
|
12
11
|
RUBYGEMS_SHORT_URL = 'http://is.gd/gGazV'
|
13
|
-
RUBYGEMS_SHORT_URL_ENC = 'http%3a%2f%2fis.gd%2fgGazV'
|
14
12
|
RUBYLANG_FIXTURE = fixture_file 'shorten_rubylang.html'
|
15
13
|
RUBYLANG_FULL_URL = 'http://ruby-lang.org/'
|
16
|
-
RUBYLANG_FULL_URL_ENC = 'http%3a%2f%2fruby-lang.org%2f'
|
17
14
|
RUBYLANG_SHORT_URL = 'http://is.gd/gGaM3'
|
18
|
-
RUBYLANG_SHORT_URL_ENC = 'http%3a%2f%2fis.gd%2fgGaM3'
|
19
15
|
SHORTEN_CONFIG = read_shorten_config
|
20
16
|
SHORTEN_METHOD = SHORTEN_CONFIG[:method].to_sym
|
21
17
|
STATUS_WITH_FULL_URLS = "ruby links: #{RUBYGEMS_FULL_URL} #{RUBYLANG_FULL_URL}"
|
18
|
+
STATUS_WITH_MIXED_URLS = "ruby links: #{RUBYGEMS_SHORT_URL} #{RUBYLANG_FULL_URL}"
|
22
19
|
STATUS_WITH_SHORT_URLS = "ruby links: #{RUBYGEMS_SHORT_URL} #{RUBYLANG_SHORT_URL}"
|
23
20
|
STATUS_WITHOUT_URLS = "bored. going to sleep."
|
24
21
|
UPDATE_FIXTURE_WITH_URLS = fixture_file 'update_with_urls.json'
|
@@ -26,8 +23,9 @@ class UpdateStatusTest < TestCase
|
|
26
23
|
UPDATE_FIXTURE_UTF8 = fixture_file 'update_utf8.json'
|
27
24
|
UPDATE_URL = "https://api.twitter.com/1/statuses/update.json"
|
28
25
|
|
29
|
-
BODY_WITH_SHORT_URLS =
|
30
|
-
|
26
|
+
BODY_WITH_SHORT_URLS = { 'status' => STATUS_WITH_SHORT_URLS }
|
27
|
+
BODY_WITH_MIXED_URLS = { 'status' => STATUS_WITH_MIXED_URLS }
|
28
|
+
BODY_WITHOUT_URLS = { 'status' => STATUS_WITHOUT_URLS }
|
31
29
|
|
32
30
|
describe "update my status from command line with colorization disabled" do
|
33
31
|
before do
|
@@ -111,8 +109,7 @@ class UpdateStatusTest < TestCase
|
|
111
109
|
before do
|
112
110
|
@status_utf8 = "résumé"
|
113
111
|
@status_latin1 = @status_utf8.encode('ISO-8859-1')
|
114
|
-
|
115
|
-
stub_http_request(:post, UPDATE_URL).with(:body => url_encoded_body).to_return(:body => UPDATE_FIXTURE_UTF8)
|
112
|
+
stub_http_request(:post, UPDATE_URL).with(:body => { 'status' => @status_utf8 }).to_return(:body => UPDATE_FIXTURE_UTF8)
|
116
113
|
at_snapshot do
|
117
114
|
@output = start_cli %W{--no-colors update #{@status_latin1}}, %w{y}
|
118
115
|
end
|
@@ -131,8 +128,7 @@ class UpdateStatusTest < TestCase
|
|
131
128
|
before do
|
132
129
|
@status_latin1 = "r\xe9sum\xe9"
|
133
130
|
@status_utf8 = "r\xc3\xa9sum\xc3\xa9"
|
134
|
-
|
135
|
-
stub_http_request(:post, UPDATE_URL).with(:body => url_encoded_body).to_return(:body => UPDATE_FIXTURE_UTF8)
|
131
|
+
stub_http_request(:post, UPDATE_URL).with(:body => { 'status' => @status_utf8 }).to_return(:body => UPDATE_FIXTURE_UTF8)
|
136
132
|
tmp_kcode('NONE') do
|
137
133
|
tmp_env(:LANG => 'latin1') do
|
138
134
|
Tweetwine::CharacterEncoding.forget_guess
|
@@ -153,14 +149,7 @@ class UpdateStatusTest < TestCase
|
|
153
149
|
|
154
150
|
describe "shorten URLs in status update" do
|
155
151
|
before do
|
156
|
-
|
157
|
-
@shorten_rubylang_body = "#{SHORTEN_CONFIG[:url_param_name]}=#{RUBYLANG_FULL_URL_ENC}"
|
158
|
-
stub_http_request(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url]).
|
159
|
-
with(:body => @shorten_rubygems_body).
|
160
|
-
to_return(:body => RUBYGEMS_FIXTURE)
|
161
|
-
stub_http_request(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url]).
|
162
|
-
with(:body => @shorten_rubylang_body).
|
163
|
-
to_return(:body => RUBYLANG_FIXTURE)
|
152
|
+
stub_url_shortening(:rubygems => RUBYGEMS_FIXTURE, :rubylang => RUBYLANG_FIXTURE)
|
164
153
|
stub_http_request(:post, UPDATE_URL).
|
165
154
|
with(:body => BODY_WITH_SHORT_URLS).
|
166
155
|
to_return(:body => UPDATE_FIXTURE_WITH_URLS)
|
@@ -170,14 +159,31 @@ class UpdateStatusTest < TestCase
|
|
170
159
|
end
|
171
160
|
|
172
161
|
it "shortens the URLs in the status before sending it" do
|
173
|
-
assert_requested(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url], :body => @
|
174
|
-
assert_requested(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url], :body => @
|
162
|
+
assert_requested(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url], :body => @request_bodies[:rubygems])
|
163
|
+
assert_requested(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url], :body => @request_bodies[:rubylang])
|
175
164
|
@output[1].must_equal STATUS_WITH_SHORT_URLS
|
176
165
|
@output[5].must_equal "#{USER}, 9 hours ago:"
|
177
166
|
@output[6].must_equal STATUS_WITH_SHORT_URLS
|
178
167
|
end
|
179
168
|
end
|
180
169
|
|
170
|
+
describe "warn if URL shortening results in no shortened URL in status update" do
|
171
|
+
before do
|
172
|
+
stub_url_shortening(:rubygems => RUBYGEMS_FIXTURE, :rubylang => '')
|
173
|
+
stub_http_request(:post, UPDATE_URL).
|
174
|
+
with(:body => BODY_WITH_MIXED_URLS).
|
175
|
+
to_return(:body => UPDATE_FIXTURE_WITH_URLS)
|
176
|
+
at_snapshot do
|
177
|
+
@output = start_cli %W{--no-colors update #{STATUS_WITH_FULL_URLS}}, %w{y}
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
it "warns which URL was not shortened, falling back to using the original URL" do
|
182
|
+
@output[0].must_equal "Warning: No short URL for #{RUBYLANG_FULL_URL}"
|
183
|
+
@output[2].must_equal STATUS_WITH_MIXED_URLS
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
181
187
|
describe "disable URL shortening for status updates" do
|
182
188
|
before do
|
183
189
|
stub_http_request(:post, UPDATE_URL).
|
@@ -194,6 +200,21 @@ class UpdateStatusTest < TestCase
|
|
194
200
|
@output[6].must_equal STATUS_WITH_SHORT_URLS
|
195
201
|
end
|
196
202
|
end
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def stub_url_shortening(response_bodies)
|
207
|
+
@request_bodies = {
|
208
|
+
:rubygems => { SHORTEN_CONFIG[:url_param_name] => RUBYGEMS_FULL_URL },
|
209
|
+
:rubylang => { SHORTEN_CONFIG[:url_param_name] => RUBYLANG_FULL_URL }
|
210
|
+
}
|
211
|
+
stub_http_request(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url]).
|
212
|
+
with(:body => @request_bodies[:rubygems]).
|
213
|
+
to_return(:body => response_bodies[:rubygems])
|
214
|
+
stub_http_request(SHORTEN_METHOD, SHORTEN_CONFIG[:service_url]).
|
215
|
+
with(:body => @request_bodies[:rubylang]).
|
216
|
+
to_return(:body => response_bodies[:rubylang])
|
217
|
+
end
|
197
218
|
end
|
198
219
|
|
199
220
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'support/integration_test_case'
|
4
4
|
|
5
5
|
module Tweetwine::Test::Integration
|
6
6
|
|
@@ -22,7 +22,7 @@ class UseHttpProxyTest < TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "uses the proxy to fetch my home timeline" do
|
25
|
-
|
25
|
+
assert_use_proxy
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -33,7 +33,7 @@ class UseHttpProxyTest < TestCase
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "uses the proxy to fetch my home timeline" do
|
36
|
-
|
36
|
+
assert_use_proxy
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -50,16 +50,16 @@ class UseHttpProxyTest < TestCase
|
|
50
50
|
|
51
51
|
private
|
52
52
|
|
53
|
-
def
|
53
|
+
def assert_use_proxy
|
54
54
|
nh = net_http
|
55
|
-
nh.proxy_class
|
55
|
+
assert nh.proxy_class?
|
56
56
|
nh.instance_variable_get(:@proxy_address).must_equal PROXY_HOST
|
57
57
|
nh.instance_variable_get(:@proxy_port).must_equal PROXY_PORT
|
58
58
|
assert_requested(:get, HOME_URL)
|
59
59
|
end
|
60
60
|
|
61
61
|
def refute_use_proxy
|
62
|
-
net_http.proxy_class
|
62
|
+
refute net_http.proxy_class?
|
63
63
|
assert_requested(:get, HOME_URL)
|
64
64
|
end
|
65
65
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'support/integration_test_case'
|
4
4
|
|
5
5
|
module Tweetwine::Test::Integration
|
6
6
|
|
@@ -14,7 +14,7 @@ class UserHelpTest < TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "shows version and exists with success status" do
|
17
|
-
@output.must_match(/\d+\.\d+\.\d
|
17
|
+
@output.must_match(/\d+\.\d+\.\d+[\w\.]*$/)
|
18
18
|
@status.exitstatus.must_equal 0
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Tweetwine::Test
|
4
|
+
module Assertions
|
5
|
+
# Asserts whether an Enumeration-like object contains all the elements.
|
6
|
+
# Fails unless +actual+ contains the same elements as +expected+,
|
7
|
+
# ignoring the order of the elements.
|
8
|
+
def assert_contains_exactly(expected, actual, msg_diff_size = nil, msg_diff_elems = nil)
|
9
|
+
assert_equal(expected.size, actual.size, message(msg_diff_size) {
|
10
|
+
'Expected %s to be of same size as %s' % [actual.inspect, expected.inspect]
|
11
|
+
})
|
12
|
+
assert(Assertions.enumerable_minus_each_element(actual, expected).empty?, message(msg_diff_elems) {
|
13
|
+
'Expected %s to contain all the elements of %s' % [actual.inspect, expected.inspect]
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
# Fails unless +str+ is a full match to +regex+.
|
18
|
+
def assert_full_match(regex, str, msg = nil)
|
19
|
+
match_data = regex.match(str)
|
20
|
+
assert(str == match_data.to_s, message(msg) {
|
21
|
+
'Expected %s to be a full match to %s' % [str, regex.inspect]
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
# Fails if +str+ is a full match to +regex+.
|
26
|
+
def assert_no_full_match(regex, str, msg = nil)
|
27
|
+
match_data = regex.match(str)
|
28
|
+
assert(str != match_data.to_s, message(msg) {
|
29
|
+
'Expected %s not to be a full match to %s' % [str, regex.inspect]
|
30
|
+
})
|
31
|
+
end
|
32
|
+
|
33
|
+
# Fails unless +fun.call(*args)+ is equal to +expected+ and
|
34
|
+
# +fun.call(*args)+ is equal to +fun.call(*args.reverse)+.
|
35
|
+
def assert_commutative(expected, args, msg_not_expected = nil, msg_not_commutative = nil, &fun)
|
36
|
+
left_args = args
|
37
|
+
left_actual = fun.call(left_args)
|
38
|
+
assert_equal(expected, left_actual, message(msg_not_expected) {
|
39
|
+
'Expected %s, not %s' % [expected.inspect, left_actual.inspect]
|
40
|
+
})
|
41
|
+
right_args = args.reverse
|
42
|
+
right_actual = fun.call(*right_args)
|
43
|
+
assert_equal(left_actual, right_actual, message(msg_not_commutative) {
|
44
|
+
'Expected fun%s => %s to be commutative with fun%s => %s' %
|
45
|
+
[left_args.inspect, left_actual.inspect, right_args.inspect, right_actual.inspect]
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.enumerable_minus_each_element(enumerable, elements)
|
50
|
+
remaining = enumerable.dup.to_a
|
51
|
+
elements.each do |e|
|
52
|
+
index = remaining.index(e)
|
53
|
+
remaining.delete_at(index) if index
|
54
|
+
end
|
55
|
+
remaining
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|