Class: MSpecScript

Inherits:
Object show all
Defined in:
lib/extensions/mspec/mspec/utils/script.rb,
lib/extensions/rhospec/rhospec.rb

Overview

MSpecScript provides a skeleton for all the MSpec runner scripts.

Direct Known Subclasses

MSpecCI, MSpecMain, MSpecRun, MSpecTag, SpecRunner

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMSpecScript

Returns a new instance of MSpecScript.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 40

def initialize
  config[:formatter] = nil
  config[:includes]  = []
  config[:excludes]  = []
  config[:patterns]  = []
  config[:xpatterns] = []
  config[:tags]      = []
  config[:xtags]     = []
  config[:profiles]  = []
  config[:xprofiles] = []
  config[:atags]     = []
  config[:astrings]  = []
  config[:ltags]     = []
  config[:abort]     = true
  @loaded = []
end

Class Method Details

.configObject

Returns the config object. Maintained at the class level to easily enable simple config files. See the class method set.



7
8
9
10
# File 'lib/extensions/rhospec/rhospec.rb', line 7

def self.config
  @config ||= {
  }
end

.get(key) ⇒ Object

Gets the value of key from the config object. Simplifies getting values in a config file:

class MSpecScript
  set :a, 1
  set :b, 2
  set :c, get(:a) + get(:b)
end


36
37
38
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 36

def self.get(key)
  config[key]
end

.mainObject

Instantiates an instance and calls the series of methods to invoke the script.



256
257
258
259
260
261
262
263
264
265
266
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 256

def self.main
  script = new
  script.load_default
  script.try_load '~/.mspecrc'
  script.options
  script.signals
  script.register
  script.setup_env
  require 'mspec'
  script.run
end

.set(key, value) ⇒ Object

Associates value with key in the config object. Enables simple config files of the form:

class MSpecScript
  set :target, "ruby"
  set :files, ["one_spec.rb", "two_spec.rb"]
end


24
25
26
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 24

def self.set(key, value)
  config[key] = value
end

Instance Method Details

#configObject

Returns the config object maintained by the instance’s class. See the class methods set and config.



59
60
61
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 59

def config
  MSpecScript.config
end

#coresObject



237
238
239
240
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 237

def cores
  require 'etc'
  Etc.nprocessors
end

#custom_options(options) ⇒ Object

Callback for enabling custom options. This version is a no-op. Provide an implementation specific version in a config file. Called by #options after the MSpec-provided options are added.



112
113
114
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 112

def custom_options(options)
  options.doc "   No custom options registered"
end

#custom_registerObject

Callback for enabling custom actions, etc. This version is a no-op. Provide an implementation specific version in a config file. Called by #register.



150
151
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 150

def custom_register
end

#entries(partial) ⇒ Object

Attempts to resolve partial as a file or directory name in the following order:

1. +partial+
2. +partial+ + "_spec.rb"
3. <tt>File.join(config[:prefix], partial)</tt>
4. <tt>File.join(config[:prefix], partial + "_spec.rb")</tt>

If it is a file name, returns the name as an entry in an array. If it is a directory, returns all *_spec.rb files in the directory and subdirectories.

If unable to resolve partial, Kernel.abort is called.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 178

def entries(partial)
  file = partial + "_spec.rb"
  patterns = [partial, file]
  if config[:prefix]
    patterns << File.join(config[:prefix], partial)
    patterns << File.join(config[:prefix], file)
  end

  patterns.each do |pattern|
    expanded = File.expand_path(pattern)
    if File.file?(expanded) && expanded.end_with?('.rb')
      return [expanded]
    elsif File.directory?(expanded)
      return Dir["#{expanded}/**/*_spec.rb"].sort
    end
  end

  abort "Could not find spec file #{partial}"
end

#files(list) ⇒ Object

Resolves each entry in list to a set of files.

If the entry has a leading ‘^’ character, the list of files is subtracted from the list of files accumulated to that point.

If the entry has a leading ‘:’ character, the corresponding key is looked up in the config object and the entries in the value retrieved are processed through #entries.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 206

def files(list)
  list.inject([]) do |files, item|
    case item[0]
    when ?^
      files -= entries(item[1..-1])
    when ?:
      key = item[1..-1].to_sym
      files += files(Array(config[key]))
    else
      files += entries(item)
    end
    files
  end
end

#files_from_patterns(patterns) ⇒ Object



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 221

def files_from_patterns(patterns)
  unless $0.end_with?("_spec.rb")
    if patterns.empty?
      patterns = config[:files]
    end
    if patterns.empty? and File.directory? "./spec"
      patterns = ["spec/"]
    end
    if patterns.empty?
      puts "No files specified."
      exit 1
    end
  end
  files patterns
end

#load(target) ⇒ Object



88
89
90
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 88

def load(target)
  try_load(target) or abort "Could not load config file #{target}"
end

#load_defaultObject

Attempts to load a default config file. First tries to load ‘default.mspec’. If that fails, attempts to load a config file name constructed from the value of RUBY_ENGINE and the first two numbers in RUBY_VERSION. For example, on MRI 1.8.6, the file name would be ‘ruby.1.8.mspec’.



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 97

def load_default
  try_load 'default.mspec'

  if Object.const_defined?(:RUBY_ENGINE)
    engine = RUBY_ENGINE
  else
    engine = 'ruby'
  end
  try_load "#{engine}.#{SpecGuard.ruby_version}.mspec"
  try_load "#{engine}.mspec"
end

#registerObject

Registers all filters and actions.



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
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 117

def register
  require 'mspec/runner/formatters/dotted'
  require 'mspec/runner/formatters/spinner'
  require 'mspec/runner/formatters/file'
  require 'mspec/runner/filters'

  if config[:formatter].nil?
    config[:formatter] = STDOUT.tty? ? SpinnerFormatter : @files.size < 50 ? DottedFormatter : FileFormatter
  end

  if config[:formatter]
    formatter = config[:formatter].new(config[:output])
    formatter.register
    MSpec.store :formatter, formatter
  end

  MatchFilter.new(:include, *config[:includes]).register    unless config[:includes].empty?
  MatchFilter.new(:exclude, *config[:excludes]).register    unless config[:excludes].empty?
  RegexpFilter.new(:include, *config[:patterns]).register   unless config[:patterns].empty?
  RegexpFilter.new(:exclude, *config[:xpatterns]).register  unless config[:xpatterns].empty?
  TagFilter.new(:include, *config[:tags]).register          unless config[:tags].empty?
  TagFilter.new(:exclude, *config[:xtags]).register         unless config[:xtags].empty?
  ProfileFilter.new(:include, *config[:profiles]).register  unless config[:profiles].empty?
  ProfileFilter.new(:exclude, *config[:xprofiles]).register unless config[:xprofiles].empty?

  DebugAction.new(config[:atags], config[:astrings]).register if config[:debugger]

  custom_register
end

#setup_envObject



242
243
244
245
246
247
248
249
250
251
252
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 242

def setup_env
  ENV['MSPEC_RUNNER'] = '1'

  unless ENV['RUBY_EXE']
    ENV['RUBY_EXE'] = config[:target] if config[:target]
  end

  unless ENV['RUBY_FLAGS']
    ENV['RUBY_FLAGS'] = config[:flags].join(" ") if config[:flags]
  end
end

#signalsObject

Sets up signal handlers. Only a handler for SIGINT is registered currently.



155
156
157
158
159
160
161
162
163
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 155

def signals
  if config[:abort]
    Signal.trap "INT" do
      MSpec.actions :abort
      puts "\nProcess aborted!"
      exit! 1
    end
  end
end

#try_load(target) ⇒ Object

Returns true if the file was located in config[:path], possibly appending +config. Returns false otherwise.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/extensions/mspec/mspec/utils/script.rb', line 66

def try_load(target)
  names = [target]
  unless target[-6..-1] == config[:config_ext]
    names << target + config[:config_ext]
  end

  names.each do |name|
    config[:path].each do |dir|
      file = File.expand_path name, dir
      if @loaded.include?(file)
        return true
      elsif File.exist? file
        value = Kernel.load(file)
        @loaded << file
        return value
      end
    end
  end

  false
end