src/metrics/loc.rs (3,119 lines of code) (raw):
use std::collections::HashSet;
use crate::checker::Checker;
use serde::Serialize;
use serde::ser::{SerializeStruct, Serializer};
use std::fmt;
use crate::macros::implement_metric_trait;
use crate::*;
/// The `SLoc` metric suite.
#[derive(Debug, Clone)]
pub struct Sloc {
start: usize,
end: usize,
unit: bool,
sloc_min: usize,
sloc_max: usize,
}
impl Default for Sloc {
fn default() -> Self {
Self {
start: 0,
end: 0,
unit: false,
sloc_min: usize::MAX,
sloc_max: 0,
}
}
}
impl Sloc {
#[inline(always)]
pub fn sloc(&self) -> f64 {
// This metric counts the number of lines in a file
// The if construct is needed to count the line of code that represents
// the function signature in a function space
let sloc = if self.unit {
self.end - self.start
} else {
(self.end - self.start) + 1
};
sloc as f64
}
/// The `Sloc` metric minimum value.
#[inline(always)]
pub fn sloc_min(&self) -> f64 {
self.sloc_min as f64
}
/// The `Sloc` metric maximum value.
#[inline(always)]
pub fn sloc_max(&self) -> f64 {
self.sloc_max as f64
}
#[inline(always)]
pub fn merge(&mut self, other: &Sloc) {
self.sloc_min = self.sloc_min.min(other.sloc() as usize);
self.sloc_max = self.sloc_max.max(other.sloc() as usize);
}
#[inline(always)]
pub(crate) fn compute_minmax(&mut self) {
if self.sloc_min == usize::MAX {
self.sloc_min = self.sloc_min.min(self.sloc() as usize);
self.sloc_max = self.sloc_max.max(self.sloc() as usize);
}
}
}
/// The `PLoc` metric suite.
#[derive(Debug, Clone)]
pub struct Ploc {
lines: HashSet<usize>,
ploc_min: usize,
ploc_max: usize,
}
impl Default for Ploc {
fn default() -> Self {
Self {
lines: HashSet::default(),
ploc_min: usize::MAX,
ploc_max: 0,
}
}
}
impl Ploc {
#[inline(always)]
pub fn ploc(&self) -> f64 {
// This metric counts the number of instruction lines in a code
// https://en.wikipedia.org/wiki/Source_lines_of_code
self.lines.len() as f64
}
/// The `Ploc` metric minimum value.
#[inline(always)]
pub fn ploc_min(&self) -> f64 {
self.ploc_min as f64
}
/// The `Ploc` metric maximum value.
#[inline(always)]
pub fn ploc_max(&self) -> f64 {
self.ploc_max as f64
}
#[inline(always)]
pub fn merge(&mut self, other: &Ploc) {
// Merge ploc lines
for l in other.lines.iter() {
self.lines.insert(*l);
}
self.ploc_min = self.ploc_min.min(other.ploc() as usize);
self.ploc_max = self.ploc_max.max(other.ploc() as usize);
}
#[inline(always)]
pub(crate) fn compute_minmax(&mut self) {
if self.ploc_min == usize::MAX {
self.ploc_min = self.ploc_min.min(self.ploc() as usize);
self.ploc_max = self.ploc_max.max(self.ploc() as usize);
}
}
}
/// The `CLoc` metric suite.
#[derive(Debug, Clone)]
pub struct Cloc {
only_comment_lines: usize,
code_comment_lines: usize,
comment_line_end: Option<usize>,
cloc_min: usize,
cloc_max: usize,
}
impl Default for Cloc {
fn default() -> Self {
Self {
only_comment_lines: 0,
code_comment_lines: 0,
comment_line_end: Option::default(),
cloc_min: usize::MAX,
cloc_max: 0,
}
}
}
impl Cloc {
#[inline(always)]
pub fn cloc(&self) -> f64 {
// Comments are counted regardless of their placement
// https://en.wikipedia.org/wiki/Source_lines_of_code
(self.only_comment_lines + self.code_comment_lines) as f64
}
/// The `Ploc` metric minimum value.
#[inline(always)]
pub fn cloc_min(&self) -> f64 {
self.cloc_min as f64
}
/// The `Ploc` metric maximum value.
#[inline(always)]
pub fn cloc_max(&self) -> f64 {
self.cloc_max as f64
}
#[inline(always)]
pub fn merge(&mut self, other: &Cloc) {
// Merge cloc lines
self.only_comment_lines += other.only_comment_lines;
self.code_comment_lines += other.code_comment_lines;
self.cloc_min = self.cloc_min.min(other.cloc() as usize);
self.cloc_max = self.cloc_max.max(other.cloc() as usize);
}
#[inline(always)]
pub(crate) fn compute_minmax(&mut self) {
if self.cloc_min == usize::MAX {
self.cloc_min = self.cloc_min.min(self.cloc() as usize);
self.cloc_max = self.cloc_max.max(self.cloc() as usize);
}
}
}
/// The `LLoc` metric suite.
#[derive(Debug, Clone)]
pub struct Lloc {
logical_lines: usize,
lloc_min: usize,
lloc_max: usize,
}
impl Default for Lloc {
fn default() -> Self {
Self {
logical_lines: 0,
lloc_min: usize::MAX,
lloc_max: 0,
}
}
}
impl Lloc {
#[inline(always)]
pub fn lloc(&self) -> f64 {
// This metric counts the number of statements in a code
// https://en.wikipedia.org/wiki/Source_lines_of_code
self.logical_lines as f64
}
/// The `Lloc` metric minimum value.
#[inline(always)]
pub fn lloc_min(&self) -> f64 {
self.lloc_min as f64
}
/// The `Lloc` metric maximum value.
#[inline(always)]
pub fn lloc_max(&self) -> f64 {
self.lloc_max as f64
}
#[inline(always)]
pub fn merge(&mut self, other: &Lloc) {
// Merge lloc lines
self.logical_lines += other.logical_lines;
self.lloc_min = self.lloc_min.min(other.lloc() as usize);
self.lloc_max = self.lloc_max.max(other.lloc() as usize);
}
#[inline(always)]
pub(crate) fn compute_minmax(&mut self) {
if self.lloc_min == usize::MAX {
self.lloc_min = self.lloc_min.min(self.lloc() as usize);
self.lloc_max = self.lloc_max.max(self.lloc() as usize);
}
}
}
/// The `Loc` metric suite.
#[derive(Debug, Clone)]
pub struct Stats {
sloc: Sloc,
ploc: Ploc,
cloc: Cloc,
lloc: Lloc,
space_count: usize,
blank_min: usize,
blank_max: usize,
}
impl Default for Stats {
fn default() -> Self {
Self {
sloc: Sloc::default(),
ploc: Ploc::default(),
cloc: Cloc::default(),
lloc: Lloc::default(),
space_count: 1,
blank_min: usize::MAX,
blank_max: 0,
}
}
}
impl Serialize for Stats {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut st = serializer.serialize_struct("loc", 20)?;
st.serialize_field("sloc", &self.sloc())?;
st.serialize_field("ploc", &self.ploc())?;
st.serialize_field("lloc", &self.lloc())?;
st.serialize_field("cloc", &self.cloc())?;
st.serialize_field("blank", &self.blank())?;
st.serialize_field("sloc_average", &self.sloc_average())?;
st.serialize_field("ploc_average", &self.ploc_average())?;
st.serialize_field("lloc_average", &self.lloc_average())?;
st.serialize_field("cloc_average", &self.cloc_average())?;
st.serialize_field("blank_average", &self.blank_average())?;
st.serialize_field("sloc_min", &self.sloc_min())?;
st.serialize_field("sloc_max", &self.sloc_max())?;
st.serialize_field("cloc_min", &self.cloc_min())?;
st.serialize_field("cloc_max", &self.cloc_max())?;
st.serialize_field("ploc_min", &self.ploc_min())?;
st.serialize_field("ploc_max", &self.ploc_max())?;
st.serialize_field("lloc_min", &self.lloc_min())?;
st.serialize_field("lloc_max", &self.lloc_max())?;
st.serialize_field("blank_min", &self.blank_min())?;
st.serialize_field("blank_max", &self.blank_max())?;
st.end()
}
}
impl fmt::Display for Stats {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"sloc: {}, ploc: {}, lloc: {}, cloc: {}, blank: {}, sloc_average: {}, ploc_average: {}, lloc_average: {}, cloc_average: {}, blank_average: {}, sloc_min: {}, sloc_max: {}, cloc_min: {}, cloc_max: {}, ploc_min: {}, ploc_max: {}, lloc_min: {}, lloc_max: {}, blank_min: {}, blank_max: {}",
self.sloc(),
self.ploc(),
self.lloc(),
self.cloc(),
self.blank(),
self.sloc_average(),
self.ploc_average(),
self.lloc_average(),
self.cloc_average(),
self.blank_average(),
self.sloc_min(),
self.sloc_max(),
self.cloc_min(),
self.cloc_max(),
self.ploc_min(),
self.ploc_max(),
self.lloc_min(),
self.lloc_max(),
self.blank_min(),
self.blank_max(),
)
}
}
impl Stats {
/// Merges a second `Loc` metric suite into the first one
pub fn merge(&mut self, other: &Stats) {
self.sloc.merge(&other.sloc);
self.ploc.merge(&other.ploc);
self.cloc.merge(&other.cloc);
self.lloc.merge(&other.lloc);
// Count spaces
self.space_count += other.space_count;
// min and max
self.blank_min = self.blank_min.min(other.blank() as usize);
self.blank_max = self.blank_max.max(other.blank() as usize);
}
/// The `Sloc` metric.
///
/// Counts the number of lines in a scope
#[inline(always)]
pub fn sloc(&self) -> f64 {
self.sloc.sloc()
}
/// The `Ploc` metric.
///
/// Counts the number of instruction lines in a scope
#[inline(always)]
pub fn ploc(&self) -> f64 {
self.ploc.ploc()
}
/// The `Lloc` metric.
///
/// Counts the number of statements in a scope
#[inline(always)]
pub fn lloc(&self) -> f64 {
self.lloc.lloc()
}
/// The `Cloc` metric.
///
/// Counts the number of comments in a scope
#[inline(always)]
pub fn cloc(&self) -> f64 {
self.cloc.cloc()
}
/// The `Blank` metric.
///
/// Counts the number of blank lines in a scope
#[inline(always)]
pub fn blank(&self) -> f64 {
self.sloc() - self.ploc() - self.cloc.only_comment_lines as f64
}
/// The `Sloc` metric average value.
///
/// This value is computed dividing the `Sloc` value for the number of spaces
#[inline(always)]
pub fn sloc_average(&self) -> f64 {
self.sloc() / self.space_count as f64
}
/// The `Ploc` metric average value.
///
/// This value is computed dividing the `Ploc` value for the number of spaces
#[inline(always)]
pub fn ploc_average(&self) -> f64 {
self.ploc() / self.space_count as f64
}
/// The `Lloc` metric average value.
///
/// This value is computed dividing the `Lloc` value for the number of spaces
#[inline(always)]
pub fn lloc_average(&self) -> f64 {
self.lloc() / self.space_count as f64
}
/// The `Cloc` metric average value.
///
/// This value is computed dividing the `Cloc` value for the number of spaces
#[inline(always)]
pub fn cloc_average(&self) -> f64 {
self.cloc() / self.space_count as f64
}
/// The `Blank` metric average value.
///
/// This value is computed dividing the `Blank` value for the number of spaces
#[inline(always)]
pub fn blank_average(&self) -> f64 {
self.blank() / self.space_count as f64
}
/// The `Sloc` metric minimum value.
#[inline(always)]
pub fn sloc_min(&self) -> f64 {
self.sloc.sloc_min()
}
/// The `Sloc` metric maximum value.
#[inline(always)]
pub fn sloc_max(&self) -> f64 {
self.sloc.sloc_max()
}
/// The `Cloc` metric minimum value.
#[inline(always)]
pub fn cloc_min(&self) -> f64 {
self.cloc.cloc_min()
}
/// The `Cloc` metric maximum value.
#[inline(always)]
pub fn cloc_max(&self) -> f64 {
self.cloc.cloc_max()
}
/// The `Ploc` metric minimum value.
#[inline(always)]
pub fn ploc_min(&self) -> f64 {
self.ploc.ploc_min()
}
/// The `Ploc` metric maximum value.
#[inline(always)]
pub fn ploc_max(&self) -> f64 {
self.ploc.ploc_max()
}
/// The `Lloc` metric minimum value.
#[inline(always)]
pub fn lloc_min(&self) -> f64 {
self.lloc.lloc_min()
}
/// The `Lloc` metric maximum value.
#[inline(always)]
pub fn lloc_max(&self) -> f64 {
self.lloc.lloc_max()
}
/// The `Blank` metric minimum value.
#[inline(always)]
pub fn blank_min(&self) -> f64 {
self.blank_min as f64
}
/// The `Blank` metric maximum value.
#[inline(always)]
pub fn blank_max(&self) -> f64 {
self.blank_max as f64
}
#[inline(always)]
pub(crate) fn compute_minmax(&mut self) {
self.sloc.compute_minmax();
self.ploc.compute_minmax();
self.cloc.compute_minmax();
self.lloc.compute_minmax();
if self.blank_min == usize::MAX {
self.blank_min = self.blank_min.min(self.blank() as usize);
self.blank_max = self.blank_max.max(self.blank() as usize);
}
}
}
pub trait Loc
where
Self: Checker,
{
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool);
}
#[inline(always)]
fn init(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) -> (usize, usize) {
let start = node.start_row();
let end = node.end_row();
if is_func_space {
stats.sloc.start = start;
stats.sloc.end = end;
stats.sloc.unit = is_unit;
}
(start, end)
}
#[inline(always)]
// Discriminates among the comments that are *after* a code line and
// the ones that are on an independent line.
// This difference is necessary in order to avoid having
// a wrong count for the blank metric.
fn add_cloc_lines(stats: &mut Stats, start: usize, end: usize) {
let comment_diff = end - start;
let is_comment_after_code_line = stats.ploc.lines.contains(&start);
if is_comment_after_code_line && comment_diff == 0 {
// A comment is *entirely* next to a code line
stats.cloc.code_comment_lines += 1;
} else if is_comment_after_code_line && comment_diff > 0 {
// A block comment that starts next to a code line and ends on
// independent lines.
stats.cloc.code_comment_lines += 1;
stats.cloc.only_comment_lines += comment_diff;
} else {
// A comment on an independent line AND
// a block comment on independent lines OR
// a comment *before* a code line
stats.cloc.only_comment_lines += (end - start) + 1;
// Save line end of a comment to check whether
// a comment *before* a code line is considered
stats.cloc.comment_line_end = Some(end);
}
}
#[inline(always)]
// Detects the comments that are on a code line but *before* the code part.
// This difference is necessary in order to avoid having
// a wrong count for the blank metric.
fn check_comment_ends_on_code_line(stats: &mut Stats, start_code_line: usize) {
if let Some(end) = stats.cloc.comment_line_end {
if end == start_code_line && !stats.ploc.lines.contains(&start_code_line) {
// Comment entirely *before* a code line
stats.cloc.only_comment_lines -= 1;
stats.cloc.code_comment_lines += 1;
}
}
}
impl Loc for PythonCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Python::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
StringStart | StringEnd | StringContent | Block | Module => {}
Comment => {
add_cloc_lines(stats, start, end);
}
String => {
let parent = node.parent().unwrap();
if let ExpressionStatement = parent.kind_id().into() {
add_cloc_lines(stats, start, end);
} else if parent.start_row() != start {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
Statement
| SimpleStatements
| ImportStatement
| FutureImportStatement
| ImportFromStatement
| PrintStatement
| AssertStatement
| ReturnStatement
| DeleteStatement
| RaiseStatement
| PassStatement
| BreakStatement
| ContinueStatement
| IfStatement
| ForStatement
| WhileStatement
| TryStatement
| WithStatement
| GlobalStatement
| NonlocalStatement
| ExecStatement
| ExpressionStatement => {
stats.lloc.logical_lines += 1;
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
impl Loc for MozjsCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Mozjs::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
String | DQUOTE | Program => {}
Comment => {
add_cloc_lines(stats, start, end);
}
ExpressionStatement | ExportStatement | ImportStatement | StatementBlock
| IfStatement | SwitchStatement | ForStatement | ForInStatement | WhileStatement
| DoStatement | TryStatement | WithStatement | BreakStatement | ContinueStatement
| DebuggerStatement | ReturnStatement | ThrowStatement | EmptyStatement
| StatementIdentifier => {
stats.lloc.logical_lines += 1;
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
impl Loc for JavascriptCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Javascript::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
String | DQUOTE | Program => {}
Comment => {
add_cloc_lines(stats, start, end);
}
ExpressionStatement | ExportStatement | ImportStatement | StatementBlock
| IfStatement | SwitchStatement | ForStatement | ForInStatement | WhileStatement
| DoStatement | TryStatement | WithStatement | BreakStatement | ContinueStatement
| DebuggerStatement | ReturnStatement | ThrowStatement | EmptyStatement
| StatementIdentifier => {
stats.lloc.logical_lines += 1;
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
impl Loc for TypescriptCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Typescript::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
String | DQUOTE | Program => {}
Comment => {
add_cloc_lines(stats, start, end);
}
ExpressionStatement | ExportStatement | ImportStatement | StatementBlock
| IfStatement | SwitchStatement | ForStatement | ForInStatement | WhileStatement
| DoStatement | TryStatement | WithStatement | BreakStatement | ContinueStatement
| DebuggerStatement | ReturnStatement | ThrowStatement | EmptyStatement
| StatementIdentifier => {
stats.lloc.logical_lines += 1;
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
impl Loc for TsxCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Tsx::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
String | DQUOTE | Program => {}
Comment => {
add_cloc_lines(stats, start, end);
}
ExpressionStatement | ExportStatement | ImportStatement | StatementBlock
| IfStatement | SwitchStatement | ForStatement | ForInStatement | WhileStatement
| DoStatement | TryStatement | WithStatement | BreakStatement | ContinueStatement
| DebuggerStatement | ReturnStatement | ThrowStatement | EmptyStatement
| StatementIdentifier => {
stats.lloc.logical_lines += 1;
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
impl Loc for RustCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Rust::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
StringLiteral
| RawStringLiteral
| Block
| SourceFile
| SLASH
| SLASHSLASH
| SLASHSTAR
| STARSLASH
| OuterDocCommentMarker
| OuterDocCommentMarker2
| DocComment
| InnerDocCommentMarker
| BANG => {}
BlockComment => {
add_cloc_lines(stats, start, end);
}
LineComment => {
// Exclude the last line for `LineComment` containing a `DocComment`,
// since the `DocComment` includes the newline,
// as explained here: https://github.com/tree-sitter/tree-sitter-rust/blob/2eaf126458a4d6a69401089b6ba78c5e5d6c1ced/src/scanner.c#L194-L195
let end = if node.is_child(DocComment as u16) {
end - 1
} else {
end
};
add_cloc_lines(stats, start, end);
}
Statement
| EmptyStatement
| ExpressionStatement
| LetDeclaration
| AssignmentExpression
| CompoundAssignmentExpr => {
stats.lloc.logical_lines += 1;
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
impl Loc for CppCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Cpp::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
RawStringLiteral | StringLiteral | DeclarationList | FieldDeclarationList
| TranslationUnit => {}
Comment => {
add_cloc_lines(stats, start, end);
}
WhileStatement | SwitchStatement | CaseStatement | IfStatement | ForStatement
| ReturnStatement | BreakStatement | ContinueStatement | GotoStatement
| ThrowStatement | TryStatement | TryStatement2 | ExpressionStatement
| ExpressionStatement2 | LabeledStatement | StatementIdentifier => {
stats.lloc.logical_lines += 1;
}
Declaration => {
if node.count_specific_ancestors::<CppParser>(
|node| {
matches!(
node.kind_id().into(),
WhileStatement | ForStatement | IfStatement
)
},
|node| node.kind_id() == CompoundStatement,
) == 0
{
stats.lloc.logical_lines += 1;
}
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
// As reported here: https://github.com/tree-sitter/tree-sitter-cpp/issues/276
// `tree-sitter-cpp` doesn't expand macros, providing a single `PreprocArg` node for the entire macro argument.
// Therefore, all lines from `start_row` to `end_row` must be added to PLOC to account for the unexpanded macro content
if let PreprocArg = node.kind_id().into() {
(node.start_row() + 1..=node.end_row()).for_each(|line| {
stats.ploc.lines.insert(line);
});
}
}
}
}
}
impl Loc for JavaCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Java::*;
let (start, end) = init(node, stats, is_func_space, is_unit);
let kind_id: Java = node.kind_id().into();
// LLOC in Java is counted for statements only
// https://docs.oracle.com/javase/tutorial/java/nutsandbolts/expressions.html
match kind_id {
Program => {}
LineComment | BlockComment => {
add_cloc_lines(stats, start, end);
}
AssertStatement | BreakStatement | ContinueStatement | DoStatement
| EnhancedForStatement | ExpressionStatement | ForStatement | IfStatement
| ReturnStatement | SwitchExpression | ThrowStatement | TryStatement
| WhileStatement => {
stats.lloc.logical_lines += 1;
}
LocalVariableDeclaration => {
if node.count_specific_ancestors::<JavaParser>(
|node| node.kind_id() == ForStatement,
|node| node.kind_id() == Block,
) == 0
{
// The initializer, condition, and increment in a for loop are expressions.
// Don't count the variable declaration if in a ForStatement.
// https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
stats.lloc.logical_lines += 1;
}
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}
implement_metric_trait!(Loc, PreprocCode, CcommentCode, KotlinCode);
#[cfg(test)]
mod tests {
use crate::tools::check_metrics;
use super::*;
#[test]
fn python_sloc() {
check_metrics::<PythonParser>(
"
a = 42
",
"foo.py",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn python_blank() {
check_metrics::<PythonParser>(
"
a = 42
b = 43
",
"foo.py",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 1.0,
"sloc_average": 3.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 1.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn rust_blank() {
check_metrics::<RustParser>(
"
let a = 42;
let b = 43;
",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 1.0,
"sloc_average": 3.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 1.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
check_metrics::<RustParser>("fn func() { /* comment */ }", "foo.rs", |metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 0.0,
"cloc": 1.0,
"blank": 0.0,
"sloc_average": 0.5,
"ploc_average": 0.5,
"lloc_average": 0.0,
"cloc_average": 0.5,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 1.0,
"cloc_max": 1.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 0.0,
"lloc_max": 0.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn c_blank() {
check_metrics::<CppParser>(
"
int a = 42;
int b = 43;
",
"foo.c",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 1.0,
"sloc_average": 3.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 1.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn python_no_zero_blank() {
// Checks that the blank metric is not equal to 0 when there are some
// comments next to code lines.
check_metrics::<PythonParser>(
"def ConnectToUpdateServer():
pool = 4
updateServer = -42
isConnected = False
currTry = 0
numRetries = 10 # Number of IPC connection retries before
# giving up.
numTries = 20 # Number of IPC connection tries before
# giving up.",
"foo.py",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 10.0,
"ploc": 7.0,
"lloc": 6.0,
"cloc": 4.0,
"blank": 1.0,
"sloc_average": 5.0,
"ploc_average": 3.5,
"lloc_average": 3.0,
"cloc_average": 2.0,
"blank_average": 0.5,
"sloc_min": 10.0,
"sloc_max": 10.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 7.0,
"ploc_max": 7.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn python_no_blank() {
// Checks that the blank metric is equal to 0 when there are no blank
// lines and there are comments next to code lines.
check_metrics::<PythonParser>(
"def ConnectToUpdateServer():
pool = 4
updateServer = -42
isConnected = False
currTry = 0
numRetries = 10 # Number of IPC connection retries before
# giving up.
numTries = 20 # Number of IPC connection tries before
# giving up.",
"foo.py",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 9.0,
"ploc": 7.0,
"lloc": 6.0,
"cloc": 4.0,
"blank": 0.0,
"sloc_average": 4.5,
"ploc_average": 3.5,
"lloc_average": 3.0,
"cloc_average": 2.0,
"blank_average": 0.0,
"sloc_min": 9.0,
"sloc_max": 9.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 7.0,
"ploc_max": 7.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn python_no_zero_blank_more_comments() {
// Checks that the blank metric is not equal to 0 when there are more
// comments next to code lines compared to the previous tests.
check_metrics::<PythonParser>(
"def ConnectToUpdateServer():
pool = 4
updateServer = -42
isConnected = False
currTry = 0 # Set this variable to 0
numRetries = 10 # Number of IPC connection retries before
# giving up.
numTries = 20 # Number of IPC connection tries before
# giving up.",
"foo.py",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 10.0,
"ploc": 7.0,
"lloc": 6.0,
"cloc": 5.0,
"blank": 1.0,
"sloc_average": 5.0,
"ploc_average": 3.5,
"lloc_average": 3.0,
"cloc_average": 2.5,
"blank_average": 0.5,
"sloc_min": 10.0,
"sloc_max": 10.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 7.0,
"ploc_max": 7.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn rust_no_zero_blank() {
// Checks that the blank metric is not equal to 0 when there are some
// comments next to code lines.
check_metrics::<RustParser>(
"fn ConnectToUpdateServer() {
let pool = 0;
let updateServer = -42;
let isConnected = false;
let currTry = 0;
let numRetries = 10; // Number of IPC connection retries before
// giving up.
let numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.rs",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 11.0,
"ploc": 8.0,
"lloc": 6.0,
"cloc": 4.0,
"blank": 1.0,
"sloc_average": 5.5,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 2.0,
"blank_average": 0.5,
"sloc_min": 11.0,
"sloc_max": 11.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn javascript_no_zero_blank() {
// Checks that the blank metric is not equal to 0 when there are some
// comments next to code lines.
check_metrics::<JavascriptParser>(
"function ConnectToUpdateServer() {
var pool = 0;
var updateServer = -42;
var isConnected = false;
var currTry = 0;
var numRetries = 10; // Number of IPC connection retries before
// giving up.
var numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.js",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 11.0,
"ploc": 8.0,
"lloc": 1.0,
"cloc": 4.0,
"blank": 1.0,
"sloc_average": 5.5,
"ploc_average": 4.0,
"lloc_average": 0.5,
"cloc_average": 2.0,
"blank_average": 0.5,
"sloc_min": 11.0,
"sloc_max": 11.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn cpp_no_zero_blank() {
// Checks that the blank metric is not equal to 0 when there are some
// comments next to code lines.
check_metrics::<CppParser>(
"void ConnectToUpdateServer() {
int pool;
int updateServer = -42;
bool isConnected = false;
int currTry = 0;
const int numRetries = 10; // Number of IPC connection retries before
// giving up.
const int numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.cpp",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 11.0,
"ploc": 8.0,
"lloc": 6.0,
"cloc": 4.0,
"blank": 1.0,
"sloc_average": 5.5,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 2.0,
"blank_average": 0.5,
"sloc_min": 11.0,
"sloc_max": 11.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn cpp_code_line_start_block_blank() {
// Checks that the blank metric is equal to 1 when there are
// block comments starting next to code lines.
check_metrics::<CppParser>(
"void ConnectToUpdateServer() {
int pool;
int updateServer = -42;
bool isConnected = false;
int currTry = 0;
const int numRetries = 10; /* Number of IPC connection retries
before
giving up. */
const int numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.cpp",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 12.0,
"ploc": 8.0,
"lloc": 6.0,
"cloc": 5.0,
"blank": 1.0,
"sloc_average": 6.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 2.5,
"blank_average": 0.5,
"sloc_min": 12.0,
"sloc_max": 12.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn cpp_block_comment_blank() {
// Checks that the blank metric is equal to 1 when there are
// block comments on independent lines.
check_metrics::<CppParser>(
"void ConnectToUpdateServer() {
int pool;
int updateServer = -42;
bool isConnected = false;
int currTry = 0;
/* Number of IPC connection retries
before
giving up. */
const int numRetries = 10;
const int numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.cpp",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 13.0,
"ploc": 8.0,
"lloc": 6.0,
"cloc": 5.0,
"blank": 1.0,
"sloc_average": 6.5,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 2.5,
"blank_average": 0.5,
"sloc_min": 13.0,
"sloc_max": 13.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn cpp_code_line_block_one_line_blank() {
// Checks that the blank metric is equal to 1 when there are
// block comments before the same code line.
check_metrics::<CppParser>(
"void ConnectToUpdateServer() {
int pool;
int updateServer = -42;
bool isConnected = false;
int currTry = 0;
/* Number of IPC connection retries before giving up. */ const int numRetries = 10;
const int numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.cpp",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 10.0,
"ploc": 8.0,
"lloc": 6.0,
"cloc": 3.0,
"blank": 1.0,
"sloc_average": 5.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 1.5,
"blank_average": 0.5,
"sloc_min": 10.0,
"sloc_max": 10.0,
"cloc_min": 3.0,
"cloc_max": 3.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn cpp_code_line_end_block_blank() {
// Checks that the blank metric is equal to 1 when there are
// block comments ending next to code lines.
check_metrics::<CppParser>(
"void ConnectToUpdateServer() {
int pool;
int updateServer = -42;
bool isConnected = false;
int currTry = 0;
/* Number of IPC connection retries
before
giving up. */ const int numRetries = 10;
const int numTries = 20; // Number of IPC connection tries before
// giving up.
}",
"foo.cpp",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 12.0,
"ploc": 8.0,
"lloc": 6.0,
"cloc": 5.0,
"blank": 1.0,
"sloc_average": 6.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 2.5,
"blank_average": 0.5,
"sloc_min": 12.0,
"sloc_max": 12.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 8.0,
"ploc_max": 8.0,
"lloc_min": 6.0,
"lloc_max": 6.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn python_cloc() {
check_metrics::<PythonParser>(
"\"\"\"Block comment
Block comment
\"\"\"
# Line Comment
a = 42 # Line Comment",
"foo.py",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 1.0,
"lloc": 2.0,
"cloc": 5.0,
"blank": 0.0,
"sloc_average": 5.0,
"ploc_average": 1.0,
"lloc_average": 2.0,
"cloc_average": 5.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_cloc() {
check_metrics::<RustParser>(
"/*Block comment
Block Comment*/
//Line Comment
/*Block Comment*/ let a = 42; // Line Comment",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 5.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 5.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn c_cloc() {
check_metrics::<CppParser>(
"/*Block comment
Block Comment*/
//Line Comment
/*Block Comment*/ int a = 42; // Line Comment",
"foo.c",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 5.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 5.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn python_lloc() {
check_metrics::<PythonParser>(
"for x in range(0,42):
if x % 2 == 0:
print(x)",
"foo.py",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_lloc() {
check_metrics::<RustParser>(
"for x in 0..42 {
if x % 2 == 0 {
println!(\"{}\", x);
}
}",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 5.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 5.0,
"ploc_average": 5.0,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
// LLOC returns three because there is an empty Rust statement
check_metrics::<RustParser>(
"let a = 42;
if true {
42
} else {
43
};",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 6.0,
"ploc": 6.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 6.0,
"ploc_average": 6.0,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 6.0,
"sloc_max": 6.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 6.0,
"ploc_max": 6.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn c_lloc() {
check_metrics::<CppParser>(
"for (;;)
break;",
"foo.c",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 2.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 2.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 2.0,
"sloc_max": 2.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn cpp_lloc() {
check_metrics::<CppParser>(
"nsTArray<xpcGCCallback> callbacks(extraGCCallbacks.Clone());
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
callbacks[i](status);
}",
"foo.cpp",
|metric| {
// Spaces: 1
// lloc: nsTArray, for, callbacks
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 4.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 4.0,
"ploc_max": 4.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn cpp_return_lloc() {
check_metrics::<CppParser>(
"uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y));
return RgbaColor(pixel_data) == blank_pixel_;",
"foo.cpp",
|metric| {
// Spaces: 1
// lloc: pixel_data, return
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 2.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 2.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 2.0,
"sloc_max": 2.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn cpp_for_lloc() {
check_metrics::<CppParser>(
"for (; start != end; ++start) {
const unsigned char idx = *start;
if (idx > 127 || !kValidTokenMap[idx]) return false;
}",
"foo.cpp",
|metric| {
// Spaces: 1
// lloc: for, idx, if, return
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 4.0,
"lloc": 4.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 4.0,
"lloc_average": 4.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 4.0,
"ploc_max": 4.0,
"lloc_min": 4.0,
"lloc_max": 4.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn cpp_while_lloc() {
check_metrics::<CppParser>(
"while (sHeapAtoms) {
HttpHeapAtom* next = sHeapAtoms->next;
free(sHeapAtoms);
}",
"foo.cpp",
|metric| {
// Spaces: 1
// lloc: while, next, free
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 4.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 4.0,
"ploc_max": 4.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn python_string_on_new_line() {
// More lines of the same instruction were counted as blank lines
check_metrics::<PythonParser>(
"capabilities[\"goog:chromeOptions\"][\"androidPackage\"] = \\
\"org.chromium.weblayer.shell\"",
"foo.py",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 2.0,
"ploc": 2.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 2.0,
"ploc_average": 2.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 2.0,
"sloc_max": 2.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_no_field_expression_lloc() {
check_metrics::<RustParser>(
"struct Foo {
field: usize,
}
let foo = Foo { 42 };
foo.field;",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 5.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 5.0,
"ploc_average": 5.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_no_parenthesized_expression_lloc() {
check_metrics::<RustParser>("let a = (42 + 0);", "foo.rs", |metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn rust_no_array_expression_lloc() {
check_metrics::<RustParser>("let a = [0; 42];", "foo.rs", |metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn rust_no_tuple_expression_lloc() {
check_metrics::<RustParser>("let a = (0, 42);", "foo.rs", |metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn rust_no_unit_expression_lloc() {
check_metrics::<RustParser>("let a = ();", "foo.rs", |metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn rust_call_function_lloc() {
check_metrics::<RustParser>(
"let a = foo(); // +1
foo(); // +1
k!(foo()); // +1",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 3.0,
"cloc": 3.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 3.0,
"cloc_average": 3.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 3.0,
"cloc_max": 3.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_macro_invocation_lloc() {
check_metrics::<RustParser>(
"let a = foo!(); // +1
foo!(); // +1
k(foo!()); // +1",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 3.0,
"cloc": 3.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 3.0,
"cloc_average": 3.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 3.0,
"cloc_max": 3.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_function_in_loop_lloc() {
check_metrics::<RustParser>(
"for (a, b) in c.iter().enumerate() {} // +1
while (a, b) in c.iter().enumerate() {} // +1
while let Some(a) = c.strip_prefix(\"hi\") {} // +1",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 3.0,
"cloc": 3.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 3.0,
"cloc_average": 3.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 3.0,
"cloc_max": 3.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_function_in_if_lloc() {
check_metrics::<RustParser>(
"if foo() {} // +1
if let Some(a) = foo() {} // +1",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 2.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 2.0,
"blank": 0.0,
"sloc_average": 2.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 2.0,
"blank_average": 0.0,
"sloc_min": 2.0,
"sloc_max": 2.0,
"cloc_min": 2.0,
"cloc_max": 2.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_function_in_return_lloc() {
check_metrics::<RustParser>(
"return foo();
await foo();",
"foo.rs",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 2.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 2.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 2.0,
"sloc_max": 2.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn rust_closure_expression_lloc() {
check_metrics::<RustParser>(
"let a = |i: i32| -> i32 { i + 1 }; // +1
a(42); // +1
k(b.iter().map(|n| n.parse.ok().unwrap_or(42))); // +1",
"foo.rs",
|metric| {
// Spaces: 3
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 3.0,
"cloc": 3.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 1.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 0.0,
"lloc_max": 0.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn python_general_loc() {
check_metrics::<PythonParser>(
"def func(a,
b,
c):
print(a)
print(b)
print(c)",
"foo.py",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 6.0,
"ploc": 6.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 1.5,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 6.0,
"sloc_max": 6.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 6.0,
"ploc_max": 6.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn python_real_loc() {
check_metrics::<PythonParser>(
"def web_socket_transfer_data(request):
while True:
line = request.ws_stream.receive_message()
if line is None:
return
code, reason = line.split(' ', 1)
if code is None or reason is None:
return
request.ws_stream.close_connection(int(code), reason)
# close_connection() initiates closing handshake. It validates code
# and reason. If you want to send a broken close frame for a test,
# following code will be useful.
# > data = struct.pack('!H', int(code)) + reason.encode('UTF-8')
# > request.connection.write(stream.create_close_frame(data))
# > # Suppress to re-respond client responding close frame.
# > raise Exception(\"customized server initiated closing handshake\")",
"foo.py",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 16.0,
"ploc": 9.0,
"lloc": 8.0,
"cloc": 7.0,
"blank": 0.0,
"sloc_average": 8.0,
"ploc_average": 4.5,
"lloc_average": 4.0,
"cloc_average": 3.5,
"blank_average": 0.0,
"sloc_min": 16.0,
"sloc_max": 16.0,
"cloc_min": 7.0,
"cloc_max": 7.0,
"ploc_min": 9.0,
"ploc_max": 9.0,
"lloc_min": 8.0,
"lloc_max": 8.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn javascript_real_loc() {
check_metrics::<JavascriptParser>(
"assert.throws(Test262Error, function() {
for (let { poisoned: x = ++initEvalCount } = poisonedProperty; ; ) {
return;
}
});",
"foo.js",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 5.0,
"lloc": 6.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 2.5,
"ploc_average": 2.5,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 5.0,
"lloc_max": 5.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn mozjs_real_loc() {
check_metrics::<MozjsParser>(
"assert.throws(Test262Error, function() {
for (let { poisoned: x = ++initEvalCount } = poisonedProperty; ; ) {
return;
}
});",
"foo.js",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 5.0,
"lloc": 6.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 2.5,
"ploc_average": 2.5,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 5.0,
"lloc_max": 5.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn cpp_namespace_loc() {
check_metrics::<CppParser>(
"namespace mozilla::dom::quota {} // namespace mozilla::dom::quota",
"foo.cpp",
|metric| {
// Spaces: 2
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 0.0,
"cloc": 1.0,
"blank": 0.0,
"sloc_average": 0.5,
"ploc_average": 0.5,
"lloc_average": 0.0,
"cloc_average": 0.5,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 0.0,
"lloc_max": 0.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_comments() {
check_metrics::<JavaParser>(
"for (int i = 0; i < 100; i++) { \
// Print hello
System.out.println(\"hello\"); \
// Print world
System.out.println(\"hello\"); \
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 3.0,
"cloc": 2.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 3.0,
"cloc_average": 2.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 2.0,
"cloc_max": 2.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_blank() {
check_metrics::<JavaParser>(
"int x = 1;
int y = 2;",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 2.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 2.0,
"sloc_average": 4.0,
"ploc_average": 2.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 2.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 2.0,
"ploc_max": 2.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 2.0,
"blank_max": 2.0
}"###
);
},
);
}
#[test]
fn java_sloc() {
check_metrics::<JavaParser>(
"for (int i = 0; i < 100; i++) {
System.out.println(i);
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_module_sloc() {
check_metrics::<JavaParser>(
"module helloworld{
exports com.test;
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 0.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 0.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 0.0,
"lloc_max": 0.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_single_ploc() {
check_metrics::<JavaParser>("int x = 1;", "foo.java", |metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn java_simple_ploc() {
check_metrics::<JavaParser>(
"for (int i = 0; i < 100; i = i++) {
System.out.println(i);
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_multi_ploc() {
check_metrics::<JavaParser>(
"int x = 1;
for (int i = 0; i < 100; i++) {
System.out.println(i);
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 4.0,
"lloc": 3.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 4.0,
"ploc_max": 4.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_single_statement_lloc() {
check_metrics::<JavaParser>("int max = 10;", "foo.java", |metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 1.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 1.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 1.0,
"lloc_max": 1.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
});
}
#[test]
fn java_for_lloc() {
check_metrics::<JavaParser>(
"for (int i = 0; i < 100; i++) { // + 1
System.out.println(i); // + 1
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 3.0,
"ploc": 3.0,
"lloc": 2.0,
"cloc": 2.0,
"blank": 0.0,
"sloc_average": 3.0,
"ploc_average": 3.0,
"lloc_average": 2.0,
"cloc_average": 2.0,
"blank_average": 0.0,
"sloc_min": 3.0,
"sloc_max": 3.0,
"cloc_min": 2.0,
"cloc_max": 2.0,
"ploc_min": 3.0,
"ploc_max": 3.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_foreach_lloc() {
check_metrics::<JavaParser>(
"
int arr[]={12,13,14,44}; // +1
for (int i:arr) { // +1
System.out.println(i); // +1
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 4.0,
"ploc": 4.0,
"lloc": 3.0,
"cloc": 3.0,
"blank": 0.0,
"sloc_average": 4.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 3.0,
"blank_average": 0.0,
"sloc_min": 4.0,
"sloc_max": 4.0,
"cloc_min": 3.0,
"cloc_max": 3.0,
"ploc_min": 4.0,
"ploc_max": 4.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_while_lloc() {
check_metrics::<JavaParser>(
"
int i=0; // +1
while(i < 10) { // +1
i++; // +1
System.out.println(i); // +1
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 5.0,
"lloc": 4.0,
"cloc": 4.0,
"blank": 0.0,
"sloc_average": 5.0,
"ploc_average": 5.0,
"lloc_average": 4.0,
"cloc_average": 4.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 4.0,
"lloc_max": 4.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_do_while_lloc() {
check_metrics::<JavaParser>(
"
int i=0; // +1
do { // +1
i++; // +1
System.out.println(i); // +1
} while(i < 10)",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 5.0,
"ploc": 5.0,
"lloc": 4.0,
"cloc": 4.0,
"blank": 0.0,
"sloc_average": 5.0,
"ploc_average": 5.0,
"lloc_average": 4.0,
"cloc_average": 4.0,
"blank_average": 0.0,
"sloc_min": 5.0,
"sloc_max": 5.0,
"cloc_min": 4.0,
"cloc_max": 4.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 4.0,
"lloc_max": 4.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_switch_lloc() {
check_metrics::<JavaParser>(
"switch(grade) { // +1
case 'A' :
System.out.println(\"Pass with distinction\"); // +1
break; // +1
case 'B' :
case 'C' :
System.out.println(\"Pass\"); // +1
break; // +1
case 'D' :
System.out.println(\"At risk\"); // +1
case 'F' :
System.out.println(\"Fail\"); // +1
break; // +1
default :
System.out.println(\"Invalid grade\"); // +1
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 16.0,
"ploc": 16.0,
"lloc": 9.0,
"cloc": 9.0,
"blank": 0.0,
"sloc_average": 16.0,
"ploc_average": 16.0,
"lloc_average": 9.0,
"cloc_average": 9.0,
"blank_average": 0.0,
"sloc_min": 16.0,
"sloc_max": 16.0,
"cloc_min": 9.0,
"cloc_max": 9.0,
"ploc_min": 16.0,
"ploc_max": 16.0,
"lloc_min": 9.0,
"lloc_max": 9.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_continue_lloc() {
check_metrics::<JavaParser>(
"int max = 10; // +1
for (int i = 0; i < max; i++) { // +1
if(i % 2 == 0) { continue;} + 2
System.out.println(i); // +1
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 6.0,
"ploc": 5.0,
"lloc": 5.0,
"cloc": 3.0,
"blank": 1.0,
"sloc_average": 6.0,
"ploc_average": 5.0,
"lloc_average": 5.0,
"cloc_average": 3.0,
"blank_average": 1.0,
"sloc_min": 6.0,
"sloc_max": 6.0,
"cloc_min": 3.0,
"cloc_max": 3.0,
"ploc_min": 5.0,
"ploc_max": 5.0,
"lloc_min": 5.0,
"lloc_max": 5.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn java_try_lloc() {
check_metrics::<JavaParser>(
"try { // +1
int[] myNumbers = {1, 2, 3}; // +1
System.out.println(myNumbers[10]); // +1
} catch (Exception e) {
System.out.println(e.getMessage()); // +1
throw e; // +1
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 7.0,
"ploc": 7.0,
"lloc": 5.0,
"cloc": 5.0,
"blank": 0.0,
"sloc_average": 7.0,
"ploc_average": 7.0,
"lloc_average": 5.0,
"cloc_average": 5.0,
"blank_average": 0.0,
"sloc_min": 7.0,
"sloc_max": 7.0,
"cloc_min": 5.0,
"cloc_max": 5.0,
"ploc_min": 7.0,
"ploc_max": 7.0,
"lloc_min": 5.0,
"lloc_max": 5.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_class_loc() {
check_metrics::<JavaParser>(
"
public class Person {
private String name;
public Person(String name){
this.name = name; // +1
}
public String getName() {
return name; // +1
}
}",
"foo.java",
|metric| {
// Spaces: 4
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 9.0,
"ploc": 9.0,
"lloc": 2.0,
"cloc": 2.0,
"blank": 0.0,
"sloc_average": 2.25,
"ploc_average": 2.25,
"lloc_average": 0.5,
"cloc_average": 0.5,
"blank_average": 0.0,
"sloc_min": 9.0,
"sloc_max": 9.0,
"cloc_min": 2.0,
"cloc_max": 2.0,
"ploc_min": 9.0,
"ploc_max": 9.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_expressions_lloc() {
check_metrics::<JavaParser>(
"int x = 10; // +1 local var declaration
x=+89; // +1 expression statement
int y = x * 2; // +1 local var declaration
IntFunction double = (n) -> n*2; // +1 local var declaration
int y2 = double(x); // +1 local var declaration
System.out.println(\"double \" + x + \" = \" + y2); // +1 expression statement
String message = (x % 2) == 0 ? \"Evenly done.\" : \"Oddly done.\"; // +1 local var declaration
Object done = (Runnable) () -> { System.out.println(\"Done!\"); }; // +2 local var declaration + expression statement
String s = \"string\"; // +1 local var declaration
boolean isS = (s instanceof String); // +1 local var declaration
done.run(); // +1 expression statement
",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 11.0,
"ploc": 11.0,
"lloc": 12.0,
"cloc": 11.0,
"blank": 0.0,
"sloc_average": 11.0,
"ploc_average": 11.0,
"lloc_average": 12.0,
"cloc_average": 11.0,
"blank_average": 0.0,
"sloc_min": 11.0,
"sloc_max": 11.0,
"cloc_min": 11.0,
"cloc_max": 11.0,
"ploc_min": 11.0,
"ploc_max": 11.0,
"lloc_min": 12.0,
"lloc_max": 12.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_statement_inline_loc() {
check_metrics::<JavaParser>(
"for (int i = 0; i < 100; i++) { System.out.println(\"hello\"); }",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 1.0,
"ploc": 1.0,
"lloc": 2.0,
"cloc": 0.0,
"blank": 0.0,
"sloc_average": 1.0,
"ploc_average": 1.0,
"lloc_average": 2.0,
"cloc_average": 0.0,
"blank_average": 0.0,
"sloc_min": 1.0,
"sloc_max": 1.0,
"cloc_min": 0.0,
"cloc_max": 0.0,
"ploc_min": 1.0,
"ploc_max": 1.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
#[test]
fn java_general_loc() {
check_metrics::<JavaParser>(
"int max = 100;
/*
Loop through and print
from: 0
to: max
*/
for (int i = 0; i < max; i++) {
// Print the value
System.out.println(i);
}",
"foo.java",
|metric| {
// Spaces: 1
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 11.0,
"ploc": 4.0,
"lloc": 3.0,
"cloc": 6.0,
"blank": 1.0,
"sloc_average": 11.0,
"ploc_average": 4.0,
"lloc_average": 3.0,
"cloc_average": 6.0,
"blank_average": 1.0,
"sloc_min": 11.0,
"sloc_max": 11.0,
"cloc_min": 6.0,
"cloc_max": 6.0,
"ploc_min": 4.0,
"ploc_max": 4.0,
"lloc_min": 3.0,
"lloc_max": 3.0,
"blank_min": 1.0,
"blank_max": 1.0
}"###
);
},
);
}
#[test]
fn java_main_class_loc() {
check_metrics::<JavaParser>(
"package com.company;
/**
* The HelloWorldApp class implements an application that
* simply prints \"Hello World!\" to standard output.
*/
class HelloWorldApp {
public void main(String[] args) {
String message = args.length == 0 ? \"Hello empty world\" : \"Hello world\"; // +1 lloc : 1 var assignment
System.out.println(message); // Display the string. +1 lloc
}
}",
"foo.java",
|metric| {
// Spaces: 3
insta::assert_json_snapshot!(
metric.loc,
@r###"
{
"sloc": 12.0,
"ploc": 7.0,
"lloc": 2.0,
"cloc": 6.0,
"blank": 1.0,
"sloc_average": 4.0,
"ploc_average": 2.3333333333333335,
"lloc_average": 0.6666666666666666,
"cloc_average": 2.0,
"blank_average": 0.3333333333333333,
"sloc_min": 6.0,
"sloc_max": 6.0,
"cloc_min": 2.0,
"cloc_max": 2.0,
"ploc_min": 6.0,
"ploc_max": 6.0,
"lloc_min": 2.0,
"lloc_max": 2.0,
"blank_min": 0.0,
"blank_max": 0.0
}"###
);
},
);
}
}