turbo_test_constant_tracer 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ def TurboTestDelegateClass(superclass)
6
+ klass = Class.new(Delegator)
7
+ ignores = [*::Delegator.public_api, :to_s, :inspect, :=~, :!~, :===]
8
+ protected_instance_methods = superclass.protected_instance_methods
9
+ protected_instance_methods -= ignores
10
+ public_instance_methods = superclass.public_instance_methods
11
+ public_instance_methods -= ignores
12
+
13
+ klass.module_eval do
14
+ def __getobj__ # :nodoc:
15
+ unless defined?(@delegate_dc_obj)
16
+ return yield if block_given?
17
+
18
+ __raise__ ::ArgumentError, "not delegated"
19
+ end
20
+ @delegate_dc_obj
21
+ end
22
+
23
+ def __setobj__(obj) # :nodoc:
24
+ # Not needed since we are controlling which classes are delegated
25
+ # __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
26
+ @delegate_dc_obj = obj
27
+ end
28
+
29
+ protected_instance_methods.each do |method|
30
+ klass.send(:define_method, method, Delegator.delegating_block(method))
31
+ protected method
32
+ end
33
+
34
+ public_instance_methods.each do |method|
35
+ if (superclass == String && TurboTest::ConstantTracer::Klass::STRING_METHODS[method]) ||
36
+ (superclass.ancestors.include?(Enumerable) &&
37
+ TurboTest::ConstantTracer::Klass::ENUMERABLE_METHODS[method])
38
+ klass.send(
39
+ :define_method,
40
+ method,
41
+ Delegator.delegating_block_with_binding_for_ruby(method)
42
+ )
43
+ else
44
+ klass.send(:define_method, method, Delegator.delegating_block(method))
45
+ end
46
+ end
47
+
48
+ if superclass == String || superclass.ancestors.include?(::String)
49
+ method_name = "=~".to_sym
50
+ klass.send(
51
+ :define_method,
52
+ method_name,
53
+ Delegator.delegating_block_with_binding_for_ruby(method_name)
54
+ )
55
+ end
56
+
57
+ if superclass == Regexp || superclass.ancestors.include?(::Regexp)
58
+ TurboTest::ConstantTracer::Klass::REGEXP_METHODS.each_key do |key|
59
+ klass.send(:remove_method, key) if klass.method_defined?(key)
60
+ klass.send(:define_method, key, Delegator.delegating_block_with_binding_for_ruby(key))
61
+ end
62
+ end
63
+ end
64
+
65
+ klass.define_singleton_method :public_instance_methods do |all = true|
66
+ super(all) | superclass.public_instance_methods
67
+ end
68
+ klass.define_singleton_method :protected_instance_methods do |all = true|
69
+ super(all) | superclass.protected_instance_methods
70
+ end
71
+ klass
72
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "binding_of_caller"
5
+ require "English"
6
+
7
+ # :nocov:
8
+ def Delegator.delegating_block_with_binding_for_ruby(mid)
9
+ if RUBY_VERSION >= "2.7"
10
+ Delegator.delegating_block_with_binding_ruby_27(mid)
11
+ else
12
+ Delegator.delegating_block_with_binding(mid)
13
+ end
14
+ end
15
+
16
+ # rubocop:disable Metrics/MethodLength
17
+ def Delegator.delegating_block_with_binding(mid) # :nodoc:
18
+ lambda do |*args, &block|
19
+ target = __getobj__
20
+ send_block = if block
21
+ proc do |match|
22
+ block_binding = block.binding
23
+ block_binding.local_variable_set(:_turbotest_tilde, $LAST_MATCH_INFO)
24
+ block_binding.eval("$~=_turbotest_tilde")
25
+ block.call(match)
26
+ end
27
+ else
28
+ block
29
+ end
30
+ result = target.__send__(mid, *args, &send_block)
31
+ caller_binding = binding.of_caller(1)
32
+ caller_binding.local_variable_set(:_turbotest_tilde, $LAST_MATCH_INFO)
33
+ caller_binding.eval("$~=_turbotest_tilde")
34
+ result
35
+ end
36
+ end
37
+ # :nocov:
38
+
39
+ def Delegator.delegating_block_with_binding_ruby_27(mid) # :nodoc:
40
+ lambda do |*args, &block|
41
+ target = __getobj__
42
+ send_block = if block
43
+ proc do |match|
44
+ block_binding = block.binding
45
+ block_binding.local_variable_set(:_turbotest_tilde, $LAST_MATCH_INFO)
46
+ block_binding.eval("$~=_turbotest_tilde")
47
+ block.call(match)
48
+ end
49
+ else
50
+ block
51
+ end
52
+ result = target.__send__(mid, *args, &send_block)
53
+ caller_binding = binding.of_caller(1)
54
+ caller_binding.local_variable_set(:_turbotest_tilde, $LAST_MATCH_INFO)
55
+ caller_binding.eval("$~=_turbotest_tilde")
56
+ result
57
+ end.ruby2_keywords
58
+ end
59
+ # rubocop:enable Metrics/MethodLength
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ module TurboTest
6
+ module ConstantTracer
7
+ class EventPublisher
8
+ include Singleton
9
+
10
+ EVENT = "proxy_object_method_call"
11
+
12
+ attr_reader :enabled
13
+
14
+ class << self
15
+ extend Forwardable
16
+ def_delegators :instance,
17
+ :reset_call_log,
18
+ :publish_all_events!,
19
+ :publish_events_once!,
20
+ :publish
21
+
22
+ private
23
+
24
+ def instance
25
+ @instance || Mutex.new.synchronize { @instance ||= new }
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ @call_log = {}
31
+ @log_all_events = false
32
+ end
33
+
34
+ def reset_call_log
35
+ @call_log = {}
36
+ end
37
+
38
+ def publish_all_events!
39
+ @log_all_events = true
40
+ end
41
+
42
+ def publish_events_once!
43
+ @log_all_events = false
44
+ end
45
+
46
+ def publish(name, location)
47
+ return unless @call_log[name].nil? || @log_all_events == true
48
+
49
+ TurboTest::EventRegistry[EVENT].publish(name, location)
50
+ @call_log[name] = true
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./../hash_lookup_with_proxy_ext"
4
+
5
+ module TurboTest
6
+ module ConstantTracer
7
+ module HashLookupWithProxy
8
+ class << self
9
+ attr_reader :enabled
10
+ end
11
+
12
+ def self.enable
13
+ return if enabled
14
+
15
+ Hash.prepend(Methods)
16
+ Methods.enable
17
+ @enabled = true
18
+ end
19
+
20
+ def self.disable
21
+ return unless enabled
22
+
23
+ Methods.disable
24
+ @enabled = false
25
+ end
26
+
27
+ module Methods
28
+ class << self
29
+ def enable
30
+ add_assign_method
31
+ end
32
+
33
+ def disable
34
+ class_eval do
35
+ remove_method :[]=
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "binding_of_caller"
5
+ require_relative "delegator"
6
+ require_relative "delegate_class"
7
+ module TurboTest
8
+ module ConstantTracer
9
+ class Klass
10
+ STRING_METHODS = {
11
+ scan: true, gsub: true, gsub!: true, sub: true, sub!: true, "=~": 1
12
+ }.freeze
13
+
14
+ ENUMERABLE_METHODS = {
15
+ all?: true, any?: true, grep: true, grep_v: true,
16
+ none?: true, one?: true, slice_before: true, slice_after: true
17
+ }.freeze
18
+
19
+ REGEXP_METHODS = {
20
+ match: 1, "=~": 1, "===": 1
21
+ }.freeze
22
+
23
+ def self.define(original_class, name)
24
+ return ::TurboTest::ConstantTracer::Regexp if original_class == ::Regexp
25
+
26
+ klass = Class.new(TurboTestDelegateClass(original_class)) do
27
+ include InstanceMethods
28
+ extend ClassMethods
29
+ end
30
+ klass.turbo_test_proxied_class = original_class
31
+ ProxyKlass.const_set name, klass
32
+ klass
33
+ end
34
+
35
+ module ClassMethods
36
+ attr_accessor :turbo_test_proxied_class
37
+
38
+ def ==(other)
39
+ turbo_test_proxied_class == other
40
+ end
41
+ end
42
+
43
+ module InstanceMethods
44
+ attr_accessor :turbo_test_name, :turbo_test_path
45
+
46
+ def initialize(object)
47
+ super
48
+ check_object_type!(object)
49
+ end
50
+
51
+ def __getobj__
52
+ result = super
53
+ TurboTest::ConstantTracer::EventPublisher.publish(
54
+ turbo_test_name, turbo_test_path
55
+ )
56
+ result
57
+ end
58
+
59
+ def turbo_test_proxied_class
60
+ __getobj__
61
+ end
62
+ alias __turbo_test_proxy_object turbo_test_proxied_class
63
+
64
+ private
65
+
66
+ def check_object_type!(object)
67
+ return if object.class == self.class.turbo_test_proxied_class
68
+
69
+ msg = "Object class is not #{self.class.turbo_test_proxied_class}"
70
+ raise(TypeError, msg)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTest
4
+ module ConstantTracer
5
+ module ProxyKlass
6
+ def self.proxied_objects
7
+ @proxied_objects ||= {}
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "binding_of_caller"
4
+ require "English"
5
+
6
+ module TurboTest
7
+ module ConstantTracer
8
+ class Regexp < TurboTestDelegateClass(::Regexp)
9
+ include ::TurboTest::ConstantTracer::Klass::InstanceMethods
10
+ extend ::TurboTest::ConstantTracer::Klass::ClassMethods
11
+
12
+ def ~
13
+ caller_binding = binding.of_caller(1)
14
+ res = (self =~ caller_binding.eval("$_"))
15
+ caller_binding.local_variable_set(:_turbotest_tilde, $LAST_MATCH_INFO)
16
+ caller_binding.eval("$~=_turbotest_tilde")
17
+ res
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ TurboTest::ConstantTracer::Regexp.turbo_test_proxied_class = ::Regexp
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTestConstantTracer
4
+ VERSION = "0.1.11"
5
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/turbo_test_constant_tracer/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "turbo_test_constant_tracer"
5
+ spec.version = TurboTestConstantTracer::VERSION
6
+ spec.authors = ["Marcos Essindi"]
7
+ spec.email = ["marcessindi@icloud.com"]
8
+
9
+ spec.summary = "Summary"
10
+ spec.homepage = "https://github.com/dunkelbraun/turbo_test_constant_tracer"
11
+ spec.license = "MIT"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
13
+
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+ spec.metadata["source_code_uri"] = spec.homepage
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "rake", "~> 13.0"
27
+ spec.add_development_dependency "minitest", "~> 5.14.1"
28
+ spec.add_development_dependency "rake-compiler"
29
+
30
+ spec.add_dependency "binding_of_caller"
31
+ spec.add_dependency "turbo_test_events"
32
+
33
+ spec.extensions = %w[ext/hash_lookup_with_proxy_ext/extconf.rb]
34
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: turbo_test_constant_tracer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.11
5
+ platform: ruby
6
+ authors:
7
+ - Marcos Essindi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.14.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.14.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: binding_of_caller
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: turbo_test_events
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - marcessindi@icloud.com
86
+ executables: []
87
+ extensions:
88
+ - ext/hash_lookup_with_proxy_ext/extconf.rb
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".github/workflows/tests.yml"
92
+ - ".gitignore"
93
+ - ".rubocop.yml"
94
+ - CODE_OF_CONDUCT.md
95
+ - Gemfile
96
+ - Gemfile.common
97
+ - Gemfile.lock
98
+ - GemfileCI
99
+ - GemfileCI.lock
100
+ - LICENSE.txt
101
+ - Makefile
102
+ - README.md
103
+ - Rakefile
104
+ - bin/console
105
+ - bin/setup
106
+ - ext/hash_lookup_with_proxy_ext/extconf.h
107
+ - ext/hash_lookup_with_proxy_ext/extconf.rb
108
+ - ext/hash_lookup_with_proxy_ext/hash_lookup_with_proxy_ext.c
109
+ - lib/turbo_test_constant_tracer.rb
110
+ - lib/turbo_test_constant_tracer/constructor.rb
111
+ - lib/turbo_test_constant_tracer/definition.rb
112
+ - lib/turbo_test_constant_tracer/definition/templates.rb
113
+ - lib/turbo_test_constant_tracer/delegate_class.rb
114
+ - lib/turbo_test_constant_tracer/delegator.rb
115
+ - lib/turbo_test_constant_tracer/event_publisher.rb
116
+ - lib/turbo_test_constant_tracer/hash_lookup_with_proxy.rb
117
+ - lib/turbo_test_constant_tracer/klass.rb
118
+ - lib/turbo_test_constant_tracer/proxy_klass.rb
119
+ - lib/turbo_test_constant_tracer/regexp/tilde.rb
120
+ - lib/turbo_test_constant_tracer/version.rb
121
+ - turbo_test_constant_tracer.gemspec
122
+ homepage: https://github.com/dunkelbraun/turbo_test_constant_tracer
123
+ licenses:
124
+ - MIT
125
+ metadata:
126
+ homepage_uri: https://github.com/dunkelbraun/turbo_test_constant_tracer
127
+ source_code_uri: https://github.com/dunkelbraun/turbo_test_constant_tracer
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: 2.4.0
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubygems_version: 3.1.2
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Summary
147
+ test_files: []