handcrafted-twitter 0.4.0 → 0.4.2
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/{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
|