Extend specs coverage

This commit is contained in:
Sijawusz Pur Rahnama 2021-01-01 16:12:57 +01:00
parent c41fcb5d28
commit 57f5746d6e
6 changed files with 287 additions and 218 deletions

View file

@ -0,0 +1,202 @@
require "../../../spec_helper"
describe Backtracer::Backtrace::Frame::Parser do
describe ".parse" do
it "fails to parse an empty string" do
expect_raises(ArgumentError) { with_frame("", &.itself) }
end
context "when --no-debug flag is set" do
it "parses frame with any value as method" do
backtrace_line = "__crystal_main"
with_frame(backtrace_line) do |frame|
frame.lineno.should be_nil
frame.column.should be_nil
frame.method.should eq(backtrace_line)
frame.path.should be_nil
frame.relative_path.should be_nil
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
end
context "with ~proc signature" do
it "parses absolute path outside of src/ dir" do
path = "/usr/local/Cellar/crystal/0.27.2/src/fiber.cr"
backtrace_line = "~proc2Proc(Fiber, (IO::FileDescriptor | Nil))@#{path}:72"
with_frame(backtrace_line) do |frame|
frame.lineno.should eq(72)
frame.column.should be_nil
frame.method.should eq("~proc2Proc(Fiber, (IO::FileDescriptor | Nil))")
frame.path.should eq(path)
frame.absolute_path.should eq(frame.path)
frame.relative_path.should be_nil
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
it "parses relative path inside of lib/ dir" do
with_configuration do |configuration|
path = "lib/kemal/src/kemal/route.cr"
backtrace_line = "~procProc(HTTP::Server::Context, String)@#{path}:11"
with_frame(backtrace_line) do |frame|
frame.lineno.should eq(11)
frame.column.should be_nil
frame.method.should eq("~procProc(HTTP::Server::Context, String)")
frame.path.should eq(path)
frame.absolute_path.should eq(
File.join(configuration.src_path.not_nil!, path)
)
frame.relative_path.should eq(frame.path)
frame.under_src_path?.should be_false
frame.shard_name.should eq("kemal")
frame.in_app?.should be_false
end
end
end
end
it "parses absolute path outside of configuration.src_path" do
path = "/some/absolute/path/to/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.absolute_path.should eq(frame.path)
frame.relative_path.should be_nil
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
context "with in_app? = false" do
it "parses absolute path outside of src/ dir" do
with_foo_frame(path: "#{__DIR__}/foo.cr") do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq("#{__DIR__}/foo.cr")
frame.absolute_path.should eq(frame.path)
frame.relative_path.should eq("spec/backtracer/backtrace/frame/foo.cr")
frame.under_src_path?.should be_true
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
it "parses relative path outside of src/ dir" do
with_configuration do |configuration|
path = "some/relative/path/to/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.absolute_path.should eq(
File.join(configuration.src_path.not_nil!, path)
)
frame.relative_path.should eq(frame.path)
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
end
end
context "with in_app? = true" do
it "parses absolute path inside of src/ dir" do
src_path = File.expand_path("../../../../src", __DIR__)
path = "#{src_path}/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.absolute_path.should eq(frame.path)
frame.relative_path.should eq("src/foo.cr")
frame.under_src_path?.should be_true
frame.shard_name.should be_nil
frame.in_app?.should be_true
end
end
it "parses relative path inside of src/ dir" do
with_configuration do |configuration|
path = "src/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.absolute_path.should eq(
File.join(configuration.src_path.not_nil!, path)
)
frame.relative_path.should eq(path)
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_true
end
end
end
end
context "with shard path" do
it "parses absolute path inside of lib/ dir" do
lib_path = File.expand_path("../../../../lib/bar", __DIR__)
path = "#{lib_path}/src/bar.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.absolute_path.should eq(frame.path)
frame.relative_path.should eq("lib/bar/src/bar.cr")
frame.under_src_path?.should be_true
frame.shard_name.should eq "bar"
frame.in_app?.should be_false
end
end
it "parses relative path inside of lib/ dir" do
with_configuration do |configuration|
path = "lib/bar/src/bar.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.absolute_path.should eq(
File.join(configuration.src_path.not_nil!, path)
)
frame.relative_path.should eq(path)
frame.under_src_path?.should be_false
frame.shard_name.should eq "bar"
frame.in_app?.should be_false
end
end
end
it "uses only folders for shard names" do
with_foo_frame(path: "lib/bar.cr") do |frame|
frame.shard_name.should be_nil
end
end
end
end
end

View file

@ -1,207 +1,6 @@
require "../../spec_helper" require "../../spec_helper"
private def parse_frame(line)
Backtracer::Backtrace::Frame::Parser.parse(line)
end
private def with_frame(method, path = nil, lineno = nil, column = nil)
line = String.build do |io|
if path
io << path
io << ':' << lineno if lineno
io << ':' << column if column
io << " in '" << method << '\''
else
io << method
end
end
yield parse_frame(line)
end
private def with_foo_frame(
method = "foo_bar?",
path = "#{__DIR__}/foo.cr",
lineno = 1,
column = 7
)
with_frame(method, path, lineno, column) do |frame|
yield frame
end
end
describe Backtracer::Backtrace::Frame do describe Backtracer::Backtrace::Frame do
describe ".parse" do
it "fails to parse an empty string" do
expect_raises(ArgumentError) { parse_frame("") }
end
context "when --no-debug flag is set" do
it "parses frame with any value as method" do
backtrace_line = "__crystal_main"
with_frame(backtrace_line) do |frame|
frame.lineno.should be_nil
frame.column.should be_nil
frame.method.should eq(backtrace_line)
frame.path.should be_nil
frame.relative_path.should be_nil
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
end
context "with ~proc signature" do
it "parses absolute path outside of src/ dir" do
backtrace_line = "~proc2Proc(Fiber, (IO::FileDescriptor | Nil))@/usr/local/Cellar/crystal/0.27.2/src/fiber.cr:72"
with_frame(backtrace_line) do |frame|
frame.lineno.should eq(72)
frame.column.should be_nil
frame.method.should eq("~proc2Proc(Fiber, (IO::FileDescriptor | Nil))")
frame.path.should eq("/usr/local/Cellar/crystal/0.27.2/src/fiber.cr")
frame.relative_path.should be_nil
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
it "parses relative path inside of lib/ dir" do
backtrace_line = "~procProc(HTTP::Server::Context, String)@lib/kemal/src/kemal/route.cr:11"
with_frame(backtrace_line) do |frame|
frame.lineno.should eq(11)
frame.column.should be_nil
frame.method.should eq("~procProc(HTTP::Server::Context, String)")
frame.path.should eq("lib/kemal/src/kemal/route.cr")
frame.relative_path.should eq("lib/kemal/src/kemal/route.cr")
frame.under_src_path?.should be_false
frame.shard_name.should eq("kemal")
frame.in_app?.should be_false
end
end
end
it "parses absolute path outside of configuration.src_path" do
path = "/some/absolute/path/to/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.relative_path.should be_nil
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
context "with in_app? = false" do
it "parses absolute path outside of src/ dir" do
with_foo_frame do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq("#{__DIR__}/foo.cr")
frame.relative_path.should eq("spec/backtracer/backtrace/foo.cr")
frame.under_src_path?.should be_true
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
it "parses relative path outside of src/ dir" do
path = "some/relative/path/to/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.relative_path.should eq(path)
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_false
end
end
end
context "with in_app? = true" do
it "parses absolute path inside of src/ dir" do
src_path = File.expand_path("../../../src", __DIR__)
path = "#{src_path}/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.relative_path.should eq("src/foo.cr")
frame.under_src_path?.should be_true
frame.shard_name.should be_nil
frame.in_app?.should be_true
end
end
it "parses relative path inside of src/ dir" do
path = "src/foo.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.relative_path.should eq(path)
frame.under_src_path?.should be_false
frame.shard_name.should be_nil
frame.in_app?.should be_true
end
end
end
context "with shard path" do
it "parses absolute path inside of lib/ dir" do
lib_path = File.expand_path("../../../lib/bar", __DIR__)
path = "#{lib_path}/src/bar.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.relative_path.should eq("lib/bar/src/bar.cr")
frame.under_src_path?.should be_true
frame.shard_name.should eq "bar"
frame.in_app?.should be_false
end
end
it "parses relative path inside of lib/ dir" do
path = "lib/bar/src/bar.cr"
with_foo_frame(path: path) do |frame|
frame.lineno.should eq(1)
frame.column.should eq(7)
frame.method.should eq("foo_bar?")
frame.path.should eq(path)
frame.relative_path.should eq(path)
frame.under_src_path?.should be_false
frame.shard_name.should eq "bar"
frame.in_app?.should be_false
end
end
it "uses only folders for shard names" do
with_foo_frame(path: "lib/bar.cr") do |frame|
frame.shard_name.should be_nil
end
end
end
end
it "#inspect" do it "#inspect" do
with_foo_frame do |frame| with_foo_frame do |frame|
frame.inspect.should match(/Backtrace::Frame(.*)$/) frame.inspect.should match(/Backtrace::Frame(.*)$/)
@ -209,7 +8,7 @@ describe Backtracer::Backtrace::Frame do
end end
it "#to_s" do it "#to_s" do
with_foo_frame do |frame| with_foo_frame(path: "#{__DIR__}/foo.cr") do |frame|
frame.to_s.should eq "`foo_bar?` at #{__DIR__}/foo.cr:1:7" frame.to_s.should eq "`foo_bar?` at #{__DIR__}/foo.cr:1:7"
end end
end end
@ -219,8 +18,8 @@ describe Backtracer::Backtrace::Frame do
with_foo_frame do |frame2| with_foo_frame do |frame2|
frame.should eq(frame2) frame.should eq(frame2)
end end
with_foo_frame(method: "other_method") do |frame2| with_foo_frame(method: "other_method") do |frame3|
frame.should_not eq(frame2) frame.should_not eq(frame3)
end end
end end
end end

View file

@ -0,0 +1,33 @@
require "../../spec_helper"
describe Backtracer::Backtrace::Parser do
describe ".parse" do
it "handles `caller` as an input" do
with_backtrace(caller) do |backtrace|
backtrace.frames.should_not be_empty
backtrace.frames.first
.tap(&.absolute_path.should eq(__FILE__))
.tap(&.path.should eq("spec/backtracer/backtrace/parser_spec.cr"))
backtrace.frames.last.method.should eq("main")
end
end
it "handles `Exception#backtrace` as an input" do
begin
raise "Oh, no!"
rescue ex
with_backtrace(ex.backtrace) do |backtrace|
backtrace.frames.should_not be_empty
backtrace.frames.first
.tap(&.absolute_path.should eq(__FILE__))
.tap(&.path.should eq("spec/backtracer/backtrace/parser_spec.cr"))
backtrace.frames.last.method.should eq("main")
end
end
end
end
end

View file

@ -1,24 +1,29 @@
require "../spec_helper" require "../spec_helper"
describe Backtracer::Backtrace do describe Backtracer::Backtrace do
backtrace = Backtracer.parse(caller)
it "#frames" do it "#frames" do
backtrace.frames.should be_a(Array(Backtracer::Backtrace::Frame)) with_backtrace(caller) do |backtrace|
backtrace.frames.should be_a(Array(Backtracer::Backtrace::Frame))
backtrace.frames.should_not be_empty
end
end end
it "#inspect" do it "#inspect" do
backtrace.inspect.should match(/#<Backtrace: .*>$/) with_backtrace(caller) do |backtrace|
backtrace.inspect.should match(/#<Backtrace: .+>$/)
end
end end
{% unless flag?(:release) || !flag?(:debug) %} it "#to_s" do
it "#to_s" do with_backtrace(caller) do |backtrace|
backtrace.to_s.should match(/backtrace_spec.cr:4/) backtrace.to_s.should match(/backtrace_spec.cr/)
end end
{% end %} end
it "#==" do it "#==" do
backtrace2 = Backtracer::Backtrace.new(backtrace.frames) with_backtrace(caller) do |backtrace|
backtrace2.should eq(backtrace) backtrace2 = Backtracer::Backtrace.new(backtrace.frames)
backtrace2.should eq(backtrace)
end
end end
end end

View file

@ -1,9 +1,5 @@
require "../spec_helper" require "../spec_helper"
private def with_configuration
yield Backtracer::Configuration.new
end
describe Backtracer::Configuration do describe Backtracer::Configuration do
it "should set #src_path to current dir from default" do it "should set #src_path to current dir from default" do
with_configuration do |configuration| with_configuration do |configuration|

View file

@ -1,2 +1,36 @@
require "spec" require "spec"
require "../src/backtracer" require "../src/backtracer"
def with_configuration(shared = true)
yield shared ? Backtracer.configuration : Backtracer::Configuration.new
end
def with_backtrace(backtrace, **options)
yield Backtracer::Backtrace::Parser.parse(backtrace, **options)
end
def with_frame(method, path = nil, lineno = nil, column = nil, **options)
line = String.build do |io|
if path
io << path
io << ':' << lineno if lineno
io << ':' << column if column
io << " in '" << method << '\''
else
io << method
end
end
yield Backtracer::Backtrace::Frame::Parser.parse(line, **options)
end
def with_foo_frame(
method = "foo_bar?",
path = "#{__DIR__}/foo.cr",
lineno = 1,
column = 7,
**options
)
with_frame(method, path, lineno, column, **options) do |frame|
yield frame
end
end