tapping_device 0.5.4 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +14 -4
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +71 -0
- data/Gemfile +17 -0
- data/Makefile +3 -0
- data/lib/tapping_device.rb +12 -15
- data/lib/tapping_device/{configurable.rb → configuration.rb} +16 -9
- data/lib/tapping_device/method_hijacker.rb +4 -0
- data/lib/tapping_device/output.rb +6 -7
- data/lib/tapping_device/output/{payload.rb → payload_wrapper.rb} +47 -40
- data/lib/tapping_device/output/writer.rb +5 -3
- data/lib/tapping_device/payload.rb +23 -13
- data/lib/tapping_device/trackable.rb +1 -1
- data/lib/tapping_device/trackers/initialization_tracker.rb +22 -4
- data/lib/tapping_device/trackers/mutation_tracker.rb +3 -4
- data/lib/tapping_device/version.rb +1 -1
- data/tapping_device.gemspec +3 -18
- metadata +16 -116
- data/Gemfile.lock +0 -74
- data/lib/tapping_device/output/file_writer.rb +0 -21
- data/lib/tapping_device/output/stdout_writer.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9700574881872ce91eedf976fd5fa7c8506acfa1c0ea8819dc15eeef6e519a9b
|
|
4
|
+
data.tar.gz: 71b65b11ed57273a0c061f23141d5da92078a16f9a7c7f75e9aebb2de71c32c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7ead5f7a86fd942005a85394a0b59e309fc41bcf625369006ec848d2688722cf5fcc8651ad925c103536bef49e1d0a50f4aab75a177242c48873bc5703aea8cd
|
|
7
|
+
data.tar.gz: f7cab27f0e27937f8c5a8f8c08283ae376e5b7880dffa21857e48c3bcf6e17ed1cb265b5ef399b2f2d294bf5af97b6b26aef16589f97f502c9ebfa29178de0a8
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
name: Ruby
|
|
2
2
|
|
|
3
|
-
on:
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- master
|
|
8
|
+
pull_request:
|
|
4
9
|
|
|
5
10
|
jobs:
|
|
6
11
|
test:
|
|
@@ -8,9 +13,12 @@ jobs:
|
|
|
8
13
|
runs-on: ${{ matrix.os }}
|
|
9
14
|
strategy:
|
|
10
15
|
matrix:
|
|
11
|
-
rails_version: ['5.2', '6']
|
|
12
|
-
ruby_version: ['2.
|
|
16
|
+
rails_version: ['5.2', '6.0.0', '6.1.0']
|
|
17
|
+
ruby_version: ['2.7', '3.0']
|
|
13
18
|
os: [ubuntu-latest]
|
|
19
|
+
exclude:
|
|
20
|
+
- ruby_version: '3.0'
|
|
21
|
+
rails_version: '5.2'
|
|
14
22
|
steps:
|
|
15
23
|
- uses: actions/checkout@v1
|
|
16
24
|
|
|
@@ -34,7 +42,9 @@ jobs:
|
|
|
34
42
|
bundle install --jobs 4 --retry 3
|
|
35
43
|
|
|
36
44
|
- name: Run test with Rails ${{ matrix.rails_version }}
|
|
37
|
-
|
|
45
|
+
env:
|
|
46
|
+
RAILS_VERSION: ${{ matrix.rails_version }}
|
|
47
|
+
run: make test
|
|
38
48
|
|
|
39
49
|
- name: Publish Test Coverage
|
|
40
50
|
uses: paambaati/codeclimate-action@v2.6.0
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,76 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.6.0](https://github.com/st0012/tapping_device/tree/v0.6.0) (2021-04-25)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.7...v0.6.0)
|
|
6
|
+
|
|
7
|
+
**Implemented enhancements:**
|
|
8
|
+
|
|
9
|
+
- Support Ruby 3.0 [\#71](https://github.com/st0012/tapping_device/pull/71) ([st0012](https://github.com/st0012))
|
|
10
|
+
|
|
11
|
+
**Merged pull requests:**
|
|
12
|
+
|
|
13
|
+
- Drop activerecord requirement [\#73](https://github.com/st0012/tapping_device/pull/73) ([st0012](https://github.com/st0012))
|
|
14
|
+
- Improve file-writing tests [\#72](https://github.com/st0012/tapping_device/pull/72) ([st0012](https://github.com/st0012))
|
|
15
|
+
- Simplify output logic with Ruby' Logger class [\#70](https://github.com/st0012/tapping_device/pull/70) ([st0012](https://github.com/st0012))
|
|
16
|
+
- Refactor Payload classes [\#68](https://github.com/st0012/tapping_device/pull/68) ([st0012](https://github.com/st0012))
|
|
17
|
+
|
|
18
|
+
## [v0.5.7](https://github.com/st0012/tapping_device/tree/v0.5.7) (2020-09-09)
|
|
19
|
+
|
|
20
|
+
[Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.6...v0.5.7)
|
|
21
|
+
|
|
22
|
+
**Implemented enhancements:**
|
|
23
|
+
|
|
24
|
+
- Use pastel in output payload [\#62](https://github.com/st0012/tapping_device/issues/62)
|
|
25
|
+
|
|
26
|
+
**Closed issues:**
|
|
27
|
+
|
|
28
|
+
- Support tag option [\#64](https://github.com/st0012/tapping_device/issues/64)
|
|
29
|
+
|
|
30
|
+
**Merged pull requests:**
|
|
31
|
+
|
|
32
|
+
- Use pastel to replace handmade colorizing logic [\#66](https://github.com/st0012/tapping_device/pull/66) ([st0012](https://github.com/st0012))
|
|
33
|
+
- Add tag option [\#65](https://github.com/st0012/tapping_device/pull/65) ([st0012](https://github.com/st0012))
|
|
34
|
+
|
|
35
|
+
## [v0.5.6](https://github.com/st0012/tapping_device/tree/v0.5.6) (2020-07-17)
|
|
36
|
+
|
|
37
|
+
[Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.5...v0.5.6)
|
|
38
|
+
|
|
39
|
+
## [v0.5.5](https://github.com/st0012/tapping_device/tree/v0.5.5) (2020-07-16)
|
|
40
|
+
|
|
41
|
+
[Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.4...v0.5.5)
|
|
42
|
+
|
|
43
|
+
**Fixed bugs:**
|
|
44
|
+
|
|
45
|
+
- InitializationTracker's logic can cause error [\#60](https://github.com/st0012/tapping_device/issues/60)
|
|
46
|
+
|
|
47
|
+
**Closed issues:**
|
|
48
|
+
|
|
49
|
+
- Refactor get\_method\_from\_object [\#59](https://github.com/st0012/tapping_device/issues/59)
|
|
50
|
+
|
|
51
|
+
**Merged pull requests:**
|
|
52
|
+
|
|
53
|
+
- Fix init tracker [\#61](https://github.com/st0012/tapping_device/pull/61) ([st0012](https://github.com/st0012))
|
|
54
|
+
|
|
55
|
+
## [v0.5.4](https://github.com/st0012/tapping_device/tree/v0.5.4) (2020-07-05)
|
|
56
|
+
|
|
57
|
+
[Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.3...v0.5.4)
|
|
58
|
+
|
|
59
|
+
**Closed issues:**
|
|
60
|
+
|
|
61
|
+
- Add with\_print\_calls method [\#52](https://github.com/st0012/tapping_device/issues/52)
|
|
62
|
+
- Tapping any instance of class [\#51](https://github.com/st0012/tapping_device/issues/51)
|
|
63
|
+
- Add ignore\_private option [\#50](https://github.com/st0012/tapping_device/issues/50)
|
|
64
|
+
|
|
65
|
+
**Merged pull requests:**
|
|
66
|
+
|
|
67
|
+
- Restructure README.md [\#58](https://github.com/st0012/tapping_device/pull/58) ([st0012](https://github.com/st0012))
|
|
68
|
+
- Better support on private methods [\#57](https://github.com/st0012/tapping_device/pull/57) ([st0012](https://github.com/st0012))
|
|
69
|
+
- Add with\_\* helpers \(e.g. with\_print\_calls\) [\#56](https://github.com/st0012/tapping_device/pull/56) ([st0012](https://github.com/st0012))
|
|
70
|
+
- Add force\_recording option for debugging [\#55](https://github.com/st0012/tapping_device/pull/55) ([st0012](https://github.com/st0012))
|
|
71
|
+
- Add print\_instance\_\* and write\_instance\_\* helpers [\#54](https://github.com/st0012/tapping_device/pull/54) ([st0012](https://github.com/st0012))
|
|
72
|
+
- Fix tap\_init by adding c\_\* event type [\#53](https://github.com/st0012/tapping_device/pull/53) ([st0012](https://github.com/st0012))
|
|
73
|
+
|
|
3
74
|
## [v0.5.3](https://github.com/st0012/tapping_device/tree/v0.5.3) (2020-06-21)
|
|
4
75
|
|
|
5
76
|
[Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.2...v0.5.3)
|
data/Gemfile
CHANGED
|
@@ -2,3 +2,20 @@ source "https://rubygems.org"
|
|
|
2
2
|
|
|
3
3
|
# Specify your gem's dependencies in tapping_device.gemspec
|
|
4
4
|
gemspec
|
|
5
|
+
|
|
6
|
+
rails_version = ENV["RAILS_VERSION"]
|
|
7
|
+
rails_version = "6.1.0" if rails_version.nil?
|
|
8
|
+
|
|
9
|
+
if rails_version.to_f < 6
|
|
10
|
+
gem "sqlite3", "~> 1.3.0"
|
|
11
|
+
else
|
|
12
|
+
gem "sqlite3"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
gem "activerecord", "~> #{rails_version}"
|
|
16
|
+
|
|
17
|
+
gem "rake", "~> 13.0"
|
|
18
|
+
gem "rspec", "~> 3.0"
|
|
19
|
+
gem "simplecov", "~> 0.17.1"
|
|
20
|
+
gem "database_cleaner", "~> 2.0.0"
|
|
21
|
+
gem "pry"
|
data/Makefile
ADDED
data/lib/tapping_device.rb
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
require "
|
|
2
|
-
require "active_support/core_ext/module/introspection"
|
|
3
|
-
require "pry" # for using Method#source
|
|
1
|
+
require "method_source" # for using Method#source
|
|
4
2
|
|
|
5
3
|
require "tapping_device/version"
|
|
6
4
|
require "tapping_device/manageable"
|
|
7
5
|
require "tapping_device/payload"
|
|
8
6
|
require "tapping_device/output"
|
|
9
7
|
require "tapping_device/trackable"
|
|
10
|
-
require "tapping_device/
|
|
8
|
+
require "tapping_device/configuration"
|
|
11
9
|
require "tapping_device/exceptions"
|
|
12
10
|
require "tapping_device/method_hijacker"
|
|
13
11
|
require "tapping_device/trackers/initialization_tracker"
|
|
@@ -28,7 +26,6 @@ class TappingDevice
|
|
|
28
26
|
|
|
29
27
|
extend Manageable
|
|
30
28
|
|
|
31
|
-
include Configurable
|
|
32
29
|
include Output::Helpers
|
|
33
30
|
|
|
34
31
|
def initialize(options = {}, &block)
|
|
@@ -120,8 +117,10 @@ class TappingDevice
|
|
|
120
117
|
|
|
121
118
|
# this needs to be placed upfront so we can exclude noise before doing more work
|
|
122
119
|
def should_be_skipped_by_paths?(filepath)
|
|
123
|
-
options[:exclude_by_paths]
|
|
124
|
-
|
|
120
|
+
exclude_by_paths = options[:exclude_by_paths]
|
|
121
|
+
filter_by_paths = options[:filter_by_paths]
|
|
122
|
+
exclude_by_paths.any? { |pattern| pattern.match?(filepath) } ||
|
|
123
|
+
(filter_by_paths && !filter_by_paths.empty? && !filter_by_paths.any? { |pattern| pattern.match?(filepath) })
|
|
125
124
|
end
|
|
126
125
|
|
|
127
126
|
def is_tapping_device_call?(tp)
|
|
@@ -137,11 +136,11 @@ class TappingDevice
|
|
|
137
136
|
end
|
|
138
137
|
|
|
139
138
|
def with_condition_satisfied?(payload)
|
|
140
|
-
@with_condition.
|
|
139
|
+
@with_condition.nil? || @with_condition.call(payload)
|
|
141
140
|
end
|
|
142
141
|
|
|
143
142
|
def build_payload(tp:, filepath:, line_number:)
|
|
144
|
-
Payload.
|
|
143
|
+
Payload.new(
|
|
145
144
|
target: @target,
|
|
146
145
|
receiver: tp.self,
|
|
147
146
|
method_name: tp.callee_id,
|
|
@@ -152,16 +151,14 @@ class TappingDevice
|
|
|
152
151
|
line_number: line_number,
|
|
153
152
|
defined_class: tp.defined_class,
|
|
154
153
|
trace: get_traces(tp),
|
|
155
|
-
is_private_call
|
|
154
|
+
is_private_call: tp.defined_class.private_method_defined?(tp.callee_id),
|
|
155
|
+
tag: options[:tag],
|
|
156
156
|
tp: tp
|
|
157
|
-
|
|
157
|
+
)
|
|
158
158
|
end
|
|
159
159
|
|
|
160
160
|
def get_method_object_from(target, method_name)
|
|
161
|
-
|
|
162
|
-
rescue ArgumentError
|
|
163
|
-
method_method = Object.method(:method).unbind
|
|
164
|
-
method_method.bind(target).call(method_name)
|
|
161
|
+
Object.instance_method(:method).bind(target).call(method_name)
|
|
165
162
|
rescue NameError
|
|
166
163
|
# if any part of the program uses Refinement to extend its methods
|
|
167
164
|
# we might still get NoMethodError when trying to get that method outside the scope
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
require "active_support/configurable"
|
|
2
|
-
require "active_support/concern"
|
|
3
|
-
|
|
4
1
|
class TappingDevice
|
|
5
|
-
|
|
6
|
-
extend ActiveSupport::Concern
|
|
7
|
-
|
|
2
|
+
class Configuration
|
|
8
3
|
DEFAULTS = {
|
|
9
4
|
filter_by_paths: [],
|
|
10
5
|
exclude_by_paths: [],
|
|
@@ -16,12 +11,24 @@ class TappingDevice
|
|
|
16
11
|
only_private: false
|
|
17
12
|
}.merge(TappingDevice::Output::DEFAULT_OPTIONS)
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
def initialize
|
|
15
|
+
@options = {}
|
|
21
16
|
|
|
22
17
|
DEFAULTS.each do |key, value|
|
|
23
|
-
|
|
18
|
+
@options[key] = value
|
|
24
19
|
end
|
|
25
20
|
end
|
|
21
|
+
|
|
22
|
+
def [](key)
|
|
23
|
+
@options[key]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def []=(key, value)
|
|
27
|
+
@options[key] = value
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.config
|
|
32
|
+
@config ||= Configuration.new
|
|
26
33
|
end
|
|
27
34
|
end
|
|
@@ -20,10 +20,14 @@ class TappingDevice
|
|
|
20
20
|
|
|
21
21
|
def is_writer_method?(method_name)
|
|
22
22
|
has_definition_source?(method_name) && method_name.match?(/\w+=/) && target.method(method_name).source.match?(/attr_writer|attr_accessor/)
|
|
23
|
+
rescue MethodSource::SourceNotFoundError
|
|
24
|
+
false
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def is_reader_method?(method_name)
|
|
26
28
|
has_definition_source?(method_name) && target.method(method_name).source.match?(/attr_reader|attr_accessor/)
|
|
29
|
+
rescue MethodSource::SourceNotFoundError
|
|
30
|
+
false
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
def has_definition_source?(method_name)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "logger"
|
|
2
|
+
require "tapping_device/output/payload_wrapper"
|
|
2
3
|
require "tapping_device/output/writer"
|
|
3
|
-
require "tapping_device/output/stdout_writer"
|
|
4
|
-
require "tapping_device/output/file_writer"
|
|
5
4
|
|
|
6
5
|
class TappingDevice
|
|
7
6
|
module Output
|
|
@@ -13,16 +12,16 @@ class TappingDevice
|
|
|
13
12
|
|
|
14
13
|
module Helpers
|
|
15
14
|
def and_write(payload_method = nil, options: {}, &block)
|
|
16
|
-
and_output(payload_method, options: options,
|
|
15
|
+
and_output(payload_method, options: options, logger: Logger.new(options[:log_file]), &block)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
def and_print(payload_method = nil, options: {}, &block)
|
|
20
|
-
and_output(payload_method, options: options,
|
|
19
|
+
and_output(payload_method, options: options, logger: Logger.new($stdout), &block)
|
|
21
20
|
end
|
|
22
21
|
|
|
23
|
-
def and_output(payload_method = nil, options: {},
|
|
22
|
+
def and_output(payload_method = nil, options: {}, logger:, &block)
|
|
24
23
|
output_block = generate_output_block(payload_method, block)
|
|
25
|
-
@output_writer =
|
|
24
|
+
@output_writer = Writer.new(options: options, output_block: output_block, logger: logger)
|
|
26
25
|
self
|
|
27
26
|
end
|
|
28
27
|
|
|
@@ -1,17 +1,44 @@
|
|
|
1
|
+
require "pastel"
|
|
2
|
+
|
|
1
3
|
class TappingDevice
|
|
2
4
|
module Output
|
|
3
|
-
class
|
|
5
|
+
class PayloadWrapper
|
|
4
6
|
UNDEFINED = "[undefined]"
|
|
7
|
+
PRIVATE_MARK = " (private)"
|
|
8
|
+
|
|
9
|
+
PASTEL = Pastel.new
|
|
10
|
+
PASTEL.alias_color(:orange, :bright_red, :bright_yellow)
|
|
11
|
+
|
|
12
|
+
TappingDevice::Payload::ATTRS.each do |attr|
|
|
13
|
+
define_method attr do |options = {}|
|
|
14
|
+
@payload.send(attr)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias :is_private_call? :is_private_call
|
|
19
|
+
|
|
20
|
+
def method_head
|
|
21
|
+
@payload.method_head
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def location(options = {})
|
|
25
|
+
@payload.location(options)
|
|
26
|
+
end
|
|
5
27
|
|
|
6
28
|
alias :raw_arguments :arguments
|
|
7
29
|
alias :raw_return_value :return_value
|
|
8
30
|
|
|
31
|
+
def initialize(payload)
|
|
32
|
+
@payload = payload
|
|
33
|
+
end
|
|
34
|
+
|
|
9
35
|
def method_name(options = {})
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
36
|
+
name = ":#{@payload.method_name}"
|
|
37
|
+
|
|
38
|
+
name += " [#{tag}]" if tag
|
|
39
|
+
name += PRIVATE_MARK if is_private_call?
|
|
40
|
+
|
|
41
|
+
name
|
|
15
42
|
end
|
|
16
43
|
|
|
17
44
|
def arguments(options = {})
|
|
@@ -22,29 +49,13 @@ class TappingDevice
|
|
|
22
49
|
generate_string_result(raw_return_value, options[:inspect])
|
|
23
50
|
end
|
|
24
51
|
|
|
25
|
-
COLOR_CODES = {
|
|
26
|
-
green: 10,
|
|
27
|
-
yellow: 11,
|
|
28
|
-
blue: 12,
|
|
29
|
-
megenta: 13,
|
|
30
|
-
cyan: 14,
|
|
31
|
-
orange: 214
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
COLORS = COLOR_CODES.each_with_object({}) do |(name, code), hash|
|
|
35
|
-
hash[name] = "\u001b[38;5;#{code}m"
|
|
36
|
-
end.merge(
|
|
37
|
-
reset: "\u001b[0m",
|
|
38
|
-
nocolor: ""
|
|
39
|
-
)
|
|
40
|
-
|
|
41
52
|
PAYLOAD_ATTRIBUTES = {
|
|
42
|
-
method_name: {symbol: "", color:
|
|
43
|
-
location: {symbol: "from:", color:
|
|
44
|
-
return_value: {symbol: "=>", color:
|
|
45
|
-
arguments: {symbol: "<=", color:
|
|
46
|
-
ivar_changes: {symbol: "changes:\n", color:
|
|
47
|
-
defined_class: {symbol: "#", color:
|
|
53
|
+
method_name: {symbol: "", color: :bright_blue},
|
|
54
|
+
location: {symbol: "from:", color: :green},
|
|
55
|
+
return_value: {symbol: "=>", color: :magenta},
|
|
56
|
+
arguments: {symbol: "<=", color: :orange},
|
|
57
|
+
ivar_changes: {symbol: "changes:\n", color: :blue},
|
|
58
|
+
defined_class: {symbol: "#", color: :yellow}
|
|
48
59
|
}
|
|
49
60
|
|
|
50
61
|
PAYLOAD_ATTRIBUTES.each do |attribute, attribute_options|
|
|
@@ -54,10 +65,10 @@ class TappingDevice
|
|
|
54
65
|
|
|
55
66
|
# regenerate attributes with `colorize: true` support
|
|
56
67
|
define_method attribute do |options = {}|
|
|
57
|
-
call_result = send("original_#{attribute}", options)
|
|
68
|
+
call_result = send("original_#{attribute}", options).to_s
|
|
58
69
|
|
|
59
70
|
if options[:colorize]
|
|
60
|
-
|
|
71
|
+
PASTEL.send(color, call_result)
|
|
61
72
|
else
|
|
62
73
|
call_result
|
|
63
74
|
end
|
|
@@ -87,7 +98,7 @@ class TappingDevice
|
|
|
87
98
|
return unless arg_name
|
|
88
99
|
|
|
89
100
|
arg_name = ":#{arg_name}"
|
|
90
|
-
arg_name =
|
|
101
|
+
arg_name = PASTEL.orange(arg_name) if options[:colorize]
|
|
91
102
|
msg = "Passed as #{arg_name} in '#{defined_class(options)}##{method_name(options)}' at #{location(options)}\n"
|
|
92
103
|
msg += " > #{method_head}\n" if with_method_head
|
|
93
104
|
msg
|
|
@@ -104,17 +115,17 @@ class TappingDevice
|
|
|
104
115
|
end
|
|
105
116
|
|
|
106
117
|
def ivar_changes(options = {})
|
|
107
|
-
|
|
118
|
+
@payload.ivar_changes.map do |ivar, value_changes|
|
|
108
119
|
before = generate_string_result(value_changes[:before], options[:inspect])
|
|
109
120
|
after = generate_string_result(value_changes[:after], options[:inspect])
|
|
110
121
|
|
|
111
122
|
if options[:colorize]
|
|
112
|
-
ivar =
|
|
113
|
-
before =
|
|
114
|
-
after =
|
|
123
|
+
ivar = PASTEL.orange(ivar.to_s)
|
|
124
|
+
before = PASTEL.bright_blue(before.to_s)
|
|
125
|
+
after = PASTEL.bright_blue(after.to_s)
|
|
115
126
|
end
|
|
116
127
|
|
|
117
|
-
" #{ivar}: #{before
|
|
128
|
+
" #{ivar}: #{before} => #{after}"
|
|
118
129
|
end.join("\n")
|
|
119
130
|
end
|
|
120
131
|
|
|
@@ -130,10 +141,6 @@ class TappingDevice
|
|
|
130
141
|
|
|
131
142
|
private
|
|
132
143
|
|
|
133
|
-
def value_with_color(value, color)
|
|
134
|
-
"#{COLORS[color]}#{value}#{COLORS[:reset]}"
|
|
135
|
-
end
|
|
136
|
-
|
|
137
144
|
def generate_string_result(obj, inspect)
|
|
138
145
|
case obj
|
|
139
146
|
when Array
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
class TappingDevice
|
|
2
2
|
module Output
|
|
3
3
|
class Writer
|
|
4
|
-
def initialize(options
|
|
4
|
+
def initialize(options:, output_block:, logger:)
|
|
5
5
|
@options = options
|
|
6
6
|
@output_block = output_block
|
|
7
|
+
@logger = logger
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def write!(payload)
|
|
10
|
-
|
|
11
|
+
output = generate_output(payload)
|
|
12
|
+
@logger << output
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
private
|
|
14
16
|
|
|
15
17
|
def generate_output(payload)
|
|
16
|
-
@output_block.call(
|
|
18
|
+
@output_block.call(PayloadWrapper.new(payload), @options)
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
end
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
class TappingDevice
|
|
2
|
-
class Payload
|
|
2
|
+
class Payload
|
|
3
3
|
ATTRS = [
|
|
4
4
|
:target, :receiver, :method_name, :method_object, :arguments, :return_value, :filepath, :line_number,
|
|
5
|
-
:defined_class, :trace, :tp, :ivar_changes, :is_private_call
|
|
5
|
+
:defined_class, :trace, :tag, :tp, :ivar_changes, :is_private_call
|
|
6
6
|
]
|
|
7
7
|
|
|
8
|
-
ATTRS
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
12
|
-
end
|
|
8
|
+
attr_accessor(*ATTRS)
|
|
9
|
+
|
|
10
|
+
alias :is_private_call? :is_private_call
|
|
13
11
|
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
def initialize(
|
|
13
|
+
target:, receiver:, method_name:, method_object:, arguments:, return_value:, filepath:, line_number:,
|
|
14
|
+
defined_class:, trace:, tag:, tp:, is_private_call:
|
|
15
|
+
)
|
|
16
|
+
@target = target
|
|
17
|
+
@receiver = receiver
|
|
18
|
+
@method_name = method_name
|
|
19
|
+
@method_object = method_object
|
|
20
|
+
@arguments = arguments
|
|
21
|
+
@return_value = return_value
|
|
22
|
+
@filepath = filepath
|
|
23
|
+
@line_number = line_number
|
|
24
|
+
@defined_class = defined_class
|
|
25
|
+
@trace = trace
|
|
26
|
+
@tag = tag
|
|
27
|
+
@tp = tp
|
|
28
|
+
@ivar_changes = {}
|
|
29
|
+
@is_private_call = is_private_call
|
|
20
30
|
end
|
|
21
31
|
|
|
22
32
|
def method_head
|
|
@@ -36,7 +36,7 @@ class TappingDevice
|
|
|
36
36
|
define_method "#{output_action}_instance_#{subject}" do |target_klass, options = {}|
|
|
37
37
|
collection_proxy = AsyncCollectionProxy.new
|
|
38
38
|
|
|
39
|
-
tap_init!(target_klass, options) do |payload|
|
|
39
|
+
tap_init!(target_klass, options.merge(force_recording: true)) do |payload|
|
|
40
40
|
collection_proxy << send(helper_method_name, payload.return_value, options)
|
|
41
41
|
end
|
|
42
42
|
|
|
@@ -9,10 +9,19 @@ class TappingDevice
|
|
|
9
9
|
@options[:event_type] = [event_type, "c_#{event_type}"]
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
def track(object)
|
|
13
|
+
super
|
|
14
|
+
@is_active_record_model = defined?(ActiveRecord) && target.ancestors.include?(ActiveRecord::Base)
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
def build_payload(tp:, filepath:, line_number:)
|
|
13
19
|
payload = super
|
|
14
|
-
|
|
15
|
-
payload
|
|
20
|
+
|
|
21
|
+
return payload if @is_active_record_model
|
|
22
|
+
|
|
23
|
+
payload.return_value = payload.receiver
|
|
24
|
+
payload.receiver = target
|
|
16
25
|
payload
|
|
17
26
|
end
|
|
18
27
|
|
|
@@ -24,8 +33,17 @@ class TappingDevice
|
|
|
24
33
|
receiver = tp.self
|
|
25
34
|
method_name = tp.callee_id
|
|
26
35
|
|
|
27
|
-
if
|
|
28
|
-
|
|
36
|
+
if @is_active_record_model
|
|
37
|
+
# ActiveRecord redefines model classes' .new method,
|
|
38
|
+
# so instead of calling Model#initialize, it'll actually call Model.new
|
|
39
|
+
# see https://github.com/rails/rails/blob/master/activerecord/lib/active_record/inheritance.rb#L50
|
|
40
|
+
method_name == :new &&
|
|
41
|
+
receiver.is_a?(Class) &&
|
|
42
|
+
# this checks if the model class is the target class or a subclass of it
|
|
43
|
+
receiver.ancestors.include?(target) &&
|
|
44
|
+
# Model.new triggers both c_return and return events. so we should only return in 1 type of the events
|
|
45
|
+
# otherwise the callback will be triggered twice
|
|
46
|
+
tp.event == :return
|
|
29
47
|
else
|
|
30
48
|
method_name == :initialize && receiver.is_a?(target)
|
|
31
49
|
end
|
|
@@ -47,7 +47,7 @@ class TappingDevice
|
|
|
47
47
|
payload = super
|
|
48
48
|
|
|
49
49
|
if change_capturing_event?(tp)
|
|
50
|
-
payload
|
|
50
|
+
payload.ivar_changes = capture_ivar_changes
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
payload
|
|
@@ -55,15 +55,14 @@ class TappingDevice
|
|
|
55
55
|
|
|
56
56
|
def capture_ivar_changes
|
|
57
57
|
changes = {}
|
|
58
|
-
|
|
59
58
|
additional_keys = @latest_instance_variables.keys - @instance_variables_snapshot.keys
|
|
60
59
|
additional_keys.each do |key|
|
|
61
|
-
changes[key] = {before: Output::
|
|
60
|
+
changes[key] = {before: Output::PayloadWrapper::UNDEFINED, after: @latest_instance_variables[key]}
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
removed_keys = @instance_variables_snapshot.keys - @latest_instance_variables.keys
|
|
65
64
|
removed_keys.each do |key|
|
|
66
|
-
changes[key] = {before: @instance_variables_snapshot[key], after: Output::
|
|
65
|
+
changes[key] = {before: @instance_variables_snapshot[key], after: Output::PayloadWrapper::UNDEFINED}
|
|
67
66
|
end
|
|
68
67
|
|
|
69
68
|
remained_keys = @latest_instance_variables.keys - additional_keys
|
data/tapping_device.gemspec
CHANGED
|
@@ -15,30 +15,15 @@ Gem::Specification.new do |spec|
|
|
|
15
15
|
|
|
16
16
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
17
17
|
spec.metadata["source_code_uri"] = "https://github.com/st0012/tapping_device"
|
|
18
|
-
spec.metadata["changelog_uri"] = "https://github.com/st0012/tapping_device/
|
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/st0012/tapping_device/CHANGELOG.md"
|
|
19
19
|
|
|
20
20
|
# Specify which files should be added to the gem when it is released.
|
|
21
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
22
22
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
23
23
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
24
24
|
end
|
|
25
|
-
spec.bindir = "exe"
|
|
26
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
27
25
|
spec.require_paths = ["lib"]
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
else
|
|
32
|
-
spec.add_dependency "activerecord", ">= 5.2"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
spec.add_dependency "pry" # for using Method#source in MutationTracker
|
|
36
|
-
spec.add_dependency "activesupport"
|
|
37
|
-
|
|
38
|
-
spec.add_development_dependency "sqlite3", ">= 1.3.6"
|
|
39
|
-
spec.add_development_dependency "database_cleaner"
|
|
40
|
-
spec.add_development_dependency "bundler", "~> 2.0"
|
|
41
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
42
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
|
43
|
-
spec.add_development_dependency "simplecov", "0.17.1"
|
|
27
|
+
spec.add_dependency "method_source", "~> 1.0.0"
|
|
28
|
+
spec.add_dependency "pastel", "~> 0.7"
|
|
44
29
|
end
|
metadata
CHANGED
|
@@ -1,141 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tapping_device
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- st0012
|
|
8
8
|
autorequire:
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-05-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: method_source
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '5.2'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '5.2'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: pry
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: activesupport
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :runtime
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: sqlite3
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - ">="
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: 1.3.6
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - ">="
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: 1.3.6
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: database_cleaner
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: bundler
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - "~>"
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '2.0'
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
16
|
requirements:
|
|
94
17
|
- - "~>"
|
|
95
18
|
- !ruby/object:Gem::Version
|
|
96
|
-
version:
|
|
97
|
-
|
|
98
|
-
name: rake
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - "~>"
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '13.0'
|
|
104
|
-
type: :development
|
|
19
|
+
version: 1.0.0
|
|
20
|
+
type: :runtime
|
|
105
21
|
prerelease: false
|
|
106
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
23
|
requirements:
|
|
108
24
|
- - "~>"
|
|
109
25
|
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
26
|
+
version: 1.0.0
|
|
111
27
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
28
|
+
name: pastel
|
|
113
29
|
requirement: !ruby/object:Gem::Requirement
|
|
114
30
|
requirements:
|
|
115
31
|
- - "~>"
|
|
116
32
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
118
|
-
type: :
|
|
33
|
+
version: '0.7'
|
|
34
|
+
type: :runtime
|
|
119
35
|
prerelease: false
|
|
120
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
37
|
requirements:
|
|
122
38
|
- - "~>"
|
|
123
39
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
125
|
-
- !ruby/object:Gem::Dependency
|
|
126
|
-
name: simplecov
|
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - '='
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: 0.17.1
|
|
132
|
-
type: :development
|
|
133
|
-
prerelease: false
|
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - '='
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: 0.17.1
|
|
40
|
+
version: '0.7'
|
|
139
41
|
description: tapping_device lets you understand what your Ruby objects do without
|
|
140
42
|
digging into the code
|
|
141
43
|
email:
|
|
@@ -154,8 +56,8 @@ files:
|
|
|
154
56
|
- CHANGELOG.md
|
|
155
57
|
- CODE_OF_CONDUCT.md
|
|
156
58
|
- Gemfile
|
|
157
|
-
- Gemfile.lock
|
|
158
59
|
- LICENSE.txt
|
|
60
|
+
- Makefile
|
|
159
61
|
- README.md
|
|
160
62
|
- Rakefile
|
|
161
63
|
- bin/console
|
|
@@ -165,14 +67,12 @@ files:
|
|
|
165
67
|
- images/print_mutations.png
|
|
166
68
|
- images/print_traces.png
|
|
167
69
|
- lib/tapping_device.rb
|
|
168
|
-
- lib/tapping_device/
|
|
70
|
+
- lib/tapping_device/configuration.rb
|
|
169
71
|
- lib/tapping_device/exceptions.rb
|
|
170
72
|
- lib/tapping_device/manageable.rb
|
|
171
73
|
- lib/tapping_device/method_hijacker.rb
|
|
172
74
|
- lib/tapping_device/output.rb
|
|
173
|
-
- lib/tapping_device/output/
|
|
174
|
-
- lib/tapping_device/output/payload.rb
|
|
175
|
-
- lib/tapping_device/output/stdout_writer.rb
|
|
75
|
+
- lib/tapping_device/output/payload_wrapper.rb
|
|
176
76
|
- lib/tapping_device/output/writer.rb
|
|
177
77
|
- lib/tapping_device/payload.rb
|
|
178
78
|
- lib/tapping_device/trackable.rb
|
|
@@ -189,7 +89,7 @@ licenses:
|
|
|
189
89
|
metadata:
|
|
190
90
|
homepage_uri: https://github.com/st0012/tapping_device
|
|
191
91
|
source_code_uri: https://github.com/st0012/tapping_device
|
|
192
|
-
changelog_uri: https://github.com/st0012/tapping_device/
|
|
92
|
+
changelog_uri: https://github.com/st0012/tapping_device/CHANGELOG.md
|
|
193
93
|
post_install_message:
|
|
194
94
|
rdoc_options: []
|
|
195
95
|
require_paths:
|
|
@@ -205,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
205
105
|
- !ruby/object:Gem::Version
|
|
206
106
|
version: '0'
|
|
207
107
|
requirements: []
|
|
208
|
-
rubygems_version: 3.
|
|
108
|
+
rubygems_version: 3.2.15
|
|
209
109
|
signing_key:
|
|
210
110
|
specification_version: 4
|
|
211
111
|
summary: tapping_device lets you understand what your Ruby objects do without digging
|
data/Gemfile.lock
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
tapping_device (0.5.4)
|
|
5
|
-
activerecord (>= 5.2)
|
|
6
|
-
activesupport
|
|
7
|
-
pry
|
|
8
|
-
|
|
9
|
-
GEM
|
|
10
|
-
remote: https://rubygems.org/
|
|
11
|
-
specs:
|
|
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)
|
|
18
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
19
|
-
i18n (>= 0.7, < 2)
|
|
20
|
-
minitest (~> 5.1)
|
|
21
|
-
tzinfo (~> 1.1)
|
|
22
|
-
zeitwerk (~> 2.2, >= 2.2.2)
|
|
23
|
-
coderay (1.1.3)
|
|
24
|
-
concurrent-ruby (1.1.6)
|
|
25
|
-
database_cleaner (1.7.0)
|
|
26
|
-
diff-lcs (1.3)
|
|
27
|
-
docile (1.3.2)
|
|
28
|
-
i18n (1.8.3)
|
|
29
|
-
concurrent-ruby (~> 1.0)
|
|
30
|
-
json (2.3.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)
|
|
36
|
-
rake (13.0.1)
|
|
37
|
-
rspec (3.8.0)
|
|
38
|
-
rspec-core (~> 3.8.0)
|
|
39
|
-
rspec-expectations (~> 3.8.0)
|
|
40
|
-
rspec-mocks (~> 3.8.0)
|
|
41
|
-
rspec-core (3.8.2)
|
|
42
|
-
rspec-support (~> 3.8.0)
|
|
43
|
-
rspec-expectations (3.8.4)
|
|
44
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
45
|
-
rspec-support (~> 3.8.0)
|
|
46
|
-
rspec-mocks (3.8.1)
|
|
47
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
48
|
-
rspec-support (~> 3.8.0)
|
|
49
|
-
rspec-support (3.8.2)
|
|
50
|
-
simplecov (0.17.1)
|
|
51
|
-
docile (~> 1.1)
|
|
52
|
-
json (>= 1.8, < 3)
|
|
53
|
-
simplecov-html (~> 0.10.0)
|
|
54
|
-
simplecov-html (0.10.2)
|
|
55
|
-
sqlite3 (1.4.1)
|
|
56
|
-
thread_safe (0.3.6)
|
|
57
|
-
tzinfo (1.2.7)
|
|
58
|
-
thread_safe (~> 0.1)
|
|
59
|
-
zeitwerk (2.3.1)
|
|
60
|
-
|
|
61
|
-
PLATFORMS
|
|
62
|
-
ruby
|
|
63
|
-
|
|
64
|
-
DEPENDENCIES
|
|
65
|
-
bundler (~> 2.0)
|
|
66
|
-
database_cleaner
|
|
67
|
-
rake (~> 13.0)
|
|
68
|
-
rspec (~> 3.0)
|
|
69
|
-
simplecov (= 0.17.1)
|
|
70
|
-
sqlite3 (>= 1.3.6)
|
|
71
|
-
tapping_device!
|
|
72
|
-
|
|
73
|
-
BUNDLED WITH
|
|
74
|
-
2.1.1
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
class TappingDevice
|
|
2
|
-
module Output
|
|
3
|
-
class FileWriter < Writer
|
|
4
|
-
def initialize(options, output_block)
|
|
5
|
-
@path = options[:log_file]
|
|
6
|
-
|
|
7
|
-
File.write(@path, "") # clean file
|
|
8
|
-
|
|
9
|
-
super
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def write!(payload)
|
|
13
|
-
output = generate_output(payload)
|
|
14
|
-
|
|
15
|
-
File.open(@path, "a") do |f|
|
|
16
|
-
f << output
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|