defmodule PropWise do @moduledoc """ PropWise - AST-based analyzer for identifying property-based testing candidates. PropWise analyzes Elixir codebases to find functions that would benefit from property-based testing. It uses AST analysis to: - Detect pure functions (no side effects) - Identify common patterns (collections, transformations, validation, etc.) - Find inverse function pairs (encode/decode, serialize/deserialize, etc.) - Score and rank candidates by testability - Provide specific testing suggestions ## Usage As a library: result = PropWise.analyze("./my_project") PropWise.print_report(result) As a command-line tool: $ mix escript.build $ ./propwise ./my_project $ ./propwise --min-score 5 --format json ./my_project ## Configuration You can customize the minimum score threshold: PropWise.analyze("./my_project", min_score: 5) The default minimum score is 4. Output formats: `:text` (default) or `:json` PropWise.print_report(result, format: :json) """ alias PropWise.{Analyzer, Reporter} @doc """ Analyzes an Elixir project for property-based testing candidates. ## Parameters - `path` - Path to the Elixir project directory - `opts` - Keyword list of options: - `:min_score` - Minimum score for candidates (default: 4) ## Returns A map containing: - `:candidates` - List of `PropWise.Candidate` structs with scores - `:inverse_pairs` - Detected inverse function pairs - `:total_functions` - Total number of functions analyzed - `:candidates_count` - Number of candidates above the score threshold - `:dropped_count` - Number of candidates that scored > 0 but below the threshold ## Examples result = PropWise.analyze(".") result = PropWise.analyze("./lib", min_score: 5) """ @spec analyze(String.t(), keyword()) :: PropWise.Analyzer.analysis_result() def analyze(path, opts \\ []) do Analyzer.analyze_project(path, opts) end @doc """ Prints the analysis report. ## Parameters - `analysis_result` - Result from `analyze/2` - `opts` - Keyword list of options: - `:format` - Output format: `:text` or `:json` (default: `:text`) ## Examples result = PropWise.analyze(".") PropWise.print_report(result) PropWise.print_report(result, format: :json) """ @spec print_report(PropWise.Analyzer.analysis_result(), keyword()) :: :ok def print_report(analysis_result, opts \\ []) do Reporter.print_report(analysis_result, opts) end end