tapping_device 0.5.1 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/CHANGELOG.md +210 -0
- data/Gemfile.lock +15 -14
- data/README.md +192 -74
- data/images/print_mutations.png +0 -0
- data/lib/tapping_device.rb +112 -138
- data/lib/tapping_device/configurable.rb +27 -0
- data/lib/tapping_device/exceptions.rb +12 -0
- data/lib/tapping_device/method_hijacker.rb +51 -0
- data/lib/tapping_device/output.rb +42 -0
- data/lib/tapping_device/output/file_writer.rb +21 -0
- data/lib/tapping_device/output/payload.rb +179 -0
- data/lib/tapping_device/output/stdout_writer.rb +9 -0
- data/lib/tapping_device/output/writer.rb +20 -0
- data/lib/tapping_device/payload.rb +2 -3
- data/lib/tapping_device/trackable.rb +100 -19
- data/lib/tapping_device/trackers/association_call_tracker.rb +17 -0
- data/lib/tapping_device/trackers/initialization_tracker.rb +44 -0
- data/lib/tapping_device/trackers/method_call_tracker.rb +9 -0
- data/lib/tapping_device/trackers/mutation_tracker.rb +112 -0
- data/lib/tapping_device/trackers/passed_tracker.rb +16 -0
- data/lib/tapping_device/version.rb +1 -1
- data/tapping_device.gemspec +3 -1
- metadata +42 -15
- data/lib/tapping_device/output_payload.rb +0 -145
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83a8ec6a373e181e3125d846a7621edf426441f68177406364ce67e268774f6a
|
4
|
+
data.tar.gz: aa9a5f8c937a33f8d1ea18e755e6cf6971fe6db5a6c3aa87329c9394bc90e916
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2343c68ade029e6323d606eb34564476051bb65ffa0631361d1c306fd47875c530ba5e2e4c164a5fe53e9b7c34d54d543a3a811855808af99c97afaa718beb47
|
7
|
+
data.tar.gz: d5270b82e2f8058512394f529c26f3f690f142982be36533504662468f8b23cbd981e2631cd10196505b9e0cd963e3c719e2fb24fd79d263a025bde804d6ebc1
|
data/.DS_Store
CHANGED
Binary file
|
data/CHANGELOG.md
ADDED
@@ -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)*
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tapping_device (0.5.
|
4
|
+
tapping_device (0.5.6)
|
5
5
|
activerecord (>= 5.2)
|
6
|
+
activesupport
|
7
|
+
pry
|
6
8
|
|
7
9
|
GEM
|
8
10
|
remote: https://rubygems.org/
|
9
11
|
specs:
|
10
|
-
activemodel (6.0.3.
|
11
|
-
activesupport (= 6.0.3.
|
12
|
-
activerecord (6.0.3.
|
13
|
-
activemodel (= 6.0.3.
|
14
|
-
activesupport (= 6.0.3.
|
15
|
-
activesupport (6.0.3.
|
12
|
+
activemodel (6.0.3.2)
|
13
|
+
activesupport (= 6.0.3.2)
|
14
|
+
activerecord (6.0.3.2)
|
15
|
+
activemodel (= 6.0.3.2)
|
16
|
+
activesupport (= 6.0.3.2)
|
17
|
+
activesupport (6.0.3.2)
|
16
18
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
19
|
i18n (>= 0.7, < 2)
|
18
20
|
minitest (~> 5.1)
|
19
21
|
tzinfo (~> 1.1)
|
20
22
|
zeitwerk (~> 2.2, >= 2.2.2)
|
21
|
-
coderay (1.1.
|
23
|
+
coderay (1.1.3)
|
22
24
|
concurrent-ruby (1.1.6)
|
23
25
|
database_cleaner (1.7.0)
|
24
26
|
diff-lcs (1.3)
|
@@ -26,11 +28,11 @@ GEM
|
|
26
28
|
i18n (1.8.3)
|
27
29
|
concurrent-ruby (~> 1.0)
|
28
30
|
json (2.3.0)
|
29
|
-
method_source (0.
|
31
|
+
method_source (1.0.0)
|
30
32
|
minitest (5.14.1)
|
31
|
-
pry (0.
|
32
|
-
coderay (~> 1.1
|
33
|
-
method_source (~>
|
33
|
+
pry (0.13.1)
|
34
|
+
coderay (~> 1.1)
|
35
|
+
method_source (~> 1.0)
|
34
36
|
rake (13.0.1)
|
35
37
|
rspec (3.8.0)
|
36
38
|
rspec-core (~> 3.8.0)
|
@@ -54,7 +56,7 @@ GEM
|
|
54
56
|
thread_safe (0.3.6)
|
55
57
|
tzinfo (1.2.7)
|
56
58
|
thread_safe (~> 0.1)
|
57
|
-
zeitwerk (2.
|
59
|
+
zeitwerk (2.4.0)
|
58
60
|
|
59
61
|
PLATFORMS
|
60
62
|
ruby
|
@@ -62,7 +64,6 @@ PLATFORMS
|
|
62
64
|
DEPENDENCIES
|
63
65
|
bundler (~> 2.0)
|
64
66
|
database_cleaner
|
65
|
-
pry
|
66
67
|
rake (~> 13.0)
|
67
68
|
rspec (~> 3.0)
|
68
69
|
simplecov (= 0.17.1)
|
data/README.md
CHANGED
@@ -8,106 +8,118 @@
|
|
8
8
|
|
9
9
|
|
10
10
|
## Introduction
|
11
|
-
|
11
|
+
As the name states, `TappingDevice` allows you to secretly listen to different events of an object:
|
12
12
|
|
13
|
-
|
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
|
-
|
17
|
+
After collecting the events, `TappingDevice` will output them in a nice, readable format to either stdout or a file.
|
16
18
|
|
17
|
-
|
18
|
-
- `print_traces(object)` to see how the object interacts with other objects (like used as an argument)
|
19
|
+
**Ultimately, its goal is to let you know all the information you need for debugging with just 1 line of code.**
|
19
20
|
|
20
|
-
|
21
|
+
## Usages
|
21
22
|
|
22
|
-
###
|
23
|
+
### Track Method Calls
|
23
24
|
|
24
|
-
|
25
|
+
By tracking an object's method calls, you'll be able to observe the object's behavior very easily
|
25
26
|
|
26
|
-
|
27
|
-
def create
|
28
|
-
@manager_params = create_params
|
29
|
-
@manager_params[:first_post_checks] = !is_api?
|
30
|
-
|
31
|
-
manager = NewPostManager.new(current_user, @manager_params)
|
32
|
-
|
33
|
-
if is_api?
|
34
|
-
memoized_payload = DistributedMemoizer.memoize(signature_for(@manager_params), 120) do
|
35
|
-
result = manager.perform
|
36
|
-
MultiJson.dump(serialize_data(result, NewPostResultSerializer, root: false))
|
37
|
-
end
|
38
|
-
|
39
|
-
parsed_payload = JSON.parse(memoized_payload)
|
40
|
-
backwards_compatible_json(parsed_payload, parsed_payload['success'])
|
41
|
-
else
|
42
|
-
result = manager.perform
|
43
|
-
json = serialize_data(result, NewPostResultSerializer, root: false)
|
44
|
-
backwards_compatible_json(json, result.success?)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
```
|
27
|
+
<img src="https://github.com/st0012/tapping_device/blob/master/images/print_calls.png" alt="image of print_calls output" width="50%">
|
48
28
|
|
49
|
-
|
29
|
+
Each entry consists of 5 pieces of information:
|
30
|
+
- method name
|
31
|
+
- source of the method
|
32
|
+
- call site
|
33
|
+
- arguments
|
34
|
+
- return value
|
50
35
|
|
51
|
-
|
36
|
+
![explanation of individual entry](https://github.com/st0012/tapping_device/blob/master/images/print_calls%20-%20single%20entry.png)
|
52
37
|
|
53
|
-
|
54
|
-
def create
|
55
|
-
# you can retrieve the current guardian object by calling guardian in the controller
|
56
|
-
print_calls(guardian)
|
57
|
-
@manager_params = create_params
|
58
|
-
|
59
|
-
# .....
|
60
|
-
```
|
38
|
+
#### Helpers
|
61
39
|
|
62
|
-
|
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
|
63
43
|
|
64
|
-
|
65
|
-
|
66
|
-
|
44
|
+
#### Use Cases
|
45
|
+
- Understand a service object/form object's behavior
|
46
|
+
- Debug a messy controller
|
67
47
|
|
68
|
-
|
48
|
+
### Track Traces
|
69
49
|
|
70
|
-
|
50
|
+
By tracking an object's traces, you'll be able to observe the object's journey in your application
|
71
51
|
|
72
|
-
|
73
|
-
- method name
|
74
|
-
- method source class/module
|
75
|
-
- call site
|
76
|
-
- arguments
|
77
|
-
- return value
|
52
|
+
![image of print_traces output](https://github.com/st0012/tapping_device/blob/master/images/print_traces.png)
|
78
53
|
|
79
|
-
|
54
|
+
#### Helpers
|
80
55
|
|
81
|
-
|
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
|
82
59
|
|
60
|
+
#### Use Cases
|
61
|
+
- Debug argument related issues
|
62
|
+
- Understand how a library uses your objects
|
83
63
|
|
84
|
-
###
|
64
|
+
### Track State Mutations
|
85
65
|
|
86
|
-
|
66
|
+
By tracking an object's traces, you'll be able to observe the state changes happen inside the object between each method call
|
87
67
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
68
|
+
<img src="https://github.com/st0012/tapping_device/blob/master/images/print_mutations.png" alt="image of print_mutations output" width="50%">
|
69
|
+
|
70
|
+
#### Helpers
|
71
|
+
|
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
|
75
|
+
|
76
|
+
#### Use Cases
|
77
|
+
- Debug state related issues
|
78
|
+
- Debug memoization issues
|
79
|
+
|
80
|
+
### Track All Instances Of A Class
|
94
81
|
|
95
|
-
|
96
|
-
|
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:
|
83
|
+
|
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)`
|
90
|
+
|
91
|
+
|
92
|
+
### Use `with_HELPER_NAME` for chained method calls
|
93
|
+
|
94
|
+
In Ruby programs, we often chain multiple methods together like this:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
SomeService.new(params).perform
|
97
98
|
```
|
98
99
|
|
99
|
-
And
|
100
|
+
And to debug it, we'll need to break the method chain into
|
100
101
|
|
101
|
-
```
|
102
|
-
|
102
|
+
```ruby
|
103
|
+
service = SomeService.new(params)
|
104
|
+
print_calls(service, options)
|
105
|
+
service.perform
|
103
106
|
```
|
104
107
|
|
105
|
-
|
108
|
+
This kind of code changes are usually annoying, and that's one of the problems I want to solve with `TappingDevice`.
|
106
109
|
|
107
|
-
|
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
|
+
```
|
108
115
|
|
109
|
-
|
116
|
+
And it'll behave exactly like
|
110
117
|
|
118
|
+
```ruby
|
119
|
+
service = SomeService.new(params)
|
120
|
+
print_calls(service, options)
|
121
|
+
service.perform
|
122
|
+
```
|
111
123
|
|
112
124
|
## Installation
|
113
125
|
Add this line to your application's Gemfile:
|
@@ -131,9 +143,9 @@ $ gem install tapping_device
|
|
131
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**
|
132
144
|
|
133
145
|
|
134
|
-
|
146
|
+
## Advance Usages & Options
|
135
147
|
|
136
|
-
|
148
|
+
### Add Conditions With `.with`
|
137
149
|
|
138
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.
|
139
151
|
|
@@ -144,7 +156,29 @@ print_calls(object).with do |payload|
|
|
144
156
|
end
|
145
157
|
```
|
146
158
|
|
147
|
-
|
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`
|
148
182
|
|
149
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.
|
150
184
|
|
@@ -154,7 +188,9 @@ print_calls(object, colorize: false)
|
|
154
188
|
```
|
155
189
|
|
156
190
|
|
157
|
-
#### `inspect: true`
|
191
|
+
#### `inspect: true`
|
192
|
+
|
193
|
+
- default: `false`
|
158
194
|
|
159
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:
|
160
196
|
|
@@ -163,6 +199,87 @@ post.to_s #=> #
|
|
163
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>
|
164
200
|
```
|
165
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
|
+
|
166
283
|
|
167
284
|
### Lower-Level Helpers
|
168
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)
|
@@ -190,3 +307,4 @@ The gem is available as open-source under the terms of the [MIT License](https:/
|
|
190
307
|
## Code of Conduct
|
191
308
|
|
192
309
|
Everyone interacting in the TappingDevice project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/tapping_device/blob/master/CODE_OF_CONDUCT.md).
|
310
|
+
|