Module: Minitest::Compress
- Included in:
- UnexpectedError
- Defined in:
- lib/minitest/compress.rb
Overview
Compresses backtraces.
Instance Method Summary collapse
-
#compress(orig) ⇒ Object
Takes a backtrace (array of strings) and compresses repeating cycles in it to make it more readable.
Instance Method Details
#compress(orig) ⇒ Object
Takes a backtrace (array of strings) and compresses repeating cycles in it to make it more readable.
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/minitest/compress.rb', line 11 def compress orig ary = orig eswo = ->(a, n, off) { # each_slice_with_offset if off.zero? then a.each_slice n else # [ ...off... [...n...] [...n...] ... ] front, back = a.take(off), a.drop(off) [front].chain back.each_slice n end } 3.times do # maybe don't use loop do here? index = ary # [ a b c b c b c d ] .size .times # 0...size .group_by { |i| ary[i] } # { a: [0] b: [1 3 5], c: [2 4 6], d: [7] } order = index .reject { |k, v| v.size == 1 } # { b: [1 3 5], c: [2 4 6] } .sort_by { |k, a1| ### sort by max dist + min offset d = a1.each_cons(2).sum { |a2, b| b-a2 } [-d, a1.first] } # b: [1 3 5] c: [2 4 6] ranges = order .map { |k, a1| # [[1..2 3..4] [2..3 4..5]] a1 .each_cons(2) .map { |a2, b| a2..b-1 } } big_ranges = ranges .flat_map { |a| # [1..2 3..4 2..3 4..5] a.sort_by { |r| [-r.size, r.first] }.first 5 } .first(100) culprits = big_ranges .map { |r| eswo[ary, r.size, r.begin] # [o1 s1 s1 s2 s2] .chunk_while { |a, b| a == b } # [[o1] [s1 s1] [s2 s2]] .map { |a| [a.size, a.first] } # [[1 o1] [2 s1] [2 s2]] } .select { |chunks| chunks.any? { |a| a.first > 1 } # compressed anything? } min = culprits .min_by { |a| a.flatten.size } # most compressed break unless min ary = min.flat_map { |(n, lines)| if n > 1 then [[n, compress(lines)]] # [o1 [2 s1] [2 s2]] else lines end } end format = ->(lines) { lines.flat_map { |line| case line when Array then n, lines = line lines = format[lines] [ " +->> #{n} cycles of #{lines.size} lines:", *lines.map { |s| " | #{s}" }, " +-<<", ] else line end } } format[ary] end |