source_route 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a900afbf3890bf31f01041e72ac6a65f61f3a477
4
- data.tar.gz: 85e3915fb47c64ac5cbbe9312c2435a4720758f2
3
+ metadata.gz: c2fa5c78d22ad8c809c220b45e5d7940fdbe9f84
4
+ data.tar.gz: f9ff7bcf3f5cb8e116b3dc0023a677aa2e434677
5
5
  SHA512:
6
- metadata.gz: 91e0b7a0a43e00dddf0d1b8f278324c197f9d62179c066d490c8049913c7eb19e32bb500966938ae2914a5b76541caa77e84508da96b9454dd5a667bcfdeb8ec
7
- data.tar.gz: bdc789e2660545ec2b6c0aaac975d2b276bbaf618d4414d46a944fafe383eccd8e9ba1cf38b92a6564541d4ff69e2ce246f3a00da3047cf499f63d695db470b7
6
+ metadata.gz: d13bafaf3a17ffdc98aeb9491d2cf15c3f05dc140bacc769f4a82a45fbd5143df729b0e1097e63a3939a0330f388ac01d4da1c6fcd6a6a5c06c79d9d57a26286
7
+ data.tar.gz: 2d4c883291edd2c76e33ae293a99e4046b066fbd3b5194f69ef2fae2504cc685adc0ee786d4dea71f3abc93d9e09c4cf327edd109ac6e1158adfb277fd0dd623
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SourceRoute
2
2
 
3
- Wrapper of TracePoint
3
+ Trace ruby code
4
4
 
5
5
  ## Dependency
6
6
 
@@ -40,6 +40,7 @@ you will get a different trace file.
40
40
  SourceRoute.enable do
41
41
  method_id :wanted_method_name
42
42
  full_feature
43
+ filename 'tmp/capture_wanted.html'
43
44
  end
44
45
  .... # here is your code
45
46
  ....
@@ -5,7 +5,7 @@ require 'source_route'
5
5
  SourceRoute.enable do
6
6
  method_id 'base_decorate', 'prepare_decorate'
7
7
  defined_class 'ActiveSupport::Callbacks', 'House', 'Filters'
8
- result_config.filename = 'trace_callback.html'
8
+ filename = 'trace_callback.html'
9
9
  full_feature 10
10
10
  end
11
11
 
data/lib/source_route.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'ostruct'
2
- require 'logger'
3
2
  require 'singleton'
4
3
  require 'forwardable'
5
4
  require 'oj'
@@ -7,7 +6,8 @@ require 'awesome_print'
7
6
 
8
7
  require "source_route/core_ext"
9
8
  require "source_route/version"
10
- require "source_route/wrapper"
9
+ require "source_route/config"
10
+ require "source_route/proxy"
11
11
  require "source_route/jsonify"
12
12
  require "source_route/generate_result"
13
13
  require "source_route/tp_result"
@@ -18,7 +18,7 @@ require 'source_route/json_overrides/activerecord_associations_association'
18
18
  begin
19
19
  if Rails
20
20
  ActiveSupport.on_load(:after_initialize, yield: true) do
21
- # make it respond to to_s. IN rails source, almost all of its methods are removed, including to_s.
21
+ # make it respond to to_s. In rails source, almost all of its methods are removed, including to_s.
22
22
  module ActiveSupport
23
23
  class OptionMerger
24
24
  def to_s
@@ -35,51 +35,38 @@ end
35
35
  module SourceRoute
36
36
  extend self
37
37
 
38
- def wrapper
39
- @@wrapper ||= Wrapper.instance
38
+ def proxy
39
+ @@proxy ||= Proxy.instance
40
40
  end
41
41
 
42
42
  def reset
43
- wrapper.reset
43
+ proxy.reset
44
44
  end
45
45
 
46
46
  def disable
47
- wrapper.tp.disable
47
+ proxy.tp.disable
48
48
  end
49
49
 
50
50
  def enable(match = nil, &block)
51
- wrapper.reset
51
+ proxy.reset
52
52
 
53
- if match
54
- wrapper.condition.method_id(match)
55
- wrapper.condition.defined_class(match)
56
- end
57
-
58
- wrapper.condition.instance_eval(&block) if block_given?
53
+ proxy.config = BlockConfigParser.new.run(match, &block)
59
54
 
60
- wrapper.trace
55
+ proxy.trace
61
56
  end
62
57
 
63
58
  def trace(opt, &block)
64
- opt[:output_format] ||= :test
65
- wrapper.reset
66
- opt.each do |k, v|
67
- wrapper.condition.send(k, v)
68
- end
69
-
70
- wrapper.trace
59
+ proxy.reset
60
+ proxy.config = ParamsConfigParser.run(opt)
61
+ proxy.trace
71
62
  yield
72
- wrapper.tp.disable
73
- SourceRoute.output_html if opt[:output_format].to_sym == :html
63
+ proxy.tp.disable
64
+ SourceRoute.output_html if proxy.config.output_format == :html
74
65
  end
75
66
 
76
67
  def output_html
77
68
  SourceRoute.disable
78
- SourceRoute::Formats::Html.slim_render(wrapper)
79
- end
80
-
81
- # Not implement yet
82
- class Logger < Logger
69
+ SourceRoute::Formats::Html.slim_render(proxy)
83
70
  end
84
71
 
85
72
  module Formats
@@ -0,0 +1,123 @@
1
+ module SourceRoute
2
+ TP_FILTER = [:defined_class, :method_id, :path, :lineno].freeze
3
+ TP_FILTER_METHODS = (TP_FILTER + TP_FILTER.map { |tpf| "#{tpf}_not".to_sym }).freeze
4
+
5
+ class Config
6
+
7
+ DIRECT_ATTRS = [:event, :full_feature, :debug,
8
+ :output_format, :show_additional_attrs,
9
+ :filename, :include_local_var, :include_instance_var,
10
+ :import_return_to_call
11
+ ]
12
+
13
+ attr_accessor *DIRECT_ATTRS
14
+ attr_accessor :negatives, :positives
15
+
16
+ def initialize
17
+ @event = [:call]
18
+ @output_format = :test
19
+ @positives = {}
20
+ @negatives = {}
21
+ end
22
+
23
+ # mutable method
24
+ def formulize
25
+ symbolize_output_format
26
+ event_becomes_array
27
+ self
28
+ end
29
+
30
+ def symbolize_output_format
31
+ self.output_format = output_format.to_sym if output_format.respond_to? :to_sym
32
+ end
33
+
34
+ def event_becomes_array
35
+ self.event = Array(event).map(&:to_sym)
36
+ end
37
+
38
+ def has_call_and_return_event
39
+ event.include? :return and event.include? :call
40
+ end
41
+ end # END Config
42
+
43
+ class BlockConfigParser
44
+ attr_accessor :ret_params
45
+
46
+ def initialize
47
+ @ret_params = {}
48
+ end
49
+
50
+ def run(match_str = nil, &block)
51
+ unless match_str.nil?
52
+ ret_params[:defined_class] = match_str
53
+ ret_params[:method_id] = match_str
54
+ end
55
+ instance_eval(&block) if block_given?
56
+ ParamsConfigParser.run(@ret_params)
57
+ end
58
+
59
+ Config::DIRECT_ATTRS.each do |attr|
60
+ define_method attr do |v=true|
61
+ ret_params[attr] = v
62
+ end
63
+ end
64
+
65
+ # override
66
+ [:event, :show_additional_attrs].each do |attr|
67
+ define_method attr do |*v|
68
+ ret_params[attr] = v unless v == []
69
+ end
70
+ end
71
+
72
+ # override
73
+ def output_format(data = nil, &block)
74
+ ret_params[:output_format] = block_given? ? block : data
75
+ end
76
+
77
+ TP_FILTER_METHODS.each do |m|
78
+ define_method m do |*v|
79
+ ret_params[m] = v
80
+ end
81
+ end
82
+
83
+ end # END BlockConfigParser
84
+
85
+ module ParamsConfigParser
86
+ extend self
87
+
88
+ TP_FILTER.each do |m|
89
+ define_method m do |v|
90
+ @config.positives[m] = Array(v).flatten.map(&:to_s).join('|')
91
+ end
92
+
93
+ define_method "#{m}_not" do |*v|
94
+ @config.negatives[m] = Array(v).flatten.map(&:to_s).join('|')
95
+ end
96
+ end
97
+
98
+ def run(params)
99
+ @config = Config.new
100
+ params.each do |k, v|
101
+ @config.send("#{k}=", v) if Config::DIRECT_ATTRS.include? k.to_sym
102
+ send(k, v) if (TP_FILTER_METHODS + [:full_feature]).include? k.to_sym
103
+ end
104
+ @config.formulize
105
+ end
106
+
107
+ # todo. value equal 10 may not be a good params
108
+ def full_feature(value=true)
109
+ return unless value
110
+ @config.formulize
111
+ @config.event = (@config.event + [:call, :return]).uniq
112
+ @config.import_return_to_call = true
113
+ @config.show_additional_attrs = [:path, :lineno]
114
+ # JSON serialize trigger many problems when handle complicated object(in rails?)
115
+ # a Back Door to open more data. but be care it could trigger weird crash when Jsonify these vars
116
+ if value == 10
117
+ @config.include_instance_var = true
118
+ @config.include_local_var = true
119
+ end
120
+ end
121
+ end # END ParamsConfigParser
122
+
123
+ end
@@ -5,19 +5,19 @@ module SourceRoute
5
5
  module Formats
6
6
  module Html
7
7
 
8
- def self.slim_render(wrapper)
9
- result_config = wrapper.condition.result_config
8
+ def self.slim_render(proxy)
9
+
10
10
  template_path = File.expand_path "../html_semantic.slim", __FILE__
11
11
  slim_template = Slim::Template.new(template_path, pretty: true)
12
12
 
13
- filename = result_config[:filename] || "#{Time.now.strftime('%H')}-source-route.html"
13
+ filename = proxy.config.filename || "#{Time.now.strftime('%H')}-source-route.html"
14
14
 
15
- if result_config.import_return_to_call and wrapper.condition.has_call_and_return_event
16
- wrapper.result_builder.import_return_value_to_call_chain
17
- wrapper.result_builder.treeize_call_chain
15
+ if proxy.config.import_return_to_call and proxy.config.has_call_and_return_event
16
+ proxy.result_builder.import_return_value_to_call_chain
17
+ proxy.result_builder.treeize_call_chain
18
18
  end
19
19
  # TODO: any exception triggered in render method will be absorb totally, how to fix it?
20
- html_output_str = slim_template.render(wrapper.result_builder)
20
+ html_output_str = slim_template.render(proxy.result_builder)
21
21
  File.open(filename, 'w') do |f|
22
22
  f << html_output_str
23
23
  end
@@ -4,12 +4,12 @@ html
4
4
  title Source Route Result
5
5
  link rel="stylesheet" href="https://cdn.rawgit.com/Urigo/angular-spinkit/master/build/angular-spinkit.min.css"
6
6
  link rel="stylesheet" href="https://cdn.rawgit.com/mohsen1/json-formatter/master/dist/json-formatter.css"
7
- link rel="stylesheet" href="http://oss.maxcdn.com/semantic-ui/2.0.7/semantic.min.css"
7
+ link rel="stylesheet" href="http://oss.maxcdn.com/semantic-ui/2.1.4/semantic.min.css"
8
8
 
9
9
  script async=true src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.js"
10
10
  script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"
11
- script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"
12
- script async=true src="http://oss.maxcdn.com/semantic-ui/2.0.7/semantic.min.js"
11
+ script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"
12
+ script async=true src="http://oss.maxcdn.com/semantic-ui/2.1.4/semantic.min.js"
13
13
 
14
14
  css:
15
15
  .call-level-0 {}
@@ -42,7 +42,7 @@ html
42
42
  .right.menu
43
43
  .item
44
44
  span Trace Count
45
- .ui.teal.pointing.left.label(ng-bind="currentCounter()")
45
+ .ui.teal.left.pointing.label(ng-bind="currentCounter()")
46
46
 
47
47
  .ui.container
48
48
  .row
@@ -57,11 +57,11 @@ html
57
57
  / workaround for return_value is 'false' and return_value always to be string when existed
58
58
  .meta(ng-if="trace.hasOwnProperty('return_value')")
59
59
  i.icon.pointing.right.small
60
- json-formatter(open="1" json="::trace.return_value")
60
+ json-formatter(open="1" json="::trace.return_value" style="display: inline-block")
61
61
  .description
62
62
  .ui.vertical.buttons.basic
63
63
  button.ui.labeled.icon.button(ng-show="::containsDetail(trace)" ng-click="showMoreDetail = !showMoreDetail")
64
- i.info.icon
64
+ i.browser.icon
65
65
  span Details
66
66
  button.ui.labeled.icon.button(ng-if="::hasChild()" ng-click="toggleChild()" ng-class="{loading: togglingChild}")
67
67
  i.icon.angle.down(ng-show="trace.childOpened")
@@ -71,20 +71,20 @@ html
71
71
 
72
72
  .details.right.floated(ng-if="showMoreDetail")
73
73
  .ui.segments(style="border-color: blue")
74
+ .ui.segment(ng-if="::trace.params_var")
75
+ .ui.teal.right.ribbon.label Parameters
76
+ json-formatter(open="1" json="::trace.params_var")
74
77
  .ui.segment(ng-if="::trace.hasOwnProperty('return_value')")
75
78
  .ui.grey.right.ribbon.label Return Value
76
79
  json-formatter(json="::trace.return_value")
77
80
  .ui.segment(ng-if="::containsOtherAttrs(trace)")
78
- .ui.orange.right.ribbon.label Trace Attrs
81
+ .ui.orange.right.ribbon.label Trace Attributes
79
82
  json-formatter(open="1" json="::plusTraceAttrs[trace.order_id]")
80
- .ui.segment(ng-if="::trace.params_var")
81
- .ui.teal.right.ribbon.label Params Var
82
- json-formatter(open="1" json="::trace.params_var")
83
83
  .ui.segment(ng-if="::trace.local_var")
84
- .ui.teal.right.ribbon.label Local Var
84
+ .ui.teal.right.ribbon.label Local Variables
85
85
  json-formatter(open="1" json="::trace.local_var")
86
86
  .ui.segment(ng-if="::trace.instance_var")
87
- .ui.blue.right.ribbon.label Instance Var
87
+ .ui.blue.right.ribbon.label Instance Variables
88
88
  json-formatter(open="1" json="::trace.instance_var")
89
89
 
90
90
  script src="https://cdn.rawgit.com/Urigo/angular-spinkit/master/build/angular-spinkit.min.js"
@@ -11,16 +11,7 @@ module SourceRoute
11
11
  attr_reader :tp_result_chain, :tp_self_caches, :collected_data
12
12
 
13
13
  extend Forwardable
14
-
15
- def_delegators :@tp_result_chain, :import_return_value_to_call_chain, :treeize_call_chain, :call_chain, :return_chain, :parent_length_list
16
-
17
- Config = Struct.new(:format, :show_additional_attrs,
18
- :include_local_var, :include_instance_var,
19
- :filename, :import_return_to_call) do
20
- def initialize(f=:test, s=[], ilr=false, iiv=false)
21
- super(f, s, ilr, iiv)
22
- end
23
- end
14
+ def_delegators :@tp_result_chain, :import_return_value_to_call_chain, :treeize_call_chain
24
15
 
25
16
  # see event description in TracePoint API Doc
26
17
  DEFAULT_ATTRS = {
@@ -39,22 +30,17 @@ module SourceRoute
39
30
  thread_end: [:defined_class, :method_id]
40
31
  }
41
32
 
42
- def initialize(wrapper)
43
- @wrapper = wrapper
44
-
45
- @config = @wrapper.condition.result_config
46
-
33
+ def initialize(proxy)
34
+ @proxy = proxy
47
35
  @tp_result_chain = TpResultChain.new
48
-
49
36
  @tp_self_caches = []
50
- @wanted_attributes = {}
51
37
  end
52
38
 
53
39
  # it cached and only calculate once for one trace point block round
54
40
  def self.wanted_attributes(eve)
55
41
  event = eve.to_sym
56
42
  @wanted_attributes.fetch event do
57
- attrs = DEFAULT_ATTRS[event] + Array(SourceRoute.wrapper.condition.result_config.show_additional_attrs)
43
+ attrs = DEFAULT_ATTRS[event] + Array(SourceRoute.proxy.config.show_additional_attrs)
58
44
  attrs.push(:event)
59
45
  @wanted_attributes[event] = attrs.uniq
60
46
  @wanted_attributes[event]
@@ -66,21 +52,18 @@ module SourceRoute
66
52
  end
67
53
 
68
54
  def output(tp_ins)
69
- format = @config.format
70
- format = format.to_sym if format.respond_to? :to_sym
55
+ format = @proxy.config.output_format
71
56
 
72
57
  assign_tp_self_caches(tp_ins)
73
58
  # we cant call method on tp_ins outside of track block,
74
59
  # so we have to run it immediately
75
-
76
60
  @collected_data = TpResult.new(tp_ins)
77
-
78
61
  case format
79
62
  when :console
80
63
  console_put(tp_ins)
81
64
  when :html
82
- # we cant generate html right now becase the tp collection is still in process
83
- # so we collect tp here
65
+ # we cant generate html right now becase the tp callback is still in process
66
+ # so we gather data into array
84
67
  @tp_result_chain.push(TpResult.new(tp_ins))
85
68
  when :silence, :none
86
69
  # do nothing at now
@@ -92,26 +75,10 @@ module SourceRoute
92
75
  format.call(tp_ins)
93
76
  else
94
77
  klass = "SourceRoute::Formats::#{format.to_s.capitalize}"
95
- ::SourceRoute.const_get(klass).render(self, tp_ins)
78
+ ::SourceRoute.const_get(klass).render(self, tp_ins, @collected_data)
96
79
  end
97
80
  end
98
81
 
99
- # def build(trace_point_instance)
100
- # TpResult.new(trace_point_instance)
101
- # # tp_result.collect_self
102
-
103
- # # @tp = trace_point_instance
104
- # # collect_tp_data
105
- # # collect_tp_self # NEED more check. Does TracePoint support self for all events?
106
- # # collect_local_var_data if @config[:include_local_var]
107
- # # collect_instance_var_data if @config[:include_instance_var]
108
- # # @collected_data
109
- # end
110
-
111
- # def collect_tp_result
112
- # tp_result = TpResult.new(tp)
113
- # end
114
-
115
82
  # include? will evaluate @tp.self, if @tp.self is AR::Relation, it could cause problems
116
83
  # So that's why I use object_id as replace
117
84
  def assign_tp_self_caches(tp_ins)
@@ -121,7 +88,7 @@ module SourceRoute
121
88
  end
122
89
 
123
90
  def jsonify_events
124
- Oj.dump(@wrapper.condition.events.map(&:to_s))
91
+ Oj.dump(@proxy.config.event.map(&:to_s))
125
92
  end
126
93
 
127
94
  def jsonify_tp_result_chain
@@ -138,44 +105,6 @@ module SourceRoute
138
105
 
139
106
  private
140
107
 
141
- # def collect_tp_data
142
- # tp_data = wanted_attributes(@tp.event).inject({}) do |memo, key|
143
- # memo[key.to_sym] = @tp.send(key) if @tp.respond_to?(key)
144
- # memo
145
- # end
146
- # @collected_data = TpResult.new(tp_data)
147
- # puts @collected_data.inspect if @wrapper.condition.is_debug?
148
- # end
149
-
150
- # def collect_tp_self(tp)
151
- # unless tp_self_caches.find { |tp_cache| tp_cache.object_id.equal? tp.self.object_id }
152
- # tp_self_caches.push tp.self
153
- # end
154
- # @collected_data[:tp_self_refer] = tp_self_caches.map(&:__id__).index(tp.self.__id__)
155
- # end
156
-
157
- # def collect_local_var_data
158
- # local_var_hash = {}
159
- # # Warn: @tp.binding.eval('local_variables') =! @tp.binding.send('local_variables')
160
- # @tp.binding.eval('local_variables').each do |v|
161
- # # I need rememeber why i need source_route_display
162
- # local_var_hash[v] = @tp.binding.local_variable_get(v).source_route_display
163
- # end
164
- # if local_var_hash != {}
165
- # @collected_data.merge!(local_var: local_var_hash)
166
- # end
167
- # end
168
-
169
- # def collect_instance_var_data
170
- # instance_var_hash = {}
171
- # @tp.self.instance_variables.each do |key|
172
- # instance_var_hash[key] = @tp.self.instance_variable_get(key).source_route_display
173
- # end
174
- # if instance_var_hash != {}
175
- # @collected_data.merge!(instance_var: instance_var_hash)
176
- # end
177
- # end
178
-
179
108
  def console_put(tp)
180
109
  ret = []
181
110
  ret << "#{collected_data.defined_class.inspect}##{collected_data.method_id}"
@@ -0,0 +1,36 @@
1
+ module SourceRoute
2
+
3
+ class Proxy # todo Rename it to Proxy
4
+ include Singleton
5
+
6
+ attr_accessor :config, :tp, :result_builder
7
+
8
+ def initialize
9
+ reset
10
+ end
11
+
12
+ def reset
13
+ @tp.disable if defined? @tp
14
+ @config = Config.new
15
+ # only init once, so its @collected_data seems not useful
16
+ @result_builder = GenerateResult.new(self)
17
+ GenerateResult.clear_wanted_attributes
18
+ self
19
+ end
20
+
21
+ def trace
22
+ tp_filter = TpFilter.new(config)
23
+ track = TracePoint.new(*config.event) do |tp|
24
+ next if tp_filter.block_it?(tp)
25
+ @result_builder.output(tp)
26
+ end
27
+ track.enable
28
+ self.tp = track
29
+ end
30
+
31
+ def tp_result_chain
32
+ result_builder.tp_result_chain
33
+ end
34
+ end # END Proxy
35
+
36
+ end
@@ -1,26 +1,27 @@
1
1
  module SourceRoute
2
2
 
3
3
  class TpFilter
4
+ attr_accessor :cond
4
5
  def initialize(condition)
5
- @condition = condition
6
+ @cond = condition
6
7
  end
7
8
 
8
9
  # to improve performance, we didnt assign tp as instance variable
9
10
  def block_it?(tp)
10
11
  return true if negative_check(tp)
11
- return false if positive_check(tp)
12
+ return false if positives_check(tp)
12
13
  true
13
14
  end
14
15
 
15
16
  def negative_check(tp)
16
- @condition.negatives.any? do |method_key, value|
17
+ cond.negatives.any? do |method_key, value|
17
18
  tp.send(method_key).to_s =~ Regexp.new(value)
18
19
  end
19
20
  end
20
21
 
21
- def positive_check(tp)
22
- return true if @condition.positive == {}
23
- @condition.positive.any? do |method_key, value|
22
+ def positives_check(tp)
23
+ return true if cond.positives == {}
24
+ cond.positives.any? do |method_key, value|
24
25
  tp.send(method_key).to_s =~ Regexp.new(value)
25
26
  end
26
27
  end
@@ -10,19 +10,18 @@ module SourceRoute
10
10
  INNER_ATTRS = [:local_var, :instance_var, :params_var].freeze
11
11
  attr_accessor *INNER_ATTRS
12
12
 
13
- # customized attrs
13
+ # customized attrs for build html output
14
14
  CUSTOM_ATTRS = [:order_id, :parent_ids, :direct_child_order_ids,
15
15
  :has_return_value, :parent_length, :tp_self_refer].freeze
16
16
  attr_accessor *CUSTOM_ATTRS
17
17
 
18
- # extend Forwardable
19
- # def_delegators :@ret_data, :[], :merge, :merge!, :reject, :has_key?, :values, :[]=
20
-
21
18
  # The tricky part is
22
- # cant call @core after trace block finished
19
+ # can't call method on @tp_ins outside trace block finished
20
+ # it could be a security limitation in ruby TracePoint object
21
+ # so collect_required_data can only run once and immediately
23
22
  def initialize(tp_ins)
24
- @tp_ins = tp_ins # it only workable in TracePoint block
25
- collect_required_data # so this method can only called once
23
+ @tp_ins = tp_ins
24
+ collect_required_data
26
25
  end
27
26
 
28
27
  def found_opposite
@@ -57,16 +56,13 @@ module SourceRoute
57
56
  call_tp.instance_var = instance_var unless instance_var.nil?
58
57
  end
59
58
 
60
- # to_hash
61
- # why we need wrapper?
62
- # it's nonsense
63
59
  def to_hash
64
60
  stringify
65
61
  ret_hash = GenerateResult.wanted_attributes(event).inject({}) do |memo, k|
66
62
  memo[k.to_s] = send(k)
67
63
  memo
68
64
  end
69
- if SourceRoute.wrapper.condition.events.include?(:return)
65
+ if SourceRoute.proxy.config.event.include?(:return)
70
66
  ret_hash['return_value'] = return_value.nil? ? return_value.inspect : return_value
71
67
  end
72
68
  (INNER_ATTRS + CUSTOM_ATTRS).each do |k|
@@ -75,16 +71,7 @@ module SourceRoute
75
71
  ret_hash
76
72
  end
77
73
 
78
- # def stringify
79
- # # why dup it?
80
- # # dup_core = ret_data.dup
81
- # # to_s is safer than inspect
82
- # # ex: inspect on ActiveRecord_Relation may crash
83
- # ret_data[:defined_class] = ret_data[:defined_class].to_s if ret_data.has_key?(:defined_class)
84
- # ret_data[:return_value] = ret_data[:return_value].source_route_display if ret_data.has_key?(:return_value)
85
- # end
86
-
87
- # this is a mutable method
74
+ # todo: this is a mutable method
88
75
  # not a good solution.
89
76
  # we should use it on the return hash of method to_hash
90
77
  def stringify
@@ -109,30 +96,21 @@ module SourceRoute
109
96
  get_attrs
110
97
  get_self_refer
111
98
 
112
- get_local_or_params_var if SourceRoute.wrapper.condition.result_config[:include_local_var]
113
- get_instance_var if SourceRoute.wrapper.condition.result_config[:include_instance_var] and return_event?
99
+ get_local_or_params_var if SourceRoute.proxy.config.include_local_var
100
+ get_instance_var if SourceRoute.proxy.config.include_instance_var and return_event?
114
101
  self
115
102
  end
116
103
 
117
- # Becare. we cal @tp_ins.event here
118
- # but in stringify method we jsut call event
119
104
  def get_attrs
120
- attrs_data = GenerateResult.wanted_attributes(
121
- @tp_ins.event).each do |key|
105
+ GenerateResult.wanted_attributes(@tp_ins.event).each do |key|
122
106
  if @tp_ins.respond_to?(key)
123
107
  send("#{key}=", @tp_ins.send(key))
124
108
  end
125
109
  end
126
110
  end
127
111
 
128
- # def get_additional_attributes
129
- # [:order_id, :parent_ids, :direct_child_order_ids, :parent_length].each do |k|
130
- # @ret_data[k] = send(k) unless send(k).nil?
131
- # end
132
- # end
133
-
134
112
  def get_self_refer
135
- self.tp_self_refer = SourceRoute.wrapper.result_builder.tp_self_caches
113
+ self.tp_self_refer = SourceRoute.proxy.result_builder.tp_self_caches
136
114
  .map(&:__id__).index(@tp_ins.self.__id__)
137
115
  end
138
116
 
@@ -56,20 +56,6 @@ module SourceRoute
56
56
  call_chain.map { |tp| tp.parent_length }.uniq.sort
57
57
  end
58
58
 
59
- # def deep_cloned
60
- # chain.map { |r| r.clone }
61
- # end
62
-
63
- # def stringify
64
- # deep_cloned.map do |tr|
65
- # # to_s is safer than inspect
66
- # # ex: inspect on ActiveRecord_Relation may crash
67
- # # should moved to tr object
68
- # tr.stringify
69
- # tr
70
- # end
71
- # end
72
-
73
59
  private
74
60
  def init_order_id_and_parent_ids
75
61
  each_with_index do |tpr, index|
@@ -1,3 +1,3 @@
1
1
  module SourceRoute
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,86 @@
1
+ require 'test_helper'
2
+
3
+ module SourceRoute
4
+ class ConfigTest < Minitest::Test
5
+
6
+ def test_tp_filter_methods
7
+ assert TP_FILTER_METHODS.include?(:defined_class_not)
8
+ assert TP_FILTER_METHODS.include?(:method_id_not)
9
+ assert TP_FILTER_METHODS.include?(:path)
10
+ assert TP_FILTER_METHODS.frozen?
11
+ end
12
+
13
+ def test_block_parser
14
+ block_parser = BlockConfigParser.new
15
+ config = block_parser.run do
16
+ event :call, 'c_call'
17
+ method_id_not :exception_method_name
18
+ defined_class 'ActiveRecord::Callback'
19
+ output_format 'silence'
20
+ end
21
+ assert_equal [:call, :c_call], config.event
22
+ assert_equal 'exception_method_name', config.negatives[:method_id]
23
+ assert_equal 'ActiveRecord::Callback', config.positives[:defined_class]
24
+ assert_equal :silence, config.output_format
25
+ end
26
+
27
+ def test_block_parser_with_full_feature
28
+ block_parser = BlockConfigParser.new
29
+ config = block_parser.run do
30
+ event :call, 'c_call'
31
+ path 'your_rails_application_root_dir_name'
32
+ filename 'trial.html'
33
+ full_feature 10
34
+ end
35
+ assert_equal 3, config.event.size
36
+ assert_includes config.event, :return
37
+ assert config.import_return_to_call
38
+ assert 'trial.html', config.filename
39
+ assert_includes config.positives[:path], 'root_dir'
40
+ end
41
+
42
+ def test_block_parser_with_params
43
+ block_parser = BlockConfigParser.new
44
+ config = block_parser.run 'wanted' do
45
+ end
46
+ assert_equal 'wanted', config.positives[:defined_class]
47
+ assert_equal 'wanted', config.positives[:method_id]
48
+ end
49
+
50
+ def test_block_parser_without_block
51
+ block_parser = BlockConfigParser.new
52
+ config = block_parser.run 'ActiveSupport'
53
+ assert_equal 'ActiveSupport', config.positives[:defined_class]
54
+ end
55
+
56
+ def test_full_feature_of_params_parser
57
+ params = {output_format: 'html', event: :c_call,
58
+ defined_class: 'ActiveRecord::Base',
59
+ method_id_not: ['initialize', 'nonsense']
60
+ }
61
+ config = ParamsConfigParser.run(params)
62
+ assert_equal :html, config.output_format
63
+ assert_equal [:c_call], config.event
64
+ assert_equal 'ActiveRecord::Base', config.positives[:defined_class]
65
+ assert_equal 'initialize|nonsense', config.negatives[:method_id]
66
+ end
67
+
68
+ def test_default_value_of_config
69
+ params = {defined_class: [:Rack, :ActiveRecord]}
70
+ config = ParamsConfigParser.run(params)
71
+ assert_equal :test, config.output_format
72
+ assert_equal [:call], config.event
73
+ assert_equal 'Rack|ActiveRecord', config.positives[:defined_class]
74
+ end
75
+
76
+ def test_config_formulize
77
+ config = Config.new
78
+ config.output_format = 'html'
79
+ config.event = ['return', :call]
80
+ config.formulize
81
+ assert_equal :html, config.output_format
82
+ assert_equal [:return, :call], config.event
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ class SourceRoute::ProxyTest < Minitest::Test
4
+
5
+ def setup
6
+ @proxy = SourceRoute::Proxy.instance
7
+ super
8
+ end
9
+
10
+ end
@@ -14,39 +14,45 @@ module SourceRoute
14
14
  @warden_tp = FakeTp.new(:auth, Warden, 6)
15
15
  @user_tp = FakeTp.new(:new, User, 8)
16
16
  @tps = [@devise_tp, @warden_tp, @user_tp]
17
- @result_config = GenerateResult::Config.new('silence', [], false, false)
17
+ super
18
18
  end
19
19
 
20
20
  def test_filter_method_not_auth
21
- cond = Wrapper::Condition.new([:call], {method_id: 'auth'}, {}, @result_config)
21
+ cond = Config.new
22
+ cond.negatives[:method_id] = 'auth'
22
23
  @tp_filter = TpFilter.new(cond)
23
24
  filtered = @tps.reject { |tp| @tp_filter.block_it?(tp) }
24
25
  assert_equal [@user_tp], filtered
25
26
  end
26
27
 
27
28
  def test_filter_class_is_admin
28
- cond = Wrapper::Condition.new([:call], {}, {defined_class: 'Admin'}, @result_config)
29
+ cond = Config.new
30
+ cond.positives[:defined_class] = 'Admin'
29
31
  @tp_filter = TpFilter.new(cond)
30
32
  filtered = @tps.reject { |tp| @tp_filter.block_it?(tp) }
31
33
  assert_equal [], filtered
32
34
  end
33
35
 
34
36
  def test_filter_method_is_auth
35
- cond = Wrapper::Condition.new([:call], {}, {method_id: 'auth'}, @result_config)
37
+ cond = Config.new
38
+ cond.positives[:method_id] = 'auth'
36
39
  @tp_filter = TpFilter.new(cond)
37
40
  filtered = @tps.reject { |tp| @tp_filter.block_it?(tp) }
38
41
  assert_equal [@devise_tp, @warden_tp], filtered
39
42
  end
40
43
 
41
44
  def test_filter_method_is_new_class_is_devise
42
- cond = Wrapper::Condition.new([:call], {}, {defined_class: 'Devise', method_id: 'new'}, @result_config)
45
+ cond = Config.new
46
+ cond.positives[:defined_class] = 'Devise'
47
+ cond.positives[:method_id] = 'new'
43
48
  @tp_filter = TpFilter.new(cond)
44
49
  filtered = @tps.reject { |tp| @tp_filter.block_it?(tp) }
45
50
  assert_equal [@devise_tp, @user_tp], filtered
46
51
  end
47
52
 
48
53
  def test_filter_class_is_devise_or_warden
49
- cond = Wrapper::Condition.new([:call], {}, {defined_class: 'Warden|User'}, @result_config)
54
+ cond = Config.new
55
+ cond.positives[:defined_class] = 'Warden|User'
50
56
  @tp_filter = TpFilter.new(cond)
51
57
  filtered = @tps.reject { |tp| @tp_filter.block_it?(tp) }
52
58
  assert_equal [@warden_tp, @user_tp], filtered
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  class SourceRouteTest < Minitest::Test
4
4
 
5
5
  def setup
6
- @wrapper = SourceRoute::Wrapper.instance
6
+ @proxy = SourceRoute::Proxy.instance
7
7
  super
8
8
  end
9
9
 
@@ -13,9 +13,9 @@ class SourceRouteTest < Minitest::Test
13
13
  end
14
14
 
15
15
  def test_enable_return_true
16
- @source_route = SourceRoute.enable /nnnonsense/
16
+ @source_route = SourceRoute.enable 'nnnonsense'
17
17
  assert @source_route
18
- assert_equal @wrapper, SourceRoute.wrapper
18
+ assert_equal @proxy, SourceRoute.proxy
19
19
  end
20
20
 
21
21
  def test_catch_call_event
@@ -26,24 +26,24 @@ class SourceRouteTest < Minitest::Test
26
26
  end
27
27
  SampleApp.new.nonsense
28
28
 
29
- assert @wrapper.tp
29
+ assert @proxy.tp
30
30
  end
31
31
 
32
32
  def test_show_addtional_attrs
33
33
  SourceRoute.enable 'nonsense' do
34
- result_config.show_additional_attrs = :path
34
+ show_additional_attrs :path
35
35
  full_feature
36
36
  end
37
37
  SampleApp.new.nonsense
38
38
 
39
- assert_includes @wrapper.tp_result_chain.first.path, 'test'
39
+ assert_includes @proxy.tp_result_chain.first.path, 'test'
40
40
  end
41
41
 
42
42
  def test_match_class_name_by_first_parameter
43
43
  @source_route = SourceRoute.enable 'SampleApp'
44
44
  SampleApp.new.nonsense
45
45
 
46
- assert @wrapper.tp_result_chain.size > 0
46
+ assert @proxy.tp_result_chain.size > 0
47
47
  end
48
48
 
49
49
  def test_not_match
@@ -52,7 +52,7 @@ class SourceRouteTest < Minitest::Test
52
52
  method_id_not 'nonsense'
53
53
  end
54
54
  SampleApp.new.nonsense
55
- refute_includes @wrapper.tp_result_chain.map(&:method_id).flatten, 'nonsense'
55
+ refute_includes @proxy.tp_result_chain.map(&:method_id).flatten, 'nonsense'
56
56
  end
57
57
 
58
58
  def test_match_multiple_class_name
@@ -61,8 +61,8 @@ class SourceRouteTest < Minitest::Test
61
61
  end
62
62
 
63
63
  SampleApp.new.nonsense
64
- assert @wrapper.tp_result_chain.size > 0
65
- assert_equal SampleApp, @wrapper.tp_result_chain.last.defined_class
64
+ assert @proxy.tp_result_chain.size > 0
65
+ assert_equal SampleApp, @proxy.tp_result_chain.last.defined_class
66
66
  end
67
67
 
68
68
  def test_source_route_with_one_parameter
@@ -71,19 +71,19 @@ class SourceRouteTest < Minitest::Test
71
71
  end
72
72
  SampleApp.new.nonsense
73
73
 
74
- ret_tp = @wrapper.tp_result_chain.last
74
+ ret_tp = @proxy.tp_result_chain.last
75
75
  assert_equal SampleApp, ret_tp.defined_class
76
76
  end
77
77
 
78
- def test_wrapper_reset
78
+ def test_proxy_reset
79
79
  SourceRoute.enable 'nonsense'
80
80
  SampleApp.new.nonsense
81
- assert_equal 1, @wrapper.tp_result_chain.size
81
+ assert_equal 1, @proxy.tp_result_chain.size
82
82
 
83
83
  SourceRoute.reset
84
84
  SampleApp.new.nonsense
85
85
 
86
- assert_equal 0, @wrapper.tp_result_chain.size
86
+ assert_equal 0, @proxy.tp_result_chain.size
87
87
  end
88
88
 
89
89
  def test_source_route_with_block
@@ -96,7 +96,7 @@ class SourceRouteTest < Minitest::Test
96
96
  end
97
97
  SampleApp.new.nonsense
98
98
 
99
- assert_equal 0, @wrapper.tp_result_chain.size
99
+ assert_equal 0, @proxy.tp_result_chain.size
100
100
  assert_equal 1, paths.size
101
101
  assert_includes paths.first, 'sample_app'
102
102
  end
@@ -104,14 +104,14 @@ class SourceRouteTest < Minitest::Test
104
104
  def test_trace_with_c_call
105
105
  SourceRoute.trace(event: :c_call) { 'abc'.upcase }
106
106
 
107
- assert_equal 2, @wrapper.tp_result_chain.size
107
+ assert_equal 2, @proxy.tp_result_chain.size
108
108
  end
109
109
 
110
110
  def test_trace_with_full_feature
111
111
  SourceRoute.trace method_id: 'nonsense', full_feature: 10 do
112
112
  SampleApp.new.nonsense
113
113
  end
114
- first_result = @wrapper.tp_result_chain.first
114
+ first_result = @proxy.tp_result_chain.first
115
115
  assert_equal first_result.tp_self_refer, 0
116
116
  end
117
117
 
@@ -119,25 +119,25 @@ class SourceRouteTest < Minitest::Test
119
119
  # SourceRoute.trace method_id: 'nonsense', full_feature: true do
120
120
  # SampleApp.new.nonsense
121
121
  # end
122
- # assert_equal 1, @wrapper.tp_self_caches.size
123
- # assert @wrapper.tp_self_caches.first.is_a? SampleApp
122
+ # assert_equal 1, @proxy.tp_self_caches.size
123
+ # assert @proxy.tp_self_caches.first.is_a? SampleApp
124
124
  # end
125
125
 
126
126
  def test_stringify_tp_result_chain_only
127
127
  SourceRoute.trace method_id: 'nonsense', full_feature: true do
128
128
  SampleApp.new.nonsense
129
129
  end
130
- origin_tp_result_chain = @wrapper.tp_result_chain
131
- assert @wrapper.tp_result_chain.first.stringify.defined_class.is_a? String
132
- assert_equal origin_tp_result_chain, @wrapper.tp_result_chain
130
+ origin_tp_result_chain = @proxy.tp_result_chain
131
+ assert @proxy.tp_result_chain.first.stringify.defined_class.is_a? String
132
+ assert_equal origin_tp_result_chain, @proxy.tp_result_chain
133
133
  end
134
134
 
135
135
  def test_trace_without_first_hash_option
136
136
  SourceRoute.trace output_format: :test do
137
137
  SampleApp.new.nonsense
138
138
  end
139
- assert @wrapper.tp_result_chain.size > 0
140
- refute @wrapper.tp.enabled?
139
+ assert @proxy.tp_result_chain.size > 0
140
+ refute @proxy.tp.enabled?
141
141
  end
142
142
 
143
143
  def test_trace_two_events
@@ -145,44 +145,44 @@ class SourceRouteTest < Minitest::Test
145
145
  event :call, :return
146
146
  end
147
147
  SampleApp.new.nonsense
148
- assert_equal 2, @wrapper.tp_result_chain.size
148
+ assert_equal 2, @proxy.tp_result_chain.size
149
149
  end
150
150
 
151
151
  # but local var didnt displayed
152
152
  def test_show_local_variables
153
153
  SourceRoute.enable 'nonsense_with_params' do
154
- result_config.include_local_var = true
154
+ include_local_var true
155
155
  output_format :console
156
156
  end
157
157
 
158
158
  SampleApp.new.nonsense_with_params(88)
159
159
 
160
- ret_value = @wrapper.tp_result_chain.last
160
+ ret_value = @proxy.tp_result_chain.last
161
161
  end
162
162
 
163
163
  def test_track_local_var_when_event_is_return
164
164
  SourceRoute.enable 'nonsense_with_params' do
165
165
  event :return
166
- result_config.include_local_var = true
166
+ include_local_var true
167
167
  end
168
168
 
169
169
  SampleApp.new.nonsense_with_params(88)
170
- assert_equal 1, @wrapper.tp_result_chain.size
170
+ assert_equal 1, @proxy.tp_result_chain.size
171
171
 
172
- ret_value_for_return_event = @wrapper.tp_result_chain.last
172
+ ret_value_for_return_event = @proxy.tp_result_chain.last
173
173
  assert_equal 88, ret_value_for_return_event.local_var[:param1]
174
174
  assert_equal 5, ret_value_for_return_event.local_var[:param2]
175
175
  end
176
176
 
177
177
  def test_show_instance_vars_only
178
178
  SourceRoute.enable 'nonsense' do
179
- result_config.include_instance_var = true
179
+ include_instance_var true
180
180
  event :call, :return
181
181
  end
182
182
  SampleApp.new('ins sure').nonsense_with_instance_var
183
183
 
184
- assert_equal 4, @wrapper.tp_result_chain.size
185
- ret_value = @wrapper.tp_result_chain.pop
184
+ assert_equal 4, @proxy.tp_result_chain.size
185
+ ret_value = @proxy.tp_result_chain.pop
186
186
 
187
187
  assert_equal 'ins sure', ret_value.instance_var[:@sample]
188
188
  end
@@ -192,8 +192,8 @@ class SourceRouteTest < Minitest::Test
192
192
  full_feature 10
193
193
  end
194
194
  SampleApp.new('cool stuff').init_cool_app
195
- @wrapper.tp_result_chain.import_return_value_to_call_chain
196
- assert @wrapper.tp_result_chain.call_chain[0].return_value, 'call results should contain return_value'
195
+ @proxy.tp_result_chain.import_return_value_to_call_chain
196
+ assert @proxy.tp_result_chain.call_chain[0].return_value, 'call results should contain return_value'
197
197
  end
198
198
 
199
199
  def test_order_call_sequence
@@ -202,8 +202,8 @@ class SourceRouteTest < Minitest::Test
202
202
  end
203
203
  SampleApp.new.nonsense_with_instance_var
204
204
 
205
- @wrapper.tp_result_chain.treeize_call_chain
206
- call_results = @wrapper.result_builder.call_chain
205
+ @proxy.tp_result_chain.treeize_call_chain
206
+ call_results = @proxy.result_builder.tp_result_chain.call_chain
207
207
 
208
208
  nonsense_call_tp = call_results.find { |tp| tp.method_id == :nonsense }
209
209
  nonsense_with_instance_var_call_tp = call_results.find do |tp|
@@ -211,7 +211,7 @@ class SourceRouteTest < Minitest::Test
211
211
  end
212
212
  assert_equal [nonsense_with_instance_var_call_tp.order_id], nonsense_call_tp.parent_ids
213
213
  assert_equal 1, nonsense_call_tp.parent_length
214
- assert_equal [0, 1], @wrapper.result_builder.parent_length_list
214
+ assert_equal [0, 1], @proxy.result_builder.tp_result_chain.parent_length_list
215
215
  assert_equal [nonsense_call_tp.order_id], nonsense_with_instance_var_call_tp.direct_child_order_ids
216
216
  end
217
217
 
@@ -221,7 +221,7 @@ class SourceRouteTest < Minitest::Test
221
221
  defined_class 'SampleApp'
222
222
  event :call, :return
223
223
  full_feature 10
224
- result_config.filename = 'call_and_return_in_sample_app.html'
224
+ filename 'call_and_return_in_sample_app.html'
225
225
  end
226
226
 
227
227
  SampleApp.new.init_cool_app
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: source_route
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - raykin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-18 00:00:00.000000000 Z
11
+ date: 2015-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -197,23 +197,25 @@ files:
197
197
  - examples/show_task_trace_in_rails.rb
198
198
  - examples/study_callback.rb
199
199
  - lib/source_route.rb
200
+ - lib/source_route/config.rb
200
201
  - lib/source_route/core_ext.rb
201
202
  - lib/source_route/formats/html.rb
202
203
  - lib/source_route/formats/html_semantic.slim
203
204
  - lib/source_route/generate_result.rb
204
205
  - lib/source_route/json_overrides/activerecord_associations_association.rb
205
206
  - lib/source_route/jsonify.rb
207
+ - lib/source_route/proxy.rb
206
208
  - lib/source_route/rails_plugins/source_track_middleware.rb
207
209
  - lib/source_route/tp_filter.rb
208
210
  - lib/source_route/tp_result.rb
209
211
  - lib/source_route/tp_result_chain.rb
210
212
  - lib/source_route/version.rb
211
- - lib/source_route/wrapper.rb
212
213
  - source_route.gemspec
213
214
  - test/fake_app.rb
214
215
  - test/sample_app.rb
216
+ - test/source_route/config_test.rb
217
+ - test/source_route/proxy_test.rb
215
218
  - test/source_route/tp_filter_test.rb
216
- - test/source_route/wrapper_test.rb
217
219
  - test/source_route_test.rb
218
220
  - test/test_helper.rb
219
221
  homepage: http://github.com/raykin/source-route
@@ -243,8 +245,9 @@ summary: Wrapper of TracePoint.
243
245
  test_files:
244
246
  - test/fake_app.rb
245
247
  - test/sample_app.rb
248
+ - test/source_route/config_test.rb
249
+ - test/source_route/proxy_test.rb
246
250
  - test/source_route/tp_filter_test.rb
247
- - test/source_route/wrapper_test.rb
248
251
  - test/source_route_test.rb
249
252
  - test/test_helper.rb
250
253
  has_rdoc:
@@ -1,112 +0,0 @@
1
- module SourceRoute
2
-
3
- class Wrapper
4
- include Singleton
5
-
6
- TRACE_POINT_METHODS = [:defined_class, :method_id, :path, :lineno]
7
-
8
- attr_accessor :condition, :tp, :result_builder
9
-
10
- Condition = Struct.new(:events, :negatives, :positive, :result_config) do
11
- def initialize(e=[:call], n={}, p={}, r=GenerateResult::Config.new)
12
- @debug = false
13
- super(e, n, p, r)
14
- end
15
- end
16
-
17
- class Condition
18
-
19
- TRACE_POINT_METHODS.each do |m|
20
- define_method m do |*v|
21
- positive[m] = v.flatten.map(&:to_s).join('|')
22
- end
23
-
24
- define_method "#{m}_not" do |*v|
25
- negatives[m] = v.map(&:to_s).join('|')
26
- end
27
- end
28
-
29
- def event(*v)
30
- self.events = v.map(&:to_sym) unless v == []
31
- end
32
-
33
- def output_format(data = nil, &block)
34
- result_config.format = block_given? ? block : data
35
- end
36
-
37
- def has_call_and_return_event
38
- events.include? :return and events.include? :call
39
- end
40
-
41
- def full_feature(value=true)
42
- return unless value
43
-
44
- self.events = [:call, :return]
45
- result_config.import_return_to_call = true
46
-
47
- result_config.show_additional_attrs = [:path, :lineno]
48
- # JSON serialize trigger many problems when handle complicated object
49
-
50
- # a Back Door to open more data. but be care it could trigger weird crash when Jsonify these vars
51
- if value == 10
52
- result_config.include_instance_var = true
53
- result_config.include_local_var = true
54
- end
55
- end
56
-
57
- def debug(value=false)
58
- @debug = value
59
- end
60
-
61
- def is_debug?
62
- @debug
63
- end
64
- end
65
-
66
- def initialize
67
- reset
68
- end
69
-
70
- def reset
71
- @tp.disable if defined? @tp
72
- @condition = Condition.new
73
- @result_builder = GenerateResult.new(self)
74
- GenerateResult.clear_wanted_attributes
75
- self
76
- end
77
-
78
- def trace
79
- # dont wanna init it in tp block, cause tp block could run thousands of times in one cycle trace
80
-
81
- tp_filter = TpFilter.new(condition)
82
-
83
- track = TracePoint.new *condition.events do |tp|
84
-
85
- next if tp_filter.block_it?(tp)
86
-
87
- # immediate output trace point result
88
- # here is confused. todo
89
- # should move tp_result_chain to result generator
90
- @result_builder.output(tp)
91
- # if condition.result_config.format == :console
92
- # ret_data = build_result.build(tp)
93
- # @tp_result_chain.push(ret_data)
94
- # build_result.output(tp)
95
- # elsif condition.result_config.format.is_a? Proc
96
- # build_result.output(tp)
97
- # else
98
- # # why not push the tp to result chain
99
- # ret_data = build_result.build(tp)
100
- # @tp_result_chain.push(ret_data)
101
- # end
102
- end
103
- track.enable
104
- self.tp = track
105
- end
106
-
107
- def tp_result_chain
108
- result_builder.tp_result_chain
109
- end
110
- end # END Wrapper
111
-
112
- end
@@ -1,9 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SourceRoute::WrapperTest < Minitest::Test
4
-
5
- def setup
6
- @wrapper = SourceRoute::Wrapper.instance
7
- end
8
-
9
- end