Skip to main content

fallow_core/
results.rs

1// Re-export all result types from fallow-types
2pub use fallow_types::output_dead_code::{
3    BoundaryViolationFinding, CircularDependencyFinding, DuplicateExportFinding,
4    EmptyCatalogGroupFinding, MisconfiguredDependencyOverrideFinding, PrivateTypeLeakFinding,
5    ReExportCycleFinding, TestOnlyDependencyFinding, TypeOnlyDependencyFinding,
6    UnlistedDependencyFinding, UnresolvedCatalogReferenceFinding, UnresolvedImportFinding,
7    UnusedCatalogEntryFinding, UnusedClassMemberFinding, UnusedDependencyFinding,
8    UnusedDependencyOverrideFinding, UnusedDevDependencyFinding, UnusedEnumMemberFinding,
9    UnusedExportFinding, UnusedFileFinding, UnusedOptionalDependencyFinding, UnusedTypeFinding,
10};
11pub use fallow_types::results::{
12    AnalysisResults, BoundaryViolation, CircularDependency, DependencyLocation,
13    DependencyOverrideMisconfigReason, DependencyOverrideSource, DuplicateExport,
14    DuplicateLocation, EmptyCatalogGroup, EntryPointSummary, ExportUsage, ImportSite,
15    MisconfiguredDependencyOverride, PrivateTypeLeak, ReExportCycle, ReExportCycleKind,
16    ReferenceLocation, StaleSuppression, SuppressionOrigin, TestOnlyDependency, TypeOnlyDependency,
17    UnlistedDependency, UnresolvedCatalogReference, UnresolvedImport, UnusedCatalogEntry,
18    UnusedDependency, UnusedDependencyOverride, UnusedExport, UnusedFile, UnusedMember,
19};
20
21#[cfg(test)]
22mod tests {
23    use std::path::PathBuf;
24
25    use super::*;
26    use crate::extract::MemberKind;
27    use fallow_types::output_dead_code::{UnresolvedImportFinding, UnusedFileFinding};
28
29    #[test]
30    fn empty_results_no_issues() {
31        let results = AnalysisResults::default();
32        assert_eq!(results.total_issues(), 0);
33        assert!(!results.has_issues());
34    }
35
36    #[test]
37    fn results_with_unused_file() {
38        let mut results = AnalysisResults::default();
39        results
40            .unused_files
41            .push(UnusedFileFinding::with_actions(UnusedFile {
42                path: PathBuf::from("test.ts"),
43            }));
44        assert_eq!(results.total_issues(), 1);
45        assert!(results.has_issues());
46    }
47
48    #[test]
49    fn results_with_unused_export() {
50        let mut results = AnalysisResults::default();
51        results
52            .unused_exports
53            .push(UnusedExportFinding::with_actions(UnusedExport {
54                path: PathBuf::from("test.ts"),
55                export_name: "foo".to_string(),
56                is_type_only: false,
57                line: 1,
58                col: 0,
59                span_start: 0,
60                is_re_export: false,
61            }));
62        assert_eq!(results.total_issues(), 1);
63        assert!(results.has_issues());
64    }
65
66    #[test]
67    fn results_total_counts_all_types() {
68        let mut results = AnalysisResults::default();
69        results
70            .unused_files
71            .push(UnusedFileFinding::with_actions(UnusedFile {
72                path: PathBuf::from("a.ts"),
73            }));
74        results
75            .unused_exports
76            .push(UnusedExportFinding::with_actions(UnusedExport {
77                path: PathBuf::from("b.ts"),
78                export_name: "x".to_string(),
79                is_type_only: false,
80                line: 1,
81                col: 0,
82                span_start: 0,
83                is_re_export: false,
84            }));
85        results
86            .unused_types
87            .push(UnusedTypeFinding::with_actions(UnusedExport {
88                path: PathBuf::from("c.ts"),
89                export_name: "T".to_string(),
90                is_type_only: true,
91                line: 1,
92                col: 0,
93                span_start: 0,
94                is_re_export: false,
95            }));
96        results
97            .unused_dependencies
98            .push(UnusedDependencyFinding::with_actions(UnusedDependency {
99                package_name: "dep".to_string(),
100                location: DependencyLocation::Dependencies,
101                path: PathBuf::from("package.json"),
102                line: 5,
103                used_in_workspaces: Vec::new(),
104            }));
105        results
106            .unused_dev_dependencies
107            .push(UnusedDevDependencyFinding::with_actions(UnusedDependency {
108                package_name: "dev".to_string(),
109                location: DependencyLocation::DevDependencies,
110                path: PathBuf::from("package.json"),
111                line: 5,
112                used_in_workspaces: Vec::new(),
113            }));
114        results
115            .unused_enum_members
116            .push(UnusedEnumMemberFinding::with_actions(UnusedMember {
117                path: PathBuf::from("d.ts"),
118                parent_name: "E".to_string(),
119                member_name: "A".to_string(),
120                kind: MemberKind::EnumMember,
121                line: 1,
122                col: 0,
123            }));
124        results
125            .unused_class_members
126            .push(UnusedClassMemberFinding::with_actions(UnusedMember {
127                path: PathBuf::from("e.ts"),
128                parent_name: "C".to_string(),
129                member_name: "m".to_string(),
130                kind: MemberKind::ClassMethod,
131                line: 1,
132                col: 0,
133            }));
134        results
135            .unresolved_imports
136            .push(UnresolvedImportFinding::with_actions(UnresolvedImport {
137                path: PathBuf::from("f.ts"),
138                specifier: "./missing".to_string(),
139                line: 1,
140                col: 0,
141                specifier_col: 0,
142            }));
143        results
144            .unlisted_dependencies
145            .push(UnlistedDependencyFinding::with_actions(
146                UnlistedDependency {
147                    package_name: "unlisted".to_string(),
148                    imported_from: vec![ImportSite {
149                        path: PathBuf::from("g.ts"),
150                        line: 1,
151                        col: 0,
152                    }],
153                },
154            ));
155        results
156            .duplicate_exports
157            .push(DuplicateExportFinding::with_actions(DuplicateExport {
158                export_name: "dup".to_string(),
159                locations: vec![
160                    DuplicateLocation {
161                        path: PathBuf::from("h.ts"),
162                        line: 15,
163                        col: 0,
164                    },
165                    DuplicateLocation {
166                        path: PathBuf::from("i.ts"),
167                        line: 30,
168                        col: 0,
169                    },
170                ],
171            }));
172
173        assert_eq!(results.total_issues(), 10);
174        assert!(results.has_issues());
175    }
176}