birth_control 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3904cd8ccfa1d3999f2ff5611bce9e262a09f6b2
4
+ data.tar.gz: a1c6f5c1995106164acee1dd712aed0747ac1f66
5
+ SHA512:
6
+ metadata.gz: 0d97df7b6818906dc7c538f703190ab7bfd82b12f026d4bd09f15895b1e13f2a386e365ad6b1f12cf7ee691570164e8564b2d12b0312dfc6f359239c46039d76
7
+ data.tar.gz: 19803e430038e1ab9fc303ad3669bc820de8bb948d1170bb3dcfee498b19b143f64f4ee8c28089de068a3a28086206bed6bc6cfa7954691b2aca898fe832517f
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ birth_control
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 2.0.0
3
+
4
+ script: "bundle exec rspec"
5
+
6
+ notifications:
7
+ disabled: false
8
+ recipients:
9
+ - xijo@gmx.de
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in birth_control.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (c) 2013 Johannes Opper
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # BirthControl
2
+
3
+ Count active record instantiations and report them to the log.
4
+
5
+ [![Build Status](https://secure.travis-ci.org/xijo/birth_control.png)](http://travis-ci.org/xijo/birth_control)
6
+
7
+ [![Coderwall Endorse](http://api.coderwall.com/xijo/endorsecount.png)](http://coderwall.com/xijo)
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'birth_control', groups: [:development]
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ After bundling you'll need to enable the logging by putting this line into your development environment:
20
+
21
+ BirthControl.enable = true
22
+
23
+ ## Usage
24
+
25
+ Two new reports will be logged into your rails log:
26
+
27
+ 1. The class instantiation report - count all active record objects by class and in total
28
+ 2. Duplication report - reveals where active record objects were loaded more than once
29
+
30
+ ### Example reports:
31
+
32
+ This example show the result of a project detail page. You can see, that there were 5 project instantiations but always the same project. The first two may be necassary, but the later 3 could have been avoided.
33
+
34
+ *** [BirthControl] Class instantiation overview ***
35
+ 5 Projects
36
+ 20 ProjectPictures
37
+ 2 Users
38
+ 1 Countries
39
+ 3 BlogPosts
40
+ 30 Total
41
+
42
+ *** [BirthControl] Duplicate instantiation detected ***
43
+
44
+ Project(42) - 5 times
45
+ 1. app/controllers/projects_controller.rb:27:in `load_project_for_caching'
46
+ 2. app/controllers/projects_controller.rb:13:in `show'
47
+ 3. app/views/projects/_blog_post.html.slim:3:in `...'
48
+ 4. app/views/projects/_blog_post.html.slim:3:in `...'
49
+ 5. app/views/projects/_blog_post.html.slim:3:in `...'
50
+
51
+ ## Contributing
52
+
53
+ 1. Fork it
54
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
55
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
56
+ 4. Push to the branch (`git push origin my-new-feature`)
57
+ 5. Create new Pull Request
58
+
59
+ ## Changelog
60
+
61
+ **0.0.1** (*2013-11-16*)
62
+ * Initial import, basic reports
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'birth_control/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "birth_control"
8
+ spec.version = BirthControl::VERSION
9
+ spec.authors = ["Johannes Opper"]
10
+ spec.email = ["xijo@gmx.de"]
11
+ spec.description = %q{Count active record instantiations and report them to the log}
12
+ spec.summary = %q{Count active record instantiations and report them to the log}
13
+ spec.homepage = "http://github.com/xijo/birth_control"
14
+ spec.license = "WTFPL"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'terminal-table'
22
+ spec.add_dependency 'actionpack'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'rspec'
27
+ spec.add_development_dependency 'simplecov'
28
+ end
@@ -0,0 +1,21 @@
1
+ require 'active_support'
2
+ require 'terminal-table'
3
+ require 'singleton'
4
+
5
+ module BirthControl
6
+ def self.enable=(enable)
7
+ @enabled = enable
8
+ end
9
+
10
+ def self.enabled?
11
+ !!@enabled
12
+ end
13
+ end
14
+
15
+ require 'birth_control/extensions/active_record'
16
+ require 'birth_control/extensions/controller'
17
+ require 'birth_control/counter'
18
+ require 'birth_control/railtie' if defined?(Rails)
19
+ require 'birth_control/report'
20
+ require 'birth_control/version'
21
+
@@ -0,0 +1,22 @@
1
+ module BirthControl
2
+ class Counter
3
+ include Singleton
4
+
5
+ attr_accessor :results
6
+
7
+ def initialize
8
+ reset
9
+ end
10
+
11
+ def count(klass, id, caller = [])
12
+ @results[klass] ||= {}
13
+ @results[klass][id] ||= []
14
+ @results[klass][id] << caller
15
+ @results
16
+ end
17
+
18
+ def reset
19
+ @results = {}
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module BirthControl
2
+ module Extensions
3
+ module ActiveRecord
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_initialize :count_class_instantiation
8
+ end
9
+
10
+ def count_class_instantiation
11
+ BirthControl::Counter.instance.count(self.class.name, id, caller)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module BirthControl
2
+ module Extensions
3
+ module Controller
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_filter :reset_birth_control
8
+ after_filter :birth_control_report
9
+ end
10
+
11
+ def reset_birth_control
12
+ BirthControl::Counter.instance.reset
13
+ end
14
+
15
+ def birth_control_report
16
+ Rails.logger.warn BirthControl::Report.new(BirthControl::Counter.instance.results)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module BirthControl
2
+ class Railtie < Rails::Railtie
3
+ initializer 'birth_control.initialize_extensions' do
4
+ if BirthControl.enabled?
5
+ ActiveRecord::Base.send :include, BirthControl::Extensions::ActiveRecord
6
+ ActionController::Base.send :include, BirthControl::Extensions::Controller
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,59 @@
1
+ module BirthControl
2
+ class Report
3
+ def initialize(results)
4
+ @results = results
5
+ end
6
+
7
+ def count_class_and_id(klass, id)
8
+ @results[klass][id].size
9
+ end
10
+
11
+ def count_class(klass)
12
+ @results[klass].inject(0) { |c, (id, _)| c + count_class_and_id(klass, id) }
13
+ end
14
+
15
+ def count
16
+ @results.inject(0) { |c, (klass, _)| c + count_class(klass) }
17
+ end
18
+
19
+ def duplication_report
20
+ lines = []
21
+
22
+ @results.each do |klass, entries|
23
+ entries.each do |id, callers|
24
+ if callers.size > 1
25
+ lines << "\n#{klass}(#{id}) - #{callers.size} times"
26
+ callers.each_with_index do |caller, index|
27
+ occurence = caller.detect { |call| call.match(/app\//) }
28
+ occurence.sub!(/(.*)\/app\//, 'app/')
29
+ lines << " #{index+1}. #{occurence}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ if lines.size > 0
35
+ lines.unshift "*** [BirthControl] Duplicate instantiation detected ***"
36
+ lines.join("\n") + "\n"
37
+ end
38
+ end
39
+
40
+ def class_instantiation_report
41
+ lines = ["*** [BirthControl] Class instantiation overview ***"]
42
+ @results.each do |klass, _|
43
+ count = "%5s" % count_class(klass)
44
+ lines << "#{count} #{klass.pluralize}"
45
+ end
46
+ lines << "#{"%5s" % count} Total"
47
+ lines.join("\n") + "\n"
48
+ end
49
+
50
+ def to_s
51
+ lines = [
52
+ '[BirthControl]',
53
+ class_instantiation_report,
54
+ duplication_report
55
+ ]
56
+ lines.join "\n"
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module BirthControl
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe BirthControl::Counter do
4
+
5
+ let(:counter) { BirthControl::Counter.instance }
6
+ after { counter.reset }
7
+
8
+ it 'behaves as singleton' do
9
+ counter.should eq BirthControl::Counter.instance
10
+ end
11
+
12
+ describe '#reset' do
13
+ it 'removes all existing results' do
14
+ counter.results = :something
15
+ counter.reset
16
+ counter.results.should eq({})
17
+ end
18
+ end
19
+
20
+ describe '#count' do
21
+ it 'groups results by class' do
22
+ counter.count('Foo', 1)
23
+ counter.count('Bar', 1)
24
+ counter.results.should have(2).keys
25
+ end
26
+
27
+ it 'counts different ids per class' do
28
+ counter.count 'Foo', 1
29
+ counter.count 'Foo', 2
30
+ counter.results['Foo'].should have(2).keys
31
+ end
32
+
33
+ it 'groups multiple occurencies of the same id' do
34
+ counter.count('Foo', 1)
35
+ counter.count('Foo', 1)
36
+ counter.results['Foo'][1].should have(2).entries
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe BirthControl::Report do
4
+ let(:results) do
5
+ {
6
+ 'Project' => {
7
+ 1 => [['somewhere/app/models/project.rb:123'], ['somewhere/lib/project_counter.rb:1']],
8
+ 2 => [['somewhere/app/models/project.rb:123']]
9
+ },
10
+ 'User' => {
11
+ 1 => [['somewhere/app/controllers/sessions_controller.rb:1']],
12
+ }
13
+ }
14
+ end
15
+ let(:report) { BirthControl::Report.new(results) }
16
+
17
+ it '#count returns total of all counted objects' do
18
+ report.count_class_and_id('Project', 1).should eq 2
19
+ report.count_class('Project').should eq 3
20
+ report.count.should eq 4
21
+ end
22
+
23
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe BirthControl do
4
+
5
+ it '#enable= works as intended' do
6
+ BirthControl.enable = false
7
+ BirthControl.should_not be_enabled
8
+ BirthControl.enable = true
9
+ BirthControl.should be_enabled
10
+ end
11
+
12
+ end
@@ -0,0 +1,13 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.adapters.define 'gem' do
4
+ add_filter '/spec/'
5
+ add_group 'Libraries', '/lib/'
6
+ end
7
+ SimpleCov.start 'gem'
8
+
9
+ require 'birth_control'
10
+
11
+ RSpec.configure do |config|
12
+ config.color_enabled = true
13
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: birth_control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Johannes Opper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: terminal-table
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionpack
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: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
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: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Count active record instantiations and report them to the log
98
+ email:
99
+ - xijo@gmx.de
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .ruby-gemset
106
+ - .ruby-version
107
+ - .travis.yml
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - birth_control.gemspec
113
+ - lib/birth_control.rb
114
+ - lib/birth_control/counter.rb
115
+ - lib/birth_control/extensions/active_record.rb
116
+ - lib/birth_control/extensions/controller.rb
117
+ - lib/birth_control/railtie.rb
118
+ - lib/birth_control/report.rb
119
+ - lib/birth_control/version.rb
120
+ - spec/lib/birth_control/counter_spec.rb
121
+ - spec/lib/birth_control/report_spec.rb
122
+ - spec/lib/birth_control_spec.rb
123
+ - spec/spec_helper.rb
124
+ homepage: http://github.com/xijo/birth_control
125
+ licenses:
126
+ - WTFPL
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.0.3
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Count active record instantiations and report them to the log
148
+ test_files:
149
+ - spec/lib/birth_control/counter_spec.rb
150
+ - spec/lib/birth_control/report_spec.rb
151
+ - spec/lib/birth_control_spec.rb
152
+ - spec/spec_helper.rb