Module: MSpec

Defined in:
lib/mspec/matchers/include.rb,
lib/mspec/version.rb,
lib/mspec/runner/mspec.rb

Overview

Cannot override #include at the toplevel in MRI

Constant Summary collapse

VERSION =
'1.5.1'

Class Method Summary collapse

Class Method Details

.actions(action, *args) ⇒ Object



59
60
61
62
# File 'lib/mspec/runner/mspec.rb', line 59

def self.actions(action, *args)
  actions = retrieve(action)
  actions.each { |obj| obj.send action, *args } if actions
end

.clear_currentObject

Sets the toplevel ContextState to nil.



83
84
85
# File 'lib/mspec/runner/mspec.rb', line 83

def self.clear_current
  store :current, nil
end

.clear_expectationsObject

Resets the flag that an expectation has been encountered in an example.



218
219
220
# File 'lib/mspec/runner/mspec.rb', line 218

def self.clear_expectations
  store :expectations, false
end

.currentObject

Returns the toplevel ContextState.



88
89
90
# File 'lib/mspec/runner/mspec.rb', line 88

def self.current
  retrieve :current
end

.delete_tag(tag) ⇒ Object



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/mspec/runner/mspec.rb', line 270

def self.delete_tag(tag)
  deleted = false
  pattern = /#{tag.tag}.*#{Regexp.escape tag.description}/
  file = tags_file
  if File.exist? file
    lines = IO.readlines(file)
    File.open(file, "w") do |f|
      lines.each do |line|
        unless pattern =~ line.chomp
          f.puts line unless line.empty?
        else
          deleted = true
        end
      end
    end
    File.delete file unless File.size? file
  end
  return deleted
end

.describe(mod, options = nil, &block) ⇒ Object



28
29
30
31
32
33
34
35
36
# File 'lib/mspec/runner/mspec.rb', line 28

def self.describe(mod, options=nil, &block)
  state = ContextState.new mod, options
  state.parent = current

  MSpec.register_current state
  state.describe(&block)

  state.process unless state.shared? or current
end

.exit_codeObject

Retrieves the stored exit code.



108
109
110
# File 'lib/mspec/runner/mspec.rb', line 108

def self.exit_code
  retrieve(:exit).to_i
end

.expectationObject

Records that an expectation has been encountered in an example.



208
209
210
# File 'lib/mspec/runner/mspec.rb', line 208

def self.expectation
  store :expectations, true
end

.expectation?Boolean

Returns true if an expectation has been encountered

Returns:

  • (Boolean)


213
214
215
# File 'lib/mspec/runner/mspec.rb', line 213

def self.expectation?
  retrieve :expectations
end

.filesObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/mspec/runner/mspec.rb', line 44

def self.files
  return unless files = retrieve(:files)

  shuffle files if randomize?
  files.each do |file|
    @env = Object.new
    @env.extend MSpec

    store :file, file
    actions :load
    protect("loading #{file}") { Kernel.load file }
    actions :unload
  end
end

.include(*expected) ⇒ Object



28
29
30
# File 'lib/mspec/matchers/include.rb', line 28

def include(*expected)
  IncludeMatcher.new(*expected)
end

.pretend_mode?Boolean

Returns:

  • (Boolean)


185
186
187
# File 'lib/mspec/runner/mspec.rb', line 185

def self.pretend_mode?
  @mode == :pretend
end

.processObject



38
39
40
41
42
# File 'lib/mspec/runner/mspec.rb', line 38

def self.process
  actions :start
  files
  actions :finish
end

.protect(location, &block) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mspec/runner/mspec.rb', line 64

def self.protect(location, &block)
  begin
    @env.instance_eval(&block)
    return true
  rescue SystemExit
    raise
  rescue Exception => exc
    register_exit 1
    actions :exception, ExceptionState.new(current && current.state, location, exc)
    return false
  end
end

.randomize(flag = true) ⇒ Object



189
190
191
# File 'lib/mspec/runner/mspec.rb', line 189

def self.randomize(flag=true)
  @randomize = flag
end

.randomize?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/mspec/runner/mspec.rb', line 193

def self.randomize?
  @randomize == true
end

.read_tags(keys) ⇒ Object

Returns a list of tags matching any tag string in keys based on the return value of keys.include?("tag_name")



242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/mspec/runner/mspec.rb', line 242

def self.read_tags(keys)
  tags = []
  file = tags_file
  if File.exist? file
    File.open(file, "r") do |f|
      f.each_line do |line|
        tag = SpecTag.new line.chomp
        tags << tag if keys.include? tag.tag
      end
    end
  end
  tags
end

.register(symbol, action) ⇒ Object

This method is used for registering actions that are run at particular points in the spec cycle:

:start        before any specs are run
:load         before a spec file is loaded
:enter        before a describe block is run
:before       before a single spec is run
:expectation  before a 'should', 'should_receive', etc.
:example      after an example block is run, passed the block
:exception    after an exception is rescued
:after        after a single spec is run
:leave        after a describe block is run
:unload       after a spec file is run
:finish       after all specs are run

Objects registered as actions above should respond to a method of the same name. For example, if an object is registered as a :start action, it should respond to a #start method call.

Additionally, there are two “action” lists for filtering specs:

:include  return true if the spec should be run
:exclude  return true if the spec should NOT be run


164
165
166
167
168
169
# File 'lib/mspec/runner/mspec.rb', line 164

def self.register(symbol, action)
  unless value = retrieve(symbol)
    value = store symbol, []
  end
  value << action unless value.include? action
end

.register_current(state) ⇒ Object

Sets the toplevel ContextState to state.



78
79
80
# File 'lib/mspec/runner/mspec.rb', line 78

def self.register_current(state)
  store :current, state
end

.register_exit(code) ⇒ Object

Stores the exit code used by the runner scripts.



103
104
105
# File 'lib/mspec/runner/mspec.rb', line 103

def self.register_exit(code)
  store :exit, code
end

.register_files(files) ⇒ Object

Stores the list of files to be evaluated.



113
114
115
# File 'lib/mspec/runner/mspec.rb', line 113

def self.register_files(files)
  store :files, files
end

.register_mode(mode) ⇒ Object



128
129
130
# File 'lib/mspec/runner/mspec.rb', line 128

def self.register_mode(mode)
  store :mode, mode
end

.register_shared(state) ⇒ Object

Stores the shared ContextState keyed by description.



93
94
95
# File 'lib/mspec/runner/mspec.rb', line 93

def self.register_shared(state)
  @shared[state.to_s] = state
end

.register_tags_patterns(patterns) ⇒ Object

Stores one or more substitution patterns for transforming a spec filename into a tags filename, where each pattern has the form:

[Regexp, String]

See also tags_file.



124
125
126
# File 'lib/mspec/runner/mspec.rb', line 124

def self.register_tags_patterns(patterns)
  store :tags_patterns, patterns
end

.report_mode?Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/mspec/runner/mspec.rb', line 181

def self.report_mode?
  @mode == :report
end

.retrieve(symbol) ⇒ Object



132
133
134
# File 'lib/mspec/runner/mspec.rb', line 132

def self.retrieve(symbol)
  instance_variable_get :"@#{symbol}"
end

.retrieve_shared(desc) ⇒ Object

Returns the shared ContextState matching description.



98
99
100
# File 'lib/mspec/runner/mspec.rb', line 98

def self.retrieve_shared(desc)
  @shared[desc.to_s]
end

.shuffle(ary) ⇒ Object



197
198
199
200
201
202
203
204
205
# File 'lib/mspec/runner/mspec.rb', line 197

def self.shuffle(ary)
  return if ary.empty?

  size = ary.size
  size.times do |i|
    r = rand(size - i - 1)
    ary[i], ary[r] = ary[r], ary[i]
  end
end

.store(symbol, value) ⇒ Object



136
137
138
# File 'lib/mspec/runner/mspec.rb', line 136

def self.store(symbol, value)
  instance_variable_set :"@#{symbol}", value
end

.tags_fileObject

Transforms a spec filename into a tags filename by applying each substitution pattern in :tags_pattern. The default patterns are:

[%r(/spec/), '/spec/tags/'], [/_spec.rb$/, '_tags.txt']

which will perform the following transformation:

path/to/spec/class/method_spec.rb => path/to/spec/tags/class/method_tags.txt

See also register_tags_patterns.



232
233
234
235
236
237
238
# File 'lib/mspec/runner/mspec.rb', line 232

def self.tags_file
  patterns = retrieve(:tags_patterns) ||
             [[%r(spec/), 'spec/tags/'], [/_spec.rb$/, '_tags.txt']]
  patterns.inject(retrieve(:file).dup) do |file, pattern|
    file.gsub(*pattern)
  end
end

.unregister(symbol, action) ⇒ Object



171
172
173
174
175
# File 'lib/mspec/runner/mspec.rb', line 171

def self.unregister(symbol, action)
  if value = retrieve(symbol)
    value.delete action
  end
end

.verify_mode?Boolean

Returns:

  • (Boolean)


177
178
179
# File 'lib/mspec/runner/mspec.rb', line 177

def self.verify_mode?
  @mode == :verify
end

.write_tag(tag) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/mspec/runner/mspec.rb', line 256

def self.write_tag(tag)
  string = tag.to_s
  file = tags_file
  path = File.dirname file
  FileUtils.mkdir_p(path) unless File.exist?(path)
  if File.exist? file
    File.open(file, "r") do |f|
      f.each_line { |line| return false if line.chomp == string }
    end
  end
  File.open(file, "a") { |f| f.puts string }
  return true
end