diff --git a/CLAUDE.md b/CLAUDE.md index 5165751..f597b21 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,12 +19,49 @@ just quality-tools # Auto-format code with rustfmt ### Running the Tool +**Single file mode** — refactor one PHP file: ```bash -cargo run -- path/to/file.php -# or -./target/debug/php-refactor path/to/file.php +cargo run -- app.php +./target/debug/php-refactor app.php ``` +**Directory mode** — refactor all PHP files in a directory (recursive): +```bash +cargo run -- src/ +./target/debug/php-refactor tests/ +``` + +**Config mode** — refactor multiple directories defined in a TOML config file: +```bash +cargo run -- config.toml +./target/debug/php-refactor target/config.toml +``` + +### Config File Format + +Create a `config.toml` file to process multiple directories at once: + +```toml +[source] +paths = ["src", "tests", "app"] +``` + +Paths can be: +- Relative to the project root (where you run the command): `"src"`, `"./app"` +- Absolute: `"/home/user/project/src"` +- Nested: `"src/components/php"` + +The tool will recursively walk each path and apply all rules to every `.php` file found. + +## How Rules Work + +Rules receive a **path** (file, directory, or config file) and are responsible for: +1. Expanding it to actual PHP files (single file, directory walk, config parsing) +2. Reading each file, applying transformations, writing back if changed +3. Returning stats: how many files changed and how many were analyzed + +This design keeps `main.rs` simple — it just passes the input path to each rule in sequence. Each rule is autonomous and can process different subsets of files if needed. + ## How to Find What You Need - **Writing or modifying a rule?** → See `.claude/rules/rule-contract.md` (function contract, return semantics) @@ -34,21 +71,25 @@ cargo run -- path/to/file.php - **Looking at architecture in `src/`?** → `.claude/rules/architecture.md` (loaded automatically when working in src/) - **Understanding test fixtures in `tests/`?** → `.claude/rules/testing-patterns.md` (loaded automatically when working in tests/) - **Need a definition?** → Invoke `/glossary` skill (Rule, Fixture, AST, Span, Bump Arena, Idempotent, mago-syntax) +- **Understanding file discovery?** → See `src/resolver.rs` (handles single files, directories, and TOML config expansion) ## Project Structure ``` src/ - ├── main.rs # CLI entry, rule chaining, file I/O + ├── main.rs # CLI entry: get path, loop rules, report results ├── lib.rs # Module re-exports - ├── reporter.rs # Timing and memory reporting - └── rules/mod.rs # Rule registry (all_rules) + └── rules/ + ├── mod.rs # Rule registry (all_rules, all_source_transforms) + └── quality/ # Quality rules by category + ├── mod.rs + └── add_final_keyword.rs # Example rule (adds final to classes) tests/ - ├── rules_test.rs # Fixture-based integration test runner - └── rules/ # Test fixtures by rule path + ├── *_test.rs # Individual unit tests + ├── rules_test.rs # Rule integration tests (uses source fixtures) + └── fixtures/ # Versioned fixtures for test data -.github/workflows/quality.yml # CI: check, fmt, clippy, test -Cargo.toml / Cargo.lock # Dependencies -justfile # Task automation +Cargo.toml / Cargo.lock # Dependencies +justfile # Task automation ``` diff --git a/Cargo.lock b/Cargo.lock index 8bb4f6f..321f76b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -504,6 +504,9 @@ dependencies = [ "mago-database", "mago-span", "mago-syntax", + "serde", + "toml", + "walkdir", ] [[package]] @@ -764,6 +767,15 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "shlex" version = "1.3.0" @@ -866,6 +878,47 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tracing" version = "0.1.44" @@ -1053,6 +1106,15 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 995e2fb..b002eff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,6 @@ mago-syntax = "1.15.3" mago-span = "1.15.3" mago-database = "1.15.3" bumpalo = "3" +serde = { version = "1", features = ["derive"] } +toml = "0.8" +walkdir = "2" diff --git a/README.md b/README.md index 151e51e..4103b2d 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,14 @@ docker run --rm -v $(pwd):/workspace php-refactor \ ## Usage +The tool accepts a **single argument**: a file path, directory path, or config file path. + +### Single File Mode + +Process one PHP file: + ```bash -php-refactor path/to/file.php +php-refactor MyClass.php ``` **Example:** @@ -54,7 +60,40 @@ final class MyClass { } ``` -The tool modifies the file in-place. If no rules apply, the file is left unchanged. +### Directory Mode + +Recursively process all PHP files in a directory: + +```bash +php-refactor src/ +php-refactor tests/ +``` + +### Config File Mode + +Process multiple directories defined in a TOML config file: + +```bash +php-refactor config.toml +``` + +**config.toml:** + +```toml +[source] +paths = ["src", "tests", "app"] +``` + +Paths can be: +- Relative to the project root: `"src"`, `"./app"` +- Absolute: `"/home/user/project/src"` +- Nested: `"src/components/php"` + +The tool will recursively walk each path and apply all rules to every `.php` file found. + +--- + +The tool modifies files in-place. If no rules apply, files are left unchanged. ### Output diff --git a/docs/rules.md b/docs/rules.md new file mode 100644 index 0000000..97bd998 --- /dev/null +++ b/docs/rules.md @@ -0,0 +1,40 @@ +# PHP Refactor Rules + +Detailed documentation of all available transformation rules. + +--- + +## `quality/add_final_keyword` + +**Summary**: Adds `final` keyword to concrete classes to prevent accidental subclassing. + +**When to use**: Enforce class design intent — mark classes that shouldn't be extended as `final`. + +**What it does:** +- Adds `final` keyword before any non-abstract, non-final class declaration +- Supports classes inside namespaces +- Handles `readonly` classes: produces `final readonly class` +- Returns `None` (no change) if already processed + +**What it skips:** +- Abstract classes (marked `abstract`) +- Classes that already have `final` +- Interfaces and traits (no `final` modifier in PHP) +- Enums (PHP enums cannot be marked `final`) + +**Example:** + +```php +// Before +class Service {} +readonly class Config {} +namespace App; +class Model {} + +// After +final class Service {} +final readonly class Config {} +namespace App; +final class Model {} +``` + diff --git a/justfile b/justfile index 4fd381f..eca07bd 100644 --- a/justfile +++ b/justfile @@ -12,9 +12,10 @@ docker-build: build: docker compose run --rm app cargo build -# Build release binary (optimized) +# Build release binary (optimized, auto-detects OS) build-release: - docker compose run --rm app cargo build --release + cargo build --release + bash scripts/rename-binary.sh # Auto-fix code: format + run tests quality-tools: diff --git a/scripts/rename-binary.sh b/scripts/rename-binary.sh new file mode 100644 index 0000000..521cf33 --- /dev/null +++ b/scripts/rename-binary.sh @@ -0,0 +1,4 @@ +#!/bin/bash +VERSION=$(grep '^version' Cargo.toml | grep -o '"[^"]*"' | head -1 | tr -d '"') +mv target/release/php-refactor target/release/php-refactor-${VERSION} +echo "Binary available at: $(pwd)/target/release/php-refactor-${VERSION}" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..82807f1 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,18 @@ +use serde::Deserialize; +use std::fs; + +#[derive(Deserialize)] +pub struct Config { + pub source: SourceConfig, +} + +#[derive(Deserialize)] +pub struct SourceConfig { + pub paths: Vec, +} + +pub fn load(path: &str) -> Result> { + let contents = fs::read_to_string(path)?; + let config = toml::from_str(&contents)?; + Ok(config) +} diff --git a/src/lib.rs b/src/lib.rs index 5ee7f5c..61b166b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,4 @@ +pub mod config; pub mod reporter; +pub mod resolver; pub mod rules; diff --git a/src/main.rs b/src/main.rs index 3941227..fa58706 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,4 @@ -use php_refactor::reporter; use php_refactor::rules; -use std::fs; use std::process; use std::time::Instant; @@ -10,51 +8,36 @@ fn main() { let path = match std::env::args().nth(1) { Some(p) => p, None => { - let elapsed = total_start.elapsed(); - eprintln!("[ERROR] Something went wrong: Usage: php-refactor "); - reporter::print_timing(&[], elapsed); + eprintln!( + "[ERROR] Something went wrong: Usage: php-refactor " + ); + eprintln!("[INFO] No processing, exiting."); process::exit(1); } }; - let original = match fs::read_to_string(&path) { - Ok(s) => s, - Err(e) => { - let elapsed = total_start.elapsed(); - eprintln!("[ERROR] Something went wrong: {}", e); - reporter::print_timing(&[], elapsed); - process::exit(1); - } - }; - - let mut rule_timings: Vec<(&str, std::time::Duration)> = Vec::new(); - let mut content = original.clone(); - - for (rule_name, rule_fn) in rules::all_rules() { - let rule_start = Instant::now(); - let result = rule_fn(&content); - rule_timings.push((rule_name, rule_start.elapsed())); + let mut total_changed = 0; + let mut total_analyzed = 0; - if let Some(new_content) = result { - content = new_content; - } + for (_, rule_fn) in rules::all_rules() { + let result = rule_fn(&path); + total_changed += result.files_changed; + total_analyzed = result.files_analyzed; } let total_elapsed = total_start.elapsed(); - // Separate "needs update?" step — rule logic stays pure - let needs_update = content != original; - - if needs_update { - if let Err(e) = fs::write(&path, &content) { - eprintln!("[ERROR] Something went wrong: {}", e); - reporter::print_timing(&rule_timings, total_elapsed); - process::exit(1); - } - println!("[OK] 1 file has been changed, 1 file analyzed."); + if total_analyzed == 0 { + println!("[OK] No PHP files found, nothing to do."); } else { - println!("[OK] 1 file analyzed, nothing to do."); + println!( + "[OK] {} file(s) changed, {} file(s) analyzed.", + total_changed, total_analyzed + ); } - reporter::print_timing(&rule_timings, total_elapsed); + eprintln!( + "[INFO] {:.2}ms total duration.", + total_elapsed.as_secs_f64() * 1000.0 + ); } diff --git a/src/resolver.rs b/src/resolver.rs new file mode 100644 index 0000000..bb67c95 --- /dev/null +++ b/src/resolver.rs @@ -0,0 +1,45 @@ +use std::path::{Path, PathBuf}; +use walkdir::WalkDir; + +/// Expand a path argument into a list of PHP files to process. +/// - `.toml` file → load config, walk configured paths +/// - directory → walk and collect .php files +/// - anything else → treat as a single file (return as-is) +pub fn collect_php_files(path: &str) -> Result, Box> { + let p = Path::new(path); + + if path.ends_with(".toml") { + collect_from_config(path) + } else if p.is_dir() { + Ok(collect_from_directory(path)) + } else { + // Single file: return as-is if .php, empty if not + if path.ends_with(".php") { + Ok(vec![p.to_path_buf()]) + } else { + Ok(vec![]) + } + } +} + +/// Load a TOML config and collect all .php files from configured paths. +fn collect_from_config(config_path: &str) -> Result, Box> { + let cfg = crate::config::load(config_path)?; + let mut files = Vec::new(); + + for path in &cfg.source.paths { + files.extend(collect_from_directory(path)); + } + + Ok(files) +} + +/// Walk a directory recursively and collect all .php files. +fn collect_from_directory(dir_path: &str) -> Vec { + WalkDir::new(dir_path) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.path().extension().and_then(|s| s.to_str()) == Some("php")) + .map(|e| e.path().to_path_buf()) + .collect() +} diff --git a/src/rules/mod.rs b/src/rules/mod.rs index 7275e31..97ee597 100644 --- a/src/rules/mod.rs +++ b/src/rules/mod.rs @@ -1,10 +1,30 @@ pub mod quality; -pub type RuleFn = fn(&str) -> Option; +/// Result of applying a rule to a path. +#[derive(Debug, Clone, Copy)] +pub struct RuleResult { + pub files_changed: usize, + pub files_analyzed: usize, +} + +/// File-aware rule: takes a path (file, config, or directory) and returns stats. +pub type RuleFn = fn(&str) -> RuleResult; +/// Pure source transformation: takes source code, returns modified source or None. +pub type SourceTransformFn = fn(&str) -> Option; + +/// Rules registered for execution via main.rs pub fn all_rules() -> Vec<(&'static str, RuleFn)> { vec![( "quality/add_final_keyword", quality::add_final_keyword::apply, )] } + +/// Pure source transforms used by tests +pub fn all_source_transforms() -> Vec<(&'static str, SourceTransformFn)> { + vec![( + "quality/add_final_keyword", + quality::add_final_keyword::apply_to_source, + )] +} diff --git a/src/rules/quality/add_final_keyword.rs b/src/rules/quality/add_final_keyword.rs index 99e0995..c495d73 100644 --- a/src/rules/quality/add_final_keyword.rs +++ b/src/rules/quality/add_final_keyword.rs @@ -2,8 +2,41 @@ use bumpalo::Bump; use mago_database::file::FileId; use mago_syntax::ast::{Modifier, Sequence, Statement}; use mago_syntax::parser::parse_file_content; +use std::fs; -pub fn apply(source: &str) -> Option { +/// File-aware entry point: takes a path and returns stats. +pub fn apply(path: &str) -> crate::rules::RuleResult { + let files = match crate::resolver::collect_php_files(path) { + Ok(f) => f, + Err(_) => { + return crate::rules::RuleResult { + files_changed: 0, + files_analyzed: 0, + }; + } + }; + + let mut files_changed = 0; + let total_analyzed = files.len(); + + for file_path in files { + let Ok(original) = fs::read_to_string(&file_path) else { + continue; + }; + + if let Some(modified) = apply_to_source(&original) { + files_changed += usize::from(fs::write(&file_path, &modified).is_ok()); + } + } + + crate::rules::RuleResult { + files_changed, + files_analyzed: total_analyzed, + } +} + +/// Pure source transformation: used by tests. +pub fn apply_to_source(source: &str) -> Option { let arena = Bump::new(); let file_id = FileId::zero(); let program = parse_file_content(&arena, file_id, source); diff --git a/tests/config_test.rs b/tests/config_test.rs new file mode 100644 index 0000000..d87c64f --- /dev/null +++ b/tests/config_test.rs @@ -0,0 +1,74 @@ +fn fixture(name: &str) -> String { + format!("tests/fixtures/config/{}", name) +} + +#[test] +fn test_load_valid_config_single_path() { + let config = php_refactor::config::load(&fixture("valid_single_path.toml")).unwrap(); + assert_eq!(config.source.paths.len(), 1); + assert_eq!(config.source.paths[0], "src"); +} + +#[test] +fn test_load_valid_config_multiple_paths() { + let config = php_refactor::config::load(&fixture("valid_multiple_paths.toml")).unwrap(); + assert_eq!(config.source.paths.len(), 3); + assert_eq!(config.source.paths[0], "src"); + assert_eq!(config.source.paths[1], "tests"); + assert_eq!(config.source.paths[2], "app"); +} + +#[test] +fn test_load_valid_config_absolute_paths() { + let config = php_refactor::config::load(&fixture("valid_absolute_paths.toml")).unwrap(); + assert_eq!(config.source.paths.len(), 2); + assert_eq!(config.source.paths[0], "/home/user/src"); + assert_eq!(config.source.paths[1], "/var/app/tests"); +} + +#[test] +fn test_load_valid_config_empty_paths() { + let config = php_refactor::config::load(&fixture("valid_empty_paths.toml")).unwrap(); + assert_eq!(config.source.paths.len(), 0); +} + +#[test] +fn test_load_nonexistent_file() { + let result = php_refactor::config::load("/nonexistent/path/config.toml"); + assert!(result.is_err()); +} + +#[test] +fn test_load_invalid_toml_syntax() { + let result = php_refactor::config::load(&fixture("invalid_syntax.toml")); + assert!(result.is_err()); +} + +#[test] +fn test_load_missing_source_section() { + let result = php_refactor::config::load(&fixture("missing_source_section.toml")); + assert!(result.is_err()); +} + +#[test] +fn test_load_missing_paths_field() { + let result = php_refactor::config::load(&fixture("missing_paths_field.toml")); + assert!(result.is_err()); +} + +#[test] +fn test_load_config_with_special_characters_in_paths() { + let config = php_refactor::config::load(&fixture("special_characters.toml")).unwrap(); + assert_eq!(config.source.paths.len(), 3); + assert_eq!(config.source.paths[0], "src/php-app"); + assert_eq!(config.source.paths[1], "./tests/unit"); + assert_eq!(config.source.paths[2], "../shared"); +} + +#[test] +fn test_load_config_with_extra_whitespace() { + let config = php_refactor::config::load(&fixture("extra_whitespace.toml")).unwrap(); + assert_eq!(config.source.paths.len(), 2); + assert_eq!(config.source.paths[0], "src"); + assert_eq!(config.source.paths[1], "tests"); +} diff --git a/tests/fixtures/config/extra_whitespace.toml b/tests/fixtures/config/extra_whitespace.toml new file mode 100644 index 0000000..7adeab7 --- /dev/null +++ b/tests/fixtures/config/extra_whitespace.toml @@ -0,0 +1,2 @@ +[source] +paths = [ "src" , "tests" ] diff --git a/tests/fixtures/config/invalid_syntax.toml b/tests/fixtures/config/invalid_syntax.toml new file mode 100644 index 0000000..8b994cc --- /dev/null +++ b/tests/fixtures/config/invalid_syntax.toml @@ -0,0 +1,2 @@ +[source +paths = ["src"] diff --git a/tests/fixtures/config/missing_paths_field.toml b/tests/fixtures/config/missing_paths_field.toml new file mode 100644 index 0000000..ffd29c3 --- /dev/null +++ b/tests/fixtures/config/missing_paths_field.toml @@ -0,0 +1,2 @@ +[source] +other_field = [] diff --git a/tests/fixtures/config/missing_source_section.toml b/tests/fixtures/config/missing_source_section.toml new file mode 100644 index 0000000..1bca015 --- /dev/null +++ b/tests/fixtures/config/missing_source_section.toml @@ -0,0 +1 @@ +other_section = [] diff --git a/tests/fixtures/config/special_characters.toml b/tests/fixtures/config/special_characters.toml new file mode 100644 index 0000000..cfb7de0 --- /dev/null +++ b/tests/fixtures/config/special_characters.toml @@ -0,0 +1,2 @@ +[source] +paths = ["src/php-app", "./tests/unit", "../shared"] diff --git a/tests/fixtures/config/valid_absolute_paths.toml b/tests/fixtures/config/valid_absolute_paths.toml new file mode 100644 index 0000000..7f344d0 --- /dev/null +++ b/tests/fixtures/config/valid_absolute_paths.toml @@ -0,0 +1,2 @@ +[source] +paths = ["/home/user/src", "/var/app/tests"] diff --git a/tests/fixtures/config/valid_empty_paths.toml b/tests/fixtures/config/valid_empty_paths.toml new file mode 100644 index 0000000..ca94965 --- /dev/null +++ b/tests/fixtures/config/valid_empty_paths.toml @@ -0,0 +1,2 @@ +[source] +paths = [] diff --git a/tests/fixtures/config/valid_multiple_paths.toml b/tests/fixtures/config/valid_multiple_paths.toml new file mode 100644 index 0000000..329db46 --- /dev/null +++ b/tests/fixtures/config/valid_multiple_paths.toml @@ -0,0 +1,2 @@ +[source] +paths = ["src", "tests", "app"] diff --git a/tests/fixtures/config/valid_single_path.toml b/tests/fixtures/config/valid_single_path.toml new file mode 100644 index 0000000..0cf85c9 --- /dev/null +++ b/tests/fixtures/config/valid_single_path.toml @@ -0,0 +1,2 @@ +[source] +paths = ["src"] diff --git a/tests/fixtures/resolver/config/config.toml b/tests/fixtures/resolver/config/config.toml new file mode 100644 index 0000000..ba991e6 --- /dev/null +++ b/tests/fixtures/resolver/config/config.toml @@ -0,0 +1,2 @@ +[source] +paths = ["tests/fixtures/resolver/config/src", "tests/fixtures/resolver/config/tests"] diff --git a/tests/fixtures/resolver/config/src/app.php b/tests/fixtures/resolver/config/src/app.php new file mode 100644 index 0000000..29fe1c5 --- /dev/null +++ b/tests/fixtures/resolver/config/src/app.php @@ -0,0 +1,3 @@ + String { + format!("tests/fixtures/resolver/{}", name) +} + +#[test] +fn test_single_php_file() { + let result = php_refactor::resolver::collect_php_files(&fixture("single.php")).unwrap(); + assert_eq!(result.len(), 1); + assert!(result[0].ends_with("single.php")); +} + +#[test] +fn test_single_non_php_file() { + let result = php_refactor::resolver::collect_php_files(&fixture("single.txt")).unwrap(); + assert_eq!(result.len(), 0); +} + +#[test] +fn test_directory_with_php_files() { + let result = php_refactor::resolver::collect_php_files(&fixture("dir_with_php")).unwrap(); + assert_eq!(result.len(), 2); +} + +#[test] +fn test_directory_with_nested_php_files() { + let result = php_refactor::resolver::collect_php_files(&fixture("nested")).unwrap(); + assert_eq!(result.len(), 2); + assert!(result.iter().any(|p| p.ends_with("root.php"))); + assert!(result.iter().any(|p| p.ends_with("nested.php"))); +} + +#[test] +fn test_empty_directory() { + let result = php_refactor::resolver::collect_php_files(&fixture("empty_dir")).unwrap(); + assert_eq!(result.len(), 0); +} + +#[test] +fn test_directory_with_only_non_php_files() { + let result = php_refactor::resolver::collect_php_files(&fixture("only_non_php")).unwrap(); + assert_eq!(result.len(), 0); +} + +#[test] +fn test_nonexistent_php_file() { + let result = php_refactor::resolver::collect_php_files("/nonexistent/path/file.php").unwrap(); + assert_eq!(result.len(), 1); +} + +#[test] +fn test_config_file() { + let result = php_refactor::resolver::collect_php_files(&fixture("config/config.toml")).unwrap(); + assert_eq!(result.len(), 2); +} diff --git a/tests/rules_test.rs b/tests/rules_test.rs index 2095c5b..a8007ee 100644 --- a/tests/rules_test.rs +++ b/tests/rules_test.rs @@ -5,7 +5,7 @@ const SEPARATOR: &str = "\n-----\n"; #[test] fn test_all_rules() { - let rules = php_refactor::rules::all_rules(); + let rules = php_refactor::rules::all_source_transforms(); for (rule_path, rule_fn) in rules { let fixture_dir = format!("tests/rules/{}", rule_path);