class VirtualFile
Attributes
business_value[R]
commits[R]
file_id[R]
issues[R]
lines[R]
path[R]
Public Class Methods
from_json(file_id, json)
click to toggle source
# File lib/virtual_file.rb, line 32 def self.from_json(file_id, json) file = VirtualFile.new(json["path"]) touched_at_times = (json["touched_at_times"] || []).map { |time| DateTime.rfc3339(time) } lines = (json["lines"] || []).map { |line| line.deep_symbolize_keys } functions = (json["functions"] || []).map { |function| function.deep_symbolize_keys } file.instance_variable_set(:@file_id, file_id) file.instance_variable_set(:@previous_file_id, json["previous_file_id"]) file.instance_variable_set(:@touched_at_times, touched_at_times) file.instance_variable_set(:@lines, lines) file.instance_variable_set(:@functions, functions) file.instance_variable_set(:@commits, json["commits"] || []) file.instance_variable_set(:@issues, json["issues"] || []) file.instance_variable_set(:@bugs, json["bugs"] || []) file.instance_variable_set(:@business_value, json["business_value"] || 0) file.instance_variable_set(:@is_binary, false) file end
new(file_path, diff=nil)
click to toggle source
# File lib/virtual_file.rb, line 18 def initialize(file_path, diff=nil) @path = file_path @file_id = nil @previous_file_id = nil @touched_at_times = [] @commits = [] @issues = [] @bugs = [] @lines = [] @functions = [] @business_value = 0 @is_binary = diff.blank? ? false : diff.operation == :binary end
Public Instance Methods
apply_file_diff!(commit, file_diff)
click to toggle source
# File lib/virtual_file.rb, line 71 def apply_file_diff!(commit, file_diff) touch(commit, file_diff) return if binary? context = file_diff.diffs .reduce(new_context(commit), &method(:apply_diff)) new_lines = context[:new_lines] unchanged_lines = @lines[context[:position]..-1] new_lines.concat(unchanged_lines) if unchanged_lines @lines = new_lines end
as_json()
click to toggle source
# File lib/virtual_file.rb, line 127 def as_json() { path: @path, previous_file_id: @previous_file_id, lines: @lines, functions: @functions.map { |function| function.as_json() }, commits: @commits, issues: @issues, business_value: @business_value, bugs: @bugs } end
binary?()
click to toggle source
# File lib/virtual_file.rb, line 86 def binary? @is_binary end
buggy_lines_total()
click to toggle source
# File lib/virtual_file.rb, line 155 def buggy_lines_total() @lines .map do |line| line[:revisions].flat_map { |revision| revision[:bugs] }.count + line[:bugs].count end .reduce(0, &:+) end
change_line!(line_change, line_number)
click to toggle source
# File lib/virtual_file.rb, line 102 def change_line!(line_change, line_number) @lines[line_number] = Line::change!(line_change, @lines[line_number]) end
covered_lines()
click to toggle source
# File lib/virtual_file.rb, line 164 def covered_lines @lines .select { |line| line[:coverage] != nil && line[:coverage] > 0 } .count end
created_at()
click to toggle source
# File lib/virtual_file.rb, line 94 def created_at @touched_at_times.first end
errors_total()
click to toggle source
# File lib/virtual_file.rb, line 146 def errors_total() @lines .map do |line| line[:revisions].flat_map { |revision| revision[:errors] }.count + line[:errors].count end .reduce(0, &:+) end
last_updated_at()
click to toggle source
# File lib/virtual_file.rb, line 98 def last_updated_at @touched_at_times.last end
merge_coverage!(file_coverage)
click to toggle source
# File lib/virtual_file.rb, line 116 def merge_coverage!(file_coverage) @lines.each_with_index do |line, index| line[:coverage] = file_coverage.dig("lines", (index + 1).to_s, "hits") end end
merge_error!(error, trace, depth)
click to toggle source
# File lib/virtual_file.rb, line 122 def merge_error!(error, trace, depth) line = @lines[trace[:line] - 1] Line::merge_error!(line, error, depth) end
move_line!(line_movement, line_number)
click to toggle source
# File lib/virtual_file.rb, line 106 def move_line!(line_movement, line_number) line = @lines[line_number] if line_movement[:text].strip() != line[:text].strip() # TODO: raise reconstruction error. Loggr.instance.warn("MISMATCH: #{line[:text]} VS #{line_movement[:text]}") else @lines[line_number] = Line::move!(line_movement, line) end end
plain_text()
click to toggle source
# File lib/virtual_file.rb, line 90 def plain_text @lines.map { |line| line[:text] } end
revisions_total()
click to toggle source
# File lib/virtual_file.rb, line 140 def revisions_total() @lines .map { |line| line[:revisions].count } .reduce(0, &:+) end
save()
click to toggle source
# File lib/virtual_file.rb, line 62 def save() @functions = Tracer .new .trace(@path, as_text()) .map { |function| VirtualFunction.new(function, @path, @lines) } Cache::write_object(@file_id, as_json()) end
touch(commit, file_diff)
click to toggle source
# File lib/virtual_file.rb, line 51 def touch(commit, file_diff) @path = file_diff.b_file_name @file_id = file_diff.b_file_id if not file_diff.b_file_id.nil? @previous_file_id = file_diff.a_file_id @touched_at_times << commit.date @commits << commit.id @issues << commit.issue_id if commit.issue_id.present? @bugs << commit.bug_id if commit.bug_id.present? @business_value += diff_business_value(commit, file_diff) end
uncovered_lines()
click to toggle source
# File lib/virtual_file.rb, line 170 def uncovered_lines @lines .select { |line| line[:coverage] == 0 } .count end
Private Instance Methods
apply_diff(acc, diff)
click to toggle source
# File lib/virtual_file.rb, line 184 def apply_diff(acc, diff) delete_start = diff.delete_start delete_count = diff.delete_count copy_end = delete_count == 0 ? delete_start : delete_start - 1 new_lines = diff.insertions .each_with_index .map do |line, index| line_num = diff.insert_start + index Line::new_line(line, @path, line_num, acc[:commit]) end unchanged_lines = acc[:existing_lines][acc[:position]...copy_end] acc[:new_lines].concat(unchanged_lines) if unchanged_lines acc[:position] = copy_end + delete_count acc[:new_lines].concat(new_lines) acc end
as_text()
click to toggle source
# File lib/virtual_file.rb, line 178 def as_text() @lines .map { |line| line[:text] } .join("\n") end
diff_business_value(commit, file_diff)
click to toggle source
# File lib/virtual_file.rb, line 206 def diff_business_value(commit, file_diff) (file_diff.changes_total / commit.changes_total.to_f) * commit.business_value end
new_context(commit)
click to toggle source
# File lib/virtual_file.rb, line 210 def new_context(commit) { position: 0, new_lines: [], existing_lines: @lines, commit: commit } end