App-vaporcalc

 view release on metacpan or  search on metacpan

bin/vaporcalc  view on Meta::CPAN

my $recipe = App::vaporcalc::Recipe->new(
  target_quantity   => 10,
  base_nic_per_ml   => 100,
  target_nic_per_ml => 12,
  target_pg         => 45,
  target_vg         => 55,
  flavor_percentage => 10,
);
my $initial_input = getopts->recipe ? 'recipe load '.getopts->recipe : undef;

my $orig_prompt = colorify green => 'vcalc> ';
my $prompt;
PROMPT: while (1) {
  $prompt //= $orig_prompt;

  my $input = $initial_input // $term->get_reply(
    prompt  => $prompt,
    default => 'calc'
  );
  undef $initial_input;

  next PROMPT unless $input;

  $term->addhistory($input);

  $input = 'show recipe' if $input eq 'calc';
  last PROMPT            if $input =~ /^(?:exit|quit)/i;

bin/vaporcalc  view on Meta::CPAN


  sswitch ($cmd_result->action) {
    case 'display': {
      $outfh->print( format_resultset( $cmd_result->resultset ) );
    }

    case 'print': {
      $outfh->say( colorify yellow => $cmd_result->string );
    }

    case 'prompt': {
      my $reply = $term->get_reply(prompt => $cmd_result->prompt);
      $cmd_result->run_prompt_callback($reply)
    }

    case 'recipe': { 
      $recipe = $cmd_result->recipe;
      $outfh->say( colorify yellow => $cmd_result->string )
        if $cmd_result->string;
    }

    case 'next': { next PROMPT }

lib/App/vaporcalc/Cmd/Result.pm  view on Meta::CPAN

use Moo;

has action => (
  lazy      => 1,
  is        => 'ro',
  isa       => CommandAction,
  builder   => sub {
    my ($self) = @_;
      $self->has_recipe    ? 'recipe'
    : $self->has_resultset ? 'display'
    : $self->has_prompt    ? 'prompt'
    :                        'print'
  },
);


has string => (
  lazy      => 1,
  is        => 'ro',
  isa       => Str,
  predicate => 1,
  builder   => sub { '' },
);


has prompt => (
  lazy      => 1,
  is        => 'ro',
  isa       => Str,
  predicate => 1,
  builder   => sub { '(undef)' },
);

has prompt_callback => (
  lazy      => 1,
  is        => 'ro',
  isa       => CodeRef,
  predicate => 1,
  builder   => sub { sub {} }
);

has prompt_default_ans => (
  lazy      => 1,
  is        => 'ro',
  isa       => Str,
  predicate => 1,
  builder   => sub { '' },
);

method run_prompt_callback (Str $answer = '') {
  chomp $answer;
  $self->prompt_callback->(
    local $_ = $answer || $self->prompt_default_ans || undef
  )
}


has recipe => (
  lazy      => 1,
  is        => 'ro',
  isa       => RecipeObject,
  coerce    => 1,
  predicate => 1,

lib/App/vaporcalc/Cmd/Result.pm  view on Meta::CPAN

An object representing the result of an L<App::vaporcalc::Role::UI::Cmd>
consumer's execution.

=head2 ATTRIBUTES

=head3 action

The action the controller should take; must be a
L<App::vaporcalc::Types/"CommandAction">.

=head3 prompt

The prompt to display when L</action> eq 'prompt'

=head3 prompt_callback

An optional callback that should be run with the answer given to L</prompt> (or
L</prompt_default_ans> if no answer is given).

See L</run_prompt_callback>.

=head3 prompt_default_ans

A default answer for use by L</run_prompt_callback> if none is given.

=head3 recipe

The L<App::vaporcalc::Recipe> to attach for L</action> eq 'recipe'

=head3 resultset

The L<App::vaporcalc::RecipeResultSet> to attach for L</action> eq 'display'

=head2 METHODS

=head3 run_prompt_callback

Runs L</prompt_callback> with C<$_> and C<$_[0]> set to either the given
argument or L</prompt_default_ans> if none given.

=head1 AUTHOR

Jon Portnoy <avenj@cobaltirc.org>

=cut

lib/App/vaporcalc/Types.pm  view on Meta::CPAN

  via { uc $_ };


declare CommandAction =>
  as Str(),
  where {
    $_ |M| [qw/
      display

      print
      prompt

      next
      last

      recipe
    /]
  };

1;

lib/App/vaporcalc/Types.pm  view on Meta::CPAN

=head3 VaporLiquid

A valid base liquid type (B<PG> or B<VG>).

Can be coerced from a lowercase string.

=head3 CommandAction

A valid C<vaporcalc> loop control action, one of:

  display print prompt next last recipe

=head1 AUTHOR

Jon Portnoy <avenj@cobaltirc.org>

=cut

t/lib/cmd/result.t  view on Meta::CPAN

use Test::Modern;


use App::vaporcalc::Cmd::Result;

my $res = App::vaporcalc::Cmd::Result->new;
cmp_ok $res->action, 'eq', 'print',
  'default action ok';
cmp_ok $res->string, 'eq', '',
  'default string ok';
cmp_ok $res->prompt, 'eq', '(undef)',
  'default prompt ok';
cmp_ok $res->prompt_default_ans, 'eq', '',
  'default prompt_default_ans ok';
ok !$res->prompt_callback->(),
  'default prompt_callback ok';
ok !$res->run_prompt_callback,
  'run_prompt_callback without prompt_callback ok';

$res = App::vaporcalc::Cmd::Result->new(
  action => 'next',
);
cmp_ok $res->action, 'eq', 'next',
  'action eq next ok';

$res = App::vaporcalc::Cmd::Result->new(
  action => 'last',
);
cmp_ok $res->action, 'eq', 'last',
  'action eq last ok';

# prompt, with cb and no default answer
my %t;
$res = App::vaporcalc::Cmd::Result->new(
  prompt => 'foo',
  prompt_callback => sub {
    my ($ans) = @_;
    $t{$ans}++;
    $t{$_}++;
  },
);
cmp_ok $res->prompt, 'eq', 'foo',
  'prompt ok';
cmp_ok $res->action, 'eq', 'prompt',
  'action eq prompt ok';
$res->run_prompt_callback("bar\n");
cmp_ok $t{bar}, '==', 2, 
  'run_prompt_callback ok';
%t = ();

# prompt, with cb and default answer
$res = App::vaporcalc::Cmd::Result->new(
  prompt => 'foo',
  prompt_default_ans => 'bar',
  prompt_callback => sub {
    my ($ans) = @_;
    $t{$ans}++;
    $t{$_}++;
  },
);
cmp_ok $res->prompt_default_ans, 'eq', 'bar',
  'prompt_default_ans ok';
$res->run_prompt_callback;
$res->run_prompt_callback("baz");
is_deeply \%t,
  +{ bar => 2, baz => 2 },
  'run_prompt_callback with prompt_default_ans ok';

# recipe attached
my $recipe = bless +{}, 'App::vaporcalc::Recipe';
$res = App::vaporcalc::Cmd::Result->new(
  recipe => $recipe,
);
ok $recipe == $res->recipe, 'recipe ok';
cmp_ok $res->action, 'eq', 'recipe',
  'action eq recipe ok';

t/lib/types.t  view on Meta::CPAN


# VaporLiquid
should_pass 'PG',  VaporLiquid;
should_pass 'VG',  VaporLiquid;
should_fail 'foo', VaporLiquid;
should_fail 1,     VaporLiquid;

# CommandAction
should_pass 'display', CommandAction;
should_pass 'print',   CommandAction;
should_pass 'prompt',  CommandAction;
should_pass 'next',    CommandAction;
should_pass 'last',    CommandAction;
should_pass 'recipe',  CommandAction;
should_fail 'foo',     CommandAction;
should_fail [],        CommandAction;

# Percentage
should_pass 100, Percentage;
should_pass 0,   Percentage;
should_pass 0.5, Percentage;



( run in 1.533 second using v1.01-cache-2.11-cpan-0b5f733616e )