# module Spec

##
Overview

Crystal's built-in testing library. It provides a structure for writing executable examples of how your code should behave. A domain specific language allows you to write them in a way similar to natural language.

The Crystal compiler has a `spec` command with tools to constrain which examples get run and tailor the output.

A basic spec looks something like this:

    require "spec"

    describe Array do
      describe "#size" do
        it "correctly reports the number of elements in the Array" do
          [1, 2, 3].size.should eq 3
        end
      end

      describe "#empty?" do
        it "is empty when no elements are in the array" do
          ([] of Int32).empty?.should be_true
        end

        it "is not empty if there are elements in the array" do
          [1].empty?.should be_false
        end
      end

      # lots more specs
    end

Test files are structured by use of the `describe` or `context` methods. Typically a top level `describe` defines the `outer` unit (such as a class) that is to be tested by the spec. Further `describe` calls can be nested within the outer unit to specify smaller units under test (such as individual methods). `describe` can also be used to set up a certain context - think empty `Array` versus `Array` with elements. The `context` method behaves just like the `describe` method and may be used instead, to emphasize context to the reader.

Within a `describe` block, concrete test cases are defined with `it` . A descriptive string is supplied to `it` describing what the test case tests specifically.

Specs then use the `should` method to verify that the expected value is returned. See the example above for details.

By convention, specs live in the `spec` directory of a project. You can compile and run the specs of a project by running `crystal spec`.

    # Run all specs in files matching spec/**/*_spec.cr
    crystal spec

    # Run all specs in files matching spec/my/test/**/*_spec.cr
    crystal spec spec/my/test/

    # Run all specs in spec/my/test/file_spec.cr
    crystal spec spec/my/test/file_spec.cr

    # Run the spec or group defined in line 14 of spec/my/test/file_spec.cr
    crystal spec spec/my/test/file_spec.cr:14

    # Run all specs tagged with "fast"
    crystal spec --tag 'fast'

    # Run all specs not tagged with "slow"
    crystal spec --tag '~slow'

##
Focusing on a group of specs

A `describe`, `context` or `it` can be marked with `focus: true`, like this:

    it "adds", focus: true do
      (2 + 2).should_not eq(5)
    end

If any such thing is marked with `focus: true` then only those examples will run.

##
Randomizing order of specs

Specs, by default, run in the order defined, but can be run in a random order by passing `--order random` to `crystal spec`.

Specs run in random order will display a seed value upon completion. This seed value can be used to rerun the specs in that same order by passing the seed value to `--order`.

##
Defined in:

spec.cr
spec/cli.cr
spec/context.cr
spec/dsl.cr
spec/example.cr
spec/example/procsy.cr
spec/example_group/procsy.cr
spec/expectations.cr
spec/filters.cr
spec/formatter.cr
spec/item.cr
spec/junit_formatter.cr
spec/source.cr

##
Class Method Summary

- .add_formatter(formatter)

  DEPRECATED This is an internal API.

- .add_split_filter(filter)

  DEPRECATED This is an internal API.

- .after_each(&block)

  Instructs the spec runner to execute the given block after each spec in the spec suite.

- .after_suite(&block)

  Instructs the spec runner to execute the given block after the entire spec suite.

- .around_each(&block : Example::Procsy -> )

  Instructs the spec runner to execute the given block when each spec in the spec suite runs.

- .before_each(&block)

  Instructs the spec runner to execute the given block before each spec in the spec suite.

- .before_suite(&block)

  Instructs the spec runner to execute the given block before the entire spec suite.

- .finish_run

  DEPRECATED This is an internal API.

- .override_default_formatter(formatter)

  DEPRECATED This is an internal API.

- .randomizer : Random::PCG32 | Nil

  DEPRECATED This is an internal API.

##
Class Method Detail

def self.add_formatter(formatter) #

DEPRECATED This is an internal API.

def self.add_split_filter(filter) #

DEPRECATED This is an internal API.

def self.after_each(&block) #

Instructs the spec runner to execute the given block after each spec in the spec suite.

If multiple blocks are registered they run in the reversed order that they are given.

For example:

    Spec.after_each { puts 1 }
    Spec.after_each { puts 2 }

will print, just after each spec, 2 and then 1.

def self.after_suite(&block) #

Instructs the spec runner to execute the given block after the entire spec suite.

If multiple blocks are registered they run in the reversed order that they are given.

For example:

    Spec.after_suite { puts 1 }
    Spec.after_suite { puts 2 }

will print, just after the spec suite ends, 2 and then 1.

def self.around_each(&block : Example::Procsy -> ) #

Instructs the spec runner to execute the given block when each spec in the spec suite runs.

The block must call `run` on the given `Example::Procsy` object.

If multiple blocks are registered they run in the reversed order that they are given.

    require "spec"

    Spec.around_each do |example|
      puts "runs before each sample"
      example.run
      puts "runs after each sample"
    end

    it { }
    it { }

def self.before_each(&block) #

Instructs the spec runner to execute the given block before each spec in the spec suite.

If multiple blocks are registered they run in the order that they are given.

For example:

    Spec.before_each { puts 1 }
    Spec.before_each { puts 2 }

will print, just before each spec, 1 and then 2.

def self.before_suite(&block) #

Instructs the spec runner to execute the given block before the entire spec suite.

If multiple blocks are registered they run in the order that they are given.

For example:

    Spec.before_suite { puts 1 }
    Spec.before_suite { puts 2 }

will print, just before the spec suite starts, 1 and then 2.

def self.finish_run #

DEPRECATED This is an internal API.

def self.override_default_formatter(formatter) #

DEPRECATED This is an internal API.

def self.randomizer : Random::PCG32 | Nil #

DEPRECATED This is an internal API.