Refactor context tuple into a dedicated Context struct

This commit is contained in:
Sijawusz Pur Rahnama 2021-01-03 17:04:34 +01:00
parent e3ee3a494d
commit 0300476813
3 changed files with 80 additions and 30 deletions

View file

@ -0,0 +1,33 @@
require "../../../spec_helper"
describe Backtracer::Backtrace::Frame::Context do
describe ".to_h" do
it "works with empty #pre and #post" do
context = Backtracer::Backtrace::Frame::Context.new(
lineno: 1,
pre: %w[],
line: "violent offender!",
post: %w[],
)
context.to_h.should eq({1 => "violent offender!"})
end
it "returns hash with #pre, #line and #post strings" do
context = Backtracer::Backtrace::Frame::Context.new(
lineno: 10,
pre: %w[foo bar baz],
line: "violent offender!",
post: %w[boo far faz],
)
context.to_h.should eq({
7 => "foo",
8 => "bar",
9 => "baz",
10 => "violent offender!",
11 => "boo",
12 => "far",
13 => "faz",
})
end
end
end

View file

@ -96,15 +96,18 @@ module Backtracer
!!(relative_path.try(&.matches?(configuration.app_dirs_pattern))) !!(relative_path.try(&.matches?(configuration.app_dirs_pattern)))
end end
# Returns a tuple consisting of 3 elements - an array of context lines # Returns `Context` record consisting of 3 elements - an array of context lines
# before the `lineno`, line at `lineno`, and an array of context lines # before the `lineno`, line at `lineno`, and an array of context lines
# after the `lineno`. In case of failure it returns `nil`. # after the `lineno`. In case of failure it returns `nil`.
# #
# Amount of returned context lines is taken from the *context_lines* # Amount of returned context lines is taken from the *context_lines*
# argument if given, or `configuration.context_lines` otherwise. # argument if given, or `configuration.context_lines` otherwise.
# #
# NOTE: amount of returned context lines might be lower than given
# in cases where `lineno` is near the start or the end of the file.
#
# See `Configuration#context_lines` # See `Configuration#context_lines`
def context(context_lines : Int32? = nil) : {Array(String), String, Array(String)}? def context(context_lines : Int32? = nil) : Context?
context_lines ||= configuration.context_lines context_lines ||= configuration.context_lines
return unless context_lines && (context_lines > 0) return unless context_lines && (context_lines > 0)
@ -117,35 +120,13 @@ module Backtracer
if context_line = lines[lineidx]? if context_line = lines[lineidx]?
pre_context = lines[Math.max(0, lineidx - context_lines), context_lines] pre_context = lines[Math.max(0, lineidx - context_lines), context_lines]
post_context = lines[Math.min(lines.size, lineidx + 1), context_lines] post_context = lines[Math.min(lines.size, lineidx + 1), context_lines]
{pre_context, context_line, post_context}
end
end
# Returns hash with context lines, where line numbers are keys and Context.new(
# the lines itself are values. In case of failure it returns `nil`. lineno: lineno,
# pre: pre_context,
# Amount of returned context lines is taken from the *context_lines* line: context_line,
# argument if given, or `configuration.context_lines` otherwise. post: post_context,
# )
# See `Configuration#context`, `Configuration#context_lines`
def context_hash(context_lines : Int32? = nil) : Hash(Int32, String)?
return unless context = self.context(context_lines)
return unless lineno = @lineno
pre_context, context_line, post_context = context
({} of Int32 => String).tap do |hash|
pre_context.each_with_index do |code, index|
line = (lineno - pre_context.size) + index
hash[line] = code
end
hash[lineno] = context_line
post_context.each_with_index do |code, index|
line = lineno + (index + 1)
hash[line] = code
end
end end
end end
end end

View file

@ -0,0 +1,36 @@
module Backtracer
struct Backtrace::Frame::Context
# The line number this `Context` refers to.
getter lineno : Int32
# An array of lines before `lineno`.
getter pre : Array(String)
# The line at `lineno`.
getter line : String
# An array of lines after `lineno`.
getter post : Array(String)
def initialize(@lineno, @pre, @line, @post)
end
# Returns hash with context lines, where line numbers are
# the keys and the lines itself are the values.
def to_h : Hash(Int32, String)
({} of Int32 => String).tap do |hash|
base_index = lineno - pre.size
pre.each_with_index do |code, index|
hash[base_index + index] = code
end
hash[lineno] = line
base_index = lineno + 1
post.each_with_index do |code, index|
hash[base_index + index] = code
end
end
end
end
end