Created
April 29, 2010 15:49
-
-
Save lucaspiller/383802 to your computer and use it in GitHub Desktop.
Play Spec - Making your specs fun!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# Play Spec v0.2.0 | |
# Making your specs fun! | |
# | |
# 1) Download | |
# 2) Save as play_spec, somewhere in your path | |
# 3) chmod +x play_spec | |
# 4) Run it! | |
# play_spec spec/controllers/application_spec.rb | |
# | |
# History | |
# | |
# 0.2.0 | |
# Tidyer points display after specs | |
# Lots of pretty colours | |
# | |
# 0.1.1 | |
# Fix silly bugs | |
# | |
# 0.1.0 | |
# Initial version | |
# | |
require 'yaml' | |
require 'open3' | |
require 'rubygems' | |
# load options | |
begin | |
$options = YAML::load_file(File.expand_path('~/.play_spec')) | |
rescue Errno::ENOENT | |
$options = nil | |
end | |
# doesn't exist yet | |
if $options.nil? | |
$options = { | |
:points => 0, | |
:name => ENV['USER'] | |
} | |
end | |
def terminal_width | |
$term_width ||= %x{stty size}.split[1].to_i | |
end | |
$small_width = 40 | |
def level | |
Math.sqrt($options[:points] < 1 ? 1 : ($options[:points] / 2)).to_i | |
end | |
def render_status_line | |
if defined? Term::ANSIColor | |
part_width = (terminal_width - 4) / 3 | |
name_part = $options[:name].ljust(part_width) | |
points_part = ($options[:points].to_s + " point(s)").ljust(part_width) | |
level_part = ("level " + level.to_s).ljust(part_width) | |
print Term::ANSIColor.negative, Term::ANSIColor.bold, "\n" | |
print (" " + name_part + points_part + level_part + " ").ljust(terminal_width) | |
print "\n", Term::ANSIColor.reset | |
else | |
print "\n" | |
print $options[:name].ljust(20) | |
print ($options[:points].to_s + " point(s)").ljust(20) | |
print ("level " + level.to_s).ljust(20) | |
print "\n" | |
end | |
end | |
def alter_points(points, reason) | |
$options[:points] += points | |
if defined? Term::ANSIColor | |
part_width = terminal_width / 3 | |
if points < 0 | |
print Term::ANSIColor.bold, Term::ANSIColor.red, points.to_s.rjust(10), Term::ANSIColor.reset | |
else | |
print Term::ANSIColor.bold, Term::ANSIColor.green, (("+" + points.to_s).rjust(10)), Term::ANSIColor.reset | |
end | |
print Term::ANSIColor.bold, ' ' + reason, "\n", Term::ANSIColor.reset | |
else | |
if points < 0 | |
print points.to_s.rjust(10) | |
else | |
print(("+" + points.to_s).rjust(10)) | |
end | |
print ' ' + reason | |
print "\n" | |
end | |
end | |
# save options at exit | |
at_exit do | |
render_status_line | |
File.open(File.expand_path('~/.play_spec'), 'w') { |f| f.write(YAML::dump($options)) } | |
end | |
# catch ctrl c | |
Signal.trap('INT') { exit } | |
# check gems | |
begin | |
gem 'rspec'; require 'spec' | |
rescue Gem::LoadError | |
alter_points -10, "You need the `rspec' gem installed. n00b." | |
exit | |
end | |
begin | |
gem 'term-ansicolor'; require 'term/ansicolor' | |
rescue Gem::LoadError | |
alter_points -1, "You need the `term-ansicolor' gem installed." | |
exit | |
end | |
unless ARGV.size == 1 | |
print "Err... Nothing to play with?\n\n" | |
print "usage: play_spec [options] file\n" | |
exit | |
end | |
file = ARGV[0] | |
unless File.exists?(file) | |
print "Err... Can't find `#{ARGV[0]}'?\n\n" | |
print "usage: play_spec [options] file\n" | |
exit | |
end | |
# sexy, its like being back in 1986! | |
print Term::ANSIColor.on_red, " " | |
print Term::ANSIColor.on_yellow, " " | |
print Term::ANSIColor.on_green, " " | |
print Term::ANSIColor.on_blue, " " | |
print "\n" | |
print Term::ANSIColor.on_red, " " | |
print Term::ANSIColor.on_yellow, " " | |
print Term::ANSIColor.on_green, " " | |
print Term::ANSIColor.on_blue, " " | |
print "\n" | |
print Term::ANSIColor.on_red, " " | |
print Term::ANSIColor.on_yellow, " " | |
print Term::ANSIColor.on_green, " " | |
print Term::ANSIColor.on_blue, " " | |
print Term::ANSIColor.reset, Term::ANSIColor.bold, " OK... Lets play spec!", Term::ANSIColor.reset | |
print "\n" | |
print Term::ANSIColor.on_red, " " | |
print Term::ANSIColor.on_yellow, " " | |
print Term::ANSIColor.on_green, " " | |
print Term::ANSIColor.on_blue, " " | |
print Term::ANSIColor.reset, " Copyright (C) 1986", Term::ANSIColor.reset | |
print "\n" | |
print Term::ANSIColor.on_red, " " | |
print Term::ANSIColor.on_yellow, " " | |
print Term::ANSIColor.on_green, " " | |
print Term::ANSIColor.on_blue, " " | |
print Term::ANSIColor.reset | |
print "\n" | |
round = 0 | |
last_changed = 0 | |
examples = nil | |
failures = nil | |
pending = nil | |
loop do | |
# check it exists | |
unless File.exists?(file) | |
print "Looks like that's it folks!" | |
exit | |
end | |
# any change? | |
if last_changed == 0 or File.mtime(file) > last_changed | |
old_examples = examples | |
old_failures = failures | |
old_pending = pending | |
last_changed = File.mtime(file) | |
print "\n", Term::ANSIColor.on_cyan, Term::ANSIColor.black, " Get ready for round #{round += 1}! ", Term::ANSIColor.reset, "\n" | |
# run the command | |
stdin, stdout, stderr = Open3.popen3("spec -fs --color #{file}") | |
loop do | |
out = stdout.gets | |
break if out.nil? | |
print out | |
if out =~ /([0-9]+) examples?, ([0-9]+) failures?(, ([0-9]+) pending)?/ | |
examples = $1.to_i | |
failures = $2.to_i | |
pending = ($4 || 0).to_i | |
end | |
end | |
# points baby | |
if not old_failures.nil? | |
print "\n" | |
points = old_failures - failures | |
if old_failures > failures | |
alter_points points, "You fixed #{points} example(s), great job!" | |
elsif failures > old_failures | |
alter_points (points * 2), "You do know you are supposed to fix the specs?" | |
end | |
end | |
if failures == 0 | |
print "\n", Term::ANSIColor.on_green, Term::ANSIColor.bold, Term::ANSIColor.blink | |
print " Looks like your work here is done! \n" | |
print Term::ANSIColor.reset | |
exit | |
end | |
render_status_line | |
else | |
sleep 1 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment