Class: Capybara::Simulated::Sourcemap
- Inherits:
-
Object
- Object
- Capybara::Simulated::Sourcemap
- Defined in:
- lib/capybara/simulated/sourcemap.rb
Overview
Minimal source-map v3 decoder. Just enough for the stack-trace rewriter to map ‘<asset URL>:<line>:<col>` back to `<source file>:<line>:<col>` so failing-test traces point at the original TS/JS instead of a 100k-char minified blob.
Not handled:
- `sections` (composite maps) — Vite/Rolldown don't emit them
- `names` lookup — we don't need them for source-only resolution
Defined Under Namespace
Classes: Position
Constant Summary collapse
- BASE64_CHARS =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'- BASE64_LOOKUP =
BASE64_CHARS.each_char.with_index.to_h.freeze
Instance Method Summary collapse
-
#initialize(json) ⇒ Sourcemap
constructor
A new instance of Sourcemap.
-
#resolve(line, column) ⇒ Object
Returns the nearest mapping at-or-before (line, column).
Constructor Details
#initialize(json) ⇒ Sourcemap
Returns a new instance of Sourcemap.
21 22 23 24 25 |
# File 'lib/capybara/simulated/sourcemap.rb', line 21 def initialize(json) @sources = (json['sources'] || []).map(&:to_s) @source_root = json['sourceRoot'].to_s @segments_by_line = parse_mappings(json['mappings'].to_s) end |
Instance Method Details
#resolve(line, column) ⇒ Object
Returns the nearest mapping at-or-before (line, column). Line/col are 1-based to match V8’s stack-trace convention.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/capybara/simulated/sourcemap.rb', line 29 def resolve(line, column) return nil if line < 1 row = @segments_by_line[line - 1] return nil unless row && !row.empty? # Per-line row is a flat Integer array of stride 4: [gen_col, # source_idx, src_line, src_col, ...]. `bsearch_index` finds the # first segment whose gen_col is *strictly greater* than target; # the segment before that is the match. target = column - 1 idx = (0...(row.length / 4)).bsearch {|i| row[i * 4] > target } match_i = (idx || row.length / 4) - 1 return nil if match_i < 0 base = match_i * 4 source_idx = row[base + 1] return nil unless source_idx && @sources[source_idx] Position.new( source: full_source(@sources[source_idx]), line: row[base + 2] + 1, column: row[base + 3] + 1 ) end |