Skip to content

Instantly share code, notes, and snippets.

@mockdeep
Last active January 4, 2016 20:49
Show Gist options
  • Save mockdeep/8676728 to your computer and use it in GitHub Desktop.
Save mockdeep/8676728 to your computer and use it in GitHub Desktop.
List rspec example groups
#!/usr/bin/env ruby
ENV['RAILS_ENV'] = 'test'
require_relative '../config/environment'
class Speccer
def configuration
@configuration ||= RSpec::Core::Configuration.new
end
def world
RSpec.world
end
def example_groups
world.example_groups
end
def descriptions
options.configure(configuration)
configuration.load_spec_files
example_groups.map(&:description)
end
def rspec_options
RSpec::Core::ConfigurationOptions.new(%w(--fail-fast spec))
end
def parsed_options
rspec_options.tap { |options| options.parse_options }
end
def options
@options ||= parsed_options
end
end
class ClassSignature
attr_accessor :file_path
def initialize(file_path)
self.file_path = file_path
end
def method_signatures
# TODO: handle files that have nested classes/modules
return [] if class_or_module_name.nil?
instance_method_signatures + class_method_signatures
end
def instance_method_signatures
instance_method_names.map do |method_name|
"#{class_or_module_name}##{method_name}"
end
end
def class_method_signatures
class_method_names.map do |method_name|
"#{class_or_module_name}.#{method_name}"
end
end
def class_method_names
search_ast(/\(self\) :(\S+[\w!=?])$/)
end
def instance_method_names
search_ast(/\(def :(.+)$/)
end
def class_or_module_name
@class ||= begin
lines = grep_for(/^ *(class|module)/)
if lines.length > 1
return nil
end
fail "no lines! #{file_path} --- #{file.read}" if lines.empty?
line = lines.first
line.match(/(class|module) (\w*)/).captures.last
end
end
def search_ast(regex)
sexp_lines.flat_map { |line| matches = line.match(regex); matches.captures if matches }.compact
end
def sexp_lines
ast.to_sexp.lines
end
def ast
Parser::CurrentRuby.parse(file_contents)
end
def file_contents
@file_contenst ||= begin
contents = file.read
file.rewind
contents
end
end
def file
@file ||= File.open(file_path)
end
def grep_for(regex)
results = file.grep(regex)
file.rewind
results
end
end
class SignatureCollector
def collected_signatures
app_files.flat_map do |file_path|
ClassSignature.new(file_path).method_signatures
end
end
def app_files
Dir.glob(File.join(Rails.root, 'app', '**/*.rb'))
end
end
p SignatureCollector.new.collected_signatures - Speccer.new.descriptions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment