tapping_device 0.5.2 → 0.5.7

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
  SHA256:
3
- metadata.gz: fbf652959b6f125f5e4ece39c59db0b8ebd55096e4aa639452de306857193bf7
4
- data.tar.gz: 31d13f1f4f38b6009795e4d948ba4596428355cb03d113603b3801c307c14a18
3
+ metadata.gz: 28a848cfef98c43315488230c1593aba48ef1b3ee91dc7a495a6cee7cb406771
4
+ data.tar.gz: 30601c6039343512d3d7c157bd0c8e5645b8005aa37a4b365458018cb477c2d2
5
5
  SHA512:
6
- metadata.gz: 98eae30679e7e08f7607dbd7ee457b9db9565e46ddf2859a782f2b5ce817bf014937b65f8ee0f342bb7d6dbec3afcb3aef980e396362726839c4031db03cb2e5
7
- data.tar.gz: bf2d0e6e8e38466f928d57580edf745b1ee1ce18ed1ee03968dc76647b67cfb4e0feaeff0166ac7503c295c54351445344f828a0bc3878b57a74ed8a130a03cb
6
+ metadata.gz: 2540416f3d4ece8dfb76ee567030d3f4ab9da497c9ae97e9d7418b952d7ce0552453aad33278344ce683dc89a393244d74aef20bc6c6cf9847f0198911999a20
7
+ data.tar.gz: b417c4c17f18a152ce0bbc4135657bc41cb90b70788b971debb4242a1d35a9189c21621420af5f5bf06e9aa76148f9a49c6e2fb786000769a193c57765de45d1
data/.DS_Store CHANGED
Binary file
@@ -0,0 +1,210 @@
1
+ # Changelog
2
+
3
+ ## [v0.5.3](https://github.com/st0012/tapping_device/tree/v0.5.3) (2020-06-21)
4
+
5
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.2...v0.5.3)
6
+
7
+ **Closed issues:**
8
+
9
+ - Global Configuration [\#46](https://github.com/st0012/tapping_device/issues/46)
10
+ - Support write\_\* helpers [\#44](https://github.com/st0012/tapping_device/issues/44)
11
+ - Use Method\#source to replace Payload\#method\_head’s implementation [\#19](https://github.com/st0012/tapping_device/issues/19)
12
+
13
+ **Merged pull requests:**
14
+
15
+ - Support Global Configuration [\#48](https://github.com/st0012/tapping_device/pull/48) ([st0012](https://github.com/st0012))
16
+ - Support write\_\* helpers [\#47](https://github.com/st0012/tapping_device/pull/47) ([st0012](https://github.com/st0012))
17
+ - Hijack attr methods with `hijack\_attr\_methods` option [\#45](https://github.com/st0012/tapping_device/pull/45) ([st0012](https://github.com/st0012))
18
+
19
+ ## [v0.5.2](https://github.com/st0012/tapping_device/tree/v0.5.2) (2020-06-10)
20
+
21
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.1...v0.5.2)
22
+
23
+ **Closed issues:**
24
+
25
+ - Add print\_mutations [\#41](https://github.com/st0012/tapping_device/issues/41)
26
+ - Add tap\_on\_mutation! [\#18](https://github.com/st0012/tapping_device/issues/18)
27
+
28
+ **Merged pull requests:**
29
+
30
+ - Print mutations [\#43](https://github.com/st0012/tapping_device/pull/43) ([st0012](https://github.com/st0012))
31
+ - Refactorings [\#42](https://github.com/st0012/tapping_device/pull/42) ([st0012](https://github.com/st0012))
32
+
33
+ ## [v0.5.1](https://github.com/st0012/tapping_device/tree/v0.5.1) (2020-06-07)
34
+
35
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.0...v0.5.1)
36
+
37
+ **Fixed bugs:**
38
+
39
+ - Filter Out Entries From TappingDevice [\#35](https://github.com/st0012/tapping_device/issues/35)
40
+
41
+ **Merged pull requests:**
42
+
43
+ - Update GitHub Actions Configuration [\#40](https://github.com/st0012/tapping_device/pull/40) ([st0012](https://github.com/st0012))
44
+ - Fix typo: Guadian -\> Guardian [\#39](https://github.com/st0012/tapping_device/pull/39) ([skade](https://github.com/skade))
45
+ - Filter out calls about TappingDevice [\#38](https://github.com/st0012/tapping_device/pull/38) ([st0012](https://github.com/st0012))
46
+ - Drop tap\_sql! [\#37](https://github.com/st0012/tapping_device/pull/37) ([st0012](https://github.com/st0012))
47
+ - Add CollectionProxy class [\#36](https://github.com/st0012/tapping_device/pull/36) ([st0012](https://github.com/st0012))
48
+
49
+ ## [v0.5.0](https://github.com/st0012/tapping_device/tree/v0.5.0) (2020-05-25)
50
+
51
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.11...v0.5.0)
52
+
53
+ **Closed issues:**
54
+
55
+ - Colorize output of tracing helpers [\#25](https://github.com/st0012/tapping_device/issues/25)
56
+
57
+ **Merged pull requests:**
58
+
59
+ - Update README.md [\#34](https://github.com/st0012/tapping_device/pull/34) ([st0012](https://github.com/st0012))
60
+ - Colorize output [\#33](https://github.com/st0012/tapping_device/pull/33) ([st0012](https://github.com/st0012))
61
+ - Add TappingDevice\#with to register a with condition [\#32](https://github.com/st0012/tapping_device/pull/32) ([st0012](https://github.com/st0012))
62
+
63
+ ## [v0.4.11](https://github.com/st0012/tapping_device/tree/v0.4.11) (2020-04-19)
64
+
65
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.10...v0.4.11)
66
+
67
+ **Merged pull requests:**
68
+
69
+ - Update rake requirement from ~\> 10.0 to ~\> 13.0 [\#31](https://github.com/st0012/tapping_device/pull/31) ([dependabot[bot]](https://github.com/apps/dependabot))
70
+
71
+ ## [v0.4.10](https://github.com/st0012/tapping_device/tree/v0.4.10) (2020-02-05)
72
+
73
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.9...v0.4.10)
74
+
75
+ **Implemented enhancements:**
76
+
77
+ - Usability improvements [\#30](https://github.com/st0012/tapping_device/pull/30) ([st0012](https://github.com/st0012))
78
+
79
+ **Merged pull requests:**
80
+
81
+ - Fix tap\_init!'s payload content [\#29](https://github.com/st0012/tapping_device/pull/29) ([st0012](https://github.com/st0012))
82
+ - Refactorings and fixes [\#28](https://github.com/st0012/tapping_device/pull/28) ([st0012](https://github.com/st0012))
83
+
84
+ ## [v0.4.9](https://github.com/st0012/tapping_device/tree/v0.4.9) (2020-01-20)
85
+
86
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.8...v0.4.9)
87
+
88
+ **Implemented enhancements:**
89
+
90
+ - Improve detail\_call\_info's output format [\#27](https://github.com/st0012/tapping_device/pull/27) ([st0012](https://github.com/st0012))
91
+
92
+ ## [v0.4.8](https://github.com/st0012/tapping_device/tree/v0.4.8) (2020-01-05)
93
+
94
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.7...v0.4.8)
95
+
96
+ **Closed issues:**
97
+
98
+ - Provide options for tapping on call or return events [\#23](https://github.com/st0012/tapping_device/issues/23)
99
+
100
+ **Merged pull requests:**
101
+
102
+ - Add tracing helpers [\#24](https://github.com/st0012/tapping_device/pull/24) ([st0012](https://github.com/st0012))
103
+
104
+ ## [v0.4.7](https://github.com/st0012/tapping_device/tree/v0.4.7) (2019-12-29)
105
+
106
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.6...v0.4.7)
107
+
108
+ **Implemented enhancements:**
109
+
110
+ - Config test coverage for codeclimate [\#22](https://github.com/st0012/tapping_device/pull/22) ([st0012](https://github.com/st0012))
111
+
112
+ **Closed issues:**
113
+
114
+ - Support tracking ActiveRecord::Base instances by their ids [\#17](https://github.com/st0012/tapping_device/issues/17)
115
+
116
+ **Merged pull requests:**
117
+
118
+ - Refactor tests and some minor fixes [\#21](https://github.com/st0012/tapping_device/pull/21) ([st0012](https://github.com/st0012))
119
+ - Support track\_as\_records option [\#20](https://github.com/st0012/tapping_device/pull/20) ([st0012](https://github.com/st0012))
120
+
121
+ ## [v0.4.6](https://github.com/st0012/tapping_device/tree/v0.4.6) (2019-12-25)
122
+
123
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.5...v0.4.6)
124
+
125
+ **Merged pull requests:**
126
+
127
+ - Add TappingDevice\#and\_print method [\#16](https://github.com/st0012/tapping_device/pull/16) ([st0012](https://github.com/st0012))
128
+ - Add Payload\#detail\_call\_info and improve method\_name's format [\#15](https://github.com/st0012/tapping_device/pull/15) ([st0012](https://github.com/st0012))
129
+
130
+ ## [v0.4.5](https://github.com/st0012/tapping_device/tree/v0.4.5) (2019-12-15)
131
+
132
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.4...v0.4.5)
133
+
134
+ ## [v0.4.4](https://github.com/st0012/tapping_device/tree/v0.4.4) (2019-12-15)
135
+
136
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.3...v0.4.4)
137
+
138
+ **Merged pull requests:**
139
+
140
+ - Implement tap\_passed! [\#14](https://github.com/st0012/tapping_device/pull/14) ([st0012](https://github.com/st0012))
141
+
142
+ ## [v0.4.3](https://github.com/st0012/tapping_device/tree/v0.4.3) (2019-12-09)
143
+
144
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.2...v0.4.3)
145
+
146
+ ## [v0.4.2](https://github.com/st0012/tapping_device/tree/v0.4.2) (2019-12-09)
147
+
148
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.1...v0.4.2)
149
+
150
+ **Merged pull requests:**
151
+
152
+ - Refactor tap\_sql! [\#13](https://github.com/st0012/tapping_device/pull/13) ([st0012](https://github.com/st0012))
153
+ - Improve tap sql [\#12](https://github.com/st0012/tapping_device/pull/12) ([st0012](https://github.com/st0012))
154
+
155
+ ## [v0.4.1](https://github.com/st0012/tapping_device/tree/v0.4.1) (2019-12-06)
156
+
157
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.0...v0.4.1)
158
+
159
+ **Merged pull requests:**
160
+
161
+ - Add TappingDevice::Payload class [\#11](https://github.com/st0012/tapping_device/pull/11) ([st0012](https://github.com/st0012))
162
+
163
+ ## [v0.4.0](https://github.com/st0012/tapping_device/tree/v0.4.0) (2019-11-25)
164
+
165
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.3.0...v0.4.0)
166
+
167
+ **Merged pull requests:**
168
+
169
+ - Support tap\_sql! [\#10](https://github.com/st0012/tapping_device/pull/10) ([st0012](https://github.com/st0012))
170
+ - Minor adjustment [\#9](https://github.com/st0012/tapping_device/pull/9) ([NickWarm](https://github.com/NickWarm))
171
+
172
+ ## [v0.3.0](https://github.com/st0012/tapping_device/tree/v0.3.0) (2019-11-03)
173
+
174
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.2.0...v0.3.0)
175
+
176
+ **Implemented enhancements:**
177
+
178
+ - Largely improve performance by fixing bad design [\#8](https://github.com/st0012/tapping_device/pull/8) ([st0012](https://github.com/st0012))
179
+
180
+ ## [v0.2.0](https://github.com/st0012/tapping_device/tree/v0.2.0) (2019-11-02)
181
+
182
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.1.1...v0.2.0)
183
+
184
+ **Implemented enhancements:**
185
+
186
+ - Add Device class [\#3](https://github.com/st0012/tapping_device/pull/3) ([st0012](https://github.com/st0012))
187
+
188
+ **Merged pull requests:**
189
+
190
+ - Remove tapping\_deivce/device.rb [\#7](https://github.com/st0012/tapping_device/pull/7) ([st0012](https://github.com/st0012))
191
+ - Reduce namespace [\#6](https://github.com/st0012/tapping_device/pull/6) ([st0012](https://github.com/st0012))
192
+ - Register and control all devices from Device class [\#5](https://github.com/st0012/tapping_device/pull/5) ([st0012](https://github.com/st0012))
193
+ - Support `TappingDevice::Device\#stop\_when` [\#4](https://github.com/st0012/tapping_device/pull/4) ([st0012](https://github.com/st0012))
194
+
195
+ ## [v0.1.1](https://github.com/st0012/tapping_device/tree/v0.1.1) (2019-10-20)
196
+
197
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.1.0...v0.1.1)
198
+
199
+ **Implemented enhancements:**
200
+
201
+ - More filters, Refactoring and Readme update [\#2](https://github.com/st0012/tapping_device/pull/2) ([st0012](https://github.com/st0012))
202
+ - Support tapping ActiveRecord class/instance [\#1](https://github.com/st0012/tapping_device/pull/1) ([st0012](https://github.com/st0012))
203
+
204
+ ## [v0.1.0](https://github.com/st0012/tapping_device/tree/v0.1.0) (2019-10-19)
205
+
206
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/61039c87a55c664661b788e24311e263b28a3ee8...v0.1.0)
207
+
208
+
209
+
210
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
@@ -1,34 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tapping_device (0.5.2)
4
+ tapping_device (0.5.7)
5
5
  activerecord (>= 5.2)
6
+ activesupport
7
+ pastel
6
8
  pry
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
10
12
  specs:
11
- activemodel (6.0.3.1)
12
- activesupport (= 6.0.3.1)
13
- activerecord (6.0.3.1)
14
- activemodel (= 6.0.3.1)
15
- activesupport (= 6.0.3.1)
16
- activesupport (6.0.3.1)
13
+ activemodel (6.0.3.2)
14
+ activesupport (= 6.0.3.2)
15
+ activerecord (6.0.3.2)
16
+ activemodel (= 6.0.3.2)
17
+ activesupport (= 6.0.3.2)
18
+ activesupport (6.0.3.2)
17
19
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
20
  i18n (>= 0.7, < 2)
19
21
  minitest (~> 5.1)
20
22
  tzinfo (~> 1.1)
21
23
  zeitwerk (~> 2.2, >= 2.2.2)
22
24
  coderay (1.1.3)
23
- concurrent-ruby (1.1.6)
25
+ concurrent-ruby (1.1.7)
24
26
  database_cleaner (1.7.0)
25
27
  diff-lcs (1.3)
26
28
  docile (1.3.2)
27
- i18n (1.8.3)
29
+ i18n (1.8.5)
28
30
  concurrent-ruby (~> 1.0)
29
31
  json (2.3.0)
30
32
  method_source (1.0.0)
31
- minitest (5.14.1)
33
+ minitest (5.14.2)
34
+ pastel (0.8.0)
35
+ tty-color (~> 0.5)
32
36
  pry (0.13.1)
33
37
  coderay (~> 1.1)
34
38
  method_source (~> 1.0)
@@ -53,9 +57,10 @@ GEM
53
57
  simplecov-html (0.10.2)
54
58
  sqlite3 (1.4.1)
55
59
  thread_safe (0.3.6)
60
+ tty-color (0.5.2)
56
61
  tzinfo (1.2.7)
57
62
  thread_safe (~> 0.1)
58
- zeitwerk (2.3.0)
63
+ zeitwerk (2.4.0)
59
64
 
60
65
  PLATFORMS
61
66
  ruby
data/README.md CHANGED
@@ -8,172 +8,118 @@
8
8
 
9
9
 
10
10
  ## Introduction
11
- `TappingDevice` makes the objects tell you what they do, so you don't need to track them yourself.
11
+ As the name states, `TappingDevice` allows you to secretly listen to different events of an object:
12
12
 
13
- #### Contact Tracing For Objects
13
+ - `Method Calls` - what does the object do
14
+ - `Traces` - how is the object used by the application
15
+ - `State Mutations` - what happens inside the object
14
16
 
15
- The concept is very simple. It's basically like [contact tracing](https://en.wikipedia.org/wiki/Contact_tracing) for your Ruby objects. You can use
17
+ After collecting the events, `TappingDevice` will output them in a nice, readable format to either stdout or a file.
16
18
 
17
- - `print_calls(object)` to see what the object does
18
- - `print_traces(object)` to see how the object interacts with other objects (like used as an argument)
19
- - `print_mutations(object)` to see what actions changed the object's state (instance variables)
19
+ **Ultimately, its goal is to let you know all the information you need for debugging with just 1 line of code.**
20
20
 
21
- Still sounds vague? Let's see some examples:
21
+ ## Usages
22
22
 
23
- ### `print_calls` - Track Method Calls
23
+ ### Track Method Calls
24
24
 
25
- In [Discourse](https://github.com/discourse/discourse), it uses the `Guardian` class for authorization (like policy objects). It's barely visible in controller actions, but it does many checks under the hood. Now, let's say we want to know what the `Guardian` would do when a user creates a post; here's the controller action:
26
-
27
- ```ruby
28
- def create
29
- @manager_params = create_params
30
- @manager_params[:first_post_checks] = !is_api?
31
-
32
- manager = NewPostManager.new(current_user, @manager_params)
33
-
34
- if is_api?
35
- memoized_payload = DistributedMemoizer.memoize(signature_for(@manager_params), 120) do
36
- result = manager.perform
37
- MultiJson.dump(serialize_data(result, NewPostResultSerializer, root: false))
38
- end
39
-
40
- parsed_payload = JSON.parse(memoized_payload)
41
- backwards_compatible_json(parsed_payload, parsed_payload['success'])
42
- else
43
- result = manager.perform
44
- json = serialize_data(result, NewPostResultSerializer, root: false)
45
- backwards_compatible_json(json, result.success?)
46
- end
47
- end
48
- ```
49
-
50
- As you can see, it doesn't even exist in the controller action, which makes tracking it by reading code very hard to do.
51
-
52
- But with `TappingDevice`. You can use `print_calls` to show what method calls the object performs
53
-
54
- ```ruby
55
- def create
56
- # you can retrieve the current guardian object by calling guardian in the controller
57
- print_calls(guardian)
58
- @manager_params = create_params
59
-
60
- # .....
61
- ```
62
-
63
- Now, if you execute the code, like via tests:
64
-
65
- ```shell
66
- $ rspec spec/requests/posts_controller_spec.rb:603
67
- ```
68
-
69
- You can get all the method calls it performs with basically everything you need to know
25
+ By tracking an object's method calls, you'll be able to observe the object's behavior very easily
70
26
 
71
27
  <img src="https://github.com/st0012/tapping_device/blob/master/images/print_calls.png" alt="image of print_calls output" width="50%">
72
28
 
73
- Let's take a closer look at each entry. Everyone of them contains the method call's
74
- - method name
75
- - method source class/module
29
+ Each entry consists of 5 pieces of information:
30
+ - method name
31
+ - source of the method
76
32
  - call site
77
33
  - arguments
78
34
  - return value
79
35
 
80
36
  ![explanation of individual entry](https://github.com/st0012/tapping_device/blob/master/images/print_calls%20-%20single%20entry.png)
81
37
 
82
- These are the information you'd have to look up one by one manually (probably with many debug code writing). Now you can get all of them in just one line of code.
38
+ #### Helpers
83
39
 
40
+ - `print_calls(object)` - prints the result to stdout
41
+ - `write_calls(object, log_file: "file_name")` - writes the result to a file
42
+ - the default file is `/tmp/tapping_device.log`, but you can change it with `log_file: "new_path"` option
84
43
 
85
- ### `print_traces` - See The Object's Traces
44
+ #### Use Cases
45
+ - Understand a service object/form object's behavior
46
+ - Debug a messy controller
86
47
 
87
- If you're not interested in what an object does, but what it interacts with other parts of the program, e.g., used as arguments. You can use the `print_traces` helper. Let's see how `Discourse` uses the `manager` object when creating a post
48
+ ### Track Traces
88
49
 
89
- ```ruby
90
- def create
91
- @manager_params = create_params
92
- @manager_params[:first_post_checks] = !is_api?
93
-
94
- manager = NewPostManager.new(current_user, @manager_params)
95
-
96
- print_traces(manager)
97
- # .....
98
- ```
50
+ By tracking an object's traces, you'll be able to observe the object's journey in your application
99
51
 
100
- And after running the test case
52
+ ![image of print_traces output](https://github.com/st0012/tapping_device/blob/master/images/print_traces.png)
101
53
 
102
- ```shell
103
- $ rspec spec/requests/posts_controller_spec.rb:603
104
- ```
54
+ #### Helpers
105
55
 
106
- You will see that it performs 2 calls: `perform` and `perform_create_post`. And it's also used as `manager` argument in various of calls of the `NewPostManager` class.
56
+ - `print_traces(object)` - prints the result to stdout
57
+ - `write_traces(object, log_file: "file_name")` - writes the result to a file
58
+ - the default file is `/tmp/tapping_device.log`, but you can change it with `log_file: "new_path"` option
107
59
 
108
- ![image of print_traces output](https://github.com/st0012/tapping_device/blob/master/images/print_traces.png)
60
+ #### Use Cases
61
+ - Debug argument related issues
62
+ - Understand how a library uses your objects
109
63
 
110
- ### `print_mutations` - Display All State Changes At Once
64
+ ### Track State Mutations
111
65
 
112
- Another thing that often bothers developers in debugging is to track an object's internal state changes. And `tapping_device` allows you to see all state changes with just one line of code. Let me keep using [Discourse](https://github.com/discourse/discourse) to demonstrate it.
66
+ By tracking an object's traces, you'll be able to observe the state changes happen inside the object between each method call
113
67
 
114
- When updating a post, it uses an object called `PostRevisor` to revise it:
68
+ <img src="https://github.com/st0012/tapping_device/blob/master/images/print_mutations.png" alt="image of print_mutations output" width="50%">
115
69
 
116
- ```ruby
117
- # app/controllers/posts_controller.rb
118
- class PostsController
119
- def update
120
- # ......
121
- revisor = PostRevisor.new(post, topic)
122
- revisor.revise!(current_user, changes, opts)
123
- # ......
124
- end
125
- end
126
- ```
70
+ #### Helpers
127
71
 
128
- In the `PostReviser#revise!`, it uses many instance variables to track different information:
72
+ - `print_mutations(object)` - prints the result to stdout
73
+ - `write_mutations(object, log_file: "file_name")` - writes the result to a file
74
+ - the default file is `/tmp/tapping_device.log`, but you can change it with `log_file: "new_path"` option
129
75
 
130
- ```ruby
131
- # lib/post_revisor.rb
132
- def revise!(editor, fields, opts = {})
133
- @editor = editor
134
- @fields = fields.with_indifferent_access
135
- @opts = opts
76
+ #### Use Cases
77
+ - Debug state related issues
78
+ - Debug memoization issues
136
79
 
137
- @topic_changes = TopicChanges.new(@topic, editor)
138
-
139
- # ......
80
+ ### Track All Instances Of A Class
140
81
 
141
- @revised_at = @opts[:revised_at] || Time.now
142
- @last_version_at = @post.last_version_at || Time.now
82
+ It's not always easy to directly access the objects we want to track, especially when they're managed by a library (e.g. `ActiveRecord::Relation`). In such cases, you can use these helpers to track the class's instances:
143
83
 
144
- @version_changed = false
145
- @post_successfully_saved = true
84
+ - `print_instance_calls(ObjectKlass)`
85
+ - `print_instance_traces(ObjectKlass)`
86
+ - `print_instance_mutations(ObjectKlass)`
87
+ - `write_instance_calls(ObjectKlass)`
88
+ - `write_instance_traces(ObjectKlass)`
89
+ - `write_instance_mutations(ObjectKlass)`
146
90
 
147
- @validate_post = true
148
- # ......
149
- end
150
- ```
151
91
 
152
- Tracking the changes of that many instance variables can be a painful task, especially when we want to know the values before and after certain method call. This is why I created `print_mutations` to save us from this.
92
+ ### Use `with_HELPER_NAME` for chained method calls
153
93
 
154
- Like other helpers, you only need 1 line of code
94
+ In Ruby programs, we often chain multiple methods together like this:
155
95
 
156
96
  ```ruby
157
- # app/controllers/posts_controller.rb
158
- class PostsController
159
- def update
160
- # ......
161
- revisor = PostRevisor.new(post, topic)
162
- print_mutations(revisor)
163
- revisor.revise!(current_user, changes, opts)
164
- # ......
165
- end
166
- end
97
+ SomeService.new(params).perform
167
98
  ```
168
99
 
169
- And then you'll see all the state changes:
100
+ And to debug it, we'll need to break the method chain into
170
101
 
171
- <img src="https://github.com/st0012/tapping_device/blob/master/images/print_mutations.png" alt="image of print_mutations output" width="50%">
102
+ ```ruby
103
+ service = SomeService.new(params)
104
+ print_calls(service, options)
105
+ service.perform
106
+ ```
107
+
108
+ This kind of code changes are usually annoying, and that's one of the problems I want to solve with `TappingDevice`.
172
109
 
173
- Now you can see what method changes which states. And more importantly, you get to see all the sate changes at once!
110
+ So here's another option, just insert a `with_HELPER_NAME` call in between:
111
+
112
+ ```ruby
113
+ SomeService.new(params).with_print_calls(options).perform
114
+ ```
174
115
 
175
- **You can try these examples on [my fork of discourse](https://github.com/st0012/discourse/tree/demo-for-tapping-device)**
116
+ And it'll behave exactly like
176
117
 
118
+ ```ruby
119
+ service = SomeService.new(params)
120
+ print_calls(service, options)
121
+ service.perform
122
+ ```
177
123
 
178
124
  ## Installation
179
125
  Add this line to your application's Gemfile:
@@ -197,9 +143,9 @@ $ gem install tapping_device
197
143
  **Depending on the size of your application, `TappingDevice` could harm the performance significantly. So make sure you don't put it inside the production group**
198
144
 
199
145
 
200
- ### Advance Usages & Options
146
+ ## Advance Usages & Options
201
147
 
202
- #### Add Conditions With `.with`
148
+ ### Add Conditions With `.with`
203
149
 
204
150
  Sometimes we don't need to know all the calls or traces of an object; we just want some of them. In those cases, we can chain the helpers with `.with` to filter the calls/traces.
205
151
 
@@ -210,7 +156,29 @@ print_calls(object).with do |payload|
210
156
  end
211
157
  ```
212
158
 
213
- #### `colorize: false`
159
+ ### Options
160
+
161
+ There are many options you can pass when using a helper method. You can list all available options and their default value with
162
+
163
+ ```ruby
164
+ TappingDevice::Configurable::DEFAULTS #=> {
165
+ :filter_by_paths=>[],
166
+ :exclude_by_paths=>[],
167
+ :with_trace_to=>50,
168
+ :event_type=>:return,
169
+ :hijack_attr_methods=>false,
170
+ :track_as_records=>false,
171
+ :inspect=>false,
172
+ :colorize=>true,
173
+ :log_file=>"/tmp/tapping_device.log"
174
+ }
175
+ ```
176
+
177
+ Here are some commonly used options:
178
+
179
+ #### `colorize: false`
180
+
181
+ - default: `true`
214
182
 
215
183
  By default `print_calls` and `print_traces` colorize their output. If you don't want the colors, you can use `colorize: false` to disable it.
216
184
 
@@ -220,7 +188,9 @@ print_calls(object, colorize: false)
220
188
  ```
221
189
 
222
190
 
223
- #### `inspect: true`
191
+ #### `inspect: true`
192
+
193
+ - default: `false`
224
194
 
225
195
  As you might have noticed, all the objects are converted into strings with `#to_s` instead of `#inspect`. This is because when used on some Rails objects, `#inspect` can generate a significantly larger string than `#to_s`. For example:
226
196
 
@@ -229,6 +199,87 @@ post.to_s #=> #<Post:0x00007f89a55201d0>
229
199
  post.inspect #=> #<Post id: 649, user_id: 3, topic_id: 600, post_number: 1, raw: "Hello world", cooked: "<p>Hello world</p>", created_at: "2020-05-24 08:07:29", updated_at: "2020-05-24 08:07:29", reply_to_post_number: nil, reply_count: 0, quote_count: 0, deleted_at: nil, off_topic_count: 0, like_count: 0, incoming_link_count: 0, bookmark_count: 0, score: nil, reads: 0, post_type: 1, sort_order: 1, last_editor_id: 3, hidden: false, hidden_reason_id: nil, notify_moderators_count: 0, spam_count: 0, illegal_count: 0, inappropriate_count: 0, last_version_at: "2020-05-24 08:07:29", user_deleted: false, reply_to_user_id: nil, percent_rank: 1.0, notify_user_count: 0, like_score: 0, deleted_by_id: nil, edit_reason: nil, word_count: 2, version: 1, cook_method: 1, wiki: false, baked_at: "2020-05-24 08:07:29", baked_version: 2, hidden_at: nil, self_edits: 0, reply_quoted: false, via_email: false, raw_email: nil, public_version: 1, action_code: nil, image_url: nil, locked_by_id: nil, image_upload_id: nil>
230
200
  ```
231
201
 
202
+ #### `hijack_attr_methods: true`
203
+
204
+ - default: `false`
205
+ - except for `tap_mutation!` and `print_mutations`
206
+
207
+ Because `TracePoint` doesn't track methods generated by `attr_*` helpers (see [this issue](https://bugs.ruby-lang.org/issues/16383) for more info), we need to redefine those methods with the normal method definition.
208
+
209
+ For example, it generates
210
+
211
+ ```ruby
212
+ def name=(val)
213
+ @name = val
214
+ end
215
+ ```
216
+
217
+ for
218
+
219
+ ```ruby
220
+ attr_writer :name
221
+ ```
222
+
223
+ This hack will only be applied to the target instance with `instance_eval`. So other instances of the class remain untouched.
224
+
225
+ The default is `false` because
226
+
227
+ 1. Checking what methods are generated by `attr_*` helpers isn't free. It's an `O(n)` operation, where `n` is the number of methods the target object has.
228
+ 2. It's still unclear if this hack safe enough for most applications.
229
+
230
+
231
+ #### `ignore_private`
232
+
233
+ Sometimes we use many private methods to perform trivial operations, like
234
+
235
+ ```ruby
236
+ class Operation
237
+ def extras
238
+ dig_attribute("extras")
239
+ end
240
+
241
+ private
242
+
243
+ def data
244
+ @data
245
+ end
246
+
247
+ def dig_attribute(attr)
248
+ data.dig("attributes", attr)
249
+ end
250
+ end
251
+ ```
252
+
253
+ And we may not be interested in those method calls. If that's the case, you can use the `ignore_private` option
254
+
255
+ ```ruby
256
+ operation = Operation.new(params)
257
+ print_calls(operation, ignore_private: true) #=> only prints the `extras` call
258
+ ```
259
+
260
+ #### `only_private`
261
+
262
+ This option does the opposite of the `ignore_private` option does.
263
+
264
+
265
+ ### Global Configuration
266
+
267
+ If you don't want to pass options every time you use a helper, you can use global configuration to change the default values:
268
+
269
+ ```ruby
270
+ TappingDevice.config[:colorize] = false
271
+ TappingDevice.config[:hijack_attr_methods] = true
272
+ ```
273
+
274
+ And if you're using Rails, you can put the configs under `config/initializers/tapping_device.rb` like this:
275
+
276
+ ```ruby
277
+ if defined?(TappingDevice)
278
+ TappingDevice.config[:colorize] = false
279
+ TappingDevice.config[:hijack_attr_methods] = true
280
+ end
281
+ ```
282
+
232
283
 
233
284
  ### Lower-Level Helpers
234
285
  `print_calls` and `print_traces` aren't the only helpers you can get from `TappingDevice`. They are actually built on top of other helpers, which you can use as well. To know more about them, please check [this page](https://github.com/st0012/tapping_device/wiki/Advance-Usages)