handcrafted-twitter 0.4.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/{History.txt → History} +16 -0
- data/{License.txt → License} +0 -0
- data/{Manifest.txt → Manifest} +14 -16
- data/{README.txt → README} +0 -0
- data/Rakefile +41 -3
- data/bin/twitter +1 -2
- data/examples/direct_messages.rb +1 -0
- data/examples/favorites.rb +4 -4
- data/examples/replies.rb +1 -0
- data/examples/search.rb +1 -0
- data/examples/sent_messages.rb +1 -0
- data/examples/timeline.rb +1 -0
- data/lib/twitter.rb +13 -2
- data/lib/twitter/base.rb +52 -19
- data/lib/twitter/cli.rb +13 -7
- data/lib/twitter/cli/helpers.rb +20 -8
- data/lib/twitter/direct_message.rb +7 -7
- data/lib/twitter/rate_limit_status.rb +4 -4
- data/lib/twitter/search.rb +10 -3
- data/lib/twitter/search_result.rb +83 -0
- data/lib/twitter/search_result_info.rb +82 -0
- data/lib/twitter/status.rb +8 -8
- data/lib/twitter/user.rb +18 -18
- data/lib/twitter/version.rb +1 -7
- data/spec/base_spec.rb +32 -2
- data/spec/cli/helper_spec.rb +21 -7
- data/spec/fixtures/follower_ids.xml +11 -0
- data/spec/fixtures/friend_ids.xml +12 -0
- data/spec/fixtures/friendship_already_exists.xml +5 -0
- data/spec/fixtures/friendship_created.xml +12 -0
- data/spec/fixtures/search_result_info.yml +147 -0
- data/spec/search_spec.rb +12 -1
- data/spec/spec_helper.rb +12 -1
- data/twitter.gemspec +17 -21
- data/website/index.html +4 -1
- metadata +49 -46
- data/config/hoe.rb +0 -74
- data/config/requirements.rb +0 -17
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -74
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -50
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -17
data/lib/twitter/cli/helpers.rb
CHANGED
@@ -5,25 +5,37 @@ module Twitter
|
|
5
5
|
class NoAccounts < StandardError; end
|
6
6
|
|
7
7
|
def output_tweets(collection, options={})
|
8
|
-
options
|
8
|
+
options = {
|
9
9
|
:cache => false,
|
10
10
|
:since_prefix => '',
|
11
|
-
:empty_msg => 'Nothing new since your last check.'
|
12
|
-
|
11
|
+
:empty_msg => 'Nothing new since your last check.',
|
12
|
+
:reverse => false
|
13
|
+
}.merge(options)
|
14
|
+
|
13
15
|
if collection.size > 0
|
14
16
|
justify = collection.collect { |s| s.user.screen_name }.max { |a,b| a.length <=> b.length }.length rescue 0
|
15
17
|
indention = ' ' * (justify + 3)
|
16
18
|
say("\n#{indention}#{collection.size} new tweet(s) found.\n\n")
|
19
|
+
collection.reverse! if options[:reverse]
|
17
20
|
collection.each do |s|
|
18
21
|
Tweet.create_from_tweet(current_account, s) if options[:cache]
|
22
|
+
|
19
23
|
occurred_at = Time.parse(s.created_at).strftime('On %b %d at %l:%M%P')
|
20
24
|
formatted_time = '-' * occurred_at.length + "\n#{indention}#{occurred_at}"
|
21
25
|
formatted_name = s.user.screen_name.rjust(justify + 1)
|
22
26
|
formatted_msg = ''
|
23
|
-
|
24
|
-
|
27
|
+
|
28
|
+
s.text.split(' ').each_with_index do |word, idx|
|
29
|
+
formatted_msg += "#{word} "
|
30
|
+
|
31
|
+
sixth_word = idx != 0 && idx % 6 == 0
|
32
|
+
formatted_msg += "\n#{indention}" if sixth_word
|
33
|
+
end
|
34
|
+
|
35
|
+
say "#{CGI::unescapeHTML(formatted_name)}: #{CGI::unescapeHTML(formatted_msg)}\n#{indention}#{formatted_time}\n\n"
|
25
36
|
end
|
26
|
-
|
37
|
+
|
38
|
+
Configuration["#{options[:since_prefix]}_since_id"] = options[:reverse] ? collection.last.id : collection.first.id
|
27
39
|
else
|
28
40
|
say(options[:empty_msg])
|
29
41
|
end
|
@@ -35,7 +47,7 @@ module Twitter
|
|
35
47
|
|
36
48
|
def current_account
|
37
49
|
@current_account ||= Account.active
|
38
|
-
raise Account.count == 0 ? NoAccounts : NoActiveAccount if @current_account.
|
50
|
+
raise Account.count == 0 ? NoAccounts : NoActiveAccount if @current_account.nil?
|
39
51
|
@current_account
|
40
52
|
end
|
41
53
|
|
@@ -44,7 +56,7 @@ module Twitter
|
|
44
56
|
if File.exists?(tweet_file)
|
45
57
|
say '.twitter file found, attempting import...'
|
46
58
|
config = YAML::load(File.read(tweet_file))
|
47
|
-
if !config['email'].
|
59
|
+
if !config['email'].nil? && !config['password'].nil?
|
48
60
|
Account.add(:username => config['email'], :password => config['password'])
|
49
61
|
say 'Account imported'
|
50
62
|
block.call if block_given?
|
@@ -8,13 +8,13 @@ module Twitter
|
|
8
8
|
# Creates a new status from a piece of xml
|
9
9
|
def new_from_xml(xml)
|
10
10
|
DirectMessage.new do |d|
|
11
|
-
d.id = (xml).at('id').
|
12
|
-
d.text = (xml).get_elements_by_tag_name('text').
|
13
|
-
d.sender_id = (xml).at('sender_id').
|
14
|
-
d.recipient_id = (xml).at('recipient_id').
|
15
|
-
d.created_at = (xml).at('created_at').
|
16
|
-
d.sender_screen_name = (xml).at('sender_screen_name').
|
17
|
-
d.recipient_screen_name = (xml).at('recipient_screen_name').
|
11
|
+
d.id = (xml).at('id').innerHTML
|
12
|
+
d.text = (xml).get_elements_by_tag_name('text').innerHTML
|
13
|
+
d.sender_id = (xml).at('sender_id').innerHTML
|
14
|
+
d.recipient_id = (xml).at('recipient_id').innerHTML
|
15
|
+
d.created_at = (xml).at('created_at').innerHTML
|
16
|
+
d.sender_screen_name = (xml).at('sender_screen_name').innerHTML
|
17
|
+
d.recipient_screen_name = (xml).at('recipient_screen_name').innerHTML
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -8,10 +8,10 @@ module Twitter
|
|
8
8
|
# Creates a new rate limi status from a piece of xml
|
9
9
|
def new_from_xml(xml)
|
10
10
|
RateLimitStatus.new do |s|
|
11
|
-
s.reset_time_in_seconds = xml.at('reset-time-in-seconds').
|
12
|
-
s.reset_time = Time.parse xml.at('reset-time').
|
13
|
-
s.remaining_hits = xml.at('remaining-hits').
|
14
|
-
s.hourly_limit = xml.at('hourly-limit').
|
11
|
+
s.reset_time_in_seconds = xml.at('reset-time-in-seconds').inner_html.to_i
|
12
|
+
s.reset_time = Time.parse xml.at('reset-time').inner_html
|
13
|
+
s.remaining_hits = xml.at('remaining-hits').inner_html.to_i
|
14
|
+
s.hourly_limit = xml.at('hourly-limit').inner_html.to_i
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/twitter/search.rb
CHANGED
@@ -11,7 +11,7 @@ module Twitter
|
|
11
11
|
|
12
12
|
def initialize(q=nil)
|
13
13
|
clear
|
14
|
-
containing(q)
|
14
|
+
containing(q) if q && q.strip != ''
|
15
15
|
end
|
16
16
|
|
17
17
|
def from(user)
|
@@ -59,6 +59,12 @@ module Twitter
|
|
59
59
|
self
|
60
60
|
end
|
61
61
|
|
62
|
+
# Which page of results to fetch
|
63
|
+
def page(num)
|
64
|
+
@query[:page] = num
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
62
68
|
# Only searches tweets since a given id.
|
63
69
|
# Recommended to use this when possible.
|
64
70
|
def since(since_id)
|
@@ -83,7 +89,7 @@ module Twitter
|
|
83
89
|
# If you want to get results do something other than iterate over them.
|
84
90
|
def fetch
|
85
91
|
@query[:q] = @query[:q].join(' ')
|
86
|
-
self.class.get('/search.json', {:query => @query})
|
92
|
+
SearchResultInfo.new_from_hash(self.class.get('/search.json', {:query => @query}))
|
87
93
|
end
|
88
94
|
|
89
95
|
def each
|
@@ -91,4 +97,5 @@ module Twitter
|
|
91
97
|
@result['results'].each { |r| yield r }
|
92
98
|
end
|
93
99
|
end
|
94
|
-
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Twitter
|
2
|
+
class SearchResult < Hash
|
3
|
+
|
4
|
+
# Creates an easier to work with hash from
|
5
|
+
# one with string-based keys
|
6
|
+
def self.new_from_hash(hash)
|
7
|
+
new.merge!(hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def created_at
|
11
|
+
self['created_at']
|
12
|
+
end
|
13
|
+
|
14
|
+
def created_at=(val)
|
15
|
+
self['created_at'] = val
|
16
|
+
end
|
17
|
+
|
18
|
+
def from_user
|
19
|
+
self['from_user']
|
20
|
+
end
|
21
|
+
|
22
|
+
def from_user=(val)
|
23
|
+
self['from_user'] = val
|
24
|
+
end
|
25
|
+
|
26
|
+
def from_user_id
|
27
|
+
self['from_user_id']
|
28
|
+
end
|
29
|
+
|
30
|
+
def from_user_id=(val)
|
31
|
+
self['from_user_id'] = val
|
32
|
+
end
|
33
|
+
|
34
|
+
def id
|
35
|
+
self['id']
|
36
|
+
end
|
37
|
+
|
38
|
+
def id=(val)
|
39
|
+
self['id'] = val
|
40
|
+
end
|
41
|
+
|
42
|
+
def iso_language_code
|
43
|
+
self['iso_language_code']
|
44
|
+
end
|
45
|
+
|
46
|
+
def iso_language_code=(val)
|
47
|
+
self['iso_language_code'] = val
|
48
|
+
end
|
49
|
+
|
50
|
+
def profile_image_url
|
51
|
+
self['profile_image_url']
|
52
|
+
end
|
53
|
+
|
54
|
+
def profile_image_url=(val)
|
55
|
+
self['profile_image_url'] = val
|
56
|
+
end
|
57
|
+
|
58
|
+
def text
|
59
|
+
self['text']
|
60
|
+
end
|
61
|
+
|
62
|
+
def text=(val)
|
63
|
+
self['text'] = val
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_user
|
67
|
+
self['to_user']
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_user=(val)
|
71
|
+
self['to_user'] = val
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_user_id
|
75
|
+
self['to_user_id']
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_user_id=(val)
|
79
|
+
self['to_user_id'] = val
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Twitter
|
2
|
+
class SearchResultInfo < Hash
|
3
|
+
|
4
|
+
# Creates an easier to work with hash from
|
5
|
+
# one with string-based keys
|
6
|
+
def self.new_from_hash(hash)
|
7
|
+
i = new
|
8
|
+
i.merge!(hash)
|
9
|
+
search_results = []
|
10
|
+
i.results.each do |r|
|
11
|
+
search_results << SearchResult.new_from_hash(r)
|
12
|
+
end
|
13
|
+
i.results = search_results
|
14
|
+
i
|
15
|
+
end
|
16
|
+
|
17
|
+
def completed_in
|
18
|
+
self['completed_in']
|
19
|
+
end
|
20
|
+
|
21
|
+
def completed_in=(val)
|
22
|
+
self['completed_in'] = val
|
23
|
+
end
|
24
|
+
|
25
|
+
def max_id
|
26
|
+
self['max_id']
|
27
|
+
end
|
28
|
+
|
29
|
+
def max_id=(val)
|
30
|
+
self['max_id'] = val
|
31
|
+
end
|
32
|
+
|
33
|
+
def next_page
|
34
|
+
self['next_page']
|
35
|
+
end
|
36
|
+
|
37
|
+
def next_page=(val)
|
38
|
+
self['next_page'] = val
|
39
|
+
end
|
40
|
+
|
41
|
+
def page
|
42
|
+
self['page']
|
43
|
+
end
|
44
|
+
|
45
|
+
def page=(val)
|
46
|
+
self['page'] = val
|
47
|
+
end
|
48
|
+
|
49
|
+
def refresh_url
|
50
|
+
self['refresh_url']
|
51
|
+
end
|
52
|
+
|
53
|
+
def refresh_url=(val)
|
54
|
+
self['refresh_url'] = val
|
55
|
+
end
|
56
|
+
|
57
|
+
def results_per_page
|
58
|
+
self['results_per_page']
|
59
|
+
end
|
60
|
+
|
61
|
+
def results_per_page=(val)
|
62
|
+
self['results_per_page'] = val
|
63
|
+
end
|
64
|
+
|
65
|
+
def since_id
|
66
|
+
self['since_id']
|
67
|
+
end
|
68
|
+
|
69
|
+
def since_id=(val)
|
70
|
+
self['since_id'] = val
|
71
|
+
end
|
72
|
+
|
73
|
+
def results
|
74
|
+
self['results']
|
75
|
+
end
|
76
|
+
|
77
|
+
def results=(val)
|
78
|
+
self['results'] = val
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
data/lib/twitter/status.rb
CHANGED
@@ -7,14 +7,14 @@ module Twitter
|
|
7
7
|
# Creates a new status from a piece of xml
|
8
8
|
def self.new_from_xml(xml)
|
9
9
|
s = new
|
10
|
-
s.id = (xml).at('id').
|
11
|
-
s.created_at = (xml).at('created_at').
|
12
|
-
s.text = (xml).get_elements_by_tag_name('text').
|
13
|
-
s.source = (xml).at('source').
|
14
|
-
s.truncated = (xml).at('truncated').
|
15
|
-
s.favorited = (xml).at('favorited').
|
16
|
-
s.in_reply_to_status_id = (xml).at('in_reply_to_status_id').
|
17
|
-
s.in_reply_to_user_id = (xml).at('in_reply_to_user_id').
|
10
|
+
s.id = (xml).at('id').innerHTML
|
11
|
+
s.created_at = (xml).at('created_at').innerHTML
|
12
|
+
s.text = (xml).get_elements_by_tag_name('text').innerHTML
|
13
|
+
s.source = (xml).at('source').innerHTML
|
14
|
+
s.truncated = (xml).at('truncated').innerHTML == 'false' ? false : true
|
15
|
+
s.favorited = (xml).at('favorited').innerHTML == 'false' ? false : true
|
16
|
+
s.in_reply_to_status_id = (xml).at('in_reply_to_status_id').innerHTML
|
17
|
+
s.in_reply_to_user_id = (xml).at('in_reply_to_user_id').innerHTML
|
18
18
|
s.user = User.new_from_xml(xml.at('user')) if (xml).at('user')
|
19
19
|
s
|
20
20
|
end
|
data/lib/twitter/user.rb
CHANGED
@@ -10,26 +10,26 @@ module Twitter
|
|
10
10
|
# Creates a new user from a piece of xml
|
11
11
|
def self.new_from_xml(xml)
|
12
12
|
u = new
|
13
|
-
u.id = (xml).at('id').
|
14
|
-
u.name = (xml).at('name').
|
15
|
-
u.screen_name = (xml).at('screen_name').
|
16
|
-
u.location = (xml).at('location').
|
17
|
-
u.description = (xml).at('description').
|
18
|
-
u.url = (xml).at('url').
|
19
|
-
u.profile_image_url = (xml).at('profile_image_url').
|
13
|
+
u.id = (xml).at('id').innerHTML
|
14
|
+
u.name = (xml).at('name').innerHTML
|
15
|
+
u.screen_name = (xml).at('screen_name').innerHTML
|
16
|
+
u.location = (xml).at('location').innerHTML
|
17
|
+
u.description = (xml).at('description').innerHTML
|
18
|
+
u.url = (xml).at('url').innerHTML
|
19
|
+
u.profile_image_url = (xml).at('profile_image_url').innerHTML
|
20
20
|
|
21
21
|
# optional, not always present
|
22
|
-
u.profile_background_color = (xml).at('profile_background_color').
|
23
|
-
u.profile_text_color = (xml).at('profile_text_color').
|
24
|
-
u.profile_link_color = (xml).at('profile_link_color').
|
25
|
-
u.profile_sidebar_fill_color = (xml).at('profile_sidebar_fill_color').
|
26
|
-
u.profile_sidebar_border_color = (xml).at('profile_sidebar_border_color').
|
27
|
-
u.friends_count = (xml).at('friends_count').
|
28
|
-
u.followers_count = (xml).at('followers_count').
|
29
|
-
u.favourites_count = (xml).at('favourites_count').
|
30
|
-
u.statuses_count = (xml).at('statuses_count').
|
31
|
-
u.utc_offset = (xml).at('utc_offset').
|
32
|
-
u.protected = (xml).at('protected').
|
22
|
+
u.profile_background_color = (xml).at('profile_background_color').innerHTML if (xml).at('profile_background_color')
|
23
|
+
u.profile_text_color = (xml).at('profile_text_color').innerHTML if (xml).at('profile_text_color')
|
24
|
+
u.profile_link_color = (xml).at('profile_link_color').innerHTML if (xml).at('profile_link_color')
|
25
|
+
u.profile_sidebar_fill_color = (xml).at('profile_sidebar_fill_color').innerHTML if (xml).at('profile_sidebar_fill_color')
|
26
|
+
u.profile_sidebar_border_color = (xml).at('profile_sidebar_border_color').innerHTML if (xml).at('profile_sidebar_border_color')
|
27
|
+
u.friends_count = (xml).at('friends_count').innerHTML if (xml).at('friends_count')
|
28
|
+
u.followers_count = (xml).at('followers_count').innerHTML if (xml).at('followers_count')
|
29
|
+
u.favourites_count = (xml).at('favourites_count').innerHTML if (xml).at('favourites_count')
|
30
|
+
u.statuses_count = (xml).at('statuses_count').innerHTML if (xml).at('statuses_count')
|
31
|
+
u.utc_offset = (xml).at('utc_offset').innerHTML if (xml).at('utc_offset')
|
32
|
+
u.protected = (xml).at('protected').innerHTML == 'false' ? false : true if (xml).at('protected')
|
33
33
|
u.status = Status.new_from_xml(xml.at('status')) if (xml).at('status')
|
34
34
|
u
|
35
35
|
end
|
data/lib/twitter/version.rb
CHANGED
data/spec/base_spec.rb
CHANGED
@@ -16,7 +16,11 @@ describe "Twitter::Base" do
|
|
16
16
|
lambda { @base.timeline(:fakeyoutey) }.should raise_error(Twitter::UnknownTimeline)
|
17
17
|
end
|
18
18
|
|
19
|
-
it "should default to friends timeline"
|
19
|
+
it "should default to friends timeline" do
|
20
|
+
@base.should_receive(:call).with("friends_timeline", {:auth=>true, :args=>{}, :since=>nil})
|
21
|
+
@base.should_receive(:statuses)
|
22
|
+
@base.timeline
|
23
|
+
end
|
20
24
|
|
21
25
|
it "should be able to retrieve friends timeline" do
|
22
26
|
data = open(File.dirname(__FILE__) + '/fixtures/friends_timeline.xml').read
|
@@ -50,6 +54,12 @@ describe "Twitter::Base" do
|
|
50
54
|
@base.friends(:lite => true).size.should == 15
|
51
55
|
end
|
52
56
|
|
57
|
+
it "should be able to get friend ids" do
|
58
|
+
data = open(File.dirname(__FILE__) + '/fixtures/friend_ids.xml').read
|
59
|
+
@base.should_receive(:request).and_return(Hpricot::XML(data))
|
60
|
+
@base.friend_ids.size.should == 8
|
61
|
+
end
|
62
|
+
|
53
63
|
it "should be able to get friends for another user" do
|
54
64
|
data = open(File.dirname(__FILE__) + '/fixtures/friends_for.xml').read
|
55
65
|
@base.should_receive(:request).and_return(Hpricot::XML(data))
|
@@ -65,6 +75,26 @@ describe "Twitter::Base" do
|
|
65
75
|
timeline.size.should == 29
|
66
76
|
timeline.first.name.should == 'Blaine Cook'
|
67
77
|
end
|
78
|
+
|
79
|
+
it "should be able to get follower ids" do
|
80
|
+
data = open(File.dirname(__FILE__) + '/fixtures/follower_ids.xml').read
|
81
|
+
@base.should_receive(:request).and_return(Hpricot::XML(data))
|
82
|
+
@base.follower_ids.size.should == 8
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should be able to create a friendship" do
|
86
|
+
data = open(File.dirname(__FILE__) + '/fixtures/friendship_created.xml').read
|
87
|
+
@base.should_receive(:request).and_return(Hpricot::XML(data))
|
88
|
+
user = @base.create_friendship('jnunemaker')
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should bomb if friendship already exists" do
|
92
|
+
data = open(File.dirname(__FILE__) + '/fixtures/friendship_already_exists.xml').read
|
93
|
+
response = Net::HTTPForbidden.new("1.1", '403', '')
|
94
|
+
response.stub!(:body).and_return(data)
|
95
|
+
@base.should_receive(:response).and_return(response)
|
96
|
+
lambda { @base.create_friendship('billymeltdown') }.should raise_error(Twitter::AlreadyFollowing)
|
97
|
+
end
|
68
98
|
end
|
69
99
|
|
70
100
|
it "should be able to get single status" do
|
@@ -106,4 +136,4 @@ describe "Twitter::Base" do
|
|
106
136
|
@base.rate_limit_status.remaining_hits.should == 5
|
107
137
|
end
|
108
138
|
end
|
109
|
-
end
|
139
|
+
end
|
data/spec/cli/helper_spec.rb
CHANGED
@@ -8,6 +8,10 @@ def say(str)
|
|
8
8
|
puts str
|
9
9
|
end
|
10
10
|
|
11
|
+
class Tweet < OpenStruct
|
12
|
+
attr_accessor :id
|
13
|
+
end
|
14
|
+
|
11
15
|
describe Twitter::CLI::Helpers do
|
12
16
|
include Twitter::CLI::Helpers
|
13
17
|
|
@@ -15,21 +19,31 @@ describe Twitter::CLI::Helpers do
|
|
15
19
|
before do
|
16
20
|
Configuration.stub!(:[]=).and_return(true)
|
17
21
|
@collection = [
|
18
|
-
|
19
|
-
:
|
22
|
+
Tweet.new(
|
23
|
+
:id => 1,
|
24
|
+
:text => 'This is my long message that I want to see formatted ooooh so pretty with a few words on each line so it is easy to scan.',
|
20
25
|
:created_at => Time.mktime(2008, 5, 1, 10, 15, 00).strftime('%Y-%m-%d %H:%M:%S'),
|
21
|
-
:user
|
26
|
+
:user => OpenStruct.new(:screen_name => 'jnunemaker')
|
22
27
|
),
|
23
|
-
|
24
|
-
:
|
28
|
+
Tweet.new(
|
29
|
+
:id => 2,
|
30
|
+
:text => 'This is my long message that I want to see formatted ooooh so pretty with a.',
|
25
31
|
:created_at => Time.mktime(2008, 4, 1, 10, 15, 00).strftime('%Y-%m-%d %H:%M:%S'),
|
26
|
-
:user
|
32
|
+
:user => OpenStruct.new(:screen_name => 'danielmorrison')
|
27
33
|
)
|
28
34
|
]
|
29
35
|
end
|
30
36
|
|
31
37
|
specify "should properly format" do
|
32
|
-
|
38
|
+
stdout_for {
|
39
|
+
output_tweets(@collection)
|
40
|
+
}.should match(/with a few words[\w\W]*with a\./)
|
41
|
+
end
|
42
|
+
|
43
|
+
specify 'should format in reverse' do
|
44
|
+
stdout_for {
|
45
|
+
output_tweets(@collection, :reverse => true)
|
46
|
+
}.should match(/with a\.[\w\W]*with a few words/)
|
33
47
|
end
|
34
48
|
end
|
35
49
|
end
|