public
Description: Behaviour Driven Development framework for Ruby
Homepage: http://rspec.info
Clone URL: git://github.com/dchelimsky/rspec.git
Click here to lend your support to: rspec and make a donation at www.pledgie.com !
btakita (author)
Sun May 25 12:09:41 -0700 2008
commit  8b73e1288e62f4d59e17405a715d58d0cb56cf4a
tree    72ca14e69d4ceda89e2c1e35ab7f5c48da078622
parent  3c00f80308585649dc4b59c581a9174c91240f8a
rspec / lib / spec / rake / spectask.rb
100644 236 lines (203 sloc) 8.088 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/env ruby
 
# Define a task library for running RSpec contexts.
 
require 'rake'
require 'rake/tasklib'
 
module Spec
  module Rake
 
    # A Rake task that runs a set of specs.
    #
    # Example:
    #
    # Spec::Rake::SpecTask.new do |t|
    # t.warning = true
    # t.rcov = true
    # end
    #
    # This will create a task that can be run with:
    #
    # rake spec
    #
    # If rake is invoked with a "SPEC=filename" command line option,
    # then the list of spec files will be overridden to include only the
    # filename specified on the command line. This provides an easy way
    # to run just one spec.
    #
    # If rake is invoked with a "SPEC_OPTS=options" command line option,
    # then the given options will override the value of the +spec_opts+
    # attribute.
    #
    # If rake is invoked with a "RCOV_OPTS=options" command line option,
    # then the given options will override the value of the +rcov_opts+
    # attribute.
    #
    # Examples:
    #
    # rake spec # run specs normally
    # rake spec SPEC=just_one_file.rb # run just one spec file.
    # rake spec SPEC_OPTS="--diff" # enable diffing
    # rake spec RCOV_OPTS="--aggregate myfile.txt" # see rcov --help for details
    #
    # Each attribute of this task may be a proc. This allows for lazy evaluation,
    # which is sometimes handy if you want to defer the evaluation of an attribute value
    # until the task is run (as opposed to when it is defined).
    #
    # This task can also be used to run existing Test::Unit tests and get RSpec
    # output, for example like this:
    #
    # require 'rubygems'
    # require 'spec/rake/spectask'
    # Spec::Rake::SpecTask.new do |t|
    # t.ruby_opts = ['-rtest/unit']
    # t.spec_files = FileList['test/**/*_test.rb']
    # end
    #
    class SpecTask < ::Rake::TaskLib
      class << self
        def attr_accessor(*names)
          super(*names)
          names.each do |name|
            module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
          end
        end
      end
 
      # Name of spec task. (default is :spec)
      attr_accessor :name
 
      # Array of directories to be added to $LOAD_PATH before running the
      # specs. Defaults to ['<the absolute path to RSpec's lib directory>']
      attr_accessor :libs
 
      # If true, requests that the specs be run with the warning flag set.
      # E.g. warning=true implies "ruby -w" used to run the specs. Defaults to false.
      attr_accessor :warning
 
      # Glob pattern to match spec files. (default is 'spec/**/*_spec.rb')
      # Setting the SPEC environment variable overrides this.
      attr_accessor :pattern
 
      # Array of commandline options to pass to RSpec. Defaults to [].
      # Setting the SPEC_OPTS environment variable overrides this.
      attr_accessor :spec_opts
 
      # Whether or not to use RCov (default is false)
      # See http://eigenclass.org/hiki.rb?rcov
      attr_accessor :rcov
 
      # Array of commandline options to pass to RCov. Defaults to ['--exclude', 'lib\/spec,bin\/spec'].
      # Ignored if rcov=false
      # Setting the RCOV_OPTS environment variable overrides this.
      attr_accessor :rcov_opts
 
      # Directory where the RCov report is written. Defaults to "coverage"
      # Ignored if rcov=false
      attr_accessor :rcov_dir
 
      # Array of commandline options to pass to ruby. Defaults to [].
      attr_accessor :ruby_opts
 
      # Whether or not to fail Rake when an error occurs (typically when specs fail).
      # Defaults to true.
      attr_accessor :fail_on_error
 
      # A message to print to stderr when there are failures.
      attr_accessor :failure_message
 
      # Where RSpec's output is written. Defaults to STDOUT.
      # DEPRECATED. Use --format FORMAT:WHERE in spec_opts.
      attr_accessor :out
 
      # Explicitly define the list of spec files to be included in a
      # spec. +spec_files+ is expected to be an array of file names (a
      # FileList is acceptable). If both +pattern+ and +spec_files+ are
      # used, then the list of spec files is the union of the two.
      # Setting the SPEC environment variable overrides this.
      attr_accessor :spec_files
 
      # Use verbose output. If this is set to true, the task will print
      # the executed spec command to stdout. Defaults to false.
      attr_accessor :verbose
 
      # Defines a new task, using the name +name+.
      def initialize(name=:spec)
        @name = name
        @libs = [File.expand_path(File.dirname(__FILE__) + '/../../../lib')]
        @pattern = nil
        @spec_files = nil
        @spec_opts = []
        @warning = false
        @ruby_opts = []
        @fail_on_error = true
        @rcov = false
        @rcov_opts = ['--exclude', 'lib\/spec,bin\/spec,config\/boot.rb']
        @rcov_dir = "coverage"
 
        yield self if block_given?
        @pattern = 'spec/**/*_spec.rb' if pattern.nil? && spec_files.nil?
        define
      end
 
      def define # :nodoc:
        spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/spec')
 
        lib_path = libs.join(File::PATH_SEPARATOR)
        actual_name = Hash === name ? name.keys.first : name
        unless ::Rake.application.last_comment
          desc "Run specs" + (rcov ? " using RCov" : "")
        end
        task name do
          RakeFileUtils.verbose(verbose) do
            unless spec_file_list.empty?
              # ruby [ruby_opts] -Ilib -S rcov [rcov_opts] bin/spec -- examples [spec_opts]
              # or
              # ruby [ruby_opts] -Ilib bin/spec examples [spec_opts]
              cmd = "#{File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])} "
 
              rb_opts = ruby_opts.clone
              rb_opts << "-I\"#{lib_path}\""
              rb_opts << "-S rcov" if rcov
              rb_opts << "-w" if warning
              cmd << rb_opts.join(" ")
              cmd << " "
              cmd << rcov_option_list
              cmd << %[ -o "#{rcov_dir}" ] if rcov
              cmd << %Q|"#{spec_script}"|
cmd << " "
cmd << "-- " if rcov
cmd << spec_file_list.collect { |fn| %["#{fn}"] }.join(' ')
cmd << " "
cmd << spec_option_list
if out
cmd << " "
cmd << %Q| > "#{out}"|
STDERR.puts "The Spec::Rake::SpecTask#out attribute is DEPRECATED and will be removed in a future version. Use --format FORMAT:WHERE instead."
end
if verbose
puts cmd
end
unless system(cmd)
STDERR.puts failure_message if failure_message
raise("Command #{cmd} failed") if fail_on_error
end
end
end
end
 
if rcov
desc "Remove rcov products for #{actual_name}"
task paste("clobber_", actual_name) do
rm_r rcov_dir rescue nil
end
 
clobber_task = paste("clobber_", actual_name)
task :clobber => [clobber_task]
 
task actual_name => clobber_task
end
self
end
 
def rcov_option_list # :nodoc:
return "" unless rcov
ENV['RCOV_OPTS'] || rcov_opts.join(" ") || ""
end
 
def spec_option_list # :nodoc:
STDERR.puts "RSPECOPTS is DEPRECATED and will be removed in a future version. Use SPEC_OPTS instead." if ENV['RSPECOPTS']
ENV['SPEC_OPTS'] || ENV['RSPECOPTS'] || spec_opts.join(" ") || ""
      end
 
      def evaluate(o) # :nodoc:
        case o
          when Proc then o.call
          else o
        end
      end
 
      def spec_file_list # :nodoc:
        if ENV['SPEC']
          FileList[ ENV['SPEC'] ]
        else
          result = []
          result += spec_files.to_a if spec_files
          result += FileList[ pattern ].to_a if pattern
          FileList[result]
        end
      end
 
    end
  end
end