source_route 0.1.2 → 0.1.3

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: e359db40f93fb8aa3973ed198e521e29c21aa2ab
4
- data.tar.gz: b0f07e1dce0010f430d54b81b993c0bd7dcb73e4
3
+ metadata.gz: 1a153562bb55ebdbeed1c374089561c69be101a5
4
+ data.tar.gz: 326bc1d36580221a021630ddd59ce66ea2cedfc2
5
5
  SHA512:
6
- metadata.gz: b418b380f34fe5ed9aa794eab4950b6c9936f9f019408047de068412c1986f49d17c0d84cb05e80d302d30af3f27b3d404797d8d2d7077feb7f143bc728437ec
7
- data.tar.gz: 02fd9a36fbb122ebadfd660baf1fe19328f272ba0260a5620becdd310bb69b34d68af85655f1355353b9ac375b38f4819f9feb61690c17d4f4358924e8f16ff1
6
+ metadata.gz: 1265a2077f7420311560c804169c50c369639c5c0882453549bee819ceb429bfa4713d3e545fca2c079076bce45911b7fe3db03547811dfb28f1a4acee3255ee
7
+ data.tar.gz: 381f9a950f6b582edded7df76c30934f123c14fcbf51b4853b6062333d48c42a40d393543ec20b5c3c63682d4d0d65fe296f0ecb8e1ffe11d706c62fd5a9989f
data/README.md CHANGED
@@ -44,8 +44,9 @@ you will get a different trace file.
44
44
  SourceRoute.enable :wanted_method_name
45
45
  .... # here is your code
46
46
  ....
47
- # may be code this in another file
48
- SourceRoute.build_html_output
47
+ ....
48
+ # add it after your tracked code, it will output the trace into a html file
49
+ SourceRoute.output_html
49
50
 
50
51
  Same as the previous example, you will get a html file showing the code trace.
51
52
 
@@ -91,12 +92,14 @@ Finally, I expect my working style can change from searching workaround from int
91
92
 
92
93
  ### TODO
93
94
 
94
- Open Method directly from browser
95
+ Add debug option to provider more verbose messages of what has happened
96
+
97
+ Open File directly from browser(chrome) by plugin?
95
98
 
96
99
  Apply https://github.com/a5hik/ng-sortable
97
100
 
98
- Hide defined class filter. Add vertical timeline.
101
+ Add vertical timeline.
99
102
  (see http://tympanus.net/codrops/2013/05/02/vertical-timeline/
100
103
  http://stackoverflow.com/questions/20896240/responsive-timeline-ui-with-bootstrap3)
101
104
 
102
- Add debug option to provider more verbose messages of what has happened
105
+ Hide defined class filter.
@@ -14,8 +14,9 @@ module SourceRoute
14
14
 
15
15
  if result_config.import_return_to_call and wrapper.condition.has_call_and_return_event
16
16
  wrapper.import_return_value_to_call_chain
17
- wrapper.order_call_chain
17
+ wrapper.treeize_call_chain
18
18
  end
19
+ # TODO: any exception triggered in render method will be absorb totally, how to fix it?
19
20
  html_output_str = slim_template.render(wrapper)
20
21
  File.open(filename, 'w') do |f|
21
22
  f << html_output_str
@@ -7,10 +7,14 @@ html
7
7
  script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"
8
8
 
9
9
  css:
10
- .call-level-1 {}
11
- .call-level-2 { margin-left: 50px }
12
- .call-level-3 { margin-left: 100px }
13
- .call-level-4 { margin-left: 150px }
10
+ .call-level-0 {}
11
+ .call-level-1 { margin-left: 50px }
12
+ .call-level-2 { margin-left: 100px }
13
+ .call-level-3 { margin-left: 150px }
14
+ .call-level-4 { margin-left: 200px }
15
+ .call-level-5 { margin-left: 250px }
16
+ .call-level-6 { margin-left: 300px }
17
+ .call-level-7 { margin-left: 300px }
14
18
  body(ng-app="SourceRoute" ng-controller="MainCtrl")
15
19
 
16
20
  nav.navbar.navbar-default.navbar-static-top
@@ -30,6 +34,14 @@ html
30
34
  .clearfix
31
35
 
32
36
  .container
37
+ .level-header(ng-if="parentLengthList" style="padding-bottom: 10px")
38
+ .btn-group>
39
+ button.btn.btn-default>(ng-click="traceFilter.parent_length = length" ng-repeat="length in parentLengthList")
40
+ span> Level
41
+ span(ng-bind="::length")
42
+ span
43
+ button.btn.btn-primary(ng-click="traceFilter.parent_length = undefined") Clear
44
+
33
45
  .trace-flow
34
46
  .row
35
47
  .left-info.col-sm-4(ng-if="false")
@@ -67,6 +79,10 @@ html
67
79
  span<>
68
80
  | =>
69
81
  span<>(ng-bind="value | json")
82
+ .self-obj.well.well-sm(ng-if="trace.hasOwnProperty('tp_self')" style="color: red; margin-bottom: 0")
83
+ span Self
84
+ div
85
+ span(ng-bind="tpSelfList[trace.tp_self] | json")
70
86
  .path-value.well.well-sm(ng-if="trace.path")
71
87
  span Path
72
88
  div
@@ -82,7 +98,9 @@ html
82
98
  sourceRoute = angular.module('SourceRoute', ['ui.bootstrap'])
83
99
  sourceRoute.controller('MainCtrl', function($scope, $filter) {
84
100
  $scope.traces = angular.element("#trace-data").data('trace')
101
+ $scope.tpSelfList = angular.element("#trace-data").data('tp-self-caches')
85
102
  $scope.tpEvents = angular.element("#trace-data").data('tp-events')
103
+ $scope.parentLengthList = angular.element("#trace-data").data('tp-parent-length-list')
86
104
 
87
105
  $scope.traceFilter = {event: $scope.tpEvents[0]}
88
106
  if ($scope.tpEvents.length == 1 && angular.isUndefined($scope.traces[0].event)) {
@@ -94,8 +112,8 @@ html
94
112
  $scope.definedClasses = _.uniq(_.map($scope.traces, 'defined_class'))
95
113
 
96
114
  $scope.callLevelClass = function(trace) {
97
- if (trace.parent_length > 4) {
98
- return 'call-level-4'
115
+ if (trace.parent_length > 7) {
116
+ return 'call-level-7'
99
117
  } else {
100
118
  return 'call-level-' + trace.parent_length
101
119
  }
@@ -110,15 +128,9 @@ html
110
128
 
111
129
  })
112
130
 
113
- ruby:
114
- local_trace_data = @tp_result_chain.map do |tp_result|
115
- if tp_result.key?(:defined_class)
116
- tp_result[:defined_class] = tp_result[:defined_class].to_s
117
- tp_result[:return_value] = tp_result[:return_value].inspect if tp_result.key?(:return_value)
118
- end
119
- tp_result
120
- end
121
-
122
131
  .data-collect
123
132
  / dont use local_trace_data.to_json, because ActiveSupport override it and can introduce unexpected crash for some data
124
- #trace-data(data-trace="#{JSON.dump(local_trace_data)}" data-tp-events="#{JSON.dump(@condition.events)}")
133
+ #trace-data(data-trace="#{jsonify_tp_result_chain}"
134
+ data-tp-events="#{jsonify_events}"
135
+ data-tp-self-caches="#{jsonify_tp_self_caches}"
136
+ data-tp-parent-length-list="#{JSON.dump(parent_length_list)}")
@@ -44,7 +44,7 @@ module SourceRoute
44
44
  def build(trace_point_instance)
45
45
  @tp = trace_point_instance
46
46
  collect_tp_data
47
- @collect_data[:tp_self] = @tp.self if @config[:include_tp_self]
47
+ collect_tp_self if @config[:include_tp_self]
48
48
  collect_local_var_data if @config[:include_local_var]
49
49
  collect_instance_var_data if @config[:include_instance_var]
50
50
  @collect_data
@@ -77,6 +77,15 @@ module SourceRoute
77
77
 
78
78
  private
79
79
 
80
+ # include? will evaluate @tp.self, if @tp.self is AR::Relation, it could cause problems
81
+ # So that's why I use object_id as replace
82
+ def collect_tp_self
83
+ unless @wrapper.tp_self_caches.find { |tp_cache| tp_cache.equal? @tp.self }
84
+ @wrapper.tp_self_caches.push @tp.self
85
+ end
86
+ @collect_data[:tp_self] = @wrapper.tp_self_caches.map(&:__id__).index(@tp.self.__id__)
87
+ end
88
+
80
89
  def collect_tp_data
81
90
  @collect_data = output_attributes(@tp.event).inject({}) do |memo, key|
82
91
  memo[key.to_sym] = @tp.send(key) if @tp.respond_to?(key)
@@ -87,6 +96,7 @@ module SourceRoute
87
96
  def collect_local_var_data
88
97
  local_var_hash = {}
89
98
 
99
+ # Warn: @tp.binding.eval('local_variables') =! @tp.binding.send('local_variables')
90
100
  @tp.binding.eval('local_variables').each do |v|
91
101
  local_var_hash[v] = @tp.binding.local_variable_get v
92
102
  end
@@ -0,0 +1,20 @@
1
+ if defined? ActiveRecord
2
+ class ActiveRecord::Associations::Association
3
+
4
+ # dump association can trigger ActiveSupport::JSON::Encoding::CircularReferenceError when use rails ~> 4.0.1
5
+ # I try other json gems to fix it, but all failed. That's why I override it here.
6
+ def to_json(options = nil)
7
+ JSON.dump(to_s)
8
+ end
9
+ end
10
+
11
+ class ActiveRecord::Base
12
+
13
+ # dump association can trigger ActiveSupport::JSON::Encoding::CircularReferenceError when use rails ~> 4.0.1
14
+ # I try other json gems to fix it, but all failed. That's why I override it here.
15
+ def to_json(options = nil)
16
+ JSON.dump(to_s)
17
+ end
18
+ end
19
+
20
+ end
@@ -21,17 +21,15 @@ module SourceRoute
21
21
  def import_return_value_to_call_chain
22
22
  call_chain.each do |ctp|
23
23
  matched_return_tp = return_chain.detect do |rtp|
24
- rtp[:defined_class] == ctp[:defined_class] and rtp[:method_id] == ctp[:method_id] and
25
- rtp[:tp_self] == ctp[:tp_self]
26
-
24
+ rtp[:tp_self] == ctp[:tp_self] and rtp[:method_id] == ctp[:method_id] and rtp[:defined_class] == ctp[:defined_class]
27
25
  end
28
26
  ctp[:return_value] = matched_return_tp[:return_value]
29
- ctp[:local_var] = matched_return_tp[:local_var]
30
- ctp[:instance_var] = matched_return_tp[:instance_var]
27
+ ctp[:local_var] = matched_return_tp[:local_var] if matched_return_tp.key? :local_var
28
+ ctp[:instance_var] = matched_return_tp[:instance_var] if matched_return_tp.key? :instance_var
31
29
  end
32
30
  end
33
31
 
34
- def order_call_chain
32
+ def treeize_call_chain
35
33
  init_order_id_and_parent_ids
36
34
  call_chain.each do |tpr|
37
35
  return_tpr = return_chain.find do |rtpr|
@@ -49,10 +47,14 @@ module SourceRoute
49
47
  cal_parent_length
50
48
  end
51
49
 
50
+ def parent_length_list
51
+ call_chain.map { |tp| tp[:parent_length] }.uniq.sort
52
+ end
53
+
52
54
  private
53
55
  def init_order_id_and_parent_ids
54
56
  each_with_index do |tpr, index|
55
- tpr[:order_id], tpr[:parent_ids] = index, [-1]
57
+ tpr[:order_id], tpr[:parent_ids] = index, []
56
58
  end
57
59
  end
58
60
 
@@ -1,3 +1,3 @@
1
1
  module SourceRoute
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -6,10 +6,10 @@ module SourceRoute
6
6
  TRACE_POINT_METHODS = [:defined_class, :method_id, :path, :lineno]
7
7
 
8
8
  attr_accessor :condition, :tp
9
- attr_reader :tp_result_chain
9
+ attr_reader :tp_result_chain, :tp_self_caches
10
10
 
11
11
  extend Forwardable
12
- def_delegators :@tp_result_chain, :import_return_value_to_call_chain, :order_call_chain, :call_chain, :return_chain
12
+ def_delegators :@tp_result_chain, :import_return_value_to_call_chain, :treeize_call_chain, :call_chain, :return_chain, :parent_length_list
13
13
 
14
14
  Condition = Struct.new(:events, :negatives, :positive, :result_config) do
15
15
  def initialize(e=[:call], n={}, p={}, r=GenerateResult::Config.new)
@@ -46,9 +46,12 @@ module SourceRoute
46
46
 
47
47
  self.events = [:call, :return]
48
48
  result_config.import_return_to_call = true
49
- result_config.include_instance_var = true
50
- result_config.include_local_var = true
51
49
  result_config.include_tp_self = true
50
+
51
+ result_config.show_additional_attrs = [:path, :lineno]
52
+ # JSON serialize trigger many problems when handle complicated object
53
+ # result_config.include_instance_var = true
54
+ # result_config.include_local_var = true
52
55
  end
53
56
  end
54
57
 
@@ -57,9 +60,10 @@ module SourceRoute
57
60
  end
58
61
 
59
62
  def reset
60
- @tp.disable if @tp
63
+ @tp.disable if defined? @tp
61
64
  @condition = Condition.new
62
65
  @tp_result_chain = TpResultChain.new
66
+ @tp_self_caches = []
63
67
  self
64
68
  end
65
69
 
@@ -81,9 +85,43 @@ module SourceRoute
81
85
  end
82
86
  track.enable
83
87
  self.tp = track
84
- track
85
88
  end
86
89
 
90
+ # TODO: move this into chain self
91
+ def stringify_tp_self_caches
92
+ tp_self_caches.clone.map(&:to_s)
93
+ end
94
+
95
+ def stringify_tp_result_chain
96
+ deep_cloned = tp_result_chain.map do |tp_result|
97
+ tp_result.clone
98
+ end
99
+ deep_cloned.map do |tr|
100
+ # to_s is safer than inspect
101
+ # ex: inspect on ActiveRecord_Relation may crash
102
+ tr[:defined_class] = tr[:defined_class].to_s if tr.key?(:defined_class)
103
+ if tr.key?(:return_value)
104
+ if tr[:return_value].nil? or tr[:return_value] == ''
105
+ tr[:return_value] = tr[:return_value].inspect
106
+ else
107
+ tr[:return_value] = tr[:return_value].to_s
108
+ end
109
+ end
110
+ tr
111
+ end
112
+ end
113
+
114
+ def jsonify_events
115
+ JSON.dump(@condition.events.map(&:to_s))
116
+ end
117
+
118
+ def jsonify_tp_result_chain
119
+ JSON.dump(stringify_tp_result_chain)
120
+ end
121
+
122
+ def jsonify_tp_self_caches
123
+ JSON.dump(stringify_tp_self_caches)
124
+ end
87
125
  end # END Wrapper
88
126
 
89
127
  end
data/lib/source_route.rb CHANGED
@@ -10,6 +10,7 @@ require "source_route/wrapper"
10
10
  require "source_route/generate_result"
11
11
  require "source_route/tp_result_chain"
12
12
  require "source_route/tp_filter"
13
+ require 'source_route/json_overrides/activerecord_associations_association'
13
14
 
14
15
  module SourceRoute
15
16
  extend self
@@ -58,6 +59,10 @@ module SourceRoute
58
59
  SourceRoute::Formats::Html.slim_render(wrapper)
59
60
  end
60
61
 
62
+ def output_html
63
+ build_html_output
64
+ end
65
+
61
66
  # Not implement yet
62
67
  class Logger < Logger
63
68
  end
@@ -110,7 +110,25 @@ class SourceRouteTest < Minitest::Test
110
110
  end
111
111
  assert @wrapper.condition.result_config.include_tp_self
112
112
  first_result = @wrapper.tp_result_chain.first
113
- assert first_result[:tp_self]
113
+ assert_equal first_result[:tp_self], 0
114
+ end
115
+
116
+ def test_trace_include_tp_self
117
+ SourceRoute.trace method_id: 'nonsense', full_feature: true do
118
+ SampleApp.new.nonsense
119
+ end
120
+ assert_equal 1, @wrapper.tp_self_caches.size
121
+ assert @wrapper.stringify_tp_self_caches.first.is_a? String
122
+ assert @wrapper.tp_self_caches.first.is_a? SampleApp
123
+ end
124
+
125
+ def test_stringify_tp_result_chain
126
+ SourceRoute.trace method_id: 'nonsense', full_feature: true do
127
+ SampleApp.new.nonsense
128
+ end
129
+ origin_tp_result_chain = @wrapper.tp_result_chain
130
+ assert @wrapper.stringify_tp_result_chain.first[:defined_class].is_a? String
131
+ assert_equal origin_tp_result_chain, @wrapper.tp_result_chain
114
132
  end
115
133
 
116
134
  def test_trace_without_first_hash_option
@@ -188,15 +206,16 @@ class SourceRouteTest < Minitest::Test
188
206
  event :call, :return
189
207
  end
190
208
  SampleApp.new.nonsense_with_instance_var
191
- @wrapper.order_call_chain
192
- @wrapper.order_call_chain
209
+ @wrapper.treeize_call_chain
210
+ @wrapper.treeize_call_chain
193
211
  call_results = @wrapper.call_chain
194
212
 
195
213
  nonsense_call_tp = call_results.find { |tp| tp[:method_id] == :nonsense }
196
214
  nonsense_with_instance_var_call_tp = call_results.find { |tp| tp[:method_id] == :nonsense_with_instance_var }
197
215
 
198
- assert_equal [-1, nonsense_with_instance_var_call_tp[:order_id]], nonsense_call_tp[:parent_ids]
199
- assert_equal 2, nonsense_call_tp[:parent_length]
216
+ assert_equal [nonsense_with_instance_var_call_tp[:order_id]], nonsense_call_tp[:parent_ids]
217
+ assert_equal 1, nonsense_call_tp[:parent_length]
218
+ assert_equal [0, 1], @wrapper.parent_length_list
200
219
  end
201
220
 
202
221
  # Nothing has tested really when run rake cause ENV['ignore_html_generation'] was set to true
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.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - raykin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-14 00:00:00.000000000 Z
11
+ date: 2014-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -128,6 +128,7 @@ files:
128
128
  - lib/source_route/formats/html.rb
129
129
  - lib/source_route/formats/html_template.slim
130
130
  - lib/source_route/generate_result.rb
131
+ - lib/source_route/json_overrides/activerecord_associations_association.rb
131
132
  - lib/source_route/tp_filter.rb
132
133
  - lib/source_route/tp_result_chain.rb
133
134
  - lib/source_route/version.rb