Skip to content

Instantly share code, notes, and snippets.

@esmevane
Last active December 29, 2015 15:56
Show Gist options
  • Save esmevane/70319488088665269af4 to your computer and use it in GitHub Desktop.
Save esmevane/70319488088665269af4 to your computer and use it in GitHub Desktop.
[ Ruby / Rake ]: Spec shame yourself.

Spec shame

Because you spiked out your entire gem or Rails app without bothering to write a single spec. Then you wanted to see your test coverage to get rolling on it, so you install simplecov and it said you had 95%! But of course, that's a lie. It just has no idea you have so many vacant specs.

Usage: time to shame yourself

Just require this file in your Rakefile, like so:

require File.join(__dir__, 'tasks/spec_shame.rb')

(Assuming it's in tasks/)

If you're in rails, everywhere it says SpecShame.new, replace that with SpecShame.new(Rails.root, 'app') and change project = "ProjectName" to project = nil.

require 'active_support/core_ext/string'
class SpecShame
attr_reader :root, :source, :spec
def initialize(root = __dir__, source = "lib", spec = "spec")
@root = root
@source = source
@spec = spec
end
def candidates
untested_files.gsub(".rb", "_spec.rb").gsub(source, spec)
end
def source_files
FileList.new("#{source}/**/*.rb")
end
def existing_specs
FileList.new("#{spec}/**/*_spec.rb")
end
def get_source
-> file do
file.gsub("_spec.rb", ".rb").gsub(spec, source)
end
end
def tested_source_files
existing_specs.gsub("_spec.rb", ".rb").gsub(spec, source)
end
def untested_files
source_files - tested_source_files
end
end
class EmptySpec
TEMPLATE = <<-EOF.strip_heredoc
require 'spec_helper'
describe <%= namespace %> do
it 'is stubbed and awaits tests'
end
EOF
attr_reader :namespace
def initialize(root, source)
@namespace = source
.gsub("lib/", '')
.ext('')
.split("/")
.slice(1..-1)
.map(&:camelize)
.unshift(root)
.join("::")
end
def to_s
ERB.new(TEMPLATE).result(binding)
end
end
desc "Shame yourself by populating empty specs for all untested files."
task spec_shame: SpecShame.new.candidates
rule "_spec.rb" => SpecShame.new.get_source do |task|
project = "ProjectName"
contents = EmptySpec.new(project, task.source).to_s
path = File.join(__dir__, '..', task.name)
directory = path.to_s.pathmap('%d')
mkdir_p(directory) unless Dir.exists?(directory)
File.open(path, "w+") { |file| file.puts(contents) }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment