bin/jspec in jspec-2.11.13 vs bin/jspec in jspec-3.0.0
- old
+ new
@@ -1,309 +1,178 @@
#!/usr/bin/env ruby
-JSPEC_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+JSPEC_ROOT = File.expand_path File.join(File.dirname(__FILE__), '..')
$:.unshift JSPEC_ROOT
require 'rubygems'
require 'commander/import'
require 'bind'
require 'fileutils'
-require 'server/server'
+require 'src/project'
+require 'src/installables'
+require 'src/server'
-RHINO = 'java org.mozilla.javascript.tools.shell.Main'
-
program :name, 'JSpec'
-program :version, '2.11.13'
+program :version, '3.0.0'
program :description, 'JavaScript BDD Testing Framework'
default_command :bind
+JSpec::Project.load_commands_at '~/.jspec/commands'
+JSpec::Project.load_commands_at 'spec/commands'
+JSpec::Project.load_commands_at 'jspec/commands'
+
+command :stats do |c|
+ c.syntax = 'jspec stats [path ...]'
+ c.summary = 'View javascript source statistics'
+ c.description = 'View statistics for the given [paths], defaulting to /lib/**/*.js'
+ c.example 'View stats for all /lib javascript', 'jspec stats'
+ c.example 'View stats for all /public/javascript files', 'jspec stats public/javascript/*.js'
+ c.when_called do |paths, options|
+ paths = Dir['lib/**/*.js'] if paths.empty?
+ paths.each do |path|
+ contents = File.read path
+ say "%33s : \n" % $terminal.color(path, :bold)
+ say "%25s : %0.2f KiB\n" % ['size', File.size(path).to_f / 1024]
+ say "%25s : %d\n" % ['lines', contents.to_a.length]
+ say "%25s : %d\n" % ['comments', contents.scan(/\/\*.*?\*\/|\/\/.*?$/m).length]
+ say "%25s : %d\n" % ['functions', contents.scan(/function/i).length]
+ say "%25s : %d\n" % ['vars', contents.scan(/\bvar\b/).length]
+ say "\n"
+ end
+ end
+end
+
+command :install do |c|
+ c.syntax = 'jspec install <project> [dest]'
+ c.summary = 'Install a project such as jQuery, Prototype, Rhino, etc.'
+ c.description = 'Install the given <project> to [dest] or spec/support/<project>.
+ When --release is not specified, the latest stable release will be used.
+ Currently the following projects are supported:
+
+ - jquery
+ - jqueryui
+ - prototype
+ - mootools
+ - dojo
+ - envjs (--release not yet supported)
+ - rhino (--release not yet supported)'
+ c.option '-r', '--release STRING', 'Release version to install'
+ c.example 'Install jQuery to spec/support/jquery.js', 'jspec install jquery'
+ c.example 'Install jQuery 1.3.0 to spec/support/jquery.js', 'jspec install jquery --release 1.3.0'
+ c.example 'Install Prototype to spec/prototype.js', 'jspec install prototype spec'
+ c.example 'Install Prototype to spec/vendor/prototype.js', 'jspec install prototype spec/vendor'
+ c.when_called do |args, options|
+ name = args.shift or raise 'Project name required'
+ project = JSpec::Project.for '.'
+ if dest = args.shift
+ project.install name, :to => dest, :release => options.release
+ else
+ Dir.mkdir project.normalize('support') unless File.directory? project.normalize('support')
+ project.install name, :to => project.normalize('support'), :release => options.release
+ end
+ end
+end
+
command :init do |c|
c.syntax = 'jspec init [dest]'
c.summary = 'Initialize a JSpec project template'
c.description = 'Initialize a JSpec project template. Defaults to the current directory
when [dest] is not specified. The template includes several files for
running via Rhino, DOM, and the JSpec Rack server.
Additional switches --freeze, and --symlink are available in order
to preserve the version of JSpec at the time of initialization. Otherwise
incompatibilities from later versions may prevent your suite from
- running properly.'
+ running properly.
+
+ To update a project to the recent version of JSpec use
+ `jspec help udpate` for more information.'
c.option '-R', '--rails', 'Initialize rails template from rails root directory'
c.option '-f', '--freeze', 'Copy the JSpec library'
c.option '-s', '--symlink', 'Symlink the JSpec library instead of copying it'
+ c.example 'Create a project in the current directory', 'jspec init'
c.example 'Create a directory foo, initialized with a jspec template', 'jspec init foo'
+ c.example 'Rails application support', 'jspec init --rails'
+ c.example 'Rails application support, --rails is no longer required', 'jspec init'
+ c.example 'Freeze JSpec\'s library at spec/lib', 'jspec init --freeze'
c.when_called do |args, options|
- dest = args.shift || '.'
- if options.rails
- initialize_rails_at dest, options
- else
- initialize_at dest, options
- end
+ JSpec::Project.for(dest = args.shift || '.').init! options.__hash__
say "Template initialized at `#{dest}'"
end
end
command :shell do |c|
c.syntax = 'jspec shell [path ...]'
c.summary = 'JSpec interactive shell'
- c.description = 'Launch interactive shell with jspec.js, jspec.shell.js,
+ c.description = 'Launch interactive Rhino shell with jspec.js, jspec.shell.js,
and any [path]s given. Simply type "quit" or "exit" to
terminate the shell.'
c.example 'Run shell', 'jspec shell'
c.example 'Run shell with glob of files', 'jspec shell lib/*.js'
c.example 'Run shell with list of files', 'jspec shell lib/foo.js lib/bar.js'
c.when_called do |args, options|
paths = ['jspec.js', 'jspec.shell.js'] | args
paths.map! do |path|
- if path.include? 'jspec'
+ if path.include? 'jspec.'
"-f #{JSPEC_ROOT}/lib/#{path}"
else
"-f #{path}"
end
end
say "JSpec #{program(:version)}"
- `#{RHINO} #{paths.join(' ')} -f -`
+ `#{JSpec::Project::RHINO} #{paths.join(' ')} -f -`
end
end
command :update do |c|
- c.syntax = 'jspec update [path ...]'
+ c.syntax = 'jspec update [dest]'
c.summary = 'Update JSpec releases'
- c.description = 'Update JSpec release in [paths], this will allow you to utilize
- the latest JSpec features. Execute from JSpec project root without [paths] to
- update the default template spec files.'
+ c.description = 'Update JSpec release relative to [dest], this will allow you
+ to utilize the latest JSpec features. Execute from JSpec project
+ root without [dest] to update the default template spec files.
+
+ This command supports regular projects, as well as those initialized
+ with --symlink and --freeze.'
+ c.example 'Update project in the current directory', 'jspec update'
+ c.example 'Update project in the directory specified', 'jspec update path/to/project'
c.when_called do |args, options|
- if args.empty?
- if rails?
- paths = 'jspec/spec.dom.html', 'jspec/spec.rhino.js'
- else
- paths = 'spec/spec.dom.html', 'spec/spec.rhino.js'
- end
- else
- paths = args
- end
- update_version_in *paths
+ JSpec::Project.for(dest = args.shift || '.').update!
end
end
command :run do |c|
c.syntax = 'jspec run [path] [options]'
c.summary = 'Run specifications'
- c.description = 'Run specifications, defaulting [path] to spec/spec.dom.html.
+ c.description = 'Run specifications, defaulting [path] to spec/dom.html.
You will need to supply [path] if your specs do not reside
in this location. `run --bind` is the default sub-command of
jspec so you may simply execute `jspec` in order to bind execution
of your specs when a file is altered.
- JSpec supports Rhino execution when installed. The [path] is assumed
- to be spec/spec.rhino.js unless specified. See examples below for
- using the --rhino switch.
+ Rhino:
+ The [path] is assumed to be spec/rhino.js unless specified.
+ Node.js:
+ The [path] is assumed to be spec/node.js unless specified.
+
JSpec\'s server is also available via --server, which defaults
the [path] to spec/server.html'
- c.example 'Run once in Safari', 'jspec run'
+ c.example 'Run once in default browser', 'jspec run'
c.example 'Run once in Safari and Firefox', 'jspec run --browsers Safari,Firefox'
c.example 'Run once in Opera, Firefox, and Chrome', 'jspec run --browsers opera,ff,chrome'
c.example 'Run custom spec file', 'jspec run foo.html'
c.example 'Auto-run browsers when a file is altered', 'jspec run --bind --browsers Safari,Firefox'
c.example 'Shortcut for the previous example', 'jspec --browsers Safari,Firefox'
+ c.example 'Run Rhino specs', 'jspec run --rhino'
c.example 'Auto-run rhino when a file is altered', 'jspec --rhino'
- c.example 'Run Rhino specs at spec/rhino.js', 'jspec run --rhino'
- c.example 'Run Rhino specs once', 'jspec run specs/something.js --rhino'
c.option '-b', '--browsers BROWSERS', Array, 'Specify browsers to test'
c.option '-p', '--paths PATHS', Array, 'Specify paths when binding, defaults to javascript within ./lib and ./spec'
c.option '-B', '--bind', 'Auto-run specs when source files or specs are altered'
c.option '-R', '--rhino', 'Run specs using Rhino'
+ c.option '-N', '--node', 'Run specs using Node.js'
c.option '-S', '--server', 'Run specs using the JSpec server'
c.option '-P', '--port NUMBER', Integer, 'Start JSpec server using the given port number'
c.when_called do |args, options|
-
- # Rails
- if rails?
- options.default :paths => ['public/javascripts/**/*.js', 'jspec/**/*.js'], :port => 4444
- else
- options.default :paths => ['lib/**/*.js', 'spec/**/*.js'], :port => 4444
- end
-
- # Actions
- if options.rhino
- suite = args.shift || path_to('spec.rhino.js')
- action = lambda { exit rhino(suite) }
- elsif options.server
- raise 'Cannot use --server with --bind' if options.bind
- suite = args.shift || path_to('spec.server.html')
- action = lambda { start_server suite, options }
- else
- suite = args.shift || path_to('spec.dom.html')
- browsers = browsers_for options.browsers || ['safari']
- action = lambda do
- browsers.each do |browser|
- browser.visit File.expand_path(suite)
- end
- end
- end
-
- # Binding
- if options.bind
- listener = Bind::Listener.new :paths => options.paths, :interval => 1, :actions => [action], :debug => $stdout
- listener.run!
- else
- action.call File.new(suite)
- end
+ JSpec::Project.for('.').run! args.first, options.__hash__
end
end
alias_command :bind, :run, '--bind'
-
-##
-# Initialize template at _dest_.
-
-def initialize_at dest, options
- unless Dir[dest + '/*'].empty?
- abort unless agree "'#{dest}' is not empty; continue? "
- end
-
- copy_template_to 'default', dest
- setup_lib_dir dest, options
- replace_root_in dest, 'spec/spec.dom.html', 'spec/spec.rhino.js'
-end
-
-##
-# Initialize rails template at _dest_.
-
-def initialize_rails_at dest, options
- unless looks_like_rails_root?(dest)
- abort unless agree "'#{dest}' does not look like root of a rails project; continue? "
- end
-
- copy_template_to 'rails', "#{dest}/jspec"
- setup_lib_dir "#{dest}/jspec", options
- replace_root_in "#{dest}/jspec", 'spec.dom.html', 'spec.rhino.js'
-end
-
-##
-# Copy template _name_ to _dest_.
-
-def copy_template_to name, dest
- FileUtils.mkdir_p dest
- FileUtils.cp_r path_to_template(name), dest
-end
-
-##
-# Return path to template _name_.
-
-def path_to_template name
- File.join JSPEC_ROOT, 'templates', name, '.'
-end
-
-##
-# Resolve path to _file_. Supports rails and unbound projects.
-
-def path_to file
- rails? ? "jspec/#{file}" : "spec/#{file}"
-end
-
-##
-# Execute _file_ with Rhino.
-
-def rhino file
- raise "#{file} not found" unless File.exists? file
- system "#{RHINO} #{file}"
-end
-
-##
-# Start server with _suite_ html and _options_.
-
-def start_server suite, options
- set :port, options.port
- set :server, 'Mongrel'
- enable :sessions
- disable :logging
- hook = File.expand_path path_to('server.rb')
- load hook if File.exists? hook
- JSpec::Server.new(suite, options.port).start(options.browsers ? browsers_for(options.browsers) : nil)
-end
-
-##
-# Return array of browser instances for the given _names_.
-
-def browsers_for names
- names.map do |name|
- begin
- Browser.subclasses.find do |browser|
- browser.matches_name? name
- end.new
- rescue
- raise "Unsupported browser `#{name}'"
- end
- end
-end
-
-##
-# Check if the current directory looks like a rails app.
-
-def rails?
- File.directory? 'jspec'
-end
-
-##
-# Replace JSPEC_ROOT placeholder in _paths_ relative to _dest_.
-
-def replace_root_in dest, *paths
- if rails? && File.exist?("#{dest}/jspec/lib")
- root = './jspec'
- elsif File.exist?("#{dest}/spec/lib")
- root = "./spec"
- else
- root = JSPEC_ROOT
- end
-
- paths.each do |path|
- path = File.join dest, path
- if path.include? 'dom'
- contents = File.read(path).gsub 'JSPEC_ROOT/', root == JSPEC_ROOT ? "#{JSPEC_ROOT}/" : ''
- else
- contents = File.read(path).gsub 'JSPEC_ROOT', root
- end
- File.open(path, 'w') { |file| file.write contents }
- end
-end
-
-##
-# Update JSpec version in _paths_. Matches jspec-TRIPLE
-
-def update_version_in *paths
- paths.each do |path|
- next unless File.exists? path
- contents = File.read(path).gsub /jspec-(\d+\.\d+\.\d+)/, "jspec-#{program(:version)}"
- File.open(path, 'r+'){ |file| file.write contents }
- say "Updated #{path}; #{$1} -> #{program(:version)}"
- end
- say "Finished updating JSpec"
-end
-
-##
-# Check if _path_ looks like a rails root directory.
-
-def looks_like_rails_root? path = '.'
- File.directory? "#{path}/vendor"
-end
-
-##
-# Copy or symlink library to the specified path.
-
-def setup_lib_dir dest, options
- return unless options.symlink || options.freeze
-
- if rails?
- dest = File.join dest, "lib"
- else
- dest = File.join dest, "spec", "lib"
- end
-
- from = File.join JSPEC_ROOT, "lib"
-
- if options.symlink
- FileUtils.symlink from, dest, :force => true
- else
- FileUtils.cp_r from, dest
- end
-end