rshade 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Gemfile +6 -2
  4. data/Gemfile.lock +10 -1
  5. data/README.md +19 -3
  6. data/Rakefile +5 -3
  7. data/bin/console +4 -3
  8. data/lib/rshade/config/registry.rb +47 -0
  9. data/lib/rshade/config/stack_store.rb +58 -0
  10. data/lib/rshade/config/store.rb +14 -5
  11. data/lib/rshade/config.rb +9 -3
  12. data/lib/rshade/core_extensions/object/reveal.rb +34 -5
  13. data/lib/rshade/event.rb +15 -9
  14. data/lib/rshade/event_observer.rb +3 -1
  15. data/lib/rshade/event_processor.rb +14 -12
  16. data/lib/rshade/event_tree.rb +13 -15
  17. data/lib/rshade/filter/abstract_filter.rb +3 -1
  18. data/lib/rshade/filter/default.rb +3 -1
  19. data/lib/rshade/filter/exclude_path_filter.rb +10 -7
  20. data/lib/rshade/filter/filter_builder.rb +14 -3
  21. data/lib/rshade/filter/filter_composition.rb +26 -24
  22. data/lib/rshade/filter/include_path_filter.rb +5 -1
  23. data/lib/rshade/filter/variable_filter.rb +4 -1
  24. data/lib/rshade/formatter/stack/json.rb +51 -0
  25. data/lib/rshade/formatter/stack/stdout.rb +13 -0
  26. data/lib/rshade/formatter/stack/string.rb +41 -0
  27. data/lib/rshade/formatter/trace/file.rb +33 -0
  28. data/lib/rshade/formatter/trace/html.rb +38 -0
  29. data/lib/rshade/formatter/trace/json.rb +61 -0
  30. data/lib/rshade/formatter/trace/stdout.rb +14 -0
  31. data/lib/rshade/formatter/trace/string.rb +48 -0
  32. data/lib/rshade/rspec/rspec.rb +7 -6
  33. data/lib/rshade/serializer/traversal.rb +54 -0
  34. data/lib/rshade/stack.rb +26 -0
  35. data/lib/rshade/stack_frame.rb +60 -0
  36. data/lib/rshade/trace.rb +8 -5
  37. data/lib/rshade/trace_observable.rb +5 -0
  38. data/lib/rshade/version.rb +3 -1
  39. data/lib/rshade.rb +26 -10
  40. data/rshade.gemspec +24 -21
  41. metadata +44 -9
  42. data/lib/rshade/binding_serializer.rb +0 -35
  43. data/lib/rshade/formatter/file.rb +0 -28
  44. data/lib/rshade/formatter/html.rb +0 -33
  45. data/lib/rshade/formatter/json.rb +0 -59
  46. data/lib/rshade/formatter/stdout.rb +0 -10
  47. data/lib/rshade/formatter/string.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5ef0c31c59c3ed46f44326e1e28f6a5b2b2ccbdbce32152e6b54233f875d6d0
4
- data.tar.gz: f394a28db1cda3274954309996eaea895bf715737f34aecbb09c0d0873fd09fb
3
+ metadata.gz: 39758f070ab0a6b6e7dc0bdc09aa03bb107130f84fe7115331189a31c0e013eb
4
+ data.tar.gz: 0331bdd526cd0155df7d210603bb07a15c9541bcce62197b2754731e640060c3
5
5
  SHA512:
6
- metadata.gz: 956a68bec41feea89513eab5e0002fadb70d9d0f9e57f1c47f316d2c30c6e801cb510a80312e54b9d075c4fa7f768ad6b2acc881dc3db03680a9351abe56dda4
7
- data.tar.gz: 4bafb27714ffaf13734f99522897b3057da42f5bf4eb05929b824af9c67f19076f304373ab835f1cf0b0bb3ef5a253a1fd23ec343236596255b64f34290702b3
6
+ metadata.gz: b0c97b53d02f997d05484e850655dfe561c82da1d110a111022885278ece826b5fc75b2e5d70260ff59095ca29178e681c85915301a6b171efe263aa42c82f64
7
+ data.tar.gz: ed9a95bceb71f94cd17587bd88086a6e26d77b5a19fe14ed96b4cfbd559fa1574ffaca380ec3fc49167e788197008bc08b581f83fb5997fb058dedba77e49bf8
data/.gitignore CHANGED
@@ -5,6 +5,7 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
+ /spec/store/
8
9
  /tmp/
9
10
  .idea
10
11
 
@@ -12,4 +13,4 @@
12
13
  .rspec_status
13
14
  .ruby-version
14
15
  .DS_Store
15
- test.rb
16
+ test.rb
data/Gemfile CHANGED
@@ -1,10 +1,14 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in rshade.gemspec
6
8
  gemspec
7
9
 
8
10
  group :development, :test do
11
+ gem 'binding_of_caller'
12
+ gem 'prism'
9
13
  gem 'pry'
10
14
  end
data/Gemfile.lock CHANGED
@@ -1,16 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rshade (0.1.9)
4
+ rshade (0.2.0)
5
+ binding_of_caller
5
6
  colorize
7
+ prism
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
9
11
  specs:
12
+ binding_of_caller (1.0.1)
13
+ debug_inspector (>= 1.2.0)
10
14
  coderay (1.1.3)
11
15
  colorize (0.8.1)
16
+ debug_inspector (1.2.0)
12
17
  diff-lcs (1.5.0)
13
18
  method_source (1.0.0)
19
+ prism (1.3.0)
14
20
  pry (0.14.1)
15
21
  coderay (~> 1.1)
16
22
  method_source (~> 1.0)
@@ -32,9 +38,12 @@ GEM
32
38
  PLATFORMS
33
39
  x86_64-darwin-19
34
40
  x86_64-darwin-20
41
+ x86_64-darwin-22
35
42
 
36
43
  DEPENDENCIES
44
+ binding_of_caller
37
45
  bundler (~> 2.2.33)
46
+ prism
38
47
  pry
39
48
  rake (>= 12.3.3)
40
49
  rshade!
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # RShade
2
-
3
- ![warcraft shade](https://github.com/gingray/rshade/raw/master/shade.jpg)
2
+ <p align="center">
3
+ <img src="https://github.com/gingray/rshade/raw/master/shade.jpg">
4
+ </p>
4
5
 
5
6
  RShade is a debugging/code exploration tool based on `TracePoint` functionality.
6
7
  Recent years I've working with relatively huge legacy code and I need a tool which can help me to figure out what is going on due execution.
@@ -85,7 +86,7 @@ On such huge codebase as spree it's helpful to know what callbacks are triggered
85
86
  context 'when cost currency is nil' do
86
87
  before { variant.cost_currency = nil }
87
88
 
88
- it 'populates cost currency with the default value on save', focus: true do
89
+ it 'populates cost currency with the default value on save' do
89
90
  RShade::Trace.reveal do
90
91
  variant.save!
91
92
  end
@@ -99,6 +100,21 @@ Below is example how output will look like.
99
100
  As you can see all code that have been in use is printed.
100
101
  [![asciicast](https://asciinema.org/a/MR5KL7TmHmYRUhwBUWQjBI373.svg)](https://asciinema.org/a/MR5KL7TmHmYRUhwBUWQjBI373)
101
102
 
103
+ ## Stack reveal
104
+ Config
105
+ ```ruby
106
+ ::RShade::Config::Registry.instance.stack_config do |config|
107
+ config.exclude_gems!
108
+ filepath = File.join(Rails.root, 'log', 'rshade-stack.json.log')
109
+ config.set_formatter(:json, { filepath: filepath, pretty: false })
110
+ end
111
+ ```
112
+
113
+ Execute (put in any place where you want reveal stack)
114
+ ```ruby
115
+ ::RShade::Stack.trace
116
+ ```
117
+
102
118
  ## TODO
103
119
  Use stack to keep connections between current method and caller
104
120
  take a look on https://github.com/matugm/visual-call-graph
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "rshade"
4
+ require 'bundler/setup'
5
+ require 'rshade'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "rshade"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RShade
4
+ class Config
5
+ class Registry
6
+ attr_reader :map, :mutex
7
+
8
+ include Singleton
9
+
10
+ def initialize
11
+ @map = {}
12
+ @mutex = Mutex.new
13
+ defaults
14
+ end
15
+
16
+ def set_default_stack(config)
17
+ mutex.synchronize do
18
+ map[:store_default] = config
19
+ end
20
+ end
21
+
22
+ def default_stack_config
23
+ val = nil
24
+ mutex.synchronize do
25
+ val = map[:store_default]
26
+ end
27
+ val
28
+ end
29
+
30
+ def stack_config(&block)
31
+ val = nil
32
+ mutex.synchronize do
33
+ val = ::RShade::Config::StackStore.new
34
+ block.call(val)
35
+ map[:store_default] = val
36
+ end
37
+ val
38
+ end
39
+
40
+ def defaults
41
+ mutex.synchronize do
42
+ map[:store_default] = ::RShade::Config::StackStore.new
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RShade
4
+ class Config
5
+ class StackStore
6
+ attr_reader :filter, :formatter, :custom_serializers
7
+
8
+ DEFAULT_FORMATTER = {
9
+ json: ::RShade::Formatter::Stack::Json
10
+ }.freeze
11
+
12
+ # @param [Hash] options
13
+ # @option options [::RShade::Filter::FilterComposition] :filter_composition
14
+ # @option options [#call(event_store)] :formatter
15
+ def initialize(options = {})
16
+ @filter = options.fetch(:filter, default_filter_composition)
17
+ @formatter = options.fetch(:formatter, ::RShade::Formatter::Stack::Stdout.new)
18
+ @custom_serializers = options.fetch(:custom_serializers, {})
19
+ end
20
+
21
+ def add_custom_serializers(hash)
22
+ custom_serializers.merge!(hash)
23
+ self
24
+ end
25
+
26
+ def config_filter(filter_type, &block)
27
+ filter.config_filter(filter_type, &block)
28
+ self
29
+ end
30
+
31
+ def set_formatter(formatter, opts = {})
32
+ @formatter = formatter.is_a?(Symbol) ? set_symbol_formatter(formatter, opts) : formatter
33
+ self
34
+ end
35
+
36
+ def exclude_gems!
37
+ config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
38
+ paths.concat(RShade::Config.default_excluded_path)
39
+ end
40
+ self
41
+ end
42
+
43
+ private
44
+
45
+ def set_symbol_formatter(type, opts)
46
+ formatter_class = DEFAULT_FORMATTER[type]
47
+ return formatter_class unless formatter_class
48
+
49
+ @formatter = formatter_class.new(**opts)
50
+ end
51
+
52
+ def default_filter_composition
53
+ RShade::Filter::FilterBuilder.build([:or,
54
+ [:or, RShade::Filter::VariableFilter.new, RShade::Filter::IncludePathFilter.new], RShade::Filter::ExcludePathFilter.new])
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,21 +1,29 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module RShade
3
4
  class Config
4
5
  class Store
5
- attr_reader :filter_composition, :formatter, :tp_events
6
+ attr_reader :filter_composition, :formatter, :tp_events, :custom_serializers
6
7
 
7
8
  # @param [Hash] options
8
9
  # @option options [RShade::Filter::FilterComposition] :filter_composition
9
10
  # @option options [#call(event_store)] :formatter
10
11
  # @option options [Array<Symbol>] :tp_events
11
- def initialize(options={})
12
+ def initialize(options = {})
12
13
  @filter_composition = options.fetch(:filter_composition, default_filter_composition)
13
- @formatter = options.fetch(:formatter, ::RShade::Formatter::Stdout)
14
- @tp_events = options.fetch(:tp_events, [:call, :return])
14
+ @formatter = options.fetch(:formatter, ::RShade::Formatter::Trace::Stdout)
15
+ @tp_events = options.fetch(:tp_events, %i[call return])
16
+ @custom_serializers = options.fetch(:custom_serializers, {})
15
17
  end
16
18
 
17
19
  def set_tp_events(tp_events)
18
20
  @tp_events = tp_events
21
+ self
22
+ end
23
+
24
+ def add_custom_serializers(hash)
25
+ custom_serializers.merge!(hash)
26
+ self
19
27
  end
20
28
 
21
29
  def config_filter(filter_type, &block)
@@ -31,7 +39,8 @@ module RShade
31
39
  private
32
40
 
33
41
  def default_filter_composition
34
- RShade::Filter::FilterBuilder.build([:or,[:or, RShade::Filter::VariableFilter.new, RShade::Filter::IncludePathFilter.new] , RShade::Filter::ExcludePathFilter.new])
42
+ RShade::Filter::FilterBuilder.build([:or,
43
+ [:or, RShade::Filter::VariableFilter.new, RShade::Filter::IncludePathFilter.new], RShade::Filter::ExcludePathFilter.new])
35
44
  end
36
45
  end
37
46
  end
data/lib/rshade/config.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  class Config
3
5
  RUBY_VERSION_PATTERN = /ruby-[0-9.]*/
4
6
 
5
7
  def self.default
6
- ::RShade::Config::Store.new.set_formatter(::RShade::Formatter::Stdout.new)
8
+ ::RShade::Config::Store.new.set_formatter(::RShade::Formatter::Trace::Stdout.new)
7
9
  .config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
8
10
  default_excluded_path.each do |path|
9
11
  paths << path
@@ -20,7 +22,7 @@ module RShade
20
22
  # @option options [RShade::Filter::FilterComposition] :filter_composition
21
23
  # @option options [#call(event_store)] :formatter
22
24
  # @option options [Array<Symbol>] :tp_events
23
- def self.create(options={})
25
+ def self.create(options = {})
24
26
  new(Config::Store.new(options))
25
27
  end
26
28
 
@@ -51,6 +53,11 @@ module RShade
51
53
  self
52
54
  end
53
55
 
56
+ def add_custom_serializers(hash)
57
+ @config_store.add_custom_serializers(hash)
58
+ self
59
+ end
60
+
54
61
  def value
55
62
  @config_store
56
63
  end
@@ -63,7 +70,6 @@ module RShade
63
70
  @root_dir ||= File.expand_path('../../', __dir__)
64
71
  end
65
72
 
66
- private
67
73
  def self.default_excluded_path
68
74
  [ENV['GEM_PATH'].split(':'), RUBY_VERSION_PATTERN, /internal/].flatten.compact
69
75
  end
@@ -1,8 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
- def reveal(&block)
3
- trace = ::RShade::Trace.reveal do
4
- block.call
4
+ def reveal(method_name = nil, **opts, &block)
5
+ if method_name
6
+ @__cache_rshade_reveal ||= {}
7
+ config = opts.fetch(:config, ::RShade::Config.default)
8
+ @__cache_rshade_reveal[method_name] = config
9
+ instance_eval do
10
+ def method_added(name)
11
+ return unless @__cache_rshade_reveal[name]
12
+
13
+ if @__reveal_rewrite
14
+ @__reveal_rewrite = false
15
+ return
16
+ end
17
+ @__reveal_rewrite = true
18
+ config = @__cache_rshade_reveal[name]
19
+ origin_method = instance_method(name)
20
+ define_method(name) do |*args, &fn|
21
+ val = nil
22
+ trace = ::RShade::Trace.reveal(config) do
23
+ val = origin_method.bind(self).call(*args, &fn)
24
+ end
25
+ trace.show
26
+ val
27
+ end
28
+ end
29
+ end
30
+ else
31
+ trace = ::RShade::Trace.reveal do
32
+ block.call if block_given?
33
+ end
34
+ trace.show
5
35
  end
6
- trace.show
7
36
  end
8
- end
37
+ end
data/lib/rshade/event.rb CHANGED
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  # nodoc
3
5
  class Event
4
6
  attr_reader :hash, :skipped
5
- RETURN_EVENTS = [:return, :b_return, :c_return]
6
7
 
8
+ RETURN_EVENTS = %i[return b_return c_return].freeze
7
9
 
8
10
  def initialize(hash)
9
11
  @hash = hash
10
12
  end
11
13
 
12
- [:klass, :path, :lineno, :method_name, :vars, :level, :return_value].each do |method_name|
14
+ %i[klass path lineno method_name vars level return_value].each do |method_name|
13
15
  define_method method_name do
14
16
  fetch method_name
15
17
  end
@@ -38,17 +40,21 @@ module RShade
38
40
  def self.from_trace_point(evt)
39
41
  vars = {}
40
42
  evt.binding.local_variables.each do |var_name|
41
- vars[var_name] = evt.binding.local_variable_get var_name
43
+ local_val = evt.binding.local_variable_get(var_name)
44
+ local_val_type = local_val.is_a?(Class) ? local_val : local_val.class
45
+ hash = { name: var_name, value: local_val, type: local_val_type }
46
+ vars[var_name] = hash
42
47
  end
43
48
 
44
- hash = { path: evt.path, lineno: evt.lineno, klass: evt.defined_class, method_name: evt.method_id, vars: vars,
49
+ hash = { path: evt.path, lineno: evt.lineno, klass: evt.defined_class, method_name: evt.method_id, vars:,
45
50
  event_type: evt.event }
46
- hash.merge!({return_value: evt.return_value}) if RETURN_EVENTS.include?(evt.event)
47
- new(hash)
48
- end
49
51
 
50
- def self.create_blank(level)
51
- new({level: level}, true)
52
+ if RETURN_EVENTS.include?(evt.event)
53
+ ret_val = evt.return_value
54
+ ret_val_type = evt.return_value.is_a?(Class) ? evt.return_value : evt.return_value.class
55
+ hash.merge!({ return_value: { value: ret_val, type: ret_val_type } })
56
+ end
57
+ new(hash)
52
58
  end
53
59
 
54
60
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  class EventObserver
3
5
  attr_reader :event_processor, :config
@@ -42,4 +44,4 @@ module RShade
42
44
  config.filter_composition.call(event)
43
45
  end
44
46
  end
45
- end
47
+ end
@@ -1,35 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  # nodoc
3
5
  class EventProcessor
4
- attr_reader :store
6
+ attr_reader :store, :serializer
5
7
 
6
- def initialize(store)
8
+ def initialize(store, config)
7
9
  @store = store
8
- @var_serializer = BindingSerializer.new
10
+ custom_serializers = config.custom_serializers
11
+ @serializer = ::RShade::Serializer::Traversal.new(custom_serializers)
9
12
  end
10
13
 
11
14
  # @param [RShade::Event] event
12
15
  # @param [Integer] level
13
16
  def enter(event, level)
14
- event.with_serialized_vars!(@var_serializer).with_level!(level)
17
+ event.with_serialized_vars!(serializer).with_level!(level)
15
18
  store.add(event, level)
16
19
  end
17
20
 
18
21
  # @param [RShade::Event] event
19
22
  # @param [Integer] level
20
- def leave(event, level)
23
+ def leave(event, _level)
21
24
  store.current! do |node|
22
- node.value.set_return_value!(event.return_value)
23
- .with_serialized_return!(->(value) { value.inspect })
25
+ node.value.set_return_value!(event.return_value)
26
+ .with_serialized_return!(serializer)
24
27
  end
25
- rescue => e
28
+ rescue StandardError
26
29
  # this rescue here due this issue which reproduce in ruby-2.6.6 at least
27
30
  # https://bugs.ruby-lang.org/issues/18060
28
31
  end
32
+
29
33
  # @param [RShade::Event] event
30
34
  # @param [Integer] level
31
- def other(event, level)
32
-
33
- end
35
+ def other(event, level); end
34
36
  end
35
- end
37
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  class EventTree
3
5
  include Enumerable
@@ -16,21 +18,17 @@ module RShade
16
18
  if current.level + 1 < level
17
19
 
18
20
  last = current.children.last
19
- unless last
20
- current.children << EventTreeNode.new(nil, current.level + 1 , current)
21
- end
21
+ current.children << EventTreeNode.new(nil, current.level + 1, current) unless last
22
22
  @current = current.children.last
23
23
  add(value, level)
24
24
  return
25
25
  end
26
26
 
27
- if current.level + 1 > level
28
- unless current.parent
29
- return
30
- end
31
- @current = current.parent
32
- add(value, level)
33
- end
27
+ return unless current.level + 1 > level
28
+ return unless current.parent
29
+
30
+ @current = current.parent
31
+ add(value, level)
34
32
  end
35
33
 
36
34
  def current!(&block)
@@ -47,7 +45,7 @@ module RShade
47
45
  attr_reader :children, :level, :vlevel, :value
48
46
  attr_accessor :parent
49
47
 
50
- def initialize(value, level, parent=nil)
48
+ def initialize(value, level, parent = nil)
51
49
  @children = []
52
50
  @level = level
53
51
  @parent = parent
@@ -56,20 +54,20 @@ module RShade
56
54
  end
57
55
 
58
56
  def each(&block)
59
- block.call(self) if parent != nil || value != nil
57
+ block.call(self) if !parent.nil? || !value.nil?
60
58
  children.each { |item| item.each(&block) }
61
59
  end
62
60
 
63
61
  private
64
62
 
65
63
  def set_vlevel(node)
66
- return 0 if node == nil
64
+ return 0 if node.nil?
67
65
 
68
- if node.value || node.level == 0
66
+ if node.value || node.level.zero?
69
67
  node.vlevel + 1
70
68
  else
71
69
  set_vlevel(node.parent)
72
70
  end
73
71
  end
74
72
  end
75
- end
73
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  module Filter
3
5
  class AbstractFilter
@@ -23,4 +25,4 @@ module RShade
23
25
  end
24
26
  end
25
27
  end
26
- end
28
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  module Filter
3
5
  class Default
@@ -25,4 +27,4 @@ module RShade
25
27
  end
26
28
  end
27
29
  end
28
- end
30
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  module Filter
3
5
  class ExcludePathFilter < IncludePathFilter
@@ -11,14 +13,15 @@ module RShade
11
13
  0
12
14
  end
13
15
 
14
- private
15
- def str?(str, event_path)
16
- !event_path.include?(str)
17
- end
16
+ def call(event)
17
+ event_path = event.path
18
+ paths.none? do |path|
19
+ next str?(path, event_path) if path.is_a? String
20
+ next regexp?(path, event_path) if path.is_a? Regexp
18
21
 
19
- def regexp?(regex, event_path)
20
- !regex.match?(event_path)
22
+ false
23
+ end
21
24
  end
22
25
  end
23
26
  end
24
- end
27
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  module Filter
3
5
  class FilterBuilder
@@ -18,11 +20,20 @@ module RShade
18
20
  arg1 = arr[1]
19
21
  arg2 = nil
20
22
  arg2 = arr[2] if arity == 2
21
- arg1 = traverse(arg1) if arg1.is_a?(Array)
22
- arg2 = traverse(arg2) if arg2.is_a?(Array)
23
+ arg1 = if arg1.is_a?(Array)
24
+ traverse(arg1)
25
+ else
26
+ RShade::Filter::FilterComposition.new(arg1)
27
+ end
28
+
29
+ arg2 = if arg2.is_a?(Array)
30
+ traverse(arg2)
31
+ else
32
+ RShade::Filter::FilterComposition.new(arg2)
33
+ end
23
34
 
24
35
  RShade::Filter::FilterComposition.new(op, arg1, arg2)
25
36
  end
26
37
  end
27
38
  end
28
- end
39
+ end