hometown 0.2.1 → 0.2.3

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
  SHA1:
3
- metadata.gz: 6faccd91b19c91bb38e978cae748c863bb1997c0
4
- data.tar.gz: c7d57e8b40777dbadfa4c6e7171c0a7ff240e74b
3
+ metadata.gz: ef3bf9cd07fd65698dbf269368f59acf0e8af42c
4
+ data.tar.gz: 4e911e6a515e81f1009bf40afd6673dceb00fde9
5
5
  SHA512:
6
- metadata.gz: 7cde03cef004ca7e1121d7cc6e15cfdb51753fe663f66e63239ab45ac0315866d3b293bf70565f647102faaf608a48394efc163cdb68906bec87cdee56fa654d
7
- data.tar.gz: df5d5a65aaa19c4efd14f6a9da712ad699c477d223551ffc901247ffa634587a5c752a53980776dd87ebdd89d74138429fb2767202524d21f0c8c061927601ce
6
+ metadata.gz: 2c0c696f52311f61a9d46ca615014f7d1c748bf33670aca6575e17e8ad96f26543c2504be435ab118476044f414d7fbca0a93f5c1a481ddda0067cc7c65a83fd
7
+ data.tar.gz: b9d13e4fffd22bac7677d67cdce2ae4c6b28540430047970cef33fb87d7fdf639c8b33a91fe90163d83fc5a2e821fefe41698fb169d163db4feb88a566762c17
data/README.md CHANGED
@@ -56,6 +56,8 @@ Hometown can help track down these leaks. To watch a class of objects to ensure
56
56
  created instances are disposed, call `Hometown.watch_for_disposal` on the
57
57
  class. `Hometown.undisposed` returns you objects indicating--with stack traces
58
58
  --all the locations where an object was created but not released.
59
+ `Hometown.undisposed_report` will give a formatted output of the undisposed
60
+ objects.
59
61
 
60
62
  ```
61
63
  # dispose.rb
@@ -73,12 +75,13 @@ Hometown.watch_for_disposal(Disposable, :dispose)
73
75
  # Creating initial object
74
76
  disposable = Disposable.new
75
77
  puts "Still there!"
76
- p Hometown.undisposed()
78
+ p Hometown.undisposed
79
+ puts
77
80
 
78
81
  # All done!
79
82
  disposable.dispose
80
83
  puts "Properly disposed"
81
- p Hometown.undisposed()
84
+ puts Hometown.undisposed_report
82
85
 
83
86
 
84
87
  $ ruby examples/dispose.rb
@@ -87,7 +90,12 @@ Still there!
87
90
  { #<Hometown::Trace:0x007f9aa516ec88 ...> => 1 }
88
91
 
89
92
  Properly disposed!
90
- { #<Hometown::Trace:0x007f9aa516ec88 ...> => 0 }
93
+ Undisposed Resources:
94
+ [Disposable] => 0
95
+ examples/dispose.rb:13:in `<main>'
96
+
97
+ Undiposed Totals:
98
+ [Disposable] => 0
91
99
  ```
92
100
 
93
101
  ## Contributing
data/Rakefile CHANGED
@@ -11,3 +11,16 @@ Rake::TestTask.new do |test|
11
11
  test.test_files = FileList['test/**/*_test.rb']
12
12
  end
13
13
 
14
+ if Rake::Task.task_defined?("release:source_control_push")
15
+ puts "Found release:source_control_push task... overwriting to support push.default=nothing"
16
+
17
+ Rake::Task['release:source_control_push'].clear
18
+ task 'release:source_control_push' do
19
+ `git push origin master`
20
+
21
+ version = Bundler::GemHelper.gemspec.version
22
+ version_tag = "v#{version}"
23
+ `git tag -a -m \"Version #{version}\" #{version_tag}`
24
+ `git push --tags`
25
+ end
26
+ end
data/examples/dispose.rb CHANGED
@@ -8,13 +8,17 @@ end
8
8
 
9
9
  # Watch Disposable and track calls to dispose
10
10
  Hometown.watch_for_disposal(Disposable, :dispose)
11
+ Hometown.undisposed_report_at_exit
11
12
 
12
13
  # Creating initial object
13
14
  disposable = Disposable.new
15
+ Disposable.new
14
16
  puts "Still there!"
15
- p Hometown.undisposed()
17
+ puts "*" * 30
18
+ puts Hometown.undisposed_report
19
+ puts
16
20
 
17
- # All done!
21
+ # Dispose of one, and at_exit hook will show the results!
18
22
  disposable.dispose
19
- puts "Properly disposed"
20
- p Hometown.undisposed()
23
+ puts "Final undisposed report!"
24
+ puts "*" * 30
data/lib/hometown.rb CHANGED
@@ -7,12 +7,8 @@ module Hometown
7
7
  @creation_tracer = Hometown::CreationTracer.new
8
8
  @disposal_tracer = Hometown::DisposalTracer.new
9
9
 
10
- def self.creation_tracer
11
- @creation_tracer
12
- end
13
-
14
- def self.disposal_tracer
15
- @disposal_tracer
10
+ class << self
11
+ attr_accessor :creation_tracer, :disposal_tracer
16
12
  end
17
13
 
18
14
  def self.watch(clazz)
@@ -28,6 +24,16 @@ module Hometown
28
24
  end
29
25
 
30
26
  def self.undisposed
31
- @disposal_tracer.undisposed()
27
+ @disposal_tracer.undisposed
28
+ end
29
+
30
+ def self.undisposed_report
31
+ @disposal_tracer.undisposed_report
32
+ end
33
+
34
+ def self.undisposed_report_at_exit
35
+ at_exit do
36
+ puts Hometown.undisposed_report
37
+ end
32
38
  end
33
39
  end
@@ -1,10 +1,12 @@
1
1
  module Hometown
2
2
  class DisposalTracer
3
- attr_reader :undisposed
3
+ attr_reader :undisposed, :untraced_disposals
4
4
 
5
5
  def initialize
6
- @undisposed = Hash.new(0)
7
6
  @tracing_classes = {}
7
+
8
+ @undisposed = Hash.new(0)
9
+ @untraced_disposals = Hash.new(0)
8
10
  end
9
11
 
10
12
  def patch(clazz, disposal_method)
@@ -41,7 +43,59 @@ module Hometown
41
43
 
42
44
  def notice_disposed(instance)
43
45
  trace = Hometown.for(instance)
44
- @undisposed[trace] -= 1 if @undisposed[trace]
46
+ if trace
47
+ @undisposed[trace] -= 1
48
+ else
49
+ trace = Trace.new(instance.class, caller)
50
+ @untraced_disposals[trace] += 1
51
+ end
52
+ end
53
+
54
+ UNDISPOSED_HEADING = "Undisposed Resources"
55
+ UNTRACED_HEADING = "Untraced Disposals"
56
+ UNDISPOSED_TOTALS_HEADING = "Undisposed Totals"
57
+ UNTRACED_TOTALS_HEADING = "Untraced Disposals Totals"
58
+
59
+ def undisposed_report
60
+ result = format_trace_hash(UNDISPOSED_HEADING, @undisposed)
61
+ result += format_trace_hash(UNTRACED_HEADING, @untraced_disposals)
62
+
63
+ result += format_totals(UNDISPOSED_TOTALS_HEADING, @undisposed)
64
+ result += format_totals(UNTRACED_TOTALS_HEADING, @untraced_disposals)
65
+
66
+ result
67
+ end
68
+
69
+ def format_trace_hash(heading, hash)
70
+ result = ""
71
+ hash.each do |trace, count|
72
+ if count > 0
73
+ result += "[#{trace.traced_class}] => #{count}\n"
74
+ result += "\t#{trace.backtrace.join("\n\t")}\n\n"
75
+ end
76
+ end
77
+
78
+ add_heading_if_needed(heading, result)
79
+ end
80
+
81
+ def format_totals(heading, hash)
82
+ result = ""
83
+ hash.group_by { |trace, _| trace.traced_class }.each do |clazz, counts|
84
+ count = counts.map { |count| count.last }.inject(0, &:+)
85
+ if count > 0
86
+ result += "[#{clazz}] => #{count}"
87
+ end
88
+ end
89
+
90
+ add_heading_if_needed(heading, result)
91
+ end
92
+
93
+ def add_heading_if_needed(heading, result)
94
+ if result.empty?
95
+ ""
96
+ else
97
+ "#{heading}:\n#{result}"
98
+ end
45
99
  end
46
100
  end
47
101
  end
@@ -1,3 +1,3 @@
1
1
  module Hometown
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -0,0 +1,90 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "test_helper"))
2
+ require 'hometown'
3
+ require 'hometown/disposal_tracer'
4
+
5
+ module Hometown
6
+ class DisposalTracerTest < Minitest::Test
7
+ def setup
8
+ @tracer = DisposalTracer.new
9
+ @original_tracer = Hometown.disposal_tracer
10
+ Hometown.disposal_tracer = @tracer
11
+ end
12
+
13
+ def teardown
14
+ Hometown.disposal_tracer = @original_tracer
15
+ end
16
+
17
+ def test_empty_report
18
+ assert_empty @tracer.undisposed_report
19
+ end
20
+
21
+ def test_traces_disposal
22
+ clazz = new_class
23
+ @tracer.patch(clazz, :dispose)
24
+
25
+ instance = clazz.new
26
+ trace = Hometown.for(instance)
27
+ assert_equal 1, @tracer.undisposed[trace]
28
+
29
+ instance.dispose
30
+ assert_equal 0, @tracer.undisposed[trace]
31
+ end
32
+
33
+ def test_undisposed_report
34
+ clazz = new_class
35
+ @tracer.patch(clazz, :dispose)
36
+
37
+ instance = clazz.new
38
+ report = @tracer.undisposed_report
39
+
40
+ assert_match DisposalTracer::UNDISPOSED_HEADING, report
41
+ assert_match DisposalTracer::UNDISPOSED_TOTALS_HEADING, report
42
+ assert_match clazz.to_s, report
43
+ assert_match __FILE__, report
44
+ assert_match /#{clazz.to_s}.*1/, report
45
+ end
46
+
47
+ def test_empty_report_if_all_disposed
48
+ clazz = new_class
49
+ @tracer.patch(clazz, :dispose)
50
+
51
+ instance = clazz.new
52
+ instance.dispose
53
+
54
+ assert_empty @tracer.undisposed_report
55
+ end
56
+
57
+ def test_safely_disposes_already_created_objects
58
+ clazz = new_class
59
+ instance = clazz.new
60
+ @tracer.patch(clazz, :dispose)
61
+
62
+ instance.dispose
63
+
64
+ assert_empty @tracer.undisposed
65
+ assert_equal 1, @tracer.untraced_disposals.count
66
+ end
67
+
68
+ def test_untraced_disposals_show_up_in_report
69
+ clazz = new_class
70
+ instance = clazz.new
71
+ @tracer.patch(clazz, :dispose)
72
+
73
+ instance.dispose
74
+ report = @tracer.undisposed_report
75
+
76
+ assert_match DisposalTracer::UNTRACED_HEADING, report
77
+ assert_match DisposalTracer::UNTRACED_TOTALS_HEADING, report
78
+ assert_match clazz.to_s, report
79
+ assert_match __FILE__, report
80
+ assert_match /#{clazz.to_s}.*1/, report
81
+ end
82
+
83
+ def new_class
84
+ Class.new do
85
+ define_method(:dispose) do
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -158,4 +158,19 @@ class HometownTest < Minitest::Test
158
158
  result = Hometown.undisposed
159
159
  assert_equal 1, result[trace]
160
160
  end
161
+
162
+ def test_undisposed_report
163
+ clazz = Class.new do
164
+ define_method(:dispose) do
165
+ end
166
+ end
167
+
168
+ Hometown.watch_for_disposal(clazz, :dispose)
169
+ instance = clazz.new
170
+
171
+ report = Hometown.undisposed_report
172
+ assert_kind_of String, report
173
+ assert_includes report, clazz.to_s
174
+ assert_includes report, __FILE__
175
+ end
161
176
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hometown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason R. Clark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-18 00:00:00.000000000 Z
11
+ date: 2014-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -144,6 +144,7 @@ files:
144
144
  - lib/hometown/disposal_tracer.rb
145
145
  - lib/hometown/trace.rb
146
146
  - lib/hometown/version.rb
147
+ - test/hometown/disposal_tracer_test.rb
147
148
  - test/hometown/trace_test.rb
148
149
  - test/hometown_test.rb
149
150
  - test/test_helper.rb
@@ -172,7 +173,7 @@ signing_key:
172
173
  specification_version: 4
173
174
  summary: Track object creation
174
175
  test_files:
176
+ - test/hometown/disposal_tracer_test.rb
175
177
  - test/hometown/trace_test.rb
176
178
  - test/hometown_test.rb
177
179
  - test/test_helper.rb
178
- has_rdoc: