The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Module::TestConfig - Write a config module for your tests and/or module.

SYNOPSIS

  use Module::TestConfig;

  Module::TestConfig->new(
        verbose   => 1,
        defaults  => 'defaults.config',
        file      => 'MyConfig.pm',
        package   => 'MyConfig',
        order     => [ qw/defaults env/ ],
        questions => [
          [ 'Would you like tea?' => 'tea', 'y' ],
          [ 'Crumpets?' => 'crumpets', 'y' ],
        ]
  )->ask->save;

# and in another module or test file:

  use MyConfig;

  my $config = TestConfig->new;
  print $config->tea eq 'y'
    ? "We're having tea today; splendid!"
    : "No tea, I'm afraid. P'raps tomorrow.";

  print $config->crumpets eq 'y'
    ? "Crumpets; lovely!"
    : "Alas, we have no crumpets today";

DESCRIPTION

This module prompts a user for info and writes a module for later use. You can use it during the module build process (e.g. perl Makefile.PL) to share info among your test files. You can use it to write a module and install that into your site_perl tree.

Module::TestConfig writes an object-oriented file. You specify the file's location as well as the package name. When you use that file, all of the question names will behave as object methods.

e.g. If you asked the question:

  Module::TestConfig->new(
        file      => 't/MyConfig.pm',
        package   => 'MyConfig',
        questions => [
                       { name => 'fingers',
                         msg => 'How many fingers am I holding up?',
                         default => 11,
                       },
                     ],
  )->ask->save;

Then the file t/MyConfig.pm would be written. To use it, add this to another file:

  use MyConfig;

  my $config = MyConfig->new;
  print $config->fingers; # prints 11 or whatever number the user picked.

PUBLIC METHODS

new()

Args and defaults:

  verbose   => 1,
  defaults  => 'defaults.config',
  file      => 'MyConfig.pm',
  package   => 'MyConfig',
  order     => [ 'defaults' ],
  questions => [ ... ],

Returns a new Module::TestConfig object.

questions()

Set up the questions that we prompt the user for. They can be in one of two forms, the array form or the hash form. See Module::TestConfig::Question for more about the question's arguments.

Args:

questions:

A string like "Have you seen my eggplant?" or "Kittens:". They look best when they end with a ':' or a '?'.

name:

A simple mnemonic used for looking up values later. Since it will turn into a method name in the future, it ought to match /[\w_]+/.

default:

optional. a default answer.

options:

optional. A hashref with any or all of the following:

noecho:

optional. 1 or 0. Do we print the user's answer while they are typing? This is useful when asking for for passwords.

skip:

optional. Accepts either a coderef or a scalar. The Module::TestConfig will be passed to the coderef as its first and only argument. Use it to look up answer()s. If the coderef returns true or the scalar is true, the current question will be skipped.

validate:

optional. a Params::Validate::validate() hashref. See Params::Validate. The question will loop until the user types an answer that validates.

Args: an AoH. e.g. questions( [ { ... }, ... ] ) a LoH. e.g. questions( { ... }, ... )

e.g.

  [
    [ "Question to ask",  $name, $optional_default, \%optional_options ],
    ...
  ]

or

  [
    { question => "Question to ask",
      name => "foo",
      default => 0,
      opts => { ... }
    },
    ...
  ]

the $optional_options looks like:

  {
     noecho => 1,               # set to 1 for password-prompting
     skip => \&coderef | $scalar, # skip the current question if true
     validate => Params::Validate::hashref # question will loop until this passes
     ...
  }

Returns: a list of questions in list context an arrayref of questions in scalar context.

ask()

Asks the user the questions.

Returns: a Module::TestConfig object.

save()

Writes our answers to the file. The file created will always be 0600 for security reasons. This may change in the future. See "SECURITY" for more info.

defaults()

A file parsed by Config::Auto which may be used as default answers to the questions. See "order()"

Default: "defaults.config"

Args: A filename or path.

Returns: A filename or path.

file()

The filename that gets written during save().

Default: "MyConfig.pm"

Args: a filepath that should probably end in ".pm". e.g. "t/MyConfig.pm"

Returns: the filename or path.

package()

The file's package name written during save().

Default: "MyConfig"

Args: a package namespace. e.g. "Foo::Bar::Baz"

Returns: the set package.

order()

Default: [ 'defaults' ]

Args: ordered list of 'defaults' and/or 'env'.

Defaults to the questions can come from either a file, the environment, or some combination of both.

Args:

defaults:

a file read by Config::Auto that must parse to a hash of question names and values.

env:

environment variables in either upper or lowercase.

The following will also be checked, in order:

answers:

Any answers already hard-set via answers().

a question's default:

A default supplied with the question.

There's a security risk when accepting defaults from the environment. See "SECURITY"

answer()

Get the current value of a question. This can be used with skip.

Args: a question's name.

Returns: The current value or undef.

verbose()

Should the module be chatty while running? Should it print a report at the end?

Default: 1

Args: 1 or 0

Returns: current value

debug()

Placeholder for future development - this method isn't used.

Default: 0

Args: 1 or 0

Returns: current value

PROTECTED METHODS

These are documented primarily for subclassing.

answers()

A user's questions get stored here. If you preset any answers beforehand, they may be used as defaults. See "order()" for those rules.

Args: a hash of question names and answers

Returns: A hash in list context, a hashref in scalar context.

prompt()

Ask the user a question. The answer will be cached in the object for later.

Args: $question, $default_answer, \%options

get_default()

Look through the options(), the answers(), and the question's default for a suitable default to print with the question.

load_defaults()

Uses Config::Auto to parse the file specified by defaults(). Defaults are stored in $obj->{_defaults}.

package_text()

Returns the new file's text. This should take package() and answers() into account.

qi()

The current question index.

Args: A number

Returns: The current number

report()

Returns a report of question names and values. Will be printed if the object is in verbose mode.

SECURITY

The resultant file (TestConfig.pm by default) will be chmod'd to 0600 but it will remain on the system.

Using the environment as input may also be a security risk - or a potential bug - especially if your names mimic existing environment variables.

AUTHOR

Joshua Keroes <jkeroes@eli.net>

COPYRIGHT AND LICENSE

Copyright 2003 by Joshua Keroes <jkeroes@eli.net>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

ExtUtils::MakeMaker Module::Build