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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8328ddf34918bc8be607eb8bad74e3588f435a13dcefdf0690dd7f03ec4774f
4
- data.tar.gz: d34dd35817a235e92e12f7c086a3911d11c8564851a29e3ae31676b9b699f67f
3
+ metadata.gz: 231efa59a44f630df303db52d0d3bb460698c02a116374838e4bad4d71d7f69e
4
+ data.tar.gz: ca80df8a0ea00350c1e074628425848b5cba4d7f53a7aa4176947d55a3164929
5
5
  SHA512:
6
- metadata.gz: c12632e9ecdfed8970b36f191f2d2ea736cf1dc61a12096559cf25dfd791ee22c240e80d0230ffad4dc334d8dd9e6071efb1d6372256e339cd4387f79316a995
7
- data.tar.gz: 92a81f59e1f130ea25a41e58fb06c4ca153fa0eaa021094c59782737d16af34160ccb257a42a1bdd0a589d3e739a17ebf126c2cf72e233a0b61eab133825311e
6
+ metadata.gz: 77131aab9e85a2661694ee57470b9067ee44d479d574cbe395eefabd7f88350eaf31071c4ed0d117b1608856e9e6beff9d7ccae592a665c8969231425dafdc43
7
+ data.tar.gz: c06dedd14da7798cf93d80ae0d4866928c9e2522184f453588691fdf1a3220b21cfdf953f04575f1015cc1cb58c5bcb2cb5673fd9384cf5515855d048d0bbdb3
Binary file
@@ -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 }} and publish result
37
- uses: paambaati/codeclimate-action@v2.3.0
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
- coverageCommand: bundle exec rake
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
@@ -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,36 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tapping_device (0.4.11)
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.2.2)
11
- activesupport (= 6.0.2.2)
12
- activerecord (6.0.2.2)
13
- activemodel (= 6.0.2.2)
14
- activesupport (= 6.0.2.2)
15
- activesupport (6.0.2.2)
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.2)
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.2)
28
+ i18n (1.8.3)
27
29
  concurrent-ruby (~> 1.0)
28
30
  json (2.3.0)
29
- method_source (0.9.2)
30
- minitest (5.14.0)
31
- pry (0.12.2)
32
- coderay (~> 1.1.0)
33
- method_source (~> 0.9.0)
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.0)
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
- ## Table of Content
16
- - [Introduction](#introduction)
17
- - [Print Object’s Traces](print-objects-traces)
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
- ## Introduction
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
- Sample usage:
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
- ### Print Object’s Traces
21
+ ## Usages
40
22
 
41
- Let your objects report to you, so you don’t need to guess how they work!
23
+ ### Track Method Calls
42
24
 
43
- ```ruby
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
- (Also see [print_calls_in_detail](#print_calls_in_detail))
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
- However, depending on the size of your application, tapping any object could **harm the performance significantly**. **Don't use this on production**
38
+ #### Helpers
66
39
 
67
- ## Installation
68
- Add this line to your application's Gemfile:
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
- ```ruby
71
- gem 'tapping_device', group: :development
72
- ```
44
+ #### Use Cases
45
+ - Understand a service object/form object's behavior
46
+ - Debug a messy controller
73
47
 
74
- And then execute:
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
- Or install it yourself as:
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
- ## Usages
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
- ### print_traces
60
+ #### Use Cases
61
+ - Debug argument related issues
62
+ - Understand how a library uses your objects
89
63
 
90
- It prints the object's trace. It's like mounting a GPS tracker + a spy camera on your object, so you can inspect your program through the object's eyes.
64
+ ### Track State Mutations
91
65
 
92
- ```ruby
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
- Passed as 'cart' in 'OrderCreationService#perform' at /Users/st0012/projects/tapping_device-demo/app/controllers/orders_controller.rb:10
103
- Passed as 'cart' in 'OrderCreationService#validate_cart' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:8
104
- Called :reserved_until FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:18
105
- Called :errors FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:9
106
- Passed as 'cart' in 'OrderCreationService#apply_discount' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:10
107
- Called :apply_discount FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:24
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
- ### print_calls_in_detail
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
- It prints the object's calls in detail (including call location, arguments, and return value). It's useful for observing an object's behavior when debugging.
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
- #### Options
116
- - `inspect:` - will print objects with `#inspect` instead of `#to_s` if set to `true` (very noisy when having large objects). Default is `false`.
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
- class OrdersController < ApplicationController
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
- The output's order might look strange. This is because `tapping_device` needs to wait for the call to return in order to have its return value.
102
+ ```ruby
103
+ service = SomeService.new(params)
104
+ print_calls(service, options)
105
+ service.perform
106
+ ```
148
107
 
149
- ### tap_init!
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
- `tap_init!(class)` - tracks a class’ instance initialization
110
+ So here's another option, just insert a `with_HELPER_NAME` call in between:
152
111
 
153
112
  ```ruby
154
- calls = []
155
- tap_init!(Student) do |payload|
156
- calls << [payload[:method_name], payload[:arguments]]
157
- end
113
+ SomeService.new(params).with_print_calls(options).perform
114
+ ```
158
115
 
159
- Student.new("Stan", 18)
160
- Student.new("Jane", 23)
116
+ And it'll behave exactly like
161
117
 
162
- puts(calls.to_s) #=> [[:initialize, {:name=>"Stan", :age=>18}], [:initialize, {:name=>"Jane", :age=>23}]]
118
+ ```ruby
119
+ service = SomeService.new(params)
120
+ print_calls(service, options)
121
+ service.perform
163
122
  ```
164
123
 
165
- ### tap_on!
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
- class PostsController < ApplicationController
171
- before_action :set_post, only: [:show, :edit, :update, :destroy]
128
+ gem 'tapping_device', group: :development
129
+ ```
172
130
 
173
- def show
174
- tap_on!(@post).and_print(:method_name_and_location)
175
- end
176
- end
131
+ And then execute:
132
+
133
+ ```
134
+ $ bundle
177
135
  ```
178
136
 
179
- And you can see these in log:
137
+ Or install it directly:
180
138
 
181
139
  ```
182
- name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
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
- Also check the `track_as_records` option if you want to track `ActiveRecord` records.
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
- `tap_passed!(target)` tracks method calls that **takes the target as its argument**. This is particularly useful when debugging libraries. It saves your time from jumping between files and check which path the object will go.
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
- class PostsController < ApplicationController
195
- # GET /posts/new
196
- def new
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
- `tap_assoc!(activerecord_object)` tracks association calls on a record, like `post.comments`
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
- tap_assoc!(order).and_print(:method_name_and_location)
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
- ### tap_sql!
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
- class PostsController < ApplicationController
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
- ### Options
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
- stan = Student.new("Stan", 18)
279
- tap_on!(stan, with_trace_to: 5)
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
- #### track_as_records
293
- It makes the device to track objects as they are ActiveRecord instances. For example:
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
- tap_on!(@post, track_as_records: true)
297
- post = Post.find(@post.id) # same record but a different object
298
- post.title #=> this call will be recorded as well
212
+ def name=(val)
213
+ @name = val
214
+ end
299
215
  ```
300
216
 
301
- #### exclude_by_paths
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
- tap_on!(@post, exclude_by_paths: [/active_record/]).and_print(:method_name_and_location)
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
- # versus
225
+ The default is `false` because
316
226
 
317
- name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
318
- user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
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
- You can also set `passed_at(with_method_head: true)` to see the method's head.
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
- - `detail_call_info`
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
- ### Advance Usages
243
+ def data
244
+ @data
245
+ end
381
246
 
382
- Tapping methods introduced above like `tap_on!` are designed for simple use cases. They're actually short for
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
- device = TappingDevice.new { # tapping action }
386
- device.tap_on!(object)
256
+ operation = Operation.new(params)
257
+ print_calls(operation, ignore_private: true) #=> only prints the `extras` call
387
258
  ```
388
259
 
389
- And if you want to do some more configurations like stopping them manually or setting stop condition, you must have a `TappingDevie` instance. You can either get them like the above code or save the return value of `tap_*!` method calls.
260
+ #### `only_private`
261
+
262
+ This option does the opposite of the `ignore_private` option does.
263
+
390
264
 
391
- #### Stop tapping
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
- Once you have a `TappingDevice` instance in hand, you will be able to stop the tapping by
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
- device.stop_when do |payload|
399
- device.calls.count >= 10 # stop after gathering 10 calls’ data
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
- Each `TappingDevice` instance can have 3 states:
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
- When debugging, we may create many device instances and tap objects in several places. Then it'll be quite annoying to manage their states. So `TappingDevice` has several class methods that allows you to manage all `TappingDevice` instances:
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
+