Module: Dfect

Included in:
Object
Defined in:
lib/dfect.rb

Defined Under Namespace

Classes: Suite

Constant Summary collapse

D =

Allows before and after hooks to be specified via the D() method syntax when this module is mixed-in:

D .<  { puts "before each nested test" }
D .>  { puts "after  each nested test" }
D .<< { puts "before all nested tests" }
D .>> { puts "after  all nested tests" }
self

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.optionsObject

Hash of choices that affect how Dfect operates.

:debug

Launch an interactive debugger during assertion failures so the user can investigate them.

The default value is true.

:quiet

Do not print the report after executing all tests.

The default value is false.



96
97
98
# File 'lib/dfect.rb', line 96

def options
  @options
end

.reportObject (readonly)

Hash of test results, assembled by #run.

:execution

Hierarchical trace of all tests executed, where each test is represented by its description, is mapped to an Array of nested tests, and may contain zero or more assertion failures.

Assertion failures are represented as a Hash:

“fail”

Description of the assertion failure.

“code”

Source code surrounding the point of failure.

“vars”

Local variables visible at the point of failure.

“call”

Stack trace leading to the point of failure.

:statistics

Hash of counts of major events in test execution:

:passed_assertions

Number of assertions that held true.

:failed_assertions

Number of assertions that did not hold true.

:uncaught_exceptions

Number of exceptions that were not rescued.



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

def report
  @report
end

Class Method Details

.<(*args, &block) ⇒ Object

:call-seq: <(&block)

Registers the given block to be executed before each nested test inside this test.

Examples

D .< { puts "before each nested test" }

D .< do
  puts "before each nested test"
end


146
147
148
149
150
151
152
153
154
# File 'lib/dfect.rb', line 146

def <(*args, &block)
  if args.empty?
    raise ArgumentError, 'block must be given' unless block
    @curr_suite.before_each << block
  else
    # the < method is being used as a check for inheritance
    super
  end
end

.<<(&block) ⇒ Object

Registers the given block to be executed before all nested tests inside this test.

Examples

D .<< { puts "before all nested tests" }

D .<< do
  puts "before all nested tests"
end

Raises:

  • (ArgumentError)


185
186
187
188
# File 'lib/dfect.rb', line 185

def << &block
  raise ArgumentError, 'block must be given' unless block
  @curr_suite.before_all << block
end

.>(&block) ⇒ Object

Registers the given block to be executed after each nested test inside this test.

Examples

D .> { puts "after each nested test" }

D .> do
  puts "after each nested test"
end

Raises:

  • (ArgumentError)


168
169
170
171
# File 'lib/dfect.rb', line 168

def > &block
  raise ArgumentError, 'block must be given' unless block
  @curr_suite.after_each << block
end

.>>(&block) ⇒ Object

Registers the given block to be executed after all nested tests inside this test.

Examples

D .>> { puts "after all nested tests" }

D .>> do
  puts "after all nested tests"
end

Raises:

  • (ArgumentError)


202
203
204
205
# File 'lib/dfect.rb', line 202

def >> &block
  raise ArgumentError, 'block must be given' unless block
  @curr_suite.after_all << block
end

.C(message = nil, symbol = nil, &block) ⇒ Object

Asserts that the given symbol is thrown when the given block is executed.

If a value is thrown along with the expected symbol, then that value is returned.

Otherwise, nil is returned.

Parameters

message

Optional message to show in the report if this assertion fails.

symbol

Symbol that must be thrown by the given block.

Examples

# no message specified:

C(:foo) { throw :foo, 123 } # passes, => 123
C(:foo) { throw :bar, 456 } # fails,  => 456
C(:foo) { }                 # fails,  => nil

# message specified:

C( ":foo must be thrown", :foo ) { throw :bar, 789 } # fails, => nil


464
465
466
# File 'lib/dfect.rb', line 464

def C message = nil, symbol = nil, &block
  assert_catch :assert, message, symbol, &block
end

.C!(message = nil, symbol = nil, &block) ⇒ Object

Asserts that the given symbol is not thrown when the given block is executed.

Returns nil, always.

Parameters

message

Optional message to show in the report if this assertion fails.

symbol

Symbol that must not be thrown by the given block.

Examples

# no message specified:

C!(:foo) { throw :foo, 123 } # fails,  => nil
C!(:foo) { throw :bar, 456 } # passes, => nil
C!(:foo) { }                 # passes, => nil

# message specified:

C!( ":foo must be thrown", :foo ) { throw :bar, 789 } # passes, => nil


495
496
497
# File 'lib/dfect.rb', line 495

def C! message = nil, symbol = nil, &block
  assert_catch :negate, message, symbol, &block
end

.C?(message = nil, symbol = nil, &block) ⇒ Boolean

Returns true if the given symbol is thrown when the given block is executed. Otherwise, returns false.

Parameters

message

This parameter is optional and completely ignored.

symbol

Symbol that must be thrown by the given block.

Examples

# no message specified:

C?(:foo) { throw :foo, 123 } # => true
C?(:foo) { throw :bar, 456 } # => false
C?(:foo) { }                 # => false

# message specified:

C?( ":foo must be thrown", :foo ) { throw :bar, 789 } # => false

Returns:

  • (Boolean)


523
524
525
# File 'lib/dfect.rb', line 523

def C? message = nil, symbol = nil, &block
  assert_catch :sample, message, symbol, &block
end

.D(description = caller.first, &block) ⇒ Object

Defines a new test, composed of the given description and the given block to execute.

A test may contain nested tests.

Parameters

description

A short summary of the test being defined.

Examples

D "a new array" do
  D .< { @array = [] }

  D "must be empty" do
    T { @array.empty? }
  end

  D "when populated" do
    D .< { @array.push 55 }

    D "must not be empty" do
      F { @array.empty? }
    end
  end
end

Raises:

  • (ArgumentError)


127
128
129
130
# File 'lib/dfect.rb', line 127

def D description = caller.first, &block
  raise ArgumentError, 'block must be given' unless block
  @curr_suite.tests << Suite::Test.new(description.to_s, block)
end

.E(message = nil, *kinds, &block) ⇒ Object

Asserts that one of the given kinds of exceptions is raised when the given block is executed.

If the block raises an exception, then that exception is returned.

Otherwise, nil is returned.

Parameters

message

Optional message to show in the report if this assertion fails.

kinds

Exception classes that must be raised by the given block.

If none are given, then StandardError is assumed (similar to how a plain ‘rescue’ statement without any arguments catches StandardError).

Examples

# no exceptions specified:

E { }       # fails
E { raise } # passes

# single exception specified:

E( ArgumentError ) { raise ArgumentError }
E( "argument must be invalid", ArgumentError ) { raise ArgumentError }

# multiple exceptions specified:

E( SyntaxError, NameError ) { eval "..." }
E( "string must compile", SyntaxError, NameError ) { eval "..." }


352
353
354
# File 'lib/dfect.rb', line 352

def E message = nil, *kinds, &block
  assert_raise :assert, message, *kinds, &block
end

.E!(message = nil, *kinds, &block) ⇒ Object

Asserts that one of the given kinds of exceptions is not raised when the given block is executed.

If the block raises an exception, then that exception is returned.

Otherwise, nil is returned.

Parameters

message

Optional message to show in the report if this assertion fails.

kinds

Exception classes that must not be raised by the given block.

If none are given, then StandardError is assumed (similar to how a plain ‘rescue’ statement without any arguments catches StandardError).

Examples

# no exceptions specified:

E! { }       # passes
E! { raise } # fails

# single exception specified:

E!( ArgumentError ) { raise ArgumentError } # fails
E!( "argument must be invalid", ArgumentError ) { raise ArgumentError }

# multiple exceptions specified:

E!( SyntaxError, NameError ) { eval "..." }
E!( "string must compile", SyntaxError, NameError ) { eval "..." }


394
395
396
# File 'lib/dfect.rb', line 394

def E! message = nil, *kinds, &block
  assert_raise :negate, message, *kinds, &block
end

.E?(message = nil, *kinds, &block) ⇒ Boolean

Returns true if one of the given kinds of exceptions is raised when the given block is executed. Otherwise, returns false.

Parameters

message

This parameter is optional and completely ignored.

kinds

Exception classes that must be raised by the given block.

If none are given, then StandardError is assumed (similar to how a plain ‘rescue’ statement without any arguments catches StandardError).

Examples

# no exceptions specified:

E? { }       # => false
E? { raise } # => true

# single exception specified:

E?( ArgumentError ) { raise ArgumentError } # => true

# multiple exceptions specified:

E?( SyntaxError, NameError ) { eval "..." } # => true

Returns:

  • (Boolean)


429
430
431
# File 'lib/dfect.rb', line 429

def E? message = nil, *kinds, &block
  assert_raise :sample, message, *kinds, &block
end

.F?(message = nil, &block) ⇒ Boolean

Returns true if the result of the given block is either nil or false. Otherwise, returns false.

Parameters

message

This parameter is optional and completely ignored.

Examples

# no message specified:

F? { true }  # => false
F? { false } # => true
F? { nil }   # => true

# message specified:

F?( "computers do not doublethink" ) { 2 + 2 == 5 } # => true

Returns:

  • (Boolean)


309
310
311
# File 'lib/dfect.rb', line 309

def F? message = nil, &block
  not T? message, &block
end

.run(continue = true) ⇒ Object

Executes all tests defined thus far and stores the results in #report.

Parameters

continue

If true, results from previous executions will not be cleared.



535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'lib/dfect.rb', line 535

def run continue = true
  # clear previous results
  unless continue
    @exec_stats.clear
    @exec_trace.clear
    @test_stack.clear
  end

  # make new results
  catch(:stop_dfect_execution) { execute }

  # print new results
  puts @report.to_yaml unless @options[:quiet]
end

.stopObject

Stops the execution of the #run method or raises an exception if that method is not currently executing.



554
555
556
# File 'lib/dfect.rb', line 554

def stop
  throw :stop_dfect_execution
end

.T(message = nil, &block) ⇒ Object Also known as: F!

Asserts that the result of the given block is neither nil nor false and returns that result.

Parameters

message

Optional message to show in the report if this assertion fails.

Examples

# no message specified:

T { true }  # passes
T { false } # fails
T { nil }   # fails

# message specified:

T( "computers do not doublethink" ) { 2 + 2 != 5 } # passes


229
230
231
# File 'lib/dfect.rb', line 229

def T message = nil, &block
  assert_yield :assert, message, &block
end

.T!(message = nil, &block) ⇒ Object Also known as: F

Asserts that the result of the given block is either nil or false and returns that result.

Parameters

message

Optional message to show in the report if this assertion fails.

Examples

# no message specified:

T! { true }  # fails
T! { false } # passes
T! { nil }   # passes

# message specified:

T!( "computers do not doublethink" ) { 2 + 2 == 5 } # passes


255
256
257
# File 'lib/dfect.rb', line 255

def T! message = nil, &block
  assert_yield :negate, message, &block
end

.T?(message = nil, &block) ⇒ Boolean

Returns true if the result of the given block is neither nil nor false. Otherwise, returns false.

Parameters

message

This parameter is optional and completely ignored.

Examples

# no message specified:

T? { true }  # => true
T? { false } # => false
T? { nil }   # => false

# message specified:

T?( "computers do not doublethink" ) { 2 + 2 != 5 } # => true

Returns:

  • (Boolean)


280
281
282
# File 'lib/dfect.rb', line 280

def T? message = nil, &block
  assert_yield :sample, message, &block
end