App-Test-Generator
view release on metacpan or search on metacpan
t/Analyzer-Complexity.t view on Meta::CPAN
# ==================================================================
# analyze -- tolerates missing body key
# --------------------------------------------------
# analyze must not die when body key is absent or undef
# ==================================================================
subtest 'analyze: tolerates missing body key' => sub {
my $analyser = App::Test::Generator::Analyzer::Complexity->new();
# No body key at all -- defaults to empty string
lives_ok { $analyser->analyze({}) }
'analyze lives when body key absent';
my $report = $analyser->analyze({});
is($report->{cyclomatic_score}, $CYCLOMATIC_BASE,
'absent body gives base score');
is($report->{complexity_level}, $LEVEL_LOW,
'absent body is low complexity');
# Explicit undef body -- also defaults to empty string
lives_ok { $analyser->analyze({ body => undef }) }
'analyze lives when body is undef';
$report = $analyser->analyze({ body => undef });
is($report->{cyclomatic_score}, $CYCLOMATIC_BASE,
'undef body gives base score');
done_testing();
};
# ==================================================================
# analyze -- branch keywords are whole-word matched
# --------------------------------------------------
# Keywords embedded in identifiers must not trigger
# a branching point count
# ==================================================================
subtest 'analyze: branching keywords are whole-word matched' => sub {
# 'iform' contains 'for' but should not count as a for loop
my $report = _analyze_body('my $uniform = 1;');
is($report->{branching_points}, 0,
'"uniform" does not trigger for branching point');
# 'notify' contains 'if' (as substring) but not as a word
$report = _analyze_body('my $notify = 1;');
is($report->{branching_points}, 0,
'"notify" does not trigger if branching point');
# 'foreacher' is not a keyword
$report = _analyze_body('my $foreacher = 1;');
is($report->{branching_points}, 0,
'"foreacher" does not trigger foreach branching point');
done_testing();
};
# ==================================================================
# analyze -- ? and other operators inside strings/comments
# must NOT inflate the cyclomatic score
# --------------------------------------------------
# Regression: the logical-operator count previously matched
# &&/||/? against the raw source body, so a literal "?" inside a
# string message (e.g. a prompt like "Are you sure?") or a
# keyword inside a comment was miscounted as a real decision point.
# ==================================================================
subtest 'analyze: ?/keywords inside strings or comments do not inflate score' => sub {
# A bare string containing "?" but no real ternary operator
my $report = _analyze_body('sub confirm { return "Are you sure?"; }');
is($report->{cyclomatic_score}, $CYCLOMATIC_BASE,
'"?" inside a string literal does not add to cyclomatic_score');
# "if"/"die" appear only inside a comment, not as real code
$report = _analyze_body(
"sub get { # die if this fails, but it never does\n\treturn 1;\n}"
);
is($report->{branching_points}, 0, '"if" inside a comment does not count as a branching point');
is($report->{exception_paths}, 0, '"die" inside a comment does not count as an exception path');
# A real ternary alongside a string containing "?" -- both must
# be counted correctly: the real ternary detected, the string
# content ignored
$report = _analyze_body(
q{sub ask { my $x = $a ? "Are you sure?" : "No way?"; return $x; }}
);
is($report->{cyclomatic_score}, $CYCLOMATIC_BASE + 1,
'real ternary is still counted once despite "?" inside the surrounding strings');
done_testing();
};
# ==================================================================
# analyze -- exception keywords are whole-word matched
# ==================================================================
subtest 'analyze: exception keywords are whole-word matched' => sub {
# 'evaluate' contains 'eval' but should not count
my $report = _analyze_body('my $evaluate = 1;');
is($report->{exception_paths}, 0,
'"evaluate" does not trigger eval exception path');
# 'croaky' contains 'croak' but should not count
$report = _analyze_body('my $croaky = 1;');
is($report->{exception_paths}, 0,
'"croaky" does not trigger croak exception path');
done_testing();
};
done_testing();
( run in 1.613 second using v1.01-cache-2.11-cpan-6aa56a78535 )