summaryrefslogtreecommitdiff
path: root/spec/mspec/lib/mspec/commands/mkspec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/mspec/lib/mspec/commands/mkspec.rb')
-rwxr-xr-xspec/mspec/lib/mspec/commands/mkspec.rb155
1 files changed, 155 insertions, 0 deletions
diff --git a/spec/mspec/lib/mspec/commands/mkspec.rb b/spec/mspec/lib/mspec/commands/mkspec.rb
new file mode 100755
index 0000000000..7a943aa1fe
--- /dev/null
+++ b/spec/mspec/lib/mspec/commands/mkspec.rb
@@ -0,0 +1,155 @@
+#!/usr/bin/env ruby
+
+require 'rbconfig'
+require 'mspec/version'
+require 'mspec/utils/options'
+require 'mspec/utils/name_map'
+require 'mspec/helpers/fs'
+
+class MkSpec
+ attr_reader :config
+
+ def initialize
+ @config = {
+ :constants => [],
+ :requires => [],
+ :base => "core",
+ :version => nil
+ }
+ @map = NameMap.new true
+ end
+
+ def options(argv=ARGV)
+ options = MSpecOptions.new "mkspec [options]", 32
+
+ options.on("-c", "--constant", "CONSTANT",
+ "Class or Module to generate spec stubs for") do |name|
+ config[:constants] << name
+ end
+ options.on("-b", "--base", "DIR",
+ "Directory to generate specs into") do |directory|
+ config[:base] = File.expand_path directory
+ end
+ options.on("-r", "--require", "LIBRARY",
+ "A library to require") do |file|
+ config[:requires] << file
+ end
+ options.on("-V", "--version-guard", "VERSION",
+ "Specify version for ruby_version_is guards") do |version|
+ config[:version] = version
+ end
+ options.version MSpec::VERSION
+ options.help
+
+ options.doc "\n How might this work in the real world?\n"
+ options.doc " 1. To create spec stubs for every class or module in Object\n"
+ options.doc " $ mkspec\n"
+ options.doc " 2. To create spec stubs for Fixnum\n"
+ options.doc " $ mkspec -c Fixnum\n"
+ options.doc " 3. To create spec stubs for Complex in 'superspec/complex'\n"
+ options.doc " $ mkspec -c Complex -r complex -b superspec"
+ options.doc ""
+
+ options.parse argv
+ end
+
+ def create_directory(mod)
+ subdir = @map.dir_name mod, config[:base]
+
+ if File.exist? subdir
+ unless File.directory? subdir
+ puts "#{subdir} already exists and is not a directory."
+ return nil
+ end
+ else
+ mkdir_p subdir
+ end
+
+ subdir
+ end
+
+ def write_requires(dir, file)
+ prefix = config[:base] + '/'
+ raise dir unless dir.start_with? prefix
+ sub = dir[prefix.size..-1]
+ parents = '../' * (sub.split('/').length + 1)
+
+ File.open(file, 'w') do |f|
+ f.puts "require File.expand_path('../#{parents}spec_helper', __FILE__)"
+ config[:requires].each do |lib|
+ f.puts "require '#{lib}'"
+ end
+ end
+ end
+
+ def write_version(f)
+ f.puts ""
+ if version = config[:version]
+ f.puts "ruby_version_is #{version} do"
+ yield " "
+ f.puts "end"
+ else
+ yield ""
+ end
+ end
+
+ def write_spec(file, meth, exists)
+ if exists
+ out = `#{ruby} #{MSPEC_HOME}/bin/mspec-run --dry-run --unguarded -fs -e '#{meth}' #{file}`
+ return if out.include?(meth)
+ end
+
+ File.open file, 'a' do |f|
+ write_version(f) do |indent|
+ f.puts <<-EOS
+#{indent}describe "#{meth}" do
+#{indent} it "needs to be reviewed for spec completeness"
+#{indent}end
+EOS
+ end
+ end
+
+ puts file
+ end
+
+ def create_file(dir, mod, meth, name)
+ file = File.join dir, @map.file_name(meth, mod)
+ exists = File.exist? file
+
+ write_requires dir, file unless exists
+ write_spec file, name, exists
+ end
+
+ def run
+ config[:requires].each { |lib| require lib }
+ constants = config[:constants]
+ constants = Object.constants if constants.empty?
+
+ @map.map({}, constants).each do |mod, methods|
+ name = mod.chop
+ next unless dir = create_directory(name)
+
+ methods.each { |method| create_file dir, name, method, mod + method }
+ end
+ end
+
+ ##
+ # Determine and return the path of the ruby executable.
+
+ def ruby
+ ruby = File.join(RbConfig::CONFIG['bindir'],
+ RbConfig::CONFIG['ruby_install_name'])
+
+ ruby.gsub! File::SEPARATOR, File::ALT_SEPARATOR if File::ALT_SEPARATOR
+
+ return ruby
+ end
+
+ def self.main
+ ENV['MSPEC_RUNNER'] = '1'
+
+ script = new
+ script.options
+ script.run
+ end
+end