tapping_device 0.4.11 → 0.5.4
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/.github/workflows/ruby.yml +11 -4
- data/CHANGELOG.md +210 -0
- data/Gemfile.lock +18 -17
- data/README.md +182 -306
- data/images/print_calls - single entry.png +0 -0
- data/images/print_calls.png +0 -0
- data/images/print_mutations.png +0 -0
- data/images/print_traces.png +0 -0
- data/lib/tapping_device.rb +118 -115
- 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 +4 -78
- data/lib/tapping_device/trackable.rb +114 -18
- data/lib/tapping_device/trackers/association_call_tracker.rb +17 -0
- data/lib/tapping_device/trackers/initialization_tracker.rb +35 -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 +5 -3
- metadata +50 -17
- data/lib/tapping_device/sql_tapping_methods.rb +0 -89
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 231efa59a44f630df303db52d0d3bb460698c02a116374838e4bad4d71d7f69e
|
4
|
+
data.tar.gz: ca80df8a0ea00350c1e074628425848b5cba4d7f53a7aa4176947d55a3164929
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77131aab9e85a2661694ee57470b9067ee44d479d574cbe395eefabd7f88350eaf31071c4ed0d117b1608856e9e6beff9d7ccae592a665c8969231425dafdc43
|
7
|
+
data.tar.gz: c06dedd14da7798cf93d80ae0d4866928c9e2522184f453588691fdf1a3220b21cfdf953f04575f1015cc1cb58c5bcb2cb5673fd9384cf5515855d048d0bbdb3
|
data/.DS_Store
ADDED
Binary file
|
data/.github/workflows/ruby.yml
CHANGED
@@ -33,10 +33,17 @@ jobs:
|
|
33
33
|
gem install bundler
|
34
34
|
bundle install --jobs 4 --retry 3
|
35
35
|
|
36
|
-
- name: Run test with Rails ${{ matrix.rails_version }}
|
37
|
-
|
36
|
+
- name: Run test with Rails ${{ matrix.rails_version }}
|
37
|
+
run: bundle exec rake
|
38
|
+
|
39
|
+
- name: Publish Test Coverage
|
40
|
+
uses: paambaati/codeclimate-action@v2.6.0
|
38
41
|
env:
|
39
|
-
CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
|
42
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
43
|
+
if: ${{ env.CC_TEST_REPORTER_ID != '' }}
|
40
44
|
with:
|
41
|
-
|
45
|
+
# the coverage result should already be generated by the previous step
|
46
|
+
# so we don't need to provide and command in the step
|
47
|
+
# this is just a placeholder to avoid it run the default `yarn coverage` command
|
48
|
+
coverageCommand: ruby -v
|
42
49
|
debug: true
|
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,36 +1,38 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tapping_device (0.4
|
4
|
+
tapping_device (0.5.4)
|
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.
|
11
|
-
activesupport (= 6.0.
|
12
|
-
activerecord (6.0.
|
13
|
-
activemodel (= 6.0.
|
14
|
-
activesupport (= 6.0.
|
15
|
-
activesupport (6.0.
|
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
|
-
zeitwerk (~> 2.2)
|
21
|
-
coderay (1.1.
|
22
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
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)
|
25
27
|
docile (1.3.2)
|
26
|
-
i18n (1.8.
|
28
|
+
i18n (1.8.3)
|
27
29
|
concurrent-ruby (~> 1.0)
|
28
30
|
json (2.3.0)
|
29
|
-
method_source (0.
|
30
|
-
minitest (5.14.
|
31
|
-
pry (0.
|
32
|
-
coderay (~> 1.1
|
33
|
-
method_source (~>
|
31
|
+
method_source (1.0.0)
|
32
|
+
minitest (5.14.1)
|
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.3.
|
59
|
+
zeitwerk (2.3.1)
|
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
@@ -6,417 +6,292 @@
|
|
6
6
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/3e3732a6983785bccdbd/test_coverage)](https://codeclimate.com/github/st0012/tapping_device/test_coverage)
|
7
7
|
[![Open Source Helpers](https://www.codetriage.com/st0012/tapping_device/badges/users.svg)](https://www.codetriage.com/st0012/tapping_device)
|
8
8
|
|
9
|
-
## Related Posts
|
10
|
-
- [Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device](http://bit.ly/object-oriented-tracing)
|
11
|
-
- [Debug Rails issues effectively with tapping_device](https://dev.to/st0012/debug-rails-issues-effectively-with-tappingdevice-c7c)
|
12
|
-
- [Want to know more about your Rails app? Tap on your objects!](https://dev.to/st0012/want-to-know-more-about-your-rails-app-tap-on-your-objects-bd3)
|
13
9
|
|
10
|
+
## Introduction
|
11
|
+
As the name states, `TappingDevice` allows you to secretly listen to different events of an object:
|
14
12
|
|
15
|
-
|
16
|
-
-
|
17
|
-
|
18
|
-
- [Track Calls that Generates SQL Queries](#track-calls-that-generates-sql-queries)
|
19
|
-
- [Installation](#installation)
|
20
|
-
- [Usages](#usages)
|
21
|
-
- Tracing Helpers
|
22
|
-
- [print_traces](#print_traces)
|
23
|
-
- [print_calls_in_detail](#print_calls_in_detail)
|
24
|
-
- Tapping Methods
|
25
|
-
- [tap_init!](#tap_init)
|
26
|
-
- [tap_on!](#tap_on)
|
27
|
-
- [tap_passed!](#tap_passed)
|
28
|
-
- [tap_assoc!](#tap_assoc)
|
29
|
-
- [tap_sql!](#tap_sql)
|
30
|
-
- [Options](#options)
|
31
|
-
- [Payload](#payload-of-the-call)
|
32
|
-
- [Advance Usages](#advance-usages)
|
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
|
33
16
|
|
34
|
-
|
35
|
-
`tapping_device` is a debugging tool built based on a concept called `object-oriented tracing` and on top of Ruby's `TracePoint` class. It allows you to inspect an object’s behavior, and thus build the program’s execution path for later debugging. Here’s a post to explain how to use `object-oriented tracing` and this gem to improve your debugging workflow: [Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device](http://bit.ly/object-oriented-tracing).
|
17
|
+
After collecting the events, `TappingDevice` will output them in a nice, readable format to either stdout or a file.
|
36
18
|
|
37
|
-
|
19
|
+
**Ultimately, its goal is to let you know all the information you need for debugging with just 1 line of code.**
|
38
20
|
|
39
|
-
|
21
|
+
## Usages
|
40
22
|
|
41
|
-
|
23
|
+
### Track Method Calls
|
42
24
|
|
43
|
-
|
44
|
-
class OrdersController < ApplicationController
|
45
|
-
def create
|
46
|
-
@cart = Cart.find(order_params[:cart_id])
|
47
|
-
print_traces(@cart, exclude_by_paths: [/gems/])
|
48
|
-
@order = OrderCreationService.new.perform(@cart)
|
49
|
-
end
|
50
|
-
```
|
25
|
+
By tracking an object's method calls, you'll be able to observe the object's behavior very easily
|
51
26
|
|
52
|
-
|
53
|
-
Passed as 'cart' in 'OrderCreationService#perform' at /Users/st0012/projects/tapping_device-demo/app/controllers/orders_controller.rb:10
|
54
|
-
Passed as 'cart' in 'OrderCreationService#validate_cart' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:8
|
55
|
-
Called :reserved_until FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:18
|
56
|
-
Called :errors FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:9
|
57
|
-
Passed as 'cart' in 'OrderCreationService#apply_discount' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:10
|
58
|
-
Called :apply_discount FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:24
|
59
|
-
……
|
60
|
-
```
|
27
|
+
<img src="https://github.com/st0012/tapping_device/blob/master/images/print_calls.png" alt="image of print_calls output" width="50%">
|
61
28
|
|
62
|
-
|
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
|
63
35
|
|
36
|
+
![explanation of individual entry](https://github.com/st0012/tapping_device/blob/master/images/print_calls%20-%20single%20entry.png)
|
64
37
|
|
65
|
-
|
38
|
+
#### Helpers
|
66
39
|
|
67
|
-
|
68
|
-
|
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
|
69
43
|
|
70
|
-
|
71
|
-
|
72
|
-
|
44
|
+
#### Use Cases
|
45
|
+
- Understand a service object/form object's behavior
|
46
|
+
- Debug a messy controller
|
73
47
|
|
74
|
-
|
48
|
+
### Track Traces
|
75
49
|
|
76
|
-
|
77
|
-
$ bundle
|
78
|
-
```
|
50
|
+
By tracking an object's traces, you'll be able to observe the object's journey in your application
|
79
51
|
|
80
|
-
|
52
|
+
![image of print_traces output](https://github.com/st0012/tapping_device/blob/master/images/print_traces.png)
|
81
53
|
|
82
|
-
|
83
|
-
$ gem install tapping_device
|
84
|
-
```
|
54
|
+
#### Helpers
|
85
55
|
|
86
|
-
|
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
|
87
59
|
|
88
|
-
|
60
|
+
#### Use Cases
|
61
|
+
- Debug argument related issues
|
62
|
+
- Understand how a library uses your objects
|
89
63
|
|
90
|
-
|
64
|
+
### Track State Mutations
|
91
65
|
|
92
|
-
|
93
|
-
class OrdersController < ApplicationController
|
94
|
-
def create
|
95
|
-
@cart = Cart.find(order_params[:cart_id])
|
96
|
-
print_traces(@cart, exclude_by_paths: [/gems/])
|
97
|
-
@order = OrderCreationService.new.perform(@cart)
|
98
|
-
end
|
99
|
-
```
|
66
|
+
By tracking an object's traces, you'll be able to observe the state changes happen inside the object between each method call
|
100
67
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
110
81
|
|
111
|
-
|
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:
|
112
83
|
|
113
|
-
|
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)`
|
114
90
|
|
115
|
-
|
116
|
-
|
91
|
+
|
92
|
+
### Use `with_HELPER_NAME` for chained method calls
|
93
|
+
|
94
|
+
In Ruby programs, we often chain multiple methods together like this:
|
117
95
|
|
118
96
|
```ruby
|
119
|
-
|
120
|
-
def create
|
121
|
-
@cart = Cart.find(order_params[:cart_id])
|
122
|
-
service = OrderCreationService.new
|
123
|
-
print_calls_in_detail(service)
|
124
|
-
@order = service.perform(@cart)
|
125
|
-
end
|
97
|
+
SomeService.new(params).perform
|
126
98
|
```
|
127
99
|
|
128
|
-
|
129
|
-
:validate_cart # OrderCreationService
|
130
|
-
<= {:cart=>#<Cart id: 1, total: 10, customer_id: 1, promotion_id: nil, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
|
131
|
-
=> nil
|
132
|
-
FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:8
|
133
|
-
:apply_discount # OrderCreationService
|
134
|
-
<= {:cart=>#<Cart id: 1, total: 5, customer_id: 1, promotion_id: 1, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">, :promotion=>#<Promotion id: 1, amount: 0.5e1, customer_id: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
|
135
|
-
=> true
|
136
|
-
FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:10
|
137
|
-
:create_order # OrderCreationService
|
138
|
-
<= {:cart=>#<Cart id: 1, total: 5, customer_id: 1, promotion_id: 1, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
|
139
|
-
=> #<Order:0x00007f9ebcb17f08>
|
140
|
-
FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:11
|
141
|
-
:perform # OrderCreationService
|
142
|
-
<= {:cart=>#<Cart id: 1, total: 5, customer_id: 1, promotion_id: 1, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">, :promotion=>#<Promotion id: 1, amount: 0.5e1, customer_id: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
|
143
|
-
=> #<Order:0x00007f9ebcb17f08>
|
144
|
-
FROM /Users/st0012/projects/tapping_device-demo/app/controllers/orders_controller.rb:11
|
145
|
-
```
|
100
|
+
And to debug it, we'll need to break the method chain into
|
146
101
|
|
147
|
-
|
102
|
+
```ruby
|
103
|
+
service = SomeService.new(params)
|
104
|
+
print_calls(service, options)
|
105
|
+
service.perform
|
106
|
+
```
|
148
107
|
|
149
|
-
|
108
|
+
This kind of code changes are usually annoying, and that's one of the problems I want to solve with `TappingDevice`.
|
150
109
|
|
151
|
-
|
110
|
+
So here's another option, just insert a `with_HELPER_NAME` call in between:
|
152
111
|
|
153
112
|
```ruby
|
154
|
-
|
155
|
-
|
156
|
-
calls << [payload[:method_name], payload[:arguments]]
|
157
|
-
end
|
113
|
+
SomeService.new(params).with_print_calls(options).perform
|
114
|
+
```
|
158
115
|
|
159
|
-
|
160
|
-
Student.new("Jane", 23)
|
116
|
+
And it'll behave exactly like
|
161
117
|
|
162
|
-
|
118
|
+
```ruby
|
119
|
+
service = SomeService.new(params)
|
120
|
+
print_calls(service, options)
|
121
|
+
service.perform
|
163
122
|
```
|
164
123
|
|
165
|
-
|
166
|
-
|
167
|
-
`tap_on!(object)` - tracks any calls received by the object.
|
124
|
+
## Installation
|
125
|
+
Add this line to your application's Gemfile:
|
168
126
|
|
169
127
|
```ruby
|
170
|
-
|
171
|
-
|
128
|
+
gem 'tapping_device', group: :development
|
129
|
+
```
|
172
130
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
131
|
+
And then execute:
|
132
|
+
|
133
|
+
```
|
134
|
+
$ bundle
|
177
135
|
```
|
178
136
|
|
179
|
-
|
137
|
+
Or install it directly:
|
180
138
|
|
181
139
|
```
|
182
|
-
|
183
|
-
user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
|
184
|
-
to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
|
140
|
+
$ gem install tapping_device
|
185
141
|
```
|
186
142
|
|
187
|
-
|
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**
|
188
144
|
|
189
|
-
### tap_passed!
|
190
145
|
|
191
|
-
|
146
|
+
## Advance Usages & Options
|
147
|
+
|
148
|
+
### Add Conditions With `.with`
|
149
|
+
|
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.
|
192
151
|
|
193
152
|
```ruby
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
@post = Post.new
|
198
|
-
|
199
|
-
tap_passed!(@post) do |payload|
|
200
|
-
puts(payload.passed_at(with_method_head: true))
|
201
|
-
end
|
202
|
-
end
|
153
|
+
# only prints calls with name matches /foo/
|
154
|
+
print_calls(object).with do |payload|
|
155
|
+
payload.method_name.to_s.match?(/foo/)
|
203
156
|
end
|
204
157
|
```
|
205
158
|
|
206
|
-
|
207
|
-
Passed as 'record' in method ':polymorphic_mapping'
|
208
|
-
> def polymorphic_mapping(record)
|
209
|
-
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:131
|
210
|
-
Passed as 'klass' in method ':get_method_for_class'
|
211
|
-
> def get_method_for_class(klass)
|
212
|
-
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:269
|
213
|
-
Passed as 'record' in method ':handle_model'
|
214
|
-
> def handle_model(record)
|
215
|
-
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:227
|
216
|
-
Passed as 'record_or_hash_or_array' in method ':polymorphic_method'
|
217
|
-
> def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
|
218
|
-
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:139
|
219
|
-
```
|
220
|
-
|
221
|
-
### tap_assoc!
|
159
|
+
### Options
|
222
160
|
|
223
|
-
|
161
|
+
There are many options you can pass when using a helper method. You can list all available options and their default value with
|
224
162
|
|
225
163
|
```ruby
|
226
|
-
|
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
|
+
}
|
227
175
|
```
|
228
176
|
|
229
|
-
|
230
|
-
payments FROM /RUBY_PATH/gems/2.6.0/gems/jsonapi-resources-0.9.10/lib/jsonapi/resource.rb:124
|
231
|
-
line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:44
|
232
|
-
effective_line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:110
|
233
|
-
amending_orders FROM /MY_PROJECT/app/models/order.rb:385
|
234
|
-
amends_order FROM /MY_PROJECT/app/models/order.rb:432
|
235
|
-
```
|
177
|
+
Here are some commonly used options:
|
236
178
|
|
237
|
-
|
179
|
+
#### `colorize: false`
|
180
|
+
|
181
|
+
- default: `true`
|
182
|
+
|
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.
|
238
184
|
|
239
|
-
`tap_sql!(anything_that_generates_sql_queries)` tracks sql queries generated from the target
|
240
185
|
|
241
186
|
```ruby
|
242
|
-
|
243
|
-
def index
|
244
|
-
# simulate current_user
|
245
|
-
@current_user = User.last
|
246
|
-
# reusable ActiveRecord::Relation
|
247
|
-
@posts = Post.all
|
248
|
-
|
249
|
-
tap_sql!(@posts) do |payload|
|
250
|
-
puts("Method: #{payload[:method_name]} generated sql: #{payload[:sql]} from #{payload[:filepath]}:#{payload[:line_number]}")
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
187
|
+
print_calls(object, colorize: false)
|
254
188
|
```
|
255
189
|
|
256
|
-
```erb
|
257
|
-
<h1>Posts (<%= @posts.count %>)</h1>
|
258
|
-
......
|
259
|
-
<% @posts.each do |post| %>
|
260
|
-
......
|
261
|
-
<% end %>
|
262
|
-
......
|
263
|
-
<p>Posts created by you: <%= @posts.where(user: @current_user).count %></p>
|
264
|
-
```
|
265
190
|
|
266
|
-
|
267
|
-
Method: count generated sql: SELECT COUNT(*) FROM "posts" from /PROJECT_PATH/rails-6-sample/app/views/posts/index.html.erb:3
|
268
|
-
Method: each generated sql: SELECT "posts".* FROM "posts" from /PROJECT_PATH/rails-6-sample/app/views/posts/index.html.erb:16
|
269
|
-
Method: count generated sql: SELECT COUNT(*) FROM "posts" WHERE "posts"."user_id" = ? from /PROJECT_PATH/rails-6-sample/app/views/posts/index.html.erb:31
|
270
|
-
```
|
191
|
+
#### `inspect: true`
|
271
192
|
|
193
|
+
- default: `false`
|
272
194
|
|
273
|
-
|
274
|
-
#### with_trace_to
|
275
|
-
It takes an integer as the number of traces we want to put into `trace`. Default is `nil`, so `trace` would be empty.
|
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:
|
276
196
|
|
277
|
-
```ruby
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
stan.name
|
282
|
-
|
283
|
-
puts(device.calls.first.trace) #=>
|
284
|
-
/Users/st0012/projects/tapping_device/spec/tapping_device_spec.rb:287:in `block (4 levels) in <top (required)>'
|
285
|
-
/Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:257:in `instance_exec'
|
286
|
-
/Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:257:in `block in run'
|
287
|
-
/Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:503:in `block in with_around_and_singleton_context_hooks'
|
288
|
-
/Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:460:in `block in with_around_example_hooks'
|
289
|
-
/Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/hooks.rb:464:in `block in run'
|
197
|
+
``` ruby
|
198
|
+
post.to_s #=> #<Post:0x00007f89a55201d0>
|
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>
|
290
200
|
```
|
291
201
|
|
292
|
-
####
|
293
|
-
|
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
|
294
210
|
|
295
211
|
```ruby
|
296
|
-
|
297
|
-
|
298
|
-
|
212
|
+
def name=(val)
|
213
|
+
@name = val
|
214
|
+
end
|
299
215
|
```
|
300
216
|
|
301
|
-
|
302
|
-
It takes an array of call path patterns that we want to skip. This could be very helpful when working on a large project like Rails applications.
|
217
|
+
for
|
303
218
|
|
304
219
|
```ruby
|
305
|
-
|
220
|
+
attr_writer :name
|
306
221
|
```
|
307
222
|
|
308
|
-
|
309
|
-
_read_attribute FROM /RUBY_PATH/gems/2.6.0/gems/activerecord-5.2.0/lib/active_record/attribute_methods/read.rb:40
|
310
|
-
name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
|
311
|
-
_read_attribute FROM /RUBY_PATH/gems/2.6.0/gems/activerecord-5.2.0/lib/active_record/attribute_methods/read.rb:40
|
312
|
-
user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
|
313
|
-
.......
|
223
|
+
This hack will only be applied to the target instance with `instance_eval`. So other instances of the class remain untouched.
|
314
224
|
|
315
|
-
|
225
|
+
The default is `false` because
|
316
226
|
|
317
|
-
|
318
|
-
|
319
|
-
to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
|
320
|
-
```
|
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.
|
321
229
|
|
322
|
-
#### filter_by_paths
|
323
|
-
|
324
|
-
Like `exclude_by_paths`, but work in the opposite way.
|
325
|
-
|
326
|
-
|
327
|
-
### Payload of The Call
|
328
|
-
All tapping methods (start with `tap_`) takes a block and yield a `Payload` object as a block argument. It responds to
|
329
|
-
|
330
|
-
- `target` - the target for `tap_x` call
|
331
|
-
- `receiver` - the receiver object
|
332
|
-
- `method_name` - method’s name (symbol)
|
333
|
-
- e.g. `:name`
|
334
|
-
- `method_object` - the method object that's being called. It might be `nil` in some edge cases.
|
335
|
-
- `arguments` - arguments of the method call
|
336
|
-
- e.g. `{name: “Stan”, age: 25}`
|
337
|
-
- `return_value` - return value of the method call
|
338
|
-
- `filepath` - path to the file that performs the method call
|
339
|
-
- `line_number`
|
340
|
-
- `defined_class` - in which class that defines the method being called
|
341
|
-
- `trace` - stack trace of the call. Default is an empty array unless `with_trace_to` option is set
|
342
|
-
- `sql` - sql that generated from the call (only present in `tap_sql!` payloads)
|
343
|
-
- `tp` - trace point object of this call
|
344
|
-
|
345
|
-
|
346
|
-
#### Symbols for Payload Helpers
|
347
|
-
- `FROM` for method call’s location
|
348
|
-
- `<=` for arguments
|
349
|
-
- `=>` for return value
|
350
|
-
- `@` for defined class
|
351
|
-
|
352
|
-
#### Payload Helpers
|
353
|
-
- `method_name_and_location` - `initialize FROM /PROJECT_PATH/tapping_device/spec/payload_spec.rb:7`
|
354
|
-
- `method_name_and_arguments` - `initialize <= {:name=>\"Stan\", :age=>25}`
|
355
|
-
- `method_name_and_return_value` - `ten => 10`
|
356
|
-
- `method_name_and_defined_class` - `initialize @ Student`
|
357
|
-
- `passed_at` -
|
358
|
-
```
|
359
|
-
Passed as 'object' in method ':initialize'
|
360
|
-
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionview-6.0.0/lib/action_view/helpers/tags/label.rb:60
|
361
|
-
```
|
362
230
|
|
363
|
-
|
231
|
+
#### `ignore_private`
|
364
232
|
|
365
|
-
|
366
|
-
Passed as 'object' in method ':initialize'
|
367
|
-
> def initialize(template_object, object_name, method_name, object, tag_value)
|
368
|
-
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionview-6.0.0/lib/action_view/helpers/tags/label.rb:60
|
369
|
-
```
|
233
|
+
Sometimes we use many private methods to perform trivial operations, like
|
370
234
|
|
371
|
-
|
235
|
+
```ruby
|
236
|
+
class Operation
|
237
|
+
def extras
|
238
|
+
dig_attribute("extras")
|
239
|
+
end
|
372
240
|
|
373
|
-
|
374
|
-
initialize @ Student
|
375
|
-
<= {:name=>"Stan", :age=>25}
|
376
|
-
=> 25
|
377
|
-
FROM /Users/st0012/projects/tapping_device/spec/payload_spec.rb:7
|
378
|
-
```
|
241
|
+
private
|
379
242
|
|
380
|
-
|
243
|
+
def data
|
244
|
+
@data
|
245
|
+
end
|
381
246
|
|
382
|
-
|
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
|
383
254
|
|
384
255
|
```ruby
|
385
|
-
|
386
|
-
|
256
|
+
operation = Operation.new(params)
|
257
|
+
print_calls(operation, ignore_private: true) #=> only prints the `extras` call
|
387
258
|
```
|
388
259
|
|
389
|
-
|
260
|
+
#### `only_private`
|
261
|
+
|
262
|
+
This option does the opposite of the `ignore_private` option does.
|
263
|
+
|
390
264
|
|
391
|
-
|
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
|
+
```
|
392
273
|
|
393
|
-
|
394
|
-
1. Manually calling `device.stop!`
|
395
|
-
2. Setting stop condition with `device.stop_when`, like
|
274
|
+
And if you're using Rails, you can put the configs under `config/initializers/tapping_device.rb` like this:
|
396
275
|
|
397
276
|
```ruby
|
398
|
-
|
399
|
-
|
277
|
+
if defined?(TappingDevice)
|
278
|
+
TappingDevice.config[:colorize] = false
|
279
|
+
TappingDevice.config[:hijack_attr_methods] = true
|
400
280
|
end
|
401
281
|
```
|
402
282
|
|
403
|
-
#### Device states & Managing Devices
|
404
283
|
|
405
|
-
|
284
|
+
### Lower-Level Helpers
|
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)
|
406
286
|
|
407
|
-
- `Initial` - means the instance is initialized but hasn't tapped on anything.
|
408
|
-
- `Enabled` - means the instance is tapping on something (has called `tap_*` methods).
|
409
|
-
- `Disabled` - means the instance has been disabled. It will no longer receive any call info.
|
410
287
|
|
411
|
-
|
288
|
+
### Related Blog Posts
|
289
|
+
- [Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device](http://bit.ly/object-oriented-tracing)
|
290
|
+
- [Debug Rails issues effectively with tapping_device](https://dev.to/st0012/debug-rails-issues-effectively-with-tappingdevice-c7c)
|
291
|
+
- [Want to know more about your Rails app? Tap on your objects!](https://dev.to/st0012/want-to-know-more-about-your-rails-app-tap-on-your-objects-bd3)
|
412
292
|
|
413
|
-
- `TappingDevice.devices` - Lists all registered devices with `initial` or `enabled` state. Note that any instance that's been stopped will be removed from the list.
|
414
|
-
- `TappingDevice.stop_all!` - Stops all registered devices and remove them from the `devices` list.
|
415
|
-
- `TappingDevice.suspend_new!` - Suspends any device instance from changing their state from `initial` to `enabled`. Which means any `tap_*` calls after it will no longer work.
|
416
|
-
- `TappingDevice.reset!` - Cancels `suspend_new` (if called) and stops/removes all created devices. Useful to reset the environment between test cases.
|
417
293
|
|
418
294
|
## Development
|
419
|
-
|
420
295
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
421
296
|
|
422
297
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
@@ -432,3 +307,4 @@ The gem is available as open-source under the terms of the [MIT License](https:/
|
|
432
307
|
## Code of Conduct
|
433
308
|
|
434
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
|
+
|