Class: MSpecScript

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

Overview

MSpecScript provides a skeleton for all the MSpec runner scripts.

Direct Known Subclasses

MSpecCI, MSpecMain, MSpecRun, MSpecTag

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
# File 'lib/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
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.



10
11
12
13
14
15
# File 'lib/mspec/utils/script.rb', line 10

def self.config
  @config ||= {
    :path => ['.', 'spec'],
    :config_ext => '.mspec'
  }
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/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.



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

def self.main
  $VERBOSE = nil unless ENV['OUTPUT_WARNINGS']
  script = new
  script.load_default
  script.load '~/.mspecrc'
  script.options
  script.signals
  script.register
  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/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.



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

def config
  MSpecScript.config
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.



102
103
104
# File 'lib/mspec/utils/script.rb', line 102

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.



136
137
# File 'lib/mspec/utils/script.rb', line 136

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, returns Dir[partial].



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/mspec/utils/script.rb', line 163

def entries(partial)
  file = partial + "_spec.rb"
  patterns = [partial]
  patterns << 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)
    return [expanded] if File.file?(expanded)

    specs = File.join(pattern, "/**/*_spec.rb")
    specs = File.expand_path(specs) rescue specs
    return Dir[specs].sort if File.directory?(expanded)
  end

  Dir[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.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/mspec/utils/script.rb', line 192

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

#load(target) ⇒ Object

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



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

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

  names.each do |name|
    return Kernel.load(name) if File.exist?(File.expand_path(name))

    config[:path].each do |dir|
      file = File.join dir, name
      return Kernel.load(file) if File.exist? file
    end
  end

  false
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’.



88
89
90
91
92
93
94
95
96
97
# File 'lib/mspec/utils/script.rb', line 88

def load_default
  return if load 'default.mspec'

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

#registerObject

Registers all filters and actions.



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

def register
  if config[:formatter].nil?
    config[:formatter] = @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]
  GdbAction.new(config[:atags], config[:astrings]).register   if config[:gdb]

  custom_register
end

#signalsObject

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



141
142
143
144
145
146
147
148
# File 'lib/mspec/utils/script.rb', line 141

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