From 6e3ef6ad9550696956c5bd36dd28c135e1c9291a Mon Sep 17 00:00:00 2001 From: Bruce Williams Date: Thu, 30 Aug 2012 13:12:57 -0300 Subject: [PATCH] Use rspec2, add basic channel mocking --- .rspec | 1 + Rakefile | 80 +++++++++++++++++++++++ bin/twtail | 2 +- lib/twtail.rb | 122 +++++++++++++++++++---------------- spec/spec.opts | 1 - spec/spec_helper.rb | 10 ++- spec/support/mock_channel.rb | 28 ++++++++ spec/twtail_spec.rb | 25 ++++--- 8 files changed, 203 insertions(+), 66 deletions(-) create mode 100644 .rspec create mode 100644 Rakefile delete mode 100644 spec/spec.opts create mode 100644 spec/support/mock_channel.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..4e1e0d2 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--color diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..abe27b5 --- /dev/null +++ b/Rakefile @@ -0,0 +1,80 @@ +begin + require 'rspec' +rescue LoadError + require 'rubygems' + require 'rspec' +end +begin + require 'rspec/core/rake_task' +rescue LoadError + puts <<-EOS +To use rspec for testing you must install rspec2 gem: + gem install rspec +EOS + exit(0) +end + +begin + require 'jeweler' + Jeweler::Tasks.new do |gem| + gem.name = "twtail" + gem.summary = "twitter tail based on search.twitter.com - works perfectly with crappy internet connections usually available at tech conferences" + gem.description = "twitter tail based on search.twitter.com - works perfectly with crappy internet connections usually available at tech conferences" + gem.email = "caffeine@gmail.com" + gem.homepage = "http://github.com/caffo/twtail" + gem.authors = ["rodrigo franco (caffo)"] + gem.add_dependency "htmlentities", ">= 4.2.1" + gem.add_dependency "simple-rss", ">= 1.2.2" + gem.add_development_dependency 'rspec', '>= 2.11.0' + end + Jeweler::GemcutterTasks.new +rescue LoadError + puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" +end + +require 'rake/testtask' +Rake::TestTask.new(:test) do |test| + test.libs << 'lib' << 'test' + test.pattern = 'test/**/test_*.rb' + test.verbose = true +end + +begin + require 'rcov/rcovtask' + Rcov::RcovTask.new do |test| + test.libs << 'test' + test.pattern = 'test/**/test_*.rb' + test.verbose = true + end +rescue LoadError + task :rcov do + abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov" + end +end + +task :test => :check_dependencies + +task :default => :test + +require 'rake/rdoctask' +Rake::RDocTask.new do |rdoc| + version = File.exist?('VERSION') ? File.read('VERSION') : "" + + rdoc.rdoc_dir = 'rdoc' + rdoc.title = "twtail #{version}" + rdoc.rdoc_files.include('README*') + rdoc.rdoc_files.include('lib/**/*.rb') +end + +desc 'Default: run specs.' +task :default => :spec + +desc "Run specs" +RSpec::Core::RakeTask.new do |t| + t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default. +end + +task :default do + puts "\nAvailable tasks: #{Rake.application.tasks.to_a.join(', ')}" + puts "Use rake -T for more info.\n\n" +end diff --git a/bin/twtail b/bin/twtail index cce1ee2..d0d225a 100755 --- a/bin/twtail +++ b/bin/twtail @@ -3,4 +3,4 @@ $:.unshift(File.dirname(__FILE__) + '/../lib') require 'twtail' -puts (Twtail.execute(ARGV[0])) \ No newline at end of file +Twtail.execute(ARGV[0]) diff --git a/lib/twtail.rb b/lib/twtail.rb index 1793a45..2810da4 100644 --- a/lib/twtail.rb +++ b/lib/twtail.rb @@ -1,7 +1,6 @@ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) - require 'rubygems' require 'simple-rss' require 'open-uri' @@ -10,72 +9,87 @@ require 'htmlentities' module Twtail + class << self + attr_writer :channel + attr_writer :error_channel + end + + def self.channel + @channel ||= STDOUT + end - def execute(params=nil) - trap("INT") { exit } - params ? self.search(params) : self.help + def self.error_channel + @error_channel ||= STDERR + end + + def self.execute(params=nil) + trap("INT") { exit } + if params + search(params) + else + error_channel.puts help end + end - def help - return("Usage: twtail [xbox+live | from:caffo | '#barcamp' | '-spammed_keyword']") - end + def self.help + "Usage: twtail [xbox+live | from:caffo | '#barcamp']" + end - def search(params) - begin - pointer = Time.now-86400 - parameter = CGI::escape(params) - url = "http://search.twitter.com/search.atom?q=#{parameter}" - feed = SimpleRSS.parse open(url) - coder = HTMLEntities.new + def self.search(params) + begin + pointer = Time.now-86400 + parameter = CGI::escape(params) + url = "http://search.twitter.com/search.atom?q=#{parameter}" + feed = SimpleRSS.parse open(url) + coder = HTMLEntities.new - puts "\033[37m==\033[0m \033[1;32m#{feed.channel.title}\033[0m \033[37m==\033[0m\n\n" unless Module.constants.include?("DEBUG") - if feed.items[0].published < pointer - puts "No items found since yesterday" - exit - end + channel.puts "\033[37m==\033[0m \033[1;32m#{feed.channel.title}\033[0m \033[37m==\033[0m\n\n" + + if feed.items[0].published < pointer + channel.puts "No items found since yesterday" + exit + end - while 1==1 do - new_items = false - begin - feed = SimpleRSS.parse open(url) rescue nil - feed.items.each do |item| - next if item.published < pointer - unless Module.constants.include?("DEBUG") - msg = colorize(37, coder.decode(item.title)) - msg = colorize(31, msg, /(#[[\d]]?(\S+))/i) - msg = colorize(33, msg, /(@[[\d]]?(\S+))/i) - msg = colorize(34, msg, /(https?:\/\/[\S]+)/i) - puts "#{coder.decode(from_parser(item.author))} #{msg}" - new_items = true - end - end - rescue + while 1==1 do + new_items = false + begin + feed = SimpleRSS.parse open(url) rescue nil + feed.items.each do |item| + next if item.published < pointer + msg = colorize(37, coder.decode(item.title)) + msg = colorize(31, msg, /(#[[\d]]?(\S+))/i) + msg = colorize(33, msg, /(@[[\d]]?(\S+))/i) + msg = colorize(34, msg, /(https?:\/\/[\S]+)/i) + channel.puts "#{coder.decode(from_parser(item.author))} #{msg}" + new_items = true end - puts "\n\n" if new_items == true - pointer = feed.items[0].published + 1 - break if Module.constants.include?("DEBUG") - sleep(60) + rescue end - rescue - "No data was found for this criteria. please try with other keywords." + channel.puts "\n\n" if new_items == true + pointer = feed.items[0].published + 1 + break if $testing + sleep(60) end + rescue + "No data was found for this criteria. please try with other keywords." end + end - def from_parser(from) - from.sub!(/(\w+).+\n.+/,'\1') - from.gsub!(/.*(\(.*)/, "\\1") - from.gsub!(/\)http/, ") - http") - from = colorize(32, "#{from}: ") - colorize(4, from, /(https?:\/\/[\S]+)/i) - end + def self.from_parser(from) + from.sub!(/(\w+).+\n.+/,'\1') + from.gsub!(/.*(\(.*)/, "\\1") + from.gsub!(/\)http/, ") - http") + from = colorize(32, "#{from}: ") + colorize(4, from, /(https?:\/\/[\S]+)/i) + end - def colorize(color, text, regex = nil) - if regex.nil? - "\033[#{color}m#{text}\033[0m" - else - text.gsub(regex, "\033[#{color}m\\1\033[0m") - end + def self.colorize(color, text, regex = nil) + if regex.nil? + "\033[#{color}m#{text}\033[0m" + else + text.gsub(regex, "\033[#{color}m\\1\033[0m") end end + end diff --git a/spec/spec.opts b/spec/spec.opts deleted file mode 100644 index cf6add7..0000000 --- a/spec/spec.opts +++ /dev/null @@ -1 +0,0 @@ ---colour \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 40a90ee..6a73f83 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,16 @@ begin - require 'spec' + require 'rspec' rescue LoadError require 'rubygems' gem 'rspec' - require 'spec' + require 'rspec' end $:.unshift(File.dirname(__FILE__) + '/../lib') require 'twtail' + +$testing = true + +Dir.glob(File.expand_path('../support/*.rb', __FILE__)) do |filename| + require filename +end diff --git a/spec/support/mock_channel.rb b/spec/support/mock_channel.rb new file mode 100644 index 0000000..21021f5 --- /dev/null +++ b/spec/support/mock_channel.rb @@ -0,0 +1,28 @@ +shared_context "mock channel", :mock_channel => true do + + let(:channel) { StringIO.new } + let(:error_channel) { StringIO.new } + + before do + @old_channel = Twtail.channel + Twtail.channel = channel + @old_error_channel = Twtail.error_channel + Twtail.error_channel = error_channel + end + + after do + Twtail.channel = @old_channel + Twtail.error_channel = @old_error_channel + end + + def output + channel.rewind + channel.read + end + + def error_output + error_channel.rewind + error_channel.read + end + +end diff --git a/spec/twtail_spec.rb b/spec/twtail_spec.rb index 038c55b..d78f79b 100644 --- a/spec/twtail_spec.rb +++ b/spec/twtail_spec.rb @@ -1,14 +1,23 @@ require File.dirname(__FILE__) + '/spec_helper.rb' -describe "A call without parameters" do +describe Twtail, 'execute', :mock_channel => true do + + context "without parameters" do + before do + Twtail.execute(nil) + end it "should return the application usage" do - Twtail.execute(nil).should == "Usage: twtail [xbox+live | from:caffo | '#barcamp']" + error_output.should == "Usage: twtail [xbox+live | from:caffo | '#barcamp']\n" end -end + end -describe "A call with a parameter" do - it "should display some results" do - DEBUG=true - Twtail.execute("xbox").should ==~ /xbox/ + context "with a parameter" do + before do + Twtail.execute("xbox") + end + it "should display some results" do + output.should =~ /xbox/ + end end -end \ No newline at end of file + +end