~ubuntu-branches/ubuntu/oneiric/puppet/oneiric-security

« back to all changes in this revision

Viewing changes to vendor/gems/rspec/lib/spec/runner/options.rb

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Pollock
  • Date: 2009-04-13 17:12:47 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (3.1.3 squeeze) (1.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20090413171247-61zlnwi5esw1lhtv
ImportĀ upstreamĀ versionĀ 0.24.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
module Spec
2
 
  module Runner
3
 
    class Options
4
 
      FILE_SORTERS = {
5
 
        'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)}
6
 
      }
7
 
 
8
 
      EXAMPLE_FORMATTERS = { # Load these lazily for better speed
9
 
               'specdoc' => ['spec/runner/formatter/specdoc_formatter',                'Formatter::SpecdocFormatter'],
10
 
                     's' => ['spec/runner/formatter/specdoc_formatter',                'Formatter::SpecdocFormatter'],
11
 
                  'html' => ['spec/runner/formatter/html_formatter',                   'Formatter::HtmlFormatter'],
12
 
                     'h' => ['spec/runner/formatter/html_formatter',                   'Formatter::HtmlFormatter'],
13
 
              'progress' => ['spec/runner/formatter/progress_bar_formatter',           'Formatter::ProgressBarFormatter'],
14
 
                     'p' => ['spec/runner/formatter/progress_bar_formatter',           'Formatter::ProgressBarFormatter'],
15
 
      'failing_examples' => ['spec/runner/formatter/failing_examples_formatter',       'Formatter::FailingExamplesFormatter'],
16
 
                     'e' => ['spec/runner/formatter/failing_examples_formatter',       'Formatter::FailingExamplesFormatter'],
17
 
'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
18
 
                     'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
19
 
               'profile' => ['spec/runner/formatter/profile_formatter',                'Formatter::ProfileFormatter'],
20
 
                     'o' => ['spec/runner/formatter/profile_formatter',                'Formatter::ProfileFormatter'],
21
 
              'textmate' => ['spec/runner/formatter/text_mate_formatter',              'Formatter::TextMateFormatter']
22
 
      }
23
 
 
24
 
      STORY_FORMATTERS = {
25
 
        'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
26
 
            'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
27
 
         'html' => ['spec/runner/formatter/story/html_formatter',       'Formatter::Story::HtmlFormatter'],
28
 
            'h' => ['spec/runner/formatter/story/html_formatter',       'Formatter::Story::HtmlFormatter']
29
 
      }
30
 
 
31
 
      attr_accessor(
32
 
        :filename_pattern,
33
 
        :backtrace_tweaker,
34
 
        :context_lines,
35
 
        :diff_format,
36
 
        :dry_run,
37
 
        :profile,
38
 
        :examples,
39
 
        :heckle_runner,
40
 
        :line_number,
41
 
        :loadby,
42
 
        :reporter,
43
 
        :reverse,
44
 
        :timeout,
45
 
        :verbose,
46
 
        :user_input_for_runner,
47
 
        :error_stream,
48
 
        :output_stream,
49
 
        # TODO: BT - Figure out a better name
50
 
        :argv
51
 
      )
52
 
      attr_reader :colour, :differ_class, :files, :example_groups
53
 
 
54
 
      def initialize(error_stream, output_stream)
55
 
        @error_stream = error_stream
56
 
        @output_stream = output_stream
57
 
        @filename_pattern = "**/*_spec.rb"
58
 
        @backtrace_tweaker = QuietBacktraceTweaker.new
59
 
        @examples = []
60
 
        @colour = false
61
 
        @profile = false
62
 
        @dry_run = false
63
 
        @reporter = Reporter.new(self)
64
 
        @context_lines = 3
65
 
        @diff_format  = :unified
66
 
        @files = []
67
 
        @example_groups = []
68
 
        @examples_run = false
69
 
        @examples_should_be_run = nil
70
 
        @user_input_for_runner = nil
71
 
      end
72
 
 
73
 
      def add_example_group(example_group)
74
 
        @example_groups << example_group
75
 
      end
76
 
 
77
 
      def remove_example_group(example_group)
78
 
        @example_groups.delete(example_group)
79
 
      end
80
 
 
81
 
      def run_examples
82
 
        return true unless examples_should_be_run?
83
 
        runner = custom_runner || ExampleGroupRunner.new(self)
84
 
 
85
 
        runner.load_files(files_to_load)
86
 
        if example_groups.empty?
87
 
          true
88
 
        else
89
 
          set_spec_from_line_number if line_number
90
 
          success = runner.run
91
 
          @examples_run = true
92
 
          heckle if heckle_runner
93
 
          success
94
 
        end
95
 
      end
96
 
 
97
 
      def examples_run?
98
 
        @examples_run
99
 
      end
100
 
 
101
 
      def examples_should_not_be_run
102
 
        @examples_should_be_run = false
103
 
      end      
104
 
 
105
 
      def colour=(colour)
106
 
        @colour = colour
107
 
        if @colour && RUBY_PLATFORM =~ /win32/ ;\
108
 
          begin ;\
109
 
            require 'rubygems' ;\
110
 
            require 'Win32/Console/ANSI' ;\
111
 
          rescue LoadError ;\
112
 
            warn "You must 'gem install win32console' to use colour on Windows" ;\
113
 
            @colour = false ;\
114
 
          end
115
 
        end
116
 
      end
117
 
 
118
 
      def parse_diff(format)
119
 
        case format
120
 
        when :context, 'context', 'c'
121
 
          @diff_format  = :context
122
 
          default_differ
123
 
        when :unified, 'unified', 'u', '', nil
124
 
          @diff_format  = :unified
125
 
          default_differ
126
 
        else
127
 
          @diff_format  = :custom
128
 
          self.differ_class = load_class(format, 'differ', '--diff')
129
 
        end
130
 
      end
131
 
 
132
 
      def parse_example(example)
133
 
        if(File.file?(example))
134
 
          @examples = File.open(example).read.split("\n")
135
 
        else
136
 
          @examples = [example]
137
 
        end
138
 
      end
139
 
 
140
 
      def parse_format(format_arg)
141
 
        format, where = ClassAndArgumentsParser.parse(format_arg)
142
 
        unless where
143
 
          raise "When using several --format options only one of them can be without a file" if @out_used
144
 
          where = @output_stream
145
 
          @out_used = true
146
 
        end
147
 
        @format_options ||= []
148
 
        @format_options << [format, where]
149
 
      end
150
 
      
151
 
      def formatters
152
 
        @format_options ||= [['progress', @output_stream]]
153
 
        @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS)
154
 
      end
155
 
 
156
 
      def story_formatters
157
 
        @format_options ||= [['plain', @output_stream]]
158
 
        @formatters ||= load_formatters(@format_options, STORY_FORMATTERS)
159
 
      end
160
 
      
161
 
      def load_formatters(format_options, formatters)
162
 
        format_options.map do |format, where|
163
 
          formatter_type = if formatters[format]
164
 
            require formatters[format][0]
165
 
            eval(formatters[format][1], binding, __FILE__, __LINE__)
166
 
          else
167
 
            load_class(format, 'formatter', '--format')
168
 
          end
169
 
          formatter_type.new(self, where)
170
 
        end
171
 
      end
172
 
 
173
 
      def load_heckle_runner(heckle)
174
 
        suffix = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? '_unsupported' : ''
175
 
        require "spec/runner/heckle_runner#{suffix}"
176
 
        @heckle_runner = HeckleRunner.new(heckle)
177
 
      end
178
 
 
179
 
      def number_of_examples
180
 
        @example_groups.inject(0) do |sum, example_group|
181
 
          sum + example_group.number_of_examples
182
 
        end
183
 
      end
184
 
 
185
 
      def files_to_load
186
 
        result = []
187
 
        sorted_files.each do |file|
188
 
          if File.directory?(file)
189
 
            filename_pattern.split(",").each do |pattern|
190
 
              result += Dir[File.expand_path("#{file}/#{pattern.strip}")]
191
 
            end
192
 
          elsif File.file?(file)
193
 
            result << file
194
 
          else
195
 
            raise "File or directory not found: #{file}"
196
 
          end
197
 
        end
198
 
        result
199
 
      end
200
 
      
201
 
      protected
202
 
      def examples_should_be_run?
203
 
        return @examples_should_be_run unless @examples_should_be_run.nil?
204
 
        @examples_should_be_run = true
205
 
      end
206
 
      
207
 
      def differ_class=(klass)
208
 
        return unless klass
209
 
        @differ_class = klass
210
 
        Spec::Expectations.differ = self.differ_class.new(self)
211
 
      end
212
 
 
213
 
      def load_class(name, kind, option)
214
 
        if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
215
 
          arg = $2 == "" ? nil : $2
216
 
          [$1, arg]
217
 
        else
218
 
          m = "#{name.inspect} is not a valid class name"
219
 
          @error_stream.puts m
220
 
          raise m
221
 
        end
222
 
        begin
223
 
          eval(name, binding, __FILE__, __LINE__)
224
 
        rescue NameError => e
225
 
          @error_stream.puts "Couldn't find #{kind} class #{name}"
226
 
          @error_stream.puts "Make sure the --require option is specified *before* #{option}"
227
 
          if $_spec_spec ; raise e ; else exit(1) ; end
228
 
        end
229
 
      end
230
 
      
231
 
      def custom_runner
232
 
        return nil unless custom_runner?
233
 
        klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner)
234
 
        runner_type = load_class(klass_name, 'behaviour runner', '--runner')
235
 
        return runner_type.new(self, arg)
236
 
      end
237
 
 
238
 
      def custom_runner?
239
 
        return user_input_for_runner ? true : false
240
 
      end
241
 
      
242
 
      def heckle
243
 
        returns = self.heckle_runner.heckle_with
244
 
        self.heckle_runner = nil
245
 
        returns
246
 
      end
247
 
      
248
 
      def sorted_files
249
 
        return sorter ? files.sort(&sorter) : files
250
 
      end
251
 
 
252
 
      def sorter
253
 
        FILE_SORTERS[loadby]
254
 
      end
255
 
 
256
 
      def default_differ
257
 
        require 'spec/expectations/differs/default'
258
 
        self.differ_class = Spec::Expectations::Differs::Default
259
 
      end
260
 
 
261
 
      def set_spec_from_line_number
262
 
        if examples.empty?
263
 
          if files.length == 1
264
 
            if File.directory?(files[0])
265
 
              error_stream.puts "You must specify one file, not a directory when using the --line option"
266
 
              exit(1) if stderr?
267
 
            else
268
 
              example = SpecParser.new.spec_name_for(files[0], line_number)
269
 
              @examples = [example]
270
 
            end
271
 
          else
272
 
            error_stream.puts "Only one file can be specified when using the --line option: #{files.inspect}"
273
 
            exit(3) if stderr?
274
 
          end
275
 
        else
276
 
          error_stream.puts "You cannot use both --line and --example"
277
 
          exit(4) if stderr?
278
 
        end
279
 
      end
280
 
 
281
 
      def stderr?
282
 
        @error_stream == $stderr
283
 
      end
284
 
    end
285
 
  end
286
 
end