### ----------------------------------------------------
### -- Text::CodeProcessing
### -- Licenses: Artistic-2.0
### -- Authors: Anton Antonov
### -- File: t/02-string-code-chunks-processing-markdown.rakutest
### ----------------------------------------------------
use Test;

use lib './lib';
use lib '.';

use Text::CodeProcessing;
use Text::CodeProcessing::REPLSandbox;

plan 13;

#============================================================
# 1 markdown - Simple
#============================================================
my Str $code = q:to/INIT/;
```{raku}
my $answer = 42;
```
INIT

my Str $resCode = q:to/INIT/;
```{raku}
my $answer = 42;
```
```
#OUT:42
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'my $answer = 42;';


#============================================================
# 2 markdown - eval=TRUE
#============================================================
$code = q:to/INIT/;
```{raku, eval=TRUE}
my $answer = 42;
```
INIT

$resCode = q:to/INIT/;
```{raku, eval=TRUE}
my $answer = 42;
```
```
#OUT:42
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'eval=TRUE: my $answer = 42;';


#============================================================
# 3 markdown - eval=FALSE
#============================================================
$code = q:to/INIT/;
```{raku, eval=FALSE}
my $answer = 42;
```
INIT

$resCode = q:to/INIT/;
```{raku, eval=FALSE}
my $answer = 42;
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'eval=FALSE: my $answer = 42;';


#============================================================
# 4 markdown - no {}
#============================================================
$code = q:to/INIT/;
```raku
my $answer = 42;
```
INIT

$resCode = q:to/INIT/;
```raku
my $answer = 42;
```
```
#OUT:42
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'eval=FALSE: my $answer = 42;';


#============================================================
# 5 markdown - multi-line (my)
#============================================================
$code = q:to/INIT/;
```raku
my $ans = "43\n333\n32";
```
INIT

$resCode = q:to/INIT/;
```raku
my $ans = "43\n333\n32";
```
```
#OUT:43
#OUT:333
#OUT:32
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'my $ans = "43\n333\n32";';


#============================================================
# 6 markdown - multi-line (say)
#============================================================
$code = q:to/INIT/;
```raku
say "43\n333\n32";
```
INIT

$resCode = q:to/INIT/;
```raku
say "43\n333\n32";
```
```
#OUT:43
#OUT:333
#OUT:32
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'say "43\n333\n32";';


#============================================================
# 7 markdown - multi-line (say) one prompt
#============================================================
$code = q:to/INIT/;
```raku
say "43\n333\n32";
```
INIT

$resCode = q:to/INIT/;
```raku
say "43\n333\n32";
```
```
#OUT:43
333
32
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:', :!promptPerLine),
        $resCode,
        ':!promptPerLine; say "43\n333\n32";';


#============================================================
# 8 markdown - State
#============================================================
$code = q:to/INIT/;
```{raku}
my $answer = 42;
```
```{raku}
$answer ** 2
```
INIT

$resCode = q:to/INIT/;
```{raku}
my $answer = 42;
```
```
#OUT:42
```
```{raku}
$answer ** 2
```
```
#OUT:1764
```
INIT

is
        StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode,
        'my $answer = 42; $answer ** 2';


#============================================================
# 9 markdown - State incomplete code
#============================================================
$code = q:to/INIT/;
```{raku}
my $answer = 42 *
```
```{raku}
$answer ** 2
```
INIT

$resCode = q:to/INIT/;
```{raku}
my $answer = 42 *
```
```
#ERR:Missing required term after infix
#OUT:Nil
```
```{raku}
$answer ** 2
```
```
#ERR:Variable '$answer' is not declared
#OUT:Nil
```
INIT

## This regex "replaces" the $resCode above.
## The regex is needed in order to address past and new messages issued
## for an undeclared variable. See:
## https://github.com/antononcube/Raku-Text-CodeProcessing/issues/2
my $resCodeRegex =
/ '```' '{raku}' \s*
'my $answer = 42 *' \s*
'```' \s+
'```' \s*
'#ERR:Missing required term after infix' \s*
'#OUT:Nil' \s*
'```' \s*
'```' '{raku}' \s* \n
'$answer ** 2' \s* \n
'```' \s*
'```' \s*
'#ERR:Variable \'$answer\' is not declared' .* .\s*
'#OUT:Nil' \s*
'```' /;

my $resCodeUpdate = $resCode.subst('Variable \'$answer\' is not declared',
        'Variable \'$answer\' is not declared. Perhaps you forgot a \'sub\' if this was intended to be part of a signature?');

my $resRun = StringCodeChunksEvaluation($code, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:');

like $resRun,
        $resCodeRegex,
        'my $answer = 42 *; $answer ** 2';


#============================================================
# 10 markdown - Other language chunk
#============================================================

my Str $code10 = q:to/INIT/;
Here we translate into Julia the data wrangling workflow:
```raku, outputLang=json
say '{ "a" : 12 }';
```
INIT

my Str $resCode10 = q:to/INIT/;
Here we translate into Julia the data wrangling workflow:
```raku, outputLang=json
say '{ "a" : 12 }';
```
```json
{ "a" : 12 }
```
INIT

is
        StringCodeChunksEvaluation($code10, 'markdown', evalOutputPrompt => '', evalErrorPrompt => '#ERR:'),
        $resCode10,
        'JSON output chunk';


#============================================================
# 11 markdown - Other language chunk 2
#============================================================

my Str $code11 = q:to/INIT/;
Here we translate into Julia the data wrangling workflow:
```raku, outputLang={json}
say '{ "a" : 12 }';
```
INIT

my Str $resCode11 = q:to/INIT/;
Here we translate into Julia the data wrangling workflow:
```raku, outputLang={json}
say '{ "a" : 12 }';
```
```{json}
{ "a" : 12 }
```
INIT

is
        StringCodeChunksEvaluation($code11, 'markdown', evalOutputPrompt => '', evalErrorPrompt => '#ERR:'),
        $resCode11,
        'JSON output chunk with {}';


#============================================================
# 12 markdown - Other language chunk 3
#============================================================

my Str $code12 = q:to/INIT/;
Here we translate into Julia the data wrangling workflow:
```{raku, outputLang={json}}
say '{ "a" : 12 }';
```
INIT

my Str $resCode12 = q:to/INIT/;
Here we translate into Julia the data wrangling workflow:
```{raku, outputLang={json}}
say '{ "a" : 12 }';
```
```{json}
{ "a" : 12 }
```
INIT

is
        StringCodeChunksEvaluation($code12, 'markdown', evalOutputPrompt => '', evalErrorPrompt => '#ERR:'),
        $resCode12,
        'JSON output chunk with {{}}';


#============================================================
# 13 markdown - State
#============================================================
# Testing the fix / feature of
# https://github.com/antononcube/Raku-Text-CodeProcessing/issues/4
my $code13 = q:to/INIT/;
~~~~raku
my $answer = 42;
$answer ** 2
~~~~
INIT

my $resCode13 = q:to/INIT/;
~~~~raku
my $answer = 42;
$answer ** 2
~~~~
```
#OUT:1764
```
INIT

is
        StringCodeChunksEvaluation($code13, 'markdown', evalOutputPrompt => '#OUT:', evalErrorPrompt => '#ERR:'),
        $resCode13,
        'my $answer = 42; $answer ** 2 qith `~~~~`';


done-testing;


