faketwitter 0.1.4
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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.textile +21 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/faketwitter.gemspec +55 -0
- data/lib/core_ext/hash.rb +10 -0
- data/lib/faketwitter.rb +172 -0
- data/spec/faketwitter_spec.rb +195 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +9 -0
- metadata +77 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Ben Mabey
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
h1. faketwitter
|
2
|
+
|
3
|
+
Factory goodness for twitter search responses wrapped in FakeWeb awesomeness.
|
4
|
+
|
5
|
+
<pre>
|
6
|
+
irb(main):001:0> require 'faketwitter'
|
7
|
+
=> true
|
8
|
+
irb(main):002:0> require 'twitter_search'
|
9
|
+
=> true
|
10
|
+
irb(main):003:0> FakeTwitter.register_search("#cheese", {:results => [{:text => "#cheese is good"}]})
|
11
|
+
=> [#<FakeWeb::Responder:0x19792c0 @times=1, @uri="http://search.twitter.com/search.json?q=%23cheese", @options={:body=>"{"results":[{"text":"#cheese is good","from_user":"jojo","to_user_id":null,"id":1,"from_user_id":1,"iso_language_code":"en","source":"<a href="http:\\/\\/twitter.com\\/">web<\\/a>","created_at":"Fri, 21 Aug 2009 09:31:27 +0000","profile_image_url":"http:\\/\\/s3.amazonaws.com\\/twitter_production\\/profile_images\\/1\\/photo.jpg"}],"since_id":0,"max_id":1,"results_per_page":15,"completed_in":0.008646,"page":1,"query":"%23cheese"}"}, method:get]
|
12
|
+
irb(main):004:0> TwitterSearch::Client.new('').query('#cheese')
|
13
|
+
=> [#<TwitterSearch::Tweet:0x196cef8 @id=1, @text="#cheese is good", @created_at="Fri, 21 Aug 2009 09:31:27 +0000", @to_user_id=nil, @from_user_id=1, @to_user=nil, @source="<a href="http://twitter.com/">web</a>", @iso_language_code="en", @from_user="jojo", @language="en", @profile_image_url="http://s3.amazonaws.com/twitter_production/profile_images/1/photo.jpg">]
|
14
|
+
irb(main):005:0>
|
15
|
+
|
16
|
+
</pre>
|
17
|
+
|
18
|
+
For an example on how to use this in Cucumber see this "scenario":http://github.com/bmabey/codenote/blob/master/features/twitter_quiz.feature#L31-34 and the corresponding "step definitions":http://github.com/bmabey/codenote/blob/master/features/step_definitions/twitter_search_steps.rb#L1-12.
|
19
|
+
|
20
|
+
Documentation is lacking at this point, but there really isn't much to this gem. Take a look at the "code":http://github.com/bmabey/faketwitter/blob/master/lib/faketwitter.rb and the corresponding "RSpec examples":http://github.com/bmabey/faketwitter/blob/master/spec/faketwitter_spec.rb.
|
21
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "faketwitter"
|
8
|
+
gem.summary = %Q{Easily stub out Twitter searches}
|
9
|
+
gem.description = %Q{FakeWeb wrapper for Twitter and factories to build tweets and search responses}
|
10
|
+
gem.email = "ben@benmabey.com"
|
11
|
+
gem.homepage = "http://github.com/bmabey/faketwitter"
|
12
|
+
gem.authors = ["Ben Mabey"]
|
13
|
+
gem.add_development_dependency "rspec"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'spec/rake/spectask'
|
21
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
22
|
+
spec.libs << 'lib' << 'spec'
|
23
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
29
|
+
spec.rcov = true
|
30
|
+
end
|
31
|
+
|
32
|
+
task :spec => :check_dependencies
|
33
|
+
|
34
|
+
task :default => :spec
|
35
|
+
|
36
|
+
require 'rake/rdoctask'
|
37
|
+
Rake::RDocTask.new do |rdoc|
|
38
|
+
if File.exist?('VERSION')
|
39
|
+
version = File.read('VERSION')
|
40
|
+
else
|
41
|
+
version = ""
|
42
|
+
end
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "faketwitter #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.4
|
data/faketwitter.gemspec
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{faketwitter}
|
8
|
+
s.version = "0.1.4"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ben Mabey"]
|
12
|
+
s.date = %q{2009-11-03}
|
13
|
+
s.description = %q{FakeWeb wrapper for Twitter and factories to build tweets and search responses}
|
14
|
+
s.email = %q{ben@benmabey.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.textile"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.textile",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"faketwitter.gemspec",
|
27
|
+
"lib/core_ext/hash.rb",
|
28
|
+
"lib/faketwitter.rb",
|
29
|
+
"spec/faketwitter_spec.rb",
|
30
|
+
"spec/spec.opts",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/bmabey/faketwitter}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.3}
|
37
|
+
s.summary = %q{Easily stub out Twitter searches}
|
38
|
+
s.test_files = [
|
39
|
+
"spec/faketwitter_spec.rb",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
48
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
49
|
+
else
|
50
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
51
|
+
end
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
54
|
+
end
|
55
|
+
end
|
data/lib/faketwitter.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'fakeweb'
|
2
|
+
require 'cgi'
|
3
|
+
require File.dirname(__FILE__) + "/core_ext/hash"
|
4
|
+
|
5
|
+
module FakeTwitter
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def register_search(query, search_options = {})
|
10
|
+
return register_searches(query, search_options) if search_options.is_a?(Array)
|
11
|
+
escaped_query = CGI.escape(query)
|
12
|
+
search_options['query'] = escaped_query
|
13
|
+
FakeWeb.register_uri(
|
14
|
+
:get,
|
15
|
+
search_url(escaped_query),
|
16
|
+
fake_web_options(search_options)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def register_searches(query, rotated_search_options)
|
21
|
+
escaped_query = CGI.escape(query)
|
22
|
+
search_results = rotated_search_options.map do |search_options|
|
23
|
+
search_options['query'] = escaped_query
|
24
|
+
fake_web_options(search_options)
|
25
|
+
end
|
26
|
+
FakeWeb.register_uri(
|
27
|
+
:get,
|
28
|
+
search_url(escaped_query),
|
29
|
+
search_results
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset
|
34
|
+
FakeWeb.clean_registry
|
35
|
+
TweetFactory.reset
|
36
|
+
end
|
37
|
+
|
38
|
+
def new_tweet(attributes)
|
39
|
+
TweetFactory.create(attributes)
|
40
|
+
end
|
41
|
+
|
42
|
+
def search_response(options={})
|
43
|
+
SearchResponseFactory.create(options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def tweets_from(user)
|
47
|
+
TweetFactory.tweets_from(user)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def search_url(escaped_query)
|
53
|
+
"http://search.twitter.com/search.json?q=#{escaped_query}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def fake_web_options(search_options)
|
57
|
+
{:body => search_response(search_options).to_json}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
class SearchResponseFactory
|
64
|
+
DEFAULTS = {
|
65
|
+
'results' => [],
|
66
|
+
'since_id' => 0,
|
67
|
+
'max_id' => -1,
|
68
|
+
'results_per_page' => 15,
|
69
|
+
'completed_in' => 0.008646,
|
70
|
+
'page' => 1,
|
71
|
+
'query' => ''
|
72
|
+
}
|
73
|
+
|
74
|
+
class << self
|
75
|
+
|
76
|
+
def create(attributes)
|
77
|
+
# TODO: remove duplication between factories.
|
78
|
+
response = DEFAULTS.merge(attributes.stringify_keys)
|
79
|
+
response['results'] = create_tweets(response['results'].dup)
|
80
|
+
|
81
|
+
unless response['results'].empty?
|
82
|
+
response['max_id'] = response['results'].map { |t| t['id'] }.max
|
83
|
+
end
|
84
|
+
|
85
|
+
response
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
private
|
90
|
+
def create_tweets(tweets)
|
91
|
+
now = Time.now
|
92
|
+
tweets.sort! do |tweet_a, tweet_b|
|
93
|
+
(tweet_b['created_at'] || now) <=> (tweet_a['created_at'] || now)
|
94
|
+
end
|
95
|
+
# We do the reverses so that the id's are auto-incremented correctly
|
96
|
+
tweets.reverse!.map! do |tweet_hash|
|
97
|
+
tweet = FakeTwitter.new_tweet(tweet_hash)
|
98
|
+
# hardcoding +0000 because %z was giving -0700 for UTC for some reason (leopard MRI)..
|
99
|
+
tweet['created_at'] = tweet['created_at'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000")
|
100
|
+
tweet['source'] = CGI.escapeHTML(tweet['source'])
|
101
|
+
tweet
|
102
|
+
end
|
103
|
+
|
104
|
+
tweets.reverse!
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
class TweetFactory
|
112
|
+
DEFAULTS = {
|
113
|
+
"text"=>"just some tweet",
|
114
|
+
"from_user"=>"jojo",
|
115
|
+
"to_user_id"=>nil,
|
116
|
+
"iso_language_code"=>"en",
|
117
|
+
"source"=>'<a href="http://twitter.com/">web</a>',
|
118
|
+
}
|
119
|
+
|
120
|
+
class << self
|
121
|
+
|
122
|
+
def reset
|
123
|
+
@counter = nil
|
124
|
+
@users = nil
|
125
|
+
@tweet_repo = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
def create(attributes)
|
129
|
+
tweet = DEFAULTS.merge(attributes.stringify_keys)
|
130
|
+
clean_user_names(tweet)
|
131
|
+
tweet['id'] ||= counter(:id)
|
132
|
+
tweet['from_user_id'] ||= user_id_for(tweet['from_user'])
|
133
|
+
tweet['to_user_id'] ||= user_id_for(tweet['to_user'])
|
134
|
+
tweet['profile_image_url'] ||= "http://s3.amazonaws.com/twitter_production/profile_images/#{tweet['from_user_id']}/photo.jpg"
|
135
|
+
tweet['created_at'] ||= Time.now
|
136
|
+
|
137
|
+
tweet_repo << tweet
|
138
|
+
tweet
|
139
|
+
end
|
140
|
+
|
141
|
+
def tweets_from(user)
|
142
|
+
tweet_repo.select { |tweet| tweet['from_user'] == user }
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
def counter(counter_type)
|
148
|
+
@counter ||= Hash.new(0)
|
149
|
+
@counter[counter_type] += 1
|
150
|
+
end
|
151
|
+
|
152
|
+
def user_id_for(user)
|
153
|
+
return unless user
|
154
|
+
@users ||= {}
|
155
|
+
@users[user] ||= counter(:user_id)
|
156
|
+
end
|
157
|
+
|
158
|
+
def clean_user_names(tweet)
|
159
|
+
['from_user', 'to_user'].each do |key|
|
160
|
+
next unless tweet[key]
|
161
|
+
tweet[key].sub!('@','')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def tweet_repo
|
166
|
+
@tweet_repo ||= []
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'activesupport'
|
3
|
+
|
4
|
+
describe FakeTwitter do
|
5
|
+
before(:each) do
|
6
|
+
FakeTwitter.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '::register_search' do
|
10
|
+
it "registers the twitter search url and the specified query with FakeWeb" do
|
11
|
+
# expect
|
12
|
+
FakeWeb.should_receive(:register_uri).with(:get, "http://search.twitter.com/search.json?q=%23foo+%22some+string%22", anything)
|
13
|
+
# when
|
14
|
+
FakeTwitter.register_search('#foo "some string"', {})
|
15
|
+
end
|
16
|
+
|
17
|
+
it "uses the provided tweets for the stubbed response" do
|
18
|
+
# given
|
19
|
+
created_at = Time.parse("Thu, 20 Aug 2009 23:23:09 +0000")
|
20
|
+
tweets = [
|
21
|
+
{:from_user => "bmabey", :id => 1000, :from_user_id => 100,
|
22
|
+
:created_at => created_at, :text => 'making FakeTwitter'}
|
23
|
+
]
|
24
|
+
|
25
|
+
# expect
|
26
|
+
expected_json_tweet = <<-EOT
|
27
|
+
{
|
28
|
+
"text": "making FakeTwitter",
|
29
|
+
"to_user_id": null,
|
30
|
+
"from_user": "bmabey",
|
31
|
+
"id": 1000,
|
32
|
+
"from_user_id": 100,
|
33
|
+
"iso_language_code": "en",
|
34
|
+
"source": "<a href="http:\/\/twitter.com\/">web<\/a>",
|
35
|
+
"profile_image_url": "http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/100\/photo.jpg",
|
36
|
+
"created_at": "Thu, 20 Aug 2009 23:23:09 +0000"
|
37
|
+
}
|
38
|
+
EOT
|
39
|
+
|
40
|
+
FakeWeb.should_receive(:register_uri).with do |_, _, fakeweb_return_options|
|
41
|
+
json = fakeweb_return_options[:body]
|
42
|
+
JSON.parse(json)['results'].first.should == JSON.parse(expected_json_tweet)
|
43
|
+
end
|
44
|
+
|
45
|
+
# when
|
46
|
+
FakeTwitter.register_search('foo', :results => tweets)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "includes the escaped query in the response" do
|
50
|
+
FakeWeb.should_receive(:register_uri).with do |_, _, fakeweb_return_options|
|
51
|
+
json = fakeweb_return_options[:body]
|
52
|
+
JSON.parse(json)['query'].should == "%23foo"
|
53
|
+
end
|
54
|
+
|
55
|
+
# when
|
56
|
+
FakeTwitter.register_search('#foo')
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '::register_searches' do
|
62
|
+
it "registers the multiple search results with FakeWeb to be rotated" do
|
63
|
+
# expect
|
64
|
+
FakeWeb.should_receive(:register_uri).with do |_, _, fakeweb_return_options|
|
65
|
+
fakeweb_return_options.size.should == 2
|
66
|
+
first_result_set = JSON.parse(fakeweb_return_options.first[:body])
|
67
|
+
second_result_set = JSON.parse(fakeweb_return_options.last[:body])
|
68
|
+
first_result_set['results'].should be_empty
|
69
|
+
second_result_set['results'].first['text'] == 'foo bar'
|
70
|
+
end
|
71
|
+
|
72
|
+
# when
|
73
|
+
FakeTwitter.register_searches('foo', [
|
74
|
+
{:results => []},
|
75
|
+
{:results => [{:text => 'foo bar'}]}
|
76
|
+
])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
describe '::search_response' do
|
82
|
+
it "has sane defaults for the other response values" do
|
83
|
+
response = FakeTwitter.search_response()
|
84
|
+
response.slice(*%w[since_id max_id results_per_page completed_in page query]).should == {
|
85
|
+
'since_id' => 0,
|
86
|
+
'max_id' => -1,
|
87
|
+
'results_per_page' => 15,
|
88
|
+
'completed_in' => 0.008646,
|
89
|
+
'page' => 1,
|
90
|
+
'query' => ''
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "sets the max_id based on the highest tweet id in the result set" do
|
95
|
+
response = FakeTwitter.search_response(:results => [{:id => 1}, {:id => 100}])
|
96
|
+
response['max_id'].should == 100
|
97
|
+
end
|
98
|
+
|
99
|
+
it "creates the tweets based on the defined created_at times if possible" do
|
100
|
+
response = FakeTwitter.search_response(:results => [
|
101
|
+
{'created_at' => Time.now - 100, :text => 'first tweet'},
|
102
|
+
{'created_at' => Time.now, :text => 'most recent tweet'}
|
103
|
+
])
|
104
|
+
response['results'].first['text'].should == 'most recent tweet'
|
105
|
+
response['results'].first['id'].should > response['results'].last['id']
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
describe '::new_tweet' do
|
112
|
+
it "returns hash of an API compliant tweet with sane defaults" do
|
113
|
+
tweet = FakeTwitter.new_tweet({})
|
114
|
+
tweet.slice(*%w[text from_user to_user_id iso_language_code source]).should == {
|
115
|
+
"text"=>"just some tweet",
|
116
|
+
"from_user"=>"jojo",
|
117
|
+
"to_user_id"=>nil,
|
118
|
+
"iso_language_code"=>"en",
|
119
|
+
"source"=>'<a href="http://twitter.com/">web</a>',
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
it "auto-increments the tweet ids when they are not provided" do
|
124
|
+
FakeTwitter.new_tweet({})['id'].should == 1
|
125
|
+
FakeTwitter.new_tweet({})['id'].should == 2
|
126
|
+
end
|
127
|
+
|
128
|
+
it "auto-increments user ids when none are provided" do
|
129
|
+
FakeTwitter.new_tweet({'from_user' => 'jojo'})['from_user_id'].should == 1
|
130
|
+
FakeTwitter.new_tweet({'from_user' => 'krusty'})['from_user_id'].should == 2
|
131
|
+
end
|
132
|
+
|
133
|
+
it "assigns a user_id for to_user when needed" do
|
134
|
+
FakeTwitter.new_tweet({'to_user' => 'billy'})['to_user_id'].should_not be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
it "resuses the same user id for tweets made for the same user" do
|
139
|
+
FakeTwitter.new_tweet({'from_user' => 'jojo'})['from_user_id'].should == 1
|
140
|
+
FakeTwitter.new_tweet({'from_user' => 'jojo'})['from_user_id'].should == 1
|
141
|
+
end
|
142
|
+
|
143
|
+
it "defaults create_at to Time.now" do
|
144
|
+
Time.stub!(:now => 'current time')
|
145
|
+
FakeTwitter.new_tweet({})['created_at'].should == 'current time'
|
146
|
+
end
|
147
|
+
|
148
|
+
it "bases the default profile_image_url off of the user id" do
|
149
|
+
FakeTwitter.new_tweet('from_user_id' => 123)['profile_image_url'].
|
150
|
+
should == "http://s3.amazonaws.com/twitter_production/profile_images/123/photo.jpg"
|
151
|
+
end
|
152
|
+
|
153
|
+
it "strips leading @s from user names" do
|
154
|
+
tweet = FakeTwitter.new_tweet('from_user' => '@james', 'to_user' => '@john')
|
155
|
+
tweet['from_user'].should == 'james'
|
156
|
+
tweet['to_user'].should == 'john'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '::tweets_from' do
|
161
|
+
it "returns all the tweets that have been created from the specified user" do
|
162
|
+
FakeTwitter.search_response(:results => [
|
163
|
+
{'from_user' => 'ben', 'text' => 'hello'},
|
164
|
+
{'from_user' => 'ben', 'text' => 'goodbye'},
|
165
|
+
{'from_user' => 'someone_else', 'text' => 'just sending a tweet'}
|
166
|
+
])
|
167
|
+
|
168
|
+
tweets = FakeTwitter.tweets_from('ben')
|
169
|
+
tweets.map { |t| t['text'] }.should == ['goodbye', 'hello']
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '::reset' do
|
174
|
+
it "tells FakeWeb to clean it's registry" do
|
175
|
+
FakeWeb.should_receive(:clean_registry)
|
176
|
+
FakeTwitter.reset
|
177
|
+
end
|
178
|
+
it "resets the user id counter for tweets" do
|
179
|
+
FakeTwitter.new_tweet('from_user' => 'foo')['from_user_id'].should == 1
|
180
|
+
FakeTwitter.reset
|
181
|
+
FakeTwitter.new_tweet('from_user' => 'bar')['from_user_id'].should == 1
|
182
|
+
end
|
183
|
+
it "resets the tweet id counter" do
|
184
|
+
FakeTwitter.new_tweet('from_user' => 'foo')['id'].should == 1
|
185
|
+
FakeTwitter.reset
|
186
|
+
FakeTwitter.new_tweet('from_user' => 'foo')['id'].should == 1
|
187
|
+
end
|
188
|
+
it "clears the sent tweets" do
|
189
|
+
FakeTwitter.new_tweet('from_user' => 'foo')
|
190
|
+
FakeTwitter.reset
|
191
|
+
FakeTwitter.tweets_from('foo').should be_empty
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: faketwitter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Mabey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-03 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: FakeWeb wrapper for Twitter and factories to build tweets and search responses
|
26
|
+
email: ben@benmabey.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.textile
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.textile
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- faketwitter.gemspec
|
42
|
+
- lib/core_ext/hash.rb
|
43
|
+
- lib/faketwitter.rb
|
44
|
+
- spec/faketwitter_spec.rb
|
45
|
+
- spec/spec.opts
|
46
|
+
- spec/spec_helper.rb
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/bmabey/faketwitter
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --charset=UTF-8
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.3
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Easily stub out Twitter searches
|
75
|
+
test_files:
|
76
|
+
- spec/faketwitter_spec.rb
|
77
|
+
- spec/spec_helper.rb
|