Module: MSpec
- Defined in:
- lib/extensions/mspec/mspec/matchers/include.rb,
lib/extensions/mspec/mspec/version.rb,
lib/extensions/mspec/mspec/runner/mspec.rb,
lib/extensions/mspec/mspec/utils/deprecate.rb
Overview
Cannot override #include at the toplevel in MRI
Class Method Summary collapse
- .actions(action, *args) ⇒ Object
-
.clear_current ⇒ Object
Sets the toplevel ContextState to
nil. -
.clear_expectations ⇒ Object
Resets the flag that an expectation has been encountered in an example.
-
.clear_modes ⇒ Object
Clears all registered modes.
-
.delete_tag(tag) ⇒ Object
Deletes
tagfrom the tag file if it exists. -
.delete_tags ⇒ Object
Removes the tag file associated with a spec file.
- .deprecate(what, replacement) ⇒ Object
- .disable_feature(feature) ⇒ Object
- .each_file(&block) ⇒ Object
- .enable_feature(feature) ⇒ Object
- .exc_locations ⇒ Object
-
.expectation ⇒ Object
Records that an expectation has been encountered in an example.
-
.expectation? ⇒ Boolean
Returns true if an expectation has been encountered.
- .feature_enabled?(feature) ⇒ Boolean
- .files ⇒ Object
-
.guard ⇒ Object
Guards can be nested, so a stack is necessary to know when we have exited the toplevel guard.
- .guarded? ⇒ Boolean
- .include(*expected) ⇒ Object
- .make_tag_dir(path) ⇒ Object
-
.mode?(mode) ⇒ Boolean
Returns
trueifmodeis registered. - .not_supported_count ⇒ Object
- .protect(location, &block) ⇒ Object
- .randomize(flag = true) ⇒ Object
- .randomize? ⇒ Boolean
-
.read_tags(keys) ⇒ Object
Returns a list of tags matching any tag string in
keysbased on the return value ofkeys.include?("tag_name"). -
.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 :add while a describe block is adding examples to run later :expectation before a ‘should’, ‘should_receive’, etc.
-
.register_current(state) ⇒ Object
Sets the toplevel ContextState to
state. -
.register_exit(code) ⇒ Object
Stores the exit code used by the runner scripts.
-
.register_mode(mode) ⇒ Object
Registers an operating mode.
-
.register_shared(state) ⇒ Object
Stores the shared ContextState keyed by description.
-
.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:.
- .repeat ⇒ Object
- .repeat=(times) ⇒ Object
- .retrieve(symbol) ⇒ Object
-
.retrieve_shared(desc) ⇒ Object
Returns the shared ContextState matching description.
-
.run_spec(file, settings) ⇒ Object
RHO.
-
.setup_env ⇒ Object
RHO.
- .shuffle(ary) ⇒ Object
- .store(symbol, value) ⇒ Object
-
.tags_file ⇒ Object
Transforms a spec filename into a tags filename by applying each substitution pattern in :tags_pattern.
- .unguard ⇒ Object
- .unregister(symbol, action) ⇒ Object
-
.write_tag(tag) ⇒ Object
Writes
tagto the tag file if it does not already exist. -
.write_tags(tags) ⇒ Object
Writes each tag in
tagsto the tag file.
Class Method Details
.actions(action, *args) ⇒ Object
135 136 137 138 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 135 def self.actions(action, *args) actions = retrieve(action) actions.each { |obj| obj.send action, *args } if actions end |
.clear_current ⇒ Object
Sets the toplevel ContextState to nil.
222 223 224 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 222 def self.clear_current store :current, nil end |
.clear_expectations ⇒ Object
Resets the flag that an expectation has been encountered in an example.
386 387 388 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 386 def self.clear_expectations store :expectations, false end |
.clear_modes ⇒ Object
Clears all registered modes.
280 281 282 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 280 def self.clear_modes store :modes, [] end |
.delete_tag(tag) ⇒ Object
Deletes tag from the tag file if it exists. Returns true if the tag is deleted, false otherwise. Deletes the tag file if it is empty.
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 466 def self.delete_tag(tag) deleted = false desc = tag.escape(tag.description) file = if File.exist? file lines = IO.readlines(file) File.open(file, "w:utf-8") do |f| lines.each do |line| line = line.chomp if line.start_with?(tag.tag) and line.end_with?(desc) deleted = true else f.puts line unless line.empty? end end end File.delete file unless File.size? file end return deleted end |
.delete_tags ⇒ Object
Removes the tag file associated with a spec file.
488 489 490 491 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 488 def self. file = File.delete file if File.exist? file end |
.deprecate(what, replacement) ⇒ Object
2 3 4 5 |
# File 'lib/extensions/mspec/mspec/utils/deprecate.rb', line 2 def self.deprecate(what, replacement) user_caller = caller.find { |line| !line.include?('lib/mspec') } $stderr.puts "\n#{what} is deprecated, use #{replacement} instead.\nfrom #{user_caller}" end |
.disable_feature(feature) ⇒ Object
293 294 295 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 293 def self.disable_feature(feature) retrieve(:features)[feature] = false end |
.each_file(&block) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 98 def self.each_file(&block) if ENV["MSPEC_MULTI"] STDOUT.print "." STDOUT.flush while (file = STDIN.gets.chomp) != "QUIT" yield file STDOUT.print "." STDOUT.flush end else return unless files = retrieve(:files) shuffle files if randomize? files.each(&block) end end |
.enable_feature(feature) ⇒ Object
289 290 291 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 289 def self.enable_feature(feature) retrieve(:features)[feature] = true end |
.exc_locations ⇒ Object
49 50 51 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 49 def self.exc_locations @exc_locations end |
.expectation ⇒ Object
Records that an expectation has been encountered in an example.
376 377 378 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 376 def self.expectation store :expectations, true end |
.expectation? ⇒ Boolean
Returns true if an expectation has been encountered
381 382 383 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 381 def self.expectation? retrieve :expectations end |
.feature_enabled?(feature) ⇒ Boolean
297 298 299 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 297 def self.feature_enabled?(feature) retrieve(:features)[feature] || false end |
.files ⇒ Object
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 87 def self.files each_file do |file| setup_env store :file, file actions :load puts "MSPEC run spec: ["+file.to_s+"]" protect("loading #{file}") { Kernel.load file } actions :unload end end |
.guard ⇒ Object
Guards can be nested, so a stack is necessary to know when we have exited the toplevel guard.
204 205 206 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 204 def self.guard @guarded << true end |
.guarded? ⇒ Boolean
212 213 214 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 212 def self.guarded? !@guarded.empty? end |
.include(*expected) ⇒ Object
28 29 30 |
# File 'lib/extensions/mspec/mspec/matchers/include.rb', line 28 def include(*expected) IncludeMatcher.new(*expected) end |
.make_tag_dir(path) ⇒ Object
426 427 428 429 430 431 432 433 434 435 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 426 def self.make_tag_dir(path) parent = File.dirname(path) return if File.exist? parent begin Dir.mkdir(parent) rescue SystemCallError make_tag_dir(parent) Dir.mkdir(parent) end end |
.mode?(mode) ⇒ Boolean
Returns true if mode is registered.
285 286 287 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 285 def self.mode?(mode) retrieve(:modes).include? mode end |
.not_supported_count ⇒ Object
53 54 55 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 53 def self.not_supported_count @not_supported_count end |
.protect(location, &block) ⇒ Object
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 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 140 def self.protect(location, &block) #puts ">>>>>>" #puts caller #puts "<<<<<<" passed = false begin @env.instance_eval(&block) #RHO passed = true #RHO #return true rescue SystemExit => e raise e rescue Exception => exc register_exit 1 actions :exception, ExceptionState.new(current && current.state, location, exc) #RHO puts "FAIL: #{current} - #{exc.}\n" + (@backtrace ? exc.backtrace.join("\n") : "")# + " @exc_count[#{@exc_count.to_s}]" not_supported = (exc.=='RHO: not supported') info = { 'message' => exc., 'backtrace' => exc.backtrace, 'not_supported' => not_supported } key = location.to_s key = current.state.description if current and current.state and current.state.description key = 'unknown' if key.nil? if @exc_locations[key].nil? @exc_locations[key] = [] end @exc_locations[key] << info #@exc_locations << { 'spec' => current, 'message' => exc.message, 'backtrace' => exc.backtrace } if not_supported @not_supported_count+=1 else @exc_count+=1 end #RHO return false end #RHO if passed begin #if current.to_s.length > 0 puts "PASSED: #{current.to_s} - OK"# +" @exc_count[#{@exc_count.to_s}]" #end rescue end end return true #RHO end |
.randomize(flag = true) ⇒ Object
347 348 349 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 347 def self.randomize(flag=true) @randomize = flag end |
.randomize? ⇒ Boolean
351 352 353 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 351 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")
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 410 def self.(keys) = [] file = if File.exist? file File.open(file, "r:utf-8") do |f| f.each_line do |line| line.chomp! next if line.empty? tag = SpecTag.new line << tag if keys.include? tag.tag end end end 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
:add while a describe block is adding examples to run later
: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
334 335 336 337 338 339 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 334 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.
217 218 219 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 217 def self.register_current(state) store :current, state end |
.register_exit(code) ⇒ Object
Stores the exit code used by the runner scripts.
242 243 244 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 242 def self.register_exit(code) store :exit, code end |
.register_mode(mode) ⇒ Object
Registers an operating mode. Modes recognized by MSpec:
:pretend - actions execute but specs are not run
:verify - specs are run despite guards and the result is
verified to match the expectation of the guard
:report - specs that are guarded are reported
:unguarded - all guards are forced off
274 275 276 277 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 274 def self.register_mode(mode) modes = retrieve :modes modes << mode unless modes.include? mode end |
.register_shared(state) ⇒ Object
Stores the shared ContextState keyed by description.
232 233 234 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 232 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.
263 264 265 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 263 def self.(patterns) store :tags_patterns, patterns end |
.repeat ⇒ Object
359 360 361 362 363 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 359 def self.repeat (@repeat || 1).times do yield end end |
.repeat=(times) ⇒ Object
355 356 357 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 355 def self.repeat=(times) @repeat = times end |
.retrieve(symbol) ⇒ Object
301 302 303 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 301 def self.retrieve(symbol) instance_variable_get :"@#{symbol}" end |
.retrieve_shared(desc) ⇒ Object
Returns the shared ContextState matching description.
237 238 239 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 237 def self.retrieve_shared(desc) @shared[desc.to_s] end |
.run_spec(file, settings) ⇒ Object
RHO
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 115 def self.run_spec(file,settings) setup_env $spec_settings = settings store :file, file actions :load puts "MSPEC run spec: ["+file.to_s+"]" protect("loading #{file}") { Kernel.load file } actions :unload end |
.setup_env ⇒ Object
RHO
130 131 132 133 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 130 def self.setup_env @env = Object.new @env.extend MSpec end |
.shuffle(ary) ⇒ Object
365 366 367 368 369 370 371 372 373 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 365 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
305 306 307 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 305 def self.store(symbol, value) instance_variable_set :"@#{symbol}", value end |
.tags_file ⇒ Object
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.
400 401 402 403 404 405 406 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 400 def self. 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 |
.unguard ⇒ Object
208 209 210 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 208 def self.unguard @guarded.pop end |
.unregister(symbol, action) ⇒ Object
341 342 343 344 345 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 341 def self.unregister(symbol, action) if value = retrieve(symbol) value.delete action end end |
.write_tag(tag) ⇒ Object
Writes tag to the tag file if it does not already exist. Returns true if the tag is written, false otherwise.
449 450 451 452 453 454 455 456 457 458 459 460 461 |
# File 'lib/extensions/mspec/mspec/runner/mspec.rb', line 449 def self.write_tag(tag) = ([tag.tag]) .each do |t| if t.tag == tag.tag and t.description == tag.description return false end end file = make_tag_dir(file) File.open(file, "a:utf-8") { |f| f.puts tag.to_s } return true end |