Skip to content

Commit

Permalink
Merge branch 'furnic/extract-core-improvements'
Browse files Browse the repository at this point in the history
  • Loading branch information
nfurfaro committed Mar 7, 2024
2 parents f1d2284 + a6ddac6 commit a85e0d9
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 89 deletions.
36 changes: 36 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ clap = { version = "4.4.7", features = ["derive"] }
colored = "2.0.4"
ctrlc = "3.1.0"
dialoguer = "0.11.0"
fs_extra = "1.3.0"
indicatif = {version = "*", features = ["rayon"]}
lazy_static = "1.4.0"
prettytable-rs = "^0.10"
Expand All @@ -24,4 +25,5 @@ rayon = "1.5"
regex = "1.10.2"
tempfile = "3.8.1"
tokio = { version = "1.8.0", features = ["macros", "rt-multi-thread"] }
walkdir = "2.3.2"

8 changes: 7 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::languages::common::Language;
use crate::{handlers::mutator::Mutant, languages};
use fs_extra::error::Error;
use regex::Regex;
use std::sync::Mutex;
use std::{io, path::PathBuf, process};
use tempfile::TempDir;
Expand All @@ -13,7 +15,11 @@ pub trait LanguageConfig {
fn build_command(&self) -> &'static str;
fn manifest_name(&self) -> &'static str;
fn excluded_dirs(&self) -> Vec<&'static str>;
fn setup_test_infrastructure(&self) -> io::Result<TempDir>;
fn filter_tests(&self) -> bool;
fn test_regex(&self) -> Option<Regex>;
fn comment_regex(&self) -> Regex;
fn literal_regex(&self) -> Regex;
fn setup_test_infrastructure(&self) -> Result<TempDir, Error>;
fn copy_src_file(
&self,
temp_dir: &TempDir,
Expand Down
20 changes: 0 additions & 20 deletions src/filters.rs

This file was deleted.

23 changes: 15 additions & 8 deletions src/handlers/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::{
cli::Args,
config::LanguageConfig,
file_manager::scan_for_excluded_dirs,
filters::test_regex,
handlers::mutator::{mutants, Mutant},
reporter::count_tests,
token::MetaToken,
Expand Down Expand Up @@ -80,16 +79,24 @@ pub fn scan(args: Args, config: Box<dyn LanguageConfig>) -> Result<ScanResult> {
let mut contains_unit_tests: Vec<PathBuf> = vec![];

for path in &paths {
let num_tests = count_tests(path, test_regex(&config.language()));
if num_tests > 0 {
contains_unit_tests.push(path.clone());
test_count += num_tests;
let regex = config.test_regex();

if let Some(regex) = regex {
let num_unit_tests = count_tests(path, regex);
if num_unit_tests > 0 {
contains_unit_tests.push(path.clone());
test_count += num_unit_tests;
}
}
}

// @todo consider adding a switch here to mutate all tokens in source files, or only those in files with unit tests
// @todo improve error message to comunicate that no tokens were found, no target source files were found, or that no unit tests were found in the source files.
let meta_tokens = collect_tokens(contains_unit_tests.clone(), config).expect("No tokens found");
let paths_to_scan = if config.filter_tests() {
contains_unit_tests.clone()
} else {
paths.clone()
};

let meta_tokens = collect_tokens(paths_to_scan, config).expect("No tokens found");

let mutants = mutants(&meta_tokens, args.random);

Expand Down
54 changes: 38 additions & 16 deletions src/languages/noir.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
use crate::config::LanguageConfig;
use crate::handlers::mutator::Mutant;
use crate::languages::common::Language;
use std::sync::Mutex;
use std::{
fs::{self, File, OpenOptions},
io::{self, Write},
path::PathBuf,
process::{self, Command},
sync::Mutex,
};

// use lazy_static::lazy_static;
use fs_extra::error::Error;
use regex::Regex;
use tempfile::{Builder, TempDir};

use tempfile::Builder;
use tempfile::TempDir;
use crate::{config::LanguageConfig, handlers::mutator::Mutant, languages::common::Language};

const NAME: &str = "Noir";
const EXT: &str = "nr";
const TEST_RUNNER: &str = "nargo";
const TEST_COMMAND: &str = "test";
const BUILD_COMMAND: &str = "build";
const MANIFEST_NAME: &str = "Nargo.toml";
const FILTER_TESTS: bool = true;

#[derive(Clone)]
pub struct NoirConfig;
Expand All @@ -23,34 +29,50 @@ impl LanguageConfig for NoirConfig {
}

fn name(&self) -> &'static str {
"Noir"
NAME
}

fn ext(&self) -> &'static str {
"nr"
EXT
}

fn test_runner(&self) -> &'static str {
"nargo"
TEST_RUNNER
}

fn test_command(&self) -> &'static str {
"test"
TEST_COMMAND
}

fn build_command(&self) -> &'static str {
"build"
BUILD_COMMAND
}

fn manifest_name(&self) -> &'static str {
"Nargo.toml"
MANIFEST_NAME
}

fn excluded_dirs(&self) -> Vec<&'static str> {
vec!["temp", "target", "test", "tests"]
}

fn setup_test_infrastructure(&self) -> io::Result<TempDir> {
fn filter_tests(&self) -> bool {
FILTER_TESTS
}

fn test_regex(&self) -> Option<Regex> {
Some(Regex::new(r"#\[test(\(.*\))?\]\s+fn\s+\w+\(\)\s*\{[^}]*\}").unwrap())
}

fn comment_regex(&self) -> Regex {
Regex::new(r"//.*|/\*(?s:.*?)\*/").unwrap()
}

fn literal_regex(&self) -> Regex {
Regex::new(r#""([^"\\]|\\.)*""#).unwrap()
}

fn setup_test_infrastructure(&self) -> Result<TempDir, Error> {
// Create a temp directory with a specific prefix
let temp_dir = Builder::new()
.prefix("Hunter_temp_mutations_")
Expand Down Expand Up @@ -94,15 +116,15 @@ compiler_version = ">=0.22.0"

let src_dir = temp_dir.path().join("src");

let temp_file = src_dir.join(format!("mutation_{}.{}", mutant.id(), self.ext()));
let temp_file = src_dir.join(format!("mutation_{}.{}", mutant.id(), EXT));
fs::copy(mutant.path(), &temp_file)?;

// Lock the mutex before writing to the file
let _guard = mutex.unwrap().lock().unwrap();

let mut lib_file = OpenOptions::new()
.write(true)
.open(src_dir.join(format!("lib.{}", self.ext())))?;
.open(src_dir.join(format!("lib.{}", EXT)))?;
writeln!(lib_file, "mod mutation_{};", mutant.id())?;

Ok(temp_file)
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::io::Result;
use std::process;
pub mod config;
pub mod file_manager;
pub mod filters;
// pub mod filters;
pub mod handlers;
pub mod languages;
pub mod processor;
Expand Down
29 changes: 18 additions & 11 deletions src/processor.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
use crate::{
cli::Args,
config::LanguageConfig,
file_manager::mutate_temp_file,
handlers::mutator::{calculate_mutation_score, Mutant, MutationStatus},
reporter::{mutants_progress_bar, mutation_test_summary_table, print_table},
};
use ctrlc;
use lazy_static::lazy_static;
use rayon::prelude::*;
use std::{
collections::HashSet,
fs,
Expand All @@ -19,6 +9,19 @@ use std::{
},
};

use ctrlc;
use lazy_static::lazy_static;
use rayon::prelude::*;

use crate::{
cli::Args,
config::LanguageConfig,
file_manager::mutate_temp_file,
handlers::mutator::{calculate_mutation_score, Mutant, MutationStatus},
languages::common::Language,
reporter::{mutants_progress_bar, mutation_test_summary_table, print_table},
};

pub fn process_mutants(
mutants: &mut Vec<Mutant>,
args: Args,
Expand Down Expand Up @@ -77,7 +80,11 @@ pub fn process_mutants(
std::process::exit(1);
}

let temp_file = config_guard.copy_src_file(&temp_dir, m, Some(&LIB_FILE_MUTEX))
let lib_mutex = match config_guard.language() {
Language::Noir => Some(&LIB_FILE_MUTEX as &Mutex<()>),
};

let temp_file = config_guard.copy_src_file(&temp_dir, m, lib_mutex)
.expect("Failed to copy src to temp file");

mutate_temp_file(&temp_file, m);
Expand Down
Loading

0 comments on commit a85e0d9

Please sign in to comment.