power_assert 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -3
- data/README.rdoc +6 -2
- data/Rakefile +38 -3
- data/lib/power_assert.rb +23 -13
- data/lib/power_assert/context.rb +31 -25
- data/lib/power_assert/enable_tracepoint_events.rb +10 -10
- data/lib/power_assert/parser.rb +2 -1
- data/lib/power_assert/version.rb +1 -1
- data/power_assert.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1444d874d5d014e20312a4644073d9fc166211ff
|
4
|
+
data.tar.gz: 3be96faed9006385ebd30d2d6694aaead254c426
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f19ff06f13f40abb6f4f70516618634b5b5131e2e4119fa8430ff857b01f17e82330ec9e6477b545a4d1641476e4949f0125ccd0b2fddf81ff13f09241351a8
|
7
|
+
data.tar.gz: 2f9b2f75d552b3c25bbbab548d8990bbcfb540b00e35ab9a57a987f6125cb497c79dc475c31f88a1ed4a057f9e61797c08258957fecdfa0ab11c2474e7d8c3a8
|
data/.travis.yml
CHANGED
@@ -3,12 +3,19 @@ language: ruby
|
|
3
3
|
rvm:
|
4
4
|
- 2.0.0-p648
|
5
5
|
- 2.1.10
|
6
|
-
- 2.2.
|
7
|
-
- 2.3.
|
8
|
-
- 2.4.
|
6
|
+
- 2.2.7
|
7
|
+
- 2.3.4
|
8
|
+
- 2.4.1
|
9
9
|
- ruby-head
|
10
|
+
env:
|
11
|
+
- TEST_SYMLINK="no"
|
12
|
+
- TEST_SYMLINK="yes"
|
10
13
|
matrix:
|
11
14
|
allow_failures:
|
12
15
|
- rvm: ruby-head
|
13
16
|
before_install:
|
14
17
|
- gem update bundler
|
18
|
+
before_script:
|
19
|
+
- bundle exec rake before_script
|
20
|
+
after_script:
|
21
|
+
- bundle exec rake after_script
|
data/README.rdoc
CHANGED
@@ -6,12 +6,16 @@ Power Assert shows each value of variables and method calls in the expression.
|
|
6
6
|
It is useful for testing, providing which value wasn't correct when the condition is not satisfied.
|
7
7
|
|
8
8
|
== Related Projects
|
9
|
+
In general, you don't need to use this library directly.
|
10
|
+
Use following test frameworks or extensions instead.
|
11
|
+
|
9
12
|
* {test-unit}[https://github.com/test-unit/test-unit](>= 3.0.0)
|
13
|
+
* {Document}[http://test-unit.github.io/test-unit/en/Test/Unit/Assertions.html#assert-instance_method]
|
10
14
|
* {minitest-power_assert}[https://github.com/hsbt/minitest-power_assert]
|
11
|
-
* {pry-power_assert}[https://github.com/yui-knk/pry-power_assert]
|
12
15
|
* {rspec-power_assert}[https://github.com/joker1007/rspec-power_assert]
|
13
|
-
* {
|
16
|
+
* {pry-power_assert}[https://github.com/yui-knk/pry-power_assert]
|
14
17
|
* {pry-byebug-power_assert}[https://github.com/k-tsj/pry-byebug-power_assert]
|
18
|
+
* {power_p}[https://github.com/k-tsj/power_p]
|
15
19
|
|
16
20
|
== Requirement
|
17
21
|
* CRuby 2.0.0 or later
|
data/Rakefile
CHANGED
@@ -4,7 +4,8 @@ require "rake/testtask"
|
|
4
4
|
task :default => :test
|
5
5
|
Rake::TestTask.new(:test) do |t|
|
6
6
|
# helper(simplecov) must be required before loading power_assert
|
7
|
-
|
7
|
+
helper_path = File.realpath("test/test_helper.rb")
|
8
|
+
t.ruby_opts = ["-w", "-r#{helper_path}"]
|
8
9
|
t.test_files = FileList["test/**/*_test.rb"].exclude do |i|
|
9
10
|
begin
|
10
11
|
return false unless defined?(RubyVM)
|
@@ -16,9 +17,43 @@ Rake::TestTask.new(:test) do |t|
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
20
|
+
# ruby/ruby:test/pathname/test_pathname.rb
|
21
|
+
def has_symlink?
|
22
|
+
begin
|
23
|
+
File.symlink("", "")
|
24
|
+
rescue NotImplementedError, Errno::EACCES
|
25
|
+
return false
|
26
|
+
rescue Errno::ENOENT
|
27
|
+
end
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
SYMLINK_DIRS = ["lib", "test"]
|
32
|
+
|
33
|
+
task :before_script do
|
34
|
+
if ENV["TEST_SYMLINK"] == "yes" and has_symlink?
|
35
|
+
SYMLINK_DIRS.each do |d|
|
36
|
+
File.rename(d, ".#{d}")
|
37
|
+
File.symlink(".#{d}", d)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :after_script do
|
43
|
+
SYMLINK_DIRS.each do |d|
|
44
|
+
if File.symlink?(d) and File.directory?(".#{d}")
|
45
|
+
File.unlink(d)
|
46
|
+
File.rename(".#{d}", d)
|
47
|
+
end
|
48
|
+
unless File.directory?(d)
|
49
|
+
raise "#{d} should be directory"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
19
54
|
desc "Run the benchmark suite"
|
20
|
-
task
|
21
|
-
Dir.glob(
|
55
|
+
task :benchmark do
|
56
|
+
Dir.glob("benchmark/bm_*.rb").each do |f|
|
22
57
|
load(f)
|
23
58
|
end
|
24
59
|
end
|
data/lib/power_assert.rb
CHANGED
@@ -22,9 +22,16 @@ require 'power_assert/configuration'
|
|
22
22
|
require 'power_assert/context'
|
23
23
|
|
24
24
|
module PowerAssert
|
25
|
-
POWER_ASSERT_LIB_DIR =
|
26
|
-
|
27
|
-
private_constant :POWER_ASSERT_LIB_DIR, :
|
25
|
+
POWER_ASSERT_LIB_DIR = File.dirname(caller_locations(1, 1).first.path)
|
26
|
+
INTERNAL_LIB_DIRS = {PowerAssert => POWER_ASSERT_LIB_DIR}
|
27
|
+
private_constant :POWER_ASSERT_LIB_DIR, :INTERNAL_LIB_DIRS
|
28
|
+
|
29
|
+
# For backward compatibility
|
30
|
+
IGNORED_LIB_DIRS = INTERNAL_LIB_DIRS
|
31
|
+
private_constant :IGNORED_LIB_DIRS
|
32
|
+
if respond_to?(:deprecate_constant)
|
33
|
+
deprecate_constant :IGNORED_LIB_DIRS
|
34
|
+
end
|
28
35
|
|
29
36
|
class << self
|
30
37
|
def start(assertion_proc_or_source, assertion_method: nil, source_binding: TOPLEVEL_BINDING)
|
@@ -46,27 +53,27 @@ module PowerAssert
|
|
46
53
|
end
|
47
54
|
|
48
55
|
def app_caller_locations
|
49
|
-
caller_locations.drop_while {|i|
|
56
|
+
caller_locations.drop_while {|i| internal_file?(i.path) }.take_while {|i| ! internal_file?(i.path) }
|
50
57
|
end
|
51
58
|
|
52
59
|
def app_context?
|
53
60
|
top_frame = caller_locations.drop_while {|i| i.path.start_with?(POWER_ASSERT_LIB_DIR) }.first
|
54
|
-
top_frame and !
|
61
|
+
top_frame and ! internal_file?(top_frame.path)
|
55
62
|
end
|
56
63
|
|
57
64
|
private
|
58
65
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
66
|
+
def internal_file?(file)
|
67
|
+
setup_internal_lib_dir(Byebug, :attach, 2) if defined?(Byebug)
|
68
|
+
setup_internal_lib_dir(PryByebug, :start_with_pry_byebug, 2, Pry) if defined?(PryByebug)
|
69
|
+
INTERNAL_LIB_DIRS.find do |_, dir|
|
63
70
|
file.start_with?(dir)
|
64
71
|
end
|
65
72
|
end
|
66
73
|
|
67
|
-
def
|
68
|
-
unless
|
69
|
-
|
74
|
+
def setup_internal_lib_dir(lib, mid, depth, lib_obj = lib)
|
75
|
+
unless INTERNAL_LIB_DIRS.key?(lib)
|
76
|
+
INTERNAL_LIB_DIRS[lib] = lib_dir(lib_obj, mid, depth)
|
70
77
|
end
|
71
78
|
rescue NameError
|
72
79
|
end
|
@@ -76,8 +83,11 @@ module PowerAssert
|
|
76
83
|
end
|
77
84
|
|
78
85
|
if defined?(RubyVM)
|
86
|
+
CLEAR_CACHE_ISEQ = RubyVM::InstructionSequence.compile('using PowerAssert.const_get(:Empty)')
|
87
|
+
private_constant :CLEAR_CACHE_ISEQ
|
88
|
+
|
79
89
|
def clear_global_method_cache
|
80
|
-
eval
|
90
|
+
CLEAR_CACHE_ISEQ.eval
|
81
91
|
end
|
82
92
|
end
|
83
93
|
end
|
data/lib/power_assert/context.rb
CHANGED
@@ -5,18 +5,19 @@ require 'power_assert/parser'
|
|
5
5
|
|
6
6
|
module PowerAssert
|
7
7
|
class Context
|
8
|
-
Value = Struct.new(:name, :value, :column)
|
9
|
-
|
10
|
-
attr_reader :message_proc
|
8
|
+
Value = Struct.new(:name, :value, :lineno, :column)
|
11
9
|
|
12
10
|
def initialize(base_caller_length)
|
13
11
|
@fired = false
|
14
12
|
@target_thread = Thread.current
|
15
13
|
method_id_set = nil
|
16
|
-
return_values = []
|
14
|
+
@return_values = []
|
17
15
|
trace_alias_method = PowerAssert.configuration._trace_alias_method
|
18
16
|
@trace_return = TracePoint.new(:return, :c_return) do |tp|
|
19
|
-
|
17
|
+
unless method_id_set
|
18
|
+
next unless Thread.current == @target_thread
|
19
|
+
method_id_set = @parser.method_id_set
|
20
|
+
end
|
20
21
|
method_id = SUPPORT_ALIAS_METHOD ? tp.callee_id :
|
21
22
|
trace_alias_method && tp.event == :return ? tp.binding.eval('::Kernel.__callee__') :
|
22
23
|
tp.method_id
|
@@ -31,18 +32,19 @@ module PowerAssert
|
|
31
32
|
val = PowerAssert.configuration.lazy_inspection ?
|
32
33
|
tp.return_value :
|
33
34
|
InspectedValue.new(SafeInspectable.new(tp.return_value).inspect)
|
34
|
-
return_values << Value[method_id.to_s, val, nil]
|
35
|
+
@return_values << Value[method_id.to_s, val, locs[idx].lineno, nil]
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
38
|
-
@message_proc = -> {
|
39
|
-
raise RuntimeError, 'call #yield or #enable at first' unless fired?
|
40
|
-
@message ||= build_assertion_message(@parser.line, @parser.idents, @parser.binding, return_values).freeze
|
41
|
-
}
|
42
39
|
end
|
43
40
|
|
44
41
|
def message
|
45
|
-
|
42
|
+
raise 'call #yield or #enable at first' unless fired?
|
43
|
+
@message ||= build_assertion_message(@parser, @return_values).freeze
|
44
|
+
end
|
45
|
+
|
46
|
+
def message_proc
|
47
|
+
-> { message }
|
46
48
|
end
|
47
49
|
|
48
50
|
private
|
@@ -51,24 +53,26 @@ module PowerAssert
|
|
51
53
|
@fired
|
52
54
|
end
|
53
55
|
|
54
|
-
def build_assertion_message(
|
56
|
+
def build_assertion_message(parser, return_values)
|
55
57
|
if PowerAssert.configuration._colorize_message
|
56
|
-
line = Pry::Code.new(line).highlighted
|
58
|
+
line = Pry::Code.new(parser.line).highlighted
|
59
|
+
else
|
60
|
+
line = parser.line
|
57
61
|
end
|
58
62
|
|
59
|
-
path = detect_path(
|
63
|
+
path = detect_path(parser, return_values)
|
60
64
|
return line unless path
|
61
65
|
|
62
|
-
|
63
|
-
|
64
|
-
return_values.zip(methods) do |i, j|
|
66
|
+
return_values, methods_in_path = find_all_identified_calls(return_values, path)
|
67
|
+
return_values.zip(methods_in_path) do |i, j|
|
65
68
|
unless i.name == j.name
|
66
69
|
warn "power_assert: [BUG] Failed to get column: #{i.name}"
|
67
70
|
return line
|
68
71
|
end
|
69
72
|
i.column = j.column
|
70
73
|
end
|
71
|
-
|
74
|
+
refs_in_path = path.find_all {|i| i.type == :ref }
|
75
|
+
ref_values = refs_in_path.map {|i| Value[i.name, parser.binding.eval(i.name), parser.lineno, i.column] }
|
72
76
|
vals = (return_values + ref_values).find_all(&:column).sort_by(&:column).reverse
|
73
77
|
return line if vals.empty?
|
74
78
|
|
@@ -88,9 +92,9 @@ module PowerAssert
|
|
88
92
|
lines.join("\n")
|
89
93
|
end
|
90
94
|
|
91
|
-
def detect_path(
|
92
|
-
return
|
93
|
-
all_paths =
|
95
|
+
def detect_path(parser, return_values)
|
96
|
+
return parser.call_paths.flatten.uniq if parser.method_id_set.empty?
|
97
|
+
all_paths = parser.call_paths
|
94
98
|
return_value_names = return_values.map(&:name)
|
95
99
|
uniq_calls = uniq_calls(all_paths)
|
96
100
|
uniq_call = return_value_names.find {|i| uniq_calls.include?(i) }
|
@@ -108,12 +112,14 @@ module PowerAssert
|
|
108
112
|
all_calls.find_all {|_, call_count| call_count == 1 }.map {|name, _| name }
|
109
113
|
end
|
110
114
|
|
111
|
-
def
|
115
|
+
def find_all_identified_calls(return_values, path)
|
112
116
|
return_value_num_of_calls = enum_count_by(return_values, &:name)
|
113
117
|
path_num_of_calls = enum_count_by(path.find_all {|ident| ident.type == :method }, &:name)
|
114
118
|
identified_calls = return_value_num_of_calls.find_all {|name, num| path_num_of_calls[name] == num }.map(&:first)
|
115
|
-
|
116
|
-
|
119
|
+
[
|
120
|
+
return_values.find_all {|val| identified_calls.include?(val.name) },
|
121
|
+
path.find_all {|ident| ident.type == :method and identified_calls.include?(ident.name) }
|
122
|
+
]
|
117
123
|
end
|
118
124
|
|
119
125
|
def enum_count_by(enum, &blk)
|
@@ -152,7 +158,7 @@ module PowerAssert
|
|
152
158
|
lineno = locs.last.lineno
|
153
159
|
if File.exist?(path)
|
154
160
|
line ||= open(path).each_line.drop(lineno - 1).first
|
155
|
-
@parser = Parser.new(line, path, lineno, @assertion_proc.binding, assertion_method.to_s)
|
161
|
+
@parser = Parser.new(line, path, lineno, @assertion_proc.binding, assertion_method.to_s, @assertion_proc)
|
156
162
|
end
|
157
163
|
end
|
158
164
|
end
|
@@ -13,37 +13,37 @@ if defined?(RubyVM)
|
|
13
13
|
module PowerAssert
|
14
14
|
# set redefined flag
|
15
15
|
basic_classes = [
|
16
|
-
Fixnum, Float, String, Array, Hash, Bignum, Symbol, Time, Regexp
|
16
|
+
Fixnum, Float, String, Array, Hash, Bignum, Symbol, Time, Regexp, NilClass, TrueClass, FalseClass
|
17
17
|
]
|
18
18
|
|
19
19
|
basic_operators = [
|
20
20
|
:+, :-, :*, :/, :%, :==, :===, :<, :<=, :<<, :[], :[]=,
|
21
|
-
:length, :size, :empty?, :succ, :>, :>=, :!, :!=, :=~, :freeze
|
21
|
+
:length, :size, :empty?, :succ, :>, :>=, :!, :!=, :=~, :freeze, :-@, :max, :min
|
22
22
|
]
|
23
23
|
|
24
|
-
|
24
|
+
bug11182 = Class.new do
|
25
25
|
def fixed?
|
26
26
|
true
|
27
27
|
end
|
28
28
|
end
|
29
|
-
private_constant :Bug11182
|
30
29
|
|
31
|
-
refine
|
30
|
+
refine bug11182 do
|
32
31
|
def fixed?
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
|
-
|
35
|
+
_ = Class.new(bug11182) do
|
37
36
|
alias _fixed? fixed?
|
38
37
|
protected :_fixed?
|
39
38
|
end
|
40
|
-
private_constant :Bug11182Sub
|
41
39
|
|
42
|
-
if (
|
40
|
+
if (bug11182.new.fixed? rescue false)
|
43
41
|
basic_classes.each do |klass|
|
44
42
|
basic_operators.each do |bop|
|
45
|
-
|
46
|
-
|
43
|
+
if klass.public_method_defined?(bop)
|
44
|
+
refine(klass) do
|
45
|
+
define_method(bop) {}
|
46
|
+
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
data/lib/power_assert/parser.rb
CHANGED
@@ -6,7 +6,7 @@ module PowerAssert
|
|
6
6
|
|
7
7
|
attr_reader :line, :path, :lineno, :binding
|
8
8
|
|
9
|
-
def initialize(line, path, lineno, binding, assertion_method_name = nil)
|
9
|
+
def initialize(line, path, lineno, binding, assertion_method_name = nil, assertion_proc = nil)
|
10
10
|
@line = line
|
11
11
|
@line_for_parsing = valid_syntax?(line) ? line : slice_expression(line)
|
12
12
|
@path = path
|
@@ -14,6 +14,7 @@ module PowerAssert
|
|
14
14
|
@binding = binding
|
15
15
|
@proc_local_variables = binding.eval('local_variables').map(&:to_s)
|
16
16
|
@assertion_method_name = assertion_method_name
|
17
|
+
@assertion_proc = assertion_proc
|
17
18
|
end
|
18
19
|
|
19
20
|
def idents
|
data/lib/power_assert/version.rb
CHANGED
data/power_assert.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = "Power Assert for Ruby. Power Assert shows each value of variables and method calls in the expression. It is useful for testing, providing which value wasn't correct when the condition is not satisfied."
|
14
14
|
|
15
15
|
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
-
f.match(%r{^(test|spec|features|
|
16
|
+
f.match(%r{^(test|spec|features|benchmark)/})
|
17
17
|
end
|
18
18
|
s.bindir = 'exe'
|
19
19
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: power_assert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kazuki Tsujimoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
146
|
version: '0'
|
147
147
|
requirements: []
|
148
148
|
rubyforge_project:
|
149
|
-
rubygems_version: 2.6.
|
149
|
+
rubygems_version: 2.6.11
|
150
150
|
signing_key:
|
151
151
|
specification_version: 4
|
152
152
|
summary: Power Assert for Ruby
|