trip 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -3
- data/Gemfile +9 -6
- data/{MIT-LICENSE.txt → LICENSE.txt} +0 -0
- data/README.md +14 -16
- data/lib/trip.rb +167 -167
- data/lib/trip/event.rb +30 -31
- data/lib/trip/version.rb +1 -1
- data/spec/setup.rb +3 -3
- data/spec/trip_event_spec.rb +96 -0
- data/spec/trip_spec.rb +114 -157
- metadata +4 -4
- data/.bundle/config +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df109bcf001fd8ad968bd27973d20b5034a3c237
|
4
|
+
data.tar.gz: 2e93ecf46b29369798813bba40778f08a68ce080
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f6a8ddbc84e2fdfaa897fa4d1eea599ea0839bfdbebf7df8ad310722843957dad10ab2c4bb1ee0603c89b3e559d492d50be23e644780f941f5b0d3c2dc93f49
|
7
|
+
data.tar.gz: 3059883e41d771a46821c529808bcaeabbf50ef0a70f473d780bb2a46feefd58645fbbf13e6e65a749b82ed4266df421fc8364a055610170f07d9af772ea8017
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
gemspec
|
3
|
-
group :test do
|
4
|
-
gem '
|
5
|
-
end
|
6
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gemspec
|
3
|
+
group :dev, :test do
|
4
|
+
gem 'pry', '~> 0.10.1', git: 'https://github.com/pry/pry.git'
|
5
|
+
end
|
6
|
+
group :test do
|
7
|
+
gem 'minitest', '~> 5.4', require: ['minitest', 'minitest/spec']
|
8
|
+
end
|
9
|
+
|
File without changes
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
__trip__
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/rpag/trip.svg?branch=master)](https://travis-ci.org/rpag/trip)
|
3
|
+
[![Build Status](https://travis-ci.org/rpag/trip.svg?branch=master)](https://travis-ci.org/rpag/trip)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/rpag/trip/badges/gpa.svg)](https://codeclimate.com/github/rpag/trip)
|
5
5
|
|
6
6
|
trip is a concurrent tracer for the ruby programming language. It yields control
|
@@ -10,17 +10,6 @@ It can be useful when building developer tools like a debugger or if you want to
|
|
10
10
|
step through code progmatically at runtime.
|
11
11
|
|
12
12
|
|
13
|
-
__Limitations__
|
14
|
-
|
15
|
-
trip is implemented with "Thread#set_trace_func". It can be a bottleneck,
|
16
|
-
especially when there are a large number of events being created. I have seen
|
17
|
-
ruby grind to a halt when the codepath being traced is busy. It wouldn't be a good
|
18
|
-
library to use with something like a production rails application, but it can be
|
19
|
-
useful when building developer tools.
|
20
|
-
|
21
|
-
"Thread#set_trace_func" isn't well supported on any ruby implementation but the
|
22
|
-
official MRI/CRuby implementations, so jruby+rubinius aren't supported.
|
23
|
-
|
24
13
|
__Examples__
|
25
14
|
|
26
15
|
__1.__
|
@@ -68,8 +57,8 @@ e3 = trip.resume # returns nil (thread exits)
|
|
68
57
|
|
69
58
|
__3.__
|
70
59
|
|
71
|
-
Trip::Event#binding can be used to evaluate ruby while the trip
|
72
|
-
thread is sleeping. The example returns the value of the local
|
60
|
+
Trip::Event#binding can be used to evaluate ruby while the trip
|
61
|
+
thread is sleeping. The example returns the value of the local
|
73
62
|
variable "x" after the add method has been called.
|
74
63
|
|
75
64
|
```ruby
|
@@ -90,7 +79,7 @@ __Install__
|
|
90
79
|
rubygems:
|
91
80
|
|
92
81
|
gem install trip
|
93
|
-
|
82
|
+
|
94
83
|
git:
|
95
84
|
|
96
85
|
git clone https://github.com/rpag/trip.git
|
@@ -98,6 +87,15 @@ git:
|
|
98
87
|
gem build trip.gemspec
|
99
88
|
gem install *.gem
|
100
89
|
|
90
|
+
__Contributing__
|
91
|
+
|
92
|
+
1. Fork it ( https://github.com/rpag/trip/fork )
|
93
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
94
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
95
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
96
|
+
5. Create a new Pull Request
|
97
|
+
|
98
|
+
|
101
99
|
__License__
|
102
100
|
|
103
|
-
|
101
|
+
MIT, see LICENSE.txt for details.
|
data/lib/trip.rb
CHANGED
@@ -1,167 +1,167 @@
|
|
1
|
-
class Trip
|
2
|
-
require 'thread'
|
3
|
-
require_relative 'trip/event'
|
4
|
-
require_relative 'trip/version'
|
5
|
-
|
6
|
-
NotStartedError = Class.new(RuntimeError)
|
7
|
-
NotFinishedError = Class.new(RuntimeError)
|
8
|
-
|
9
|
-
RUN_STATE = 'run'
|
10
|
-
SLEEP_STATE = 'sleep'
|
11
|
-
END_STATE = [nil, false]
|
12
|
-
CALL_E = ['call', 'c-call']
|
13
|
-
RETURN_E = ['return', 'c-return']
|
14
|
-
PAUSE_P = Proc.new { |event|
|
15
|
-
CALL_E.include?(event.name) or RETURN_E.include?(event.name)
|
16
|
-
}
|
17
|
-
|
18
|
-
#
|
19
|
-
# @param [Proc] &block
|
20
|
-
# a block of code
|
21
|
-
#
|
22
|
-
# @return [Trip]
|
23
|
-
# returns an instance of Trip
|
24
|
-
#
|
25
|
-
def initialize(&block)
|
26
|
-
if block.equal?(nil)
|
27
|
-
raise ArgumentError, '
|
28
|
-
end
|
29
|
-
@thread = nil
|
30
|
-
@block = block
|
31
|
-
@queue = nil
|
32
|
-
@pause = PAUSE_P
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
# @raise [ArgumentError]
|
37
|
-
# when no arguments are received
|
38
|
-
#
|
39
|
-
# @param [Proc] callable
|
40
|
-
# accepts a Proc or a block
|
41
|
-
#
|
42
|
-
# @return [Proc]
|
43
|
-
# returns a Proc
|
44
|
-
#
|
45
|
-
def pause?(callable = nil, &block)
|
46
|
-
pause = callable || block
|
47
|
-
if pause.equal?(nil)
|
48
|
-
raise ArgumentError, '
|
49
|
-
end
|
50
|
-
@pause = pause
|
51
|
-
end
|
52
|
-
|
53
|
-
#
|
54
|
-
# @return [Boolean]
|
55
|
-
# returns true when a trace has started
|
56
|
-
#
|
57
|
-
def started?
|
58
|
-
@thread != nil
|
59
|
-
end
|
60
|
-
|
61
|
-
#
|
62
|
-
# @return [Boolean]
|
63
|
-
# returns true when a tracer thread is running
|
64
|
-
#
|
65
|
-
def running?
|
66
|
-
@thread and @thread.status == RUN_STATE
|
67
|
-
end
|
68
|
-
|
69
|
-
#
|
70
|
-
# @return [Boolean]
|
71
|
-
# returns true when a tracer thread has finished
|
72
|
-
#
|
73
|
-
def finished?
|
74
|
-
@thread and END_STATE.include?(@thread.status)
|
75
|
-
end
|
76
|
-
|
77
|
-
#
|
78
|
-
# @return [Boolean]
|
79
|
-
# returns true when a tracer thread is sleeping
|
80
|
-
#
|
81
|
-
def sleeping?
|
82
|
-
@thread and @thread.status == SLEEP_STATE
|
83
|
-
end
|
84
|
-
|
85
|
-
#
|
86
|
-
# resume the tracer
|
87
|
-
#
|
88
|
-
# @raise [Trip::NotStartedError]
|
89
|
-
# when the start method has not been called yet
|
90
|
-
#
|
91
|
-
# @return [Trip::Event, nil]
|
92
|
-
# returns an event or nil
|
93
|
-
#
|
94
|
-
def resume
|
95
|
-
unless started?
|
96
|
-
raise NotStartedError, '
|
97
|
-
end
|
98
|
-
if sleeping?
|
99
|
-
@thread.wakeup
|
100
|
-
@queue.deq
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# start the tracer
|
106
|
-
#
|
107
|
-
# @raise [Trip::NotFinishedError]
|
108
|
-
# when a trace is already in progress
|
109
|
-
#
|
110
|
-
# @return [Trip::Event, nil]
|
111
|
-
# returns an event, or nil
|
112
|
-
#
|
113
|
-
def start
|
114
|
-
if started? and !finished?
|
115
|
-
raise NotFinishedError, '
|
116
|
-
end
|
117
|
-
@queue = Queue.new
|
118
|
-
@thread = Thread.new do
|
119
|
-
Thread.current.set_trace_func method(:on_event).to_proc
|
120
|
-
@block.call
|
121
|
-
Thread.current.set_trace_func(nil)
|
122
|
-
@queue.enq(nil)
|
123
|
-
end
|
124
|
-
@queue.deq
|
125
|
-
end
|
126
|
-
|
127
|
-
#
|
128
|
-
# stop the tracer
|
129
|
-
#
|
130
|
-
# @return [nil]
|
131
|
-
# returns nil
|
132
|
-
#
|
133
|
-
def stop
|
134
|
-
if @thread
|
135
|
-
@thread.set_trace_func(nil)
|
136
|
-
@thread.exit
|
137
|
-
@thread.join
|
138
|
-
nil
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
private
|
143
|
-
def on_event(name, file, lineno, method, binding, classname)
|
144
|
-
event = Event.new name, {
|
145
|
-
file:
|
146
|
-
lineno:
|
147
|
-
|
148
|
-
method:
|
149
|
-
binding:
|
150
|
-
}
|
151
|
-
if event.file != __FILE__ and @pause.call(event)
|
152
|
-
@queue.enq(event)
|
153
|
-
Thread.stop
|
154
|
-
end
|
155
|
-
rescue Exception => e
|
156
|
-
warn <<-CRASH.each_line.map(&:lstrip)
|
157
|
-
(trip) the tracer has crashed
|
158
|
-
|
159
|
-
#{e.class}:
|
160
|
-
#{e.message}
|
161
|
-
|
162
|
-
BACKTRACE
|
163
|
-
#{e.backtrace.join("\n")}
|
164
|
-
CRASH
|
165
|
-
Thread.current.set_trace_func(nil)
|
166
|
-
end
|
167
|
-
end
|
1
|
+
class Trip
|
2
|
+
require 'thread'
|
3
|
+
require_relative 'trip/event'
|
4
|
+
require_relative 'trip/version'
|
5
|
+
|
6
|
+
NotStartedError = Class.new(RuntimeError)
|
7
|
+
NotFinishedError = Class.new(RuntimeError)
|
8
|
+
|
9
|
+
RUN_STATE = 'run'
|
10
|
+
SLEEP_STATE = 'sleep'
|
11
|
+
END_STATE = [nil, false]
|
12
|
+
CALL_E = ['call', 'c-call']
|
13
|
+
RETURN_E = ['return', 'c-return']
|
14
|
+
PAUSE_P = Proc.new { |event|
|
15
|
+
CALL_E.include?(event.name) or RETURN_E.include?(event.name)
|
16
|
+
}
|
17
|
+
|
18
|
+
#
|
19
|
+
# @param [Proc] &block
|
20
|
+
# a block of code
|
21
|
+
#
|
22
|
+
# @return [Trip]
|
23
|
+
# returns an instance of Trip
|
24
|
+
#
|
25
|
+
def initialize(&block)
|
26
|
+
if block.equal?(nil)
|
27
|
+
raise ArgumentError, 'no block given'
|
28
|
+
end
|
29
|
+
@thread = nil
|
30
|
+
@block = block
|
31
|
+
@queue = nil
|
32
|
+
@pause = PAUSE_P
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# @raise [ArgumentError]
|
37
|
+
# when no arguments are received
|
38
|
+
#
|
39
|
+
# @param [Proc] callable
|
40
|
+
# accepts a Proc or a block
|
41
|
+
#
|
42
|
+
# @return [Proc]
|
43
|
+
# returns a Proc
|
44
|
+
#
|
45
|
+
def pause?(callable = nil, &block)
|
46
|
+
pause = callable || block
|
47
|
+
if pause.equal?(nil)
|
48
|
+
raise ArgumentError, 'no block given'
|
49
|
+
end
|
50
|
+
@pause = pause
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
# returns true when a trace has started
|
56
|
+
#
|
57
|
+
def started?
|
58
|
+
@thread != nil
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
# returns true when a tracer thread is running
|
64
|
+
#
|
65
|
+
def running?
|
66
|
+
@thread and @thread.status == RUN_STATE
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# @return [Boolean]
|
71
|
+
# returns true when a tracer thread has finished
|
72
|
+
#
|
73
|
+
def finished?
|
74
|
+
@thread and END_STATE.include?(@thread.status)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# @return [Boolean]
|
79
|
+
# returns true when a tracer thread is sleeping
|
80
|
+
#
|
81
|
+
def sleeping?
|
82
|
+
@thread and @thread.status == SLEEP_STATE
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# resume the tracer
|
87
|
+
#
|
88
|
+
# @raise [Trip::NotStartedError]
|
89
|
+
# when the start method has not been called yet
|
90
|
+
#
|
91
|
+
# @return [Trip::Event, nil]
|
92
|
+
# returns an event or nil
|
93
|
+
#
|
94
|
+
def resume
|
95
|
+
unless started?
|
96
|
+
raise NotStartedError, 'trace not started'
|
97
|
+
end
|
98
|
+
if sleeping?
|
99
|
+
@thread.wakeup
|
100
|
+
@queue.deq
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# start the tracer
|
106
|
+
#
|
107
|
+
# @raise [Trip::NotFinishedError]
|
108
|
+
# when a trace is already in progress
|
109
|
+
#
|
110
|
+
# @return [Trip::Event, nil]
|
111
|
+
# returns an event, or nil
|
112
|
+
#
|
113
|
+
def start
|
114
|
+
if started? and !finished?
|
115
|
+
raise NotFinishedError, 'trace not finished'
|
116
|
+
end
|
117
|
+
@queue = Queue.new
|
118
|
+
@thread = Thread.new do
|
119
|
+
Thread.current.set_trace_func method(:on_event).to_proc
|
120
|
+
@block.call
|
121
|
+
Thread.current.set_trace_func(nil)
|
122
|
+
@queue.enq(nil)
|
123
|
+
end
|
124
|
+
@queue.deq
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# stop the tracer
|
129
|
+
#
|
130
|
+
# @return [nil]
|
131
|
+
# returns nil
|
132
|
+
#
|
133
|
+
def stop
|
134
|
+
if @thread
|
135
|
+
@thread.set_trace_func(nil)
|
136
|
+
@thread.exit
|
137
|
+
@thread.join
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def on_event(name, file, lineno, method, binding, classname)
|
144
|
+
event = Event.new name, {
|
145
|
+
file: file,
|
146
|
+
lineno: lineno,
|
147
|
+
mod: classname,
|
148
|
+
method: method,
|
149
|
+
binding: binding
|
150
|
+
}
|
151
|
+
if event.file != __FILE__ and @pause.call(event)
|
152
|
+
@queue.enq(event)
|
153
|
+
Thread.stop
|
154
|
+
end
|
155
|
+
rescue Exception => e
|
156
|
+
warn <<-CRASH.each_line.map(&:lstrip)
|
157
|
+
(trip) the tracer has crashed.
|
158
|
+
|
159
|
+
#{e.class}:
|
160
|
+
#{e.message}
|
161
|
+
|
162
|
+
BACKTRACE
|
163
|
+
#{e.backtrace.join("\n")}
|
164
|
+
CRASH
|
165
|
+
Thread.current.set_trace_func(nil)
|
166
|
+
end
|
167
|
+
end
|
data/lib/trip/event.rb
CHANGED
@@ -1,31 +1,30 @@
|
|
1
|
-
class Trip::Event < BasicObject
|
2
|
-
Kernel = ::Kernel
|
3
|
-
Time = ::Time
|
4
|
-
CALLS = %w(call c-call)
|
5
|
-
RETURNS = %w(return c-return)
|
6
|
-
|
7
|
-
attr_reader :name, :created_at
|
8
|
-
|
9
|
-
def initialize(name, event)
|
10
|
-
@name
|
11
|
-
@
|
12
|
-
@
|
13
|
-
end
|
14
|
-
|
15
|
-
[:file, :lineno, :
|
16
|
-
define_method(name) { @event[name] }
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
1
|
+
class Trip::Event < BasicObject
|
2
|
+
Kernel = ::Kernel
|
3
|
+
Time = ::Time
|
4
|
+
CALLS = %w(call c-call)
|
5
|
+
RETURNS = %w(return c-return)
|
6
|
+
|
7
|
+
attr_reader :name, :created_at
|
8
|
+
|
9
|
+
def initialize(name, event)
|
10
|
+
@name = name
|
11
|
+
@created_at = Time.now
|
12
|
+
@event = event
|
13
|
+
end
|
14
|
+
|
15
|
+
[:file, :lineno, :mod, :method, :binding].each do |name|
|
16
|
+
define_method(name) { @event[name] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
"#<Trip::Event:0x#{__id__.to_s(16)} name='#{name}' created_at='#{created_at}' file='#{file}' lineno='#{lineno}' module='#{mod}' method='#{method}' binding=#{binding.inspect}>"
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# @return [Binding]
|
25
|
+
# returns a binding for an instance of {Trip::Event}
|
26
|
+
#
|
27
|
+
def __binding__
|
28
|
+
Kernel.binding
|
29
|
+
end
|
30
|
+
end
|
data/lib/trip/version.rb
CHANGED
data/spec/setup.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
Bundler.require :default, :test
|
3
|
-
Minitest.autorun
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.require :default, :test
|
3
|
+
Minitest.autorun
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
describe Trip::Event do
|
3
|
+
class Y
|
4
|
+
def self.run
|
5
|
+
# ..
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:trip) do
|
10
|
+
Trip.new { Y.run }
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:event) do
|
14
|
+
trip.start
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
trip.stop
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#name' do
|
22
|
+
describe 'call and return from a method implemented in Ruby' do
|
23
|
+
it 'returns "call"' do
|
24
|
+
e = trip.start
|
25
|
+
assert_equal 'call', e.name
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns "return"' do
|
29
|
+
trip.start
|
30
|
+
e = trip.resume
|
31
|
+
assert_equal 'return', e.name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'call and return from a method implemented in C' do
|
36
|
+
let(:trip) do
|
37
|
+
Trip.new { Kernel.print '' }.tap do |trip|
|
38
|
+
trip.pause? { |e| e.mod == Kernel and e.method == :print }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns "c-call"' do
|
43
|
+
e = trip.start
|
44
|
+
assert_equal 'c-call', e.name
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns "c-return"' do
|
48
|
+
trip.start
|
49
|
+
e = trip.resume
|
50
|
+
assert_equal 'c-return', e.name
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#created_at' do
|
56
|
+
it 'returns a Time' do
|
57
|
+
assert_instance_of Time, event.created_at
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#mod' do
|
62
|
+
it 'returns a Module' do
|
63
|
+
assert_equal Y, event.mod
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#file' do
|
68
|
+
it 'returns __FILE__ from binding' do
|
69
|
+
assert_equal __FILE__, event.file
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#lineno' do
|
74
|
+
it 'returns __LINE__ from binding' do
|
75
|
+
assert_equal 4, event.lineno
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#method' do
|
80
|
+
it 'returns __method__ from binding' do
|
81
|
+
assert_equal :run, event.method
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#binding' do
|
86
|
+
it 'returns a binding' do
|
87
|
+
assert_instance_of Binding, event.binding
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#__binding__' do
|
92
|
+
it 'returns a binding for instance of Trip::Event' do
|
93
|
+
assert_equal true, Trip::Event === event.__binding__.eval('self')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/spec/trip_spec.rb
CHANGED
@@ -1,157 +1,114 @@
|
|
1
|
-
require_relative 'setup'
|
2
|
-
describe Trip do
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
e1 = @trip.start
|
116
|
-
assert_equal Planet, e1.module
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe '#method' do
|
121
|
-
it 'returns a method name' do
|
122
|
-
e1 = @trip.start
|
123
|
-
assert_equal :echo, e1.method
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe '#file' do
|
128
|
-
it 'returns a path' do
|
129
|
-
e1 = @trip.start
|
130
|
-
assert_equal __FILE__, e1.file
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe '#lineno' do
|
135
|
-
it 'returns an Integer' do
|
136
|
-
e1 = @trip.start
|
137
|
-
assert_kind_of Integer, e1.lineno
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe '#binding' do
|
142
|
-
it 'returns a Binding with access to the local variable "message"' do
|
143
|
-
@trip.pause? { |e| e.name == 'call' or e.name == 'return' }
|
144
|
-
e1 = @trip.start
|
145
|
-
e2 = @trip.resume
|
146
|
-
assert_equal 'ping', e2.binding.eval('message')
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe '#__binding__' do
|
151
|
-
it 'returns a Binding for an instance of Trip::Event' do
|
152
|
-
e1 = @trip.start
|
153
|
-
assert Trip::Event === e1.__binding__.eval('self')
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
1
|
+
require_relative 'setup'
|
2
|
+
describe Trip do
|
3
|
+
let(:trip) do
|
4
|
+
Trip.new { planet.echo('ping') }
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:planet) do
|
8
|
+
Planet.new
|
9
|
+
end
|
10
|
+
|
11
|
+
class Planet
|
12
|
+
def echo(message)
|
13
|
+
return message
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
unless trip.finished?
|
19
|
+
trip.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#initialize' do
|
24
|
+
it 'raises an ArgumentError without a block' do
|
25
|
+
assert_raises(ArgumentError) { Trip.new }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#start' do
|
30
|
+
it 'returns an instance of Trip::Event' do
|
31
|
+
assert Trip::Event === trip.start
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns nil with a false pause predicate' do
|
35
|
+
trip.pause? { false }
|
36
|
+
assert_equal nil, trip.start
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises Trip::NotFinishedError' do
|
40
|
+
trip.start
|
41
|
+
assert_raises(Trip::NotFinishedError) { trip.start }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#sleeping?' do
|
46
|
+
it 'returns true' do
|
47
|
+
trip.start
|
48
|
+
assert_equal true, trip.sleeping?
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns false' do
|
52
|
+
trip.start
|
53
|
+
trip.resume while trip.resume
|
54
|
+
assert_equal false, trip.sleeping?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#started?' do
|
59
|
+
it 'returns true' do
|
60
|
+
trip.start
|
61
|
+
assert_equal true, trip.started?
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns false' do
|
65
|
+
assert_equal false, trip.started?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#resume' do
|
70
|
+
it 'raises Trip::NotStartedError' do
|
71
|
+
assert_raises(Trip::NotStartedError) { trip.resume }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#pause?' do
|
76
|
+
it 'raises an ArgumentError' do
|
77
|
+
assert_raises(ArgumentError) { trip.pause? }
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'accepts a Proc' do
|
81
|
+
obj = Proc.new {}
|
82
|
+
assert_equal obj, trip.pause?(obj)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#finished?' do
|
87
|
+
it 'returns true' do
|
88
|
+
trip.start
|
89
|
+
trip.resume while trip.resume
|
90
|
+
assert_equal true, trip.finished?
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns false' do
|
94
|
+
trip.start
|
95
|
+
assert_equal false, trip.finished?
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns nil' do
|
99
|
+
assert_equal nil, trip.finished?
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#running?' do
|
104
|
+
it 'returns false' do
|
105
|
+
trip.start
|
106
|
+
trip.resume while trip.resume
|
107
|
+
assert_equal false, trip.running?
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'returns nil' do
|
111
|
+
assert_equal nil, trip.running?
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- rpag
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: concurrent ruby tracer built with Thread#set_trace_func
|
14
14
|
email: rpag@singletonclass.com
|
@@ -16,11 +16,10 @@ executables: []
|
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
-
- ".bundle/config"
|
20
19
|
- ".gitignore"
|
21
20
|
- ".travis.yml"
|
22
21
|
- Gemfile
|
23
|
-
-
|
22
|
+
- LICENSE.txt
|
24
23
|
- README.md
|
25
24
|
- Rakefile
|
26
25
|
- examples/concurrent.rb
|
@@ -29,6 +28,7 @@ files:
|
|
29
28
|
- lib/trip/event.rb
|
30
29
|
- lib/trip/version.rb
|
31
30
|
- spec/setup.rb
|
31
|
+
- spec/trip_event_spec.rb
|
32
32
|
- spec/trip_spec.rb
|
33
33
|
- trip.gemspec
|
34
34
|
homepage:
|
data/.bundle/config
DELETED