1#![allow(
8 clippy::enum_glob_use,
9 clippy::match_same_arms,
10 clippy::struct_field_names,
11 clippy::wildcard_imports
12)]
13#![allow(
20 clippy::cast_precision_loss,
21 clippy::cast_possible_truncation,
22 clippy::cast_sign_loss
23)]
24
25use std::collections::HashSet;
26
27use crate::checker::Checker;
28use crate::metrics::npa::python_is_block;
29use std::fmt;
30
31use crate::macros::implement_metric_trait;
32use crate::*;
33
34#[inline]
39fn min_or_zero(v: usize) -> u64 {
40 if v == usize::MAX { 0 } else { v as u64 }
41}
42
43#[derive(Debug, Clone, PartialEq)]
45pub struct Sloc {
46 start: usize,
47 end: usize,
48 unit: bool,
49 excluded_lines: usize,
58 sloc_min: usize,
59 sloc_max: usize,
60}
61
62impl Default for Sloc {
63 fn default() -> Self {
64 Self {
65 start: 0,
66 end: 0,
67 unit: false,
68 excluded_lines: 0,
69 sloc_min: usize::MAX,
70 sloc_max: 0,
71 }
72 }
73}
74
75impl Sloc {
76 #[inline]
78 #[must_use]
79 pub fn sloc(&self) -> u64 {
80 let span = if self.unit {
84 self.end - self.start
85 } else {
86 (self.end - self.start) + 1
87 };
88 span.saturating_sub(self.excluded_lines) as u64
94 }
95
96 #[inline]
109 pub(crate) fn exclude_span(&mut self, start_row: usize, end_row: usize) {
110 self.excluded_lines += (end_row - start_row) + 1;
111 }
112
113 #[inline]
116 #[must_use]
117 pub fn sloc_min(&self) -> u64 {
118 min_or_zero(self.sloc_min)
119 }
120
121 #[inline]
123 #[must_use]
124 pub fn sloc_max(&self) -> u64 {
125 self.sloc_max as u64
126 }
127
128 #[inline]
131 pub fn merge(&mut self, other: &Sloc) {
132 self.sloc_min = self.sloc_min.min(other.sloc_min);
137 self.sloc_max = self.sloc_max.max(other.sloc_max);
138
139 self.excluded_lines += other.excluded_lines;
153 }
154
155 #[inline]
156 pub(crate) fn compute_minmax(&mut self) {
157 self.sloc_min = self.sloc_min.min(self.sloc() as usize);
162 self.sloc_max = self.sloc_max.max(self.sloc() as usize);
163 }
164}
165
166#[derive(Debug, Clone, PartialEq)]
168pub struct Ploc {
169 lines: HashSet<usize>,
170 ploc_min: usize,
171 ploc_max: usize,
172}
173
174impl Default for Ploc {
175 fn default() -> Self {
176 Self {
177 lines: HashSet::default(),
178 ploc_min: usize::MAX,
179 ploc_max: 0,
180 }
181 }
182}
183
184impl Ploc {
185 #[inline]
187 #[must_use]
188 pub fn ploc(&self) -> u64 {
189 self.lines.len() as u64
192 }
193
194 #[inline]
197 #[must_use]
198 pub fn ploc_min(&self) -> u64 {
199 min_or_zero(self.ploc_min)
200 }
201
202 #[inline]
204 #[must_use]
205 pub fn ploc_max(&self) -> u64 {
206 self.ploc_max as u64
207 }
208
209 #[inline]
211 pub fn merge(&mut self, other: &Ploc) {
212 for l in &other.lines {
214 self.lines.insert(*l);
215 }
216
217 self.ploc_min = self.ploc_min.min(other.ploc_min);
219 self.ploc_max = self.ploc_max.max(other.ploc_max);
220 }
221
222 #[inline]
223 pub(crate) fn compute_minmax(&mut self) {
224 self.ploc_min = self.ploc_min.min(self.ploc() as usize);
227 self.ploc_max = self.ploc_max.max(self.ploc() as usize);
228 }
229}
230
231#[derive(Debug, Clone, PartialEq)]
233pub struct Cloc {
234 only_comment_line_starts: HashSet<usize>,
242 code_comment_line_starts: HashSet<usize>,
250 comment_line_end: Option<usize>,
251 cloc_min: usize,
252 cloc_max: usize,
253}
254
255impl Default for Cloc {
256 fn default() -> Self {
257 Self {
258 only_comment_line_starts: HashSet::default(),
259 code_comment_line_starts: HashSet::default(),
260 comment_line_end: Option::default(),
261 cloc_min: usize::MAX,
262 cloc_max: 0,
263 }
264 }
265}
266
267impl Cloc {
268 #[inline]
270 #[must_use]
271 pub fn cloc(&self) -> u64 {
272 self.only_comment_line_starts
282 .union(&self.code_comment_line_starts)
283 .count() as u64
284 }
285
286 #[inline]
289 #[must_use]
290 pub fn cloc_min(&self) -> u64 {
291 min_or_zero(self.cloc_min)
292 }
293
294 #[inline]
296 #[must_use]
297 pub fn cloc_max(&self) -> u64 {
298 self.cloc_max as u64
299 }
300
301 #[inline]
303 pub fn merge(&mut self, other: &Cloc) {
304 self.only_comment_line_starts
307 .extend(&other.only_comment_line_starts);
308 self.code_comment_line_starts
309 .extend(&other.code_comment_line_starts);
310
311 self.cloc_min = self.cloc_min.min(other.cloc_min);
313 self.cloc_max = self.cloc_max.max(other.cloc_max);
314 }
315
316 #[inline]
317 pub(crate) fn compute_minmax(&mut self) {
318 self.cloc_min = self.cloc_min.min(self.cloc() as usize);
321 self.cloc_max = self.cloc_max.max(self.cloc() as usize);
322 }
323}
324
325#[derive(Debug, Clone, PartialEq)]
327pub struct Lloc {
328 logical_lines: usize,
329 lloc_min: usize,
330 lloc_max: usize,
331}
332
333impl Default for Lloc {
334 fn default() -> Self {
335 Self {
336 logical_lines: 0,
337 lloc_min: usize::MAX,
338 lloc_max: 0,
339 }
340 }
341}
342
343impl Lloc {
344 #[inline]
346 #[must_use]
347 pub fn lloc(&self) -> u64 {
348 self.logical_lines as u64
351 }
352
353 #[inline]
356 #[must_use]
357 pub fn lloc_min(&self) -> u64 {
358 min_or_zero(self.lloc_min)
359 }
360
361 #[inline]
363 #[must_use]
364 pub fn lloc_max(&self) -> u64 {
365 self.lloc_max as u64
366 }
367
368 #[inline]
370 pub fn merge(&mut self, other: &Lloc) {
371 self.logical_lines += other.logical_lines;
373 self.lloc_min = self.lloc_min.min(other.lloc_min);
375 self.lloc_max = self.lloc_max.max(other.lloc_max);
376 }
377
378 #[inline]
379 pub(crate) fn compute_minmax(&mut self) {
380 self.lloc_min = self.lloc_min.min(self.lloc() as usize);
383 self.lloc_max = self.lloc_max.max(self.lloc() as usize);
384 }
385}
386
387#[derive(Debug, Clone, PartialEq)]
389#[non_exhaustive]
390pub struct Stats {
391 sloc: Sloc,
392 ploc: Ploc,
393 cloc: Cloc,
394 lloc: Lloc,
395 space_count: usize,
396 blank_min: usize,
397 blank_max: usize,
398}
399
400impl Default for Stats {
401 fn default() -> Self {
402 Self {
403 sloc: Sloc::default(),
404 ploc: Ploc::default(),
405 cloc: Cloc::default(),
406 lloc: Lloc::default(),
407 space_count: 1,
408 blank_min: usize::MAX,
409 blank_max: 0,
410 }
411 }
412}
413
414impl fmt::Display for Stats {
415 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
416 write!(
417 f,
418 "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: {}",
419 self.sloc(),
420 self.ploc(),
421 self.lloc(),
422 self.cloc(),
423 self.blank(),
424 self.sloc_average(),
425 self.ploc_average(),
426 self.lloc_average(),
427 self.cloc_average(),
428 self.blank_average(),
429 self.sloc_min(),
430 self.sloc_max(),
431 self.cloc_min(),
432 self.cloc_max(),
433 self.ploc_min(),
434 self.ploc_max(),
435 self.lloc_min(),
436 self.lloc_max(),
437 self.blank_min(),
438 self.blank_max(),
439 )
440 }
441}
442
443impl Stats {
444 #[cfg(test)]
450 pub(crate) fn with_cloc_sloc(code_comment_lines: usize, sloc_end_row: usize) -> Self {
451 let mut stats = Stats::default();
452 stats.sloc.unit = false;
453 stats.sloc.start = 0;
454 stats.sloc.end = sloc_end_row;
455 let synthetic_base = sloc_end_row + 1;
460 stats
461 .cloc
462 .code_comment_line_starts
463 .extend(synthetic_base..synthetic_base + code_comment_lines);
464 stats
465 }
466
467 pub fn merge(&mut self, other: &Stats) {
469 self.sloc.merge(&other.sloc);
470 self.ploc.merge(&other.ploc);
471 self.cloc.merge(&other.cloc);
472 self.lloc.merge(&other.lloc);
473
474 self.space_count += other.space_count;
476
477 self.blank_min = self.blank_min.min(other.blank_min);
479 self.blank_max = self.blank_max.max(other.blank_max);
480 }
481
482 #[inline]
488 pub(crate) fn exclude_test_span(&mut self, start_row: usize, end_row: usize) {
489 self.sloc.exclude_span(start_row, end_row);
490 }
491
492 #[inline]
496 #[must_use]
497 pub fn sloc(&self) -> u64 {
498 self.sloc.sloc()
499 }
500
501 #[inline]
505 #[must_use]
506 pub fn ploc(&self) -> u64 {
507 self.ploc.ploc()
508 }
509
510 #[inline]
514 #[must_use]
515 pub fn lloc(&self) -> u64 {
516 self.lloc.lloc()
517 }
518
519 #[inline]
523 #[must_use]
524 pub fn cloc(&self) -> u64 {
525 self.cloc.cloc()
526 }
527
528 #[inline]
532 #[must_use]
533 pub fn blank(&self) -> u64 {
534 self.sloc()
540 .saturating_sub(self.ploc())
541 .saturating_sub(self.cloc.only_comment_line_starts.len() as u64)
542 }
543
544 #[inline]
548 #[must_use]
549 pub fn sloc_average(&self) -> f64 {
550 crate::metrics::average(self.sloc() as f64, self.space_count)
551 }
552
553 #[inline]
557 #[must_use]
558 pub fn ploc_average(&self) -> f64 {
559 crate::metrics::average(self.ploc() as f64, self.space_count)
560 }
561
562 #[inline]
566 #[must_use]
567 pub fn lloc_average(&self) -> f64 {
568 crate::metrics::average(self.lloc() as f64, self.space_count)
569 }
570
571 #[inline]
575 #[must_use]
576 pub fn cloc_average(&self) -> f64 {
577 crate::metrics::average(self.cloc() as f64, self.space_count)
578 }
579
580 #[inline]
584 #[must_use]
585 pub fn blank_average(&self) -> f64 {
586 crate::metrics::average(self.blank() as f64, self.space_count)
587 }
588
589 #[inline]
591 #[must_use]
592 pub fn sloc_min(&self) -> u64 {
593 self.sloc.sloc_min()
594 }
595
596 #[inline]
598 #[must_use]
599 pub fn sloc_max(&self) -> u64 {
600 self.sloc.sloc_max()
601 }
602
603 #[inline]
605 #[must_use]
606 pub fn cloc_min(&self) -> u64 {
607 self.cloc.cloc_min()
608 }
609
610 #[inline]
612 #[must_use]
613 pub fn cloc_max(&self) -> u64 {
614 self.cloc.cloc_max()
615 }
616
617 #[inline]
619 #[must_use]
620 pub fn ploc_min(&self) -> u64 {
621 self.ploc.ploc_min()
622 }
623
624 #[inline]
626 #[must_use]
627 pub fn ploc_max(&self) -> u64 {
628 self.ploc.ploc_max()
629 }
630
631 #[inline]
633 #[must_use]
634 pub fn lloc_min(&self) -> u64 {
635 self.lloc.lloc_min()
636 }
637
638 #[inline]
640 #[must_use]
641 pub fn lloc_max(&self) -> u64 {
642 self.lloc.lloc_max()
643 }
644
645 #[inline]
648 #[must_use]
649 pub fn blank_min(&self) -> u64 {
650 min_or_zero(self.blank_min)
651 }
652
653 #[inline]
655 #[must_use]
656 pub fn blank_max(&self) -> u64 {
657 self.blank_max as u64
658 }
659
660 #[inline]
661 pub(crate) fn compute_minmax(&mut self) {
662 self.sloc.compute_minmax();
663 self.ploc.compute_minmax();
664 self.cloc.compute_minmax();
665 self.lloc.compute_minmax();
666
667 self.blank_min = self.blank_min.min(self.blank() as usize);
673 self.blank_max = self.blank_max.max(self.blank() as usize);
674 }
675
676 pub(crate) fn init_unit_span(&mut self, start: usize, end: usize) {
677 self.sloc.start = start;
678 self.sloc.end = end;
679 self.sloc.unit = true;
680 }
681}
682
683#[doc(hidden)]
684pub(crate) trait Loc
686where
687 Self: Checker,
688{
689 fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool);
692}
693
694mod shared;
695pub(crate) use shared::*;
696
697implement_metric_trait!(Loc, PreprocCode, CcommentCode);
701
702mod bash;
703mod c;
704mod cpp;
705mod csharp;
706mod elixir;
707mod go;
708mod groovy;
709mod irules;
710mod java;
711mod javascript;
712mod kotlin;
713mod lua;
714mod mozcpp;
715mod mozjs;
716mod objc;
717mod perl;
718mod php;
719mod python;
720mod ruby;
721mod rust;
722mod tcl;
723mod tsx;
724mod typescript;
725
726#[cfg(test)]
727#[allow(
728 clippy::float_cmp,
729 clippy::cast_precision_loss,
730 clippy::cast_possible_truncation,
731 clippy::cast_sign_loss,
732 clippy::similar_names,
733 clippy::doc_markdown,
734 clippy::needless_raw_string_hashes,
735 clippy::too_many_lines
736)]
737mod tests {
738 use crate::tools::check_metrics;
739
740 use super::*;
741
742 #[test]
748 fn loc_empty_file_min_is_zero() {
749 let stats = Stats::default();
750 assert_eq!(stats.sloc_min(), 0);
751 assert_eq!(stats.ploc_min(), 0);
752 assert_eq!(stats.lloc_min(), 0);
753 assert_eq!(stats.cloc_min(), 0);
754 assert_eq!(stats.blank_min(), 0);
755 }
756
757 #[cfg(test)]
763 fn assert_perl_parses_cleanly(source: &str) {
764 use crate::traits::ParserTrait;
765 let path = std::path::PathBuf::from("foo.pl");
769 let mut bytes = source.trim_end_matches('\n').as_bytes().to_vec();
770 bytes.push(b'\n');
771 let parser = PerlParser::new(bytes, &path, None);
772 assert!(
773 !parser.root().has_error(),
774 "tree-sitter-perl returned an error tree for snippet:\n{source}"
775 );
776 }
777
778 #[test]
779 fn python_sloc() {
780 check_metrics::<PythonParser>(
781 "
782
783 a = 42
784
785 ",
786 "foo.py",
787 |metric| {
788 insta::assert_json_snapshot!(
790 metric.loc,
791 @r#"
792 {
793 "sloc": 1,
794 "ploc": 1,
795 "lloc": 1,
796 "cloc": 0,
797 "blank": 0,
798 "sloc_average": 1.0,
799 "ploc_average": 1.0,
800 "lloc_average": 1.0,
801 "cloc_average": 0.0,
802 "blank_average": 0.0,
803 "sloc_min": 1,
804 "sloc_max": 1,
805 "cloc_min": 0,
806 "cloc_max": 0,
807 "ploc_min": 1,
808 "ploc_max": 1,
809 "lloc_min": 1,
810 "lloc_max": 1,
811 "blank_min": 0,
812 "blank_max": 0
813 }
814 "#
815 );
816 },
817 );
818 }
819
820 #[test]
821 fn python_blank() {
822 check_metrics::<PythonParser>(
823 "
824 a = 42
825
826 b = 43
827
828 ",
829 "foo.py",
830 |metric| {
831 insta::assert_json_snapshot!(
833 metric.loc,
834 @r#"
835 {
836 "sloc": 3,
837 "ploc": 2,
838 "lloc": 2,
839 "cloc": 0,
840 "blank": 1,
841 "sloc_average": 3.0,
842 "ploc_average": 2.0,
843 "lloc_average": 2.0,
844 "cloc_average": 0.0,
845 "blank_average": 1.0,
846 "sloc_min": 3,
847 "sloc_max": 3,
848 "cloc_min": 0,
849 "cloc_max": 0,
850 "ploc_min": 2,
851 "ploc_max": 2,
852 "lloc_min": 2,
853 "lloc_max": 2,
854 "blank_min": 1,
855 "blank_max": 1
856 }
857 "#
858 );
859 },
860 );
861 }
862
863 #[test]
864 fn rust_blank() {
865 check_metrics::<RustParser>(
866 "
867
868 let a = 42;
869
870 let b = 43;
871
872 ",
873 "foo.rs",
874 |metric| {
875 insta::assert_json_snapshot!(
877 metric.loc,
878 @r#"
879 {
880 "sloc": 3,
881 "ploc": 2,
882 "lloc": 2,
883 "cloc": 0,
884 "blank": 1,
885 "sloc_average": 3.0,
886 "ploc_average": 2.0,
887 "lloc_average": 2.0,
888 "cloc_average": 0.0,
889 "blank_average": 1.0,
890 "sloc_min": 3,
891 "sloc_max": 3,
892 "cloc_min": 0,
893 "cloc_max": 0,
894 "ploc_min": 2,
895 "ploc_max": 2,
896 "lloc_min": 2,
897 "lloc_max": 2,
898 "blank_min": 1,
899 "blank_max": 1
900 }
901 "#
902 );
903 },
904 );
905
906 check_metrics::<RustParser>("fn func() { /* comment */ }", "foo.rs", |metric| {
907 insta::assert_json_snapshot!(
909 metric.loc,
910 @r#"
911 {
912 "sloc": 1,
913 "ploc": 1,
914 "lloc": 0,
915 "cloc": 1,
916 "blank": 0,
917 "sloc_average": 0.5,
918 "ploc_average": 0.5,
919 "lloc_average": 0.0,
920 "cloc_average": 0.5,
921 "blank_average": 0.0,
922 "sloc_min": 1,
923 "sloc_max": 1,
924 "cloc_min": 1,
925 "cloc_max": 1,
926 "ploc_min": 1,
927 "ploc_max": 1,
928 "lloc_min": 0,
929 "lloc_max": 0,
930 "blank_min": 0,
931 "blank_max": 0
932 }
933 "#
934 );
935 });
936 }
937
938 #[test]
939 fn c_blank() {
940 check_metrics::<CParser>(
941 "
942
943 int a = 42;
944
945 int b = 43;
946
947 ",
948 "foo.c",
949 |metric| {
950 insta::assert_json_snapshot!(
952 metric.loc,
953 @r#"
954 {
955 "sloc": 3,
956 "ploc": 2,
957 "lloc": 2,
958 "cloc": 0,
959 "blank": 1,
960 "sloc_average": 3.0,
961 "ploc_average": 2.0,
962 "lloc_average": 2.0,
963 "cloc_average": 0.0,
964 "blank_average": 1.0,
965 "sloc_min": 3,
966 "sloc_max": 3,
967 "cloc_min": 0,
968 "cloc_max": 0,
969 "ploc_min": 2,
970 "ploc_max": 2,
971 "lloc_min": 2,
972 "lloc_max": 2,
973 "blank_min": 1,
974 "blank_max": 1
975 }
976 "#
977 );
978 },
979 );
980 }
981
982 #[test]
983 fn python_no_zero_blank() {
984 check_metrics::<PythonParser>(
987 "def ConnectToUpdateServer():
988 pool = 4
989
990 updateServer = -42
991 isConnected = False
992 currTry = 0
993 numRetries = 10 # Number of IPC connection retries before
994 # giving up.
995 numTries = 20 # Number of IPC connection tries before
996 # giving up.",
997 "foo.py",
998 |metric| {
999 insta::assert_json_snapshot!(
1001 metric.loc,
1002 @r#"
1003 {
1004 "sloc": 10,
1005 "ploc": 7,
1006 "lloc": 6,
1007 "cloc": 4,
1008 "blank": 1,
1009 "sloc_average": 5.0,
1010 "ploc_average": 3.5,
1011 "lloc_average": 3.0,
1012 "cloc_average": 2.0,
1013 "blank_average": 0.5,
1014 "sloc_min": 10,
1015 "sloc_max": 10,
1016 "cloc_min": 4,
1017 "cloc_max": 4,
1018 "ploc_min": 7,
1019 "ploc_max": 7,
1020 "lloc_min": 6,
1021 "lloc_max": 6,
1022 "blank_min": 1,
1023 "blank_max": 1
1024 }
1025 "#
1026 );
1027 },
1028 );
1029 }
1030
1031 #[test]
1032 fn python_no_blank() {
1033 check_metrics::<PythonParser>(
1036 "def ConnectToUpdateServer():
1037 pool = 4
1038 updateServer = -42
1039 isConnected = False
1040 currTry = 0
1041 numRetries = 10 # Number of IPC connection retries before
1042 # giving up.
1043 numTries = 20 # Number of IPC connection tries before
1044 # giving up.",
1045 "foo.py",
1046 |metric| {
1047 insta::assert_json_snapshot!(
1049 metric.loc,
1050 @r#"
1051 {
1052 "sloc": 9,
1053 "ploc": 7,
1054 "lloc": 6,
1055 "cloc": 4,
1056 "blank": 0,
1057 "sloc_average": 4.5,
1058 "ploc_average": 3.5,
1059 "lloc_average": 3.0,
1060 "cloc_average": 2.0,
1061 "blank_average": 0.0,
1062 "sloc_min": 9,
1063 "sloc_max": 9,
1064 "cloc_min": 4,
1065 "cloc_max": 4,
1066 "ploc_min": 7,
1067 "ploc_max": 7,
1068 "lloc_min": 6,
1069 "lloc_max": 6,
1070 "blank_min": 0,
1071 "blank_max": 0
1072 }
1073 "#
1074 );
1075 },
1076 );
1077 }
1078
1079 #[test]
1080 fn python_no_zero_blank_more_comments() {
1081 check_metrics::<PythonParser>(
1084 "def ConnectToUpdateServer():
1085 pool = 4
1086
1087 updateServer = -42
1088 isConnected = False
1089 currTry = 0 # Set this variable to 0
1090 numRetries = 10 # Number of IPC connection retries before
1091 # giving up.
1092 numTries = 20 # Number of IPC connection tries before
1093 # giving up.",
1094 "foo.py",
1095 |metric| {
1096 insta::assert_json_snapshot!(
1098 metric.loc,
1099 @r#"
1100 {
1101 "sloc": 10,
1102 "ploc": 7,
1103 "lloc": 6,
1104 "cloc": 5,
1105 "blank": 1,
1106 "sloc_average": 5.0,
1107 "ploc_average": 3.5,
1108 "lloc_average": 3.0,
1109 "cloc_average": 2.5,
1110 "blank_average": 0.5,
1111 "sloc_min": 10,
1112 "sloc_max": 10,
1113 "cloc_min": 5,
1114 "cloc_max": 5,
1115 "ploc_min": 7,
1116 "ploc_max": 7,
1117 "lloc_min": 6,
1118 "lloc_max": 6,
1119 "blank_min": 1,
1120 "blank_max": 1
1121 }
1122 "#
1123 );
1124 },
1125 );
1126 }
1127
1128 #[test]
1129 fn rust_no_zero_blank() {
1130 check_metrics::<RustParser>(
1133 "fn ConnectToUpdateServer() {
1134 let pool = 0;
1135
1136 let updateServer = -42;
1137 let isConnected = false;
1138 let currTry = 0;
1139 let numRetries = 10; // Number of IPC connection retries before
1140 // giving up.
1141 let numTries = 20; // Number of IPC connection tries before
1142 // giving up.
1143 }",
1144 "foo.rs",
1145 |metric| {
1146 insta::assert_json_snapshot!(
1148 metric.loc,
1149 @r#"
1150 {
1151 "sloc": 11,
1152 "ploc": 8,
1153 "lloc": 6,
1154 "cloc": 4,
1155 "blank": 1,
1156 "sloc_average": 5.5,
1157 "ploc_average": 4.0,
1158 "lloc_average": 3.0,
1159 "cloc_average": 2.0,
1160 "blank_average": 0.5,
1161 "sloc_min": 11,
1162 "sloc_max": 11,
1163 "cloc_min": 4,
1164 "cloc_max": 4,
1165 "ploc_min": 8,
1166 "ploc_max": 8,
1167 "lloc_min": 6,
1168 "lloc_max": 6,
1169 "blank_min": 1,
1170 "blank_max": 1
1171 }
1172 "#
1173 );
1174 },
1175 );
1176 }
1177
1178 #[test]
1179 fn javascript_no_zero_blank() {
1180 check_metrics::<JavascriptParser>(
1183 "function ConnectToUpdateServer() {
1184 var pool = 0;
1185
1186 var updateServer = -42;
1187 var isConnected = false;
1188 var currTry = 0;
1189 var numRetries = 10; // Number of IPC connection retries before
1190 // giving up.
1191 var numTries = 20; // Number of IPC connection tries before
1192 // giving up.
1193 }",
1194 "foo.js",
1195 |metric| {
1196 insta::assert_json_snapshot!(
1198 metric.loc,
1199 @r#"
1200 {
1201 "sloc": 11,
1202 "ploc": 8,
1203 "lloc": 0,
1204 "cloc": 4,
1205 "blank": 1,
1206 "sloc_average": 5.5,
1207 "ploc_average": 4.0,
1208 "lloc_average": 0.0,
1209 "cloc_average": 2.0,
1210 "blank_average": 0.5,
1211 "sloc_min": 11,
1212 "sloc_max": 11,
1213 "cloc_min": 4,
1214 "cloc_max": 4,
1215 "ploc_min": 8,
1216 "ploc_max": 8,
1217 "lloc_min": 0,
1218 "lloc_max": 0,
1219 "blank_min": 1,
1220 "blank_max": 1
1221 }
1222 "#
1223 );
1224 },
1225 );
1226 }
1227
1228 #[test]
1229 fn cpp_no_zero_blank() {
1230 check_metrics::<CppParser>(
1233 "void ConnectToUpdateServer() {
1234 int pool;
1235
1236 int updateServer = -42;
1237 bool isConnected = false;
1238 int currTry = 0;
1239 const int numRetries = 10; // Number of IPC connection retries before
1240 // giving up.
1241 const int numTries = 20; // Number of IPC connection tries before
1242 // giving up.
1243 }",
1244 "foo.cpp",
1245 |metric| {
1246 insta::assert_json_snapshot!(
1248 metric.loc,
1249 @r#"
1250 {
1251 "sloc": 11,
1252 "ploc": 8,
1253 "lloc": 6,
1254 "cloc": 4,
1255 "blank": 1,
1256 "sloc_average": 5.5,
1257 "ploc_average": 4.0,
1258 "lloc_average": 3.0,
1259 "cloc_average": 2.0,
1260 "blank_average": 0.5,
1261 "sloc_min": 11,
1262 "sloc_max": 11,
1263 "cloc_min": 4,
1264 "cloc_max": 4,
1265 "ploc_min": 8,
1266 "ploc_max": 8,
1267 "lloc_min": 6,
1268 "lloc_max": 6,
1269 "blank_min": 1,
1270 "blank_max": 1
1271 }
1272 "#
1273 );
1274 },
1275 );
1276 }
1277
1278 #[test]
1279 fn cpp_code_line_start_block_blank() {
1280 check_metrics::<CppParser>(
1283 "void ConnectToUpdateServer() {
1284 int pool;
1285
1286 int updateServer = -42;
1287 bool isConnected = false;
1288 int currTry = 0;
1289 const int numRetries = 10; /* Number of IPC connection retries
1290 before
1291 giving up. */
1292 const int numTries = 20; // Number of IPC connection tries before
1293 // giving up.
1294 }",
1295 "foo.cpp",
1296 |metric| {
1297 insta::assert_json_snapshot!(
1299 metric.loc,
1300 @r#"
1301 {
1302 "sloc": 12,
1303 "ploc": 8,
1304 "lloc": 6,
1305 "cloc": 5,
1306 "blank": 1,
1307 "sloc_average": 6.0,
1308 "ploc_average": 4.0,
1309 "lloc_average": 3.0,
1310 "cloc_average": 2.5,
1311 "blank_average": 0.5,
1312 "sloc_min": 12,
1313 "sloc_max": 12,
1314 "cloc_min": 5,
1315 "cloc_max": 5,
1316 "ploc_min": 8,
1317 "ploc_max": 8,
1318 "lloc_min": 6,
1319 "lloc_max": 6,
1320 "blank_min": 1,
1321 "blank_max": 1
1322 }
1323 "#
1324 );
1325 },
1326 );
1327 }
1328
1329 #[test]
1330 fn cpp_block_comment_blank() {
1331 check_metrics::<CppParser>(
1334 "void ConnectToUpdateServer() {
1335 int pool;
1336
1337 int updateServer = -42;
1338 bool isConnected = false;
1339 int currTry = 0;
1340 /* Number of IPC connection retries
1341 before
1342 giving up. */
1343 const int numRetries = 10;
1344 const int numTries = 20; // Number of IPC connection tries before
1345 // giving up.
1346 }",
1347 "foo.cpp",
1348 |metric| {
1349 insta::assert_json_snapshot!(
1351 metric.loc,
1352 @r#"
1353 {
1354 "sloc": 13,
1355 "ploc": 8,
1356 "lloc": 6,
1357 "cloc": 5,
1358 "blank": 1,
1359 "sloc_average": 6.5,
1360 "ploc_average": 4.0,
1361 "lloc_average": 3.0,
1362 "cloc_average": 2.5,
1363 "blank_average": 0.5,
1364 "sloc_min": 13,
1365 "sloc_max": 13,
1366 "cloc_min": 5,
1367 "cloc_max": 5,
1368 "ploc_min": 8,
1369 "ploc_max": 8,
1370 "lloc_min": 6,
1371 "lloc_max": 6,
1372 "blank_min": 1,
1373 "blank_max": 1
1374 }
1375 "#
1376 );
1377 },
1378 );
1379 }
1380
1381 #[test]
1382 fn cpp_code_line_block_one_line_blank() {
1383 check_metrics::<CppParser>(
1386 "void ConnectToUpdateServer() {
1387 int pool;
1388
1389 int updateServer = -42;
1390 bool isConnected = false;
1391 int currTry = 0;
1392 /* Number of IPC connection retries before giving up. */ const int numRetries = 10;
1393 const int numTries = 20; // Number of IPC connection tries before
1394 // giving up.
1395 }",
1396 "foo.cpp",
1397 |metric| {
1398 insta::assert_json_snapshot!(
1400 metric.loc,
1401 @r#"
1402 {
1403 "sloc": 10,
1404 "ploc": 8,
1405 "lloc": 6,
1406 "cloc": 3,
1407 "blank": 1,
1408 "sloc_average": 5.0,
1409 "ploc_average": 4.0,
1410 "lloc_average": 3.0,
1411 "cloc_average": 1.5,
1412 "blank_average": 0.5,
1413 "sloc_min": 10,
1414 "sloc_max": 10,
1415 "cloc_min": 3,
1416 "cloc_max": 3,
1417 "ploc_min": 8,
1418 "ploc_max": 8,
1419 "lloc_min": 6,
1420 "lloc_max": 6,
1421 "blank_min": 1,
1422 "blank_max": 1
1423 }
1424 "#
1425 );
1426 },
1427 );
1428 }
1429
1430 #[test]
1431 fn cpp_code_line_end_block_blank() {
1432 check_metrics::<CppParser>(
1435 "void ConnectToUpdateServer() {
1436 int pool;
1437
1438 int updateServer = -42;
1439 bool isConnected = false;
1440 int currTry = 0;
1441 /* Number of IPC connection retries
1442 before
1443 giving up. */ const int numRetries = 10;
1444 const int numTries = 20; // Number of IPC connection tries before
1445 // giving up.
1446 }",
1447 "foo.cpp",
1448 |metric| {
1449 insta::assert_json_snapshot!(
1451 metric.loc,
1452 @r#"
1453 {
1454 "sloc": 12,
1455 "ploc": 8,
1456 "lloc": 6,
1457 "cloc": 5,
1458 "blank": 1,
1459 "sloc_average": 6.0,
1460 "ploc_average": 4.0,
1461 "lloc_average": 3.0,
1462 "cloc_average": 2.5,
1463 "blank_average": 0.5,
1464 "sloc_min": 12,
1465 "sloc_max": 12,
1466 "cloc_min": 5,
1467 "cloc_max": 5,
1468 "ploc_min": 8,
1469 "ploc_max": 8,
1470 "lloc_min": 6,
1471 "lloc_max": 6,
1472 "blank_min": 1,
1473 "blank_max": 1
1474 }
1475 "#
1476 );
1477 },
1478 );
1479 }
1480
1481 #[test]
1482 fn python_cloc() {
1483 check_metrics::<PythonParser>(
1484 "\"\"\"Block comment
1485 Block comment
1486 \"\"\"
1487 # Line Comment
1488 a = 42 # Line Comment",
1489 "foo.py",
1490 |metric| {
1491 insta::assert_json_snapshot!(
1493 metric.loc,
1494 @r#"
1495 {
1496 "sloc": 5,
1497 "ploc": 1,
1498 "lloc": 2,
1499 "cloc": 5,
1500 "blank": 0,
1501 "sloc_average": 5.0,
1502 "ploc_average": 1.0,
1503 "lloc_average": 2.0,
1504 "cloc_average": 5.0,
1505 "blank_average": 0.0,
1506 "sloc_min": 5,
1507 "sloc_max": 5,
1508 "cloc_min": 5,
1509 "cloc_max": 5,
1510 "ploc_min": 1,
1511 "ploc_max": 1,
1512 "lloc_min": 2,
1513 "lloc_max": 2,
1514 "blank_min": 0,
1515 "blank_max": 0
1516 }
1517 "#
1518 );
1519 },
1520 );
1521 }
1522
1523 #[test]
1524 fn rust_cloc() {
1525 check_metrics::<RustParser>(
1526 "/*Block comment
1527 Block Comment*/
1528 //Line Comment
1529 /*Block Comment*/ let a = 42; // Line Comment",
1530 "foo.rs",
1531 |metric| {
1532 insta::assert_json_snapshot!(
1541 metric.loc,
1542 @r#"
1543 {
1544 "sloc": 4,
1545 "ploc": 1,
1546 "lloc": 1,
1547 "cloc": 4,
1548 "blank": 0,
1549 "sloc_average": 4.0,
1550 "ploc_average": 1.0,
1551 "lloc_average": 1.0,
1552 "cloc_average": 4.0,
1553 "blank_average": 0.0,
1554 "sloc_min": 4,
1555 "sloc_max": 4,
1556 "cloc_min": 4,
1557 "cloc_max": 4,
1558 "ploc_min": 1,
1559 "ploc_max": 1,
1560 "lloc_min": 1,
1561 "lloc_max": 1,
1562 "blank_min": 0,
1563 "blank_max": 0
1564 }
1565 "#
1566 );
1567 },
1568 );
1569 }
1570
1571 #[test]
1572 fn c_cloc() {
1573 check_metrics::<CParser>(
1574 "/*Block comment
1575 Block Comment*/
1576 //Line Comment
1577 /*Block Comment*/ int a = 42; // Line Comment",
1578 "foo.c",
1579 |metric| {
1580 insta::assert_json_snapshot!(
1586 metric.loc,
1587 @r#"
1588 {
1589 "sloc": 4,
1590 "ploc": 1,
1591 "lloc": 1,
1592 "cloc": 4,
1593 "blank": 0,
1594 "sloc_average": 4.0,
1595 "ploc_average": 1.0,
1596 "lloc_average": 1.0,
1597 "cloc_average": 4.0,
1598 "blank_average": 0.0,
1599 "sloc_min": 4,
1600 "sloc_max": 4,
1601 "cloc_min": 4,
1602 "cloc_max": 4,
1603 "ploc_min": 1,
1604 "ploc_max": 1,
1605 "lloc_min": 1,
1606 "lloc_max": 1,
1607 "blank_min": 0,
1608 "blank_max": 0
1609 }
1610 "#
1611 );
1612 },
1613 );
1614 }
1615
1616 #[test]
1617 fn python_lloc() {
1618 check_metrics::<PythonParser>(
1619 "for x in range(0,42):
1620 if x % 2 == 0:
1621 print(x)",
1622 "foo.py",
1623 |metric| {
1624 insta::assert_json_snapshot!(
1626 metric.loc,
1627 @r#"
1628 {
1629 "sloc": 3,
1630 "ploc": 3,
1631 "lloc": 3,
1632 "cloc": 0,
1633 "blank": 0,
1634 "sloc_average": 3.0,
1635 "ploc_average": 3.0,
1636 "lloc_average": 3.0,
1637 "cloc_average": 0.0,
1638 "blank_average": 0.0,
1639 "sloc_min": 3,
1640 "sloc_max": 3,
1641 "cloc_min": 0,
1642 "cloc_max": 0,
1643 "ploc_min": 3,
1644 "ploc_max": 3,
1645 "lloc_min": 3,
1646 "lloc_max": 3,
1647 "blank_min": 0,
1648 "blank_max": 0
1649 }
1650 "#
1651 );
1652 },
1653 );
1654 }
1655
1656 #[test]
1657 fn rust_lloc() {
1658 check_metrics::<RustParser>(
1659 "for x in 0..42 {
1660 if x % 2 == 0 {
1661 println!(\"{}\", x);
1662 }
1663 }",
1664 "foo.rs",
1665 |metric| {
1666 insta::assert_json_snapshot!(
1668 metric.loc,
1669 @r#"
1670 {
1671 "sloc": 5,
1672 "ploc": 5,
1673 "lloc": 3,
1674 "cloc": 0,
1675 "blank": 0,
1676 "sloc_average": 5.0,
1677 "ploc_average": 5.0,
1678 "lloc_average": 3.0,
1679 "cloc_average": 0.0,
1680 "blank_average": 0.0,
1681 "sloc_min": 5,
1682 "sloc_max": 5,
1683 "cloc_min": 0,
1684 "cloc_max": 0,
1685 "ploc_min": 5,
1686 "ploc_max": 5,
1687 "lloc_min": 3,
1688 "lloc_max": 3,
1689 "blank_min": 0,
1690 "blank_max": 0
1691 }
1692 "#
1693 );
1694 },
1695 );
1696
1697 check_metrics::<RustParser>(
1699 "let a = 42;
1700 if true {
1701 42
1702 } else {
1703 43
1704 };",
1705 "foo.rs",
1706 |metric| {
1707 insta::assert_json_snapshot!(
1709 metric.loc,
1710 @r#"
1711 {
1712 "sloc": 6,
1713 "ploc": 6,
1714 "lloc": 3,
1715 "cloc": 0,
1716 "blank": 0,
1717 "sloc_average": 6.0,
1718 "ploc_average": 6.0,
1719 "lloc_average": 3.0,
1720 "cloc_average": 0.0,
1721 "blank_average": 0.0,
1722 "sloc_min": 6,
1723 "sloc_max": 6,
1724 "cloc_min": 0,
1725 "cloc_max": 0,
1726 "ploc_min": 6,
1727 "ploc_max": 6,
1728 "lloc_min": 3,
1729 "lloc_max": 3,
1730 "blank_min": 0,
1731 "blank_max": 0
1732 }
1733 "#
1734 );
1735 },
1736 );
1737 }
1738
1739 #[test]
1740 fn c_lloc() {
1741 check_metrics::<CParser>(
1742 "for (;;)
1743 break;",
1744 "foo.c",
1745 |metric| {
1746 insta::assert_json_snapshot!(
1748 metric.loc,
1749 @r#"
1750 {
1751 "sloc": 2,
1752 "ploc": 2,
1753 "lloc": 2,
1754 "cloc": 0,
1755 "blank": 0,
1756 "sloc_average": 2.0,
1757 "ploc_average": 2.0,
1758 "lloc_average": 2.0,
1759 "cloc_average": 0.0,
1760 "blank_average": 0.0,
1761 "sloc_min": 2,
1762 "sloc_max": 2,
1763 "cloc_min": 0,
1764 "cloc_max": 0,
1765 "ploc_min": 2,
1766 "ploc_max": 2,
1767 "lloc_min": 2,
1768 "lloc_max": 2,
1769 "blank_min": 0,
1770 "blank_max": 0
1771 }
1772 "#
1773 );
1774 },
1775 );
1776 }
1777
1778 #[test]
1779 fn cpp_lloc() {
1780 check_metrics::<CppParser>(
1781 "nsTArray<xpcGCCallback> callbacks(extraGCCallbacks.Clone());
1782 for (uint32_t i = 0; i < callbacks.Length(); ++i) {
1783 callbacks[i](status);
1784 }",
1785 "foo.cpp",
1786 |metric| {
1787 insta::assert_json_snapshot!(
1790 metric.loc,
1791 @r#"
1792 {
1793 "sloc": 4,
1794 "ploc": 4,
1795 "lloc": 3,
1796 "cloc": 0,
1797 "blank": 0,
1798 "sloc_average": 4.0,
1799 "ploc_average": 4.0,
1800 "lloc_average": 3.0,
1801 "cloc_average": 0.0,
1802 "blank_average": 0.0,
1803 "sloc_min": 4,
1804 "sloc_max": 4,
1805 "cloc_min": 0,
1806 "cloc_max": 0,
1807 "ploc_min": 4,
1808 "ploc_max": 4,
1809 "lloc_min": 3,
1810 "lloc_max": 3,
1811 "blank_min": 0,
1812 "blank_max": 0
1813 }
1814 "#
1815 );
1816 },
1817 );
1818 }
1819
1820 #[test]
1821 fn cpp_return_lloc() {
1822 check_metrics::<CppParser>(
1823 "uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y));
1824 return RgbaColor(pixel_data) == blank_pixel_;",
1825 "foo.cpp",
1826 |metric| {
1827 insta::assert_json_snapshot!(
1830 metric.loc,
1831 @r#"
1832 {
1833 "sloc": 2,
1834 "ploc": 2,
1835 "lloc": 2,
1836 "cloc": 0,
1837 "blank": 0,
1838 "sloc_average": 2.0,
1839 "ploc_average": 2.0,
1840 "lloc_average": 2.0,
1841 "cloc_average": 0.0,
1842 "blank_average": 0.0,
1843 "sloc_min": 2,
1844 "sloc_max": 2,
1845 "cloc_min": 0,
1846 "cloc_max": 0,
1847 "ploc_min": 2,
1848 "ploc_max": 2,
1849 "lloc_min": 2,
1850 "lloc_max": 2,
1851 "blank_min": 0,
1852 "blank_max": 0
1853 }
1854 "#
1855 );
1856 },
1857 );
1858 }
1859
1860 #[test]
1861 fn cpp_for_lloc() {
1862 check_metrics::<CppParser>(
1863 "for (; start != end; ++start) {
1864 const unsigned char idx = *start;
1865 if (idx > 127 || !kValidTokenMap[idx]) return false;
1866 }",
1867 "foo.cpp",
1868 |metric| {
1869 insta::assert_json_snapshot!(
1872 metric.loc,
1873 @r#"
1874 {
1875 "sloc": 4,
1876 "ploc": 4,
1877 "lloc": 4,
1878 "cloc": 0,
1879 "blank": 0,
1880 "sloc_average": 4.0,
1881 "ploc_average": 4.0,
1882 "lloc_average": 4.0,
1883 "cloc_average": 0.0,
1884 "blank_average": 0.0,
1885 "sloc_min": 4,
1886 "sloc_max": 4,
1887 "cloc_min": 0,
1888 "cloc_max": 0,
1889 "ploc_min": 4,
1890 "ploc_max": 4,
1891 "lloc_min": 4,
1892 "lloc_max": 4,
1893 "blank_min": 0,
1894 "blank_max": 0
1895 }
1896 "#
1897 );
1898 },
1899 );
1900 }
1901
1902 #[test]
1903 fn cpp_while_lloc() {
1904 check_metrics::<CppParser>(
1905 "while (sHeapAtoms) {
1906 HttpHeapAtom* next = sHeapAtoms->next;
1907 free(sHeapAtoms);
1908 }",
1909 "foo.cpp",
1910 |metric| {
1911 insta::assert_json_snapshot!(
1914 metric.loc,
1915 @r#"
1916 {
1917 "sloc": 4,
1918 "ploc": 4,
1919 "lloc": 3,
1920 "cloc": 0,
1921 "blank": 0,
1922 "sloc_average": 4.0,
1923 "ploc_average": 4.0,
1924 "lloc_average": 3.0,
1925 "cloc_average": 0.0,
1926 "blank_average": 0.0,
1927 "sloc_min": 4,
1928 "sloc_max": 4,
1929 "cloc_min": 0,
1930 "cloc_max": 0,
1931 "ploc_min": 4,
1932 "ploc_max": 4,
1933 "lloc_min": 3,
1934 "lloc_max": 3,
1935 "blank_min": 0,
1936 "blank_max": 0
1937 }
1938 "#
1939 );
1940 },
1941 );
1942 }
1943
1944 #[test]
1945 fn python_string_on_new_line() {
1946 check_metrics::<PythonParser>(
1948 "capabilities[\"goog:chromeOptions\"][\"androidPackage\"] = \\
1949 \"org.chromium.weblayer.shell\"",
1950 "foo.py",
1951 |metric| {
1952 insta::assert_json_snapshot!(
1954 metric.loc,
1955 @r#"
1956 {
1957 "sloc": 2,
1958 "ploc": 2,
1959 "lloc": 1,
1960 "cloc": 0,
1961 "blank": 0,
1962 "sloc_average": 2.0,
1963 "ploc_average": 2.0,
1964 "lloc_average": 1.0,
1965 "cloc_average": 0.0,
1966 "blank_average": 0.0,
1967 "sloc_min": 2,
1968 "sloc_max": 2,
1969 "cloc_min": 0,
1970 "cloc_max": 0,
1971 "ploc_min": 2,
1972 "ploc_max": 2,
1973 "lloc_min": 1,
1974 "lloc_max": 1,
1975 "blank_min": 0,
1976 "blank_max": 0
1977 }
1978 "#
1979 );
1980 },
1981 );
1982 }
1983
1984 #[test]
1985 fn python_multiline_string_assignment_ploc() {
1986 check_metrics::<PythonParser>(
1989 "QUERY = \"\"\"
1990SELECT id, name
1991FROM users
1992WHERE active = 1
1993ORDER BY name
1994\"\"\"",
1995 "foo.py",
1996 |metric| {
1997 assert_eq!(metric.loc.sloc(), 6);
1999 assert_eq!(metric.loc.ploc(), 6);
2000 assert_eq!(metric.loc.cloc(), 0);
2001 assert_eq!(metric.loc.blank(), 0);
2002 insta::assert_json_snapshot!(
2003 metric.loc,
2004 @r#"
2005 {
2006 "sloc": 6,
2007 "ploc": 6,
2008 "lloc": 1,
2009 "cloc": 0,
2010 "blank": 0,
2011 "sloc_average": 6.0,
2012 "ploc_average": 6.0,
2013 "lloc_average": 1.0,
2014 "cloc_average": 0.0,
2015 "blank_average": 0.0,
2016 "sloc_min": 6,
2017 "sloc_max": 6,
2018 "cloc_min": 0,
2019 "cloc_max": 0,
2020 "ploc_min": 6,
2021 "ploc_max": 6,
2022 "lloc_min": 1,
2023 "lloc_max": 1,
2024 "blank_min": 0,
2025 "blank_max": 0
2026 }
2027 "#
2028 );
2029 },
2030 );
2031 }
2032
2033 #[test]
2034 fn python_multiline_string_argument_ploc() {
2035 check_metrics::<PythonParser>(
2038 "print(\"\"\"
2039line one
2040line two
2041\"\"\")",
2042 "foo.py",
2043 |metric| {
2044 assert_eq!(metric.loc.sloc(), 4);
2046 assert_eq!(metric.loc.ploc(), 4);
2047 assert_eq!(metric.loc.cloc(), 0);
2048 assert_eq!(metric.loc.blank(), 0);
2049 },
2050 );
2051 }
2052
2053 #[test]
2054 fn python_single_line_string_assignment_ploc() {
2055 check_metrics::<PythonParser>("QUERY = \"SELECT 1\"", "foo.py", |metric| {
2058 assert_eq!(metric.loc.sloc(), 1);
2060 assert_eq!(metric.loc.ploc(), 1);
2061 assert_eq!(metric.loc.cloc(), 0);
2062 assert_eq!(metric.loc.blank(), 0);
2063 });
2064 }
2065
2066 #[test]
2067 fn python_multiline_docstring_still_cloc() {
2068 check_metrics::<PythonParser>(
2071 "def f():
2072 \"\"\"Docstring line one
2073 Docstring line two
2074 \"\"\"
2075 return 1",
2076 "foo.py",
2077 |metric| {
2078 assert_eq!(metric.loc.cloc(), 3);
2081 assert_eq!(metric.loc.blank(), 0);
2082 },
2083 );
2084 }
2085
2086 #[test]
2087 fn rust_no_field_expression_lloc() {
2088 check_metrics::<RustParser>(
2089 "struct Foo {
2090 field: usize,
2091 }
2092 let foo = Foo { 42 };
2093 foo.field;",
2094 "foo.rs",
2095 |metric| {
2096 insta::assert_json_snapshot!(
2098 metric.loc,
2099 @r#"
2100 {
2101 "sloc": 5,
2102 "ploc": 5,
2103 "lloc": 2,
2104 "cloc": 0,
2105 "blank": 0,
2106 "sloc_average": 5.0,
2107 "ploc_average": 5.0,
2108 "lloc_average": 2.0,
2109 "cloc_average": 0.0,
2110 "blank_average": 0.0,
2111 "sloc_min": 5,
2112 "sloc_max": 5,
2113 "cloc_min": 0,
2114 "cloc_max": 0,
2115 "ploc_min": 5,
2116 "ploc_max": 5,
2117 "lloc_min": 2,
2118 "lloc_max": 2,
2119 "blank_min": 0,
2120 "blank_max": 0
2121 }
2122 "#
2123 );
2124 },
2125 );
2126 }
2127
2128 #[test]
2129 fn rust_no_parenthesized_expression_lloc() {
2130 check_metrics::<RustParser>("let a = (42 + 0);", "foo.rs", |metric| {
2131 insta::assert_json_snapshot!(
2133 metric.loc,
2134 @r#"
2135 {
2136 "sloc": 1,
2137 "ploc": 1,
2138 "lloc": 1,
2139 "cloc": 0,
2140 "blank": 0,
2141 "sloc_average": 1.0,
2142 "ploc_average": 1.0,
2143 "lloc_average": 1.0,
2144 "cloc_average": 0.0,
2145 "blank_average": 0.0,
2146 "sloc_min": 1,
2147 "sloc_max": 1,
2148 "cloc_min": 0,
2149 "cloc_max": 0,
2150 "ploc_min": 1,
2151 "ploc_max": 1,
2152 "lloc_min": 1,
2153 "lloc_max": 1,
2154 "blank_min": 0,
2155 "blank_max": 0
2156 }
2157 "#
2158 );
2159 });
2160 }
2161
2162 #[test]
2163 fn rust_no_array_expression_lloc() {
2164 check_metrics::<RustParser>("let a = [0; 42];", "foo.rs", |metric| {
2165 insta::assert_json_snapshot!(
2167 metric.loc,
2168 @r#"
2169 {
2170 "sloc": 1,
2171 "ploc": 1,
2172 "lloc": 1,
2173 "cloc": 0,
2174 "blank": 0,
2175 "sloc_average": 1.0,
2176 "ploc_average": 1.0,
2177 "lloc_average": 1.0,
2178 "cloc_average": 0.0,
2179 "blank_average": 0.0,
2180 "sloc_min": 1,
2181 "sloc_max": 1,
2182 "cloc_min": 0,
2183 "cloc_max": 0,
2184 "ploc_min": 1,
2185 "ploc_max": 1,
2186 "lloc_min": 1,
2187 "lloc_max": 1,
2188 "blank_min": 0,
2189 "blank_max": 0
2190 }
2191 "#
2192 );
2193 });
2194 }
2195
2196 #[test]
2197 fn rust_no_tuple_expression_lloc() {
2198 check_metrics::<RustParser>("let a = (0, 42);", "foo.rs", |metric| {
2199 insta::assert_json_snapshot!(
2201 metric.loc,
2202 @r#"
2203 {
2204 "sloc": 1,
2205 "ploc": 1,
2206 "lloc": 1,
2207 "cloc": 0,
2208 "blank": 0,
2209 "sloc_average": 1.0,
2210 "ploc_average": 1.0,
2211 "lloc_average": 1.0,
2212 "cloc_average": 0.0,
2213 "blank_average": 0.0,
2214 "sloc_min": 1,
2215 "sloc_max": 1,
2216 "cloc_min": 0,
2217 "cloc_max": 0,
2218 "ploc_min": 1,
2219 "ploc_max": 1,
2220 "lloc_min": 1,
2221 "lloc_max": 1,
2222 "blank_min": 0,
2223 "blank_max": 0
2224 }
2225 "#
2226 );
2227 });
2228 }
2229
2230 #[test]
2231 fn rust_no_unit_expression_lloc() {
2232 check_metrics::<RustParser>("let a = ();", "foo.rs", |metric| {
2233 insta::assert_json_snapshot!(
2235 metric.loc,
2236 @r#"
2237 {
2238 "sloc": 1,
2239 "ploc": 1,
2240 "lloc": 1,
2241 "cloc": 0,
2242 "blank": 0,
2243 "sloc_average": 1.0,
2244 "ploc_average": 1.0,
2245 "lloc_average": 1.0,
2246 "cloc_average": 0.0,
2247 "blank_average": 0.0,
2248 "sloc_min": 1,
2249 "sloc_max": 1,
2250 "cloc_min": 0,
2251 "cloc_max": 0,
2252 "ploc_min": 1,
2253 "ploc_max": 1,
2254 "lloc_min": 1,
2255 "lloc_max": 1,
2256 "blank_min": 0,
2257 "blank_max": 0
2258 }
2259 "#
2260 );
2261 });
2262 }
2263
2264 #[test]
2265 fn rust_call_function_lloc() {
2266 check_metrics::<RustParser>(
2267 "let a = foo(); // +1
2268 foo(); // +1
2269 k!(foo()); // +1",
2270 "foo.rs",
2271 |metric| {
2272 insta::assert_json_snapshot!(
2274 metric.loc,
2275 @r#"
2276 {
2277 "sloc": 3,
2278 "ploc": 3,
2279 "lloc": 3,
2280 "cloc": 3,
2281 "blank": 0,
2282 "sloc_average": 3.0,
2283 "ploc_average": 3.0,
2284 "lloc_average": 3.0,
2285 "cloc_average": 3.0,
2286 "blank_average": 0.0,
2287 "sloc_min": 3,
2288 "sloc_max": 3,
2289 "cloc_min": 3,
2290 "cloc_max": 3,
2291 "ploc_min": 3,
2292 "ploc_max": 3,
2293 "lloc_min": 3,
2294 "lloc_max": 3,
2295 "blank_min": 0,
2296 "blank_max": 0
2297 }
2298 "#
2299 );
2300 },
2301 );
2302 }
2303
2304 #[test]
2305 fn rust_macro_invocation_lloc() {
2306 check_metrics::<RustParser>(
2307 "let a = foo!(); // +1
2308 foo!(); // +1
2309 k(foo!()); // +1",
2310 "foo.rs",
2311 |metric| {
2312 insta::assert_json_snapshot!(
2314 metric.loc,
2315 @r#"
2316 {
2317 "sloc": 3,
2318 "ploc": 3,
2319 "lloc": 3,
2320 "cloc": 3,
2321 "blank": 0,
2322 "sloc_average": 3.0,
2323 "ploc_average": 3.0,
2324 "lloc_average": 3.0,
2325 "cloc_average": 3.0,
2326 "blank_average": 0.0,
2327 "sloc_min": 3,
2328 "sloc_max": 3,
2329 "cloc_min": 3,
2330 "cloc_max": 3,
2331 "ploc_min": 3,
2332 "ploc_max": 3,
2333 "lloc_min": 3,
2334 "lloc_max": 3,
2335 "blank_min": 0,
2336 "blank_max": 0
2337 }
2338 "#
2339 );
2340 },
2341 );
2342 }
2343
2344 #[test]
2345 fn rust_function_in_loop_lloc() {
2346 check_metrics::<RustParser>(
2347 "for (a, b) in c.iter().enumerate() {} // +1
2348 while (a, b) in c.iter().enumerate() {} // +1
2349 while let Some(a) = c.strip_prefix(\"hi\") {} // +1",
2350 "foo.rs",
2351 |metric| {
2352 insta::assert_json_snapshot!(
2354 metric.loc,
2355 @r#"
2356 {
2357 "sloc": 3,
2358 "ploc": 3,
2359 "lloc": 3,
2360 "cloc": 3,
2361 "blank": 0,
2362 "sloc_average": 3.0,
2363 "ploc_average": 3.0,
2364 "lloc_average": 3.0,
2365 "cloc_average": 3.0,
2366 "blank_average": 0.0,
2367 "sloc_min": 3,
2368 "sloc_max": 3,
2369 "cloc_min": 3,
2370 "cloc_max": 3,
2371 "ploc_min": 3,
2372 "ploc_max": 3,
2373 "lloc_min": 3,
2374 "lloc_max": 3,
2375 "blank_min": 0,
2376 "blank_max": 0
2377 }
2378 "#
2379 );
2380 },
2381 );
2382 }
2383
2384 #[test]
2385 fn rust_function_in_if_lloc() {
2386 check_metrics::<RustParser>(
2387 "if foo() {} // +1
2388 if let Some(a) = foo() {} // +1",
2389 "foo.rs",
2390 |metric| {
2391 insta::assert_json_snapshot!(
2393 metric.loc,
2394 @r#"
2395 {
2396 "sloc": 2,
2397 "ploc": 2,
2398 "lloc": 2,
2399 "cloc": 2,
2400 "blank": 0,
2401 "sloc_average": 2.0,
2402 "ploc_average": 2.0,
2403 "lloc_average": 2.0,
2404 "cloc_average": 2.0,
2405 "blank_average": 0.0,
2406 "sloc_min": 2,
2407 "sloc_max": 2,
2408 "cloc_min": 2,
2409 "cloc_max": 2,
2410 "ploc_min": 2,
2411 "ploc_max": 2,
2412 "lloc_min": 2,
2413 "lloc_max": 2,
2414 "blank_min": 0,
2415 "blank_max": 0
2416 }
2417 "#
2418 );
2419 },
2420 );
2421 }
2422
2423 #[test]
2424 fn rust_function_in_return_lloc() {
2425 check_metrics::<RustParser>(
2426 "return foo();
2427 await foo();",
2428 "foo.rs",
2429 |metric| {
2430 insta::assert_json_snapshot!(
2432 metric.loc,
2433 @r#"
2434 {
2435 "sloc": 2,
2436 "ploc": 2,
2437 "lloc": 2,
2438 "cloc": 0,
2439 "blank": 0,
2440 "sloc_average": 2.0,
2441 "ploc_average": 2.0,
2442 "lloc_average": 2.0,
2443 "cloc_average": 0.0,
2444 "blank_average": 0.0,
2445 "sloc_min": 2,
2446 "sloc_max": 2,
2447 "cloc_min": 0,
2448 "cloc_max": 0,
2449 "ploc_min": 2,
2450 "ploc_max": 2,
2451 "lloc_min": 2,
2452 "lloc_max": 2,
2453 "blank_min": 0,
2454 "blank_max": 0
2455 }
2456 "#
2457 );
2458 },
2459 );
2460 }
2461
2462 #[test]
2463 fn rust_closure_expression_lloc() {
2464 check_metrics::<RustParser>(
2465 "let a = |i: i32| -> i32 { i + 1 }; // +1
2466 a(42); // +1
2467 k(b.iter().map(|n| n.parse.ok().unwrap_or(42))); // +1",
2468 "foo.rs",
2469 |metric| {
2470 insta::assert_json_snapshot!(
2472 metric.loc,
2473 @r#"
2474 {
2475 "sloc": 3,
2476 "ploc": 3,
2477 "lloc": 3,
2478 "cloc": 3,
2479 "blank": 0,
2480 "sloc_average": 1.0,
2481 "ploc_average": 1.0,
2482 "lloc_average": 1.0,
2483 "cloc_average": 1.0,
2484 "blank_average": 0.0,
2485 "sloc_min": 1,
2486 "sloc_max": 3,
2487 "cloc_min": 0,
2488 "cloc_max": 3,
2489 "ploc_min": 1,
2490 "ploc_max": 3,
2491 "lloc_min": 0,
2492 "lloc_max": 3,
2493 "blank_min": 0,
2494 "blank_max": 0
2495 }
2496 "#
2497 );
2498 },
2499 );
2500 }
2501
2502 #[test]
2503 fn python_general_loc() {
2504 check_metrics::<PythonParser>(
2505 "def func(a,
2506 b,
2507 c):
2508 print(a)
2509 print(b)
2510 print(c)",
2511 "foo.py",
2512 |metric| {
2513 insta::assert_json_snapshot!(
2515 metric.loc,
2516 @r#"
2517 {
2518 "sloc": 6,
2519 "ploc": 6,
2520 "lloc": 3,
2521 "cloc": 0,
2522 "blank": 0,
2523 "sloc_average": 3.0,
2524 "ploc_average": 3.0,
2525 "lloc_average": 1.5,
2526 "cloc_average": 0.0,
2527 "blank_average": 0.0,
2528 "sloc_min": 6,
2529 "sloc_max": 6,
2530 "cloc_min": 0,
2531 "cloc_max": 0,
2532 "ploc_min": 6,
2533 "ploc_max": 6,
2534 "lloc_min": 3,
2535 "lloc_max": 3,
2536 "blank_min": 0,
2537 "blank_max": 0
2538 }
2539 "#
2540 );
2541 },
2542 );
2543 }
2544
2545 #[test]
2546 fn python_real_loc() {
2547 check_metrics::<PythonParser>(
2548 "def web_socket_transfer_data(request):
2549 while True:
2550 line = request.ws_stream.receive_message()
2551 if line is None:
2552 return
2553 code, reason = line.split(' ', 1)
2554 if code is None or reason is None:
2555 return
2556 request.ws_stream.close_connection(int(code), reason)
2557 # close_connection() initiates closing handshake. It validates code
2558 # and reason. If you want to send a broken close frame for a test,
2559 # following code will be useful.
2560 # > data = struct.pack('!H', int(code)) + reason.encode('UTF-8')
2561 # > request.connection.write(stream.create_close_frame(data))
2562 # > # Suppress to re-respond client responding close frame.
2563 # > raise Exception(\"customized server initiated closing handshake\")",
2564 "foo.py",
2565 |metric| {
2566 insta::assert_json_snapshot!(
2568 metric.loc,
2569 @r#"
2570 {
2571 "sloc": 16,
2572 "ploc": 9,
2573 "lloc": 8,
2574 "cloc": 7,
2575 "blank": 0,
2576 "sloc_average": 8.0,
2577 "ploc_average": 4.5,
2578 "lloc_average": 4.0,
2579 "cloc_average": 3.5,
2580 "blank_average": 0.0,
2581 "sloc_min": 16,
2582 "sloc_max": 16,
2583 "cloc_min": 7,
2584 "cloc_max": 7,
2585 "ploc_min": 9,
2586 "ploc_max": 9,
2587 "lloc_min": 8,
2588 "lloc_max": 8,
2589 "blank_min": 0,
2590 "blank_max": 0
2591 }
2592 "#
2593 );
2594 },
2595 );
2596 }
2597
2598 #[test]
2599 fn javascript_real_loc() {
2600 check_metrics::<JavascriptParser>(
2601 "assert.throws(Test262Error, function() {
2602 for (let { poisoned: x = ++initEvalCount } = poisonedProperty; ; ) {
2603 return;
2604 }
2605 });",
2606 "foo.js",
2607 |metric| {
2608 insta::assert_json_snapshot!(
2610 metric.loc,
2611 @r#"
2612 {
2613 "sloc": 5,
2614 "ploc": 5,
2615 "lloc": 4,
2616 "cloc": 0,
2617 "blank": 0,
2618 "sloc_average": 2.5,
2619 "ploc_average": 2.5,
2620 "lloc_average": 2.0,
2621 "cloc_average": 0.0,
2622 "blank_average": 0.0,
2623 "sloc_min": 5,
2624 "sloc_max": 5,
2625 "cloc_min": 0,
2626 "cloc_max": 0,
2627 "ploc_min": 5,
2628 "ploc_max": 5,
2629 "lloc_min": 3,
2630 "lloc_max": 4,
2631 "blank_min": 0,
2632 "blank_max": 0
2633 }
2634 "#
2635 );
2636 },
2637 );
2638 }
2639
2640 #[test]
2641 fn mozjs_real_loc() {
2642 check_metrics::<MozjsParser>(
2643 "assert.throws(Test262Error, function() {
2644 for (let { poisoned: x = ++initEvalCount } = poisonedProperty; ; ) {
2645 return;
2646 }
2647 });",
2648 "foo.js",
2649 |metric| {
2650 insta::assert_json_snapshot!(
2652 metric.loc,
2653 @r#"
2654 {
2655 "sloc": 5,
2656 "ploc": 5,
2657 "lloc": 4,
2658 "cloc": 0,
2659 "blank": 0,
2660 "sloc_average": 2.5,
2661 "ploc_average": 2.5,
2662 "lloc_average": 2.0,
2663 "cloc_average": 0.0,
2664 "blank_average": 0.0,
2665 "sloc_min": 5,
2666 "sloc_max": 5,
2667 "cloc_min": 0,
2668 "cloc_max": 0,
2669 "ploc_min": 5,
2670 "ploc_max": 5,
2671 "lloc_min": 3,
2672 "lloc_max": 4,
2673 "blank_min": 0,
2674 "blank_max": 0
2675 }
2676 "#
2677 );
2678 },
2679 );
2680 }
2681
2682 #[test]
2683 fn mozjs_blank_and_comment_loc() {
2684 check_metrics::<MozjsParser>(
2685 "// a comment
2686 function f() {
2687
2688 var x = 1;
2689
2690 }",
2691 "foo.js",
2692 |metric| {
2693 insta::assert_json_snapshot!(
2694 metric.loc,
2695 @r#"
2696 {
2697 "sloc": 6,
2698 "ploc": 3,
2699 "lloc": 0,
2700 "cloc": 1,
2701 "blank": 2,
2702 "sloc_average": 3.0,
2703 "ploc_average": 1.5,
2704 "lloc_average": 0.0,
2705 "cloc_average": 0.5,
2706 "blank_average": 1.0,
2707 "sloc_min": 5,
2708 "sloc_max": 6,
2709 "cloc_min": 0,
2710 "cloc_max": 1,
2711 "ploc_min": 3,
2712 "ploc_max": 3,
2713 "lloc_min": 0,
2714 "lloc_max": 0,
2715 "blank_min": 2,
2716 "blank_max": 2
2717 }
2718 "#
2719 );
2720 },
2721 );
2722 }
2723
2724 #[test]
2725 fn cpp_namespace_loc() {
2726 check_metrics::<CppParser>(
2727 "namespace mozilla::dom::quota {} // namespace mozilla::dom::quota",
2728 "foo.cpp",
2729 |metric| {
2730 insta::assert_json_snapshot!(
2732 metric.loc,
2733 @r#"
2734 {
2735 "sloc": 1,
2736 "ploc": 1,
2737 "lloc": 0,
2738 "cloc": 1,
2739 "blank": 0,
2740 "sloc_average": 0.5,
2741 "ploc_average": 0.5,
2742 "lloc_average": 0.0,
2743 "cloc_average": 0.5,
2744 "blank_average": 0.0,
2745 "sloc_min": 1,
2746 "sloc_max": 1,
2747 "cloc_min": 0,
2748 "cloc_max": 1,
2749 "ploc_min": 1,
2750 "ploc_max": 1,
2751 "lloc_min": 0,
2752 "lloc_max": 0,
2753 "blank_min": 0,
2754 "blank_max": 0
2755 }
2756 "#
2757 );
2758 },
2759 );
2760 }
2761
2762 #[test]
2763 fn java_comments() {
2764 check_metrics::<JavaParser>(
2765 "for (int i = 0; i < 100; i++) { \
2766 // Print hello
2767 System.out.println(\"hello\"); \
2768 // Print world
2769 System.out.println(\"hello\"); \
2770 }",
2771 "foo.java",
2772 |metric| {
2773 insta::assert_json_snapshot!(
2775 metric.loc,
2776 @r#"
2777 {
2778 "sloc": 3,
2779 "ploc": 3,
2780 "lloc": 3,
2781 "cloc": 2,
2782 "blank": 0,
2783 "sloc_average": 3.0,
2784 "ploc_average": 3.0,
2785 "lloc_average": 3.0,
2786 "cloc_average": 2.0,
2787 "blank_average": 0.0,
2788 "sloc_min": 3,
2789 "sloc_max": 3,
2790 "cloc_min": 2,
2791 "cloc_max": 2,
2792 "ploc_min": 3,
2793 "ploc_max": 3,
2794 "lloc_min": 3,
2795 "lloc_max": 3,
2796 "blank_min": 0,
2797 "blank_max": 0
2798 }
2799 "#
2800 );
2801 },
2802 );
2803 }
2804
2805 #[test]
2806 fn java_blank() {
2807 check_metrics::<JavaParser>(
2808 "int x = 1;
2809
2810
2811 int y = 2;",
2812 "foo.java",
2813 |metric| {
2814 insta::assert_json_snapshot!(
2816 metric.loc,
2817 @r#"
2818 {
2819 "sloc": 4,
2820 "ploc": 2,
2821 "lloc": 2,
2822 "cloc": 0,
2823 "blank": 2,
2824 "sloc_average": 4.0,
2825 "ploc_average": 2.0,
2826 "lloc_average": 2.0,
2827 "cloc_average": 0.0,
2828 "blank_average": 2.0,
2829 "sloc_min": 4,
2830 "sloc_max": 4,
2831 "cloc_min": 0,
2832 "cloc_max": 0,
2833 "ploc_min": 2,
2834 "ploc_max": 2,
2835 "lloc_min": 2,
2836 "lloc_max": 2,
2837 "blank_min": 2,
2838 "blank_max": 2
2839 }
2840 "#
2841 );
2842 },
2843 );
2844 }
2845
2846 #[test]
2847 fn java_sloc() {
2848 check_metrics::<JavaParser>(
2849 "for (int i = 0; i < 100; i++) {
2850 System.out.println(i);
2851 }",
2852 "foo.java",
2853 |metric| {
2854 insta::assert_json_snapshot!(
2856 metric.loc,
2857 @r#"
2858 {
2859 "sloc": 3,
2860 "ploc": 3,
2861 "lloc": 2,
2862 "cloc": 0,
2863 "blank": 0,
2864 "sloc_average": 3.0,
2865 "ploc_average": 3.0,
2866 "lloc_average": 2.0,
2867 "cloc_average": 0.0,
2868 "blank_average": 0.0,
2869 "sloc_min": 3,
2870 "sloc_max": 3,
2871 "cloc_min": 0,
2872 "cloc_max": 0,
2873 "ploc_min": 3,
2874 "ploc_max": 3,
2875 "lloc_min": 2,
2876 "lloc_max": 2,
2877 "blank_min": 0,
2878 "blank_max": 0
2879 }
2880 "#
2881 );
2882 },
2883 );
2884 }
2885
2886 #[test]
2887 fn java_module_sloc() {
2888 check_metrics::<JavaParser>(
2889 "module helloworld{
2890 exports com.test;
2891 }",
2892 "foo.java",
2893 |metric| {
2894 insta::assert_json_snapshot!(
2896 metric.loc,
2897 @r#"
2898 {
2899 "sloc": 3,
2900 "ploc": 3,
2901 "lloc": 0,
2902 "cloc": 0,
2903 "blank": 0,
2904 "sloc_average": 3.0,
2905 "ploc_average": 3.0,
2906 "lloc_average": 0.0,
2907 "cloc_average": 0.0,
2908 "blank_average": 0.0,
2909 "sloc_min": 3,
2910 "sloc_max": 3,
2911 "cloc_min": 0,
2912 "cloc_max": 0,
2913 "ploc_min": 3,
2914 "ploc_max": 3,
2915 "lloc_min": 0,
2916 "lloc_max": 0,
2917 "blank_min": 0,
2918 "blank_max": 0
2919 }
2920 "#
2921 );
2922 },
2923 );
2924 }
2925
2926 #[test]
2927 fn java_single_ploc() {
2928 check_metrics::<JavaParser>("int x = 1;", "foo.java", |metric| {
2929 insta::assert_json_snapshot!(
2931 metric.loc,
2932 @r#"
2933 {
2934 "sloc": 1,
2935 "ploc": 1,
2936 "lloc": 1,
2937 "cloc": 0,
2938 "blank": 0,
2939 "sloc_average": 1.0,
2940 "ploc_average": 1.0,
2941 "lloc_average": 1.0,
2942 "cloc_average": 0.0,
2943 "blank_average": 0.0,
2944 "sloc_min": 1,
2945 "sloc_max": 1,
2946 "cloc_min": 0,
2947 "cloc_max": 0,
2948 "ploc_min": 1,
2949 "ploc_max": 1,
2950 "lloc_min": 1,
2951 "lloc_max": 1,
2952 "blank_min": 0,
2953 "blank_max": 0
2954 }
2955 "#
2956 );
2957 });
2958 }
2959
2960 #[test]
2961 fn java_simple_ploc() {
2962 check_metrics::<JavaParser>(
2963 "for (int i = 0; i < 100; i = i++) {
2964 System.out.println(i);
2965 }",
2966 "foo.java",
2967 |metric| {
2968 insta::assert_json_snapshot!(
2970 metric.loc,
2971 @r#"
2972 {
2973 "sloc": 3,
2974 "ploc": 3,
2975 "lloc": 2,
2976 "cloc": 0,
2977 "blank": 0,
2978 "sloc_average": 3.0,
2979 "ploc_average": 3.0,
2980 "lloc_average": 2.0,
2981 "cloc_average": 0.0,
2982 "blank_average": 0.0,
2983 "sloc_min": 3,
2984 "sloc_max": 3,
2985 "cloc_min": 0,
2986 "cloc_max": 0,
2987 "ploc_min": 3,
2988 "ploc_max": 3,
2989 "lloc_min": 2,
2990 "lloc_max": 2,
2991 "blank_min": 0,
2992 "blank_max": 0
2993 }
2994 "#
2995 );
2996 },
2997 );
2998 }
2999
3000 #[test]
3001 fn java_multi_ploc() {
3002 check_metrics::<JavaParser>(
3003 "int x = 1;
3004 for (int i = 0; i < 100; i++) {
3005 System.out.println(i);
3006 }",
3007 "foo.java",
3008 |metric| {
3009 insta::assert_json_snapshot!(
3011 metric.loc,
3012 @r#"
3013 {
3014 "sloc": 4,
3015 "ploc": 4,
3016 "lloc": 3,
3017 "cloc": 0,
3018 "blank": 0,
3019 "sloc_average": 4.0,
3020 "ploc_average": 4.0,
3021 "lloc_average": 3.0,
3022 "cloc_average": 0.0,
3023 "blank_average": 0.0,
3024 "sloc_min": 4,
3025 "sloc_max": 4,
3026 "cloc_min": 0,
3027 "cloc_max": 0,
3028 "ploc_min": 4,
3029 "ploc_max": 4,
3030 "lloc_min": 3,
3031 "lloc_max": 3,
3032 "blank_min": 0,
3033 "blank_max": 0
3034 }
3035 "#
3036 );
3037 },
3038 );
3039 }
3040
3041 #[test]
3042 fn java_single_statement_lloc() {
3043 check_metrics::<JavaParser>("int max = 10;", "foo.java", |metric| {
3044 insta::assert_json_snapshot!(
3046 metric.loc,
3047 @r#"
3048 {
3049 "sloc": 1,
3050 "ploc": 1,
3051 "lloc": 1,
3052 "cloc": 0,
3053 "blank": 0,
3054 "sloc_average": 1.0,
3055 "ploc_average": 1.0,
3056 "lloc_average": 1.0,
3057 "cloc_average": 0.0,
3058 "blank_average": 0.0,
3059 "sloc_min": 1,
3060 "sloc_max": 1,
3061 "cloc_min": 0,
3062 "cloc_max": 0,
3063 "ploc_min": 1,
3064 "ploc_max": 1,
3065 "lloc_min": 1,
3066 "lloc_max": 1,
3067 "blank_min": 0,
3068 "blank_max": 0
3069 }
3070 "#
3071 );
3072 });
3073 }
3074
3075 #[test]
3076 fn java_for_lloc() {
3077 check_metrics::<JavaParser>(
3078 "for (int i = 0; i < 100; i++) { // + 1
3079 System.out.println(i); // + 1
3080 }",
3081 "foo.java",
3082 |metric| {
3083 insta::assert_json_snapshot!(
3085 metric.loc,
3086 @r#"
3087 {
3088 "sloc": 3,
3089 "ploc": 3,
3090 "lloc": 2,
3091 "cloc": 2,
3092 "blank": 0,
3093 "sloc_average": 3.0,
3094 "ploc_average": 3.0,
3095 "lloc_average": 2.0,
3096 "cloc_average": 2.0,
3097 "blank_average": 0.0,
3098 "sloc_min": 3,
3099 "sloc_max": 3,
3100 "cloc_min": 2,
3101 "cloc_max": 2,
3102 "ploc_min": 3,
3103 "ploc_max": 3,
3104 "lloc_min": 2,
3105 "lloc_max": 2,
3106 "blank_min": 0,
3107 "blank_max": 0
3108 }
3109 "#
3110 );
3111 },
3112 );
3113 }
3114
3115 #[test]
3116 fn java_foreach_lloc() {
3117 check_metrics::<JavaParser>(
3118 "
3119 int arr[]={12,13,14,44}; // +1
3120 for (int i:arr) { // +1
3121 System.out.println(i); // +1
3122 }",
3123 "foo.java",
3124 |metric| {
3125 insta::assert_json_snapshot!(
3127 metric.loc,
3128 @r#"
3129 {
3130 "sloc": 4,
3131 "ploc": 4,
3132 "lloc": 3,
3133 "cloc": 3,
3134 "blank": 0,
3135 "sloc_average": 4.0,
3136 "ploc_average": 4.0,
3137 "lloc_average": 3.0,
3138 "cloc_average": 3.0,
3139 "blank_average": 0.0,
3140 "sloc_min": 4,
3141 "sloc_max": 4,
3142 "cloc_min": 3,
3143 "cloc_max": 3,
3144 "ploc_min": 4,
3145 "ploc_max": 4,
3146 "lloc_min": 3,
3147 "lloc_max": 3,
3148 "blank_min": 0,
3149 "blank_max": 0
3150 }
3151 "#
3152 );
3153 },
3154 );
3155 }
3156
3157 #[test]
3158 fn java_while_lloc() {
3159 check_metrics::<JavaParser>(
3160 "
3161 int i=0; // +1
3162 while(i < 10) { // +1
3163 i++; // +1
3164 System.out.println(i); // +1
3165 }",
3166 "foo.java",
3167 |metric| {
3168 insta::assert_json_snapshot!(
3170 metric.loc,
3171 @r#"
3172 {
3173 "sloc": 5,
3174 "ploc": 5,
3175 "lloc": 4,
3176 "cloc": 4,
3177 "blank": 0,
3178 "sloc_average": 5.0,
3179 "ploc_average": 5.0,
3180 "lloc_average": 4.0,
3181 "cloc_average": 4.0,
3182 "blank_average": 0.0,
3183 "sloc_min": 5,
3184 "sloc_max": 5,
3185 "cloc_min": 4,
3186 "cloc_max": 4,
3187 "ploc_min": 5,
3188 "ploc_max": 5,
3189 "lloc_min": 4,
3190 "lloc_max": 4,
3191 "blank_min": 0,
3192 "blank_max": 0
3193 }
3194 "#
3195 );
3196 },
3197 );
3198 }
3199
3200 #[test]
3201 fn java_do_while_lloc() {
3202 check_metrics::<JavaParser>(
3203 "
3204 int i=0; // +1
3205 do { // +1
3206 i++; // +1
3207 System.out.println(i); // +1
3208 } while(i < 10)",
3209 "foo.java",
3210 |metric| {
3211 insta::assert_json_snapshot!(
3213 metric.loc,
3214 @r#"
3215 {
3216 "sloc": 5,
3217 "ploc": 5,
3218 "lloc": 4,
3219 "cloc": 4,
3220 "blank": 0,
3221 "sloc_average": 5.0,
3222 "ploc_average": 5.0,
3223 "lloc_average": 4.0,
3224 "cloc_average": 4.0,
3225 "blank_average": 0.0,
3226 "sloc_min": 5,
3227 "sloc_max": 5,
3228 "cloc_min": 4,
3229 "cloc_max": 4,
3230 "ploc_min": 5,
3231 "ploc_max": 5,
3232 "lloc_min": 4,
3233 "lloc_max": 4,
3234 "blank_min": 0,
3235 "blank_max": 0
3236 }
3237 "#
3238 );
3239 },
3240 );
3241 }
3242
3243 #[test]
3244 fn java_switch_lloc() {
3245 check_metrics::<JavaParser>(
3246 "switch(grade) { // +1
3247 case 'A' :
3248 System.out.println(\"Pass with distinction\"); // +1
3249 break; // +1
3250 case 'B' :
3251 case 'C' :
3252 System.out.println(\"Pass\"); // +1
3253 break; // +1
3254 case 'D' :
3255 System.out.println(\"At risk\"); // +1
3256 case 'F' :
3257 System.out.println(\"Fail\"); // +1
3258 break; // +1
3259 default :
3260 System.out.println(\"Invalid grade\"); // +1
3261 }",
3262 "foo.java",
3263 |metric| {
3264 insta::assert_json_snapshot!(
3266 metric.loc,
3267 @r#"
3268 {
3269 "sloc": 16,
3270 "ploc": 16,
3271 "lloc": 9,
3272 "cloc": 9,
3273 "blank": 0,
3274 "sloc_average": 16.0,
3275 "ploc_average": 16.0,
3276 "lloc_average": 9.0,
3277 "cloc_average": 9.0,
3278 "blank_average": 0.0,
3279 "sloc_min": 16,
3280 "sloc_max": 16,
3281 "cloc_min": 9,
3282 "cloc_max": 9,
3283 "ploc_min": 16,
3284 "ploc_max": 16,
3285 "lloc_min": 9,
3286 "lloc_max": 9,
3287 "blank_min": 0,
3288 "blank_max": 0
3289 }
3290 "#
3291 );
3292 },
3293 );
3294 }
3295
3296 #[test]
3297 fn java_continue_lloc() {
3298 check_metrics::<JavaParser>(
3299 "int max = 10; // +1
3300
3301 for (int i = 0; i < max; i++) { // +1
3302 if(i % 2 == 0) { continue;} + 2
3303 System.out.println(i); // +1
3304 }",
3305 "foo.java",
3306 |metric| {
3307 insta::assert_json_snapshot!(
3309 metric.loc,
3310 @r#"
3311 {
3312 "sloc": 6,
3313 "ploc": 5,
3314 "lloc": 5,
3315 "cloc": 3,
3316 "blank": 1,
3317 "sloc_average": 6.0,
3318 "ploc_average": 5.0,
3319 "lloc_average": 5.0,
3320 "cloc_average": 3.0,
3321 "blank_average": 1.0,
3322 "sloc_min": 6,
3323 "sloc_max": 6,
3324 "cloc_min": 3,
3325 "cloc_max": 3,
3326 "ploc_min": 5,
3327 "ploc_max": 5,
3328 "lloc_min": 5,
3329 "lloc_max": 5,
3330 "blank_min": 1,
3331 "blank_max": 1
3332 }
3333 "#
3334 );
3335 },
3336 );
3337 }
3338
3339 #[test]
3340 fn java_try_lloc() {
3341 check_metrics::<JavaParser>(
3342 "try { // +1
3343 int[] myNumbers = {1, 2, 3}; // +1
3344 System.out.println(myNumbers[10]); // +1
3345 } catch (Exception e) {
3346 System.out.println(e.getMessage()); // +1
3347 throw e; // +1
3348 }",
3349 "foo.java",
3350 |metric| {
3351 insta::assert_json_snapshot!(
3353 metric.loc,
3354 @r#"
3355 {
3356 "sloc": 7,
3357 "ploc": 7,
3358 "lloc": 5,
3359 "cloc": 5,
3360 "blank": 0,
3361 "sloc_average": 7.0,
3362 "ploc_average": 7.0,
3363 "lloc_average": 5.0,
3364 "cloc_average": 5.0,
3365 "blank_average": 0.0,
3366 "sloc_min": 7,
3367 "sloc_max": 7,
3368 "cloc_min": 5,
3369 "cloc_max": 5,
3370 "ploc_min": 7,
3371 "ploc_max": 7,
3372 "lloc_min": 5,
3373 "lloc_max": 5,
3374 "blank_min": 0,
3375 "blank_max": 0
3376 }
3377 "#
3378 );
3379 },
3380 );
3381 }
3382
3383 #[test]
3384 fn java_class_loc() {
3385 check_metrics::<JavaParser>(
3386 "
3387 public class Person {
3388 private String name;
3389 public Person(String name){
3390 this.name = name; // +1
3391 }
3392 public String getName() {
3393 return name; // +1
3394 }
3395 }",
3396 "foo.java",
3397 |metric| {
3398 insta::assert_json_snapshot!(
3400 metric.loc,
3401 @r#"
3402 {
3403 "sloc": 9,
3404 "ploc": 9,
3405 "lloc": 2,
3406 "cloc": 2,
3407 "blank": 0,
3408 "sloc_average": 2.25,
3409 "ploc_average": 2.25,
3410 "lloc_average": 0.5,
3411 "cloc_average": 0.5,
3412 "blank_average": 0.0,
3413 "sloc_min": 3,
3414 "sloc_max": 9,
3415 "cloc_min": 1,
3416 "cloc_max": 2,
3417 "ploc_min": 3,
3418 "ploc_max": 9,
3419 "lloc_min": 1,
3420 "lloc_max": 2,
3421 "blank_min": 0,
3422 "blank_max": 0
3423 }
3424 "#
3425 );
3426 },
3427 );
3428 }
3429
3430 #[test]
3431 fn java_expressions_lloc() {
3432 check_metrics::<JavaParser>(
3433 "int x = 10; // +1 local var declaration
3434 x=+89; // +1 expression statement
3435 int y = x * 2; // +1 local var declaration
3436 IntFunction double = (n) -> n*2; // +1 local var declaration
3437 int y2 = double(x); // +1 local var declaration
3438 System.out.println(\"double \" + x + \" = \" + y2); // +1 expression statement
3439 String message = (x % 2) == 0 ? \"Evenly done.\" : \"Oddly done.\"; // +1 local var declaration
3440 Object done = (Runnable) () -> { System.out.println(\"Done!\"); }; // +2 local var declaration + expression statement
3441 String s = \"string\"; // +1 local var declaration
3442 boolean isS = (s instanceof String); // +1 local var declaration
3443 done.run(); // +1 expression statement
3444 ",
3445 "foo.java",
3446 |metric| {
3447 insta::assert_json_snapshot!(
3449 metric.loc,
3450 @r#"
3451 {
3452 "sloc": 11,
3453 "ploc": 11,
3454 "lloc": 12,
3455 "cloc": 11,
3456 "blank": 0,
3457 "sloc_average": 11.0,
3458 "ploc_average": 11.0,
3459 "lloc_average": 12.0,
3460 "cloc_average": 11.0,
3461 "blank_average": 0.0,
3462 "sloc_min": 11,
3463 "sloc_max": 11,
3464 "cloc_min": 11,
3465 "cloc_max": 11,
3466 "ploc_min": 11,
3467 "ploc_max": 11,
3468 "lloc_min": 12,
3469 "lloc_max": 12,
3470 "blank_min": 0,
3471 "blank_max": 0
3472 }
3473 "#
3474 );
3475 },
3476 );
3477 }
3478
3479 #[test]
3480 fn java_statement_inline_loc() {
3481 check_metrics::<JavaParser>(
3482 "for (int i = 0; i < 100; i++) { System.out.println(\"hello\"); }",
3483 "foo.java",
3484 |metric| {
3485 insta::assert_json_snapshot!(
3487 metric.loc,
3488 @r#"
3489 {
3490 "sloc": 1,
3491 "ploc": 1,
3492 "lloc": 2,
3493 "cloc": 0,
3494 "blank": 0,
3495 "sloc_average": 1.0,
3496 "ploc_average": 1.0,
3497 "lloc_average": 2.0,
3498 "cloc_average": 0.0,
3499 "blank_average": 0.0,
3500 "sloc_min": 1,
3501 "sloc_max": 1,
3502 "cloc_min": 0,
3503 "cloc_max": 0,
3504 "ploc_min": 1,
3505 "ploc_max": 1,
3506 "lloc_min": 2,
3507 "lloc_max": 2,
3508 "blank_min": 0,
3509 "blank_max": 0
3510 }
3511 "#
3512 );
3513 },
3514 );
3515 }
3516
3517 #[test]
3518 fn java_general_loc() {
3519 check_metrics::<JavaParser>(
3520 "int max = 100;
3521
3522 /*
3523 Loop through and print
3524 from: 0
3525 to: max
3526 */
3527 for (int i = 0; i < max; i++) {
3528 // Print the value
3529 System.out.println(i);
3530 }",
3531 "foo.java",
3532 |metric| {
3533 insta::assert_json_snapshot!(
3535 metric.loc,
3536 @r#"
3537 {
3538 "sloc": 11,
3539 "ploc": 4,
3540 "lloc": 3,
3541 "cloc": 6,
3542 "blank": 1,
3543 "sloc_average": 11.0,
3544 "ploc_average": 4.0,
3545 "lloc_average": 3.0,
3546 "cloc_average": 6.0,
3547 "blank_average": 1.0,
3548 "sloc_min": 11,
3549 "sloc_max": 11,
3550 "cloc_min": 6,
3551 "cloc_max": 6,
3552 "ploc_min": 4,
3553 "ploc_max": 4,
3554 "lloc_min": 3,
3555 "lloc_max": 3,
3556 "blank_min": 1,
3557 "blank_max": 1
3558 }
3559 "#
3560 );
3561 },
3562 );
3563 }
3564
3565 #[test]
3566 fn java_main_class_loc() {
3567 check_metrics::<JavaParser>(
3568 "package com.company;
3569 /**
3570 * The HelloWorldApp class implements an application that
3571 * simply prints \"Hello World!\" to standard output.
3572 */
3573
3574 class HelloWorldApp {
3575 public void main(String[] args) {
3576 String message = args.length == 0 ? \"Hello empty world\" : \"Hello world\"; // +1 lloc : 1 var assignment
3577 System.out.println(message); // Display the string. +1 lloc
3578 }
3579 }",
3580 "foo.java",
3581 |metric| {
3582 insta::assert_json_snapshot!(
3584 metric.loc,
3585 @r#"
3586 {
3587 "sloc": 12,
3588 "ploc": 7,
3589 "lloc": 2,
3590 "cloc": 6,
3591 "blank": 1,
3592 "sloc_average": 4.0,
3593 "ploc_average": 2.3333333333333335,
3594 "lloc_average": 0.6666666666666666,
3595 "cloc_average": 2.0,
3596 "blank_average": 0.3333333333333333,
3597 "sloc_min": 4,
3598 "sloc_max": 12,
3599 "cloc_min": 2,
3600 "cloc_max": 6,
3601 "ploc_min": 4,
3602 "ploc_max": 7,
3603 "lloc_min": 2,
3604 "lloc_max": 2,
3605 "blank_min": 0,
3606 "blank_max": 1
3607 }
3608 "#
3609 );
3610 },
3611 );
3612 }
3613
3614 #[test]
3615 fn go_general_loc() {
3616 check_metrics::<GoParser>(
3617 "package main
3618
3619 // entrypoint
3620 func main() {
3621 /* loop body */
3622 for i := 0; i < 10; i++ {
3623 fmt.Println(i)
3624 }
3625 }",
3626 "foo.go",
3627 |metric| {
3628 insta::assert_json_snapshot!(
3633 metric.loc,
3634 @r#"
3635 {
3636 "sloc": 9,
3637 "ploc": 6,
3638 "lloc": 2,
3639 "cloc": 2,
3640 "blank": 1,
3641 "sloc_average": 4.5,
3642 "ploc_average": 3.0,
3643 "lloc_average": 1.0,
3644 "cloc_average": 1.0,
3645 "blank_average": 0.5,
3646 "sloc_min": 6,
3647 "sloc_max": 9,
3648 "cloc_min": 1,
3649 "cloc_max": 2,
3650 "ploc_min": 5,
3651 "ploc_max": 6,
3652 "lloc_min": 2,
3653 "lloc_max": 2,
3654 "blank_min": 0,
3655 "blank_max": 1
3656 }
3657 "#
3658 );
3659 },
3660 );
3661 }
3662
3663 #[test]
3664 fn go_for_clause_does_not_double_count_lloc() {
3665 check_metrics::<GoParser>(
3669 "package main
3670 func f(n int) int {
3671 for i := 0; i < n; i++ {
3672 return i
3673 }
3674 return 0
3675 }",
3676 "foo.go",
3677 |metric| {
3678 assert_eq!(metric.loc.lloc(), 3);
3681 },
3682 );
3683 }
3684
3685 #[test]
3686 fn go_blank() {
3687 check_metrics::<GoParser>(
3688 "package main
3689
3690 func foo() {
3691 x := 1
3692
3693 y := 2
3694 }",
3695 "foo.go",
3696 |metric| {
3697 insta::assert_json_snapshot!(
3700 metric.loc,
3701 @r#"
3702 {
3703 "sloc": 7,
3704 "ploc": 5,
3705 "lloc": 2,
3706 "cloc": 0,
3707 "blank": 2,
3708 "sloc_average": 3.5,
3709 "ploc_average": 2.5,
3710 "lloc_average": 1.0,
3711 "cloc_average": 0.0,
3712 "blank_average": 1.0,
3713 "sloc_min": 5,
3714 "sloc_max": 7,
3715 "cloc_min": 0,
3716 "cloc_max": 0,
3717 "ploc_min": 4,
3718 "ploc_max": 5,
3719 "lloc_min": 2,
3720 "lloc_max": 2,
3721 "blank_min": 1,
3722 "blank_max": 2
3723 }
3724 "#
3725 );
3726 },
3727 );
3728 }
3729
3730 #[test]
3731 fn go_cloc_line_comments() {
3732 check_metrics::<GoParser>(
3733 "package main
3734
3735 // helper adds two numbers.
3736 // It returns their sum.
3737 func add(a, b int) int {
3738 // compute the result
3739 return a + b
3740 }",
3741 "foo.go",
3742 |metric| {
3743 insta::assert_json_snapshot!(
3746 metric.loc,
3747 @r#"
3748 {
3749 "sloc": 8,
3750 "ploc": 4,
3751 "lloc": 1,
3752 "cloc": 3,
3753 "blank": 1,
3754 "sloc_average": 4.0,
3755 "ploc_average": 2.0,
3756 "lloc_average": 0.5,
3757 "cloc_average": 1.5,
3758 "blank_average": 0.5,
3759 "sloc_min": 4,
3760 "sloc_max": 8,
3761 "cloc_min": 1,
3762 "cloc_max": 3,
3763 "ploc_min": 3,
3764 "ploc_max": 4,
3765 "lloc_min": 1,
3766 "lloc_max": 1,
3767 "blank_min": 0,
3768 "blank_max": 1
3769 }
3770 "#
3771 );
3772 },
3773 );
3774 }
3775
3776 #[test]
3777 fn go_cloc_block_comments() {
3778 check_metrics::<GoParser>(
3779 "package main
3780
3781 /* block comment
3782 spanning two lines */
3783 func foo() {
3784 x := 1 /* inline block */
3785 }",
3786 "foo.go",
3787 |metric| {
3788 insta::assert_json_snapshot!(
3791 metric.loc,
3792 @r#"
3793 {
3794 "sloc": 7,
3795 "ploc": 4,
3796 "lloc": 1,
3797 "cloc": 3,
3798 "blank": 1,
3799 "sloc_average": 3.5,
3800 "ploc_average": 2.0,
3801 "lloc_average": 0.5,
3802 "cloc_average": 1.5,
3803 "blank_average": 0.5,
3804 "sloc_min": 3,
3805 "sloc_max": 7,
3806 "cloc_min": 1,
3807 "cloc_max": 3,
3808 "ploc_min": 3,
3809 "ploc_max": 4,
3810 "lloc_min": 1,
3811 "lloc_max": 1,
3812 "blank_min": 0,
3813 "blank_max": 1
3814 }
3815 "#
3816 );
3817 },
3818 );
3819 }
3820
3821 #[test]
3822 fn go_lloc_if_for_switch() {
3823 check_metrics::<GoParser>(
3824 "package main
3825
3826 func foo(n int) int {
3827 if n > 0 {
3828 for i := 0; i < n; i++ {
3829 switch i {
3830 }
3831 }
3832 }
3833 return n
3834 }",
3835 "foo.go",
3836 |metric| {
3837 insta::assert_json_snapshot!(
3840 metric.loc,
3841 @r#"
3842 {
3843 "sloc": 11,
3844 "ploc": 10,
3845 "lloc": 4,
3846 "cloc": 0,
3847 "blank": 1,
3848 "sloc_average": 5.5,
3849 "ploc_average": 5.0,
3850 "lloc_average": 2.0,
3851 "cloc_average": 0.0,
3852 "blank_average": 0.5,
3853 "sloc_min": 9,
3854 "sloc_max": 11,
3855 "cloc_min": 0,
3856 "cloc_max": 0,
3857 "ploc_min": 9,
3858 "ploc_max": 10,
3859 "lloc_min": 4,
3860 "lloc_max": 4,
3861 "blank_min": 0,
3862 "blank_max": 1
3863 }
3864 "#
3865 );
3866 },
3867 );
3868 }
3869
3870 #[test]
3871 fn go_lloc_go_defer() {
3872 check_metrics::<GoParser>(
3873 "package main
3874
3875 func foo() {
3876 go run()
3877 defer cleanup()
3878 }",
3879 "foo.go",
3880 |metric| {
3881 insta::assert_json_snapshot!(
3884 metric.loc,
3885 @r#"
3886 {
3887 "sloc": 6,
3888 "ploc": 5,
3889 "lloc": 2,
3890 "cloc": 0,
3891 "blank": 1,
3892 "sloc_average": 3.0,
3893 "ploc_average": 2.5,
3894 "lloc_average": 1.0,
3895 "cloc_average": 0.0,
3896 "blank_average": 0.5,
3897 "sloc_min": 4,
3898 "sloc_max": 6,
3899 "cloc_min": 0,
3900 "cloc_max": 0,
3901 "ploc_min": 4,
3902 "ploc_max": 5,
3903 "lloc_min": 2,
3904 "lloc_max": 2,
3905 "blank_min": 0,
3906 "blank_max": 1
3907 }
3908 "#
3909 );
3910 },
3911 );
3912 }
3913
3914 #[test]
3915 fn go_lloc_var_const_declarations() {
3916 check_metrics::<GoParser>(
3917 "package main
3918
3919 func foo() {
3920 var x int
3921 var y = 10
3922 const z = 42
3923 a := 3
3924 a = 4
3925 }",
3926 "foo.go",
3927 |metric| {
3928 insta::assert_json_snapshot!(
3932 metric.loc,
3933 @r#"
3934 {
3935 "sloc": 9,
3936 "ploc": 8,
3937 "lloc": 5,
3938 "cloc": 0,
3939 "blank": 1,
3940 "sloc_average": 4.5,
3941 "ploc_average": 4.0,
3942 "lloc_average": 2.5,
3943 "cloc_average": 0.0,
3944 "blank_average": 0.5,
3945 "sloc_min": 7,
3946 "sloc_max": 9,
3947 "cloc_min": 0,
3948 "cloc_max": 0,
3949 "ploc_min": 7,
3950 "ploc_max": 8,
3951 "lloc_min": 5,
3952 "lloc_max": 5,
3953 "blank_min": 0,
3954 "blank_max": 1
3955 }
3956 "#
3957 );
3958 },
3959 );
3960 }
3961
3962 #[test]
3963 fn go_lloc_select() {
3964 check_metrics::<GoParser>(
3965 "package main
3966
3967 func foo(ch chan int) {
3968 select {
3969 case v := <-ch:
3970 _ = v
3971 }
3972 }",
3973 "foo.go",
3974 |metric| {
3975 insta::assert_json_snapshot!(
3980 metric.loc,
3981 @r#"
3982 {
3983 "sloc": 8,
3984 "ploc": 7,
3985 "lloc": 2,
3986 "cloc": 0,
3987 "blank": 1,
3988 "sloc_average": 4.0,
3989 "ploc_average": 3.5,
3990 "lloc_average": 1.0,
3991 "cloc_average": 0.0,
3992 "blank_average": 0.5,
3993 "sloc_min": 6,
3994 "sloc_max": 8,
3995 "cloc_min": 0,
3996 "cloc_max": 0,
3997 "ploc_min": 6,
3998 "ploc_max": 7,
3999 "lloc_min": 2,
4000 "lloc_max": 2,
4001 "blank_min": 0,
4002 "blank_max": 1
4003 }
4004 "#
4005 );
4006 },
4007 );
4008 }
4009
4010 #[test]
4011 fn go_sloc_multiline_function() {
4012 check_metrics::<GoParser>(
4013 "package main
4014
4015 func add(
4016 a int,
4017 b int,
4018 ) int {
4019 return a + b
4020 }",
4021 "foo.go",
4022 |metric| {
4023 insta::assert_json_snapshot!(
4026 metric.loc,
4027 @r#"
4028 {
4029 "sloc": 8,
4030 "ploc": 7,
4031 "lloc": 1,
4032 "cloc": 0,
4033 "blank": 1,
4034 "sloc_average": 4.0,
4035 "ploc_average": 3.5,
4036 "lloc_average": 0.5,
4037 "cloc_average": 0.0,
4038 "blank_average": 0.5,
4039 "sloc_min": 6,
4040 "sloc_max": 8,
4041 "cloc_min": 0,
4042 "cloc_max": 0,
4043 "ploc_min": 6,
4044 "ploc_max": 7,
4045 "lloc_min": 1,
4046 "lloc_max": 1,
4047 "blank_min": 0,
4048 "blank_max": 1
4049 }
4050 "#
4051 );
4052 },
4053 );
4054 }
4055
4056 #[test]
4057 fn go_code_comment_same_line() {
4058 check_metrics::<GoParser>(
4059 "package main
4060
4061 func foo() {
4062 x := 1 // initialize x
4063 y := 2 // initialize y
4064 }",
4065 "foo.go",
4066 |metric| {
4067 insta::assert_json_snapshot!(
4072 metric.loc,
4073 @r#"
4074 {
4075 "sloc": 6,
4076 "ploc": 5,
4077 "lloc": 2,
4078 "cloc": 2,
4079 "blank": 1,
4080 "sloc_average": 3.0,
4081 "ploc_average": 2.5,
4082 "lloc_average": 1.0,
4083 "cloc_average": 1.0,
4084 "blank_average": 0.5,
4085 "sloc_min": 4,
4086 "sloc_max": 6,
4087 "cloc_min": 2,
4088 "cloc_max": 2,
4089 "ploc_min": 4,
4090 "ploc_max": 5,
4091 "lloc_min": 2,
4092 "lloc_max": 2,
4093 "blank_min": 0,
4094 "blank_max": 1
4095 }
4096 "#
4097 );
4098 },
4099 );
4100 }
4101
4102 #[test]
4103 fn perl_grammar_smoke() {
4104 assert_perl_parses_cleanly(
4110 "use strict;
4111use warnings;
4112
4113# line comment
4114
4115=pod
4116multi-line POD
4117=cut
4118
4119sub factorial {
4120 my ($n) = @_;
4121 return 1 if $n <= 1;
4122 return $n * factorial($n - 1);
4123}
4124
4125my @arr = (1, 2, 3);
4126my %hash = (a => 1, b => 2);
4127my $closure = sub { return $_[0] + 1; };
4128
4129for my $i (1..3) {
4130 if ($i % 2 == 0) {
4131 print \"even\\n\";
4132 } elsif ($i == 1) {
4133 print \"one\\n\";
4134 } else {
4135 print \"odd\\n\";
4136 }
4137}
4138
4139while ($x > 0) {
4140 last if $x == 0;
4141 $x--;
4142}
4143
4144unless ($done) {
4145 next;
4146}
4147
4148my $heredoc = <<END;
4149hello
4150END
4151",
4152 );
4153 }
4154
4155 #[test]
4156 fn perl_blank() {
4157 check_metrics::<PerlParser>(
4158 "
4159
4160my $a = 42;
4161
4162my $b = 43;
4163
4164",
4165 "foo.pl",
4166 |metric| {
4167 insta::assert_json_snapshot!(metric.loc, @r#"
4168 {
4169 "sloc": 3,
4170 "ploc": 2,
4171 "lloc": 2,
4172 "cloc": 0,
4173 "blank": 1,
4174 "sloc_average": 3.0,
4175 "ploc_average": 2.0,
4176 "lloc_average": 2.0,
4177 "cloc_average": 0.0,
4178 "blank_average": 1.0,
4179 "sloc_min": 3,
4180 "sloc_max": 3,
4181 "cloc_min": 0,
4182 "cloc_max": 0,
4183 "ploc_min": 2,
4184 "ploc_max": 2,
4185 "lloc_min": 2,
4186 "lloc_max": 2,
4187 "blank_min": 1,
4188 "blank_max": 1
4189 }
4190 "#);
4191 },
4192 );
4193 }
4194
4195 #[test]
4196 fn perl_no_zero_blank() {
4197 check_metrics::<PerlParser>(
4200 "my $a = 1;
4201my $b = 2;
4202
4203my $c = 3; # trailing
4204my $d = 4; # trailing
4205my $e = 5;",
4206 "foo.pl",
4207 |metric| {
4208 assert_eq!(metric.loc.sloc(), 6);
4209 assert_eq!(metric.loc.ploc(), 5);
4210 assert_eq!(metric.loc.cloc(), 2);
4211 assert_eq!(metric.loc.blank(), 1);
4212 insta::assert_json_snapshot!(metric.loc);
4213 },
4214 );
4215 }
4216
4217 #[test]
4218 fn perl_blank_zero_sanity() {
4219 check_metrics::<PerlParser>(
4222 "my $a = 1;
4223my $b = 2;",
4224 "foo.pl",
4225 |metric| {
4226 assert_eq!(metric.loc.sloc(), 2);
4227 assert_eq!(metric.loc.ploc(), 2);
4228 assert_eq!(metric.loc.lloc(), 2);
4229 assert_eq!(metric.loc.cloc(), 0);
4230 assert_eq!(metric.loc.blank(), 0);
4231 },
4232 );
4233 }
4234
4235 #[test]
4236 fn perl_cloc_line_comments() {
4237 check_metrics::<PerlParser>(
4238 "# top comment
4239my $a = 1; # trailing
4240my $b = 2;",
4241 "foo.pl",
4242 |metric| {
4243 insta::assert_json_snapshot!(metric.loc, @r#"
4244 {
4245 "sloc": 3,
4246 "ploc": 3,
4247 "lloc": 2,
4248 "cloc": 2,
4249 "blank": 0,
4250 "sloc_average": 3.0,
4251 "ploc_average": 3.0,
4252 "lloc_average": 2.0,
4253 "cloc_average": 2.0,
4254 "blank_average": 0.0,
4255 "sloc_min": 3,
4256 "sloc_max": 3,
4257 "cloc_min": 2,
4258 "cloc_max": 2,
4259 "ploc_min": 3,
4260 "ploc_max": 3,
4261 "lloc_min": 2,
4262 "lloc_max": 2,
4263 "blank_min": 0,
4264 "blank_max": 0
4265 }
4266 "#);
4267 },
4268 );
4269 }
4270
4271 #[test]
4272 fn perl_cloc_pod_block() {
4273 check_metrics::<PerlParser>(
4274 "my $x = 1;
4275=pod
4276multi-line
4277pod block
4278=cut
4279my $y = 2;",
4280 "foo.pl",
4281 |metric| {
4282 insta::assert_json_snapshot!(metric.loc, @r#"
4283 {
4284 "sloc": 6,
4285 "ploc": 2,
4286 "lloc": 2,
4287 "cloc": 4,
4288 "blank": 0,
4289 "sloc_average": 6.0,
4290 "ploc_average": 2.0,
4291 "lloc_average": 2.0,
4292 "cloc_average": 4.0,
4293 "blank_average": 0.0,
4294 "sloc_min": 6,
4295 "sloc_max": 6,
4296 "cloc_min": 4,
4297 "cloc_max": 4,
4298 "ploc_min": 2,
4299 "ploc_max": 2,
4300 "lloc_min": 2,
4301 "lloc_max": 2,
4302 "blank_min": 0,
4303 "blank_max": 0
4304 }
4305 "#);
4306 },
4307 );
4308 }
4309
4310 #[test]
4311 fn perl_lloc_simple_statements() {
4312 check_metrics::<PerlParser>(
4313 "my $a = 1;
4314my $b = 2;
4315my $c = 3;",
4316 "foo.pl",
4317 |metric| {
4318 insta::assert_json_snapshot!(metric.loc, @r#"
4319 {
4320 "sloc": 3,
4321 "ploc": 3,
4322 "lloc": 3,
4323 "cloc": 0,
4324 "blank": 0,
4325 "sloc_average": 3.0,
4326 "ploc_average": 3.0,
4327 "lloc_average": 3.0,
4328 "cloc_average": 0.0,
4329 "blank_average": 0.0,
4330 "sloc_min": 3,
4331 "sloc_max": 3,
4332 "cloc_min": 0,
4333 "cloc_max": 0,
4334 "ploc_min": 3,
4335 "ploc_max": 3,
4336 "lloc_min": 3,
4337 "lloc_max": 3,
4338 "blank_min": 0,
4339 "blank_max": 0
4340 }
4341 "#);
4342 },
4343 );
4344 }
4345
4346 #[test]
4347 fn perl_lloc_compound_statements() {
4348 check_metrics::<PerlParser>(
4349 "if ($x) {
4350 print 'a';
4351}
4352while ($n > 0) {
4353 $n--;
4354}",
4355 "foo.pl",
4356 |metric| {
4357 insta::assert_json_snapshot!(metric.loc, @r#"
4358 {
4359 "sloc": 6,
4360 "ploc": 6,
4361 "lloc": 4,
4362 "cloc": 0,
4363 "blank": 0,
4364 "sloc_average": 6.0,
4365 "ploc_average": 6.0,
4366 "lloc_average": 4.0,
4367 "cloc_average": 0.0,
4368 "blank_average": 0.0,
4369 "sloc_min": 6,
4370 "sloc_max": 6,
4371 "cloc_min": 0,
4372 "cloc_max": 0,
4373 "ploc_min": 6,
4374 "ploc_max": 6,
4375 "lloc_min": 4,
4376 "lloc_max": 4,
4377 "blank_min": 0,
4378 "blank_max": 0
4379 }
4380 "#);
4381 },
4382 );
4383 }
4384
4385 #[test]
4386 fn perl_lloc_postfix_form_counts_once() {
4387 check_metrics::<PerlParser>(
4391 "sub f {
4392 return 1 if $_[0];
4393}",
4394 "foo.pl",
4395 |metric| {
4396 assert_eq!(metric.loc.lloc(), 1);
4397 },
4398 );
4399 }
4400
4401 #[test]
4402 fn perl_lloc_use_statement() {
4403 check_metrics::<PerlParser>(
4404 "use strict;
4405use warnings;
4406my $x = 1;",
4407 "foo.pl",
4408 |metric| {
4409 insta::assert_json_snapshot!(metric.loc, @r#"
4410 {
4411 "sloc": 3,
4412 "ploc": 3,
4413 "lloc": 3,
4414 "cloc": 0,
4415 "blank": 0,
4416 "sloc_average": 3.0,
4417 "ploc_average": 3.0,
4418 "lloc_average": 3.0,
4419 "cloc_average": 0.0,
4420 "blank_average": 0.0,
4421 "sloc_min": 3,
4422 "sloc_max": 3,
4423 "cloc_min": 0,
4424 "cloc_max": 0,
4425 "ploc_min": 3,
4426 "ploc_max": 3,
4427 "lloc_min": 3,
4428 "lloc_max": 3,
4429 "blank_min": 0,
4430 "blank_max": 0
4431 }
4432 "#);
4433 },
4434 );
4435 }
4436
4437 #[test]
4438 fn perl_lloc_for_loop() {
4439 check_metrics::<PerlParser>(
4440 "for my $i (1..3) {
4441 print $i;
4442}",
4443 "foo.pl",
4444 |metric| {
4445 assert_eq!(metric.loc.lloc(), 2);
4447 },
4448 );
4449 }
4450
4451 #[test]
4452 fn perl_lloc_loop_control_statement() {
4453 check_metrics::<PerlParser>(
4454 "while (1) {
4455 last if $done;
4456}",
4457 "foo.pl",
4458 |metric| {
4459 assert_eq!(metric.loc.lloc(), 2);
4461 },
4462 );
4463 }
4464
4465 #[test]
4466 fn perl_lloc_no_double_count_inside_single_line_statement() {
4467 check_metrics::<PerlParser>(
4470 "sub f {
4471 print 'a' unless $_[0];
4472}",
4473 "foo.pl",
4474 |metric| {
4475 assert_eq!(metric.loc.lloc(), 1);
4476 },
4477 );
4478 }
4479
4480 #[test]
4481 fn perl_lloc_function_definition_not_counted() {
4482 check_metrics::<PerlParser>(
4485 "sub f {
4486 my $x = 1;
4487}",
4488 "foo.pl",
4489 |metric| {
4490 assert_eq!(metric.loc.lloc(), 1);
4491 },
4492 );
4493 }
4494
4495 #[test]
4496 fn perl_lloc_anonymous_function() {
4497 check_metrics::<PerlParser>("my $f = sub { return 1; };", "foo.pl", |metric| {
4501 assert_eq!(metric.loc.lloc(), 2);
4502 });
4503 }
4504
4505 #[test]
4506 fn perl_multiline_string_assignment_ploc() {
4507 check_metrics::<PerlParser>(
4514 "my $s = \"line1
4515line2
4516line3\";",
4517 "foo.pl",
4518 |metric| {
4519 assert_eq!(metric.loc.sloc(), 3);
4521 assert_eq!(metric.loc.ploc(), 3);
4522 assert_eq!(metric.loc.cloc(), 0);
4523 assert_eq!(metric.loc.blank(), 0);
4524 },
4525 );
4526 }
4527
4528 #[test]
4529 fn multiline_string_ploc_consistent_across_languages() {
4530 #[allow(clippy::needless_pass_by_value)]
4538 fn assert_three_code_rows(metric: crate::CodeMetrics) {
4539 assert_eq!(metric.loc.sloc(), 3);
4540 assert_eq!(metric.loc.ploc(), 3);
4541 assert_eq!(metric.loc.cloc(), 0);
4542 assert_eq!(metric.loc.blank(), 0);
4543 }
4544 check_metrics::<PythonParser>(
4545 "s = \"\"\"line1\nline2\nline3\"\"\"",
4546 "foo.py",
4547 assert_three_code_rows,
4548 );
4549 check_metrics::<PerlParser>(
4550 "my $s = \"line1\nline2\nline3\";",
4551 "foo.pl",
4552 assert_three_code_rows,
4553 );
4554 check_metrics::<RubyParser>(
4555 "s = \"line1\nline2\nline3\"",
4556 "foo.rb",
4557 assert_three_code_rows,
4558 );
4559 }
4560
4561 #[test]
4562 fn perl_lloc_unless_until() {
4563 check_metrics::<PerlParser>(
4564 "unless ($x) {
4565 print 'a';
4566}
4567until ($n == 0) {
4568 $n--;
4569}",
4570 "foo.pl",
4571 |metric| {
4572 assert_eq!(metric.loc.lloc(), 4);
4575 },
4576 );
4577 }
4578
4579 #[test]
4580 fn perl_lloc_heredoc_body_not_counted() {
4581 check_metrics::<PerlParser>(
4584 "my $s = <<END;
4585line1
4586line2
4587END
4588my $x = 1;",
4589 "foo.pl",
4590 |metric| {
4591 assert_eq!(metric.loc.lloc(), 2);
4594 },
4595 );
4596 assert_perl_parses_cleanly(
4600 "my $s = <<END;
4601line1
4602line2
4603END
4604my $x = 1;",
4605 );
4606 }
4607
4608 #[test]
4609 fn perl_lloc_package_and_require() {
4610 check_metrics::<PerlParser>(
4611 "package Foo;
4612require 5.010;
4613my $x = 1;",
4614 "foo.pl",
4615 |metric| {
4616 insta::assert_json_snapshot!(metric.loc, @r#"
4617 {
4618 "sloc": 3,
4619 "ploc": 3,
4620 "lloc": 3,
4621 "cloc": 0,
4622 "blank": 0,
4623 "sloc_average": 3.0,
4624 "ploc_average": 3.0,
4625 "lloc_average": 3.0,
4626 "cloc_average": 0.0,
4627 "blank_average": 0.0,
4628 "sloc_min": 3,
4629 "sloc_max": 3,
4630 "cloc_min": 0,
4631 "cloc_max": 0,
4632 "ploc_min": 3,
4633 "ploc_max": 3,
4634 "lloc_min": 3,
4635 "lloc_max": 3,
4636 "blank_min": 0,
4637 "blank_max": 0
4638 }
4639 "#);
4640 },
4641 );
4642 }
4643
4644 #[test]
4645 fn lua_blank() {
4646 check_metrics::<LuaParser>(
4647 "local x = 1
4648
4649local y = 2",
4650 "foo.lua",
4651 |metric| {
4652 assert_eq!(metric.loc.sloc(), 3);
4653 assert_eq!(metric.loc.ploc(), 2);
4654 assert_eq!(metric.loc.lloc(), 2);
4655 assert_eq!(metric.loc.cloc(), 0);
4656 assert_eq!(metric.loc.blank(), 1);
4657 insta::assert_json_snapshot!(metric.loc);
4658 },
4659 );
4660 }
4661
4662 #[test]
4663 fn lua_no_zero_blank() {
4664 check_metrics::<LuaParser>(
4667 "local a = 1
4668local b = 2
4669
4670local c = 3 -- trailing
4671local d = 4 -- trailing
4672local e = 5",
4673 "foo.lua",
4674 |metric| {
4675 assert_eq!(metric.loc.sloc(), 6);
4676 assert_eq!(metric.loc.ploc(), 5);
4677 assert_eq!(metric.loc.cloc(), 2);
4678 assert_eq!(metric.loc.blank(), 1);
4679 insta::assert_json_snapshot!(metric.loc);
4680 },
4681 );
4682 }
4683
4684 #[test]
4685 fn lua_blank_zero_sanity() {
4686 check_metrics::<LuaParser>(
4689 "local x = 1
4690local y = 2",
4691 "foo.lua",
4692 |metric| {
4693 assert_eq!(metric.loc.sloc(), 2);
4694 assert_eq!(metric.loc.ploc(), 2);
4695 assert_eq!(metric.loc.lloc(), 2);
4696 assert_eq!(metric.loc.cloc(), 0);
4697 assert_eq!(metric.loc.blank(), 0);
4698 },
4699 );
4700 }
4701
4702 #[test]
4703 fn lua_cloc() {
4704 check_metrics::<LuaParser>(
4705 "-- single line comment
4706local x = 1
4707--[[
4708 block comment
4709 second line
4710]]",
4711 "foo.lua",
4712 |metric| {
4713 assert_eq!(metric.loc.sloc(), 6);
4714 assert_eq!(metric.loc.ploc(), 1);
4715 assert_eq!(metric.loc.lloc(), 1);
4716 assert_eq!(metric.loc.cloc(), 5);
4717 assert_eq!(metric.loc.blank(), 0);
4718 insta::assert_json_snapshot!(metric.loc);
4719 },
4720 );
4721 }
4722
4723 #[test]
4724 fn lua_lloc() {
4725 check_metrics::<LuaParser>(
4726 "local function f(x)
4727 if x > 0 then
4728 local y = x + 1
4729 return y
4730 end
4731 return 0
4732end",
4733 "foo.lua",
4734 |metric| {
4735 assert_eq!(metric.loc.sloc(), 7);
4736 assert_eq!(metric.loc.ploc(), 7);
4737 assert_eq!(metric.loc.lloc(), 5);
4738 assert_eq!(metric.loc.cloc(), 0);
4739 assert_eq!(metric.loc.blank(), 0);
4740 insta::assert_json_snapshot!(metric.loc);
4741 },
4742 );
4743 }
4744
4745 #[test]
4746 fn lua_no_string_lloc() {
4747 check_metrics::<LuaParser>(
4749 "local s = [[
4750 line one
4751 line two
4752]]",
4753 "foo.lua",
4754 |metric| {
4755 assert_eq!(metric.loc.sloc(), 4);
4760 assert_eq!(metric.loc.ploc(), 4);
4761 assert_eq!(metric.loc.lloc(), 1);
4762 assert_eq!(metric.loc.cloc(), 0);
4763 assert_eq!(metric.loc.blank(), 0);
4764 insta::assert_json_snapshot!(metric.loc);
4765 },
4766 );
4767 }
4768
4769 #[test]
4770 fn lua_no_functiondefinition_lloc() {
4771 check_metrics::<LuaParser>(
4774 "local f = function(x)
4775 return x + 1
4776end",
4777 "foo.lua",
4778 |metric| {
4779 assert_eq!(metric.loc.sloc(), 3);
4780 assert_eq!(metric.loc.ploc(), 3);
4781 assert_eq!(metric.loc.lloc(), 2);
4782 assert_eq!(metric.loc.cloc(), 0);
4783 assert_eq!(metric.loc.blank(), 0);
4784 insta::assert_json_snapshot!(metric.loc);
4785 },
4786 );
4787 }
4788
4789 #[test]
4790 fn lua_no_elseif_lloc() {
4791 check_metrics::<LuaParser>(
4793 "local function f(x)
4794 if x > 0 then
4795 return 1
4796 elseif x < 0 then
4797 return -1
4798 else
4799 return 0
4800 end
4801end",
4802 "foo.lua",
4803 |metric| {
4804 assert_eq!(metric.loc.sloc(), 9);
4805 assert_eq!(metric.loc.ploc(), 9);
4806 assert_eq!(metric.loc.lloc(), 5);
4807 assert_eq!(metric.loc.cloc(), 0);
4808 assert_eq!(metric.loc.blank(), 0);
4809 insta::assert_json_snapshot!(metric.loc);
4810 },
4811 );
4812 }
4813
4814 #[test]
4815 fn lua_no_else_lloc() {
4816 check_metrics::<LuaParser>(
4818 "local function f(x)
4819 if x > 0 then
4820 return 1
4821 else
4822 return 0
4823 end
4824end",
4825 "foo.lua",
4826 |metric| {
4827 assert_eq!(metric.loc.sloc(), 7);
4828 assert_eq!(metric.loc.ploc(), 7);
4829 assert_eq!(metric.loc.lloc(), 4);
4830 assert_eq!(metric.loc.cloc(), 0);
4831 assert_eq!(metric.loc.blank(), 0);
4832 insta::assert_json_snapshot!(metric.loc);
4833 },
4834 );
4835 }
4836
4837 #[test]
4838 fn lua_functiondeclaration_lloc() {
4839 check_metrics::<LuaParser>(
4841 "function f()
4842 return 1
4843end",
4844 "foo.lua",
4845 |metric| {
4846 assert_eq!(metric.loc.sloc(), 3);
4847 assert_eq!(metric.loc.ploc(), 3);
4848 assert_eq!(metric.loc.lloc(), 2);
4849 assert_eq!(metric.loc.cloc(), 0);
4850 assert_eq!(metric.loc.blank(), 0);
4851 insta::assert_json_snapshot!(metric.loc);
4852 },
4853 );
4854 }
4855
4856 #[test]
4857 fn lua_local_function_lloc() {
4858 check_metrics::<LuaParser>(
4860 "local function g()
4861 return 2
4862end",
4863 "foo.lua",
4864 |metric| {
4865 assert_eq!(metric.loc.sloc(), 3);
4866 assert_eq!(metric.loc.ploc(), 3);
4867 assert_eq!(metric.loc.lloc(), 2);
4868 assert_eq!(metric.loc.cloc(), 0);
4869 assert_eq!(metric.loc.blank(), 0);
4870 insta::assert_json_snapshot!(metric.loc);
4871 },
4872 );
4873 }
4874
4875 #[test]
4876 fn lua_for_numeric_lloc() {
4877 check_metrics::<LuaParser>(
4878 "for i = 1, 10 do
4879 print(i)
4880end",
4881 "foo.lua",
4882 |metric| {
4883 assert_eq!(metric.loc.sloc(), 3);
4884 assert_eq!(metric.loc.ploc(), 3);
4885 assert_eq!(metric.loc.lloc(), 1);
4886 assert_eq!(metric.loc.cloc(), 0);
4887 assert_eq!(metric.loc.blank(), 0);
4888 insta::assert_json_snapshot!(metric.loc);
4889 },
4890 );
4891 }
4892
4893 #[test]
4894 fn lua_for_generic_lloc() {
4895 check_metrics::<LuaParser>(
4896 "for k, v in pairs(t) do
4897 print(k, v)
4898end",
4899 "foo.lua",
4900 |metric| {
4901 assert_eq!(metric.loc.sloc(), 3);
4902 assert_eq!(metric.loc.ploc(), 3);
4903 assert_eq!(metric.loc.lloc(), 1);
4904 assert_eq!(metric.loc.cloc(), 0);
4905 assert_eq!(metric.loc.blank(), 0);
4906 insta::assert_json_snapshot!(metric.loc);
4907 },
4908 );
4909 }
4910
4911 #[test]
4912 fn lua_repeat_lloc() {
4913 check_metrics::<LuaParser>(
4914 "local i = 0
4915repeat
4916 i = i + 1
4917until i >= 10",
4918 "foo.lua",
4919 |metric| {
4920 assert_eq!(metric.loc.sloc(), 4);
4921 assert_eq!(metric.loc.ploc(), 4);
4922 assert_eq!(metric.loc.lloc(), 3);
4923 assert_eq!(metric.loc.cloc(), 0);
4924 assert_eq!(metric.loc.blank(), 0);
4925 insta::assert_json_snapshot!(metric.loc);
4926 },
4927 );
4928 }
4929
4930 #[test]
4931 fn lua_local_decl_lloc() {
4932 check_metrics::<LuaParser>(
4933 "local x = 1
4934local y, z = 2, 3",
4935 "foo.lua",
4936 |metric| {
4937 assert_eq!(metric.loc.sloc(), 2);
4938 assert_eq!(metric.loc.ploc(), 2);
4939 assert_eq!(metric.loc.lloc(), 2);
4940 assert_eq!(metric.loc.cloc(), 0);
4941 assert_eq!(metric.loc.blank(), 0);
4942 insta::assert_json_snapshot!(metric.loc);
4943 },
4944 );
4945 }
4946
4947 #[test]
4948 fn lua_function_call_lloc() {
4949 check_metrics::<LuaParser>(
4952 "print(\"hello\")
4953local x = 1",
4954 "foo.lua",
4955 |metric| {
4956 assert_eq!(metric.loc.sloc(), 2);
4957 assert_eq!(metric.loc.ploc(), 2);
4958 assert_eq!(metric.loc.lloc(), 1);
4959 assert_eq!(metric.loc.cloc(), 0);
4960 assert_eq!(metric.loc.blank(), 0);
4961 insta::assert_json_snapshot!(metric.loc);
4962 },
4963 );
4964 }
4965
4966 #[test]
4967 fn lua_toplevel_assignment_lloc() {
4968 check_metrics::<LuaParser>(
4971 "x = 1
4972y, z = 2, 3",
4973 "foo.lua",
4974 |metric| {
4975 assert_eq!(metric.loc.sloc(), 2);
4976 assert_eq!(metric.loc.ploc(), 2);
4977 assert_eq!(metric.loc.lloc(), 2);
4978 assert_eq!(metric.loc.cloc(), 0);
4979 assert_eq!(metric.loc.blank(), 0);
4980 insta::assert_json_snapshot!(metric.loc);
4981 },
4982 );
4983 }
4984
4985 #[test]
4986 fn tsx_basic_loc() {
4987 check_metrics::<TsxParser>(
4988 "// A simple utility function
4989 function add(a: number, b: number): number {
4990 /* multi-line
4991 comment */
4992 return a + b;
4993 }
4994
4995 const greet = (name: string) => {
4996 return `Hello, ${name}`;
4997 };",
4998 "foo.tsx",
4999 |metric| {
5000 insta::assert_json_snapshot!(
5001 metric.loc,
5002 @r#"
5003 {
5004 "sloc": 10,
5005 "ploc": 6,
5006 "lloc": 2,
5007 "cloc": 3,
5008 "blank": 1,
5009 "sloc_average": 3.3333333333333335,
5010 "ploc_average": 2.0,
5011 "lloc_average": 0.6666666666666666,
5012 "cloc_average": 1.0,
5013 "blank_average": 0.3333333333333333,
5014 "sloc_min": 3,
5015 "sloc_max": 10,
5016 "cloc_min": 0,
5017 "cloc_max": 3,
5018 "ploc_min": 3,
5019 "ploc_max": 6,
5020 "lloc_min": 1,
5021 "lloc_max": 2,
5022 "blank_min": 0,
5023 "blank_max": 1
5024 }
5025 "#
5026 );
5027 },
5028 );
5029 }
5030
5031 #[test]
5032 fn typescript_basic_loc() {
5033 check_metrics::<TypescriptParser>(
5034 "// Line comment
5035 /* Block
5036 comment */
5037 function greet(name: string): string {
5038 return `Hello, ${name}`;
5039 }
5040
5041 const add = (a: number, b: number): number => a + b;",
5042 "foo.ts",
5043 |metric| {
5044 insta::assert_json_snapshot!(
5045 metric.loc,
5046 @r#"
5047 {
5048 "sloc": 8,
5049 "ploc": 4,
5050 "lloc": 1,
5051 "cloc": 3,
5052 "blank": 1,
5053 "sloc_average": 2.6666666666666665,
5054 "ploc_average": 1.3333333333333333,
5055 "lloc_average": 0.3333333333333333,
5056 "cloc_average": 1.0,
5057 "blank_average": 0.3333333333333333,
5058 "sloc_min": 1,
5059 "sloc_max": 8,
5060 "cloc_min": 0,
5061 "cloc_max": 3,
5062 "ploc_min": 1,
5063 "ploc_max": 4,
5064 "lloc_min": 0,
5065 "lloc_max": 1,
5066 "blank_min": 0,
5067 "blank_max": 1
5068 }
5069 "#
5070 );
5071 },
5072 );
5073 }
5074
5075 #[test]
5076 fn csharp_comments() {
5077 check_metrics::<CsharpParser>(
5078 "for (int i = 0; i < 100; i++) {
5079 // Print hello
5080 System.Console.WriteLine(\"hello\");
5081 /// XML doc comment
5082 System.Console.WriteLine(\"hello\");
5083 }",
5084 "foo.cs",
5085 |metric| {
5086 assert_eq!(metric.loc.sloc(), 6);
5087 assert_eq!(metric.loc.ploc(), 4);
5088 assert_eq!(metric.loc.lloc(), 3);
5089 assert_eq!(metric.loc.cloc(), 2);
5090 assert_eq!(metric.loc.blank(), 0);
5091 insta::assert_json_snapshot!(metric.loc);
5092 },
5093 );
5094 }
5095
5096 #[test]
5097 fn csharp_blank() {
5098 check_metrics::<CsharpParser>(
5099 "int x = 1;
5100
5101
5102 int y = 2;",
5103 "foo.cs",
5104 |metric| {
5105 assert_eq!(metric.loc.sloc(), 4);
5106 assert_eq!(metric.loc.ploc(), 2);
5107 assert_eq!(metric.loc.lloc(), 2);
5108 assert_eq!(metric.loc.cloc(), 0);
5109 assert_eq!(metric.loc.blank(), 2);
5110 insta::assert_json_snapshot!(metric.loc);
5111 },
5112 );
5113 }
5114
5115 #[test]
5116 fn csharp_sloc() {
5117 check_metrics::<CsharpParser>(
5118 "for (int i = 0; i < 100; i++) {
5119 System.Console.WriteLine(i);
5120 }",
5121 "foo.cs",
5122 |metric| {
5123 assert_eq!(metric.loc.sloc(), 3);
5124 assert_eq!(metric.loc.ploc(), 3);
5125 assert_eq!(metric.loc.lloc(), 2);
5126 assert_eq!(metric.loc.cloc(), 0);
5127 assert_eq!(metric.loc.blank(), 0);
5128 insta::assert_json_snapshot!(metric.loc);
5129 },
5130 );
5131 }
5132
5133 #[test]
5134 fn csharp_module_sloc() {
5135 check_metrics::<CsharpParser>(
5136 "namespace HelloWorld {
5137 class Program { }
5138 }",
5139 "foo.cs",
5140 |metric| {
5141 assert_eq!(metric.loc.sloc(), 3);
5142 assert_eq!(metric.loc.ploc(), 3);
5143 assert_eq!(metric.loc.lloc(), 0);
5144 assert_eq!(metric.loc.cloc(), 0);
5145 assert_eq!(metric.loc.blank(), 0);
5146 insta::assert_json_snapshot!(metric.loc);
5147 },
5148 );
5149 }
5150
5151 #[test]
5152 fn csharp_single_ploc() {
5153 check_metrics::<CsharpParser>("int x = 1;", "foo.cs", |metric| {
5154 assert_eq!(metric.loc.sloc(), 1);
5155 assert_eq!(metric.loc.ploc(), 1);
5156 assert_eq!(metric.loc.lloc(), 1);
5157 assert_eq!(metric.loc.cloc(), 0);
5158 assert_eq!(metric.loc.blank(), 0);
5159 insta::assert_json_snapshot!(metric.loc);
5160 });
5161 }
5162
5163 #[test]
5164 fn csharp_simple_ploc() {
5165 check_metrics::<CsharpParser>(
5166 "for (int i = 0; i < 100; i++) {
5167 System.Console.WriteLine(i);
5168 }",
5169 "foo.cs",
5170 |metric| {
5171 assert_eq!(metric.loc.sloc(), 3);
5172 assert_eq!(metric.loc.ploc(), 3);
5173 assert_eq!(metric.loc.lloc(), 2);
5174 assert_eq!(metric.loc.cloc(), 0);
5175 assert_eq!(metric.loc.blank(), 0);
5176 insta::assert_json_snapshot!(metric.loc);
5177 },
5178 );
5179 }
5180
5181 #[test]
5182 fn csharp_multi_ploc() {
5183 check_metrics::<CsharpParser>(
5184 "int x = 1;
5185 for (int i = 0; i < 100; i++) {
5186 System.Console.WriteLine(i);
5187 }",
5188 "foo.cs",
5189 |metric| {
5190 assert_eq!(metric.loc.sloc(), 4);
5191 assert_eq!(metric.loc.ploc(), 4);
5192 assert_eq!(metric.loc.lloc(), 3);
5193 assert_eq!(metric.loc.cloc(), 0);
5194 assert_eq!(metric.loc.blank(), 0);
5195 insta::assert_json_snapshot!(metric.loc);
5196 },
5197 );
5198 }
5199
5200 #[test]
5201 fn csharp_single_statement_lloc() {
5202 check_metrics::<CsharpParser>("int max = 10;", "foo.cs", |metric| {
5203 assert_eq!(metric.loc.sloc(), 1);
5204 assert_eq!(metric.loc.ploc(), 1);
5205 assert_eq!(metric.loc.lloc(), 1);
5206 assert_eq!(metric.loc.cloc(), 0);
5207 assert_eq!(metric.loc.blank(), 0);
5208 insta::assert_json_snapshot!(metric.loc);
5209 });
5210 }
5211
5212 #[test]
5213 fn csharp_for_lloc() {
5214 check_metrics::<CsharpParser>(
5215 "for (int i = 0; i < 10; i++) {
5216 System.Console.WriteLine(i);
5217 }",
5218 "foo.cs",
5219 |metric| {
5220 assert_eq!(metric.loc.sloc(), 3);
5221 assert_eq!(metric.loc.ploc(), 3);
5222 assert_eq!(metric.loc.lloc(), 2);
5223 assert_eq!(metric.loc.cloc(), 0);
5224 assert_eq!(metric.loc.blank(), 0);
5225 insta::assert_json_snapshot!(metric.loc);
5226 },
5227 );
5228 }
5229
5230 #[test]
5231 fn csharp_foreach_lloc() {
5232 check_metrics::<CsharpParser>(
5233 "foreach (var item in items) {
5234 System.Console.WriteLine(item);
5235 }",
5236 "foo.cs",
5237 |metric| {
5238 assert_eq!(metric.loc.sloc(), 3);
5239 assert_eq!(metric.loc.ploc(), 3);
5240 assert_eq!(metric.loc.lloc(), 2);
5241 assert_eq!(metric.loc.cloc(), 0);
5242 assert_eq!(metric.loc.blank(), 0);
5243 insta::assert_json_snapshot!(metric.loc);
5244 },
5245 );
5246 }
5247
5248 #[test]
5249 fn csharp_while_lloc() {
5250 check_metrics::<CsharpParser>(
5251 "int i = 0;
5252 while (i < 10) {
5253 i++;
5254 }",
5255 "foo.cs",
5256 |metric| {
5257 assert_eq!(metric.loc.sloc(), 4);
5258 assert_eq!(metric.loc.ploc(), 4);
5259 assert_eq!(metric.loc.lloc(), 3);
5260 assert_eq!(metric.loc.cloc(), 0);
5261 assert_eq!(metric.loc.blank(), 0);
5262 insta::assert_json_snapshot!(metric.loc);
5263 },
5264 );
5265 }
5266
5267 #[test]
5268 fn csharp_do_while_lloc() {
5269 check_metrics::<CsharpParser>(
5270 "int i = 0;
5271 do {
5272 i++;
5273 } while (i < 10);",
5274 "foo.cs",
5275 |metric| {
5276 assert_eq!(metric.loc.sloc(), 4);
5277 assert_eq!(metric.loc.ploc(), 4);
5278 assert_eq!(metric.loc.lloc(), 3);
5279 assert_eq!(metric.loc.cloc(), 0);
5280 assert_eq!(metric.loc.blank(), 0);
5281 insta::assert_json_snapshot!(metric.loc);
5282 },
5283 );
5284 }
5285
5286 #[test]
5287 fn csharp_switch_lloc() {
5288 check_metrics::<CsharpParser>(
5289 "switch (x) {
5290 case 1: System.Console.WriteLine(1); break;
5291 case 2: System.Console.WriteLine(2); break;
5292 default: System.Console.WriteLine(0); break;
5293 }
5294 string s = x switch { 1 => \"one\", _ => \"other\" };",
5295 "foo.cs",
5296 |metric| {
5297 assert_eq!(metric.loc.sloc(), 6);
5298 assert_eq!(metric.loc.ploc(), 6);
5299 assert_eq!(metric.loc.lloc(), 8);
5300 assert_eq!(metric.loc.cloc(), 0);
5301 assert_eq!(metric.loc.blank(), 0);
5302 insta::assert_json_snapshot!(metric.loc);
5303 },
5304 );
5305 }
5306
5307 #[test]
5308 fn csharp_continue_lloc() {
5309 check_metrics::<CsharpParser>(
5310 "for (int i = 0; i < 10; i++) {
5311 if (i == 5) continue;
5312 System.Console.WriteLine(i);
5313 }",
5314 "foo.cs",
5315 |metric| {
5316 assert_eq!(metric.loc.sloc(), 4);
5317 assert_eq!(metric.loc.ploc(), 4);
5318 assert_eq!(metric.loc.lloc(), 4);
5319 assert_eq!(metric.loc.cloc(), 0);
5320 assert_eq!(metric.loc.blank(), 0);
5321 insta::assert_json_snapshot!(metric.loc);
5322 },
5323 );
5324 }
5325
5326 #[test]
5327 fn csharp_try_lloc() {
5328 check_metrics::<CsharpParser>(
5329 "try {
5330 System.Console.WriteLine(\"try\");
5331 } catch (System.Exception e) {
5332 throw new System.Exception(\"caught\");
5333 } finally {
5334 System.Console.WriteLine(\"done\");
5335 }",
5336 "foo.cs",
5337 |metric| {
5338 assert_eq!(metric.loc.sloc(), 7);
5339 assert_eq!(metric.loc.ploc(), 7);
5340 assert_eq!(metric.loc.lloc(), 4);
5341 assert_eq!(metric.loc.cloc(), 0);
5342 assert_eq!(metric.loc.blank(), 0);
5343 insta::assert_json_snapshot!(metric.loc);
5344 },
5345 );
5346 }
5347
5348 #[test]
5349 fn csharp_class_loc() {
5350 check_metrics::<CsharpParser>(
5351 "class A {
5352 int x;
5353 public void M() {
5354 System.Console.WriteLine(x);
5355 }
5356 }",
5357 "foo.cs",
5358 |metric| {
5359 assert_eq!(metric.loc.sloc(), 6);
5360 assert_eq!(metric.loc.ploc(), 6);
5361 assert_eq!(metric.loc.lloc(), 1);
5362 assert_eq!(metric.loc.cloc(), 0);
5363 assert_eq!(metric.loc.blank(), 0);
5364 insta::assert_json_snapshot!(metric.loc);
5365 },
5366 );
5367 }
5368
5369 #[test]
5370 fn csharp_expressions_lloc() {
5371 check_metrics::<CsharpParser>(
5372 "int a = 1;
5373 int b = 2;
5374 int c = a + b;
5375 System.Console.WriteLine(c);",
5376 "foo.cs",
5377 |metric| {
5378 assert_eq!(metric.loc.sloc(), 4);
5379 assert_eq!(metric.loc.ploc(), 4);
5380 assert_eq!(metric.loc.lloc(), 4);
5381 assert_eq!(metric.loc.cloc(), 0);
5382 assert_eq!(metric.loc.blank(), 0);
5383 insta::assert_json_snapshot!(metric.loc);
5384 },
5385 );
5386 }
5387
5388 #[test]
5389 fn csharp_statement_inline_loc() {
5390 check_metrics::<CsharpParser>(
5391 "if (x > 0) System.Console.WriteLine(x);",
5392 "foo.cs",
5393 |metric| {
5394 assert_eq!(metric.loc.sloc(), 1);
5395 assert_eq!(metric.loc.ploc(), 1);
5396 assert_eq!(metric.loc.lloc(), 2);
5397 assert_eq!(metric.loc.cloc(), 0);
5398 assert_eq!(metric.loc.blank(), 0);
5399 insta::assert_json_snapshot!(metric.loc);
5400 },
5401 );
5402 }
5403
5404 #[test]
5405 fn csharp_general_loc() {
5406 check_metrics::<CsharpParser>(
5407 "using System;
5408 namespace Demo {
5409 class A {
5410 public void M() {
5411 Console.WriteLine(\"hi\");
5412 }
5413 }
5414 class B {
5415 public int N() { return 0; }
5416 }
5417 }",
5418 "foo.cs",
5419 |metric| {
5420 assert_eq!(metric.loc.sloc(), 11);
5421 assert_eq!(metric.loc.ploc(), 11);
5422 assert_eq!(metric.loc.lloc(), 2);
5423 assert_eq!(metric.loc.cloc(), 0);
5424 assert_eq!(metric.loc.blank(), 0);
5425 insta::assert_json_snapshot!(metric.loc);
5426 },
5427 );
5428 }
5429
5430 #[test]
5431 fn csharp_using_lloc() {
5432 check_metrics::<CsharpParser>(
5437 "using System;
5438 using System.IO;
5439 class A {
5440 public void M() {
5441 using (var s = File.OpenRead(\"x\")) {
5442 Console.WriteLine(s);
5443 }
5444 using var t = File.OpenRead(\"y\");
5445 Console.WriteLine(t);
5446 }
5447 }",
5448 "foo.cs",
5449 |metric| {
5450 assert_eq!(metric.loc.sloc(), 11);
5451 assert_eq!(metric.loc.ploc(), 11);
5452 assert_eq!(metric.loc.lloc(), 4);
5453 assert_eq!(metric.loc.cloc(), 0);
5454 assert_eq!(metric.loc.blank(), 0);
5455 insta::assert_json_snapshot!(metric.loc);
5456 },
5457 );
5458 }
5459
5460 #[test]
5461 fn kotlin_loc_basic() {
5462 check_metrics::<KotlinParser>(
5463 "// A simple function
5464 fun greet(name: String): String {
5465 val greeting = \"Hello, \" + name
5466 if (name.isEmpty()) {
5467 return \"Hello, World!\"
5468 }
5469 return greeting
5470 }",
5471 "foo.kt",
5472 |metric| {
5473 insta::assert_json_snapshot!(
5474 metric.loc,
5475 @r#"
5476 {
5477 "sloc": 8,
5478 "ploc": 7,
5479 "lloc": 4,
5480 "cloc": 1,
5481 "blank": 0,
5482 "sloc_average": 4.0,
5483 "ploc_average": 3.5,
5484 "lloc_average": 2.0,
5485 "cloc_average": 0.5,
5486 "blank_average": 0.0,
5487 "sloc_min": 7,
5488 "sloc_max": 8,
5489 "cloc_min": 0,
5490 "cloc_max": 1,
5491 "ploc_min": 7,
5492 "ploc_max": 7,
5493 "lloc_min": 4,
5494 "lloc_max": 4,
5495 "blank_min": 0,
5496 "blank_max": 0
5497 }
5498 "#
5499 );
5500 },
5501 );
5502 }
5503
5504 #[test]
5505 fn kotlin_loc_bare_expression() {
5506 check_metrics::<KotlinParser>(
5507 "fun main() {
5508 val x = 42
5509 println(x)
5510 listOf(1, 2, 3).forEach { println(it) }
5511 }",
5512 "foo.kt",
5513 |metric| {
5514 insta::assert_json_snapshot!(
5518 metric.loc,
5519 @r#"
5520 {
5521 "sloc": 5,
5522 "ploc": 5,
5523 "lloc": 3,
5524 "cloc": 0,
5525 "blank": 0,
5526 "sloc_average": 2.5,
5527 "ploc_average": 2.5,
5528 "lloc_average": 1.5,
5529 "cloc_average": 0.0,
5530 "blank_average": 0.0,
5531 "sloc_min": 5,
5532 "sloc_max": 5,
5533 "cloc_min": 0,
5534 "cloc_max": 0,
5535 "ploc_min": 5,
5536 "ploc_max": 5,
5537 "lloc_min": 3,
5538 "lloc_max": 3,
5539 "blank_min": 0,
5540 "blank_max": 0
5541 }
5542 "#
5543 );
5544 },
5545 );
5546 }
5547
5548 #[test]
5549 fn bash_loc() {
5550 check_metrics::<BashParser>(
5551 "#!/bin/bash
5552# This is a comment
5553f() {
5554 echo 'hello'
5555}
5556
5557# Another comment
5558f",
5559 "foo.sh",
5560 |metric| {
5561 assert_eq!(metric.loc.sloc(), 8);
5562 assert_eq!(metric.loc.ploc(), 4);
5563 assert_eq!(metric.loc.lloc(), 3);
5564 assert_eq!(metric.loc.cloc(), 3);
5565 assert_eq!(metric.loc.blank(), 1);
5566 insta::assert_json_snapshot!(metric.loc);
5567 },
5568 );
5569 }
5570
5571 #[test]
5575 fn python_cloc_crlf_matches_lf() {
5576 check_metrics::<PythonParser>("# comment\nx = 1", "foo.py", |m| {
5577 assert_eq!(m.loc.cloc(), 1);
5578 assert_eq!(m.loc.ploc(), 1);
5579 assert_eq!(m.loc.sloc(), 2);
5580 assert_eq!(m.loc.blank(), 0);
5581 });
5582 check_metrics::<PythonParser>("# comment\r\nx = 1", "foo.py", |m| {
5583 assert_eq!(m.loc.cloc(), 1);
5584 assert_eq!(m.loc.ploc(), 1);
5585 assert_eq!(m.loc.sloc(), 2);
5586 assert_eq!(m.loc.blank(), 0);
5587 });
5588 check_metrics::<PythonParser>("# comment\rx = 1", "foo.py", |m| {
5592 assert_eq!(m.loc.cloc(), 1);
5593 assert_eq!(m.loc.ploc(), 1);
5594 assert_eq!(m.loc.sloc(), 2);
5595 assert_eq!(m.loc.blank(), 0);
5596 });
5597 }
5598
5599 #[test]
5600 fn python_blank_crlf_matches_lf() {
5601 check_metrics::<PythonParser>("# comment\n\nx = 1", "foo.py", |m| {
5602 assert_eq!(m.loc.blank(), 1);
5603 });
5604 check_metrics::<PythonParser>("# comment\r\n\r\nx = 1", "foo.py", |m| {
5605 assert_eq!(m.loc.blank(), 1);
5606 });
5607 check_metrics::<PythonParser>("# comment\r\rx = 1", "foo.py", |m| {
5609 assert_eq!(m.loc.blank(), 1);
5610 });
5611 }
5612
5613 #[test]
5614 fn rust_cloc_crlf_matches_lf() {
5615 check_metrics::<RustParser>(
5616 "fn f() {\n // comment\n let x = 1;\n}",
5617 "foo.rs",
5618 |m| {
5619 assert_eq!(m.loc.cloc(), 1);
5620 assert_eq!(m.loc.sloc(), 4);
5621 },
5622 );
5623 check_metrics::<RustParser>(
5624 "fn f() {\r\n // comment\r\n let x = 1;\r\n}",
5625 "foo.rs",
5626 |m| {
5627 assert_eq!(m.loc.cloc(), 1);
5628 assert_eq!(m.loc.sloc(), 4);
5629 },
5630 );
5631 check_metrics::<RustParser>(
5634 "fn f() {\r // comment\r let x = 1;\r}",
5635 "foo.rs",
5636 |m| {
5637 assert_eq!(m.loc.cloc(), 1);
5638 assert_eq!(m.loc.sloc(), 4);
5639 },
5640 );
5641 }
5642
5643 #[test]
5644 fn tcl_blank() {
5645 check_metrics::<TclParser>("set x 1\n\nset y 2", "foo.tcl", |metric| {
5646 assert_eq!(metric.loc.sloc(), 3);
5647 assert_eq!(metric.loc.ploc(), 2);
5648 assert_eq!(metric.loc.lloc(), 2);
5649 assert_eq!(metric.loc.cloc(), 0);
5650 assert_eq!(metric.loc.blank(), 1);
5651 insta::assert_json_snapshot!(metric.loc);
5652 });
5653 }
5654
5655 #[test]
5656 fn tcl_no_zero_blank() {
5657 check_metrics::<TclParser>(
5661 "set a 1\nset b 2\n\nset c 3 ;# trailing\nset d 4 ;# trailing\nset e 5",
5662 "foo.tcl",
5663 |metric| {
5664 assert_eq!(metric.loc.sloc(), 6);
5665 assert_eq!(metric.loc.ploc(), 5);
5666 assert_eq!(metric.loc.cloc(), 2);
5667 assert_eq!(metric.loc.blank(), 1);
5668 },
5669 );
5670 }
5671
5672 #[test]
5673 fn tcl_cloc() {
5674 check_metrics::<TclParser>("# This is a comment\nset x 1", "foo.tcl", |metric| {
5675 assert_eq!(metric.loc.sloc(), 2);
5676 assert_eq!(metric.loc.ploc(), 2);
5677 assert_eq!(metric.loc.lloc(), 1);
5678 assert_eq!(metric.loc.cloc(), 1);
5679 assert_eq!(metric.loc.blank(), 0);
5680 insta::assert_json_snapshot!(metric.loc);
5681 });
5682 }
5683
5684 #[test]
5685 fn tcl_lloc() {
5686 check_metrics::<TclParser>(
5687 "proc f {x} {
5688 while {$x > 0} {
5689 if {$x > 10} {
5690 set x [expr {$x - 1}]
5691 }
5692 }
5693}",
5694 "foo.tcl",
5695 |metric| {
5696 assert_eq!(metric.loc.sloc(), 7);
5697 assert_eq!(metric.loc.ploc(), 7);
5698 assert_eq!(metric.loc.lloc(), 4);
5699 assert_eq!(metric.loc.cloc(), 0);
5700 assert_eq!(metric.loc.blank(), 0);
5701 insta::assert_json_snapshot!(metric.loc);
5702 },
5703 );
5704 }
5705
5706 #[test]
5707 fn tcl_no_command_substitution_lloc() {
5708 check_metrics::<TclParser>("puts [string toupper x]", "foo.tcl", |metric| {
5710 assert_eq!(metric.loc.sloc(), 1);
5711 assert_eq!(metric.loc.ploc(), 1);
5712 assert_eq!(metric.loc.lloc(), 1);
5713 assert_eq!(metric.loc.cloc(), 0);
5714 assert_eq!(metric.loc.blank(), 0);
5715 insta::assert_json_snapshot!(metric.loc);
5716 });
5717 }
5718
5719 #[test]
5720 fn tcl_procedure_lloc() {
5721 check_metrics::<TclParser>("proc foo {} {\n puts hello\n}", "foo.tcl", |metric| {
5722 assert_eq!(metric.loc.sloc(), 3);
5723 assert_eq!(metric.loc.ploc(), 3);
5724 assert_eq!(metric.loc.lloc(), 2);
5725 assert_eq!(metric.loc.cloc(), 0);
5726 assert_eq!(metric.loc.blank(), 0);
5727 insta::assert_json_snapshot!(metric.loc);
5728 });
5729 }
5730
5731 #[test]
5732 fn tcl_if_lloc() {
5733 check_metrics::<TclParser>("if {1} {\n puts hello\n}", "foo.tcl", |metric| {
5734 assert_eq!(metric.loc.sloc(), 3);
5735 assert_eq!(metric.loc.ploc(), 3);
5736 assert_eq!(metric.loc.lloc(), 2);
5737 assert_eq!(metric.loc.cloc(), 0);
5738 assert_eq!(metric.loc.blank(), 0);
5739 insta::assert_json_snapshot!(metric.loc);
5740 });
5741 }
5742
5743 #[test]
5744 fn tcl_elseif_lloc() {
5745 check_metrics::<TclParser>(
5747 "if {$x > 10} {
5748 puts big
5749} elseif {$x > 5} {
5750 puts medium
5751} else {
5752 puts small
5753}",
5754 "foo.tcl",
5755 |metric| {
5756 assert_eq!(metric.loc.sloc(), 7);
5757 assert_eq!(metric.loc.ploc(), 7);
5758 assert_eq!(metric.loc.lloc(), 5);
5759 assert_eq!(metric.loc.cloc(), 0);
5760 assert_eq!(metric.loc.blank(), 0);
5761 insta::assert_json_snapshot!(metric.loc);
5762 },
5763 );
5764 }
5765
5766 #[test]
5767 fn tcl_while_lloc() {
5768 check_metrics::<TclParser>(
5769 "while {$x > 0} {\n set x [expr {$x - 1}]\n}",
5770 "foo.tcl",
5771 |metric| {
5772 assert_eq!(metric.loc.sloc(), 3);
5773 assert_eq!(metric.loc.ploc(), 3);
5774 assert_eq!(metric.loc.lloc(), 2);
5775 assert_eq!(metric.loc.cloc(), 0);
5776 assert_eq!(metric.loc.blank(), 0);
5777 insta::assert_json_snapshot!(metric.loc);
5778 },
5779 );
5780 }
5781
5782 #[test]
5783 fn tcl_foreach_lloc() {
5784 check_metrics::<TclParser>(
5785 "foreach item {a b c} {\n puts $item\n}",
5786 "foo.tcl",
5787 |metric| {
5788 assert_eq!(metric.loc.sloc(), 3);
5789 assert_eq!(metric.loc.ploc(), 3);
5790 assert_eq!(metric.loc.lloc(), 2);
5791 assert_eq!(metric.loc.cloc(), 0);
5792 assert_eq!(metric.loc.blank(), 0);
5793 insta::assert_json_snapshot!(metric.loc);
5794 },
5795 );
5796 }
5797
5798 #[test]
5799 fn tcl_set_lloc() {
5800 check_metrics::<TclParser>("set x 42", "foo.tcl", |metric| {
5801 assert_eq!(metric.loc.sloc(), 1);
5802 assert_eq!(metric.loc.ploc(), 1);
5803 assert_eq!(metric.loc.lloc(), 1);
5804 assert_eq!(metric.loc.cloc(), 0);
5805 assert_eq!(metric.loc.blank(), 0);
5806 insta::assert_json_snapshot!(metric.loc);
5807 });
5808 }
5809
5810 #[test]
5811 fn tcl_global_lloc() {
5812 check_metrics::<TclParser>("global x", "foo.tcl", |metric| {
5813 assert_eq!(metric.loc.sloc(), 1);
5814 assert_eq!(metric.loc.ploc(), 1);
5815 assert_eq!(metric.loc.lloc(), 1);
5816 assert_eq!(metric.loc.cloc(), 0);
5817 assert_eq!(metric.loc.blank(), 0);
5818 insta::assert_json_snapshot!(metric.loc);
5819 });
5820 }
5821
5822 #[test]
5823 fn tcl_try_catch_lloc() {
5824 check_metrics::<TclParser>(
5826 "catch {
5827 set x 1
5828} result
5829try {
5830 set y 2
5831} on error {msg} {
5832 puts $msg
5833}",
5834 "foo.tcl",
5835 |metric| {
5836 assert_eq!(metric.loc.sloc(), 8);
5837 assert_eq!(metric.loc.ploc(), 8);
5838 assert_eq!(metric.loc.lloc(), 5);
5839 assert_eq!(metric.loc.cloc(), 0);
5840 assert_eq!(metric.loc.blank(), 0);
5841 insta::assert_json_snapshot!(metric.loc);
5842 },
5843 );
5844 }
5845
5846 #[test]
5847 fn tcl_namespace_lloc() {
5848 check_metrics::<TclParser>(
5849 "namespace eval myns {\n set x 1\n}",
5850 "foo.tcl",
5851 |metric| {
5852 assert_eq!(metric.loc.sloc(), 3);
5853 assert_eq!(metric.loc.ploc(), 3);
5854 assert_eq!(metric.loc.lloc(), 2);
5855 assert_eq!(metric.loc.cloc(), 0);
5856 assert_eq!(metric.loc.blank(), 0);
5857 insta::assert_json_snapshot!(metric.loc);
5858 },
5859 );
5860 }
5861
5862 #[test]
5863 fn tcl_regexp_lloc() {
5864 check_metrics::<TclParser>("regexp {^[0-9]+$} $x", "foo.tcl", |metric| {
5865 assert_eq!(metric.loc.sloc(), 1);
5866 assert_eq!(metric.loc.ploc(), 1);
5867 assert_eq!(metric.loc.lloc(), 1);
5868 assert_eq!(metric.loc.cloc(), 0);
5869 assert_eq!(metric.loc.blank(), 0);
5870 insta::assert_json_snapshot!(metric.loc);
5871 });
5872 }
5873
5874 #[test]
5875 fn tcl_expr_cmd_lloc() {
5876 check_metrics::<TclParser>("expr {1 + 2}", "foo.tcl", |metric| {
5877 assert_eq!(metric.loc.sloc(), 1);
5878 assert_eq!(metric.loc.ploc(), 1);
5879 assert_eq!(metric.loc.lloc(), 1);
5880 assert_eq!(metric.loc.cloc(), 0);
5881 assert_eq!(metric.loc.blank(), 0);
5882 insta::assert_json_snapshot!(metric.loc);
5883 });
5884 }
5885
5886 #[test]
5887 fn tcl_no_expr_cmd_substitution_lloc() {
5888 check_metrics::<TclParser>("set x [expr {1 + 2}]", "foo.tcl", |metric| {
5890 assert_eq!(metric.loc.sloc(), 1);
5891 assert_eq!(metric.loc.ploc(), 1);
5892 assert_eq!(metric.loc.lloc(), 1);
5893 assert_eq!(metric.loc.cloc(), 0);
5894 assert_eq!(metric.loc.blank(), 0);
5895 insta::assert_json_snapshot!(metric.loc);
5896 });
5897 }
5898
5899 #[test]
5900 fn tcl_nested_commands_lloc() {
5901 check_metrics::<TclParser>(
5903 "proc f {x} {
5904 set y [expr {$x * 2}]
5905 puts $y
5906}",
5907 "foo.tcl",
5908 |metric| {
5909 assert_eq!(metric.loc.sloc(), 4);
5910 assert_eq!(metric.loc.ploc(), 4);
5911 assert_eq!(metric.loc.lloc(), 3);
5912 assert_eq!(metric.loc.cloc(), 0);
5913 assert_eq!(metric.loc.blank(), 0);
5914 insta::assert_json_snapshot!(metric.loc);
5915 },
5916 );
5917 }
5918
5919 #[test]
5920 fn tcl_command_lloc() {
5921 check_metrics::<TclParser>("puts hello", "foo.tcl", |metric| {
5922 assert_eq!(metric.loc.sloc(), 1);
5923 assert_eq!(metric.loc.ploc(), 1);
5924 assert_eq!(metric.loc.lloc(), 1);
5925 assert_eq!(metric.loc.cloc(), 0);
5926 assert_eq!(metric.loc.blank(), 0);
5927 insta::assert_json_snapshot!(metric.loc);
5928 });
5929 }
5930
5931 #[test]
5932 fn tcl_no_else_lloc() {
5933 check_metrics::<TclParser>(
5935 "if {1} {\n puts yes\n} else {\n puts no\n}",
5936 "foo.tcl",
5937 |metric| {
5938 assert_eq!(metric.loc.sloc(), 5);
5939 assert_eq!(metric.loc.ploc(), 5);
5940 assert_eq!(metric.loc.lloc(), 3);
5941 assert_eq!(metric.loc.cloc(), 0);
5942 assert_eq!(metric.loc.blank(), 0);
5943 insta::assert_json_snapshot!(metric.loc);
5944 },
5945 );
5946 }
5947
5948 #[test]
5949 fn tcl_no_finally_lloc() {
5950 check_metrics::<TclParser>(
5953 "proc f {} {\n try {\n puts hi\n } finally {\n puts done\n }\n}",
5954 "foo.tcl",
5955 |metric| {
5956 assert_eq!(
5957 metric.loc.lloc(),
5958 4,
5959 "finally adds 0 lloc; would be 5 if finally counted"
5960 );
5961 },
5962 );
5963 }
5964
5965 #[test]
5966 fn tcl_multiline_block() {
5967 check_metrics::<TclParser>(
5968 "proc f {x} {
5969 set a 1
5970
5971 set b 2
5972 return [expr {$a + $b}]
5973}",
5974 "foo.tcl",
5975 |metric| {
5976 assert_eq!(metric.loc.sloc(), 6);
5977 assert_eq!(metric.loc.ploc(), 5);
5978 assert_eq!(metric.loc.lloc(), 4);
5979 assert_eq!(metric.loc.cloc(), 0);
5980 assert_eq!(metric.loc.blank(), 1);
5981 insta::assert_json_snapshot!(metric.loc);
5982 },
5983 );
5984 }
5985
5986 #[test]
5987 fn tcl_no_string_lloc() {
5988 check_metrics::<TclParser>(
5993 "set s \"line one\nline two\nline three\"",
5994 "foo.tcl",
5995 |metric| {
5996 assert_eq!(metric.loc.sloc(), 3);
5997 assert_eq!(metric.loc.ploc(), 2);
5998 assert_eq!(metric.loc.lloc(), 1);
5999 assert_eq!(metric.loc.cloc(), 0);
6000 assert_eq!(metric.loc.blank(), 1);
6001 insta::assert_json_snapshot!(metric.loc);
6002 },
6003 );
6004 }
6005
6006 #[test]
6007 fn javascript_blank() {
6008 check_metrics::<JavascriptParser>(
6009 "// header comment
6010 function f() {
6011
6012 var x = 1;
6013
6014 var y = 2;
6015 }",
6016 "foo.js",
6017 |metric| {
6018 assert_eq!(metric.loc.sloc(), 7);
6019 assert_eq!(metric.loc.ploc(), 4);
6020 assert_eq!(metric.loc.lloc(), 0);
6021 assert_eq!(metric.loc.cloc(), 1);
6022 assert_eq!(metric.loc.blank(), 2);
6023 insta::assert_json_snapshot!(metric.loc);
6024 },
6025 );
6026 }
6027
6028 #[test]
6029 fn javascript_cloc() {
6030 check_metrics::<JavascriptParser>(
6031 "// line comment
6032 /* block
6033 comment */
6034 function f() {
6035 return 1; // inline
6036 }",
6037 "foo.js",
6038 |metric| {
6039 assert_eq!(metric.loc.sloc(), 6);
6040 assert_eq!(metric.loc.ploc(), 3);
6041 assert_eq!(metric.loc.lloc(), 1);
6042 assert_eq!(metric.loc.cloc(), 4);
6043 assert_eq!(metric.loc.blank(), 0);
6044 insta::assert_json_snapshot!(metric.loc);
6045 },
6046 );
6047 }
6048
6049 #[test]
6050 fn javascript_cloc_html_comment() {
6051 check_metrics::<JavascriptParser>(
6055 "<!-- header comment -->
6056function f() {
6057 return 1;
6058}",
6059 "foo.js",
6060 |metric| {
6061 assert_eq!(metric.loc.sloc(), 4);
6062 assert_eq!(metric.loc.ploc(), 3);
6063 assert_eq!(metric.loc.lloc(), 1);
6064 assert_eq!(metric.loc.cloc(), 1);
6065 assert_eq!(metric.loc.blank(), 0);
6066 },
6067 );
6068 }
6069
6070 #[test]
6071 fn mozjs_blank() {
6072 check_metrics::<MozjsParser>(
6073 "function f() {
6074
6075 var x = 1;
6076
6077 }",
6078 "foo.js",
6079 |metric| {
6080 assert_eq!(metric.loc.sloc(), 5);
6081 assert_eq!(metric.loc.ploc(), 3);
6082 assert_eq!(metric.loc.lloc(), 0);
6083 assert_eq!(metric.loc.cloc(), 0);
6084 assert_eq!(metric.loc.blank(), 2);
6085 insta::assert_json_snapshot!(metric.loc);
6086 },
6087 );
6088 }
6089
6090 #[test]
6091 fn mozjs_cloc() {
6092 check_metrics::<MozjsParser>(
6093 "// header
6094 /* block comment */
6095 function f() {
6096 return 42;
6097 }",
6098 "foo.js",
6099 |metric| {
6100 assert_eq!(metric.loc.sloc(), 5);
6101 assert_eq!(metric.loc.ploc(), 3);
6102 assert_eq!(metric.loc.lloc(), 1);
6103 assert_eq!(metric.loc.cloc(), 2);
6104 assert_eq!(metric.loc.blank(), 0);
6105 insta::assert_json_snapshot!(metric.loc);
6106 },
6107 );
6108 }
6109
6110 #[test]
6111 fn mozjs_no_zero_blank() {
6112 check_metrics::<MozjsParser>(
6115 "function f() {
6116 var a = 1;
6117
6118 var b = 2; // trailing
6119 var c = 3; // trailing
6120}",
6121 "foo.js",
6122 |metric| {
6123 assert_eq!(metric.loc.sloc(), 6);
6124 assert_eq!(metric.loc.ploc(), 5);
6125 assert_eq!(metric.loc.cloc(), 2);
6126 assert_eq!(metric.loc.blank(), 1);
6127 insta::assert_json_snapshot!(metric.loc);
6128 },
6129 );
6130 }
6131
6132 #[test]
6133 fn mozjs_arrow_function_loc() {
6134 check_metrics::<MozjsParser>(
6135 "const add = (a, b) => a + b;
6136 const greet = name => {
6137 return 'Hello ' + name;
6138 };",
6139 "foo.js",
6140 |metric| {
6141 assert_eq!(metric.loc.sloc(), 4);
6142 assert_eq!(metric.loc.ploc(), 4);
6143 assert_eq!(metric.loc.lloc(), 1);
6144 assert_eq!(metric.loc.cloc(), 0);
6145 assert_eq!(metric.loc.blank(), 0);
6146 insta::assert_json_snapshot!(metric.loc);
6147 },
6148 );
6149 }
6150
6151 #[test]
6152 fn mozjs_multiple_functions_loc() {
6153 check_metrics::<MozjsParser>(
6154 "function f() {
6155 return 1;
6156 }
6157 function g() {
6158 return 2;
6159 }",
6160 "foo.js",
6161 |metric| {
6162 assert_eq!(metric.loc.sloc(), 6);
6163 assert_eq!(metric.loc.ploc(), 6);
6164 assert_eq!(metric.loc.lloc(), 2);
6165 assert_eq!(metric.loc.cloc(), 0);
6166 assert_eq!(metric.loc.blank(), 0);
6167 insta::assert_json_snapshot!(metric.loc);
6168 },
6169 );
6170 }
6171
6172 #[test]
6173 fn mozjs_nested_function_loc() {
6174 check_metrics::<MozjsParser>(
6175 "function outer() {
6176 function inner() {
6177 return 1;
6178 }
6179 return inner();
6180 }",
6181 "foo.js",
6182 |metric| {
6183 assert_eq!(metric.loc.sloc(), 6);
6184 assert_eq!(metric.loc.ploc(), 6);
6185 assert_eq!(metric.loc.lloc(), 2);
6186 assert_eq!(metric.loc.cloc(), 0);
6187 assert_eq!(metric.loc.blank(), 0);
6188 insta::assert_json_snapshot!(metric.loc);
6189 },
6190 );
6191 }
6192
6193 #[test]
6194 fn mozjs_if_lloc() {
6195 check_metrics::<MozjsParser>(
6196 "function f(x) {
6197 if (x > 0) {
6198 return 1;
6199 } else {
6200 return -1;
6201 }
6202 }",
6203 "foo.js",
6204 |metric| {
6205 assert_eq!(metric.loc.sloc(), 7);
6206 assert_eq!(metric.loc.ploc(), 7);
6207 assert_eq!(metric.loc.lloc(), 3);
6214 assert_eq!(metric.loc.cloc(), 0);
6215 assert_eq!(metric.loc.blank(), 0);
6216 insta::assert_json_snapshot!(metric.loc);
6217 },
6218 );
6219 }
6220
6221 #[test]
6228 fn js_family_if_lloc_matches_c_and_rust() {
6229 const JS_SRC: &str = "function f(x) {
6230 if (x > 0) {
6231 return 1;
6232 } else {
6233 return -1;
6234 }
6235 }";
6236 const C_SRC: &str = "int f(int x) {
6237 if (x > 0) {
6238 return 1;
6239 } else {
6240 return -1;
6241 }
6242 }";
6243 const RUST_SRC: &str = "fn f(x: i32) -> i32 {
6244 if x > 0 {
6245 return 1;
6246 } else {
6247 return -1;
6248 }
6249 }";
6250
6251 const EXPECTED_LLOC: usize = 3;
6254
6255 check_metrics::<CppParser>(C_SRC, "f.c", |m| {
6256 assert_eq!(m.loc.lloc() as usize, EXPECTED_LLOC);
6257 });
6258 check_metrics::<RustParser>(RUST_SRC, "f.rs", |m| {
6259 assert_eq!(m.loc.lloc() as usize, EXPECTED_LLOC);
6260 });
6261 check_metrics::<MozjsParser>(JS_SRC, "f.js", |m| {
6262 assert_eq!(m.loc.lloc() as usize, EXPECTED_LLOC);
6263 });
6264 check_metrics::<JavascriptParser>(JS_SRC, "f.js", |m| {
6265 assert_eq!(m.loc.lloc() as usize, EXPECTED_LLOC);
6266 });
6267 check_metrics::<TypescriptParser>(JS_SRC, "f.ts", |m| {
6268 assert_eq!(m.loc.lloc() as usize, EXPECTED_LLOC);
6269 });
6270 check_metrics::<TsxParser>(JS_SRC, "f.tsx", |m| {
6271 assert_eq!(m.loc.lloc() as usize, EXPECTED_LLOC);
6272 });
6273 }
6274
6275 #[test]
6276 fn mozjs_for_lloc() {
6277 check_metrics::<MozjsParser>(
6278 "function f(n) {
6279 var s = 0;
6280 for (var i = 0; i < n; i++) {
6281 s += i;
6282 }
6283 return s;
6284 }",
6285 "foo.js",
6286 |metric| {
6287 assert_eq!(metric.loc.sloc(), 7);
6288 assert_eq!(metric.loc.ploc(), 7);
6289 assert_eq!(metric.loc.lloc(), 3);
6290 assert_eq!(metric.loc.cloc(), 0);
6291 assert_eq!(metric.loc.blank(), 0);
6292 insta::assert_json_snapshot!(metric.loc);
6293 },
6294 );
6295 }
6296
6297 #[test]
6298 fn bash_blank() {
6299 check_metrics::<BashParser>(
6300 "#!/bin/bash
6301
6302 f() {
6303
6304 echo hello
6305
6306 }",
6307 "foo.sh",
6308 |metric| {
6309 assert_eq!(metric.loc.sloc(), 7);
6310 assert_eq!(metric.loc.ploc(), 3);
6311 assert_eq!(metric.loc.lloc(), 2);
6312 assert_eq!(metric.loc.cloc(), 1);
6313 assert_eq!(metric.loc.blank(), 3);
6314 insta::assert_json_snapshot!(metric.loc);
6315 },
6316 );
6317 }
6318
6319 #[test]
6320 fn bash_cloc() {
6321 check_metrics::<BashParser>(
6322 "# header comment
6323 f() {
6324 # body comment
6325 echo hello
6326 }",
6327 "foo.sh",
6328 |metric| {
6329 assert_eq!(metric.loc.sloc(), 5);
6330 assert_eq!(metric.loc.ploc(), 3);
6331 assert_eq!(metric.loc.lloc(), 2);
6332 assert_eq!(metric.loc.cloc(), 2);
6333 assert_eq!(metric.loc.blank(), 0);
6334 insta::assert_json_snapshot!(metric.loc);
6335 },
6336 );
6337 }
6338
6339 #[test]
6340 fn bash_no_zero_blank() {
6341 check_metrics::<BashParser>(
6344 "f() {
6345 echo a
6346
6347 echo b # trailing
6348 echo c # trailing
6349}",
6350 "foo.sh",
6351 |metric| {
6352 assert_eq!(metric.loc.sloc(), 6);
6353 assert_eq!(metric.loc.ploc(), 5);
6354 assert_eq!(metric.loc.cloc(), 2);
6355 assert_eq!(metric.loc.blank(), 1);
6356 insta::assert_json_snapshot!(metric.loc);
6357 },
6358 );
6359 }
6360
6361 #[test]
6362 fn bash_comment_before_code_line_reclassified() {
6363 check_metrics::<BashParser>("echo a\n\necho \"$(\n # c\n)\"\n", "foo.sh", |metric| {
6381 assert_eq!(metric.loc.sloc(), 5);
6382 assert_eq!(metric.loc.ploc(), 4);
6383 assert_eq!(metric.loc.lloc(), 3);
6384 assert_eq!(metric.loc.cloc(), 1);
6385 assert_eq!(metric.loc.blank(), 1);
6386 insta::assert_json_snapshot!(
6387 metric.loc,
6388 @r#"
6389 {
6390 "sloc": 5,
6391 "ploc": 4,
6392 "lloc": 3,
6393 "cloc": 1,
6394 "blank": 1,
6395 "sloc_average": 5.0,
6396 "ploc_average": 4.0,
6397 "lloc_average": 3.0,
6398 "cloc_average": 1.0,
6399 "blank_average": 1.0,
6400 "sloc_min": 5,
6401 "sloc_max": 5,
6402 "cloc_min": 1,
6403 "cloc_max": 1,
6404 "ploc_min": 4,
6405 "ploc_max": 4,
6406 "lloc_min": 3,
6407 "lloc_max": 3,
6408 "blank_min": 1,
6409 "blank_max": 1
6410 }
6411 "#
6412 );
6413 });
6414 }
6415
6416 #[test]
6417 fn bash_if_lloc() {
6418 check_metrics::<BashParser>(
6419 "f() {
6420 if [ $1 -gt 0 ]; then
6421 echo positive
6422 else
6423 echo negative
6424 fi
6425 }",
6426 "foo.sh",
6427 |metric| {
6428 assert_eq!(metric.loc.sloc(), 7);
6429 assert_eq!(metric.loc.ploc(), 7);
6430 assert_eq!(metric.loc.lloc(), 4);
6431 assert_eq!(metric.loc.cloc(), 0);
6432 assert_eq!(metric.loc.blank(), 0);
6433 insta::assert_json_snapshot!(metric.loc);
6434 },
6435 );
6436 }
6437
6438 #[test]
6439 fn bash_for_lloc() {
6440 check_metrics::<BashParser>(
6441 "f() {
6442 for i in 1 2 3; do
6443 echo $i
6444 done
6445 }",
6446 "foo.sh",
6447 |metric| {
6448 assert_eq!(metric.loc.sloc(), 5);
6449 assert_eq!(metric.loc.ploc(), 5);
6450 assert_eq!(metric.loc.lloc(), 3);
6451 assert_eq!(metric.loc.cloc(), 0);
6452 assert_eq!(metric.loc.blank(), 0);
6453 insta::assert_json_snapshot!(metric.loc);
6454 },
6455 );
6456 }
6457
6458 #[test]
6459 fn bash_while_lloc() {
6460 check_metrics::<BashParser>(
6461 "f() {
6462 local n=5
6463 while [ $n -gt 0 ]; do
6464 echo $n
6465 n=$((n - 1))
6466 done
6467 }",
6468 "foo.sh",
6469 |metric| {
6470 assert_eq!(metric.loc.sloc(), 7);
6471 assert_eq!(metric.loc.ploc(), 7);
6472 assert_eq!(metric.loc.lloc(), 4);
6473 assert_eq!(metric.loc.cloc(), 0);
6474 assert_eq!(metric.loc.blank(), 0);
6475 insta::assert_json_snapshot!(metric.loc);
6476 },
6477 );
6478 }
6479
6480 #[test]
6481 fn bash_case_lloc() {
6482 check_metrics::<BashParser>(
6483 "f() {
6484 case $1 in
6485 start) echo starting ;;
6486 stop) echo stopping ;;
6487 *) echo unknown ;;
6488 esac
6489 }",
6490 "foo.sh",
6491 |metric| {
6492 assert_eq!(metric.loc.sloc(), 7);
6493 assert_eq!(metric.loc.ploc(), 7);
6494 assert_eq!(metric.loc.lloc(), 5);
6495 assert_eq!(metric.loc.cloc(), 0);
6496 assert_eq!(metric.loc.blank(), 0);
6497 insta::assert_json_snapshot!(metric.loc);
6498 },
6499 );
6500 }
6501
6502 #[test]
6503 fn bash_multiple_functions_loc() {
6504 check_metrics::<BashParser>(
6505 "f() {
6506 echo hello
6507 }
6508 g() {
6509 echo world
6510 }",
6511 "foo.sh",
6512 |metric| {
6513 assert_eq!(metric.loc.sloc(), 6);
6514 assert_eq!(metric.loc.ploc(), 6);
6515 assert_eq!(metric.loc.lloc(), 4);
6516 assert_eq!(metric.loc.cloc(), 0);
6517 assert_eq!(metric.loc.blank(), 0);
6518 insta::assert_json_snapshot!(metric.loc);
6519 },
6520 );
6521 }
6522
6523 #[test]
6524 fn bash_nested_function_loc() {
6525 check_metrics::<BashParser>(
6526 "outer() {
6527 inner() {
6528 echo inner
6529 }
6530 inner
6531 echo outer
6532 }",
6533 "foo.sh",
6534 |metric| {
6535 assert_eq!(metric.loc.sloc(), 7);
6536 assert_eq!(metric.loc.ploc(), 7);
6537 assert_eq!(metric.loc.lloc(), 5);
6538 assert_eq!(metric.loc.cloc(), 0);
6539 assert_eq!(metric.loc.blank(), 0);
6540 insta::assert_json_snapshot!(metric.loc);
6541 },
6542 );
6543 }
6544
6545 #[test]
6546 fn bash_heredoc_loc() {
6547 check_metrics::<BashParser>(
6548 "f() {
6549 cat <<EOF
6550line1
6551line2
6552EOF
6553 }",
6554 "foo.sh",
6555 |metric| {
6556 assert_eq!(metric.loc.sloc(), 6);
6557 assert_eq!(metric.loc.ploc(), 5);
6558 assert_eq!(metric.loc.lloc(), 2);
6559 assert_eq!(metric.loc.cloc(), 0);
6560 assert_eq!(metric.loc.blank(), 1);
6561 insta::assert_json_snapshot!(metric.loc);
6562 },
6563 );
6564 }
6565
6566 #[test]
6567 fn kotlin_loc_blank() {
6568 check_metrics::<KotlinParser>(
6569 "fun f(): Int {
6570
6571 val x = 1
6572
6573 return x
6574 }",
6575 "foo.kt",
6576 |metric| {
6577 assert_eq!(metric.loc.sloc(), 6);
6578 assert_eq!(metric.loc.ploc(), 4);
6579 assert_eq!(metric.loc.lloc(), 2);
6580 assert_eq!(metric.loc.cloc(), 0);
6581 assert_eq!(metric.loc.blank(), 2);
6582 insta::assert_json_snapshot!(metric.loc);
6583 },
6584 );
6585 }
6586
6587 #[test]
6588 fn kotlin_loc_cloc() {
6589 check_metrics::<KotlinParser>(
6590 "// header comment
6591 /* block
6592 comment */
6593 fun f(): Int {
6594 return 42 // inline
6595 }",
6596 "foo.kt",
6597 |metric| {
6598 assert_eq!(metric.loc.sloc(), 6);
6599 assert_eq!(metric.loc.ploc(), 3);
6600 assert_eq!(metric.loc.lloc(), 1);
6601 assert_eq!(metric.loc.cloc(), 4);
6602 assert_eq!(metric.loc.blank(), 0);
6603 insta::assert_json_snapshot!(metric.loc);
6604 },
6605 );
6606 }
6607
6608 #[test]
6609 fn kotlin_loc_no_zero_blank() {
6610 check_metrics::<KotlinParser>(
6613 "fun connectToUpdateServer() {
6614 val pool = 0
6615
6616 val updateServer = -42
6617 val isConnected = false
6618 val currTry = 0
6619 val numRetries = 10 // Number of IPC connection retries before
6620 // giving up.
6621 val numTries = 20 // Number of IPC connection tries before
6622 // giving up.
6623 }",
6624 "foo.kt",
6625 |metric| {
6626 assert_eq!(metric.loc.sloc(), 11);
6629 assert_eq!(metric.loc.ploc(), 8);
6630 assert_eq!(metric.loc.cloc(), 4);
6631 assert_eq!(metric.loc.blank(), 1);
6632 insta::assert_json_snapshot!(
6633 metric.loc,
6634 @r#"
6635 {
6636 "sloc": 11,
6637 "ploc": 8,
6638 "lloc": 6,
6639 "cloc": 4,
6640 "blank": 1,
6641 "sloc_average": 5.5,
6642 "ploc_average": 4.0,
6643 "lloc_average": 3.0,
6644 "cloc_average": 2.0,
6645 "blank_average": 0.5,
6646 "sloc_min": 11,
6647 "sloc_max": 11,
6648 "cloc_min": 4,
6649 "cloc_max": 4,
6650 "ploc_min": 8,
6651 "ploc_max": 8,
6652 "lloc_min": 6,
6653 "lloc_max": 6,
6654 "blank_min": 1,
6655 "blank_max": 1
6656 }
6657 "#
6658 );
6659 },
6660 );
6661 }
6662
6663 #[test]
6664 fn kotlin_loc_blank_zero_sanity() {
6665 check_metrics::<KotlinParser>(
6670 "fun f(): Int {
6671 val x = 1 // x
6672 val y = 2 // y
6673 return x + y
6674 }",
6675 "foo.kt",
6676 |metric| {
6677 assert_eq!(metric.loc.sloc(), 5);
6678 assert_eq!(metric.loc.ploc(), 5);
6679 assert_eq!(metric.loc.lloc(), 3);
6680 assert_eq!(metric.loc.cloc(), 2);
6681 assert_eq!(metric.loc.blank(), 0);
6682 },
6683 );
6684 }
6685
6686 #[test]
6687 fn kotlin_loc_if_lloc() {
6688 check_metrics::<KotlinParser>(
6689 "fun classify(n: Int): String {
6690 if (n > 0) {
6691 return \"positive\"
6692 } else if (n < 0) {
6693 return \"negative\"
6694 }
6695 return \"zero\"
6696 }",
6697 "foo.kt",
6698 |metric| {
6699 assert_eq!(metric.loc.sloc(), 8);
6700 assert_eq!(metric.loc.ploc(), 8);
6701 assert_eq!(metric.loc.lloc(), 5);
6702 assert_eq!(metric.loc.cloc(), 0);
6703 assert_eq!(metric.loc.blank(), 0);
6704 insta::assert_json_snapshot!(metric.loc);
6705 },
6706 );
6707 }
6708
6709 #[test]
6710 fn kotlin_loc_for_lloc() {
6711 check_metrics::<KotlinParser>(
6712 "fun sum(n: Int): Int {
6713 var s = 0
6714 for (i in 1..n) {
6715 s += i
6716 }
6717 return s
6718 }",
6719 "foo.kt",
6720 |metric| {
6721 assert_eq!(metric.loc.sloc(), 7);
6722 assert_eq!(metric.loc.ploc(), 7);
6723 assert_eq!(metric.loc.lloc(), 4);
6724 assert_eq!(metric.loc.cloc(), 0);
6725 assert_eq!(metric.loc.blank(), 0);
6726 insta::assert_json_snapshot!(metric.loc);
6727 },
6728 );
6729 }
6730
6731 #[test]
6732 fn kotlin_loc_when_lloc() {
6733 check_metrics::<KotlinParser>(
6734 "fun describe(x: Int): String {
6735 return when (x) {
6736 1 -> \"one\"
6737 2 -> \"two\"
6738 else -> \"other\"
6739 }
6740 }",
6741 "foo.kt",
6742 |metric| {
6743 assert_eq!(metric.loc.sloc(), 7);
6744 assert_eq!(metric.loc.ploc(), 7);
6745 assert_eq!(metric.loc.lloc(), 2);
6746 assert_eq!(metric.loc.cloc(), 0);
6747 assert_eq!(metric.loc.blank(), 0);
6748 insta::assert_json_snapshot!(metric.loc);
6749 },
6750 );
6751 }
6752
6753 #[test]
6754 fn kotlin_loc_lambda_lloc() {
6755 check_metrics::<KotlinParser>(
6756 "fun f(list: List<Int>): List<Int> {
6757 return list.filter { it > 0 }
6758 .map { it * 2 }
6759 }",
6760 "foo.kt",
6761 |metric| {
6762 assert_eq!(metric.loc.sloc(), 4);
6763 assert_eq!(metric.loc.ploc(), 4);
6764 assert_eq!(metric.loc.lloc(), 1);
6765 assert_eq!(metric.loc.cloc(), 0);
6766 assert_eq!(metric.loc.blank(), 0);
6767 insta::assert_json_snapshot!(metric.loc);
6768 },
6769 );
6770 }
6771
6772 #[test]
6773 fn kotlin_loc_class_loc() {
6774 check_metrics::<KotlinParser>(
6775 "class Counter {
6776 private var count = 0
6777 fun increment() { count++ }
6778 fun get(): Int = count
6779 }",
6780 "foo.kt",
6781 |metric| {
6782 assert_eq!(metric.loc.sloc(), 5);
6783 assert_eq!(metric.loc.ploc(), 5);
6784 assert_eq!(metric.loc.lloc(), 1);
6785 assert_eq!(metric.loc.cloc(), 0);
6786 assert_eq!(metric.loc.blank(), 0);
6787 insta::assert_json_snapshot!(metric.loc);
6788 },
6789 );
6790 }
6791
6792 #[test]
6793 fn kotlin_loc_multiple_functions_loc() {
6794 check_metrics::<KotlinParser>(
6795 "fun f(): Int {
6796 return 1
6797 }
6798 fun g(): Int {
6799 return 2
6800 }",
6801 "foo.kt",
6802 |metric| {
6803 assert_eq!(metric.loc.sloc(), 6);
6804 assert_eq!(metric.loc.ploc(), 6);
6805 assert_eq!(metric.loc.lloc(), 2);
6806 assert_eq!(metric.loc.cloc(), 0);
6807 assert_eq!(metric.loc.blank(), 0);
6808 insta::assert_json_snapshot!(metric.loc);
6809 },
6810 );
6811 }
6812
6813 #[test]
6814 fn kotlin_loc_while_lloc() {
6815 check_metrics::<KotlinParser>(
6816 "fun countdown(n: Int) {
6817 var i = n
6818 while (i > 0) {
6819 println(i)
6820 i--
6821 }
6822 }",
6823 "foo.kt",
6824 |metric| {
6825 assert_eq!(metric.loc.sloc(), 7);
6826 assert_eq!(metric.loc.ploc(), 7);
6827 assert_eq!(metric.loc.lloc(), 3);
6828 assert_eq!(metric.loc.cloc(), 0);
6829 assert_eq!(metric.loc.blank(), 0);
6830 insta::assert_json_snapshot!(metric.loc);
6831 },
6832 );
6833 }
6834
6835 #[test]
6836 fn typescript_blank() {
6837 check_metrics::<TypescriptParser>(
6838 "function f(): void {
6839
6840 const x = 1;
6841
6842 }",
6843 "foo.ts",
6844 |metric| {
6845 assert_eq!(metric.loc.sloc(), 5);
6846 assert_eq!(metric.loc.ploc(), 3);
6847 assert_eq!(metric.loc.lloc(), 0);
6848 assert_eq!(metric.loc.cloc(), 0);
6849 assert_eq!(metric.loc.blank(), 2);
6850 insta::assert_json_snapshot!(metric.loc);
6851 },
6852 );
6853 }
6854
6855 #[test]
6856 fn typescript_cloc() {
6857 check_metrics::<TypescriptParser>(
6858 "// header
6859 /* block
6860 comment */
6861 function f(): number {
6862 return 42; // inline
6863 }",
6864 "foo.ts",
6865 |metric| {
6866 assert_eq!(metric.loc.sloc(), 6);
6867 assert_eq!(metric.loc.ploc(), 3);
6868 assert_eq!(metric.loc.lloc(), 1);
6869 assert_eq!(metric.loc.cloc(), 4);
6870 assert_eq!(metric.loc.blank(), 0);
6871 insta::assert_json_snapshot!(metric.loc);
6872 },
6873 );
6874 }
6875
6876 #[test]
6877 fn typescript_no_zero_blank() {
6878 check_metrics::<TypescriptParser>(
6881 "function f(): void {
6882 const a = 1;
6883
6884 const b = 2; // trailing
6885 const c = 3; // trailing
6886}",
6887 "foo.ts",
6888 |metric| {
6889 assert_eq!(metric.loc.sloc(), 6);
6890 assert_eq!(metric.loc.ploc(), 5);
6891 assert_eq!(metric.loc.cloc(), 2);
6892 assert_eq!(metric.loc.blank(), 1);
6893 insta::assert_json_snapshot!(metric.loc);
6894 },
6895 );
6896 }
6897
6898 #[test]
6899 fn typescript_if_lloc() {
6900 check_metrics::<TypescriptParser>(
6901 "function classify(n: number): string {
6902 if (n > 0) {
6903 return 'positive';
6904 } else {
6905 return 'non-positive';
6906 }
6907 }",
6908 "foo.ts",
6909 |metric| {
6910 assert_eq!(metric.loc.sloc(), 7);
6911 assert_eq!(metric.loc.ploc(), 7);
6912 assert_eq!(metric.loc.lloc(), 3);
6913 assert_eq!(metric.loc.cloc(), 0);
6914 assert_eq!(metric.loc.blank(), 0);
6915 insta::assert_json_snapshot!(metric.loc);
6916 },
6917 );
6918 }
6919
6920 #[test]
6921 fn typescript_for_lloc() {
6922 check_metrics::<TypescriptParser>(
6923 "function sum(n: number): number {
6924 let s = 0;
6925 for (let i = 0; i < n; i++) {
6926 s += i;
6927 }
6928 return s;
6929 }",
6930 "foo.ts",
6931 |metric| {
6932 assert_eq!(metric.loc.sloc(), 7);
6933 assert_eq!(metric.loc.ploc(), 7);
6934 assert_eq!(metric.loc.lloc(), 3);
6935 assert_eq!(metric.loc.cloc(), 0);
6936 assert_eq!(metric.loc.blank(), 0);
6937 insta::assert_json_snapshot!(metric.loc);
6938 },
6939 );
6940 }
6941
6942 #[test]
6943 fn typescript_while_lloc() {
6944 check_metrics::<TypescriptParser>(
6945 "function countdown(n: number): void {
6946 let i = n;
6947 while (i > 0) {
6948 console.log(i);
6949 i--;
6950 }
6951 }",
6952 "foo.ts",
6953 |metric| {
6954 assert_eq!(metric.loc.sloc(), 7);
6955 assert_eq!(metric.loc.ploc(), 7);
6956 assert_eq!(metric.loc.lloc(), 3);
6957 assert_eq!(metric.loc.cloc(), 0);
6958 assert_eq!(metric.loc.blank(), 0);
6959 insta::assert_json_snapshot!(metric.loc);
6960 },
6961 );
6962 }
6963
6964 #[test]
6965 fn typescript_switch_lloc() {
6966 check_metrics::<TypescriptParser>(
6967 "function describe(x: number): string {
6968 switch (x) {
6969 case 1: return 'one';
6970 case 2: return 'two';
6971 default: return 'other';
6972 }
6973 }",
6974 "foo.ts",
6975 |metric| {
6976 assert_eq!(metric.loc.sloc(), 7);
6977 assert_eq!(metric.loc.ploc(), 7);
6978 assert_eq!(metric.loc.lloc(), 4);
6979 assert_eq!(metric.loc.cloc(), 0);
6980 assert_eq!(metric.loc.blank(), 0);
6981 insta::assert_json_snapshot!(metric.loc);
6982 },
6983 );
6984 }
6985
6986 #[test]
6987 fn typescript_class_loc() {
6988 check_metrics::<TypescriptParser>(
6989 "class Counter {
6990 private count: number = 0;
6991 increment(): void { this.count++; }
6992 get(): number { return this.count; }
6993 }",
6994 "foo.ts",
6995 |metric| {
6996 assert_eq!(metric.loc.sloc(), 5);
6997 assert_eq!(metric.loc.ploc(), 5);
6998 assert_eq!(metric.loc.lloc(), 2);
6999 assert_eq!(metric.loc.cloc(), 0);
7000 assert_eq!(metric.loc.blank(), 0);
7001 insta::assert_json_snapshot!(metric.loc);
7002 },
7003 );
7004 }
7005
7006 #[test]
7007 fn typescript_arrow_function_loc() {
7008 check_metrics::<TypescriptParser>(
7009 "const add = (a: number, b: number): number => a + b;
7010 const greet = (name: string): string => {
7011 return `Hello, ${name}`;
7012 };",
7013 "foo.ts",
7014 |metric| {
7015 assert_eq!(metric.loc.sloc(), 4);
7016 assert_eq!(metric.loc.ploc(), 4);
7017 assert_eq!(metric.loc.lloc(), 1);
7018 assert_eq!(metric.loc.cloc(), 0);
7019 assert_eq!(metric.loc.blank(), 0);
7020 insta::assert_json_snapshot!(metric.loc);
7021 },
7022 );
7023 }
7024
7025 #[test]
7026 fn typescript_interface_loc() {
7027 check_metrics::<TypescriptParser>(
7028 "interface Shape {
7029 area(): number;
7030 perimeter(): number;
7031 }
7032 function describe(s: Shape): string {
7033 return `area=${s.area()}`;
7034 }",
7035 "foo.ts",
7036 |metric| {
7037 assert_eq!(metric.loc.sloc(), 7);
7038 assert_eq!(metric.loc.ploc(), 7);
7039 assert_eq!(metric.loc.lloc(), 1);
7040 assert_eq!(metric.loc.cloc(), 0);
7041 assert_eq!(metric.loc.blank(), 0);
7042 insta::assert_json_snapshot!(metric.loc);
7043 },
7044 );
7045 }
7046
7047 #[test]
7048 fn typescript_multiple_functions_loc() {
7049 check_metrics::<TypescriptParser>(
7050 "function f(): number {
7051 return 1;
7052 }
7053 function g(): number {
7054 return 2;
7055 }
7056 function h(): number {
7057 return 3;
7058 }",
7059 "foo.ts",
7060 |metric| {
7061 assert_eq!(metric.loc.sloc(), 9);
7062 assert_eq!(metric.loc.ploc(), 9);
7063 assert_eq!(metric.loc.lloc(), 3);
7064 assert_eq!(metric.loc.cloc(), 0);
7065 assert_eq!(metric.loc.blank(), 0);
7066 insta::assert_json_snapshot!(metric.loc);
7067 },
7068 );
7069 }
7070
7071 #[test]
7072 fn typescript_try_catch_lloc() {
7073 check_metrics::<TypescriptParser>(
7074 "function safe(x: number): number {
7075 try {
7076 return 1 / x;
7077 } catch (e) {
7078 return 0;
7079 }
7080 }",
7081 "foo.ts",
7082 |metric| {
7083 assert_eq!(metric.loc.sloc(), 7);
7084 assert_eq!(metric.loc.ploc(), 7);
7085 assert_eq!(metric.loc.lloc(), 3);
7086 assert_eq!(metric.loc.cloc(), 0);
7087 assert_eq!(metric.loc.blank(), 0);
7088 insta::assert_json_snapshot!(metric.loc);
7089 },
7090 );
7091 }
7092
7093 #[test]
7094 fn typescript_nested_functions_loc() {
7095 check_metrics::<TypescriptParser>(
7096 "function outer(x: number): number {
7097 function inner(y: number): number {
7098 return y * 2;
7099 }
7100 return inner(x) + 1;
7101 }",
7102 "foo.ts",
7103 |metric| {
7104 assert_eq!(metric.loc.sloc(), 6);
7105 assert_eq!(metric.loc.ploc(), 6);
7106 assert_eq!(metric.loc.lloc(), 2);
7107 assert_eq!(metric.loc.cloc(), 0);
7108 assert_eq!(metric.loc.blank(), 0);
7109 insta::assert_json_snapshot!(metric.loc);
7110 },
7111 );
7112 }
7113
7114 #[test]
7115 fn typescript_generic_function_loc() {
7116 check_metrics::<TypescriptParser>(
7117 "function identity<T>(value: T): T {
7118 return value;
7119 }
7120 function first<T>(arr: T[]): T | undefined {
7121 return arr[0];
7122 }",
7123 "foo.ts",
7124 |metric| {
7125 assert_eq!(metric.loc.sloc(), 6);
7126 assert_eq!(metric.loc.ploc(), 6);
7127 assert_eq!(metric.loc.lloc(), 2);
7128 assert_eq!(metric.loc.cloc(), 0);
7129 assert_eq!(metric.loc.blank(), 0);
7130 insta::assert_json_snapshot!(metric.loc);
7131 },
7132 );
7133 }
7134
7135 #[test]
7136 fn tsx_blank() {
7137 check_metrics::<TsxParser>(
7138 "function f(): void {
7139
7140 const x = 1;
7141
7142 }",
7143 "foo.tsx",
7144 |metric| {
7145 assert_eq!(metric.loc.sloc(), 5);
7146 assert_eq!(metric.loc.ploc(), 3);
7147 assert_eq!(metric.loc.lloc(), 0);
7148 assert_eq!(metric.loc.cloc(), 0);
7149 assert_eq!(metric.loc.blank(), 2);
7150 insta::assert_json_snapshot!(metric.loc);
7151 },
7152 );
7153 }
7154
7155 #[test]
7156 fn tsx_cloc() {
7157 check_metrics::<TsxParser>(
7158 "// header
7159 /* block
7160 comment */
7161 function f(): number {
7162 return 42; // inline
7163 }",
7164 "foo.tsx",
7165 |metric| {
7166 assert_eq!(metric.loc.sloc(), 6);
7167 assert_eq!(metric.loc.ploc(), 3);
7168 assert_eq!(metric.loc.lloc(), 1);
7169 assert_eq!(metric.loc.cloc(), 4);
7170 assert_eq!(metric.loc.blank(), 0);
7171 insta::assert_json_snapshot!(metric.loc);
7172 },
7173 );
7174 }
7175
7176 #[test]
7177 fn tsx_no_zero_blank() {
7178 check_metrics::<TsxParser>(
7181 "function f(): void {
7182 const a = 1;
7183
7184 const b = 2; // trailing
7185 const c = 3; // trailing
7186}",
7187 "foo.tsx",
7188 |metric| {
7189 assert_eq!(metric.loc.sloc(), 6);
7190 assert_eq!(metric.loc.ploc(), 5);
7191 assert_eq!(metric.loc.cloc(), 2);
7192 assert_eq!(metric.loc.blank(), 1);
7193 insta::assert_json_snapshot!(metric.loc);
7194 },
7195 );
7196 }
7197
7198 #[test]
7199 fn tsx_if_lloc() {
7200 check_metrics::<TsxParser>(
7201 "function classify(n: number): string {
7202 if (n > 0) {
7203 return 'positive';
7204 } else {
7205 return 'non-positive';
7206 }
7207 }",
7208 "foo.tsx",
7209 |metric| {
7210 assert_eq!(metric.loc.sloc(), 7);
7211 assert_eq!(metric.loc.ploc(), 7);
7212 assert_eq!(metric.loc.lloc(), 3);
7213 assert_eq!(metric.loc.cloc(), 0);
7214 assert_eq!(metric.loc.blank(), 0);
7215 insta::assert_json_snapshot!(metric.loc);
7216 },
7217 );
7218 }
7219
7220 #[test]
7221 fn tsx_for_lloc() {
7222 check_metrics::<TsxParser>(
7223 "function sum(n: number): number {
7224 let s = 0;
7225 for (let i = 0; i < n; i++) {
7226 s += i;
7227 }
7228 return s;
7229 }",
7230 "foo.tsx",
7231 |metric| {
7232 assert_eq!(metric.loc.sloc(), 7);
7233 assert_eq!(metric.loc.ploc(), 7);
7234 assert_eq!(metric.loc.lloc(), 3);
7235 assert_eq!(metric.loc.cloc(), 0);
7236 assert_eq!(metric.loc.blank(), 0);
7237 insta::assert_json_snapshot!(metric.loc);
7238 },
7239 );
7240 }
7241
7242 #[test]
7243 fn tsx_while_lloc() {
7244 check_metrics::<TsxParser>(
7245 "function countdown(n: number): void {
7246 let i = n;
7247 while (i > 0) {
7248 console.log(i);
7249 i--;
7250 }
7251 }",
7252 "foo.tsx",
7253 |metric| {
7254 assert_eq!(metric.loc.sloc(), 7);
7255 assert_eq!(metric.loc.ploc(), 7);
7256 assert_eq!(metric.loc.lloc(), 3);
7257 assert_eq!(metric.loc.cloc(), 0);
7258 assert_eq!(metric.loc.blank(), 0);
7259 insta::assert_json_snapshot!(metric.loc);
7260 },
7261 );
7262 }
7263
7264 #[test]
7265 fn tsx_switch_lloc() {
7266 check_metrics::<TsxParser>(
7267 "function describe(x: number): string {
7268 switch (x) {
7269 case 1: return 'one';
7270 case 2: return 'two';
7271 default: return 'other';
7272 }
7273 }",
7274 "foo.tsx",
7275 |metric| {
7276 assert_eq!(metric.loc.sloc(), 7);
7277 assert_eq!(metric.loc.ploc(), 7);
7278 assert_eq!(metric.loc.lloc(), 4);
7279 assert_eq!(metric.loc.cloc(), 0);
7280 assert_eq!(metric.loc.blank(), 0);
7281 insta::assert_json_snapshot!(metric.loc);
7282 },
7283 );
7284 }
7285
7286 #[test]
7287 fn tsx_class_loc() {
7288 check_metrics::<TsxParser>(
7289 "class Counter {
7290 private count: number = 0;
7291 increment(): void { this.count++; }
7292 get(): number { return this.count; }
7293 }",
7294 "foo.tsx",
7295 |metric| {
7296 assert_eq!(metric.loc.sloc(), 5);
7297 assert_eq!(metric.loc.ploc(), 5);
7298 assert_eq!(metric.loc.lloc(), 2);
7299 assert_eq!(metric.loc.cloc(), 0);
7300 assert_eq!(metric.loc.blank(), 0);
7301 insta::assert_json_snapshot!(metric.loc);
7302 },
7303 );
7304 }
7305
7306 #[test]
7307 fn tsx_arrow_function_loc() {
7308 check_metrics::<TsxParser>(
7309 "const add = (a: number, b: number): number => a + b;
7310 const greet = (name: string): string => {
7311 return `Hello, ${name}`;
7312 };",
7313 "foo.tsx",
7314 |metric| {
7315 assert_eq!(metric.loc.sloc(), 4);
7316 assert_eq!(metric.loc.ploc(), 4);
7317 assert_eq!(metric.loc.lloc(), 1);
7318 assert_eq!(metric.loc.cloc(), 0);
7319 assert_eq!(metric.loc.blank(), 0);
7320 insta::assert_json_snapshot!(metric.loc);
7321 },
7322 );
7323 }
7324
7325 #[test]
7326 fn tsx_multiple_functions_loc() {
7327 check_metrics::<TsxParser>(
7328 "function f(): number {
7329 return 1;
7330 }
7331 function g(): number {
7332 return 2;
7333 }
7334 function h(): number {
7335 return 3;
7336 }",
7337 "foo.tsx",
7338 |metric| {
7339 assert_eq!(metric.loc.sloc(), 9);
7340 assert_eq!(metric.loc.ploc(), 9);
7341 assert_eq!(metric.loc.lloc(), 3);
7342 assert_eq!(metric.loc.cloc(), 0);
7343 assert_eq!(metric.loc.blank(), 0);
7344 insta::assert_json_snapshot!(metric.loc);
7345 },
7346 );
7347 }
7348
7349 #[test]
7350 fn tsx_try_catch_lloc() {
7351 check_metrics::<TsxParser>(
7352 "function safe(x: number): number {
7353 try {
7354 return 1 / x;
7355 } catch (e) {
7356 return 0;
7357 }
7358 }",
7359 "foo.tsx",
7360 |metric| {
7361 assert_eq!(metric.loc.sloc(), 7);
7362 assert_eq!(metric.loc.ploc(), 7);
7363 assert_eq!(metric.loc.lloc(), 3);
7364 assert_eq!(metric.loc.cloc(), 0);
7365 assert_eq!(metric.loc.blank(), 0);
7366 insta::assert_json_snapshot!(metric.loc);
7367 },
7368 );
7369 }
7370
7371 #[test]
7372 fn tsx_nested_functions_loc() {
7373 check_metrics::<TsxParser>(
7374 "function outer(x: number): number {
7375 function inner(y: number): number {
7376 return y * 2;
7377 }
7378 return inner(x) + 1;
7379 }",
7380 "foo.tsx",
7381 |metric| {
7382 assert_eq!(metric.loc.sloc(), 6);
7383 assert_eq!(metric.loc.ploc(), 6);
7384 assert_eq!(metric.loc.lloc(), 2);
7385 assert_eq!(metric.loc.cloc(), 0);
7386 assert_eq!(metric.loc.blank(), 0);
7387 insta::assert_json_snapshot!(metric.loc);
7388 },
7389 );
7390 }
7391
7392 #[test]
7393 fn tsx_interface_loc() {
7394 check_metrics::<TsxParser>(
7395 "interface Shape {
7396 area(): number;
7397 perimeter(): number;
7398 }
7399 function describe(s: Shape): string {
7400 return `area=${s.area()}`;
7401 }",
7402 "foo.tsx",
7403 |metric| {
7404 assert_eq!(metric.loc.sloc(), 7);
7405 assert_eq!(metric.loc.ploc(), 7);
7406 assert_eq!(metric.loc.lloc(), 1);
7407 assert_eq!(metric.loc.cloc(), 0);
7408 assert_eq!(metric.loc.blank(), 0);
7409 insta::assert_json_snapshot!(metric.loc);
7410 },
7411 );
7412 }
7413
7414 #[test]
7415 fn tsx_generic_function_loc() {
7416 check_metrics::<TsxParser>(
7417 "function identity<T>(value: T): T {
7418 return value;
7419 }
7420 function first<T>(arr: T[]): T | undefined {
7421 return arr[0];
7422 }",
7423 "foo.tsx",
7424 |metric| {
7425 assert_eq!(metric.loc.sloc(), 6);
7426 assert_eq!(metric.loc.ploc(), 6);
7427 assert_eq!(metric.loc.lloc(), 2);
7428 assert_eq!(metric.loc.cloc(), 0);
7429 assert_eq!(metric.loc.blank(), 0);
7430 insta::assert_json_snapshot!(metric.loc);
7431 },
7432 );
7433 }
7434
7435 #[test]
7436 fn php_blank() {
7437 check_metrics::<PhpParser>(
7438 "<?php
7439
7440$a = 1;
7441
7442$b = 2;
7443
7444",
7445 "foo.php",
7446 |metric| {
7447 assert_eq!(metric.loc.sloc(), 5);
7448 assert_eq!(metric.loc.ploc(), 3);
7449 assert_eq!(metric.loc.lloc(), 2);
7450 assert_eq!(metric.loc.cloc(), 0);
7451 assert_eq!(metric.loc.blank(), 2);
7452 insta::assert_json_snapshot!(metric.loc);
7453 },
7454 );
7455 }
7456
7457 #[test]
7458 fn php_no_zero_blank() {
7459 check_metrics::<PhpParser>(
7462 "<?php
7463$a = 1;
7464
7465$b = 2; // trailing
7466$c = 3; // trailing
7467",
7468 "foo.php",
7469 |metric| {
7470 assert_eq!(metric.loc.sloc(), 5);
7471 assert_eq!(metric.loc.ploc(), 4);
7472 assert_eq!(metric.loc.cloc(), 2);
7473 assert_eq!(metric.loc.blank(), 1);
7474 insta::assert_json_snapshot!(metric.loc);
7475 },
7476 );
7477 }
7478
7479 #[test]
7480 fn php_cloc_double_slash() {
7481 check_metrics::<PhpParser>(
7482 "<?php
7483// first
7484// second
7485$a = 1; // trailing",
7486 "foo.php",
7487 |metric| {
7488 assert_eq!(metric.loc.sloc(), 4);
7489 assert_eq!(metric.loc.ploc(), 2);
7490 assert_eq!(metric.loc.lloc(), 1);
7491 assert_eq!(metric.loc.cloc(), 3);
7492 assert_eq!(metric.loc.blank(), 0);
7493 insta::assert_json_snapshot!(metric.loc);
7494 },
7495 );
7496 }
7497
7498 #[test]
7499 fn php_cloc_hash() {
7500 check_metrics::<PhpParser>(
7501 "<?php
7502# first
7503# second
7504$a = 1;",
7505 "foo.php",
7506 |metric| {
7507 assert_eq!(metric.loc.sloc(), 4);
7508 assert_eq!(metric.loc.ploc(), 2);
7509 assert_eq!(metric.loc.lloc(), 1);
7510 assert_eq!(metric.loc.cloc(), 2);
7511 assert_eq!(metric.loc.blank(), 0);
7512 insta::assert_json_snapshot!(metric.loc);
7513 },
7514 );
7515 }
7516
7517 #[test]
7518 fn php_cloc_block() {
7519 check_metrics::<PhpParser>(
7520 "<?php
7521/*
7522 * block
7523 * comment
7524 */
7525$a = 1;",
7526 "foo.php",
7527 |metric| {
7528 assert_eq!(metric.loc.sloc(), 6);
7529 assert_eq!(metric.loc.ploc(), 2);
7530 assert_eq!(metric.loc.lloc(), 1);
7531 assert_eq!(metric.loc.cloc(), 4);
7532 assert_eq!(metric.loc.blank(), 0);
7533 insta::assert_json_snapshot!(metric.loc);
7534 },
7535 );
7536 }
7537
7538 #[test]
7539 fn php_lloc() {
7540 check_metrics::<PhpParser>(
7542 "<?php
7543$a = 1;
7544if ($a > 0) {
7545 echo $a;
7546}",
7547 "foo.php",
7548 |metric| {
7549 assert_eq!(metric.loc.sloc(), 5);
7550 assert_eq!(metric.loc.ploc(), 5);
7551 assert_eq!(metric.loc.lloc(), 3);
7552 assert_eq!(metric.loc.cloc(), 0);
7553 assert_eq!(metric.loc.blank(), 0);
7554 insta::assert_json_snapshot!(metric.loc);
7555 },
7556 );
7557 }
7558
7559 #[test]
7560 fn php_no_parenthesized_expression_lloc() {
7561 check_metrics::<PhpParser>(
7564 "<?php
7565$a = (1 + 2);",
7566 "foo.php",
7567 |metric| {
7568 assert_eq!(metric.loc.sloc(), 2);
7569 assert_eq!(metric.loc.ploc(), 2);
7570 assert_eq!(metric.loc.lloc(), 1);
7571 assert_eq!(metric.loc.cloc(), 0);
7572 assert_eq!(metric.loc.blank(), 0);
7573 insta::assert_json_snapshot!(metric.loc);
7574 },
7575 );
7576 }
7577
7578 #[test]
7579 fn php_no_compound_statement_lloc() {
7580 check_metrics::<PhpParser>(
7582 "<?php
7583function f(): void {
7584 $a = 1;
7585}",
7586 "foo.php",
7587 |metric| {
7588 assert_eq!(metric.loc.sloc(), 4);
7589 assert_eq!(metric.loc.ploc(), 4);
7590 assert_eq!(metric.loc.lloc(), 1);
7591 assert_eq!(metric.loc.cloc(), 0);
7592 assert_eq!(metric.loc.blank(), 0);
7593 insta::assert_json_snapshot!(metric.loc);
7594 },
7595 );
7596 }
7597
7598 #[test]
7599 fn php_no_colon_block_lloc() {
7600 check_metrics::<PhpParser>(
7603 "<?php
7604if (true):
7605 $a = 1;
7606endif;",
7607 "foo.php",
7608 |metric| {
7609 assert_eq!(metric.loc.sloc(), 4);
7610 assert_eq!(metric.loc.ploc(), 4);
7611 assert_eq!(metric.loc.lloc(), 2);
7612 assert_eq!(metric.loc.cloc(), 0);
7613 assert_eq!(metric.loc.blank(), 0);
7614 insta::assert_json_snapshot!(metric.loc);
7615 },
7616 );
7617 }
7618
7619 #[test]
7620 fn php_no_else_clause_lloc() {
7621 check_metrics::<PhpParser>(
7623 "<?php
7624if ($x) {
7625 $a = 1;
7626} elseif ($y) {
7627 $a = 2;
7628} else {
7629 $a = 3;
7630}",
7631 "foo.php",
7632 |metric| {
7633 assert_eq!(metric.loc.sloc(), 8);
7634 assert_eq!(metric.loc.ploc(), 8);
7635 assert_eq!(metric.loc.lloc(), 4);
7636 assert_eq!(metric.loc.cloc(), 0);
7637 assert_eq!(metric.loc.blank(), 0);
7638 insta::assert_json_snapshot!(metric.loc);
7639 },
7640 );
7641 }
7642
7643 #[test]
7644 fn php_no_case_statement_lloc() {
7645 check_metrics::<PhpParser>(
7648 "<?php
7649switch ($x) {
7650 case 1:
7651 $a = 1;
7652 break;
7653 case 2:
7654 $a = 2;
7655 break;
7656 default:
7657 $a = 0;
7658}",
7659 "foo.php",
7660 |metric| {
7661 assert_eq!(metric.loc.sloc(), 11);
7662 assert_eq!(metric.loc.ploc(), 11);
7663 assert_eq!(metric.loc.lloc(), 6);
7664 assert_eq!(metric.loc.cloc(), 0);
7665 assert_eq!(metric.loc.blank(), 0);
7666 insta::assert_json_snapshot!(metric.loc);
7667 },
7668 );
7669 }
7670
7671 #[test]
7672 fn php_no_match_arm_lloc() {
7673 check_metrics::<PhpParser>(
7676 "<?php
7677$a = match ($x) {
7678 1 => 'one',
7679 2 => 'two',
7680 default => 'other',
7681};",
7682 "foo.php",
7683 |metric| {
7684 assert_eq!(metric.loc.sloc(), 6);
7685 assert_eq!(metric.loc.ploc(), 6);
7686 assert_eq!(metric.loc.lloc(), 1);
7687 assert_eq!(metric.loc.cloc(), 0);
7688 assert_eq!(metric.loc.blank(), 0);
7689 insta::assert_json_snapshot!(metric.loc);
7690 },
7691 );
7692 }
7693
7694 #[test]
7695 fn php_no_throw_in_expression_lloc() {
7696 check_metrics::<PhpParser>(
7699 "<?php
7700$x = $y ?? throw new \\Exception('nope');",
7701 "foo.php",
7702 |metric| {
7703 assert_eq!(metric.loc.sloc(), 2);
7704 assert_eq!(metric.loc.ploc(), 2);
7705 assert_eq!(metric.loc.lloc(), 1);
7706 assert_eq!(metric.loc.cloc(), 0);
7707 assert_eq!(metric.loc.blank(), 0);
7708 insta::assert_json_snapshot!(metric.loc);
7709 },
7710 );
7711 }
7712
7713 #[test]
7714 fn php_no_closure_in_assignment_lloc() {
7715 check_metrics::<PhpParser>(
7719 "<?php
7720$f = function (): int {
7721 return 42;
7722};",
7723 "foo.php",
7724 |metric| {
7725 assert_eq!(metric.loc.sloc(), 4);
7726 assert_eq!(metric.loc.ploc(), 4);
7727 assert_eq!(metric.loc.lloc(), 2);
7728 assert_eq!(metric.loc.cloc(), 0);
7729 assert_eq!(metric.loc.blank(), 0);
7730 insta::assert_json_snapshot!(metric.loc);
7731 },
7732 );
7733 }
7734
7735 #[test]
7736 fn php_for_lloc() {
7737 check_metrics::<PhpParser>(
7740 "<?php
7741for ($i = 0; $i < 10; $i++) {
7742 echo $i;
7743}",
7744 "foo.php",
7745 |metric| {
7746 assert_eq!(metric.loc.sloc(), 4);
7747 assert_eq!(metric.loc.ploc(), 4);
7748 assert_eq!(metric.loc.lloc(), 2);
7749 assert_eq!(metric.loc.cloc(), 0);
7750 assert_eq!(metric.loc.blank(), 0);
7751 insta::assert_json_snapshot!(metric.loc);
7752 },
7753 );
7754 }
7755
7756 #[test]
7757 fn php_foreach_lloc() {
7758 check_metrics::<PhpParser>(
7759 "<?php
7760foreach ($items as $k => $v) {
7761 echo $v;
7762}",
7763 "foo.php",
7764 |metric| {
7765 assert_eq!(metric.loc.sloc(), 4);
7766 assert_eq!(metric.loc.ploc(), 4);
7767 assert_eq!(metric.loc.lloc(), 2);
7768 assert_eq!(metric.loc.cloc(), 0);
7769 assert_eq!(metric.loc.blank(), 0);
7770 insta::assert_json_snapshot!(metric.loc);
7771 },
7772 );
7773 }
7774
7775 #[test]
7776 fn php_try_lloc() {
7777 check_metrics::<PhpParser>(
7778 "<?php
7779try {
7780 $a = 1;
7781} catch (\\Exception $e) {
7782 $a = 0;
7783} finally {
7784 $b = 2;
7785}",
7786 "foo.php",
7787 |metric| {
7788 assert_eq!(metric.loc.sloc(), 8);
7789 assert_eq!(metric.loc.ploc(), 8);
7790 assert_eq!(metric.loc.lloc(), 4);
7791 assert_eq!(metric.loc.cloc(), 0);
7792 assert_eq!(metric.loc.blank(), 0);
7793 insta::assert_json_snapshot!(metric.loc);
7794 },
7795 );
7796 }
7797
7798 #[test]
7799 fn php_class_loc() {
7800 check_metrics::<PhpParser>(
7801 "<?php
7802class A {
7803 public int $x = 0;
7804 private const Y = 1;
7805 public function f(): int {
7806 return $this->x;
7807 }
7808}",
7809 "foo.php",
7810 |metric| {
7811 assert_eq!(metric.loc.sloc(), 8);
7812 assert_eq!(metric.loc.ploc(), 8);
7813 assert_eq!(metric.loc.lloc(), 3);
7814 assert_eq!(metric.loc.cloc(), 0);
7815 assert_eq!(metric.loc.blank(), 0);
7816 insta::assert_json_snapshot!(metric.loc);
7817 },
7818 );
7819 }
7820
7821 #[test]
7822 fn php_namespace_use_lloc() {
7823 check_metrics::<PhpParser>(
7824 "<?php
7825namespace App;
7826use App\\Foo;
7827use App\\Bar;
7828$a = 1;",
7829 "foo.php",
7830 |metric| {
7831 assert_eq!(metric.loc.sloc(), 5);
7832 assert_eq!(metric.loc.ploc(), 5);
7833 assert_eq!(metric.loc.lloc(), 3);
7834 assert_eq!(metric.loc.cloc(), 0);
7835 assert_eq!(metric.loc.blank(), 0);
7836 insta::assert_json_snapshot!(metric.loc);
7837 },
7838 );
7839 }
7840
7841 #[test]
7842 fn php_general_loc() {
7843 check_metrics::<PhpParser>(
7844 "<?php
7845// header
7846namespace App;
7847use App\\Foo;
7848
7849class Bar {
7850 public int $n = 0;
7851
7852 public function add(int $x): int {
7853 if ($x > 0) {
7854 return $this->n + $x;
7855 }
7856 return $this->n;
7857 }
7858}",
7859 "foo.php",
7860 |metric| {
7861 assert_eq!(metric.loc.sloc(), 15);
7862 assert_eq!(metric.loc.ploc(), 12);
7863 assert_eq!(metric.loc.lloc(), 5);
7864 assert_eq!(metric.loc.cloc(), 1);
7865 assert_eq!(metric.loc.blank(), 2);
7866 insta::assert_json_snapshot!(metric.loc);
7867 },
7868 );
7869 }
7870
7871 #[test]
7872 fn php_match_in_expression_lloc() {
7873 check_metrics::<PhpParser>(
7876 "<?php
7877$y = 10 + match ($x) { 1 => 2, default => 0 };",
7878 "foo.php",
7879 |metric| {
7880 assert_eq!(metric.loc.sloc(), 2);
7881 assert_eq!(metric.loc.ploc(), 2);
7882 assert_eq!(metric.loc.lloc(), 1);
7883 assert_eq!(metric.loc.cloc(), 0);
7884 assert_eq!(metric.loc.blank(), 0);
7885 insta::assert_json_snapshot!(metric.loc);
7886 },
7887 );
7888 }
7889
7890 #[test]
7891 fn php_html_island_ploc() {
7892 check_metrics::<PhpParser>(
7898 "<?php if ($cond): ?>
7899<div>hello</div>
7900<p>world</p>
7901<?php endif; ?>",
7902 "foo.php",
7903 |metric| {
7904 assert_eq!(metric.loc.sloc(), 4);
7905 assert_eq!(metric.loc.ploc(), 3);
7906 assert_eq!(metric.loc.lloc(), 1);
7907 assert_eq!(metric.loc.cloc(), 0);
7908 assert_eq!(metric.loc.blank(), 1);
7909 insta::assert_json_snapshot!(metric.loc);
7910 },
7911 );
7912 }
7913
7914 #[test]
7915 fn php_short_echo_tag_ploc() {
7916 check_metrics::<PhpParser>("<p><?= $name ?></p>", "foo.php", |metric| {
7920 assert_eq!(metric.loc.sloc(), 1);
7921 assert_eq!(metric.loc.ploc(), 1);
7922 assert_eq!(metric.loc.lloc(), 1);
7923 assert_eq!(metric.loc.cloc(), 0);
7924 assert_eq!(metric.loc.blank(), 0);
7925 insta::assert_json_snapshot!(metric.loc);
7926 });
7927 }
7928
7929 #[test]
7930 fn elixir_blank() {
7931 check_metrics::<ElixirParser>(
7933 "defmodule Foo do\n\n def a, do: :a\n\n def b, do: :b\nend\n",
7934 "foo.ex",
7935 |metric| {
7936 assert_eq!(metric.loc.sloc(), 6);
7937 assert_eq!(metric.loc.ploc(), 4);
7938 assert_eq!(metric.loc.lloc(), 3);
7939 assert_eq!(metric.loc.cloc(), 0);
7940 assert_eq!(metric.loc.blank(), 2);
7941 insta::assert_json_snapshot!(
7942 metric.loc,
7943 @r#"
7944 {
7945 "sloc": 6,
7946 "ploc": 4,
7947 "lloc": 3,
7948 "cloc": 0,
7949 "blank": 2,
7950 "sloc_average": 1.5,
7951 "ploc_average": 1.0,
7952 "lloc_average": 0.75,
7953 "cloc_average": 0.0,
7954 "blank_average": 0.5,
7955 "sloc_min": 1,
7956 "sloc_max": 6,
7957 "cloc_min": 0,
7958 "cloc_max": 0,
7959 "ploc_min": 1,
7960 "ploc_max": 4,
7961 "lloc_min": 1,
7962 "lloc_max": 3,
7963 "blank_min": 0,
7964 "blank_max": 2
7965 }
7966 "#
7967 );
7968 },
7969 );
7970 }
7971
7972 #[test]
7973 fn elixir_no_zero_blank() {
7974 check_metrics::<ElixirParser>(
7977 "defmodule Foo do\n def f, do: :ok\n\n def g, do: :ok # trailing\n def h, do: :ok # trailing\nend\n",
7978 "foo.ex",
7979 |metric| {
7980 assert_eq!(metric.loc.sloc(), 6);
7981 assert_eq!(metric.loc.ploc(), 5);
7982 assert_eq!(metric.loc.cloc(), 2);
7983 assert_eq!(metric.loc.blank(), 1);
7984 },
7985 );
7986 }
7987
7988 #[test]
7989 fn elixir_blank_zero_sanity() {
7990 check_metrics::<ElixirParser>(
7993 "defmodule Foo do\n def f, do: :ok\nend\n",
7994 "foo.ex",
7995 |metric| {
7996 assert_eq!(metric.loc.blank(), 0);
7997 },
7998 );
7999 }
8000
8001 #[test]
8002 fn elixir_cloc() {
8003 check_metrics::<ElixirParser>(
8006 "# top\ndefmodule Foo do\n # body\n def f, do: :ok # trailing\nend\n",
8007 "foo.ex",
8008 |metric| {
8009 assert_eq!(metric.loc.cloc(), 3);
8010 },
8011 );
8012 }
8013
8014 #[test]
8015 fn elixir_lloc() {
8016 check_metrics::<ElixirParser>(
8021 "defmodule Foo do\n def a, do: 1\n def b, do: 2\nend\n",
8022 "foo.ex",
8023 |metric| {
8024 assert_eq!(metric.loc.lloc(), 3);
8025 },
8026 );
8027 }
8028
8029 #[test]
8030 fn elixir_no_nested_call_lloc() {
8031 check_metrics::<ElixirParser>(
8035 "defmodule Foo do\n def f do\n IO.puts(Enum.join([1, 2, 3], \", \"))\n end\nend\n",
8036 "foo.ex",
8037 |metric| {
8038 assert_eq!(metric.loc.lloc(), 3);
8039 },
8040 );
8041 }
8042
8043 #[test]
8044 fn elixir_no_binary_operator_inside_call_lloc() {
8045 check_metrics::<ElixirParser>(
8051 "defmodule Foo do\n def f(a, b) do\n IO.puts(a + b)\n end\nend\n",
8052 "foo.ex",
8053 |metric| {
8054 assert_eq!(metric.loc.lloc(), 3);
8055 },
8056 );
8057 }
8058
8059 #[test]
8060 fn elixir_stab_clause_counts_lloc() {
8061 check_metrics::<ElixirParser>(
8065 "defmodule Foo do\n def f(x) do\n case x do\n 1 -> :a\n 2 -> :b\n _ -> :c\n end\n end\nend\n",
8066 "foo.ex",
8067 |metric| {
8068 assert_eq!(metric.loc.lloc(), 6);
8069 },
8070 );
8071 }
8072
8073 #[test]
8074 fn elixir_no_comment_lloc() {
8075 check_metrics::<ElixirParser>(
8080 "# leading\ndefmodule Foo do\n # inside\n def f, do: :ok\n # trailing\nend\n",
8081 "foo.ex",
8082 |metric| {
8083 assert_eq!(metric.loc.lloc(), 2);
8084 },
8085 );
8086 }
8087
8088 #[test]
8089 fn elixir_no_do_token_lloc() {
8090 check_metrics::<ElixirParser>("defmodule Foo do\n :ok\nend\n", "foo.ex", |metric| {
8095 assert_eq!(metric.loc.lloc(), 2);
8098 });
8099 }
8100
8101 #[test]
8102 fn elixir_no_keyword_pair_lloc() {
8103 check_metrics::<ElixirParser>(
8107 "defmodule Foo do\n def add(a, b), do: a + b\nend\n",
8108 "foo.ex",
8109 |metric| {
8110 assert_eq!(metric.loc.lloc(), 2);
8112 },
8113 );
8114 }
8115
8116 #[test]
8117 fn elixir_no_string_content_lloc() {
8118 check_metrics::<ElixirParser>(
8123 "defmodule Foo do\n @moduledoc \"\"\"\n line one\n line two\n \"\"\"\n def f, do: :ok\nend\n",
8124 "foo.ex",
8125 |metric| {
8126 assert_eq!(metric.loc.lloc(), 3);
8128 },
8129 );
8130 }
8131
8132 #[test]
8133 fn elixir_rescue_arm_counts_lloc() {
8134 check_metrics::<ElixirParser>(
8141 "defmodule Foo do\n def safe do\n try do\n do_it()\n rescue\n ArgumentError -> :bad\n RuntimeError -> :worse\n end\n end\nend\n",
8142 "foo.ex",
8143 |metric| {
8144 assert_eq!(metric.loc.lloc(), 7);
8145 },
8146 );
8147 }
8148
8149 #[test]
8150 fn elixir_no_arg_punctuation_lloc() {
8151 check_metrics::<ElixirParser>(
8155 "defmodule Foo do\n def add(a, b, c, d) do\n a + b + c + d\n end\nend\n",
8156 "foo.ex",
8157 |metric| {
8158 assert_eq!(metric.loc.lloc(), 3);
8160 },
8161 );
8162 }
8163
8164 #[test]
8165 fn elixir_no_list_element_lloc() {
8166 check_metrics::<ElixirParser>(
8169 "defmodule Foo do\n def f do\n [:a, :b, :c, :d]\n end\nend\n",
8170 "foo.ex",
8171 |metric| {
8172 assert_eq!(metric.loc.lloc(), 3);
8174 },
8175 );
8176 }
8177
8178 #[test]
8179 fn elixir_no_map_field_lloc() {
8180 check_metrics::<ElixirParser>(
8182 "defmodule Foo do\n def f do\n %{a: 1, b: 2, c: 3}\n end\nend\n",
8183 "foo.ex",
8184 |metric| {
8185 assert_eq!(metric.loc.lloc(), 3);
8186 },
8187 );
8188 }
8189
8190 #[test]
8191 fn elixir_anonymous_fn_body_lloc() {
8192 check_metrics::<ElixirParser>(
8200 "defmodule Foo do\n def f do\n add = fn x -> x + 1 end\n add\n end\nend\n",
8201 "foo.ex",
8202 |metric| {
8203 assert_eq!(metric.loc.lloc(), 5);
8204 },
8205 );
8206 }
8207
8208 #[test]
8209 fn ruby_blank() {
8210 check_metrics::<RubyParser>("def foo\n a = 1\n\n a + 1\nend\n", "foo.rb", |metric| {
8214 assert_eq!(metric.loc.blank(), 1);
8215 });
8216 }
8217
8218 #[test]
8219 fn ruby_no_zero_blank() {
8220 check_metrics::<RubyParser>(
8226 "def foo # entry\n pool = 0\n\n server = -42 # negative\n\n ok = false\nend\n",
8227 "foo.rb",
8228 |metric| {
8229 assert_eq!(metric.loc.blank(), 2);
8230 },
8231 );
8232 }
8233
8234 #[test]
8235 fn ruby_cloc() {
8236 check_metrics::<RubyParser>(
8238 "# one\n# two\n# three\ndef foo\nend\n",
8239 "foo.rb",
8240 |metric| {
8241 assert_eq!(metric.loc.cloc(), 3);
8242 },
8243 );
8244 }
8245
8246 #[test]
8247 fn ruby_lloc() {
8248 check_metrics::<RubyParser>(
8252 "def foo(a)\n if a\n a += 1\n end\n while a > 0\n a -= 1\n end\nend\n",
8253 "foo.rb",
8254 |metric| {
8255 assert_eq!(metric.loc.lloc(), 3);
8256 },
8257 );
8258 }
8259
8260 #[test]
8261 fn ruby_no_call_lloc() {
8262 check_metrics::<RubyParser>(
8267 "def foo\n puts 'hello'\n puts 'world'\nend\n",
8268 "foo.rb",
8269 |metric| {
8270 assert_eq!(metric.loc.lloc(), 1);
8271 },
8272 );
8273 }
8274
8275 #[test]
8276 fn ruby_no_assignment_lloc() {
8277 check_metrics::<RubyParser>(
8280 "def foo\n a = 1\n b = 2\n c = a + b\nend\n",
8281 "foo.rb",
8282 |metric| {
8283 assert_eq!(metric.loc.lloc(), 1);
8284 },
8285 );
8286 }
8287
8288 #[test]
8289 fn ruby_modifier_lloc() {
8290 check_metrics::<RubyParser>(
8296 "def foo(a)\n return a if a.nil?\n a -= 1 while a > 0\n parse(a) rescue nil\nend\n",
8297 "foo.rb",
8298 |metric| {
8299 assert_eq!(metric.loc.lloc(), 5);
8300 },
8301 );
8302 }
8303
8304 #[test]
8305 fn ruby_class_lloc() {
8306 check_metrics::<RubyParser>(
8308 "module M\n class C\n def foo\n end\n def bar\n end\n end\nend\n",
8309 "foo.rb",
8310 |metric| {
8311 assert_eq!(metric.loc.lloc(), 4);
8312 },
8313 );
8314 }
8315
8316 #[test]
8317 fn ruby_begin_rescue_lloc() {
8318 check_metrics::<RubyParser>(
8322 "def foo\n begin\n risky\n rescue StandardError\n nil\n end\nend\n",
8323 "foo.rb",
8324 |metric| {
8325 assert_eq!(metric.loc.lloc(), 2);
8326 },
8327 );
8328 }
8329
8330 #[test]
8331 fn ruby_nested_defs_lloc() {
8332 check_metrics::<RubyParser>(
8335 "def outer\n def inner\n 1\n end\nend\n",
8336 "foo.rb",
8337 |metric| {
8338 assert_eq!(metric.loc.lloc(), 2);
8339 },
8340 );
8341 }
8342
8343 #[test]
8344 fn ruby_no_block_body_lloc() {
8345 check_metrics::<RubyParser>(
8351 "[1, 2, 3].each do |x|\n puts x\nend\n",
8352 "foo.rb",
8353 |metric| {
8354 assert_eq!(metric.loc.lloc(), 0);
8355 },
8356 );
8357 }
8358
8359 #[test]
8360 fn ruby_no_lambda_body_lloc() {
8361 check_metrics::<RubyParser>("add = ->(a, b) {\n a + b\n}\n", "foo.rb", |metric| {
8366 assert_eq!(metric.loc.lloc(), 0);
8367 });
8368 }
8369
8370 #[test]
8371 fn ruby_heredoc_lloc_and_blank() {
8372 check_metrics::<RubyParser>(
8379 "def foo\n msg = <<~TXT\n one\n two\n TXT\n msg\nend\n",
8380 "foo.rb",
8381 |metric| {
8382 assert_eq!(metric.loc.sloc(), 7);
8383 assert_eq!(metric.loc.ploc(), 7);
8384 assert_eq!(metric.loc.lloc(), 1);
8385 assert_eq!(metric.loc.blank(), 0);
8386 },
8387 );
8388 }
8389
8390 #[test]
8391 fn ruby_semicolon_multistatement_lloc_undercount() {
8392 check_metrics::<RubyParser>(
8399 "def foo\n a = 1; b = 2; a + b\nend\n",
8400 "foo.rb",
8401 |metric| {
8402 assert_eq!(metric.loc.lloc(), 1);
8403 },
8404 );
8405 }
8406
8407 #[test]
8408 fn ruby_ploc_skips_comments_and_blanks() {
8409 check_metrics::<RubyParser>("# header\n\ndef foo\n a = 1\nend\n", "foo.rb", |metric| {
8412 assert_eq!(metric.loc.ploc(), 3);
8413 assert_eq!(metric.loc.cloc(), 1);
8414 assert_eq!(metric.loc.blank(), 1);
8415 });
8416 }
8417
8418 #[test]
8427 fn python_nested_def_lloc() {
8428 check_metrics::<PythonParser>(
8432 "def outer():\n def inner():\n return 1\n return inner()\n",
8433 "foo.py",
8434 |metric| {
8435 assert_eq!(metric.loc.sloc(), 4);
8436 assert_eq!(metric.loc.ploc(), 4);
8437 assert_eq!(metric.loc.lloc(), 2);
8438 assert_eq!(metric.loc.cloc(), 0);
8439 assert_eq!(metric.loc.blank(), 0);
8440 insta::assert_json_snapshot!(metric.loc);
8441 },
8442 );
8443 }
8444
8445 #[test]
8446 fn python_lambda_in_def_lloc() {
8447 check_metrics::<PythonParser>(
8451 "def outer():\n f = lambda x: x + 1\n return f(2)\n",
8452 "foo.py",
8453 |metric| {
8454 assert_eq!(metric.loc.sloc(), 3);
8455 assert_eq!(metric.loc.ploc(), 3);
8456 assert_eq!(metric.loc.lloc(), 2);
8457 assert_eq!(metric.loc.cloc(), 0);
8458 assert_eq!(metric.loc.blank(), 0);
8459 insta::assert_json_snapshot!(metric.loc);
8460 },
8461 );
8462 }
8463
8464 #[test]
8465 fn python_match_statement_lloc() {
8466 check_metrics::<PythonParser>(
8473 "def f(x):\n match x:\n case 1: return 1\n case _: return 0\n",
8474 "foo.py",
8475 |metric| {
8476 assert_eq!(metric.loc.lloc(), 3);
8477 insta::assert_json_snapshot!(metric.loc);
8478 },
8479 );
8480 }
8481
8482 #[test]
8483 fn python_match_lloc_matches_if_else() {
8484 check_metrics::<PythonParser>(
8492 "def f(x):\n if x == 1: return 1\n else: return 0\n",
8493 "foo.py",
8494 |metric| assert_eq!(metric.loc.lloc(), 3),
8495 );
8496 check_metrics::<PythonParser>(
8497 "def f(x):\n match x:\n case 1: return 1\n case _: return 0\n",
8498 "foo.py",
8499 |metric| assert_eq!(metric.loc.lloc(), 3),
8500 );
8501 }
8502
8503 #[test]
8504 fn python_type_alias_lloc() {
8505 check_metrics::<PythonParser>("type Alias = int\nx = 1\n", "foo.py", |metric| {
8510 assert_eq!(metric.loc.lloc(), 2);
8511 insta::assert_json_snapshot!(metric.loc);
8512 });
8513 }
8514
8515 #[test]
8516 fn java_local_class_in_method_lloc() {
8517 check_metrics::<JavaParser>(
8521 "class Foo {\n int bar() {\n class Local {\n int v() { return 1; }\n }\n return new Local().v();\n }\n}\n",
8522 "foo.java",
8523 |metric| {
8524 assert_eq!(metric.loc.sloc(), 8);
8525 assert_eq!(metric.loc.ploc(), 8);
8526 assert_eq!(metric.loc.lloc(), 2);
8527 assert_eq!(metric.loc.cloc(), 0);
8528 assert_eq!(metric.loc.blank(), 0);
8529 insta::assert_json_snapshot!(metric.loc);
8530 },
8531 );
8532 }
8533
8534 #[test]
8535 fn java_lambda_in_method_lloc() {
8536 check_metrics::<JavaParser>(
8540 "class Foo {\n void bar() {\n java.util.function.IntUnaryOperator f = x -> x + 1;\n f.applyAsInt(3);\n }\n}\n",
8541 "foo.java",
8542 |metric| {
8543 assert_eq!(metric.loc.sloc(), 6);
8544 assert_eq!(metric.loc.ploc(), 6);
8545 assert_eq!(metric.loc.lloc(), 2);
8546 assert_eq!(metric.loc.cloc(), 0);
8547 assert_eq!(metric.loc.blank(), 0);
8548 insta::assert_json_snapshot!(metric.loc);
8549 },
8550 );
8551 }
8552
8553 #[test]
8554 fn groovy_blank() {
8555 check_metrics::<GroovyParser>("int x = 1\n\n\nint y = 2", "foo.groovy", |metric| {
8558 assert_eq!(metric.loc.sloc(), 4);
8559 assert_eq!(metric.loc.ploc(), 2);
8560 assert_eq!(metric.loc.lloc(), 2);
8561 assert_eq!(metric.loc.blank(), 2);
8562 });
8563 }
8564
8565 #[test]
8566 fn groovy_no_zero_blank() {
8567 check_metrics::<GroovyParser>("int x = 1", "foo.groovy", |metric| {
8569 assert_eq!(metric.loc.sloc(), 1);
8570 assert_eq!(metric.loc.blank(), 0);
8571 });
8572 }
8573
8574 #[test]
8575 fn groovy_cloc_line_comments() {
8576 check_metrics::<GroovyParser>(
8577 "// first comment
8578 int x = 1
8579 // second comment
8580 int y = 2",
8581 "foo.groovy",
8582 |metric| {
8583 assert_eq!(metric.loc.cloc(), 2);
8584 assert_eq!(metric.loc.ploc(), 2);
8585 },
8586 );
8587 }
8588
8589 #[test]
8590 fn groovy_cloc_block_comment() {
8591 check_metrics::<GroovyParser>(
8592 "/* multi
8593 line
8594 comment */
8595 int x = 1",
8596 "foo.groovy",
8597 |metric| {
8598 assert_eq!(metric.loc.cloc(), 3);
8600 },
8601 );
8602 }
8603
8604 #[test]
8605 fn groovy_cloc_groovydoc_comment() {
8606 check_metrics::<GroovyParser>(
8610 "/** groovydoc */
8611class A {
8612 int x = 1
8613}",
8614 "foo.groovy",
8615 |metric| {
8616 assert_eq!(metric.loc.cloc(), 1);
8617 assert_eq!(metric.loc.ploc(), 3);
8618 },
8619 );
8620 }
8621
8622 #[test]
8623 fn groovy_simple_lloc() {
8624 check_metrics::<GroovyParser>(
8626 "int a = 1
8627 int b = 2
8628 int c = 3",
8629 "foo.groovy",
8630 |metric| {
8631 assert_eq!(metric.loc.lloc(), 3);
8632 },
8633 );
8634 }
8635
8636 #[test]
8637 fn groovy_no_local_variable_declaration_in_for_lloc() {
8638 check_metrics::<GroovyParser>(
8642 "for (int i = 0; i < 10; i++) {
8643 println(i)
8644 }",
8645 "foo.groovy",
8646 |metric| {
8647 assert_eq!(metric.loc.lloc(), 2);
8649 },
8650 );
8651 }
8652
8653 #[test]
8654 fn groovy_lambda_in_method_lloc() {
8655 check_metrics::<GroovyParser>(
8662 "class Foo {
8663 void bar() {
8664 def f = { x -> x + 1 }
8665 f(3)
8666 }
8667 }",
8668 "foo.groovy",
8669 |metric| {
8670 assert_eq!(metric.loc.lloc(), 3);
8671 },
8672 );
8673 }
8674
8675 #[test]
8676 fn groovy_try_lloc() {
8677 check_metrics::<GroovyParser>(
8680 "void f() {
8681 try {
8682 risky()
8683 } catch (Exception e) {
8684 handle(e)
8685 }
8686 }",
8687 "foo.groovy",
8688 |metric| {
8689 assert_eq!(metric.loc.lloc(), 3);
8691 },
8692 );
8693 }
8694
8695 #[test]
8696 fn groovy_class_loc() {
8697 check_metrics::<GroovyParser>(
8699 "class A {
8700 void f() {
8701 int x = 1
8702 }
8703 void g() {
8704 int y = 2
8705 }
8706 }",
8707 "foo.groovy",
8708 |metric| {
8709 assert_eq!(metric.loc.ploc(), 8);
8713 assert_eq!(metric.loc.cloc(), 0);
8714 assert_eq!(metric.loc.lloc(), 2);
8717 },
8718 );
8719 }
8720
8721 #[test]
8722 fn groovy_partial_parse_recovers_unit() {
8723 check_metrics::<GroovyParser>("def x = (((", "foo.groovy", |metric| {
8728 assert_eq!(metric.loc.sloc(), 1);
8729 assert_eq!(metric.loc.blank(), 0);
8730 });
8731 }
8732
8733 #[test]
8734 fn groovy_sloc() {
8735 check_metrics::<GroovyParser>(
8738 "int a = 1
8739 int b = 2
8740
8741 int c = 3",
8742 "foo.groovy",
8743 |metric| {
8744 assert_eq!(metric.loc.sloc(), 4);
8745 assert_eq!(metric.loc.ploc(), 3);
8746 assert_eq!(metric.loc.blank(), 1);
8747 },
8748 );
8749 }
8750
8751 #[test]
8752 fn groovy_single_ploc() {
8753 check_metrics::<GroovyParser>("int x = 42", "foo.groovy", |metric| {
8756 assert_eq!(metric.loc.ploc(), 1);
8757 assert_eq!(metric.loc.cloc(), 0);
8758 });
8759 }
8760
8761 #[test]
8762 fn groovy_multi_ploc() {
8763 check_metrics::<GroovyParser>(
8766 "int a = 1
8767 int b = 2
8768 int c = 3
8769 int d = 4",
8770 "foo.groovy",
8771 |metric| {
8772 assert_eq!(metric.loc.ploc(), 4);
8773 assert_eq!(metric.loc.lloc(), 4);
8774 },
8775 );
8776 }
8777
8778 #[test]
8779 fn groovy_single_statement_lloc() {
8780 check_metrics::<GroovyParser>("println 'hi'", "foo.groovy", |metric| {
8783 assert_eq!(metric.loc.lloc(), 1);
8784 });
8785 }
8786
8787 #[test]
8788 fn groovy_for_lloc() {
8789 check_metrics::<GroovyParser>(
8794 "for (int i = 0; i < 100; i++) {
8795 println(i)
8796 }",
8797 "foo.groovy",
8798 |metric| {
8799 assert_eq!(metric.loc.lloc(), 2);
8801 },
8802 );
8803 }
8804
8805 #[test]
8806 fn groovy_foreach_lloc() {
8807 check_metrics::<GroovyParser>(
8810 "for (item in items) {
8811 println(item)
8812 }",
8813 "foo.groovy",
8814 |metric| {
8815 assert_eq!(metric.loc.lloc(), 2);
8817 },
8818 );
8819 }
8820
8821 #[test]
8822 fn groovy_while_lloc() {
8823 check_metrics::<GroovyParser>(
8826 "int i = 0
8827 while (i < 10) {
8828 i++
8829 println(i)
8830 }",
8831 "foo.groovy",
8832 |metric| {
8833 assert_eq!(metric.loc.lloc(), 4);
8835 },
8836 );
8837 }
8838
8839 #[test]
8840 fn groovy_do_while_lloc() {
8841 check_metrics::<GroovyParser>(
8844 "int i = 0
8845 do {
8846 i++
8847 } while (i < 5)",
8848 "foo.groovy",
8849 |metric| {
8850 assert_eq!(metric.loc.lloc(), 3);
8852 },
8853 );
8854 }
8855
8856 #[test]
8857 fn groovy_continue_lloc() {
8858 check_metrics::<GroovyParser>(
8860 "for (int i = 0; i < 10; i++) {
8861 if (i == 5) {
8862 continue
8863 }
8864 println(i)
8865 }",
8866 "foo.groovy",
8867 |metric| {
8868 assert_eq!(metric.loc.lloc(), 4);
8870 },
8871 );
8872 }
8873
8874 #[test]
8875 fn groovy_expressions_lloc() {
8876 check_metrics::<GroovyParser>(
8879 "int a = 1
8880 a = 2
8881 a += 3
8882 println(a)
8883 doSomething()",
8884 "foo.groovy",
8885 |metric| {
8886 assert_eq!(metric.loc.lloc(), 5);
8888 },
8889 );
8890 }
8891
8892 #[test]
8893 fn groovy_throw_lloc() {
8894 check_metrics::<GroovyParser>(
8896 "throw new RuntimeException('bad')",
8897 "foo.groovy",
8898 |metric| {
8899 assert_eq!(metric.loc.lloc(), 1);
8900 },
8901 );
8902 }
8903
8904 #[test]
8905 fn groovy_general_loc() {
8906 check_metrics::<GroovyParser>(
8918 "class A {
8919 void f(int x) {
8920 if (x > 0) {
8921 println(x)
8922 } else {
8923 println 'neg'
8924 }
8925 return
8926 }
8927 }",
8928 "foo.groovy",
8929 |metric| {
8930 assert_eq!(metric.loc.lloc(), 4);
8931 assert_eq!(metric.loc.cloc(), 0);
8932 },
8933 );
8934 }
8935
8936 #[test]
8937 fn csharp_local_function_in_method_lloc() {
8938 check_metrics::<CsharpParser>(
8942 "class Foo {\n int Bar() {\n int Inner(int x) { return x + 1; }\n return Inner(2);\n }\n}\n",
8943 "foo.cs",
8944 |metric| {
8945 assert_eq!(metric.loc.sloc(), 6);
8946 assert_eq!(metric.loc.ploc(), 6);
8947 assert_eq!(metric.loc.lloc(), 2);
8948 assert_eq!(metric.loc.cloc(), 0);
8949 assert_eq!(metric.loc.blank(), 0);
8950 insta::assert_json_snapshot!(metric.loc);
8951 },
8952 );
8953 }
8954
8955 #[test]
8956 fn csharp_lambda_in_method_lloc() {
8957 check_metrics::<CsharpParser>(
8960 "class Foo {\n void Bar() {\n System.Func<int, int> f = x => x + 1;\n f(3);\n }\n}\n",
8961 "foo.cs",
8962 |metric| {
8963 assert_eq!(metric.loc.sloc(), 6);
8964 assert_eq!(metric.loc.ploc(), 6);
8965 assert_eq!(metric.loc.lloc(), 2);
8966 assert_eq!(metric.loc.cloc(), 0);
8967 assert_eq!(metric.loc.blank(), 0);
8968 insta::assert_json_snapshot!(metric.loc);
8969 },
8970 );
8971 }
8972
8973 #[test]
8974 fn cpp_lambda_in_function_lloc() {
8975 check_metrics::<CppParser>(
8983 "int bar() {\n auto f = [](int x) { return x + 1; };\n return f(2);\n}\n",
8984 "foo.cpp",
8985 |metric| {
8986 assert_eq!(metric.loc.sloc(), 4);
8987 assert_eq!(metric.loc.ploc(), 4);
8988 assert_eq!(metric.loc.lloc(), 3);
8989 assert_eq!(metric.loc.cloc(), 0);
8990 assert_eq!(metric.loc.blank(), 0);
8991 insta::assert_json_snapshot!(metric.loc);
8992 },
8993 );
8994 }
8995
8996 #[test]
8997 fn javascript_nested_function_lloc() {
8998 check_metrics::<JavascriptParser>(
9002 "function outer() {\n function inner() {\n return 1;\n }\n return inner();\n}\n",
9003 "foo.js",
9004 |metric| {
9005 assert_eq!(metric.loc.sloc(), 6);
9006 assert_eq!(metric.loc.ploc(), 6);
9007 assert_eq!(metric.loc.lloc(), 2);
9008 assert_eq!(metric.loc.cloc(), 0);
9009 assert_eq!(metric.loc.blank(), 0);
9010 insta::assert_json_snapshot!(metric.loc);
9011 },
9012 );
9013 }
9014
9015 #[test]
9016 fn javascript_arrow_function_lloc() {
9017 check_metrics::<JavascriptParser>(
9020 "function outer() {\n const inner = (x) => x + 1;\n return inner(2);\n}\n",
9021 "foo.js",
9022 |metric| {
9023 assert_eq!(metric.loc.sloc(), 4);
9024 assert_eq!(metric.loc.ploc(), 4);
9025 assert_eq!(metric.loc.lloc(), 1);
9026 assert_eq!(metric.loc.cloc(), 0);
9027 assert_eq!(metric.loc.blank(), 0);
9028 insta::assert_json_snapshot!(metric.loc);
9029 },
9030 );
9031 }
9032
9033 #[test]
9034 fn kotlin_lambda_literal_in_fun_lloc() {
9035 check_metrics::<KotlinParser>(
9038 "fun outer() {\n val f: (Int) -> Int = { x -> x + 1 }\n f(3)\n}\n",
9039 "foo.kt",
9040 |metric| {
9041 assert_eq!(metric.loc.sloc(), 4);
9042 assert_eq!(metric.loc.ploc(), 4);
9043 assert_eq!(metric.loc.lloc(), 2);
9044 assert_eq!(metric.loc.cloc(), 0);
9045 assert_eq!(metric.loc.blank(), 0);
9046 insta::assert_json_snapshot!(metric.loc);
9047 },
9048 );
9049 }
9050
9051 #[test]
9052 fn kotlin_local_fun_in_fun_lloc() {
9053 check_metrics::<KotlinParser>(
9057 "fun outer() {\n fun inner(x: Int): Int { return x + 1 }\n inner(3)\n}\n",
9058 "foo.kt",
9059 |metric| {
9060 assert_eq!(metric.loc.sloc(), 4);
9061 assert_eq!(metric.loc.ploc(), 4);
9062 assert_eq!(metric.loc.lloc(), 2);
9063 assert_eq!(metric.loc.cloc(), 0);
9064 assert_eq!(metric.loc.blank(), 0);
9065 insta::assert_json_snapshot!(metric.loc);
9066 },
9067 );
9068 }
9069
9070 #[test]
9071 fn kotlin_object_expression_in_fun_lloc() {
9072 check_metrics::<KotlinParser>(
9076 "fun outer() {\n val r = object : Runnable { override fun run() { println(\"hi\") } }\n r.run()\n}\n",
9077 "foo.kt",
9078 |metric| {
9079 assert_eq!(metric.loc.sloc(), 4);
9080 assert_eq!(metric.loc.ploc(), 4);
9081 assert_eq!(metric.loc.lloc(), 3);
9082 assert_eq!(metric.loc.cloc(), 0);
9083 assert_eq!(metric.loc.blank(), 0);
9084 insta::assert_json_snapshot!(metric.loc);
9085 },
9086 );
9087 }
9088
9089 #[test]
9090 fn go_function_literal_initializer_lloc() {
9091 check_metrics::<GoParser>(
9096 "package main\nfunc outer() int {\n inner := func(x int) int { return x + 1 }\n return inner(2)\n}\n",
9097 "foo.go",
9098 |metric| {
9099 assert_eq!(metric.loc.sloc(), 5);
9100 assert_eq!(metric.loc.ploc(), 5);
9101 assert_eq!(metric.loc.lloc(), 3);
9102 assert_eq!(metric.loc.cloc(), 0);
9103 assert_eq!(metric.loc.blank(), 0);
9104 insta::assert_json_snapshot!(metric.loc);
9105 },
9106 );
9107 }
9108
9109 #[test]
9110 fn php_anonymous_function_in_function_lloc() {
9111 check_metrics::<PhpParser>(
9115 "<?php\nfunction outer() {\n $f = function ($x) { return $x + 1; };\n return $f(2);\n}\n",
9116 "foo.php",
9117 |metric| {
9118 assert_eq!(metric.loc.sloc(), 5);
9119 assert_eq!(metric.loc.ploc(), 5);
9120 assert_eq!(metric.loc.lloc(), 3);
9121 assert_eq!(metric.loc.cloc(), 0);
9122 assert_eq!(metric.loc.blank(), 0);
9123 insta::assert_json_snapshot!(metric.loc);
9124 },
9125 );
9126 }
9127
9128 #[test]
9129 fn php_arrow_function_in_function_lloc() {
9130 check_metrics::<PhpParser>(
9133 "<?php\nfunction outer() {\n $f = fn ($x) => $x + 1;\n return $f(2);\n}\n",
9134 "foo.php",
9135 |metric| {
9136 assert_eq!(metric.loc.sloc(), 5);
9137 assert_eq!(metric.loc.ploc(), 5);
9138 assert_eq!(metric.loc.lloc(), 2);
9139 assert_eq!(metric.loc.cloc(), 0);
9140 assert_eq!(metric.loc.blank(), 0);
9141 insta::assert_json_snapshot!(metric.loc);
9142 },
9143 );
9144 }
9145
9146 #[test]
9147 fn lua_nested_local_function_lloc() {
9148 check_metrics::<LuaParser>(
9152 "local function outer()\n local function inner()\n return 1\n end\n return inner()\nend\n",
9153 "foo.lua",
9154 |metric| {
9155 assert_eq!(metric.loc.sloc(), 6);
9156 assert_eq!(metric.loc.ploc(), 6);
9157 assert_eq!(metric.loc.lloc(), 4);
9158 assert_eq!(metric.loc.cloc(), 0);
9159 assert_eq!(metric.loc.blank(), 0);
9160 insta::assert_json_snapshot!(metric.loc);
9161 },
9162 );
9163 }
9164
9165 #[test]
9166 fn lua_function_expression_in_local_decl_lloc() {
9167 check_metrics::<LuaParser>(
9172 "local function outer()\n local f = function (x) return x + 1 end\n return f(2)\nend\n",
9173 "foo.lua",
9174 |metric| {
9175 assert_eq!(metric.loc.sloc(), 4);
9176 assert_eq!(metric.loc.ploc(), 4);
9177 assert_eq!(metric.loc.lloc(), 4);
9178 assert_eq!(metric.loc.cloc(), 0);
9179 assert_eq!(metric.loc.blank(), 0);
9180 insta::assert_json_snapshot!(metric.loc);
9181 },
9182 );
9183 }
9184
9185 #[test]
9186 fn tcl_apply_closure_lloc() {
9187 check_metrics::<TclParser>(
9194 "proc outer {} {\n set f [list x {return [expr {$x + 1}]}]\n apply $f 2\n}\n",
9195 "foo.tcl",
9196 |metric| {
9197 assert_eq!(metric.loc.sloc(), 4);
9198 assert_eq!(metric.loc.ploc(), 4);
9199 assert_eq!(metric.loc.lloc(), 4);
9200 assert_eq!(metric.loc.cloc(), 0);
9201 assert_eq!(metric.loc.blank(), 0);
9202 insta::assert_json_snapshot!(metric.loc);
9203 },
9204 );
9205 }
9206
9207 #[test]
9208 fn perl_anonymous_sub_in_sub_lloc() {
9209 check_metrics::<PerlParser>(
9219 "sub outer {\n my $f = sub { return $_[0] + 1 };\n return $f->(2);\n}\n",
9220 "foo.pl",
9221 |metric| {
9222 assert_eq!(metric.loc.sloc(), 4);
9223 assert_eq!(metric.loc.ploc(), 4);
9224 assert_eq!(metric.loc.lloc(), 2);
9225 assert_eq!(metric.loc.cloc(), 0);
9226 assert_eq!(metric.loc.blank(), 0);
9227 insta::assert_json_snapshot!(metric.loc);
9228 },
9229 );
9230 }
9231
9232 #[test]
9233 fn perl_named_sub_in_sub_lloc() {
9234 check_metrics::<PerlParser>(
9249 "sub outer {\n sub inner { return 1 }\n return inner();\n}\n",
9250 "foo.pl",
9251 |metric| {
9252 assert_eq!(metric.loc.sloc(), 4);
9253 assert_eq!(metric.loc.ploc(), 4);
9254 assert_eq!(metric.loc.lloc(), 1);
9255 assert_eq!(metric.loc.cloc(), 0);
9256 assert_eq!(metric.loc.blank(), 0);
9257 insta::assert_json_snapshot!(metric.loc);
9258 },
9259 );
9260 }
9261
9262 #[test]
9263 fn elixir_fn_inside_def_lloc() {
9264 check_metrics::<ElixirParser>(
9268 "defmodule Foo do\n def outer do\n f = fn x -> x + 1 end\n f.(2)\n end\nend\n",
9269 "foo.ex",
9270 |metric| {
9271 assert_eq!(metric.loc.sloc(), 6);
9272 assert_eq!(metric.loc.ploc(), 6);
9273 assert_eq!(metric.loc.lloc(), 5);
9274 assert_eq!(metric.loc.cloc(), 0);
9275 assert_eq!(metric.loc.blank(), 0);
9276 insta::assert_json_snapshot!(metric.loc);
9277 },
9278 );
9279 }
9280
9281 #[test]
9293 fn rust_nested_min_max_propagates() {
9294 check_metrics::<RustParser>(
9295 "struct C;\nimpl C {\n fn small(&self) {\n let _ = 1;\n }\n fn big(&self) {\n let _ = 1;\n let _ = 2;\n let _ = 3;\n }\n}\n",
9296 "c.rs",
9297 |metric| {
9298 let loc = &metric.loc;
9304 assert!(
9305 loc.sloc_min() <= loc.sloc(),
9306 "sloc_min {} must not exceed unit sloc {}",
9307 loc.sloc_min(),
9308 loc.sloc()
9309 );
9310 assert_eq!(loc.sloc_min(), 3, "smallest leaf method span");
9311 assert_eq!(loc.sloc_max(), loc.sloc(), "largest space is the unit");
9312 assert_eq!(loc.lloc_min(), 1);
9314 },
9315 );
9316 }
9317
9318 #[test]
9323 fn java_nested_min_max_propagates() {
9324 check_metrics::<JavaParser>(
9325 "public class C {\n void small() {\n int x = 1;\n }\n void big() {\n int a = 1;\n int b = 2;\n int c = 3;\n }\n}\n",
9326 "C.java",
9327 |metric| {
9328 let loc = &metric.loc;
9330 assert!(loc.sloc_min() <= loc.sloc());
9331 assert_eq!(loc.sloc_min(), 3, "smallest leaf method span");
9332 assert_eq!(loc.sloc_max(), loc.sloc());
9333 assert_eq!(loc.lloc_min(), 1);
9334 },
9335 );
9336 }
9337
9338 #[test]
9342 fn python_nested_min_max_propagates() {
9343 check_metrics::<PythonParser>(
9344 "class C:\n def small(self):\n x = 1\n def big(self):\n a = 1\n b = 2\n c = 3\n",
9345 "c.py",
9346 |metric| {
9347 let loc = &metric.loc;
9349 assert!(loc.sloc_min() <= loc.sloc());
9350 assert_eq!(loc.sloc_min(), 2, "smallest leaf method span");
9351 assert_eq!(loc.sloc_max(), loc.sloc());
9352 assert_eq!(loc.lloc_min(), 1);
9353 },
9354 );
9355 }
9356
9357 #[test]
9370 fn blank_clamps_negative_to_zero() {
9371 let mut stats = Stats::default();
9372 stats.sloc.unit = false;
9374 stats.sloc.start = 0;
9375 stats.sloc.end = 0;
9376 stats.ploc.lines.insert(0);
9378 stats.cloc.only_comment_line_starts.insert(0);
9380
9381 assert_eq!(stats.sloc(), 1);
9383 assert_eq!(stats.ploc(), 1);
9384 assert_eq!(
9385 stats.blank(),
9386 0,
9387 "blank() must clamp the negative subtraction to 0"
9388 );
9389 }
9390
9391 #[test]
9399 fn cloc_multiple_block_comments_one_line_cpp() {
9400 check_metrics::<CppParser>(
9401 "int f(int /*a*/, int /*b*/) { return 1; }",
9402 "foo.cpp",
9403 |metric| {
9404 assert_eq!(metric.loc.cloc(), 1, "two inline comments => 1 cloc");
9405 assert!(
9406 metric.loc.cloc() <= metric.loc.sloc(),
9407 "cloc must not exceed sloc"
9408 );
9409 assert!(
9410 metric.loc.cloc() <= metric.loc.ploc(),
9411 "cloc must not exceed ploc for a single-line construct"
9412 );
9413 },
9414 );
9415 }
9416
9417 #[test]
9421 fn cloc_multiple_block_comments_one_line_rust() {
9422 check_metrics::<RustParser>(
9423 "fn f(/*a*/ x: i32, /*b*/ y: i32) -> i32 { 1 }",
9424 "foo.rs",
9425 |metric| {
9426 assert_eq!(metric.loc.cloc(), 1, "two inline comments => 1 cloc");
9427 assert!(
9428 metric.loc.cloc() <= metric.loc.sloc(),
9429 "cloc must not exceed sloc"
9430 );
9431 },
9432 );
9433 }
9434
9435 #[test]
9440 fn cloc_multiline_block_comment_counts_each_line() {
9441 check_metrics::<CppParser>(
9442 "int g() {\n /* l1\n l2\n l3 */\n return 0;\n}",
9443 "foo.cpp",
9444 |metric| {
9445 assert_eq!(
9446 metric.loc.cloc(),
9447 3,
9448 "a 3-line block comment counts 3 comment lines"
9449 );
9450 },
9451 );
9452 }
9453
9454 #[test]
9463 fn cloc_multiple_standalone_block_comments_one_line_cpp() {
9464 check_metrics::<CppParser>("/*a*/ /*b*/", "foo.cpp", |metric| {
9465 assert_eq!(
9466 metric.loc.cloc(),
9467 1,
9468 "two standalone comments on one line => 1 cloc"
9469 );
9470 assert_eq!(metric.loc.sloc(), 1);
9471 assert!(
9472 metric.loc.cloc() <= metric.loc.sloc(),
9473 "cloc must not exceed sloc"
9474 );
9475 });
9476 }
9477
9478 #[test]
9482 fn cloc_multiple_standalone_block_comments_one_line_rust() {
9483 check_metrics::<RustParser>("/*a*/ /*b*/", "foo.rs", |metric| {
9484 assert_eq!(
9485 metric.loc.cloc(),
9486 1,
9487 "two standalone comments on one line => 1 cloc"
9488 );
9489 assert_eq!(metric.loc.sloc(), 1);
9490 assert!(
9491 metric.loc.cloc() <= metric.loc.sloc(),
9492 "cloc must not exceed sloc"
9493 );
9494 });
9495 }
9496
9497 #[test]
9504 fn cloc_standalone_comments_then_code_no_double_count() {
9505 check_metrics::<CppParser>("/*a*/ /*b*/ /*c*/\nint x = 1;\n", "foo.cpp", |metric| {
9506 assert_eq!(metric.loc.sloc(), 2);
9507 assert_eq!(
9508 metric.loc.cloc(),
9509 1,
9510 "only line 1 carries comments => 1 cloc"
9511 );
9512 assert!(
9513 metric.loc.cloc() <= metric.loc.sloc(),
9514 "cloc must not exceed sloc"
9515 );
9516 });
9517 }
9518
9519 #[test]
9523 fn irules_blank() {
9524 check_metrics::<IrulesParser>(
9525 "when X {\n\n set x 1\n\n set y 2\n}\n",
9526 "foo.irule",
9527 |metric| {
9528 assert_eq!(metric.loc.sloc(), 6);
9529 assert_eq!(metric.loc.ploc(), 4);
9530 assert_eq!(metric.loc.lloc(), 3);
9531 assert_eq!(metric.loc.cloc(), 0);
9532 assert_eq!(metric.loc.blank(), 2);
9533 },
9534 );
9535 }
9536
9537 #[test]
9540 fn irules_no_zero_blank() {
9541 check_metrics::<IrulesParser>(
9542 "when HTTP_REQUEST {\n set x 1\n log local0. $x\n}\n",
9543 "foo.irule",
9544 |metric| {
9545 assert_eq!(metric.loc.sloc(), 4);
9546 assert_eq!(metric.loc.ploc(), 4);
9547 assert_eq!(metric.loc.lloc(), 3);
9548 assert_eq!(metric.loc.blank(), 0);
9549 },
9550 );
9551 }
9552
9553 #[test]
9556 fn irules_cloc() {
9557 check_metrics::<IrulesParser>(
9558 "# a\n# b\n# c\nwhen X { set x 1 }\n",
9559 "foo.irule",
9560 |metric| {
9561 assert_eq!(metric.loc.cloc(), 3);
9562 assert_eq!(metric.loc.blank(), 0);
9563 },
9564 );
9565 }
9566
9567 #[test]
9571 fn irules_lloc() {
9572 check_metrics::<IrulesParser>(
9573 "when X {\n if { $a } {\n set x 1\n }\n log local0. done\n}\n",
9574 "foo.irule",
9575 |metric| {
9576 assert_eq!(metric.loc.lloc(), 4);
9577 },
9578 );
9579 }
9580
9581 #[test]
9587 fn irules_no_command_substitution_lloc() {
9588 check_metrics::<IrulesParser>(
9589 "when X {\n set y [expr { 1 + 2 }]\n}\n",
9590 "foo.irule",
9591 |metric| {
9592 assert_eq!(metric.loc.lloc(), 2);
9593 },
9594 );
9595 }
9596
9597 #[test]
9601 fn irules_switch_lloc() {
9602 check_metrics::<IrulesParser>(
9603 "when X {\n switch $h {\n a { set r 1 }\n b { set r 2 }\n }\n}\n",
9604 "foo.irule",
9605 |metric| {
9606 assert_eq!(metric.loc.lloc(), 4);
9607 },
9608 );
9609 }
9610
9611 #[test]
9614 fn irules_proc_lloc() {
9615 check_metrics::<IrulesParser>(
9616 "proc f { a } {\n return $a\n}\n",
9617 "foo.irule",
9618 |metric| {
9619 assert_eq!(metric.loc.lloc(), 2);
9620 },
9621 );
9622 }
9623
9624 #[test]
9627 fn objc_blank() {
9628 check_metrics::<ObjcParser>(
9629 "
9630
9631 int a = 42;
9632
9633 int b = 43;
9634
9635 ",
9636 "foo.m",
9637 |metric| {
9638 assert_eq!(metric.loc.blank(), 1);
9639 insta::assert_json_snapshot!(metric.loc, @r#"
9640 {
9641 "sloc": 3,
9642 "ploc": 2,
9643 "lloc": 2,
9644 "cloc": 0,
9645 "blank": 1,
9646 "sloc_average": 3.0,
9647 "ploc_average": 2.0,
9648 "lloc_average": 2.0,
9649 "cloc_average": 0.0,
9650 "blank_average": 1.0,
9651 "sloc_min": 3,
9652 "sloc_max": 3,
9653 "cloc_min": 0,
9654 "cloc_max": 0,
9655 "ploc_min": 2,
9656 "ploc_max": 2,
9657 "lloc_min": 2,
9658 "lloc_max": 2,
9659 "blank_min": 1,
9660 "blank_max": 1
9661 }
9662 "#);
9663 },
9664 );
9665 }
9666
9667 #[test]
9670 fn objc_cloc() {
9671 check_metrics::<ObjcParser>(
9672 "/* Block comment
9673 still the block */
9674 // Line comment
9675 int a = 42; // trailing",
9676 "foo.m",
9677 |metric| {
9678 insta::assert_json_snapshot!(metric.loc, @r#"
9679 {
9680 "sloc": 4,
9681 "ploc": 1,
9682 "lloc": 1,
9683 "cloc": 4,
9684 "blank": 0,
9685 "sloc_average": 4.0,
9686 "ploc_average": 1.0,
9687 "lloc_average": 1.0,
9688 "cloc_average": 4.0,
9689 "blank_average": 0.0,
9690 "sloc_min": 4,
9691 "sloc_max": 4,
9692 "cloc_min": 4,
9693 "cloc_max": 4,
9694 "ploc_min": 1,
9695 "ploc_max": 1,
9696 "lloc_min": 1,
9697 "lloc_max": 1,
9698 "blank_min": 0,
9699 "blank_max": 0
9700 }
9701 "#);
9702 },
9703 );
9704 }
9705
9706 #[test]
9710 fn objc_lloc() {
9711 check_metrics::<ObjcParser>(
9712 "@implementation Foo
9713- (int)bar {
9714 int a = 1;
9715 int b = 2;
9716 return a + b;
9717}
9718@end
9719",
9720 "foo.m",
9721 |metric| {
9722 assert_eq!(metric.loc.lloc(), 3);
9725 insta::assert_json_snapshot!(metric.loc, @r#"
9726 {
9727 "sloc": 7,
9728 "ploc": 7,
9729 "lloc": 3,
9730 "cloc": 0,
9731 "blank": 0,
9732 "sloc_average": 2.3333333333333335,
9733 "ploc_average": 2.3333333333333335,
9734 "lloc_average": 1.0,
9735 "cloc_average": 0.0,
9736 "blank_average": 0.0,
9737 "sloc_min": 5,
9738 "sloc_max": 7,
9739 "cloc_min": 0,
9740 "cloc_max": 0,
9741 "ploc_min": 5,
9742 "ploc_max": 7,
9743 "lloc_min": 3,
9744 "lloc_max": 3,
9745 "blank_min": 0,
9746 "blank_max": 0
9747 }
9748 "#);
9749 },
9750 );
9751 }
9752
9753 #[test]
9759 fn objc_no_declaration_in_for_header_lloc() {
9760 check_metrics::<ObjcParser>(
9761 "@implementation Foo
9762- (void)bar {
9763 for (int i = 0; i < 10; ++i) {
9764 [self use:i];
9765 }
9766}
9767@end
9768",
9769 "foo.m",
9770 |metric| {
9771 assert_eq!(metric.loc.lloc(), 2);
9775 insta::assert_json_snapshot!(metric.loc, @r#"
9776 {
9777 "sloc": 7,
9778 "ploc": 7,
9779 "lloc": 2,
9780 "cloc": 0,
9781 "blank": 0,
9782 "sloc_average": 2.3333333333333335,
9783 "ploc_average": 2.3333333333333335,
9784 "lloc_average": 0.6666666666666666,
9785 "cloc_average": 0.0,
9786 "blank_average": 0.0,
9787 "sloc_min": 5,
9788 "sloc_max": 7,
9789 "cloc_min": 0,
9790 "cloc_max": 0,
9791 "ploc_min": 5,
9792 "ploc_max": 7,
9793 "lloc_min": 2,
9794 "lloc_max": 2,
9795 "blank_min": 0,
9796 "blank_max": 0
9797 }
9798 "#);
9799 },
9800 );
9801 }
9802
9803 #[test]
9804 fn objc_at_directives_lloc() {
9805 check_metrics::<ObjcParser>(
9811 "@implementation Foo
9812- (void)bar {
9813 @synchronized (self) {
9814 [self use];
9815 }
9816 @autoreleasepool {
9817 [self use];
9818 }
9819}
9820@end
9821",
9822 "foo.m",
9823 |metric| {
9824 assert_eq!(metric.loc.lloc(), 3);
9829 insta::assert_json_snapshot!(metric.loc, @r#"
9830 {
9831 "sloc": 10,
9832 "ploc": 10,
9833 "lloc": 3,
9834 "cloc": 0,
9835 "blank": 0,
9836 "sloc_average": 3.3333333333333335,
9837 "ploc_average": 3.3333333333333335,
9838 "lloc_average": 1.0,
9839 "cloc_average": 0.0,
9840 "blank_average": 0.0,
9841 "sloc_min": 8,
9842 "sloc_max": 10,
9843 "cloc_min": 0,
9844 "cloc_max": 0,
9845 "ploc_min": 8,
9846 "ploc_max": 10,
9847 "lloc_min": 3,
9848 "lloc_max": 3,
9849 "blank_min": 0,
9850 "blank_max": 0
9851 }
9852 "#);
9853 },
9854 );
9855 }
9856}