slow_factory_formatter 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3b22e8ede1da987ee803cdb2cd2efaaec13cc30c
4
+ data.tar.gz: f564caedce2c84631564990b4a7093a4fee40941
5
+ SHA512:
6
+ metadata.gz: ccaddfbf454c5763b0ca1ad6079af5dec3304ca816c70886a5191602d5e173d5cf3cfb7e0e3abc56e1355388883d4009d7ffc16d33c36dfe201aa6e42d0f632f
7
+ data.tar.gz: a898b29430ef3f9660254f87a42886ecabf52c1400f179ae7848ad513298a4dd3d5a123f0bc44987417553e1dfccc1dd7cdfa1dc8a8d2dde6caf9ba7cd16bd5f
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in slow_factory_formatter.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 mrageh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,93 @@
1
+ # SlowFactoryFormatter https://codeship.com/projects/118608/status?branch=master
2
+
3
+ This gem is a custom RSpec formatter that allows you to generate a table of
4
+ slow factories when you run your tests.
5
+
6
+ My naive definition of a slow factory is any factory that takes more then half
7
+ a second to setup or any factory that creates or builds more then five instances
8
+ of itself.
9
+
10
+ ## Why use SlowFactoryFormatter
11
+
12
+ [FactoryGirl](https://github.com/thoughtbot/factory_girl) allows you to quickly
13
+ and painlessly setup factories that you can use in your tests. The problem with
14
+ [FactoryGirl](https://github.com/thoughtbot/factory_girl) is that it makes it
15
+ very easy to write your factories in such a way that a valid factory can end up
16
+ creating or building a big tree of objects. When you try to use a factory that
17
+ sets up a lot of objects in a simple test case, you'll end up slowing down your
18
+ test suite, unaware of just how many objects are being setup in the background.
19
+
20
+ This can quickly increase the time it takes a test suite to run and as a team
21
+ grows it can really start to slow the time it takes your build to run.
22
+
23
+ I've seen projects where one of the main causes of a slow build is the number of
24
+ factories being setup in each example group.
25
+
26
+ The main benefit of using SlowFactoryFormatter is that it will help you identify
27
+ the number of objects being setup, when you run a test.
28
+
29
+ ## Installation
30
+
31
+ This gem is intended to be used on a Rails project and you will need to have
32
+ FactoryGirl, RSpec version 3.4 or later and ActiveSupport version 4 or
33
+ later in your project.
34
+
35
+ To use this gem with a Rails project add this line to your Gemfile:
36
+
37
+ ```ruby
38
+ group :test do
39
+ gem 'slow_factory_formatter'
40
+ end
41
+ ```
42
+
43
+ And then run:
44
+
45
+ `$ bundle`
46
+
47
+ Or install it yourself as:
48
+
49
+ `$ gem install slow_factory_formatter`
50
+
51
+ ## Usage
52
+
53
+ You can either use this gem when running `rspec` command:
54
+
55
+ ```
56
+ rspec spec/models/user_spec --format SlowFactoryFormatter
57
+ ```
58
+
59
+ ```
60
+ +------------------------------+--------+-------+---------------+----------------------+
61
+ | Slow Factories |
62
+ +------------------------------+--------+-------+---------------+----------------------+
63
+ | Factory Name | Create | Build | Build Stubbed | Total Time (in secs) |
64
+ +------------------------------+--------+-------+---------------+----------------------+
65
+ | user | 67 | 2 | 16 | 4.48 |
66
+ | product | 45 | 0 | 2 | 1.16 |
67
+ | order | 97 | 0 | 0 | 3.66 |
68
+ | admin | 49 | 12 | 1 | 3.02 |
69
+ | project | 33 | 40 | 34 | 4.33 |
70
+ | customer | 88 | 43 | 2 | 6.16 |
71
+ | manager | 12 | 23 | 0 | 1.10 |
72
+ +------------------------------+--------+-------+---------------+----------------------+
73
+ ```
74
+
75
+ Or if you want to use it every time you run a test in your project, you can add
76
+ it to `.rspec` file in the root of your project directory:
77
+
78
+ ```
79
+ --format SlowFactoryFormatter
80
+ ```
81
+
82
+ This will make SlowFactoryFormatter your default formatter and you'll see a
83
+ table similar to the one above of slow factories whenever you run a test, unless
84
+ you have no slow factories.
85
+
86
+ ## Contributing
87
+
88
+ Bug reports and pull requests are welcome on GitHub at https://github.com/mrageh/slow_factory_formatter.
89
+
90
+ ## License
91
+
92
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
93
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "slow_factory_formatter"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,8 @@
1
+ module RSpec
2
+ lib = File.expand_path(File.dirname(File.dirname(__FILE__)))
3
+ $LOAD_PATH << lib unless $LOAD_PATH.include?(lib)
4
+
5
+ if defined?(::RSpec::Core) && ::RSpec::Core::Version::STRING >= '3.0.0'
6
+ require "slow_factory_formatter/slow_factory_formatter"
7
+ end
8
+ end
@@ -0,0 +1,63 @@
1
+ class FactoriesTable
2
+ attr_reader :factories
3
+
4
+ def initialize
5
+ @factories = {}
6
+ end
7
+
8
+ def add_factory(start:, finish:, payload:)
9
+ execution_time_in_seconds = finish - start
10
+
11
+ factory_name = payload[:name]
12
+ strategy_name = payload[:strategy]
13
+
14
+ factories[factory_name] ||= Hash.new { |factory, strategy| factory[strategy] = Hash.new(0) }
15
+ factories[factory_name][strategy_name][:occurences] += 1
16
+ factories[factory_name][strategy_name][:time_in_seconds] += execution_time_in_seconds
17
+ end
18
+
19
+ def display_slow_factories
20
+ remove_fast_factories
21
+
22
+ if factories.any?
23
+ populate_table
24
+ puts table
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :table
31
+
32
+ def remove_fast_factories
33
+ factories.select! do |factory_name, data|
34
+ data.any? { |strategy_name, prop| prop[:occurences] > 5 || prop[:time_in_seconds] > 0.5 }
35
+ end
36
+ end
37
+
38
+ def populate_table
39
+ table_headings = ['Factory Name', 'Create', 'Build', 'Build Stubbed', 'Total Time (in secs)']
40
+ @table = Terminal::Table.new(
41
+ title: "Slow Factories",
42
+ headings: table_headings
43
+ )
44
+
45
+ factories.each do |factory_name, data|
46
+ populate_row(factory_name, data)
47
+ end
48
+ end
49
+
50
+ def populate_row(factory_name, data)
51
+ row = []
52
+ row << factory_name
53
+
54
+ [:create, :build, :build_stubbed].map do |strategy|
55
+ row << data[strategy][:occurences]
56
+ end
57
+
58
+ time_in_seconds = data.inject(0) { |acc, (_, prop)| acc += prop[:time_in_seconds] }
59
+
60
+ row << time_in_seconds.round(2)
61
+ table << row
62
+ end
63
+ end
@@ -0,0 +1,30 @@
1
+ require "terminal-table"
2
+ require "rspec/core"
3
+ require "rspec/core/formatters/documentation_formatter"
4
+ require_relative "factories_table"
5
+
6
+ class SlowFactoryFormatter < RSpec::Core::Formatters::DocumentationFormatter
7
+ RSpec::Core::Formatters.register self, :start, :dump_summary
8
+
9
+ def initialize(output)
10
+ @factories_table ||= FactoriesTable.new
11
+ super
12
+ end
13
+
14
+ def start(notification)
15
+ ActiveSupport::Notifications.subscribe("factory_girl.run_factory") do |_, start, finish, id, payload|
16
+ factories_table.add_factory(start: start, finish: finish, payload: payload)
17
+ end
18
+
19
+ super
20
+ end
21
+
22
+ def dump_summary(notification)
23
+ factories_table.display_slow_factories
24
+ super
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :factories_table
30
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "slow_factory_formatter"
7
+ spec.version = "0.1.0"
8
+ spec.authors = ["mrageh"]
9
+ spec.email = ["adam@mrageh.com"]
10
+
11
+ spec.summary = %q{Generate a table that contains the slowest factories}
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/mrageh/slow_factory_formatter"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "rspec-core", "~> 3.4"
22
+ spec.add_runtime_dependency "terminal-table", "~> 1.5"
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.4"
26
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slow_factory_formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - mrageh
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-11-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: terminal-table
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
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.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.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: '3.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.4'
83
+ description: Generate a table that contains the slowest factories
84
+ email:
85
+ - adam@mrageh.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - lib/slow_factory_formatter.rb
100
+ - lib/slow_factory_formatter/factories_table.rb
101
+ - lib/slow_factory_formatter/slow_factory_formatter.rb
102
+ - slow_factory_formatter.gemspec
103
+ homepage: https://github.com/mrageh/slow_factory_formatter
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.5.1
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Generate a table that contains the slowest factories
127
+ test_files: []