### ----------------------------------------------------
### -- App::RaCoCo
### -- Licenses: Artistic-2.0
### -- Authors: Mikhail Khorkov
### -- File: t/12-report-data.rakutest
### ----------------------------------------------------
use Test;
use lib 'lib';
use lib 't/lib';
use App::Racoco::Report::DataPart;
use App::Racoco::Report::Data;
use App::Racoco::Paths;
use App::Racoco::X;
use TestResources;
use TestHelper;

plan 9;

my ($paths);
sub setup($lib?) {
	plan $*plan;
	if $lib {
		TestResources::prepare($*subtest);
		$paths = Paths.from(lib => TestResources::exam-directory.add($lib));
	} else {
		$paths = Nil;
	}
}

'01-read-from-file'.&test(:6plan, {
	setup('lib');
	my ($data, $part);
	lives-ok { $data = Data.read(:$paths) }, 'read from file';
	ok $data, 'read defined';
	$part = $data.for(file-name => 'ModuleName1.rakumod');
	is $part, 'ModuleName1.rakumod | 37.5% | 1 0 2 3 3 1 5 0 6 0 7 0 8 0 | 4 1', 'part 1';
	$part = $data.for(file-name => 'ModuleName2.rakumod');
	is $part, 'ModuleName2.rakumod | 28.5% | 1 0 2 3 3 1 5 0 6 0 7 0 8 0', 'part 2';
	$part = $data.for(file-name => 'ModuleName3.rakumod');
	is $part, 'ModuleName3.rakumod | 0% | 1 0 2 0 3 0', 'part 3';
	nok $data.for(file-name => 'NotExists'), 'not exists';
});

'02-read-not-exist'.&test(:1plan, {
	setup('lib');
	throws-like { Data.read(:$paths) }, CannotReadReport,
		'read from not existed file', message => / {$paths.lib} /;
});

'03-read-bad-header'.&test(:3plan, {
	setup('lib');
	my ($data);
	lives-ok { $data = Data.read(:$paths) }, 'read from file';
	ok $data, 'read defined';
	nok $data.for(file-name => 'ModuleName1.rakumod'), 'not exists';
});

'04-read-corrupt'.&test(:5plan, {
	setup('lib');
	my ($data);
	lives-ok { $data = Data.read(:$paths) }, 'read from file';
	ok $data, 'read defined';
	ok $data.for(file-name => 'ModuleName1.rakumod'), 'part 1 read';
	ok $data.for(file-name => 'ModuleName2.r'), 'part 2 read';
	nok $data.for(file-name => ''), 'part 3 not read';
});

'05-get-all-parts'.&test(:4plan, {
	setup('lib');
	my $parts := Data.read(:$paths).get-all-parts;
	ok $parts ~~ Positional, 'all parts are Positional';
	is $parts.elems, 2, 'read only two from corrupt';
	is $parts[0], 'ModuleName1.rakumod | 37.5% | 1 0 2 3 3 1 5 0 6 0 7 0 8 0 | 4 1';
	is $parts[1], 'ModuleName2.r | 100%';
});

'06-write-to-file'.&test(:2plan, {
	setup('lib');
	lives-ok { Data.read(:$paths).write(:$paths) }, 'write';
	is $paths.report-data-path.slurp,
		$paths.report-data-path.parent.add('expected.txt').slurp, 'good write';
});

'07-construct'.&test(:2plan, {
	setup('lib');
	my %coverable =
		'ModuleName1.rakumod', set(1, 2, 3, 5, 6, 7, 8),
		'ModuleName2.r', set(),
		'ModuleName3.rakumod', set(1, 2);
	my %covered =
		'ModuleName1.rakumod', bag(2, 2, 2, 3, 4),
		'ModuleName2.r', bag();
	my ($data);
	lives-ok { $data = Data.new(:%coverable, :%covered) }, 'construct';
	$data.write(:$paths);
	is $paths.report-data-path.slurp,
		$paths.report-data-path.parent.add('expected.txt').slurp, 'good write';
});

'08-percent'.&test(:1plan, {
	setup('lib');
	is Data.read(:$paths).percent, 27.7, 'percent';
});

'09-plus'.&test(:3plan, {
	setup('lib');
	my $data1 = Data.new(
		coverable => ('A1', set(1, 2, 3), 'A2', set(1, 2, 3)).Map,
		covered => ('A1', bag(1, 2, 3), 'A2', bag(1, 2, 3)).Map
	);
	my $data2 = Data.new(
		coverable => ('A3', set(1, 2, 3), 'A2', set(2, 3, 4)).Map,
		covered => ('A3', bag(1, 2, 3), 'A2', bag(2, 3, 4)).Map
	);
	Data.new(
		coverable => ('A1', set(1, 2, 3), 'A2', set(1, 2, 3, 4), 'A3', set(1, 2, 3)).Map,
		covered => ('A1', bag(1, 2, 3), 'A2', bag(1, 2, 2, 3, 3, 4), 'A3', bag(1, 2, 3)).Map
	).write(:$paths);
	my $expected = $paths.report-data-path.slurp;
	$paths.report-data-path.unlink;
	Data.plus($data1, $data2).write(:$paths);
	is $paths.report-data-path.slurp, $expected, 'report data plus works';

	is Data.plus($data1, Nil), $data1, 'data plus nil';
	is Data.plus(Nil, $data1), $data1, 'nil plu data';
});


