Class: Shoulda::Context::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/shoulda/context/context.rb

Overview

:nodoc:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, parent, &blk) ⇒ Context

Returns a new instance of Context.



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/shoulda/context/context.rb', line 303

def initialize(name, parent, &blk)
  Shoulda::Context.add_context(self)
  self.name               = name
  self.parent             = parent
  self.setup_blocks       = []
  self.teardown_blocks    = []
  self.shoulds            = []
  self.should_eventuallys = []
  self.subcontexts        = []
  self.subject_block      = nil

  if block_given?
    merge_block(&blk)
  else
    merge_block { warn "  * WARNING: Block missing for context '#{full_name}'" }
  end
  Shoulda::Context.remove_context
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &blk) ⇒ Object



483
484
485
# File 'lib/shoulda/context/context.rb', line 483

def method_missing(method, *args, &blk)
  test_unit_class.send(method, *args, &blk)
end

Instance Attribute Details

#nameObject

my name



288
289
290
# File 'lib/shoulda/context/context.rb', line 288

def name
  @name
end

#parentObject

may be another context, or the original test::unit class.



289
290
291
# File 'lib/shoulda/context/context.rb', line 289

def parent
  @parent
end

#setup_blocksObject

blocks given via setup methods



291
292
293
# File 'lib/shoulda/context/context.rb', line 291

def setup_blocks
  @setup_blocks
end

#should_eventuallysObject

array of hashes representing the should eventually statements



294
295
296
# File 'lib/shoulda/context/context.rb', line 294

def should_eventuallys
  @should_eventuallys
end

#shouldsObject

array of hashes representing the should statements



293
294
295
# File 'lib/shoulda/context/context.rb', line 293

def shoulds
  @shoulds
end

#subcontextsObject

array of contexts nested under myself



290
291
292
# File 'lib/shoulda/context/context.rb', line 290

def subcontexts
  @subcontexts
end

#subject_blockObject

accessor with cache



297
298
299
300
# File 'lib/shoulda/context/context.rb', line 297

def subject_block
  return @subject_block if @subject_block
  parent.subject_block
end

#teardown_blocksObject

blocks given via teardown methods



292
293
294
# File 'lib/shoulda/context/context.rb', line 292

def teardown_blocks
  @teardown_blocks
end

Instance Method Details

#am_subcontext?Boolean

Returns:

  • (Boolean)


377
378
379
# File 'lib/shoulda/context/context.rb', line 377

def am_subcontext?
  parent.is_a?(self.class) # my parent is the same class as myself.
end

#buildObject



465
466
467
468
469
470
471
472
473
# File 'lib/shoulda/context/context.rb', line 465

def build
  shoulds.each do |should|
    create_test_from_should_hash(should)
  end

  subcontexts.each { |context| context.build }

  print_should_eventuallys
end

#context(name, &blk) ⇒ Object



331
332
333
# File 'lib/shoulda/context/context.rb', line 331

def context(name, &blk)
  self.subcontexts << Context.new(name, self, &blk)
end

#create_test_from_should_hash(should) ⇒ Object



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/shoulda/context/context.rb', line 391

def create_test_from_should_hash(should)
  test_name = [test_name_prefix, full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym

  if test_methods[test_unit_class][test_name.to_s] then
    raise DuplicateTestError, "'#{test_name}' is defined more than once."
  end

  test_methods[test_unit_class][test_name.to_s] = true
  file, line_no = should[:block].source_location
  context = self
  test_unit_class.class_eval <<-end_eval, file, line_no
    define_method test_name do
    @shoulda_context = context
    begin
      context.run_parent_setup_blocks(self)
      if should[:before]
        if self.respond_to?(:instance_exec)
          self.instance_exec(&should[:before])
        else
          should[:before].bind(self).call
        end
      end
      context.run_current_setup_blocks(self)
      if self.respond_to?(:instance_exec)
        self.instance_exec(&should[:block])
      else
        should[:block].bind(self).call
      end
    ensure
      context.run_all_teardown_blocks(self)
    end
    end
  end_eval
end

#full_nameObject



372
373
374
375
# File 'lib/shoulda/context/context.rb', line 372

def full_name
  parent_name = parent.full_name if am_subcontext?
  return [parent_name, name].join(" ").strip
end

#merge_block(&blk) ⇒ Object



322
323
324
325
326
327
328
329
# File 'lib/shoulda/context/context.rb', line 322

def merge_block(&blk)
  if self.respond_to?(:instance_exec)
    self.instance_exec(&blk)
  else
    # deprecated in Rails 4.x
    blk.bind(self).call
  end
end


458
459
460
461
462
463
# File 'lib/shoulda/context/context.rb', line 458

def print_should_eventuallys
  should_eventuallys.each do |should|
    test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
    puts "  * DEFERRED: " + test_name
  end
end

#run_all_setup_blocks(binding) ⇒ Object



426
427
428
429
# File 'lib/shoulda/context/context.rb', line 426

def run_all_setup_blocks(binding)
  run_parent_setup_blocks(binding)
  run_current_setup_blocks(binding)
end

#run_all_teardown_blocks(binding) ⇒ Object



446
447
448
449
450
451
452
453
454
455
456
# File 'lib/shoulda/context/context.rb', line 446

def run_all_teardown_blocks(binding)
  teardown_blocks.reverse.each do |teardown_block|
    if binding.respond_to?(:instance_exec)
      binding.instance_exec(&teardown_block)
    else
      # deprecated in Rails 4.x
      teardown_block.bind(binding).call
    end
  end
  self.parent.run_all_teardown_blocks(binding) if am_subcontext?
end

#run_current_setup_blocks(binding) ⇒ Object



435
436
437
438
439
440
441
442
443
444
# File 'lib/shoulda/context/context.rb', line 435

def run_current_setup_blocks(binding)
  setup_blocks.each do |setup_block|
    if binding.respond_to?(:instance_exec)
      binding.instance_exec(&setup_block)
    else
      # deprecated in Rails 4.x
      setup_block.bind(binding).call
    end
  end
end

#run_parent_setup_blocks(binding) ⇒ Object



431
432
433
# File 'lib/shoulda/context/context.rb', line 431

def run_parent_setup_blocks(binding)
  self.parent.run_all_setup_blocks(binding) if am_subcontext?
end

#setup(&blk) ⇒ Object



335
336
337
# File 'lib/shoulda/context/context.rb', line 335

def setup(&blk)
  self.setup_blocks << blk
end

#should(name_or_matcher, options = {}, &blk) ⇒ Object



343
344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/shoulda/context/context.rb', line 343

def should(name_or_matcher, options = {}, &blk)
  if name_or_matcher.respond_to?(:description) && name_or_matcher.respond_to?(:matches?)
    name = name_or_matcher.description
    blk = lambda { assert_accepts name_or_matcher, subject }
  else
    name = name_or_matcher
  end

  if blk
    self.shoulds << { :name => name, :before => options[:before], :block => blk }
  else
    self.should_eventuallys << { :name => name }
  end
end

#should_eventually(name, &blk) ⇒ Object



364
365
366
# File 'lib/shoulda/context/context.rb', line 364

def should_eventually(name, &blk)
  self.should_eventuallys << { :name => name, :block => blk }
end

#should_not(matcher) ⇒ Object



358
359
360
361
362
# File 'lib/shoulda/context/context.rb', line 358

def should_not(matcher)
  name = matcher.description
  blk = lambda { assert_rejects matcher, subject }
  self.shoulds << { :name => "not #{name}", :block => blk }
end

#subject(&block) ⇒ Object



368
369
370
# File 'lib/shoulda/context/context.rb', line 368

def subject(&block)
  self.subject_block = block
end

#teardown(&blk) ⇒ Object



339
340
341
# File 'lib/shoulda/context/context.rb', line 339

def teardown(&blk)
  self.teardown_blocks << blk
end

#test_methodsObject



385
386
387
388
389
# File 'lib/shoulda/context/context.rb', line 385

def test_methods
  @test_methods ||= Hash.new { |h,k|
    h[k] = Hash[k.instance_methods.map { |n| [n, true] }]
  }
end

#test_name_prefixObject



475
476
477
478
479
480
481
# File 'lib/shoulda/context/context.rb', line 475

def test_name_prefix
  if defined?(Minitest) || defined?(MiniTest)
    'test_:'
  else
    'test:'
  end
end

#test_unit_classObject



381
382
383
# File 'lib/shoulda/context/context.rb', line 381

def test_unit_class
  am_subcontext? ? parent.test_unit_class : parent
end