Module: NRSER::RSpex::ExampleGroup

Defined in:
lib/nrser/rspex.rb

Overview

Instance methods to extend example groups with.

Instance Method Summary collapse

Instance Method Details

#context_where(description = nil, **bindings, &body) ⇒ Object

Define a ‘context` block with `let` bindings and evaluate the `body` block in it.



586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/nrser/rspex.rb', line 586

def context_where description = nil, **bindings, &body
  
  if description.nil?
    description = bindings.map { |name, value|
      "#{ name }: #{ NRSER::RSpex.short_s value }"
    }.join( ", " )
  end
  
  context "△ #{ description }", type: :where do
    bindings.each { |name, value|
      let( name ) { unwrap value, context: self }
    }
    
    module_exec &body
  end
end

#describe_attribute(symbol, **metadata, &block) ⇒ Object Also known as: describe_attr



559
560
561
562
563
564
565
566
567
568
# File 'lib/nrser/rspex.rb', line 559

def describe_attribute symbol, **, &block
  describe(
    "#{ NRSER::RSpex::PREFIXES[:attribute] } ##{ symbol }",
    type: :attribute,
    **
  ) do
    subject { super().public_send symbol }
    module_exec &block
  end
end

#describe_called_with(*args, &body) ⇒ Object Also known as: called_with, when_called_with

Create a new RSpec.describe section where the subject is set by calling the parent subject with ‘args` and evaluate `block` in it.

Examples:

describe "hi sayer" do
  subject{ ->( name ) { "Hi #{ name }!" } }

  describe_called_with 'Mom' do
    it { is_expected.to eq 'Hi Mom!' }
  end
end


372
373
374
375
376
377
# File 'lib/nrser/rspex.rb', line 372

def describe_called_with *args, &body
  describe_x_type  "called with", List(*args),
    type: :invocation,
    subject_block: -> { super().call *args },
    &body
end

#describe_class(klass, bind_subject: true, **metadata, &block) ⇒ Object



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/nrser/rspex.rb', line 509

def describe_class klass, bind_subject: true, **, &block
  description = "#{ NRSER::RSpex::PREFIXES[:class] } #{ klass.name }"
  
  describe(
    description,
    type: :class,
    class: klass,
    **
  ) do
    if bind_subject
      subject { klass }
    end
    
    module_exec &block
  end
end

#describe_file(path, **metadata, &body) ⇒ Object



479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/nrser/rspex.rb', line 479

def describe_file path, **, &body
  title = path
  
  describe(
    "#{ NRSER::RSpex::PREFIXES[:file] } #{ title }",
    type: :file,
    file: path,
    **
  ) do
    module_exec &body
  end
end

#describe_group(title, **metadata, &block) ⇒ Object



532
533
534
535
536
537
538
539
540
# File 'lib/nrser/rspex.rb', line 532

def describe_group title, **, &block
  describe(
    "#{ NRSER::RSpex::PREFIXES[:group] } #{ title }",
    type: :group,
    **
  ) do
    module_exec &block
  end
end

#describe_instance(*constructor_args, &body) ⇒ return_type



341
342
343
344
345
346
347
348
349
350
# File 'lib/nrser/rspex.rb', line 341

def describe_instance *constructor_args, &body
  describe_x_type ".new(", Args(*constructor_args), ")",
    type: :instance,
    metadata: {
      constructor_args: constructor_args,
    },
    # subject_block: -> { super().new *described_args },
    subject_block: -> { super().new *described_constructor_args },
    &body
end

#describe_message(symbol, *args, &body) ⇒ Object



388
389
390
391
392
393
394
395
396
# File 'lib/nrser/rspex.rb', line 388

def describe_message symbol, *args, &body
  description = \
    "message #{ [symbol, *args].map( &NRSER::RSpex.method( :short_s ) ).join( ', ' ) }"
  
  describe description, type: :message do
    subject { NRSER::Message.new symbol, *args }
    module_exec &body
  end
end

#describe_method(name, **metadata, &block) ⇒ Object



543
544
545
546
547
548
549
550
551
552
553
554
555
556
# File 'lib/nrser/rspex.rb', line 543

def describe_method name, **, &block
  describe(
    "#{ NRSER::RSpex::PREFIXES[:method] } #{ name }",
    type: :method,
    method_name: name,
    **
  ) do
    if name.is_a? Symbol
      subject { super().method name }
    end
    
    module_exec &block
  end
end

#describe_module(mod, bind_subject: true, **metadata, &block) ⇒ Object



493
494
495
496
497
498
499
500
501
502
503
504
505
506
# File 'lib/nrser/rspex.rb', line 493

def describe_module mod, bind_subject: true, **, &block
  describe(
    "#{ NRSER::RSpex::PREFIXES[:module] } #{ mod.name }",
    type: :module,
    module: mod,
    **
  ) do
    if bind_subject
      subject { mod }
    end
    
    module_exec &block
  end
end

#describe_return_value(*args, &body) ⇒ Object



435
436
437
438
439
440
441
442
# File 'lib/nrser/rspex.rb', line 435

def describe_return_value *args, &body
  msg = NRSER::Message.from *args
  
  describe "return value from #{ msg }" do
    subject { msg.send_to super() }
    module_exec &body
  end # "return value from #{ msg }"
end

#describe_section(title, **metadata, &block) ⇒ Object Also known as: describe_topic

Describe a “section”. Just like RSpec.describe except it:

  1. Expects a string title.

  2. Prepends a little section squiggle ‘§` to the title so sections are easier to pick out visually.

  3. Adds ‘type: :section` metadata.



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

def describe_section title, **, &block
  describe(
    "#{ NRSER::RSpex::PREFIXES[:section] } #{ title }",
    type: :section,
    **
  ) do
    module_exec &block
  end
end

#describe_sent_to(receiver, publicly: true, &block) ⇒ Object Also known as: sent_to, when_sent_to

For use when ‘subject` is a Message. Create a new context for the `receiver` where the subject is the result of sending that message to the receiver.



413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/nrser/rspex.rb', line 413

def describe_sent_to receiver, publicly: true, &block
  mode = if publicly
    "publicly"
  else
    "privately"
  end
  
  describe "sent to #{ receiver } (#{ mode })" do
    subject { super().send_to unwrap( receiver, context: self ) }
    module_exec &block
  end
end

#describe_spec_file(description: nil, spec_path:, bind_subject: true, **metadata, &body) ⇒ nil

TODO:

This is totally just a one-off right now… would need to be generalized quite a bit…

  1. Extraction of module, class, etc from metadata should be flexible

  2. Built description would need to be conditional on what metadata was found.

EXPERIMENTAL

Example group helper for use at the top level of each spec file to set a bunch of stuff up and build a helpful description.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/nrser/rspex.rb', line 301

def describe_spec_file  description: nil,
                        spec_path:,
                        bind_subject: true,
                        **,
                        &body

  meth = [:module].method [:method]
  file, line = meth.source_location
  path = Pathname.new file
  loc = "./#{ path.relative_path_from Pathname.getwd }:#{ line }"
  
  spec_rel_path = "./#{ Pathname.new( spec_path ).relative_path_from Pathname.getwd }"
  
  desc = [
    "#{ metadata[:module].name }.#{ metadata[:method] }",
    "(#{ loc })",
    description,
    "Spec (#{ spec_rel_path})"
  ].compact.join " "
  
  describe desc, ** do
    if bind_subject
      subject { meth }
    end
    
    module_exec &body
  end
  
  nil
end

#describe_x_type(*description_parts, type:, metadata: {}, subject_block: nil, &body) ⇒ return_type



261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/nrser/rspex.rb', line 261

def describe_x_type *description_parts,
                    type:,
                    metadata: {},
                    subject_block: nil,
                    &body
  
  description = NRSER::RSpex.format *description_parts, type: type
  
  describe description, **, type: type do
    subject( &subject_block ) if subject_block
    module_exec &body
  end # description,
  
end

#described_classObject



527
528
529
# File 'lib/nrser/rspex.rb', line 527

def described_class
  [:class] || super()
end