tweetwine 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.3.2 released 2010-11-17
2
+
3
+ * Drop <tt>json</tt> gem dependency from gemspec in order to allow the user to
4
+ choose the JSON parser implementation
5
+ * Minor cleanups
6
+
1
7
  === 0.3.1 released 2010-11-14
2
8
 
3
9
  * Fix regression bug: shorten HTTPS URLs also
data/Gemfile CHANGED
@@ -1,17 +1,17 @@
1
1
  source :rubygems
2
2
 
3
- gem "nokogiri", "~> 1.4.3"
4
- gem "oauth", "~> 0.4.4"
5
- gem "json", ">= 1.0.0", :platforms => [:ruby_18, :jruby]
3
+ gem 'json', '>= 1.0.0', :platforms => [:ruby_18, :jruby]
4
+ gem 'nokogiri', '~> 1.4.4'
5
+ gem 'oauth', '~> 0.4.4'
6
6
 
7
7
  group :test do
8
- gem "contest", "~> 0.1.2"
9
- gem "coulda", "~> 0.6.0"
10
- gem "gem-man", "~> 0.2.0"
11
- gem "mcmire-matchy", "~> 0.5.2", :require => "matchy"
12
- gem "mocha", "= 0.9.8"
13
- gem "open4", "~> 1.0.1"
14
- gem "ronn", "~> 0.7.3"
15
- gem "timecop", "~> 0.3.5"
16
- gem "webmock", "~> 1.6.1"
8
+ gem 'contest', '~> 0.1.2'
9
+ gem 'coulda', '~> 0.6.0'
10
+ gem 'gem-man', '~> 0.2.0'
11
+ gem 'mcmire-matchy', '~> 0.5.2', :require => 'matchy'
12
+ gem 'mocha', '= 0.9.8'
13
+ gem 'open4', '~> 1.0.1'
14
+ gem 'ronn', '~> 0.7.3'
15
+ gem 'timecop', '~> 0.3.5'
16
+ gem 'webmock', '~> 1.6.1'
17
17
  end
data/README.md CHANGED
@@ -1,10 +1,9 @@
1
- tweetwine -- a simple Twitter command line agent
2
- ================================================
1
+ tweetwine
2
+ =========
3
3
 
4
4
  ## DESCRIPTION
5
5
 
6
- Tweetwine is designed for checking the latest tweets from the command line
7
- quickly.
6
+ Tweetwine shows the latest tweets from the command line quickly.
8
7
 
9
8
  The program can show the home timeline of the authenticated user, the latest
10
9
  tweets of friends and followers, and the latest tweets that mention the user.
@@ -28,11 +27,11 @@ Install Tweetwine with RubyGems:
28
27
  The program is tested with Ruby 1.8.7 and 1.9.2.
29
28
 
30
29
  The program requires [oauth](http://oauth.rubyforge.org/) gem to be installed.
31
- In addition, the program needs [json](http://json.rubyforge.org/) gem on Ruby
32
- 1.8.
30
+ In addition, the program needs a JSON parser library, such as
31
+ [json](http://json.rubyforge.org/) gem, on Ruby 1.8.
33
32
 
34
33
  This documentation page is also provided as a manual page. Use
35
- [gem-man](http://github.com/defunkt/gem-man) to see it:
34
+ [gem-man](https://github.com/defunkt/gem-man) to see it:
36
35
 
37
36
  $ gem man tweetwine
38
37
 
@@ -129,4 +128,4 @@ Tweetwine is Copyright (c) 2009-2010 Tuomas Kareinen.
129
128
 
130
129
  ## SEE ALSO
131
130
 
132
- <http://github.com/tuomas/tweetwine>
131
+ <https://github.com/tuomas/tweetwine>
data/Rakefile CHANGED
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
 
3
- require "rake/clean"
3
+ require 'rake/clean'
4
4
 
5
- $LOAD_PATH.unshift(File.expand_path("../lib/", __FILE__))
6
- name = "tweetwine"
5
+ $LOAD_PATH.unshift(File.expand_path('lib', File.dirname(__FILE__)))
6
+ name = 'tweetwine'
7
7
  require name
8
- version = Tweetwine::VERSION.dup
8
+ version = Tweetwine.version.dup
9
9
 
10
10
  namespace :gem do
11
11
  CLOBBER.include "#{name}-*.gem"
@@ -3,7 +3,7 @@
3
3
  module Tweetwine
4
4
  class CharacterEncoding
5
5
  class << self
6
- if "".respond_to?(:encode)
6
+ if defined? Encoding
7
7
  def to_utf8(str)
8
8
  result = str.encode('UTF-8')
9
9
  raise TranscodeError, "invalid UTF-8 byte sequence when transcoding '#{str}'" unless result.valid_encoding?
data/lib/tweetwine/cli.rb CHANGED
@@ -238,7 +238,7 @@ Usage: #{CLI::EXEC_NAME} #{name} #{usage}
238
238
  sort { |a, b| a.first.to_s <=> b.first.to_s }.
239
239
  map { |cmd, klass| [cmd, klass.about] }
240
240
  CLI.ui.info <<-END
241
- A simple but tasty Twitter agent for command line use, made for fun.
241
+ #{Tweetwine.summary}
242
242
 
243
243
  Usage: #{CLI::EXEC_NAME} [global_options...] [<command>] [command_options...]
244
244
 
@@ -372,7 +372,7 @@ Usage: #{CLI::EXEC_NAME} [global_options...] [<command>] [command_options...]
372
372
  about "Show program version and exit."
373
373
 
374
374
  def run
375
- CLI.ui.info "tweetwine #{Tweetwine::VERSION}"
375
+ CLI.ui.info "tweetwine #{Tweetwine.version}"
376
376
  end
377
377
  end
378
378
  end
@@ -1,6 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
- require "json"
4
3
  require "uri"
5
4
 
6
5
  module Tweetwine
@@ -3,7 +3,8 @@
3
3
  module Tweetwine
4
4
  class UrlShortener
5
5
  def initialize(options)
6
- raise "UrlShortener should be disabled" if options[:disable]
6
+ raise 'UrlShortener should be disabled' if options[:disable]
7
+ require 'nokogiri'
7
8
  @method = (options[:method] || :get).to_sym
8
9
  unless [:get, :post].include? @method
9
10
  raise CommandLineError, "Unsupported HTTP request method for URL shortening: #{@method}"
@@ -20,7 +21,6 @@ module Tweetwine
20
21
  end
21
22
 
22
23
  def shorten(url)
23
- require "nokogiri"
24
24
  response = CLI.http.send(@method, *get_service_url_and_params(url))
25
25
  doc = Nokogiri::HTML(response)
26
26
  doc.xpath(@xpath_selector).first.to_s
@@ -44,7 +44,7 @@ module Tweetwine
44
44
  params = @extra_params.merge({ @url_param_name.to_sym => url_to_shorten })
45
45
  [service_url, params]
46
46
  else
47
- raise "Unrecognized HTTP request method; should have been supported"
47
+ raise "Unrecognized HTTP request method #{@method}; should have been supported"
48
48
  end
49
49
  end
50
50
  end
data/lib/tweetwine.rb CHANGED
@@ -1,9 +1,25 @@
1
1
  # coding: utf-8
2
2
 
3
+ begin
4
+ require 'json'
5
+ rescue LoadError
6
+ raise 'Could not load JSON library; do you have one installed as a gem?'
7
+ end unless defined? JSON
8
+
3
9
  gem 'oauth', '~> 0.4.4'
4
10
 
5
11
  module Tweetwine
6
- VERSION = '0.3.1'.freeze
12
+ VERSION = '0.3.2'.freeze
13
+
14
+ class << self
15
+ def version
16
+ VERSION
17
+ end
18
+
19
+ def summary
20
+ 'Tweetwine shows the latest tweets from the command line quickly.'
21
+ end
22
+ end
7
23
 
8
24
  class Error < StandardError
9
25
  @status_code = 42
data/man/tweetwine.7 CHANGED
@@ -3,11 +3,8 @@
3
3
  .
4
4
  .TH "TWEETWINE" "7" "November 2010" "Tuomas Kareinen" "Tweetwine Manual"
5
5
  .
6
- .SH "NAME"
7
- \fBtweetwine\fR \- a simple Twitter command line agent
8
- .
9
6
  .SH "DESCRIPTION"
10
- Tweetwine is designed for checking the latest tweets from the command line quickly\.
7
+ Tweetwine shows the latest tweets from the command line quickly\.
11
8
  .
12
9
  .P
13
10
  The program can show the home timeline of the authenticated user, the latest tweets of friends and followers, and the latest tweets that mention the user\. If that\'s not enough, Tweetwine can search statuses with arbitrary terms and send status updates\.
@@ -46,10 +43,10 @@ $ gem install tweetwine
46
43
  The program is tested with Ruby 1\.8\.7 and 1\.9\.2\.
47
44
  .
48
45
  .P
49
- The program requires oauth \fIhttp://oauth\.rubyforge\.org/\fR gem to be installed\. In addition, the program needs json \fIhttp://json\.rubyforge\.org/\fR gem on Ruby 1\.8\.
46
+ The program requires oauth \fIhttp://oauth\.rubyforge\.org/\fR gem to be installed\. In addition, the program needs a JSON parser library, such as json \fIhttp://json\.rubyforge\.org/\fR gem, on Ruby 1\.8\.
50
47
  .
51
48
  .P
52
- This documentation page is also provided as a manual page\. Use gem\-man \fIhttp://github\.com/defunkt/gem\-man\fR to see it:
49
+ This documentation page is also provided as a manual page\. Use gem\-man \fIhttps://github\.com/defunkt/gem\-man\fR to see it:
53
50
  .
54
51
  .IP "" 4
55
52
  .
@@ -187,4 +184,4 @@ fi
187
184
  Tweetwine is Copyright (c) 2009\-2010 Tuomas Kareinen\.
188
185
  .
189
186
  .SH "SEE ALSO"
190
- \fIhttp://github\.com/tuomas/tweetwine\fR
187
+ \fIhttps://github\.com/tuomas/tweetwine\fR
data/man/tweetwine.7.ronn CHANGED
@@ -1,10 +1,9 @@
1
- tweetwine -- a simple Twitter command line agent
2
- ================================================
1
+ tweetwine
2
+ =========
3
3
 
4
4
  ## DESCRIPTION
5
5
 
6
- Tweetwine is designed for checking the latest tweets from the command line
7
- quickly.
6
+ Tweetwine shows the latest tweets from the command line quickly.
8
7
 
9
8
  The program can show the home timeline of the authenticated user, the latest
10
9
  tweets of friends and followers, and the latest tweets that mention the user.
@@ -28,11 +27,11 @@ Install Tweetwine with RubyGems:
28
27
  The program is tested with Ruby 1.8.7 and 1.9.2.
29
28
 
30
29
  The program requires [oauth](http://oauth.rubyforge.org/) gem to be installed.
31
- In addition, the program needs [json](http://json.rubyforge.org/) gem on Ruby
32
- 1.8.
30
+ In addition, the program needs a JSON parser library, such as
31
+ [json](http://json.rubyforge.org/) gem, on Ruby 1.8.
33
32
 
34
33
  This documentation page is also provided as a manual page. Use
35
- [gem-man](http://github.com/defunkt/gem-man) to see it:
34
+ [gem-man](https://github.com/defunkt/gem-man) to see it:
36
35
 
37
36
  $ gem man tweetwine
38
37
 
@@ -129,4 +128,4 @@ Tweetwine is Copyright (c) 2009-2010 Tuomas Kareinen.
129
128
 
130
129
  ## SEE ALSO
131
130
 
132
- <http://github.com/tuomas/tweetwine>
131
+ <https://github.com/tuomas/tweetwine>
@@ -35,7 +35,7 @@ Feature "application behavior" do
35
35
 
36
36
  Then "the application shows help and exists with success status" do
37
37
  @output.should == <<-END
38
- A simple but tasty Twitter agent for command line use, made for fun.
38
+ #{Tweetwine.summary}
39
39
 
40
40
  Usage: #{CLI::EXEC_NAME} [global_options...] [<command>] [command_options...]
41
41
 
@@ -147,7 +147,7 @@ Usage: tweetwine help [<command>]
147
147
  stub_http_request(METHOD, ACCESS_TOKEN_URL).to_return(:body => ACCESS_TOKEN_RESPONSE)
148
148
  stub_http_request(:get, @command_url).
149
149
  to_return(:status => [401, 'Unauthorized']).then.
150
- to_return(:body => fixture("home.json"))
150
+ to_return(:body => fixture_file('home.json'))
151
151
  @output = nil
152
152
  @config_contents = nil
153
153
  @config_mode = nil
@@ -18,7 +18,7 @@ module Tweetwine::Test
18
18
  module Helper
19
19
  include WebMock::API
20
20
 
21
- CONFIG_FILE = fixture_file('config_example.yaml')
21
+ CONFIG_FILE = fixture_path('config_example.yaml')
22
22
  PROJECT_DIR = File.expand_path('../..', File.dirname(__FILE__))
23
23
  PROXY_HOST = "proxy.net"
24
24
  PROXY_PORT = 8123
@@ -39,12 +39,6 @@ module Tweetwine::Test
39
39
  output.string.split("\n")
40
40
  end
41
41
 
42
- def fixture(filename)
43
- File.open(fixture_file(filename)) do |f|
44
- f.readlines.join("\n")
45
- end
46
- end
47
-
48
42
  def in_temp_dir
49
43
  Dir.mktmpdir do |tmp_dir|
50
44
  Dir.chdir(tmp_dir) do |dir|
@@ -9,7 +9,7 @@ Feature "search tweets" do
9
9
 
10
10
  SEARCH_OR_URL = "http://search.twitter.com/search.json?q=braid%20game&rpp=2&page=1"
11
11
  SEARCH_AND_URL = "http://search.twitter.com/search.json?q=braid%20OR%20game&rpp=2&page=1"
12
- SEARCH_FIXTURE = fixture("search.json")
12
+ SEARCH_FIXTURE = fixture_file('search.json')
13
13
 
14
14
  Scenario "search words" do
15
15
  When "I start the application with command 'search' and search words" do
@@ -9,7 +9,7 @@ Feature "show followers" do
9
9
 
10
10
  Scenario "show followers" do
11
11
  When "I start the application with 'followers' command" do
12
- stub_http_request(:get, "https://api.twitter.com/1/statuses/followers.json?count=20&page=1").to_return(:body => fixture("users.json"))
12
+ stub_http_request(:get, "https://api.twitter.com/1/statuses/followers.json?count=20&page=1").to_return(:body => fixture_file('users.json'))
13
13
  @output = start_cli %w{followers}
14
14
  end
15
15
 
@@ -9,7 +9,7 @@ Feature "show friends" do
9
9
 
10
10
  Scenario "show friends" do
11
11
  When "I start the application with 'followers' command" do
12
- stub_http_request(:get, "https://api.twitter.com/1/statuses/friends.json?count=20&page=1").to_return(:body => fixture("users.json"))
12
+ stub_http_request(:get, "https://api.twitter.com/1/statuses/friends.json?count=20&page=1").to_return(:body => fixture_file('users.json'))
13
13
  @output = start_cli %w{friends}
14
14
  end
15
15
 
@@ -9,7 +9,7 @@ Feature "show tweets from home timeline" do
9
9
 
10
10
  def setup
11
11
  super
12
- stub_http_request(:get, "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1").to_return(:body => fixture("home.json"))
12
+ stub_http_request(:get, "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1").to_return(:body => fixture_file('home.json'))
13
13
  end
14
14
 
15
15
  Scenario "with colorization disabled" do
@@ -9,7 +9,7 @@ Feature "show tweets mentioning the user" do
9
9
 
10
10
  Scenario "show tweets mentioning me" do
11
11
  When "I start the application with 'mentions' command" do
12
- stub_http_request(:get, "https://api.twitter.com/1/statuses/mentions.json?count=20&page=1").to_return(:body => fixture("mentions.json"))
12
+ stub_http_request(:get, "https://api.twitter.com/1/statuses/mentions.json?count=20&page=1").to_return(:body => fixture_file('mentions.json'))
13
13
  @output = start_cli %w{mentions}
14
14
  end
15
15
 
@@ -8,7 +8,7 @@ Feature "show user's tweets" do
8
8
  i_want_to "see that user's tweets"
9
9
 
10
10
  USER_URL = "https://api.twitter.com/1/statuses/user_timeline.json?count=20&page=1&screen_name=%s"
11
- USER_FIXTURE = fixture("user.json")
11
+ USER_FIXTURE = fixture_file('user.json')
12
12
 
13
13
  Scenario "show my tweets" do
14
14
  When "I start the application with 'user' command without extra arguments" do
@@ -8,12 +8,12 @@ Feature "update my status (send new tweet)" do
8
8
  as_a "authenticated user"
9
9
  i_want_to "update my status"
10
10
 
11
- RUBYGEMS_FIXTURE = fixture('shorten_rubygems.html')
11
+ RUBYGEMS_FIXTURE = fixture_file('shorten_rubygems.html')
12
12
  RUBYGEMS_FULL_URL = 'http://rubygems.org/'
13
13
  RUBYGEMS_FULL_URL_ENC = 'http%3a%2f%2frubygems.org%2f'
14
14
  RUBYGEMS_SHORT_URL = 'http://is.gd/gGazV'
15
15
  RUBYGEMS_SHORT_URL_ENC = 'http%3a%2f%2fis.gd%2fgGazV'
16
- RUBYLANG_FIXTURE = fixture('shorten_rubylang.html')
16
+ RUBYLANG_FIXTURE = fixture_file('shorten_rubylang.html')
17
17
  RUBYLANG_FULL_URL = 'http://ruby-lang.org/'
18
18
  RUBYLANG_FULL_URL_ENC = 'http%3a%2f%2fruby-lang.org%2f'
19
19
  RUBYLANG_SHORT_URL = 'http://is.gd/gGaM3'
@@ -23,9 +23,9 @@ Feature "update my status (send new tweet)" do
23
23
  STATUS_WITH_FULL_URLS = "ruby links: #{RUBYGEMS_FULL_URL} #{RUBYLANG_FULL_URL}"
24
24
  STATUS_WITH_SHORT_URLS = "ruby links: #{RUBYGEMS_SHORT_URL} #{RUBYLANG_SHORT_URL}"
25
25
  STATUS_WITHOUT_URLS = "bored. going to sleep."
26
- UPDATE_FIXTURE_WITH_URLS = fixture("update_with_urls.json")
27
- UPDATE_FIXTURE_WITHOUT_URLS = fixture("update_without_urls.json")
28
- UPDATE_FIXTURE_UTF8 = fixture("update_utf8.json")
26
+ UPDATE_FIXTURE_WITH_URLS = fixture_file('update_with_urls.json')
27
+ UPDATE_FIXTURE_WITHOUT_URLS = fixture_file('update_without_urls.json')
28
+ UPDATE_FIXTURE_UTF8 = fixture_file('update_utf8.json')
29
29
  UPDATE_URL = "https://api.twitter.com/1/statuses/update.json"
30
30
 
31
31
  BODY_WITH_SHORT_URLS = "status=ruby%20links%3a%20#{RUBYGEMS_SHORT_URL_ENC}%20#{RUBYLANG_SHORT_URL_ENC}"
@@ -100,7 +100,7 @@ Feature "update my status (send new tweet)" do
100
100
  end
101
101
  end
102
102
 
103
- if "".respond_to?(:encode)
103
+ if defined? Encoding
104
104
  Scenario "encode status in UTF-8 (String supports encoding)" do
105
105
  When "I start the application with 'update' command, input latin1 encoded status, and confirm" do
106
106
  @status_utf8 = "résumé"
@@ -136,7 +136,6 @@ Feature "update my status (send new tweet)" do
136
136
  Then "the application sends and shows the status" do
137
137
  @output[1].should == @status_latin1 # preview
138
138
  @output[5].should == "#{USER}, 9 hours ago:"
139
- # TODO: we should convert status back to latin-1
140
139
  @output[6].should == @status_utf8
141
140
  end
142
141
  end
@@ -9,7 +9,7 @@ Feature "using HTTP proxy" do
9
9
 
10
10
  def setup
11
11
  super
12
- stub_http_request(:get, "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1").to_return(:body => fixture("home.json"))
12
+ stub_http_request(:get, "https://api.twitter.com/1/statuses/home_timeline.json?count=20&page=1").to_return(:body => fixture_file('home.json'))
13
13
  end
14
14
 
15
15
  Scenario "enable proxy via environment variable" do
data/test/test_helper.rb CHANGED
@@ -15,10 +15,16 @@ module Tweetwine
15
15
  File.stat(file).mode & 0777
16
16
  end
17
17
 
18
- def fixture_file(filename)
18
+ def fixture_path(filename)
19
19
  File.dirname(__FILE__) << "/fixture/" << filename
20
20
  end
21
21
 
22
+ def fixture_file(filename)
23
+ File.open(fixture_path(filename)) do |f|
24
+ f.readlines.join("\n")
25
+ end
26
+ end
27
+
22
28
  def tmp_env(vars = {})
23
29
  originals = {}
24
30
  vars.each_pair do |key, value|
@@ -5,7 +5,7 @@ require "unit_helper"
5
5
  module Tweetwine::Test
6
6
 
7
7
  class CharacterEncodingTest < UnitTestCase
8
- if "".respond_to?(:encode)
8
+ if defined? Encoding
9
9
  context "when transcoding to UTF-8 when String supports encoding" do
10
10
  should "transcode string to UTF-8" do
11
11
  str_utf8 = "groß résumé"
@@ -9,7 +9,7 @@ require "yaml"
9
9
  module Tweetwine::Test
10
10
 
11
11
  class ConfigTest < UnitTestCase
12
- CONFIG_FILE = Helper.fixture_file('config_unit.yaml')
12
+ CONFIG_FILE = Helper.fixture_path('config_unit.yaml')
13
13
 
14
14
  context "when given command line arguments, no environment variables, no config file" do
15
15
  setup do
@@ -190,7 +190,7 @@ class ConfigTest < UnitTestCase
190
190
  end
191
191
 
192
192
  should "ignore nonexisting config file for initial read" do
193
- assert_contains_in_order(@default_config.keys, @config.keys) do |a, b|
193
+ assert_contains_exactly(@default_config.keys, @config.keys) do |a, b|
194
194
  # On Ruby 1.8, Symbol does not have #<=> operator for comparison.
195
195
  a.to_s <=> b.to_s
196
196
  end
@@ -263,7 +263,7 @@ class ClientTest < UnitTestCase
263
263
  @twitter.update(long_status)
264
264
  end
265
265
 
266
- if "".respond_to?(:encode)
266
+ if defined? Encoding
267
267
  should "encode status in UTF-8 (String supports encoding)" do
268
268
  status_utf8, status_latin1 = "résumé", "résumé".encode('ISO-8859-1')
269
269
  twitter_records, internal_records = create_test_twitter_status_records_from_rest_api({
@@ -447,6 +447,7 @@ class ClientTest < UnitTestCase
447
447
  end
448
448
 
449
449
  should "skip shortening URLs if required libraries are not found" do
450
+ Tweetwine::CLI.stubs(:url_shortener).raises(LoadError, 'gem not found')
450
451
  @oauth.expects(:request_signer)
451
452
  http_subresource = mock
452
453
  http_subresource.expects(:post).
@@ -455,7 +456,6 @@ class ClientTest < UnitTestCase
455
456
  @rest_api.expects(:[]).
456
457
  with("statuses/update.json").
457
458
  returns(http_subresource)
458
- @url_shortener.expects(:shorten).with(@url).raises(LoadError, "gem not found")
459
459
  @ui.expects(:warn)
460
460
  @ui.expects(:show_status_preview).with(@status)
461
461
  @ui.expects(:confirm).with("Really send?").returns(true)
@@ -619,6 +619,52 @@ class ClientTest < UnitTestCase
619
619
  end
620
620
  end
621
621
  end
622
+
623
+ private
624
+
625
+ def create_test_twitter_status_records_from_rest_api(*internal_records)
626
+ twitter_records = internal_records.map do |internal_record|
627
+ {
628
+ "user" => { "screen_name" => internal_record[:from_user] },
629
+ "created_at" => internal_record[:created_at],
630
+ "text" => internal_record[:status],
631
+ "in_reply_to_screen_name" => internal_record[:to_user]
632
+ }
633
+ end
634
+ [twitter_records, internal_records]
635
+ end
636
+
637
+ def create_test_twitter_user_records_from_rest_api(*internal_records)
638
+ twitter_records = internal_records.map do |internal_record|
639
+ twitter_record = { "screen_name" => internal_record[:from_user] }
640
+ if internal_record[:status]
641
+ twitter_record.merge!({
642
+ "status" => {
643
+ "created_at" => internal_record[:created_at],
644
+ "text" => internal_record[:status],
645
+ "in_reply_to_screen_name" => internal_record[:to_user],
646
+ }
647
+ })
648
+ end
649
+ twitter_record
650
+ end
651
+ [twitter_records, internal_records]
652
+ end
653
+
654
+ def create_test_twitter_records_from_search_api(*internal_records)
655
+ twitter_search_records = internal_records.map do |internal_record|
656
+ {
657
+ "from_user" => internal_record[:from_user],
658
+ "created_at" => internal_record[:created_at],
659
+ "text" => internal_record[:status],
660
+ "to_user" => internal_record[:to_user]
661
+ }
662
+ end
663
+ twitter_records = {
664
+ "results" => twitter_search_records
665
+ }
666
+ [twitter_records, internal_records]
667
+ end
622
668
  end
623
669
 
624
670
  end
@@ -8,51 +8,30 @@ require "mocha"
8
8
  Mocha::Configuration.prevent(:stubbing_non_existent_method)
9
9
 
10
10
  module Tweetwine::Test
11
- module Helper
12
- extend self
13
-
14
- def create_test_twitter_status_records_from_rest_api(*internal_records)
15
- twitter_records = internal_records.map do |internal_record|
16
- {
17
- "user" => { "screen_name" => internal_record[:from_user] },
18
- "created_at" => internal_record[:created_at],
19
- "text" => internal_record[:status],
20
- "in_reply_to_screen_name" => internal_record[:to_user]
21
- }
22
- end
23
- [twitter_records, internal_records]
11
+ module Assertions
12
+ # Asserts whether an Enumeration like object contains all the elements.
13
+ # Fails unless +actual+ contains the same elements as +expected+, ignoring
14
+ # the order of the elements.
15
+ #
16
+ # The method sorts +expected+ and +actual+ in order to compare them. By
17
+ # default, this sorting is done by calling #sort for each of them. If the
18
+ # method is called with a block, it is passed to the #sort calls.
19
+ def assert_contains_exactly(expected, actual, msg = '', &sorter)
20
+ expected = block_given? ? expected.sort(&sorter) : expected.sort
21
+ actual = block_given? ? actual.sort(&sorter) : actual.sort
22
+ assert_equal(expected, actual, msg)
24
23
  end
25
24
 
26
- def create_test_twitter_user_records_from_rest_api(*internal_records)
27
- twitter_records = internal_records.map do |internal_record|
28
- twitter_record = { "screen_name" => internal_record[:from_user] }
29
- if internal_record[:status]
30
- twitter_record.merge!({
31
- "status" => {
32
- "created_at" => internal_record[:created_at],
33
- "text" => internal_record[:status],
34
- "in_reply_to_screen_name" => internal_record[:to_user],
35
- }
36
- })
37
- end
38
- twitter_record
39
- end
40
- [twitter_records, internal_records]
25
+ # Fails unless +str+ is a full match to +regex+.
26
+ def assert_full_match(regex, str, msg = '')
27
+ match_data = regex.match(str)
28
+ assert(str == match_data.to_s, msg)
41
29
  end
42
30
 
43
- def create_test_twitter_records_from_search_api(*internal_records)
44
- twitter_search_records = internal_records.map do |internal_record|
45
- {
46
- "from_user" => internal_record[:from_user],
47
- "created_at" => internal_record[:created_at],
48
- "text" => internal_record[:status],
49
- "to_user" => internal_record[:to_user]
50
- }
51
- end
52
- twitter_records = {
53
- "results" => twitter_search_records
54
- }
55
- [twitter_records, internal_records]
31
+ # Fails if +str+ is a full match to +regex+.
32
+ def assert_no_full_match(regex, str, msg = '')
33
+ match_data = regex.match(str)
34
+ assert(str != match_data.to_s, msg)
56
35
  end
57
36
  end
58
37
 
@@ -88,29 +67,11 @@ module Tweetwine::Test
88
67
  end
89
68
  end
90
69
 
91
- module Assertions
92
- def assert_contains_in_order(expected, actual, msg = "", &sorter)
93
- expected = block_given? ? expected.sort(&sorter) : expected.sort
94
- actual = block_given? ? actual.sort(&sorter) : actual.sort
95
- assert_equal(expected, actual, msg)
96
- end
97
-
98
- def assert_full_match(regex, str, msg = "")
99
- match_data = regex.match(str)
100
- assert(str == match_data.to_s, msg)
101
- end
102
-
103
- def assert_no_full_match(regex, str, msg = "")
104
- match_data = regex.match(str)
105
- assert(str != match_data.to_s, msg)
106
- end
107
- end
108
-
109
70
  class UnitTestCase < ::Test::Unit::TestCase
110
71
  include WebMock::API
111
72
  include Tweetwine
112
73
  include Helper
113
- include Doubles
114
74
  include Assertions
75
+ include Doubles
115
76
  end
116
77
  end
data/tweetwine.gemspec CHANGED
@@ -1,52 +1,60 @@
1
1
  # coding: utf-8
2
2
 
3
- $LOAD_PATH.unshift(File.expand_path("../lib/", __FILE__))
4
- name = "tweetwine"
3
+ $LOAD_PATH.unshift(File.expand_path('lib', File.dirname(__FILE__)))
4
+ name = 'tweetwine'
5
5
  require name
6
- version = Tweetwine::VERSION.dup
6
+ summary = Tweetwine.summary
7
+ version = Tweetwine.version.dup
7
8
 
8
9
  Gem::Specification.new do |s|
9
- s.specification_version = 2 if s.respond_to? :specification_version=
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
-
12
10
  s.name = name
13
11
  s.version = version
14
- s.homepage = "http://github.com/tuomas/tweetwine"
15
12
 
16
- s.summary = "A simple Twitter command line agent"
17
- s.description = "A simple but tasty Twitter agent for command line use, made for fun."
13
+ s.summary = summary
14
+ s.description = <<-END
15
+ A simple but tasty Twitter agent for command line use, designed for quickly
16
+ showing the latest tweets.
17
+ END
18
+
19
+ s.email = 'tkareine@gmail.com'
20
+ s.homepage = 'https://github.com/tuomas/tweetwine'
18
21
 
19
- s.authors = "Tuomas Kareinen"
20
- s.email = "tkareine@gmail.com"
22
+ s.authors = ['Tuomas Kareinen']
21
23
 
24
+ s.executables = %w{tweetwine}
22
25
  s.files = Dir[
23
- "*.md",
24
- "*.rdoc",
25
- "LICENSE.txt",
26
- "Gemfile",
27
- "Rakefile",
28
- "tweetwine.gemspec",
29
- "{bin,contrib,example,lib,test}/**/*",
30
- "man/**/*.[1-9]",
31
- "man/**/*.ronn"
26
+ '*.md',
27
+ '*.rdoc',
28
+ 'LICENSE.txt',
29
+ 'Gemfile',
30
+ 'Rakefile',
31
+ 'tweetwine.gemspec',
32
+ '{bin,contrib,lib}/**/*',
33
+ 'man/**/*.[1-9]',
34
+ 'man/**/*.ronn'
32
35
  ]
33
- s.require_paths = %w{lib}
34
- s.executables = %w{tweetwine}
36
+ s.test_files = Dir['test/**/*']
37
+
38
+ s.add_dependency 'oauth', '~> 0.4.4'
39
+ s.add_development_dependency 'contest', '~> 0.1.2'
40
+ s.add_development_dependency 'coulda', '~> 0.6.0'
41
+ s.add_development_dependency 'gem-man', '~> 0.2.0'
42
+ s.add_development_dependency 'mcmire-matchy', '~> 0.5.2'
43
+ s.add_development_dependency 'mocha', '= 0.9.8'
44
+ s.add_development_dependency 'open4', '~> 1.0.1'
45
+ s.add_development_dependency 'ronn', '~> 0.7.3'
46
+ s.add_development_dependency 'timecop', '~> 0.3.5'
47
+ s.add_development_dependency 'webmock', '~> 1.6.1'
48
+
49
+ s.post_install_message = <<-END
50
+
51
+ Tweetwine requires a JSON parser library. Ruby 1.9 comes bundled with one by
52
+ default. For Ruby 1.8, you can install 'json' gem, for example.
35
53
 
36
- s.add_dependency "oauth", "~> 0.4.4"
37
- s.add_dependency "json", ">= 1.0.0"
38
- s.add_development_dependency "contest", "~> 0.1.2"
39
- s.add_development_dependency "coulda", "~> 0.6.0"
40
- s.add_development_dependency "gem-man", "~> 0.2.0"
41
- s.add_development_dependency "matchy", "~> 0.5.2"
42
- s.add_development_dependency "mocha", "= 0.9.8"
43
- s.add_development_dependency "open4", "~> 1.0.1"
44
- s.add_development_dependency "ronn", "~> 0.7.3"
45
- s.add_development_dependency "timecop", "~> 0.3.5"
46
- s.add_development_dependency "webmock", "~> 1.6.1"
54
+ END
47
55
 
48
56
  s.has_rdoc = true
49
- s.extra_rdoc_files = Dir["*.rdoc", "LICENSE.txt"]
50
- s.rdoc_options << "--title" << "#{name} #{version}" \
51
- << "--exclude" << "test"
57
+ s.extra_rdoc_files = Dir['*.rdoc', 'LICENSE.txt']
58
+ s.rdoc_options << '--title' << "#{name} #{version}" \
59
+ << '--exclude' << 'test'
52
60
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 1
9
- version: 0.3.1
8
+ - 2
9
+ version: 0.3.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tuomas Kareinen
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-14 00:00:00 +02:00
17
+ date: 2010-11-17 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,25 +32,10 @@ dependencies:
32
32
  version: 0.4.4
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: json
37
- prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- segments:
44
- - 1
45
- - 0
46
- - 0
47
- version: 1.0.0
48
- type: :runtime
49
- version_requirements: *id002
50
35
  - !ruby/object:Gem::Dependency
51
36
  name: contest
52
37
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &id002 !ruby/object:Gem::Requirement
54
39
  none: false
55
40
  requirements:
56
41
  - - ~>
@@ -61,11 +46,11 @@ dependencies:
61
46
  - 2
62
47
  version: 0.1.2
63
48
  type: :development
64
- version_requirements: *id003
49
+ version_requirements: *id002
65
50
  - !ruby/object:Gem::Dependency
66
51
  name: coulda
67
52
  prerelease: false
68
- requirement: &id004 !ruby/object:Gem::Requirement
53
+ requirement: &id003 !ruby/object:Gem::Requirement
69
54
  none: false
70
55
  requirements:
71
56
  - - ~>
@@ -76,11 +61,11 @@ dependencies:
76
61
  - 0
77
62
  version: 0.6.0
78
63
  type: :development
79
- version_requirements: *id004
64
+ version_requirements: *id003
80
65
  - !ruby/object:Gem::Dependency
81
66
  name: gem-man
82
67
  prerelease: false
83
- requirement: &id005 !ruby/object:Gem::Requirement
68
+ requirement: &id004 !ruby/object:Gem::Requirement
84
69
  none: false
85
70
  requirements:
86
71
  - - ~>
@@ -91,11 +76,11 @@ dependencies:
91
76
  - 0
92
77
  version: 0.2.0
93
78
  type: :development
94
- version_requirements: *id005
79
+ version_requirements: *id004
95
80
  - !ruby/object:Gem::Dependency
96
- name: matchy
81
+ name: mcmire-matchy
97
82
  prerelease: false
98
- requirement: &id006 !ruby/object:Gem::Requirement
83
+ requirement: &id005 !ruby/object:Gem::Requirement
99
84
  none: false
100
85
  requirements:
101
86
  - - ~>
@@ -106,11 +91,11 @@ dependencies:
106
91
  - 2
107
92
  version: 0.5.2
108
93
  type: :development
109
- version_requirements: *id006
94
+ version_requirements: *id005
110
95
  - !ruby/object:Gem::Dependency
111
96
  name: mocha
112
97
  prerelease: false
113
- requirement: &id007 !ruby/object:Gem::Requirement
98
+ requirement: &id006 !ruby/object:Gem::Requirement
114
99
  none: false
115
100
  requirements:
116
101
  - - "="
@@ -121,11 +106,11 @@ dependencies:
121
106
  - 8
122
107
  version: 0.9.8
123
108
  type: :development
124
- version_requirements: *id007
109
+ version_requirements: *id006
125
110
  - !ruby/object:Gem::Dependency
126
111
  name: open4
127
112
  prerelease: false
128
- requirement: &id008 !ruby/object:Gem::Requirement
113
+ requirement: &id007 !ruby/object:Gem::Requirement
129
114
  none: false
130
115
  requirements:
131
116
  - - ~>
@@ -136,11 +121,11 @@ dependencies:
136
121
  - 1
137
122
  version: 1.0.1
138
123
  type: :development
139
- version_requirements: *id008
124
+ version_requirements: *id007
140
125
  - !ruby/object:Gem::Dependency
141
126
  name: ronn
142
127
  prerelease: false
143
- requirement: &id009 !ruby/object:Gem::Requirement
128
+ requirement: &id008 !ruby/object:Gem::Requirement
144
129
  none: false
145
130
  requirements:
146
131
  - - ~>
@@ -151,11 +136,11 @@ dependencies:
151
136
  - 3
152
137
  version: 0.7.3
153
138
  type: :development
154
- version_requirements: *id009
139
+ version_requirements: *id008
155
140
  - !ruby/object:Gem::Dependency
156
141
  name: timecop
157
142
  prerelease: false
158
- requirement: &id010 !ruby/object:Gem::Requirement
143
+ requirement: &id009 !ruby/object:Gem::Requirement
159
144
  none: false
160
145
  requirements:
161
146
  - - ~>
@@ -166,11 +151,11 @@ dependencies:
166
151
  - 5
167
152
  version: 0.3.5
168
153
  type: :development
169
- version_requirements: *id010
154
+ version_requirements: *id009
170
155
  - !ruby/object:Gem::Dependency
171
156
  name: webmock
172
157
  prerelease: false
173
- requirement: &id011 !ruby/object:Gem::Requirement
158
+ requirement: &id010 !ruby/object:Gem::Requirement
174
159
  none: false
175
160
  requirements:
176
161
  - - ~>
@@ -181,8 +166,11 @@ dependencies:
181
166
  - 1
182
167
  version: 1.6.1
183
168
  type: :development
184
- version_requirements: *id011
185
- description: A simple but tasty Twitter agent for command line use, made for fun.
169
+ version_requirements: *id010
170
+ description: |
171
+ A simple but tasty Twitter agent for command line use, designed for quickly
172
+ showing the latest tweets.
173
+
186
174
  email: tkareine@gmail.com
187
175
  executables:
188
176
  - tweetwine
@@ -214,6 +202,8 @@ files:
214
202
  - lib/tweetwine/url_shortener.rb
215
203
  - lib/tweetwine/util.rb
216
204
  - lib/tweetwine.rb
205
+ - man/tweetwine.7
206
+ - man/tweetwine.7.ronn
217
207
  - test/example/application_behavior_example.rb
218
208
  - test/example/example_helper.rb
219
209
  - test/example/search_statuses_example.rb
@@ -251,16 +241,16 @@ files:
251
241
  - test/unit/unit_helper.rb
252
242
  - test/unit/url_shortener_test.rb
253
243
  - test/unit/util_test.rb
254
- - man/tweetwine.7
255
- - man/tweetwine.7.ronn
256
244
  has_rdoc: true
257
- homepage: http://github.com/tuomas/tweetwine
245
+ homepage: https://github.com/tuomas/tweetwine
258
246
  licenses: []
259
247
 
260
- post_install_message:
248
+ post_install_message: "\n\
249
+ Tweetwine requires a JSON parser library. Ruby 1.9 comes bundled with one by\n\
250
+ default. For Ruby 1.8, you can install 'json' gem, for example.\n\n"
261
251
  rdoc_options:
262
252
  - --title
263
- - tweetwine 0.3.1
253
+ - tweetwine 0.3.2
264
254
  - --exclude
265
255
  - test
266
256
  require_paths:
@@ -286,7 +276,43 @@ requirements: []
286
276
  rubyforge_project:
287
277
  rubygems_version: 1.3.7
288
278
  signing_key:
289
- specification_version: 2
290
- summary: A simple Twitter command line agent
291
- test_files: []
292
-
279
+ specification_version: 3
280
+ summary: Tweetwine shows the latest tweets from the command line quickly.
281
+ test_files:
282
+ - test/example/application_behavior_example.rb
283
+ - test/example/example_helper.rb
284
+ - test/example/search_statuses_example.rb
285
+ - test/example/show_followers_example.rb
286
+ - test/example/show_friends_example.rb
287
+ - test/example/show_home_example.rb
288
+ - test/example/show_mentions_example.rb
289
+ - test/example/show_user_example.rb
290
+ - test/example/update_status_example.rb
291
+ - test/example/use_http_proxy_example.rb
292
+ - test/fixture/config_example.yaml
293
+ - test/fixture/config_unit.yaml
294
+ - test/fixture/home.json
295
+ - test/fixture/mentions.json
296
+ - test/fixture/oauth.rb
297
+ - test/fixture/search.json
298
+ - test/fixture/shorten_rubygems.html
299
+ - test/fixture/shorten_rubylang.html
300
+ - test/fixture/update_utf8.json
301
+ - test/fixture/update_with_urls.json
302
+ - test/fixture/update_without_urls.json
303
+ - test/fixture/user.json
304
+ - test/fixture/users.json
305
+ - test/test_helper.rb
306
+ - test/unit/character_encoding_test.rb
307
+ - test/unit/cli_test.rb
308
+ - test/unit/config_test.rb
309
+ - test/unit/http_test.rb
310
+ - test/unit/oauth_test.rb
311
+ - test/unit/obfuscate_test.rb
312
+ - test/unit/option_parser_test.rb
313
+ - test/unit/promise_test.rb
314
+ - test/unit/twitter_test.rb
315
+ - test/unit/ui_test.rb
316
+ - test/unit/unit_helper.rb
317
+ - test/unit/url_shortener_test.rb
318
+ - test/unit/util_test.rb