5

I am trying to create a test file that inputs template values into a string using the template toolkit but I don't know what check/tests to include to make sure the template toolkit is processing the string correctly. Here is my code:

#!/usr/bin/env perl

use lib ('./t/lib/');

use strict;
use warnings;

use Template;

use Test::More tests => 1;



# options/configuration for template
 my $config = {
     #PRE_PROCESS => 1, # means the templates processed can use the same global vars defined earlier
     #INTERPOLATE => 1,
     #EVAL_PERL => 1,
     RELATIVE => 1,
     OUTPUT_PATH => './out',

 };

my $template = Template->new($config);

# input string
my $text = "This is string number [%num%] ."; 

# template placeholder variables
my $vars = {
     num => "one",
 };


# processes imput string and inserts placeholder values 
my $create_temp = $template->process(\$text, $vars)
    || die "Template process failed: ", $template->error(), "\n";


#is(($template->process(\$text, $vars)), '1' , 'The template is processing correctly');

# If process method is executed successfully it should have a return value of 1
diag($template->process(\$text, $vars));

The diag function returns a value of 1, which from the documentation means that the string has been processed sucessfully, but I have been trying check what the stdout is so I can see the output string but I can get it to print. I have tried writing the stdout to a file from the terminal command but nothing appears in the file. I can write the stderr to a file though. I have also been trying different configuration for the template as seen in the code below. Is it not working because I am not running any tests, or am I using the Template Toolkit in the wrong way?

If there is any other required information to needed to answer this question just comment below.

Paul Russell
  • 179
  • 10
  • 1
    You're describing the problem a bit over-complicated I think. While it's good to give background, the real problem gets lost. I think you're asking how to check if Template creates the right output, so that's what I answered. Basically you want to test if your templates work? – simbabque Apr 15 '16 at 14:34
  • 1
    Yes. haha. Sorry. I was trying to be detailed – Paul Russell Apr 15 '16 at 14:52

2 Answers2

4

This answer assumes that the $template->process statement is really in your production code, and not in the unit test, and shows how to do it if you cannot just tell it to redirect the output into a variable, like Dave shows in his answer.

You can use Test::Output to check STDOUT.

use Test::Output;

stdout_is { $template->process( \$text, $vars ) } q{This is string number one .},
    q{Template generates the correct output};

An alternative could be Capture::Tiny and a two-step test.

use Capture::Tiny 'capture_stdout';

my $output = capture_stdout {
    ok $template->process( \$text, $vars ), q{Template processes successfully};
};
is $output, q{This is string number one .}, q{... and the output is correct};

Note that both solutions will eat the output, so it also doesn't mess with your terminal (it cannot mess with the TAP, as the Test::Harness only looks at STDOUT).

Community
  • 1
  • 1
simbabque
  • 53,749
  • 8
  • 73
  • 136
4

Your main problem here is that process() sends its output to STDOUT and you're not capturing it. So you're not seeing the expanded output anythere.

The process() method takes an optional third argument which can take all sorts of useful values. You probably want to pass it a reference to an empty scalar variable, which then gets filled with the expanded template.

$template->process(\$text, $vars, \$output);
is($output, $expected_output);

But it's worth noting that the TT distribution includes Template::Test, which you'll probably find very useful.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • I was not aware of Template::Test. Very useful. :) – simbabque Apr 15 '16 at 15:00
  • And I had forgotten about it. But I was sure that something like that **must** exist :-) – Dave Cross Apr 15 '16 at 15:01
  • Now I'm thinking how we can use it at $work to get more kind-of frontend coverage. Yay. :) Also added a disclaimer to my answer to make it a bit more different from yours. – simbabque Apr 15 '16 at 15:02
  • The [docs](https://metacpan.org/pod/Template::Test#HISTORY) for Template::Test say that it became mostly redundant with the advent of Test::More. Personally, I don't like how you have to embed the tests for `test_expect()` in a specially-formatted file or `__DATA__` block. – ThisSuitIsBlackNot Apr 15 '16 at 15:30