NAME
    Method::Workflow::SPEC - RSPEC keywords + workflow

DESCRIPTION
    This module is an implementation of RSPEC on top of Method::Workflow.
    This provides the basic keywords to create an RSPEC workflow.

EARLY VERSION WARNING
    This is an early version, better tests are needed. Most documented
    features should work fine though.

SYNOPSYS
    From the acceptance test:

        #!/usr/bin/perl
        use strict;
        use warnings;
        use Test::More;
        use Method::Workflow::SPEC;

        #################
        # Define the workflow

        start_class_workflow;
        our @RUN_ORDER;

        describe aa {
            push @RUN_ORDER => "Describe";

            before_all cc { push @RUN_ORDER => "Before All" }
            before_each bb { push @RUN_ORDER => "Before Each" }

            it dd {
                push @RUN_ORDER => "It";
            }

            after_each ff { push @RUN_ORDER => "After Each" }
            after_all ee { push @RUN_ORDER => "After All" }

            describe aa {
                push @RUN_ORDER => "Describe Nested";

                before_all cc { push @RUN_ORDER => "Before All Nested" }
                before_each bb { push @RUN_ORDER => "Before Each Nested" }

                it dd {
                    push @RUN_ORDER => "It Nested";
                }

                after_each ff { push @RUN_ORDER => "After Each Nested" }
                after_all ee { push @RUN_ORDER => "After All Nested" }
            }
        }

        end_class_workflow;

        ##################
        # Run the workflow
        run_workflow;

        ##################
        # Verify the results

        is_deeply(
            \@RUN_ORDER,
            [
                # Generators
                "Describe",
                "Describe Nested",

                # Root before all
                "Before All",

                # It and each
                "Before Each",
                "It",
                "After Each",

                # Nested
                    "Before All Nested",

                "Before Each",
                    "Before Each Nested",

                        "It Nested",

                    "After Each Nested",
                "After Each",

                    "After All Nested",

                # Root after all
                "After All",
            ],
            "Order is correct"
        );

        done_testing;

KEYWORDS
    All keywords take a name and codeblock. Name is not currently optional,
    this may change.

    describe NAME { ... }
        Create a root SPEC workflow element. These are run first to generate
        the tasks that will be run. These may be nested.

    it NAME { ... }
        Create a task node, these are the blocks that should produce results
        or accomplish work. These may not be nested, but there can be
        multiple within the same describe block.

    before_each NAME { ... }
        Create a setup block that should be run once for each 'it' block
        prior to the run of that 'it' block.

    after_each NAME { ... }
        Create a setup block that should be run once before any 'it' block
        is run.

    before_all NAME { ... }
        Create a teardown block that should be run once for each 'it' block
        after the run of that 'it' block.

    after_all NAME { ... }
        Create a teardown block that should be run once before any 'it'
        block is run.

USE IN TESTING
    Works as expected, use Test::More. Checks can be placed in any block.

  ENCAPSULATING ERRORS
    Use the 'error_handler' keyword (see Method::Workflow::Base the exports
    section) to create a handler that lets your tests continue if an
    exception is thrown from any block.

        #!/usr/bin/perl
        use strict;
        use warnings;
        use Test::More;
        use Method::Workflow::SPEC;

        start_class_workflow;

        my @errors;
        error_handler( sub { @errors = @_ });

        describe aa { it xxx { die "Error!" }}
        describe bb { ok( 1, "I still run!" )}

        end_class_workflow;
        run_workflow;

        my ( $item, $root, $error ) = @errors;
        like( $error, qr/Error! at/, "Workflow element error caught" );

        done_testing;

  ORDERING TASKS
    You can specify an order at the class level and/or the block level. The
    ordering will carry-down to nested elements until a new order is
    specified.

    There are 3 orderng options:

    ordered
      The default, run in the order they were defined.

    sorted
      Sorts tasks by name, task name will be the name of the 'it' block
      unless tests are grouped togethr by at some level by a before/after
      all, or ordering change. When grouped the group will be a single task
      named after the describe block that defined the grouping.

    random
      Shuffles the items for a random run order.

   CLASS LEVEL
    Specify the ordering at use time:

        use Method::Workflow::SPEC ':random';
        use Method::Workflow::SPEC ':ordered';
        use Method::Workflow::SPEC ':sorted';

   ELEMENT LEVEL
    Specify in the parameters list '( ... )':

        describe random_describe ( random => 1 ) { ... }

        describe sorted_describe ( sorted => 1 ) { ... }

        describe ordered_describe ( ordered => 1 ) { ... }

FENNEC PROJECT
    This module is part of the Fennec project. See Fennec for more details.
    Fennec is a project to develop an extendable and powerful testing
    framework. Together the tools that make up the Fennec framework provide
    a potent testing environment.

    The tools provided by Fennec are also useful on their own. Sometimes a
    tool created for Fennec is useful outside the greator framework. Such
    tools are turned into their own projects. This is one such project.

    Fennec - The core framework
      The primary Fennec project that ties them all together.

AUTHORS
    Chad Granum exodist7@gmail.com

COPYRIGHT
    Copyright (C) 2010 Chad Granum

    Method-Workflow-SPEC is free software; Standard perl licence.

    Method-Workflow-SPEC is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for
    more details.

