Class: Canon::Diff::DiffReport

Inherits:
Object
  • Object
show all
Defined in:
lib/canon/diff/diff_report.rb

Overview

Represents a complete diff report containing multiple contexts

A DiffReport is the top-level container for diff results between two documents. It contains multiple DiffContext objects, each representing a region with changes and surrounding context lines.

Examples:

Creating a diff report

report = DiffReport.new(
  element_name: "root",
  file1_name: "expected.xml",
  file2_name: "actual.xml"
)
report.add_context(context1)
report.add_context(context2)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(element_name:, file1_name: nil, file2_name: nil, contexts: []) ⇒ DiffReport

Initialize a new diff report

Parameters:

  • element_name (String)

    name of the root element being compared

  • file1_name (String, nil) (defaults to: nil)

    name/path of the first file

  • file2_name (String, nil) (defaults to: nil)

    name/path of the second file

  • contexts (Array<DiffContext>) (defaults to: [])

    initial array of contexts



33
34
35
36
37
38
39
# File 'lib/canon/diff/diff_report.rb', line 33

def initialize(element_name:, file1_name: nil, file2_name: nil,
               contexts: [])
  @element_name = element_name
  @file1_name = file1_name
  @file2_name = file2_name
  @contexts = contexts
end

Instance Attribute Details

#contextsArray<DiffContext> (readonly)

array of diff contexts

Returns:

  • (Array<DiffContext>)

    the current value of contexts



24
25
26
# File 'lib/canon/diff/diff_report.rb', line 24

def contexts
  @contexts
end

#element_nameString (readonly)

name of the root element being compared

Returns:

  • (String)

    the current value of element_name



24
25
26
# File 'lib/canon/diff/diff_report.rb', line 24

def element_name
  @element_name
end

#file1_nameString (readonly)

name/path of the first file

Returns:

  • (String)

    the current value of file1_name



24
25
26
# File 'lib/canon/diff/diff_report.rb', line 24

def file1_name
  @file1_name
end

#file2_nameString (readonly)

name/path of the second file

Returns:

  • (String)

    the current value of file2_name



24
25
26
# File 'lib/canon/diff/diff_report.rb', line 24

def file2_name
  @file2_name
end

Instance Method Details

#==(other) ⇒ Boolean

Compare equality with another report

Parameters:

  • other (DiffReport)

    the report to compare with

Returns:

  • (Boolean)

    true if reports are equal



124
125
126
127
128
129
130
# File 'lib/canon/diff/diff_report.rb', line 124

def ==(other)
  other.is_a?(DiffReport) &&
    element_name == other.element_name &&
    file1_name == other.file1_name &&
    file2_name == other.file2_name &&
    contexts == other.contexts
end

#add_context(context) ⇒ self

Add a context to the report

Parameters:

Returns:

  • (self)

    returns self for method chaining



45
46
47
48
# File 'lib/canon/diff/diff_report.rb', line 45

def add_context(context)
  @contexts << context
  self
end

#block_countInteger

Get the total number of diff blocks across all contexts

Returns:

  • (Integer)

    total number of blocks



60
61
62
# File 'lib/canon/diff/diff_report.rb', line 60

def block_count
  contexts.sum(&:block_count)
end

#change_countInteger

Get the total number of changes (sum of all block sizes)

Returns:

  • (Integer)

    total number of changed lines



67
68
69
70
71
# File 'lib/canon/diff/diff_report.rb', line 67

def change_count
  contexts.sum do |context|
    context.blocks.sum(&:size)
  end
end

#context_countInteger

Get the total number of contexts in the report

Returns:

  • (Integer)

    number of contexts



53
54
55
# File 'lib/canon/diff/diff_report.rb', line 53

def context_count
  contexts.length
end

#contexts_with_type(type) ⇒ Array<DiffContext>

Filter contexts by change type

Parameters:

  • type (String)

    the change type to filter by (‘+’, ‘-’, ‘!’)

Returns:

  • (Array<DiffContext>)

    contexts that include the given type



92
93
94
# File 'lib/canon/diff/diff_report.rb', line 92

def contexts_with_type(type)
  contexts.select { |context| context.includes_type?(type) }
end

#has_differences?Boolean

Check if the report has any differences

Returns:

  • (Boolean)

    true if there are any contexts with differences



76
77
78
# File 'lib/canon/diff/diff_report.rb', line 76

def has_differences?
  !contexts.empty?
end

#includes_type?(type) ⇒ Boolean

Check if the report contains a specific change type

Parameters:

  • type (String)

    the change type to check for (‘+’, ‘-’, ‘!’)

Returns:

  • (Boolean)

    true if any context includes this type



84
85
86
# File 'lib/canon/diff/diff_report.rb', line 84

def includes_type?(type)
  contexts.any? { |context| context.includes_type?(type) }
end

#summaryHash

Get summary statistics about the diff

Returns:

  • (Hash)

    hash with keys: :contexts, :blocks, :changes



99
100
101
102
103
104
105
# File 'lib/canon/diff/diff_report.rb', line 99

def summary
  {
    contexts: context_count,
    blocks: block_count,
    changes: change_count,
  }
end

#to_hHash

Convert to hash representation

Returns:

  • (Hash)

    hash representation of the report



110
111
112
113
114
115
116
117
118
# File 'lib/canon/diff/diff_report.rb', line 110

def to_h
  {
    element_name: element_name,
    file1_name: file1_name,
    file2_name: file2_name,
    contexts: contexts.map(&:to_h),
    summary: summary,
  }
end