lumitrace 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/runv/sync_inline.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  index_path = File.expand_path("index.html", __dir__)
4
4
  record_path = File.expand_path("../lib/lumitrace/record_instrument.rb", __dir__)
5
5
  html_path = File.expand_path("../lib/lumitrace/generate_resulted_html.rb", __dir__)
6
+ renderer_js_path = File.expand_path("../lib/lumitrace/generate_resulted_html_renderer.js", __dir__)
6
7
  version_path = File.expand_path("../lib/lumitrace/version.rb", __dir__)
7
8
 
8
9
  index = File.read(index_path)
@@ -15,6 +16,17 @@ record_code = File.read(record_path).rstrip
15
16
  html_code = File.read(html_path).lines.reject { |line|
16
17
  line.match?(/^\s*require_relative\s+["']record_instrument["']\s*$/)
17
18
  }.join.rstrip
19
+ renderer_js = File.read(renderer_js_path).rstrip
20
+ renderer_js_literal = renderer_js.gsub(/\\/, "\\\\\\\\").gsub(/'/, "\\\\'")
21
+
22
+ renderer_method_src = <<~RUBY.rstrip
23
+ def self.html_renderer_js
24
+ @html_renderer_js ||= '#{renderer_js_literal}'
25
+ end
26
+ RUBY
27
+ html_code_after = html_code.sub(/def self\.html_renderer_js\s*\n.*?\n\s*end/m) { renderer_method_src }
28
+ abort "failed to inline renderer JS into GenerateResultedHtml" if html_code_after == html_code
29
+ html_code = html_code_after
18
30
  html_code = html_code.gsub("</script>", "\#{'</scr' + 'ipt>'}")
19
31
 
20
32
  generated = +" # LUMITRACE_INLINE_BEGIN\n"
@@ -30,7 +42,7 @@ unless index.match?(pattern)
30
42
  abort "inline block markers not found in #{index_path}"
31
43
  end
32
44
 
33
- index.sub!(pattern, generated)
45
+ index.sub!(pattern) { generated }
34
46
  index.gsub!(/lumitrace \d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?\./, "lumitrace #{version}.")
35
47
  File.write(index_path, index)
36
48
  puts "updated #{index_path}"
@@ -64,6 +64,43 @@ class LumiTraceTest < Minitest::Test
64
64
  assert_operator out.scan(/Lumitrace::R\(\d+, \(/).length, :>=, 2
65
65
  end
66
66
 
67
+ def test_instrument_command_style_call_with_hash_and_block_compiles
68
+ skip "RubyVM::InstructionSequence unavailable" unless defined?(RubyVM::InstructionSequence)
69
+
70
+ src = <<~RUBY
71
+ def path(*args)
72
+ yield if block_given?
73
+ end
74
+
75
+ path = "x"
76
+ glob = "*.rb"
77
+
78
+ path path, "glob" => glob do
79
+ path
80
+ end
81
+ RUBY
82
+
83
+ out = Lumitrace::RecordInstrument.instrument_source(src, [], file_label: "sample.rb")
84
+ RubyVM::InstructionSequence.compile(out, "sample.rb")
85
+ assert_includes out, "path path"
86
+ end
87
+
88
+ def test_instrument_does_not_wrap_inside_defined
89
+ skip "RubyVM::InstructionSequence unavailable" unless defined?(RubyVM::InstructionSequence)
90
+
91
+ src = <<~RUBY
92
+ foo = 1
93
+ bar = 2
94
+ defined?(foo + bar)
95
+ RUBY
96
+
97
+ out = Lumitrace::RecordInstrument.instrument_source(src, [], file_label: "sample.rb")
98
+ RubyVM::InstructionSequence.compile(out, "sample.rb")
99
+
100
+ assert_includes out, "defined?(foo + bar)"
101
+ refute_match(/defined\?\([^)]*Lumitrace::R\(/, out)
102
+ end
103
+
67
104
  def test_render_all_generates_html
68
105
  Dir.mktmpdir do |dir|
69
106
  path = File.join(dir, "lumitrace_events.json")
@@ -243,6 +280,37 @@ class LumiTraceTest < Minitest::Test
243
280
  end
244
281
  end
245
282
 
283
+ def test_events_from_ids_includes_unhit_locations
284
+ with_record_instrument_state do
285
+ mod = Lumitrace::RecordInstrument
286
+ mod.instance_variable_set(:@events_by_id, [])
287
+ mod.instance_variable_set(:@loc_by_id, [])
288
+ mod.instance_variable_set(:@next_id, 0)
289
+ Lumitrace.install_collect_mode("history")
290
+ mod.max_samples_per_expr = 3
291
+
292
+ hit_id = mod.register_location(
293
+ "a.rb",
294
+ { start_line: 1, start_col: 0, end_line: 1, end_col: 1 },
295
+ kind: :expr
296
+ )
297
+ mod.register_location(
298
+ "a.rb",
299
+ { start_line: 2, start_col: 0, end_line: 2, end_col: 1 },
300
+ kind: :expr
301
+ )
302
+
303
+ Lumitrace::R(hit_id, 1)
304
+
305
+ events = mod.events_from_ids.sort_by { |e| e[:start_line] }
306
+ assert_equal 2, events.length
307
+ assert_equal 1, events[0][:total]
308
+ assert_equal 0, events[1][:total]
309
+ assert_equal [], events[1][:sampled_values]
310
+ assert_equal({}, events[1][:types])
311
+ end
312
+ end
313
+
246
314
  def test_text_comment_value_includes_type
247
315
  events = [
248
316
  {
@@ -346,6 +414,46 @@ class LumiTraceTest < Minitest::Test
346
414
  assert_equal "types: Integer(3) (3rd run)", comment
347
415
  end
348
416
 
417
+ def test_comment_value_ignores_unhit_event
418
+ comment = Lumitrace::GenerateResultedHtml.comment_value_with_total_for_line(
419
+ [
420
+ {
421
+ marker: true,
422
+ kind: "expr",
423
+ start_col: 0,
424
+ end_col: 1,
425
+ sampled_values: [],
426
+ types: {},
427
+ total: 0
428
+ }
429
+ ]
430
+ )
431
+ assert_nil comment
432
+ end
433
+
434
+ def test_render_text_marks_unhit_line_with_bang
435
+ text = Lumitrace::GenerateResultedHtml.render_text_from_normalized_events(
436
+ "foo = bar\n",
437
+ [
438
+ {
439
+ file: "a.rb",
440
+ start_line: 1,
441
+ start_col: 6,
442
+ end_line: 1,
443
+ end_col: 9,
444
+ kind: "expr",
445
+ sampled_values: [],
446
+ types: {},
447
+ total: 0
448
+ }
449
+ ],
450
+ filename: "a.rb",
451
+ with_header: false
452
+ )
453
+
454
+ assert_includes text, "!1| foo = bar"
455
+ end
456
+
349
457
  def test_normalize_events_keeps_sampled_value_objects
350
458
  events = [
351
459
  {
@@ -362,6 +470,35 @@ class LumiTraceTest < Minitest::Test
362
470
  assert_equal "<obj>", normalized.first[:sampled_values].first["preview"]
363
471
  end
364
472
 
473
+ def test_event_to_html_trace_payload_uses_last_value_when_sampled_values_missing
474
+ payload = Lumitrace::GenerateResultedHtml.event_to_html_trace_payload(
475
+ {
476
+ start_line: 1,
477
+ start_col: 0,
478
+ end_line: 1,
479
+ end_col: 3,
480
+ kind: "expr",
481
+ last_value: { type: "String", preview: "\"x\"" },
482
+ types: { "String" => 2 },
483
+ total: 2
484
+ }
485
+ )
486
+
487
+ assert_equal [{ type: "String", preview: "\"x\"" }], payload[:sampled_values]
488
+ assert_equal({ "String" => 2 }, payload[:types])
489
+ assert_equal 2, payload[:total]
490
+ end
491
+
492
+ def test_build_html_payload_includes_command_text
493
+ payload = Lumitrace::GenerateResultedHtml.build_html_payload(
494
+ mode_info: { mode: "last", text: "Mode: last (last value)", max_samples: nil },
495
+ files: [],
496
+ command_text: "ruby script.rb arg1"
497
+ )
498
+
499
+ assert_equal "ruby script.rb arg1", payload[:meta][:command]
500
+ end
501
+
365
502
  def test_env_range_parsing
366
503
  with_env("LUMITRACE_RANGE" => "a.rb:1-3,5-6;b.rb", "LUMITRACE_COLLECT_MODE" => "types") do
367
504
  env = Lumitrace.resolve_env_options
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lumitrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada
@@ -34,6 +34,7 @@ files:
34
34
  - lib/lumitrace/enable_git_diff.rb
35
35
  - lib/lumitrace/env.rb
36
36
  - lib/lumitrace/generate_resulted_html.rb
37
+ - lib/lumitrace/generate_resulted_html_renderer.js
37
38
  - lib/lumitrace/git_diff.rb
38
39
  - lib/lumitrace/help_manifest.rb
39
40
  - lib/lumitrace/record_instrument.rb