hometown 0.2.1 → 0.2.3

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 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: