tweetwine 0.4.0 → 0.4.1
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/.gitignore +1 -0
- data/CHANGELOG.rdoc +5 -0
- data/{release-script.txt → RELEASING.txt} +0 -0
- data/Rakefile +19 -19
- data/lib/tweetwine/http.rb +1 -3
- data/lib/tweetwine/ui.rb +2 -1
- data/lib/tweetwine/version.rb +1 -1
- data/project.rb +30 -0
- data/test/unit/config_test.rb +2 -5
- data/test/unit/http_test.rb +6 -5
- data/test/unit/promise_test.rb +2 -0
- data/test/unit/support_test.rb +71 -32
- data/test/unit/tweet_helper.rb +13 -1
- data/test/unit/tweet_test.rb +1 -1
- data/test/unit/ui_test.rb +109 -88
- data/test/unit/unit_helper.rb +37 -15
- data/test/unit/uri_test.rb +2 -2
- data/tweetwine.gemspec +12 -22
- metadata +77 -8
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
CHANGED
File without changes
|
data/Rakefile
CHANGED
@@ -1,51 +1,51 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require File.expand_path('project', File.dirname(__FILE__))
|
4
4
|
|
5
|
-
|
6
|
-
name = 'tweetwine'
|
7
|
-
require "#{name}/version"
|
8
|
-
version = Tweetwine.version
|
5
|
+
require 'rake/clean'
|
9
6
|
|
10
7
|
namespace :gem do
|
11
|
-
CLOBBER.include "#{name}-*.gem"
|
8
|
+
CLOBBER.include "#{Project.name}-*.gem"
|
12
9
|
|
13
|
-
|
14
|
-
|
10
|
+
current_gem = "#{Project.name}-#{Project.version}.gem"
|
11
|
+
|
12
|
+
file current_gem do |f|
|
13
|
+
sh %{gem build #{Project.name}.gemspec}
|
15
14
|
end
|
16
15
|
|
17
16
|
desc "Package the software as a gem"
|
18
|
-
task :build => [:"man:build", :"test:all",
|
17
|
+
task :build => [:"man:build", :"test:all", current_gem]
|
19
18
|
|
20
19
|
desc "Install the software as a gem"
|
21
20
|
task :install => :build do
|
22
|
-
sh %{gem install #{
|
21
|
+
sh %{gem install #{current_gem}}
|
23
22
|
end
|
24
23
|
|
25
24
|
desc "Uninstall the gem"
|
26
25
|
task :uninstall => :clean do
|
27
|
-
sh %{gem uninstall #{name}}
|
26
|
+
sh %{gem uninstall #{Project.name}}
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
30
|
namespace :man do
|
32
|
-
CLOBBER.include "man/#{name}.?", "man/#{name}.?.html"
|
31
|
+
CLOBBER.include "#{Project.dirs.man}/#{Project.name}.?", "#{Project.dirs.man}/#{Project.name}.?.html"
|
33
32
|
|
34
33
|
desc "Build the manual"
|
35
34
|
task :build do
|
36
|
-
sh
|
35
|
+
sh %{ronn -br5 --manual='#{Project.name.capitalize} Manual' --organization='#{Project.authors.first}' #{Project.dirs.man}/*.ronn}
|
37
36
|
end
|
38
37
|
|
39
38
|
desc "Show the manual section 7"
|
40
39
|
task :show => :build do
|
41
|
-
sh
|
40
|
+
sh %{man #{Project.dirs.man}/#{Project.name}.7}
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
|
-
CLOBBER.include
|
44
|
+
CLOBBER.include Project.dirs.rdoc
|
45
|
+
|
46
46
|
desc "Generate RDoc"
|
47
47
|
task :rdoc do
|
48
|
-
sh %{rdoc --encoding=UTF-8 --line-numbers --title='#{
|
48
|
+
sh %{rdoc --encoding=UTF-8 --line-numbers --title='#{Project.title}' --output=#{Project.dirs.rdoc} *.rdoc LICENSE.txt lib}
|
49
49
|
end
|
50
50
|
|
51
51
|
namespace :test do
|
@@ -53,7 +53,7 @@ namespace :test do
|
|
53
53
|
base_dir = options[:base_dir]
|
54
54
|
file_glob = options[:file_glob]
|
55
55
|
test_desc = options[:desc] || "Run #{type} tests"
|
56
|
-
includes = ['lib',
|
56
|
+
includes = ['lib', Project.dirs.test, base_dir].map { |dir| "-I #{dir}" }.join(' ')
|
57
57
|
warn_opt = options[:warn] ? '-w' : ''
|
58
58
|
|
59
59
|
desc test_desc
|
@@ -68,11 +68,11 @@ namespace :test do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
create_test_task :unit,
|
71
|
-
:base_dir =>
|
71
|
+
:base_dir => "#{Project.dirs.test}/unit",
|
72
72
|
:file_glob => '**/*_test.rb',
|
73
73
|
:warn => true
|
74
74
|
create_test_task :example,
|
75
|
-
:base_dir =>
|
75
|
+
:base_dir => "#{Project.dirs.test}/example",
|
76
76
|
:file_glob => '**/*_example.rb',
|
77
77
|
:desc => 'Run integration/example tests',
|
78
78
|
:warn => false
|
data/lib/tweetwine/http.rb
CHANGED
@@ -80,12 +80,10 @@ module Tweetwine
|
|
80
80
|
response = yield connection, uri
|
81
81
|
raise HttpError.new(response.code, response.message) unless response.is_a? Net::HTTPSuccess
|
82
82
|
response.body
|
83
|
-
rescue Errno::ECONNABORTED, Errno::ECONNRESET => e
|
83
|
+
rescue Errno::ECONNABORTED, Errno::ECONNRESET, SocketError => e
|
84
84
|
raise ConnectionError, e
|
85
85
|
rescue Timeout::Error => e
|
86
86
|
raise TimeoutError, e
|
87
|
-
rescue Net::HTTPError => e
|
88
|
-
raise HttpError, e
|
89
87
|
end
|
90
88
|
|
91
89
|
def https_scheme?(uri)
|
data/lib/tweetwine/ui.rb
CHANGED
@@ -10,6 +10,7 @@ module Tweetwine
|
|
10
10
|
}.freeze
|
11
11
|
HASHTAG_REGEX = /#[\w-]+/
|
12
12
|
USERNAME_REGEX = /^(@\w+)|\s+(@\w+)/
|
13
|
+
URI_SCHEMES_TO_COLORIZE = %w{http https}
|
13
14
|
|
14
15
|
def initialize(options = {})
|
15
16
|
@in = options[:in] || $stdin
|
@@ -96,7 +97,7 @@ module Tweetwine
|
|
96
97
|
if @colors
|
97
98
|
status = colorize_matching(:yellow, status, USERNAME_REGEX)
|
98
99
|
status = colorize_matching(:magenta, status, HASHTAG_REGEX)
|
99
|
-
status = colorize_matching(:cyan, status, Uri.extract(status,
|
100
|
+
status = colorize_matching(:cyan, status, Uri.extract(status, URI_SCHEMES_TO_COLORIZE).uniq)
|
100
101
|
end
|
101
102
|
status
|
102
103
|
end
|
data/lib/tweetwine/version.rb
CHANGED
data/project.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
name = 'tweetwine'
|
6
|
+
$LOAD_PATH.unshift File.expand_path('lib', File.dirname(__FILE__))
|
7
|
+
require "#{name}/version"
|
8
|
+
|
9
|
+
Project = OpenStruct.new({
|
10
|
+
:name => name,
|
11
|
+
:version => Tweetwine.version.dup,
|
12
|
+
:summary => Tweetwine.summary,
|
13
|
+
:description => '',
|
14
|
+
:email => 'tkareine@gmail.com',
|
15
|
+
:homepage => 'https://github.com/tkareine/tweetwine',
|
16
|
+
:authors => ['Tuomas Kareinen'],
|
17
|
+
:dirs => OpenStruct.new({
|
18
|
+
:man => 'man',
|
19
|
+
:rdoc => 'rdoc',
|
20
|
+
:test => 'test'
|
21
|
+
}).freeze
|
22
|
+
})
|
23
|
+
|
24
|
+
Project.description = <<-END
|
25
|
+
A simple but tasty Twitter agent for command line use, designed for quickly
|
26
|
+
showing the latest tweets.
|
27
|
+
END
|
28
|
+
Project.title = "#{Project.name} #{Project.version}"
|
29
|
+
|
30
|
+
Project.freeze
|
data/test/unit/config_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "unit_helper"
|
4
4
|
|
5
5
|
require "fileutils"
|
6
6
|
require "tempfile"
|
@@ -190,10 +190,7 @@ class ConfigTest < UnitTestCase
|
|
190
190
|
end
|
191
191
|
|
192
192
|
should "ignore nonexisting config file for initial read" do
|
193
|
-
assert_contains_exactly
|
194
|
-
# On Ruby 1.8, Symbol does not have #<=> operator for comparison.
|
195
|
-
a.to_s <=> b.to_s
|
196
|
-
end
|
193
|
+
assert_contains_exactly @default_config.keys, @config.keys
|
197
194
|
end
|
198
195
|
|
199
196
|
should "save config to the file, implicitly without config file, env lookouts, and excludes set itself" do
|
data/test/unit/http_test.rb
CHANGED
@@ -79,17 +79,18 @@ class HttpTest < UnitTestCase
|
|
79
79
|
end
|
80
80
|
|
81
81
|
[
|
82
|
-
[Errno::ECONNABORTED, 'abort'],
|
83
|
-
[Errno::ECONNRESET, 'reset']
|
84
|
-
|
85
|
-
|
82
|
+
[Errno::ECONNABORTED, 'connection abort'],
|
83
|
+
[Errno::ECONNRESET, 'connection reset'],
|
84
|
+
[SocketError, 'socket error']
|
85
|
+
].each do |(error, desc)|
|
86
|
+
should "retry connection upon #{desc} to #{method} request" do
|
86
87
|
stub_request(method, LATEST_ARTICLES_URL).to_raise(error).then.to_return(:body => RESPONSE_BODY)
|
87
88
|
@ui.expects(:warn).with("Could not connect -- retrying in 4 seconds")
|
88
89
|
@client.send(method, LATEST_ARTICLES_URL)
|
89
90
|
assert_equal(RESPONSE_BODY, @client.send(method, LATEST_ARTICLES_URL))
|
90
91
|
end
|
91
92
|
|
92
|
-
should "retry connection a maximum of certain number of times upon
|
93
|
+
should "retry connection a maximum of certain number of times upon #{desc} to #{method} request" do
|
93
94
|
stub_request(method, LATEST_ARTICLES_URL).to_raise(error)
|
94
95
|
io_calls = sequence("IO")
|
95
96
|
Http::Client::MAX_RETRIES.times { @ui.expects(:warn).in_sequence(io_calls) }
|
data/test/unit/promise_test.rb
CHANGED
data/test/unit/support_test.rb
CHANGED
@@ -16,28 +16,28 @@ class SupportTest < UnitTestCase
|
|
16
16
|
["foo", false, "nonempty string"],
|
17
17
|
[[], true, "empty array"],
|
18
18
|
[%w{a b}, false, "nonempty array"]
|
19
|
-
].each do |(subject, emptiness,
|
20
|
-
should "return #{emptiness} for blank? with #{
|
19
|
+
].each do |(subject, emptiness, desc)|
|
20
|
+
should "return #{emptiness} for blank? with #{desc}" do
|
21
21
|
assert_equal emptiness, blank?(subject)
|
22
22
|
end
|
23
23
|
|
24
|
-
should "return #{!emptiness} for present? with #{
|
24
|
+
should "return #{!emptiness} for present? with #{desc}" do
|
25
25
|
assert_equal !emptiness, present?(subject)
|
26
26
|
end
|
27
27
|
|
28
|
-
should "return non-empty subject for presence, when subject is #{
|
28
|
+
should "return non-empty subject for presence, when subject is #{desc}" do
|
29
29
|
actual = presence(subject)
|
30
30
|
expected = present?(subject) ? subject : nil
|
31
31
|
assert_same expected, actual
|
32
32
|
end
|
33
33
|
|
34
|
-
should "return value of block for presence, when subject is #{
|
34
|
+
should "return value of block for presence, when subject is #{desc}" do
|
35
35
|
actual = presence(subject) { |s| s.size }
|
36
36
|
expected = present?(subject) ? subject.size : nil
|
37
37
|
assert_same expected, actual
|
38
38
|
end
|
39
39
|
|
40
|
-
should "allow presence to be used with || operator, when subject is #{
|
40
|
+
should "allow presence to be used with || operator, when subject is #{desc}" do
|
41
41
|
alternative = "hey"
|
42
42
|
actual = presence(subject) || alternative
|
43
43
|
expected = present?(subject) ? subject : alternative
|
@@ -47,31 +47,66 @@ class SupportTest < UnitTestCase
|
|
47
47
|
end
|
48
48
|
|
49
49
|
context "for humanizing time differences" do
|
50
|
+
should "accept string and time arguments" do
|
51
|
+
start = '2009-01-01 01:01:00'
|
52
|
+
stop = Time.parse '2009-01-01 01:03:00'
|
53
|
+
assert_commutative([2, 'min'], [start, stop]) do |a, b|
|
54
|
+
humanize_time_diff(a, b)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
50
58
|
should "use second granularity for time differences smaller than a minute" do
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
59
|
+
[
|
60
|
+
[0, '2009-01-01 01:00:00', '2009-01-01 01:00:00'],
|
61
|
+
[1, '2009-01-01 00:00:59', '2009-01-01 00:01:00'],
|
62
|
+
[1, '2009-01-01 01:00:00', '2009-01-01 01:00:01'],
|
63
|
+
[59, '2009-01-01 01:00:00', '2009-01-01 01:00:59']
|
64
|
+
].each do |(diff, start, stop)|
|
65
|
+
assert_commutative([diff, 'sec'], [start, stop]) do |a, b|
|
66
|
+
humanize_time_diff(a, b)
|
67
|
+
end
|
68
|
+
end
|
55
69
|
end
|
56
70
|
|
57
71
|
should "use minute granularity for time differences greater than a minute but smaller than an hour" do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
72
|
+
[
|
73
|
+
[1, '2009-01-01 01:00:00', '2009-01-01 01:01:00'],
|
74
|
+
[2, '2009-01-01 01:01:00', '2009-01-01 01:03:29'],
|
75
|
+
[3, '2009-01-01 01:01:00', '2009-01-01 01:03:30'],
|
76
|
+
[59, '2009-01-01 01:00:00', '2009-01-01 01:59:00'],
|
77
|
+
[59, '2009-01-01 01:00:30', '2009-01-01 01:59:00'],
|
78
|
+
[57, '2009-01-01 01:01:00', '2009-01-01 01:58:00']
|
79
|
+
].each do |(diff, start, stop)|
|
80
|
+
assert_commutative([diff, 'min'], [start, stop]) do |a, b|
|
81
|
+
humanize_time_diff(a, b)
|
82
|
+
end
|
83
|
+
end
|
64
84
|
end
|
65
85
|
|
66
86
|
should "use hour granularity for time differences greater than an hour but smaller than a day" do
|
67
|
-
|
68
|
-
|
69
|
-
|
87
|
+
[
|
88
|
+
[1, 'hour', '2009-01-01 01:00', '2009-01-01 02:00'],
|
89
|
+
[2, 'hours', '2009-01-01 01:00', '2009-01-01 03:00'],
|
90
|
+
[2, 'hours', '2009-01-01 01:00', '2009-01-01 03:29'],
|
91
|
+
[3, 'hours', '2009-01-01 01:00', '2009-01-01 03:30']
|
92
|
+
].each do |(diff, unit, start, stop)|
|
93
|
+
assert_commutative([diff, unit], [start, stop]) do |a, b|
|
94
|
+
humanize_time_diff(a, b)
|
95
|
+
end
|
96
|
+
end
|
70
97
|
end
|
71
98
|
|
72
99
|
should "use day granularity for time differences greater than a day" do
|
73
|
-
|
74
|
-
|
100
|
+
[
|
101
|
+
[1, 'day', '2009-01-01 01:00', '2009-01-02 01:00'],
|
102
|
+
[2, 'days', '2009-01-01 01:00', '2009-01-03 01:00'],
|
103
|
+
[2, 'days', '2009-01-01 01:00', '2009-01-03 12:59'],
|
104
|
+
[3, 'days', '2009-01-01 01:00', '2009-01-03 13:00']
|
105
|
+
].each do |(diff, unit, start, stop)|
|
106
|
+
assert_commutative([diff, unit], [start, stop]) do |a, b|
|
107
|
+
humanize_time_diff(a, b)
|
108
|
+
end
|
109
|
+
end
|
75
110
|
end
|
76
111
|
end
|
77
112
|
|
@@ -194,7 +229,7 @@ class SupportTest < UnitTestCase
|
|
194
229
|
%w{- dash},
|
195
230
|
%w{_ underscore},
|
196
231
|
%w{+ plus}
|
197
|
-
].each do |char, desc|
|
232
|
+
].each do |(char, desc)|
|
198
233
|
should "not affect already unescaped characters, case #{desc}" do
|
199
234
|
assert_equal char, unescape_html(char)
|
200
235
|
end
|
@@ -206,7 +241,7 @@ class SupportTest < UnitTestCase
|
|
206
241
|
%w{& &},
|
207
242
|
%w{" "},
|
208
243
|
%W{ \ }
|
209
|
-
].each do |input, expected|
|
244
|
+
].each do |(input, expected)|
|
210
245
|
should "unescape HTML-escaped characters, case '#{input}'" do
|
211
246
|
assert_equal expected, unescape_html(input)
|
212
247
|
end
|
@@ -228,12 +263,12 @@ class SupportTest < UnitTestCase
|
|
228
263
|
end
|
229
264
|
|
230
265
|
should "support both a non-array and a single element array path for finding the value" do
|
231
|
-
assert_equal
|
232
|
-
assert_equal
|
266
|
+
assert_equal @outer_hash[:simple], find_hash_path(@outer_hash, :simple)
|
267
|
+
assert_equal @outer_hash[:simple], find_hash_path(@outer_hash, [:simple])
|
233
268
|
end
|
234
269
|
|
235
270
|
should "find a nested value with an array path" do
|
236
|
-
assert_equal
|
271
|
+
assert_equal @inner_hash[:salmon], find_hash_path(@outer_hash, [:inner, :salmon])
|
237
272
|
end
|
238
273
|
|
239
274
|
should "return the default value of the hash if the value cannot be found" do
|
@@ -243,15 +278,19 @@ class SupportTest < UnitTestCase
|
|
243
278
|
end
|
244
279
|
|
245
280
|
should "return the default value of the hash if invalid path value" do
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
281
|
+
[
|
282
|
+
nil,
|
283
|
+
[:no_such, nil],
|
284
|
+
[:simple, nil],
|
285
|
+
[:inner, nil],
|
286
|
+
[:inner, :salmon, nil]
|
287
|
+
].each do |path|
|
288
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, path)
|
289
|
+
end
|
251
290
|
end
|
252
291
|
|
253
292
|
should "return nil if nil hash value" do
|
254
|
-
assert_equal nil, find_hash_path(nil,
|
293
|
+
assert_equal nil, find_hash_path(nil, [:salmon])
|
255
294
|
end
|
256
295
|
end
|
257
296
|
end
|
data/test/unit/tweet_helper.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
+
require 'timecop'
|
4
|
+
|
3
5
|
module Tweetwine::Test
|
4
6
|
module TweetHelper
|
5
7
|
FIELD_PATHS = {
|
@@ -10,11 +12,13 @@ module Tweetwine::Test
|
|
10
12
|
:status => %w{status text}
|
11
13
|
}.freeze
|
12
14
|
|
15
|
+
DEFAULT_TIMESTAMP = Time.utc(2011, 'feb', 17, 22, 28, 0)
|
16
|
+
|
13
17
|
DEFAULT_FIELD_VALUES = {
|
14
18
|
:from_user => 'fred',
|
15
19
|
:to_user => nil,
|
16
20
|
:retweet => nil,
|
17
|
-
:created_at =>
|
21
|
+
:created_at => DEFAULT_TIMESTAMP.iso8601,
|
18
22
|
:status => nil
|
19
23
|
}.freeze
|
20
24
|
|
@@ -38,6 +42,14 @@ module Tweetwine::Test
|
|
38
42
|
Tweetwine::Tweet.new(create_record(fields), FIELD_PATHS)
|
39
43
|
end
|
40
44
|
|
45
|
+
def at_default_time(&block)
|
46
|
+
Timecop.freeze(TweetHelper::DEFAULT_TIMESTAMP, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_timestamp(minus_seconds)
|
50
|
+
(TweetHelper::DEFAULT_TIMESTAMP - minus_seconds).iso8601
|
51
|
+
end
|
52
|
+
|
41
53
|
private
|
42
54
|
|
43
55
|
def find_hash_of_field_path(hash, path)
|
data/test/unit/tweet_test.rb
CHANGED
data/test/unit/ui_test.rb
CHANGED
@@ -86,18 +86,19 @@ class UITest < UnitTestCase
|
|
86
86
|
should "output regular tweet" do
|
87
87
|
from_user = "fooman"
|
88
88
|
status = "Hi, @barman! Lulz woo! #hellos"
|
89
|
+
time = 2
|
89
90
|
tweet = create_tweet(
|
90
91
|
:from_user => from_user,
|
91
|
-
:status => status
|
92
|
+
:status => status,
|
93
|
+
:created_at => create_timestamp(time)
|
92
94
|
)
|
93
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
94
95
|
@out.expects(:puts).with(<<-END
|
95
|
-
#{from_user},
|
96
|
+
#{from_user}, #{time} sec ago:
|
96
97
|
#{status}
|
97
98
|
|
98
99
|
END
|
99
100
|
)
|
100
|
-
|
101
|
+
show_tweet_at_default_time(tweet)
|
101
102
|
end
|
102
103
|
|
103
104
|
should "output replying tweet" do
|
@@ -109,14 +110,13 @@ class UITest < UnitTestCase
|
|
109
110
|
:status => status,
|
110
111
|
:to_user => to_user
|
111
112
|
)
|
112
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
113
113
|
@out.expects(:puts).with(<<-END
|
114
|
-
#{from_user}, in reply to #{to_user},
|
114
|
+
#{from_user}, in reply to #{to_user}, 0 sec ago:
|
115
115
|
#{status}
|
116
116
|
|
117
117
|
END
|
118
118
|
)
|
119
|
-
|
119
|
+
show_tweet_at_default_time(tweet)
|
120
120
|
end
|
121
121
|
|
122
122
|
should "output regular retweet" do
|
@@ -128,14 +128,13 @@ class UITest < UnitTestCase
|
|
128
128
|
:status => status,
|
129
129
|
:rt_user => rt_user
|
130
130
|
)
|
131
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
132
131
|
@out.expects(:puts).with(<<-END
|
133
|
-
#{rt_user} RT #{from_user},
|
132
|
+
#{rt_user} RT #{from_user}, 0 sec ago:
|
134
133
|
#{status}
|
135
134
|
|
136
135
|
END
|
137
136
|
)
|
138
|
-
|
137
|
+
show_tweet_at_default_time(tweet)
|
139
138
|
end
|
140
139
|
|
141
140
|
should "output replying retweet" do
|
@@ -149,14 +148,13 @@ class UITest < UnitTestCase
|
|
149
148
|
:status => status,
|
150
149
|
:rt_user => rt_user
|
151
150
|
)
|
152
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
153
151
|
@out.expects(:puts).with(<<-END
|
154
|
-
#{rt_user} RT #{from_user}, in reply to #{to_user},
|
152
|
+
#{rt_user} RT #{from_user}, in reply to #{to_user}, 0 sec ago:
|
155
153
|
#{status}
|
156
154
|
|
157
155
|
END
|
158
156
|
)
|
159
|
-
|
157
|
+
show_tweet_at_default_time(tweet)
|
160
158
|
end
|
161
159
|
|
162
160
|
should "unescape HTML in a status" do
|
@@ -167,14 +165,13 @@ class UITest < UnitTestCase
|
|
167
165
|
:from_user => from_user,
|
168
166
|
:status => escaped_status
|
169
167
|
)
|
170
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
171
168
|
@out.expects(:puts).with(<<-END
|
172
|
-
#{from_user},
|
169
|
+
#{from_user}, 0 sec ago:
|
173
170
|
#{unescaped_status}
|
174
171
|
|
175
172
|
END
|
176
173
|
)
|
177
|
-
|
174
|
+
show_tweet_at_default_time(tweet)
|
178
175
|
end
|
179
176
|
|
180
177
|
should "output a preview of a status" do
|
@@ -212,14 +209,13 @@ class UITest < UnitTestCase
|
|
212
209
|
:from_user => from_user,
|
213
210
|
:status => status
|
214
211
|
)
|
215
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
216
212
|
@out.expects(:puts).with(<<-END
|
217
|
-
\e[32m#{from_user}\e[0m,
|
213
|
+
\e[32m#{from_user}\e[0m, 0 sec ago:
|
218
214
|
#{status}
|
219
215
|
|
220
216
|
END
|
221
217
|
)
|
222
|
-
|
218
|
+
show_tweet_at_default_time(tweet)
|
223
219
|
end
|
224
220
|
|
225
221
|
should "output replying tweet" do
|
@@ -230,14 +226,13 @@ class UITest < UnitTestCase
|
|
230
226
|
:status => "@#{to_user}! How are you doing?",
|
231
227
|
:to_user => to_user
|
232
228
|
)
|
233
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
234
229
|
@out.expects(:puts).with(<<-END
|
235
|
-
\e[32m#{from_user}\e[0m, in reply to \e[32m#{to_user}\e[0m,
|
230
|
+
\e[32m#{from_user}\e[0m, in reply to \e[32m#{to_user}\e[0m, 0 sec ago:
|
236
231
|
\e[33m@#{to_user}\e[0m! How are you doing?
|
237
232
|
|
238
233
|
END
|
239
234
|
)
|
240
|
-
|
235
|
+
show_tweet_at_default_time(tweet)
|
241
236
|
end
|
242
237
|
|
243
238
|
should "output regular retweet" do
|
@@ -249,14 +244,13 @@ class UITest < UnitTestCase
|
|
249
244
|
:status => status,
|
250
245
|
:rt_user => rt_user
|
251
246
|
)
|
252
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
253
247
|
@out.expects(:puts).with(<<-END
|
254
|
-
\e[32m#{rt_user}\e[0m RT \e[32m#{from_user}\e[0m,
|
248
|
+
\e[32m#{rt_user}\e[0m RT \e[32m#{from_user}\e[0m, 0 sec ago:
|
255
249
|
#{status}
|
256
250
|
|
257
251
|
END
|
258
252
|
)
|
259
|
-
|
253
|
+
show_tweet_at_default_time(tweet)
|
260
254
|
end
|
261
255
|
|
262
256
|
should "output replying retweet" do
|
@@ -269,14 +263,13 @@ class UITest < UnitTestCase
|
|
269
263
|
:status => "@#{to_user}, reply worth retweeting",
|
270
264
|
:rt_user => rt_user
|
271
265
|
)
|
272
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
273
266
|
@out.expects(:puts).with(<<-END
|
274
|
-
\e[32m#{rt_user}\e[0m RT \e[32m#{from_user}\e[0m, in reply to \e[32m#{to_user}\e[0m,
|
267
|
+
\e[32m#{rt_user}\e[0m RT \e[32m#{from_user}\e[0m, in reply to \e[32m#{to_user}\e[0m, 0 sec ago:
|
275
268
|
\e[33m@#{to_user}\e[0m, reply worth retweeting
|
276
269
|
|
277
270
|
END
|
278
271
|
)
|
279
|
-
|
272
|
+
show_tweet_at_default_time(tweet)
|
280
273
|
end
|
281
274
|
|
282
275
|
should "output a preview of a status" do
|
@@ -297,14 +290,13 @@ class UITest < UnitTestCase
|
|
297
290
|
:from_user => from_user,
|
298
291
|
:status => "Lulz, so happy! #{hashtags[0]} #{hashtags[1]}"
|
299
292
|
)
|
300
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
301
293
|
@out.expects(:puts).with(<<-END
|
302
|
-
\e[32m#{from_user}\e[0m,
|
294
|
+
\e[32m#{from_user}\e[0m, 0 sec ago:
|
303
295
|
Lulz, so happy! \e[35m#{hashtags[0]}\e[0m \e[35m#{hashtags[1]}\e[0m
|
304
296
|
|
305
297
|
END
|
306
298
|
)
|
307
|
-
|
299
|
+
show_tweet_at_default_time(tweet)
|
308
300
|
end
|
309
301
|
|
310
302
|
%w{http://is.gd/1qLk3 http://is.gd/1qLk3?id=foo}.each do |url|
|
@@ -314,14 +306,13 @@ Lulz, so happy! \e[35m#{hashtags[0]}\e[0m \e[35m#{hashtags[1]}\e[0m
|
|
314
306
|
:from_user => from_user,
|
315
307
|
:status => "New Rails³ - #{url}"
|
316
308
|
)
|
317
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
318
309
|
@out.expects(:puts).with(<<-END
|
319
|
-
\e[32m#{from_user}\e[0m,
|
310
|
+
\e[32m#{from_user}\e[0m, 0 sec ago:
|
320
311
|
New Rails³ - \e[36m#{url}\e[0m
|
321
312
|
|
322
313
|
END
|
323
314
|
)
|
324
|
-
|
315
|
+
show_tweet_at_default_time(tweet)
|
325
316
|
end
|
326
317
|
end
|
327
318
|
|
@@ -335,14 +326,13 @@ New Rails³ - \e[36m#{url}\e[0m
|
|
335
326
|
:from_user => from_user,
|
336
327
|
:status => "Links: #{first_url} and #{second_url} np"
|
337
328
|
)
|
338
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
339
329
|
@out.expects(:puts).with(<<-END
|
340
|
-
\e[32m#{from_user}\e[0m,
|
330
|
+
\e[32m#{from_user}\e[0m, 0 sec ago:
|
341
331
|
Links: \e[36m#{first_url}\e[0m and \e[36m#{second_url}\e[0m np
|
342
332
|
|
343
333
|
END
|
344
334
|
)
|
345
|
-
|
335
|
+
show_tweet_at_default_time(tweet)
|
346
336
|
end
|
347
337
|
end
|
348
338
|
|
@@ -353,14 +343,13 @@ Links: \e[36m#{first_url}\e[0m and \e[36m#{second_url}\e[0m np
|
|
353
343
|
:from_user => from_user,
|
354
344
|
:status => "I salute you #{users[0]}, #{users[1]}, and #{users[2]}!"
|
355
345
|
)
|
356
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
357
346
|
@out.expects(:puts).with(<<-END
|
358
|
-
\e[32m#{from_user}\e[0m,
|
347
|
+
\e[32m#{from_user}\e[0m, 0 sec ago:
|
359
348
|
I salute you \e[33m#{users[0]}\e[0m, \e[33m#{users[1]}\e[0m, and \e[33m#{users[2]}\e[0m!
|
360
349
|
|
361
350
|
END
|
362
351
|
)
|
363
|
-
|
352
|
+
show_tweet_at_default_time(tweet)
|
364
353
|
end
|
365
354
|
|
366
355
|
should "not highlight email addresses as usernames in a status" do
|
@@ -371,86 +360,118 @@ I salute you \e[33m#{users[0]}\e[0m, \e[33m#{users[1]}\e[0m, and \e[33m#{users[2
|
|
371
360
|
:from_user => from_user,
|
372
361
|
:status => "Hi, #{users[0]}! You should notify #{users[1]}, #{email}"
|
373
362
|
)
|
374
|
-
Support.expects(:humanize_time_diff).returns([2, "secs"])
|
375
363
|
@out.expects(:puts).with(<<-END
|
376
|
-
\e[32m#{from_user}\e[0m,
|
364
|
+
\e[32m#{from_user}\e[0m, 0 sec ago:
|
377
365
|
Hi, \e[33m#{users[0]}\e[0m! You should notify \e[33m#{users[1]}\e[0m, #{email}
|
378
366
|
|
379
367
|
END
|
380
368
|
)
|
381
|
-
|
369
|
+
show_tweet_at_default_time(tweet)
|
382
370
|
end
|
383
371
|
end
|
384
372
|
|
385
373
|
context "for outputting a collection of tweets" do
|
386
374
|
setup do
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
375
|
+
users_and_times = [
|
376
|
+
['first', 11],
|
377
|
+
['second', 12],
|
378
|
+
['third', 13]
|
379
|
+
]
|
380
|
+
statuses = users_and_times.map { |(user, _)| "Hi, I'm #{user}." }
|
381
|
+
users_and_statuses = users_and_times.zip(statuses)
|
382
|
+
@outputs = Hash[users_and_statuses.map { |(user, time), status|
|
383
|
+
output = <<-END
|
384
|
+
#{user}, #{time} sec ago:
|
392
385
|
#{status}
|
393
386
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
:
|
387
|
+
END
|
388
|
+
[user.to_sym, output]
|
389
|
+
}]
|
390
|
+
@tweets = users_and_statuses.map { |(user, time), status| create_tweet(
|
391
|
+
:from_user => user,
|
392
|
+
:status => status,
|
393
|
+
:created_at => create_timestamp(time)
|
399
394
|
)}
|
400
|
-
Support.expects(:humanize_time_diff).twice.returns([2, "secs"])
|
401
395
|
end
|
402
396
|
|
403
|
-
should "output tweets in
|
404
|
-
ui = UI.new({ :out => @out, :show_reverse => false })
|
405
|
-
|
406
|
-
|
407
|
-
|
397
|
+
should "output tweets in normal order" do
|
398
|
+
@ui = UI.new({ :out => @out, :show_reverse => false })
|
399
|
+
[:first, :second, :third].each do |user|
|
400
|
+
@out.expects(:puts).with(@outputs[user])
|
401
|
+
end
|
402
|
+
show_tweets_at_default_time(@tweets)
|
408
403
|
end
|
409
404
|
|
410
|
-
should "output tweets in
|
411
|
-
ui = UI.new({ :out => @out, :show_reverse => true })
|
412
|
-
|
413
|
-
|
414
|
-
|
405
|
+
should "output tweets in reverse order" do
|
406
|
+
@ui = UI.new({ :out => @out, :show_reverse => true })
|
407
|
+
[:third, :second, :first].each do |user|
|
408
|
+
@out.expects(:puts).with(@outputs[user])
|
409
|
+
end
|
410
|
+
show_tweets_at_default_time(@tweets)
|
415
411
|
end
|
416
412
|
end
|
417
413
|
end
|
418
414
|
|
419
415
|
context "username regex" do
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
416
|
+
[
|
417
|
+
['@nick', 'normal'],
|
418
|
+
['@nick_man', 'underscore separated'],
|
419
|
+
[' @nick', 'beginning with space']
|
420
|
+
].each do |(nick, desc)|
|
421
|
+
should "match proper username reference, case #{desc}" do
|
422
|
+
assert_full_match UI::USERNAME_REGEX, nick
|
423
|
+
end
|
425
424
|
end
|
426
425
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
426
|
+
[
|
427
|
+
['@', 'just prefix'],
|
428
|
+
['nick', 'just body'],
|
429
|
+
['-@nick', 'beginning with dash'],
|
430
|
+
['@nick-man', 'dash separated'],
|
431
|
+
['@nick ', 'ending with space'],
|
432
|
+
[' @nick ', 'surrounded with space'],
|
433
|
+
['man @nick', 'space separated'],
|
434
|
+
['man@nick', 'prefix in between']
|
435
|
+
].each do |(no_nick, desc)|
|
436
|
+
should "not match an inproper username reference, case #{desc}" do
|
437
|
+
assert_no_full_match UI::USERNAME_REGEX, no_nick
|
438
|
+
end
|
436
439
|
end
|
437
440
|
end
|
438
441
|
|
439
442
|
context "hashtag regex" do
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
443
|
+
[
|
444
|
+
['#mayhem', 'normal'],
|
445
|
+
['#friday_mayhem', 'underscore separated'],
|
446
|
+
['#friday-mayhem', 'dash separated']
|
447
|
+
].each do |(hashtag, desc)|
|
448
|
+
should "match a proper hashtag reference, case #{desc}" do
|
449
|
+
assert_full_match UI::HASHTAG_REGEX, hashtag
|
450
|
+
end
|
444
451
|
end
|
445
452
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
453
|
+
[
|
454
|
+
['#', 'just prefix'],
|
455
|
+
['mayhem', 'just body'],
|
456
|
+
[' #mayhem', 'beginning with space'],
|
457
|
+
['#mayhem ', 'ending with space'],
|
458
|
+
[' #mayhem ', 'surrounded with space']
|
459
|
+
].each do |(no_hashtag, desc)|
|
460
|
+
should "not match an inproper hashtag reference, case #{desc}" do
|
461
|
+
assert_no_full_match UI::HASHTAG_REGEX, no_hashtag
|
462
|
+
end
|
452
463
|
end
|
453
464
|
end
|
465
|
+
|
466
|
+
private
|
467
|
+
|
468
|
+
def show_tweet_at_default_time(tweet)
|
469
|
+
at_default_time { @ui.show_tweet(tweet) }
|
470
|
+
end
|
471
|
+
|
472
|
+
def show_tweets_at_default_time(tweets)
|
473
|
+
at_default_time { @ui.show_tweets(tweets) }
|
474
|
+
end
|
454
475
|
end
|
455
476
|
|
456
477
|
end
|
data/test/unit/unit_helper.rb
CHANGED
@@ -9,42 +9,64 @@ Mocha::Configuration.prevent(:stubbing_non_existent_method)
|
|
9
9
|
|
10
10
|
module Tweetwine::Test
|
11
11
|
module Assertions
|
12
|
-
# Asserts whether an Enumeration
|
12
|
+
# Asserts whether an Enumeration-like object contains all the elements.
|
13
13
|
# Fails unless +actual+ contains the same elements as +expected+, ignoring
|
14
14
|
# the order of the elements.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
actual = block_given? ? actual.sort(&sorter) : actual.sort
|
22
|
-
assert_equal(expected, actual, get_message(msg) {
|
23
|
-
'after sorting, collection %s is not equal to %s' % [expected.inspect, actual.inspect]
|
15
|
+
def assert_contains_exactly(expected, actual, msg_diff_size = nil, msg_diff_elems = nil)
|
16
|
+
assert_equal(expected.size, actual.size, message(msg_diff_size) {
|
17
|
+
'Expected %s to be of same size as %s' % [actual.inspect, expected.inspect]
|
18
|
+
})
|
19
|
+
assert(enumerable_minus_each_element(actual, expected).empty?, message(msg_diff_elems) {
|
20
|
+
'Expected %s to contain all the elements of %s' % [actual.inspect, expected.inspect]
|
24
21
|
})
|
25
22
|
end
|
26
23
|
|
27
24
|
# Fails unless +str+ is a full match to +regex+.
|
28
25
|
def assert_full_match(regex, str, msg = nil)
|
29
26
|
match_data = regex.match(str)
|
30
|
-
assert(str == match_data.to_s,
|
31
|
-
'%s
|
27
|
+
assert(str == match_data.to_s, message(msg) {
|
28
|
+
'Expected %s to be a full match to %s' % [str, regex.inspect]
|
32
29
|
})
|
33
30
|
end
|
34
31
|
|
35
32
|
# Fails if +str+ is a full match to +regex+.
|
36
33
|
def assert_no_full_match(regex, str, msg = nil)
|
37
34
|
match_data = regex.match(str)
|
38
|
-
assert(str != match_data.to_s,
|
39
|
-
'%s
|
35
|
+
assert(str != match_data.to_s, message(msg) {
|
36
|
+
'Expected %s not to be a full match to %s' % [str, regex.inspect]
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
# Fails unless +fun.call(*args)+ is equal to +expected+ and
|
41
|
+
# +fun.call(*args)+ is equal to +fun.call(*args.reverse)+.
|
42
|
+
def assert_commutative(expected, args, msg_not_expected = nil, msg_not_commutative = nil, &fun)
|
43
|
+
left_args = args
|
44
|
+
left_actual = fun.call(left_args)
|
45
|
+
assert_equal(expected, left_actual, message(msg_not_expected) {
|
46
|
+
'Expected %s, not %s' % [expected.inspect, left_actual.inspect]
|
47
|
+
})
|
48
|
+
right_args = args.reverse
|
49
|
+
right_actual = fun.call(*right_args)
|
50
|
+
assert_equal(left_actual, right_actual, message(msg_not_commutative) {
|
51
|
+
'Expected fun%s => %s to be commutative with fun%s => %s' %
|
52
|
+
[left_args.inspect, left_actual.inspect, right_args.inspect, right_actual.inspect]
|
40
53
|
})
|
41
54
|
end
|
42
55
|
|
43
56
|
private
|
44
57
|
|
45
|
-
def
|
58
|
+
def message(given, &default)
|
46
59
|
given.nil? ? default.call : given
|
47
60
|
end
|
61
|
+
|
62
|
+
def enumerable_minus_each_element(enumerable, elements)
|
63
|
+
remaining = enumerable.dup.to_a
|
64
|
+
elements.each do |e|
|
65
|
+
index = remaining.index(e)
|
66
|
+
remaining.delete_at(index) if index
|
67
|
+
end
|
68
|
+
remaining
|
69
|
+
end
|
48
70
|
end
|
49
71
|
|
50
72
|
module Doubles
|
data/test/unit/uri_test.rb
CHANGED
@@ -13,7 +13,7 @@ class UriTest < UnitTestCase
|
|
13
13
|
%w{. period},
|
14
14
|
%w{- dash},
|
15
15
|
%w{_ underscore},
|
16
|
-
].each do |char, desc|
|
16
|
+
].each do |(char, desc)|
|
17
17
|
should "not encode safe characters, case #{desc}" do
|
18
18
|
assert_equal char, Uri.percent_encode(char)
|
19
19
|
end
|
@@ -29,7 +29,7 @@ class UriTest < UnitTestCase
|
|
29
29
|
%w{/ %2F slash},
|
30
30
|
%w{: %3A colon},
|
31
31
|
%w{, %2C comma}
|
32
|
-
].each do |char, expected, desc|
|
32
|
+
].each do |(char, expected, desc)|
|
33
33
|
should "encode unsafe characters that URI.encode leaves by default unencoded, case #{desc}" do
|
34
34
|
assert_equal char, Uri.parser.escape(char)
|
35
35
|
assert_equal expected, Uri.percent_encode(char)
|
data/tweetwine.gemspec
CHANGED
@@ -1,27 +1,18 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
name = 'tweetwine'
|
5
|
-
require "#{name}/version"
|
6
|
-
version = Tweetwine.version
|
3
|
+
require File.expand_path('project', File.dirname(__FILE__))
|
7
4
|
|
8
5
|
Gem::Specification.new do |s|
|
9
|
-
s.name
|
10
|
-
s.version
|
11
|
-
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
s.
|
19
|
-
s.homepage = 'https://github.com/tkareine/tweetwine'
|
20
|
-
|
21
|
-
s.authors = ['Tuomas Kareinen']
|
22
|
-
|
23
|
-
s.files = `git ls-files`.split("\n") + Dir['man/**/*.[1-9]']
|
24
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
6
|
+
s.name = Project.name
|
7
|
+
s.version = Project.version
|
8
|
+
s.summary = Project.summary
|
9
|
+
s.description = Project.description
|
10
|
+
s.email = Project.email
|
11
|
+
s.homepage = Project.homepage
|
12
|
+
s.authors = Project.authors
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n") + Dir["#{Project.dirs.man}/**/*.[1-9]"]
|
15
|
+
s.test_files = `git ls-files -- #{Project.dirs.test}/*`.split("\n")
|
25
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
26
17
|
|
27
18
|
s.add_dependency 'oauth', '~> 0.4.4'
|
@@ -45,6 +36,5 @@ default. For Ruby 1.8, you can install 'json' gem, for example.
|
|
45
36
|
|
46
37
|
s.has_rdoc = true
|
47
38
|
s.extra_rdoc_files = Dir['*.rdoc', 'LICENSE.txt']
|
48
|
-
s.rdoc_options << '--title'
|
49
|
-
<< '--exclude' << 'test'
|
39
|
+
s.rdoc_options << '--title' << Project.title << '--exclude' << Project.dirs.test
|
50
40
|
end
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tweetwine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 13
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 1
|
10
|
+
version: 0.4.1
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Tuomas Kareinen
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-03-23 00:00:00 +02:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +26,11 @@ dependencies:
|
|
21
26
|
requirements:
|
22
27
|
- - ~>
|
23
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 4
|
33
|
+
- 4
|
24
34
|
version: 0.4.4
|
25
35
|
type: :runtime
|
26
36
|
version_requirements: *id001
|
@@ -32,6 +42,11 @@ dependencies:
|
|
32
42
|
requirements:
|
33
43
|
- - ~>
|
34
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 31
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 1
|
49
|
+
- 2
|
35
50
|
version: 0.1.2
|
36
51
|
type: :development
|
37
52
|
version_requirements: *id002
|
@@ -43,6 +58,11 @@ dependencies:
|
|
43
58
|
requirements:
|
44
59
|
- - ~>
|
45
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 1
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 6
|
65
|
+
- 3
|
46
66
|
version: 0.6.3
|
47
67
|
type: :development
|
48
68
|
version_requirements: *id003
|
@@ -54,6 +74,11 @@ dependencies:
|
|
54
74
|
requirements:
|
55
75
|
- - ~>
|
56
76
|
- !ruby/object:Gem::Version
|
77
|
+
hash: 23
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
- 2
|
81
|
+
- 0
|
57
82
|
version: 0.2.0
|
58
83
|
type: :development
|
59
84
|
version_requirements: *id004
|
@@ -65,6 +90,11 @@ dependencies:
|
|
65
90
|
requirements:
|
66
91
|
- - ~>
|
67
92
|
- !ruby/object:Gem::Version
|
93
|
+
hash: 15
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
- 5
|
97
|
+
- 2
|
68
98
|
version: 0.5.2
|
69
99
|
type: :development
|
70
100
|
version_requirements: *id005
|
@@ -76,6 +106,11 @@ dependencies:
|
|
76
106
|
requirements:
|
77
107
|
- - ~>
|
78
108
|
- !ruby/object:Gem::Version
|
109
|
+
hash: 35
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
- 9
|
113
|
+
- 12
|
79
114
|
version: 0.9.12
|
80
115
|
type: :development
|
81
116
|
version_requirements: *id006
|
@@ -87,6 +122,11 @@ dependencies:
|
|
87
122
|
requirements:
|
88
123
|
- - ~>
|
89
124
|
- !ruby/object:Gem::Version
|
125
|
+
hash: 21
|
126
|
+
segments:
|
127
|
+
- 1
|
128
|
+
- 0
|
129
|
+
- 1
|
90
130
|
version: 1.0.1
|
91
131
|
type: :development
|
92
132
|
version_requirements: *id007
|
@@ -98,6 +138,11 @@ dependencies:
|
|
98
138
|
requirements:
|
99
139
|
- - ~>
|
100
140
|
- !ruby/object:Gem::Version
|
141
|
+
hash: 49
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
- 8
|
145
|
+
- 7
|
101
146
|
version: 0.8.7
|
102
147
|
type: :development
|
103
148
|
version_requirements: *id008
|
@@ -109,6 +154,11 @@ dependencies:
|
|
109
154
|
requirements:
|
110
155
|
- - ~>
|
111
156
|
- !ruby/object:Gem::Version
|
157
|
+
hash: 5
|
158
|
+
segments:
|
159
|
+
- 0
|
160
|
+
- 7
|
161
|
+
- 3
|
112
162
|
version: 0.7.3
|
113
163
|
type: :development
|
114
164
|
version_requirements: *id009
|
@@ -120,6 +170,11 @@ dependencies:
|
|
120
170
|
requirements:
|
121
171
|
- - ~>
|
122
172
|
- !ruby/object:Gem::Version
|
173
|
+
hash: 25
|
174
|
+
segments:
|
175
|
+
- 0
|
176
|
+
- 3
|
177
|
+
- 5
|
123
178
|
version: 0.3.5
|
124
179
|
type: :development
|
125
180
|
version_requirements: *id010
|
@@ -131,6 +186,11 @@ dependencies:
|
|
131
186
|
requirements:
|
132
187
|
- - ~>
|
133
188
|
- !ruby/object:Gem::Version
|
189
|
+
hash: 11
|
190
|
+
segments:
|
191
|
+
- 1
|
192
|
+
- 6
|
193
|
+
- 2
|
134
194
|
version: 1.6.2
|
135
195
|
type: :development
|
136
196
|
version_requirements: *id011
|
@@ -152,6 +212,7 @@ files:
|
|
152
212
|
- Gemfile
|
153
213
|
- LICENSE.txt
|
154
214
|
- README.md
|
215
|
+
- RELEASING.txt
|
155
216
|
- Rakefile
|
156
217
|
- bin/tweetwine
|
157
218
|
- contrib/tweetwine-completion.bash
|
@@ -174,7 +235,7 @@ files:
|
|
174
235
|
- lib/tweetwine/url_shortener.rb
|
175
236
|
- lib/tweetwine/version.rb
|
176
237
|
- man/tweetwine.7.ronn
|
177
|
-
-
|
238
|
+
- project.rb
|
178
239
|
- test/example/authorization_example.rb
|
179
240
|
- test/example/example_helper.rb
|
180
241
|
- test/example/global_options_example.rb
|
@@ -223,12 +284,14 @@ has_rdoc: true
|
|
223
284
|
homepage: https://github.com/tkareine/tweetwine
|
224
285
|
licenses: []
|
225
286
|
|
226
|
-
post_install_message:
|
227
|
-
|
228
|
-
|
287
|
+
post_install_message: |+
|
288
|
+
|
289
|
+
Tweetwine requires a JSON parser library. Ruby 1.9 comes bundled with one by
|
290
|
+
default. For Ruby 1.8, you can install 'json' gem, for example.
|
291
|
+
|
229
292
|
rdoc_options:
|
230
293
|
- --title
|
231
|
-
- tweetwine 0.4.
|
294
|
+
- tweetwine 0.4.1
|
232
295
|
- --exclude
|
233
296
|
- test
|
234
297
|
require_paths:
|
@@ -238,17 +301,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
238
301
|
requirements:
|
239
302
|
- - ">="
|
240
303
|
- !ruby/object:Gem::Version
|
304
|
+
hash: 3
|
305
|
+
segments:
|
306
|
+
- 0
|
241
307
|
version: "0"
|
242
308
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
309
|
none: false
|
244
310
|
requirements:
|
245
311
|
- - ">="
|
246
312
|
- !ruby/object:Gem::Version
|
313
|
+
hash: 3
|
314
|
+
segments:
|
315
|
+
- 0
|
247
316
|
version: "0"
|
248
317
|
requirements: []
|
249
318
|
|
250
319
|
rubyforge_project:
|
251
|
-
rubygems_version: 1.
|
320
|
+
rubygems_version: 1.6.2
|
252
321
|
signing_key:
|
253
322
|
specification_version: 3
|
254
323
|
summary: Tweetwine shows the latest tweets from the command line quickly.
|