Class: SixthSense::Analyzers::RedundancyClone

Inherits:
SixthSense::Analyzer show all
Defined in:
lib/sixth_sense/analyzers/redundancy_clone.rb

Instance Method Summary collapse

Methods inherited from SixthSense::Analyzer

analyzer_id, axis, inherited, level, reference, references

Instance Method Details

#analyze(test_file, _context) ⇒ Object

Paper basis: Roy/Cordy 2007 surveys Type-1/2 clone detection; this groups normalized test bodies as a low-confidence clone signal.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/sixth_sense/analyzers/redundancy_clone.rb', line 19

def analyze(test_file, _context)
  groups = test_file.test_cases.group_by { |test_case| normalize_body(test_case.body) }
  clone_groups = groups.reject { |normalized, cases| normalized.empty? || cases.length < 2 }
  duplicate_count = clone_groups.values.sum { |cases| cases.length - 1 }
  score = 100.0 * (1.0 - duplicate_count.to_f / [test_file.test_cases.length, 1].max)
  findings = clone_groups.values.flat_map do |cases|
    cases.drop(1).map do |test_case|
      finding(
        rule_id: "test_clone",
        severity: :info,
        location: test_case.location,
        message: "Example body is a Type-1/2 clone of another example in this file.",
        suggestion: "Extract setup or merge examples only if the behavioral intent is identical."
      )
    end
  end

  result(score: score.round(2), findings: findings, confidence: :low)
end