Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ group :development do
gem 'simplecov'
gem 'bundler'
gem 'irb', '>= 1.3.1'
gem 'byebug'
gem 'benchmark-ips'
end
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Use following test frameworks or extensions instead.
* [rspec-power_assert](https://github.com/joker1007/rspec-power_assert)
* [rspec-matchers-power_assert_matchers](https://github.com/kachick/rspec-matchers-power_assert_matchers)
* [pry-power_assert](https://github.com/yui-knk/pry-power_assert)
* [pry-byebug-power_assert](https://github.com/k-tsj/pry-byebug-power_assert)
* [irb-power_assert](https://github.com/kachick/irb-power_assert)
* [power_p](https://github.com/k-tsj/power_p)

Expand Down
48 changes: 11 additions & 37 deletions lib/power_assert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@
# Copyright (C) 2014 Kazuki Tsujimoto

begin
unless defined?(Byebug)
captured = false
target_thread = Thread.current
TracePoint.new(:return, :c_return) do |tp|
next unless Thread.current == target_thread
captured = true
unless tp.return_value and tp.callee_id
raise ''
end
end.enable { __id__ }
raise '' unless captured
end
captured = false
target_thread = Thread.current
TracePoint.new(:return, :c_return) do |tp|
next unless Thread.current == target_thread
captured = true
unless tp.return_value and tp.callee_id
raise ''
end
end.enable { __id__ }
raise '' unless captured
rescue
raise LoadError, 'Fully compatible TracePoint API required'
end
Expand All @@ -33,18 +31,7 @@ def start(assertion_proc_or_source, assertion_method: nil, source_binding: TOPLE
if respond_to?(:clear_global_method_cache, true)
clear_global_method_cache
end
yield BlockContext.new(assertion_proc_or_source, assertion_method, source_binding)
end

def trace(frame)
begin
raise 'Byebug is not started yet' unless Byebug.started?
rescue NameError
raise "PowerAssert.#{__method__} requires Byebug"
end
ctx = TraceContext.new(frame._binding)
ctx.enable
ctx
yield Context.new(assertion_proc_or_source, assertion_method, source_binding)
end

def app_caller_locations
Expand All @@ -59,24 +46,11 @@ def app_context?
private

def internal_file?(file)
setup_internal_lib_dir(Byebug, :attach, 2) if defined?(Byebug)
setup_internal_lib_dir(PryByebug, :start_with_pry_byebug, 2, Pry) if defined?(PryByebug)
INTERNAL_LIB_DIRS.find do |_, dir|
file.start_with?(dir)
end
end

def setup_internal_lib_dir(lib, mid, depth, lib_obj = lib)
unless INTERNAL_LIB_DIRS.key?(lib)
INTERNAL_LIB_DIRS[lib] = lib_dir(lib_obj, mid, depth)
end
rescue NameError
end

def lib_dir(obj, mid, depth)
File.expand_path('../' * depth, obj.method(mid).source_location[0])
end

if defined?(RubyVM)
CLEAR_CACHE_ISEQ = RubyVM::InstructionSequence.compile('using PowerAssert.const_get(:Empty)')
private_constant :CLEAR_CACHE_ISEQ
Expand Down
123 changes: 43 additions & 80 deletions lib/power_assert/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,34 @@ module PowerAssert
class Context
Value = Struct.new(:name, :value, :lineno, :column, :display_offset)

def initialize(base_caller_length)
def initialize(assertion_proc_or_source, assertion_method, source_binding)
@fired = false
@target_thread = Thread.current

if assertion_proc_or_source.respond_to?(:to_proc)
@assertion_proc = assertion_proc_or_source.to_proc
line = nil
else
@assertion_proc = source_binding.eval "Proc.new {#{assertion_proc_or_source}}"
line = assertion_proc_or_source
end

@parser = Parser::DUMMY
@trace_call = TracePoint.new(:call, :c_call) do
if PowerAssert.app_context? and Thread.current == @target_thread
@trace_call.disable
locs = PowerAssert.app_caller_locations
path = locs.last.path
lineno = locs.last.lineno
if File.exist?(path)
line ||= File.open(path) {|fp| fp.each_line.drop(lineno - 1).first }
end
if line
@parser = Parser.new(line, path, lineno, @assertion_proc.binding, assertion_method.to_s, @assertion_proc)
end
end
end

method_id_set = nil
@return_values = []
@trace_return = TracePoint.new(:return, :c_return) do |tp|
Expand All @@ -22,14 +47,12 @@ def initialize(base_caller_length)
next if tp.event == :c_return and
not (@parser.lineno == tp.lineno and @parser.path == tp.path)
locs = PowerAssert.app_caller_locations
diff = locs.length - base_caller_length
if (tp.event == :c_return && diff == 1 || tp.event == :return && diff <= 2) and Thread.current == @target_thread
idx = -(base_caller_length + 1)
if @parser.path == locs[idx].path and @parser.lineno == locs[idx].lineno
if (tp.event == :c_return && locs.length == 1 || tp.event == :return && locs.length <= 2) and Thread.current == @target_thread
if @parser.path == locs.last.path and @parser.lineno == locs.last.lineno
val = PowerAssert.configuration.lazy_inspection ?
tp.return_value :
InspectedValue.new(SafeInspectable.new(tp.return_value).inspect)
@return_values << Value[method_id.to_s, val, locs[idx].lineno, nil]
@return_values << Value[method_id.to_s, val, locs.last.lineno, nil]
Copy link

Copilot AI May 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable 'method_id' is used but not defined in the current scope. Define 'method_id' or update the code to properly reference an existing identifier.

Copilot uses AI. Check for mistakes.
end
end
rescue Exception => e
Expand All @@ -41,16 +64,29 @@ def initialize(base_caller_length)
end

def message
raise 'call #yield or #enable at first' unless fired?
raise 'call #yield at first' unless fired?
@message ||= build_assertion_message(@parser, @return_values).freeze
end

def message_proc
-> { message }
end

def yield
@fired = true
invoke_yield(&@assertion_proc)
end

private

def invoke_yield
@trace_return.enable do
@trace_call.enable do
yield
end
end
end

def fired?
@fired
end
Expand Down Expand Up @@ -157,77 +193,4 @@ def column2display_offset(str)
end
end
private_constant :Context

class BlockContext < Context
def initialize(assertion_proc_or_source, assertion_method, source_binding)
super(0)
if assertion_proc_or_source.respond_to?(:to_proc)
@assertion_proc = assertion_proc_or_source.to_proc
line = nil
else
@assertion_proc = source_binding.eval "Proc.new {#{assertion_proc_or_source}}"
line = assertion_proc_or_source
end
@parser = Parser::DUMMY
@trace_call = TracePoint.new(:call, :c_call) do
if PowerAssert.app_context? and Thread.current == @target_thread
@trace_call.disable
locs = PowerAssert.app_caller_locations
path = locs.last.path
lineno = locs.last.lineno
if File.exist?(path)
line ||= File.open(path) {|fp| fp.each_line.drop(lineno - 1).first }
end
if line
@parser = Parser.new(line, path, lineno, @assertion_proc.binding, assertion_method.to_s, @assertion_proc)
end
end
end
end

def yield
@fired = true
invoke_yield(&@assertion_proc)
end

private

def invoke_yield
@trace_return.enable do
@trace_call.enable do
yield
end
end
end
end
private_constant :BlockContext

class TraceContext < Context
def initialize(binding)
target_frame, *base = PowerAssert.app_caller_locations
super(base.length)
path = target_frame.path
lineno = target_frame.lineno
if File.exist?(path)
line = File.open(path) {|fp| fp.each_line.drop(lineno - 1).first }
@parser = Parser.new(line, path, lineno, binding)
else
@parser = Parser::DUMMY
end
end

def enable
@fired = true
@trace_return.enable
end

def disable
@trace_return.disable
end

def enabled?
@trace_return.enabled?
end
end
private_constant :TraceContext
end
21 changes: 0 additions & 21 deletions test/test_core_ext_helper.rb

This file was deleted.

5 changes: 0 additions & 5 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
require 'power_assert'
require 'ripper'

begin
require_relative 'test_core_ext_helper'
rescue LoadError
end

module PowerAssertTestHelper
class << self
def included(base)
Expand Down
94 changes: 0 additions & 94 deletions test/trace_test.rb

This file was deleted.

Loading