Skip to content

Commit

Permalink
big refactor 1
Browse files Browse the repository at this point in the history
  • Loading branch information
dougmcbride committed Nov 10, 2009
1 parent 13337d2 commit de8b09d
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 37 deletions.
6 changes: 6 additions & 0 deletions Rakefile
@@ -0,0 +1,6 @@
namespace :spec do
task :autotest do
require './spec/rspec_autotest'
RspecAutotest.run
end
end
152 changes: 152 additions & 0 deletions spec/rspec_autotest.rb
@@ -0,0 +1,152 @@
# (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

require 'rubygems'
gem 'ZenTest'
require 'autotest'

$TESTING = true

class RspecAutotest < Autotest
attr_accessor :spec_command
def initialize # :nodoc:
@spec_command = "spec --diff unified"
super
@exceptions = %r%^\./(?:coverage|doc)%
end

def tests_for_file(filename)
puts filename
case filename
when /^lib\/.*\.rb$/ then
impl = File.basename(filename).gsub('_', '_?').sub(/\.rb$/, '')
@files.keys.select do |k|
k =~ %r%^spec/.*#{impl}_spec\.rb$%
end
when %r%^spec/spec_helper.rb% then
@files.keys.select do |f|
f =~ %r%^spec/.*_spec\.rb$%
end
when /^spec\/.*_spec\.rb$/ then
[filename]
when /#{Regexp.quote(File.basename(__FILE__))}/
# Don't respond to changes to this file
[]
else
@output.puts "Dunno! #{filename}" if $TESTING
[]
end
end

def handle_results(results)
failed = results.scan(/^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m)
@files_to_test = consolidate_failures failed
unless @files_to_test.empty? then
hook :red
else
hook :green
end unless $TESTING
@tainted = true unless @files_to_test.empty?
end

def consolidate_failures(failed)
filters = Hash.new { |h,k| h[k] = [] }
failed.each do |spec, failed_trace|
@files.keys.select{|f| f =~ /spec\//}.each do |f|
if failed_trace =~ Regexp.new(f)
filters[f] << spec
break
end
end
end
return filters
end

def make_test_cmd(files_to_test)
cmds = []
full, partial = files_to_test.partition { |k,v| v.empty? }

unless full.empty? then
classes = full.map {|k,v| k}.flatten.join(' ')
cmds << "#{spec_command} #{classes}"
end

partial.each do |klass, methods|
methods.each { |meth| cmds << "#{spec_command} -s #{meth.inspect} #{klass}" }
end

return cmds.join('; ')
end
end

class RspecOnRailsAutotest < RspecAutotest
def initialize # :nodoc:
super
@exceptions = %r%^\./(?:coverage|db|doc|log|public|script|vendor)%
end

def tests_for_file(filename)
case filename
when %r%^spec/fixtures/(.*)s.yml% then
["spec/models/#{$1}_spec.rb",
"spec/controllers/#{$1}_controller_spec.rb"]
when %r%^spec/models/.*rb$% then
[filename]
when %r%^spec/controllers/.*\.rb$% then
[filename]
when %r%^spec/views/.*\.rb$% then
[filename]
when %r%^spec/helpers/.*\.rb$% then
[filename]
when %r%^app/models/(.*)\.rb$% then
["spec/models/#{$1}_spec.rb"]
when %r%^app/helpers/application_helper.rb% then
@files.keys.select { |f|
f =~ %r%^spec/controllers/.*_spec\.rb$%
}
when %r%^app/helpers/(.*)_helper.rb% then
["spec/controllers/#{$1}_controller_spec.rb", "spec/helpers/#{$1}_spec.rb"]
when %r%^app/controllers/application.rb$% then
@files.keys.select { |f|
f =~ %r%^spec/controllers/.*_spec\.rb$%
}
when %r%^app/controllers/(.*)\.rb$% then
["spec/controllers/#{$1}_spec.rb"]
when %r%^app/views/layouts/% then
[]
when %r%^app/views/(.*)/% then
["spec/controllers/#{$1}_controller_spec.rb", "spec/views/#{$1}_spec.rb"]
when %r%^config/routes.rb$% then
@files.keys.select do |f|
f =~ %r%^spec/controllers/.*_spec\.rb$%
end
when %r%^spec/spec_helper.rb%,
%r%^config/((boot|environment(s/test)?).rb|database.yml)% then
@files.keys.select do |f|
f =~ %r%^spec/(models|controllers)/.*_spec\.rb$%
end
else
@output.puts "Dunno! #{filename}" if $TESTING
[]
end.uniq.select { |f| @files.has_key? f }
end
end
85 changes: 85 additions & 0 deletions spec/user_spec.rb
@@ -0,0 +1,85 @@
require 'set'
require 'user'
require 'pivotal-tracker'

describe "The User class" do
it "should cache users"

it "should have a save location" do
User.save_location = '/tmp'
User.save_location.should == '/tmp'
end

it "should determine a save filename" do
User.save_location = '/tmp'
User.save_filename('dug').should == '/tmp/dug.yml'
end
end

describe "A user" do
before :each do
@user = User.for_nick 'dug'
@the_project = mock 'project'
@the_story = mock 'story'
@the_tracker = mock 'tracker', :project => @the_project
PivotalTracker.stub!(:new).with('2', 'fish').and_return(@the_tracker)
@user.stub!(:save)
end

it "should remember a token" do
@user.token = 'fish'
@user.token.should == 'fish'
end

it "should get a project by id" do
@user.token = "fish"
@user.current_project_id = "2"
@user.current_project.should == @the_project
@user.current_tracker.should == @the_tracker
end

it "should set current story by id" do
@user.current_tracker = @the_tracker
@the_tracker.should_receive(:find_story).with('pie').and_return(@the_story)
@user.current_story_id = 'pie'
@user.current_story.should == @the_story
end

it "should update stories" do
@user.current_tracker = @the_tracker
@user.current_story = @the_story
@the_story.should_receive(:name=).with('mud')
@the_tracker.should_receive(:update_story).with(@the_story)
@user.update_story 'name' => 'mud'
end

it "should create stories" do
atts = {:name => 'bananas should be tasty', :story_type => 'feature'}
Story.stub!(:new).with(atts).and_return(@the_story)
@user.current_tracker = @the_tracker
@the_tracker.should_receive(:create_story).with(@the_story).and_return(@the_story)
story = @user.create_story :name => 'bananas should be tasty', :story_type => 'feature'
story.should == @the_story
end

it "should find stories" do
stories = [1,2,3]
criteria = {:state => 'finished'}
@user.current_tracker = @the_tracker
@the_tracker.should_receive(:find).with(criteria).and_return(stories)
@user.find_stories(criteria).should == stories
end

it "should list projects" do
tracker3 = mock 'tracker3', :project => 3
tracker4 = mock 'tracker4', :project => 4
PivotalTracker.stub!(:new).with('3', 'fish').and_return(tracker3)
PivotalTracker.stub!(:new).with('4', 'fish').and_return(tracker4)
@user.token = 'fish'
@user.current_project_id = "2"
@user.current_project_id = "3"
@user.current_project_id = "4"
@user.projects.should == Set.new([@the_project,3,4])
end
end

60 changes: 23 additions & 37 deletions trakbot.rb
@@ -1,7 +1,6 @@
require 'optparse'
require 'chatbot'
require 'rubygems'
gem 'jsmestad-pivotal-tracker'
require 'pivotal-tracker'
require 'pp'
require 'yaml'
Expand Down Expand Up @@ -98,75 +97,61 @@ def initialize(options)
add_actions({
%w[token (\S+)].to_regexp =>
lambda do |nick, event, match|
user = get_user_for_nick nick
user[:token] = match[1]
save_state
user = User.for_nick nick
user.token = match[1]
reply event, "Got it, #{nick}."
end,

%w[(?:new|add) (feature|chore|bug|release) (.+)].to_regexp =>
lambda do |nick, event, match|
user = get_user_for_nick nick
tracker = current_tracker_for nick
story = tracker.create_story Story.new(:name => match[2], :story_type => match[1])
user[:current_story] = story.id
save_state
user = User.for_nick nick
story = user.create_story :name => match[2], :story_type => match[1]
reply event, "Added story #{story.id}"
end,

%w[project (\S+)].to_regexp =>
lambda do |nick, event, match|
user = get_user_for_nick(nick)
user[:projects][match[1]] ||= {}
tracker = get_tracker nick, match[1]
user[:current_project] = match[1]
save_state
reply event, "#{nick}, you're on #{tracker.project.name}."
user = User.for_nick nick
user.current_project_id = match[1]
reply event, "#{nick}, you're on #{@user.current_project.name}."
end,

%w[story (\S+)].to_regexp =>
lambda do |nick, event, match|
begin
user = get_user_for_nick nick
tracker = current_tracker_for nick
user[:current_story] = match[1]
save_state
reply event, "#{nick}'s current story: #{tracker.find_story(match[1]).name}"
user = User.for_nick nick
user.current_story_id = match[1]
reply event, "#{nick}'s current story: #{user.current_story.name}"
rescue RestClient::ResourceNotFound
reply event, "#{nick}, I couldn't find that one. Maybe it's not in your current project (#{tracker.project.name})?"
reply event, "#{nick}, I couldn't find that one. Maybe it's not in your current project (#{user.current_project.name})?"
end
end,

%w[story (story_type|estimate|current_state|name) (.+)].to_regexp =>
lambda do |nick, event, match|
begin
user = get_user_for_nick nick
tracker = current_tracker_for nick
story = tracker.find_story(current_story_for nick)
story.send "#{match[1]}=".to_sym, match[2]
tracker.update_story story
user = User.for_nick nick
user.update_story match[1] => match[2]
rescue RestClient::ResourceNotFound
reply event, "#{nick}, I couldn't find that one. Maybe it's not in your current project (#{tracker.project.name})?"
reply event, "#{nick}, I couldn't find that one. Maybe it's not in your current project (#{user.current_project.name})?"
end
end,

%w[finished].to_regexp =>
lambda do |nick, event, match|
tracker = current_tracker_for nick
stories = tracker.find :state => 'finished'
user = User.for_nick nick
stories = user.find_stories :state => 'finished'
reply event, "There are #{stories.size} finished stories."

#reply(event, stories.map{|s| "#{s.story_type.capitalize} #{s.id}: #{s.name}"}.join("\r"))

stories.each_with_index do |s, i|
reply event, "#{i+1}) #{s.story_type.capitalize} #{s.id}: #{s.name}"
stories.each_with_index do |story, i|
reply event, "#{i+1}) #{story.story_type.capitalize} #{story.id}: #{story.name}"
end
end,

%w[deliver finished].to_regexp =>
lambda do |nick, event, match|
tracker = current_tracker_for nick
stories = tracker.deliver_all_finished_stories
user = User.for_nick nick
stories = user.current_tracker.deliver_all_finished_stories

if stories.empty?
reply event, "No finished stories in project :("
Expand All @@ -178,8 +163,9 @@ def initialize(options)

%w[projects].to_regexp =>
lambda do |nick, event, match|
get_user_for_nick(nick)[:projects].keys.each do |p|
reply event, "#{p}: " + get_tracker(nick, p).project.name
user = User.for_nick nick
user.projects.each do |project|
reply event, "#{project.id}: #{project.name}"
end
end,

Expand Down

0 comments on commit de8b09d

Please sign in to comment.