Class: RubyMaat::Analysis::LogicalCoupling
- Inherits:
-
BaseAnalysis
- Object
- BaseAnalysis
- RubyMaat::Analysis::LogicalCoupling
- Defined in:
- lib/ruby_maat/analysis/logical_coupling.rb
Overview
Logical coupling analysis - finds modules that tend to change together This identifies hidden dependencies between code modules
Instance Method Summary collapse
Instance Method Details
#analyze(dataset, options = {}) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/ruby_maat/analysis/logical_coupling.rb', line 8 def analyze(dataset, = {}) min_revs = [:min_revs] || 1 min_shared_revs = [:min_shared_revs] || 1 min_coupling = [:min_coupling] || 1 max_coupling = [:max_coupling] || 100 max_changeset_size = [:max_changeset_size] || 30 verbose_results = [:verbose_results] || false # Get co-changing entities by revision co_changing_entities = get_co_changing_entities(dataset, max_changeset_size) # Calculate coupling frequencies coupling_frequencies = calculate_coupling_frequencies(co_changing_entities) # Calculate revision counts per entity entity_revisions = calculate_entity_revisions(dataset) # Generate coupling results results = [] coupling_frequencies.each do |(entity1, entity2), shared_revs| entity1_revs = entity_revisions[entity1] || 0 entity2_revs = entity_revisions[entity2] || 0 avg_revs = average(entity1_revs, entity2_revs) coupling_degree = percentage(shared_revs, avg_revs) # Apply thresholds next unless avg_revs >= min_revs next unless shared_revs >= min_shared_revs next unless coupling_degree >= min_coupling next unless coupling_degree <= max_coupling result = { entity: entity1, coupled: entity2, degree: coupling_degree, "average-revs": avg_revs.ceil } if verbose_results result.merge!( "first-entity-revisions": entity1_revs, "second-entity-revisions": entity2_revs, "shared-revisions": shared_revs ) end results << result end # Sort by coupling degree (descending), then by average revisions (descending) results.sort! do |a, b| comparison = b[:degree] <=> a[:degree] comparison.zero? ? b[:"average-revs"] <=> a[:"average-revs"] : comparison end columns = [:entity, :coupled, :degree, :"average-revs"] columns += [:"first-entity-revisions", :"second-entity-revisions", :"shared-revisions"] if verbose_results to_csv_data(results, columns) end |