fix: resolve CI/CD issues - remove unused dependencies and imports

- Remove unused thiserror dependency from Cargo.toml
- Remove unused imports (Text, Tabs, Widget, Event, KeyCode, KeyEventKind) from tui/mod.rs
- Remove unused imports (File, Write) from export/mod.rs
- Remove unused pub use ComplexityDistribution from core/analyzer.rs
This commit is contained in:
Developer
2026-02-05 15:56:58 +00:00
parent 1da735b646
commit 98e8df8906
23 changed files with 2880 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
use std::path::PathBuf;
use techdebt_tracker_cli::models::{Priority, TechDebtItem, FileLocation};
#[test]
fn test_priority_from_keyword() {
assert_eq!(Priority::from_keyword("FIXME"), Priority::Critical);
assert_eq!(Priority::from_keyword("BUG"), Priority::Critical);
assert_eq!(Priority::from_keyword("TODO"), Priority::Medium);
assert_eq!(Priority::from_keyword("HACK"), Priority::Low);
assert_eq!(Priority::from_keyword("XXX"), Priority::High);
assert_eq!(Priority::from_keyword("NOTE"), Priority::Low);
}
#[test]
fn test_priority_ordering() {
assert!(Priority::Critical > Priority::High);
assert!(Priority::High > Priority::Medium);
assert!(Priority::Medium > Priority::Low);
assert!(Priority::Low < Priority::Critical);
}
#[test]
fn test_priority_as_str() {
assert_eq!(Priority::Critical.as_str(), "Critical");
assert_eq!(Priority::High.as_str(), "High");
assert_eq!(Priority::Medium.as_str(), "Medium");
assert_eq!(Priority::Low.as_str(), "Low");
}
#[test]
fn test_tech_debt_item_creation() {
let location = FileLocation {
path: PathBuf::from("/test/file.rs"),
line: 10,
column: 5,
end_line: None,
end_column: None,
};
let item = TechDebtItem::new(
"FIXME".to_string(),
"This is a test fixme".to_string(),
location,
"Rust".to_string(),
techdebt_tracker_cli::models::CommentType::SingleLine,
);
assert_eq!(item.keyword, "FIXME");
assert_eq!(item.priority, Priority::Critical);
assert!(!item.id.is_empty());
}

View File

@@ -0,0 +1,47 @@
use assert_cmd::Command;
use std::path::PathBuf;
#[test]
fn test_cli_help() {
let mut cmd = Command::cargo_bin("techdebt-tracker-cli").unwrap();
cmd.arg("--help")
.assert()
.success();
}
#[test]
fn test_cli_version() {
let mut cmd = Command::cargo_bin("techdebt-tracker-cli").unwrap();
cmd.arg("--version")
.assert()
.success();
}
#[test]
fn test_init_command() {
let temp_dir = tempfile::tempdir().unwrap();
let temp_path = temp_dir.path().to_path_buf();
let mut cmd = Command::cargo_bin("techdebt-tracker-cli").unwrap();
cmd.arg("init")
.arg("--path")
.arg(&temp_path)
.assert()
.success();
let config_path = temp_path.join("techdebt.yaml");
assert!(config_path.exists());
let content = std::fs::read_to_string(&config_path).unwrap();
assert!(content.contains("patterns:"));
assert!(content.contains("languages:"));
}
#[test]
fn test_analyze_command_nonexistent_path() {
let mut cmd = Command::cargo_bin("techdebt-tracker-cli").unwrap();
cmd.arg("analyze")
.arg("/nonexistent/path")
.assert()
.failure();
}

View File

@@ -0,0 +1,81 @@
// JavaScript sample file with technical debt comments
function calculateTotal(items) {
// TODO: This should use reduce instead of a loop
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
return total;
}
function fetchUserData(userId) {
// FIXME: API error handling is missing
// FIXME: This endpoint may return null
return fetch(`/api/users/${userId}`)
.then(response => response.json());
}
function processPayment(amount) {
// HACK: Quick fix for holiday season
if (amount > 1000) {
console.log("High value transaction");
}
// TODO: Implement proper payment processing
}
function createUser(name, email) {
// NOTE: Email validation is basic
if (!email.includes('@')) {
throw new Error('Invalid email');
}
return { name, email };
}
class DataProcessor {
constructor() {
this.data = [];
// XXX: Memory leak - data is never cleared
}
addItem(item) {
this.data.push(item);
}
process() {
// BUG: This doesn't handle edge cases
return this.data.map(x => x * 2);
}
}
// TODO: Add JSDoc comments
// TODO: Write unit tests
async function loadConfig() {
// FIXME: Hardcoded path should be configurable
const response = await fetch('/config.json');
return response.json();
}
function temporaryFix() {
// TEMP: Remove this after Q1
return { status: 'pending' };
}
function oldCode() {
// REFACTOR: This code is legacy
let result = 0;
for (let i = 0; i < 10; i++) {
result += i;
}
return result;
}
module.exports = {
calculateTotal,
fetchUserData,
processPayment,
createUser,
DataProcessor,
loadConfig,
};

View File

@@ -0,0 +1,94 @@
# Python sample file with technical debt comments
def calculate_average(numbers):
# TODO: Handle empty list case
return sum(numbers) / len(numbers)
def process_user(user_data):
# FIXME: This may raise KeyError for missing fields
name = user_data['name']
email = user_data['email']
return {'name': name, 'email': email}
def fetch_data_from_api(endpoint):
# HACK: Skip SSL verification for testing
import requests
response = requests.get(endpoint, verify=False)
# TODO: Add retry logic
return response.json()
class DatabaseConnection:
def __init__(self, connection_string):
# FIXME: Connection string should be encrypted
self.connection_string = connection_string
def connect(self):
# BUG: Connection timeout not implemented
print("Connecting to database...")
def disconnect(self):
# NOTE: Pool cleanup happens automatically
print("Disconnecting...")
def temp_workaround():
# TEMP: Quick fix for production issue
return None
def old_implementation():
# REFACTOR: Use list comprehension instead
result = []
for i in range(10):
result.append(i * 2)
return result
def validate_input(data):
# XXX: Critical security vulnerability!
# This eval is dangerous
return eval(data) # nosec
def complex_function():
# TODO: This function is too long, split it up
# TODO: Add type hints
# TODO: Add docstring
x = 1
y = 2
z = 3
a = 4
b = 5
return x + y + z + a + b
class LegacyClass:
"""This class needs refactoring."""
def __init__(self):
self._internal_state = None
# FIXME: Memory leak risk
def _old_method(self):
# NOTE: This is deprecated
pass
def new_method(self):
"""Modern replacement for _old_method."""
pass
# TODO: Add exception handling
# TODO: Write docstrings for all public methods
# TODO: Add unit tests
def main():
data = [1, 2, 3, 4, 5]
avg = calculate_average(data)
print(f"Average: {avg}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,60 @@
// This is a Rust file with various TODO/FIXME comments
fn calculate_sum(a: i32, b: i32) -> i32 {
// TODO: Implement proper error handling
a + b
}
fn process_data(data: &[u8]) -> Result<(), String> {
// FIXME: This function has a bug with empty data
if data.is_empty() {
return Err("No data provided".to_string());
}
Ok(())
}
fn complex_function(x: i32) -> i32 {
// HACK: This is a workaround for a dependency issue
// TODO: Refactor this when the library is updated
x * 2 + 1
}
fn another_function() {
// NOTE: This function is deprecated
// TODO: Remove in next version
println!("This is deprecated");
}
struct User {
id: u32,
name: String,
}
impl User {
fn new(id: u32, name: String) -> Self {
// FIXME: Validation is missing here!
Self { id, name }
}
}
// XXX: This is a critical issue that needs immediate attention
fn critical_function() {
// BUG: Memory leak detected here
let _data = vec![1, 2, 3];
}
// TODO: Implement unit tests for this module
// TODO: Add documentation comments
fn temp_impl() {
// TEMP: Quick fix for release
println!("temp");
}
fn refactor_needed() {
// REFACTOR: This code is hard to maintain
let x = 1;
let y = 2;
let z = 3;
println!("{} {} {}", x, y, z);
}

View File

@@ -0,0 +1,113 @@
use std::path::PathBuf;
use techdebt_tracker_cli::core::language::{Language, LanguageParser};
use techdebt_tracker_cli::models::{Config, PatternConfig, Priority};
#[test]
fn test_language_from_path_js() {
let path = PathBuf::from("test.js");
assert_eq!(Language::from_path(&path), Some(Language::JavaScript));
}
#[test]
fn test_language_from_path_ts() {
let path = PathBuf::from("test.ts");
assert_eq!(Language::from_path(&path), Some(Language::TypeScript));
}
#[test]
fn test_language_from_path_py() {
let path = PathBuf::from("test.py");
assert_eq!(Language::from_path(&path), Some(Language::Python));
}
#[test]
fn test_language_from_path_rs() {
let path = PathBuf::from("test.rs");
assert_eq!(Language::from_path(&path), Some(Language::Rust));
}
#[test]
fn test_language_from_path_unknown() {
let path = PathBuf::from("test.xyz");
assert_eq!(Language::from_path(&path), None);
}
#[test]
fn test_language_single_line_comment() {
assert_eq!(Language::JavaScript.single_line_comment(), Some("//"));
assert_eq!(Language::Python.single_line_comment(), Some("#"));
assert_eq!(Language::Rust.single_line_comment(), Some("//"));
assert_eq!(Language::Unknown.single_line_comment(), None);
}
#[test]
fn test_language_as_str() {
assert_eq!(Language::JavaScript.as_str(), "JavaScript");
assert_eq!(Language::Python.as_str(), "Python");
assert_eq!(Language::Rust.as_str(), "Rust");
}
#[test]
fn test_javascript_comment_parsing() {
let content = r#"
function test() {
// TODO: Implement this
return true;
}
"#;
let parser = LanguageParser::new(Language::JavaScript);
let patterns = vec![PatternConfig {
keyword: "TODO".to_string(),
priority: Priority::Medium,
regex: false,
}];
let items = parser.parse(content, &PathBuf::from("test.js"), &patterns).unwrap();
assert!(!items.is_empty());
assert!(items.iter().any(|i| i.keyword == "TODO"));
}
#[test]
fn test_python_comment_parsing() {
let content = r#"
def test():
# FIXME: This is broken
return True
"#;
let parser = LanguageParser::new(Language::Python);
let patterns = vec![PatternConfig {
keyword: "FIXME".to_string(),
priority: Priority::Critical,
regex: false,
}];
let items = parser.parse(content, &PathBuf::from("test.py"), &patterns).unwrap();
assert!(!items.is_empty());
assert!(items.iter().any(|i| i.keyword == "FIXME"));
}
#[test]
fn test_multiline_comment_parsing() {
let content = r#"
/*
* TODO: Multi-line comment
* Need to fix this later
*/
"#;
let parser = LanguageParser::new(Language::JavaScript);
let patterns = vec![PatternConfig {
keyword: "TODO".to_string(),
priority: Priority::Medium,
regex: false,
}];
let items = parser.parse(content, &PathBuf::from("test.js"), &patterns).unwrap();
assert!(!items.is_empty());
}