test-prof 0.2.2 → 0.2.4

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: 5e482ddcaca18180a0606f53fd51871ba132e4a5
4
- data.tar.gz: cb321462168846d649df3237117451926a18398a
3
+ metadata.gz: 5c0da7ccf787bf83ee5ed43d069256d1183682ae
4
+ data.tar.gz: 44fd06ab01a79c6b499e4f9c36caaf56623df65c
5
5
  SHA512:
6
- metadata.gz: a0d9c32fb4241f02f5d6fa3234543fca96abffbc5f968a7e67f9e23da8f41dea1990992e82c8e54cc46feb2af2c0ceac1d1a2ef7055a6784359bef67d97c485d
7
- data.tar.gz: ad8a9004ee118da1fc8c9d2d32b290e8632ce0db0ac26803d2372fddf9efc898b28dd432f77ba89043a335724f2cddc9598742bca228486eb85e8ccea835437e
6
+ metadata.gz: 87ad75af611a473079d57cbe82d30a4c1a54eeb8d61a94190c72761c87ebad47bca6169b98f2fd84eda549c63dfce4d2dd9d11214a86a26ccebbec83895f53d4
7
+ data.tar.gz: 1cf076dc20db11b302d646ca8caf7379916b536ab24e42500cdb4378cbbc5cc74ba22411c8a15f024227023cc3bb8830c67d15e4e012ebc3099905470af17a5c
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Change log
2
2
 
3
- ## master
3
+ ## 0.2.4
4
+
5
+ - EventProf: Fix regression bug with examples profiling. ([@palkan][])
6
+
7
+ There was a bug when an event occurs before the example has started (e.g. in `before(:context)` hook).
8
+
9
+ ## 0.2.3
10
+
11
+ - Minor improvements. ([@palkan][])
4
12
 
5
13
  ## 0.2.2
6
14
 
data/guides/event_prof.md CHANGED
@@ -55,6 +55,8 @@ TestProf::EventProf.configure do |config|
55
55
  end
56
56
  ```
57
57
 
58
+ Or provide the `EVENT_PROF_EXAMPLES=1` env variable.
59
+
58
60
  Another useful configuration parameter – `rank_by`. It's responsible for sorting stats –
59
61
  either by the time spent in the event or by the number of occurrences:
60
62
 
data/guides/ruby_prof.md CHANGED
@@ -9,7 +9,7 @@ Install `ruby-prof` gem (>= 0.16):
9
9
  ```ruby
10
10
  # Gemfile
11
11
  group :development, :test do
12
- gem 'ruby-prof', require: false
12
+ gem 'ruby-prof', '>= 0.16.0', require: false
13
13
  end
14
14
  ```
15
15
 
data/guides/stack_prof.md CHANGED
@@ -4,12 +4,12 @@
4
4
 
5
5
  ## Instructions
6
6
 
7
- Install 'stackprof' gem (>= 0.2.7):
7
+ Install 'stackprof' gem (>= 0.2.9):
8
8
 
9
9
  ```ruby
10
10
  # Gemfile
11
11
  group :development, :test do
12
- gem 'stackprof', require: false
12
+ gem 'stackprof', '>= 0.2.9', require: false
13
13
  end
14
14
  ```
15
15
 
data/lib/test_prof.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "fileutils"
4
4
  require "test_prof/version"
5
5
  require "test_prof/logging"
6
+ require "test_prof/utils"
6
7
 
7
8
  # Ruby applications tests profiling tools.
8
9
  #
@@ -48,7 +49,7 @@ module TestProf
48
49
  # message if it fails to load
49
50
  def require(gem_name, msg)
50
51
  Kernel.require gem_name
51
- true
52
+ block_given? ? yield : true
52
53
  rescue LoadError
53
54
  log :error, msg
54
55
  false
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "test_prof/event_prof/instrumentations/active_support"
4
+ require "test_prof/utils/sized_ordered_set"
4
5
 
5
6
  module TestProf
6
7
  # EventProf profiles your tests and suites against custom events,
@@ -19,6 +20,8 @@ module TestProf
19
20
  # TestProf::EventProf.configure do |config|
20
21
  # config.per_example = true
21
22
  # end
23
+ #
24
+ # Or provide the EVENT_PROF_EXAMPLES=1 env variable.
22
25
  module EventProf
23
26
  # EventProf configuration
24
27
  class Configuration
@@ -34,7 +37,7 @@ module TestProf
34
37
  @event = ENV['EVENT_PROF']
35
38
  @instrumenter = :active_support
36
39
  @top_count = (ENV['EVENT_PROF_TOP'] || 5).to_i
37
- @per_example = false
40
+ @per_example = ENV['EVENT_PROF_EXAMPLES'] == '1'
38
41
  @rank_by = (ENV['EVENT_PROF_RANK'] || :time).to_sym
39
42
  end
40
43
 
@@ -82,13 +85,16 @@ module TestProf
82
85
 
83
86
  instrumenter.subscribe(event) { |time| track(time) }
84
87
 
85
- @groups = Hash.new { |h, k| h[k] = { id: k } }
86
- @examples = Hash.new { |h, k| h[k] = { id: k } }
88
+ @groups = Utils::SizedOrderedSet.new(
89
+ top_count, sort_by: rank_by
90
+ )
91
+
92
+ @examples = Utils::SizedOrderedSet.new(
93
+ top_count, sort_by: rank_by
94
+ )
87
95
 
88
96
  @total_count = 0
89
97
  @total_time = 0.0
90
-
91
- reset!
92
98
  end
93
99
 
94
100
  def track(time)
@@ -99,41 +105,47 @@ module TestProf
99
105
  @time += time
100
106
  @count += 1
101
107
 
102
- @example_time += time if config.per_example?
103
- @example_count += 1 if config.per_example?
108
+ return if @current_example.nil?
109
+
110
+ @example_time += time
111
+ @example_count += 1
104
112
  end
105
113
 
106
114
  def group_started(id)
107
- reset!
115
+ reset_group!
108
116
  @current_group = id
109
117
  end
110
118
 
111
119
  def group_finished(id)
112
- @groups[id][:time] = @time
113
- @groups[id][:count] = @count
114
- @groups[id][:examples] = @total_examples
120
+ data = { id: id, time: @time, count: @count, examples: @total_examples }
121
+
122
+ @groups << data unless data[rank_by].zero?
123
+
115
124
  @current_group = nil
116
125
  end
117
126
 
118
- def example_started(_id)
127
+ def example_started(id)
128
+ return unless config.per_example?
119
129
  reset_example!
130
+ @current_example = id
120
131
  end
121
132
 
122
133
  def example_finished(id)
123
134
  @total_examples += 1
124
135
  return unless config.per_example?
125
136
 
126
- @examples[id][:time] = @example_time
127
- @examples[id][:count] = @example_count
137
+ data = { id: id, time: @example_time, count: @example_count }
138
+ @examples << data unless data[rank_by].zero?
139
+ @current_example = nil
128
140
  end
129
141
 
130
142
  def results
131
143
  {
132
- groups: fetch_top(@groups.values)
144
+ groups: @groups.to_a
133
145
  }.tap do |data|
134
146
  next unless config.per_example?
135
147
 
136
- data[:examples] = fetch_top(@examples.values)
148
+ data[:examples] = @examples.to_a
137
149
  end
138
150
  end
139
151
 
@@ -147,21 +159,14 @@ module TestProf
147
159
 
148
160
  private
149
161
 
150
- def fetch_top(arr)
151
- arr.reject { |el| el[rank_by].zero? }
152
- .sort_by { |el| -el[rank_by] }
153
- .take(top_count)
154
- end
155
-
156
162
  def config
157
163
  EventProf.config
158
164
  end
159
165
 
160
- def reset!
166
+ def reset_group!
161
167
  @time = 0.0
162
168
  @count = 0
163
169
  @total_examples = 0
164
- reset_example!
165
170
  end
166
171
 
167
172
  def reset_example!
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "test_prof/ext/float_duration"
4
+ require "test_prof/ext/string_truncate"
4
5
 
5
6
  module TestProf
6
7
  module EventProf
7
8
  class RSpecListener # :nodoc:
8
9
  include Logging
9
10
  using FloatDuration
11
+ using StringTruncate
10
12
 
11
13
  NOTIFICATIONS = %i[
12
14
  example_group_started
@@ -59,7 +61,7 @@ module TestProf
59
61
 
60
62
  msgs <<
61
63
  <<~GROUP
62
- #{description} (#{location}) – #{group[:time].duration} (#{group[:count]} / #{group[:examples]})
64
+ #{description.truncate} (#{location}) – #{group[:time].duration} (#{group[:count]} / #{group[:examples]})
63
65
  GROUP
64
66
  end
65
67
 
@@ -71,7 +73,7 @@ module TestProf
71
73
  location = example[:id].metadata[:location]
72
74
  msgs <<
73
75
  <<~GROUP
74
- #{description} (#{location}) – #{example[:time].duration} (#{example[:count]})
76
+ #{description.truncate} (#{location}) – #{example[:time].duration} (#{example[:count]})
75
77
  GROUP
76
78
  end
77
79
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Add #duration method to floats
4
3
  module TestProf
5
4
  # Extend Float with #duration method
6
5
  module FloatDuration
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TestProf
4
+ # Extend String with #truncate method
5
+ module StringTruncate
6
+ refine String do
7
+ # Truncate to the specified limit
8
+ # by replacing middle part with dots
9
+ def truncate(limit = 30)
10
+ return self unless size > limit
11
+
12
+ head = ((limit - 3) / 2)
13
+ tail = head + 3 - limit
14
+
15
+ "#{self[0..(head - 1)]}...#{self[tail..-1]}"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -175,9 +175,20 @@ module TestProf
175
175
  <<~MSG
176
176
  Please, install 'ruby-prof' first:
177
177
  # Gemfile
178
- gem 'ruby-prof', require: false
178
+ gem 'ruby-prof', '>= 0.16.0', require: false
179
179
  MSG
180
- )
180
+ ) { check_ruby_prof_version }
181
+ end
182
+
183
+ def check_ruby_prof_version
184
+ if Utils.verify_gem_version('ruby-prof', at_least: '0.16.0')
185
+ true
186
+ else
187
+ log :error, <<~MGS
188
+ Please, upgrade 'ruby-prof' to version >= 0.16.0.
189
+ MGS
190
+ false
191
+ end
181
192
  end
182
193
  end
183
194
  end
@@ -114,9 +114,20 @@ module TestProf
114
114
  <<~MSG
115
115
  Please, install 'stackprof' first:
116
116
  # Gemfile
117
- gem 'stackprof', require: false
117
+ gem 'stackprof', '>= 0.2.9', require: false
118
118
  MSG
119
- )
119
+ ) { check_stack_prof_version }
120
+ end
121
+
122
+ def check_stack_prof_version
123
+ if Utils.verify_gem_version('stackprof', at_least: '0.2.9')
124
+ true
125
+ else
126
+ log :error, <<~MGS
127
+ Please, upgrade 'stackprof' to version >= 0.2.9.
128
+ MGS
129
+ false
130
+ end
120
131
  end
121
132
  end
122
133
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TestProf
4
+ module Utils # :nodoc:
5
+ class << self
6
+ # Verify that loaded gem has correct version
7
+ def verify_gem_version(gem_name, at_least: nil, at_most: nil)
8
+ raise ArgumentError, "Please, provide `at_least` or `at_most` argument" if
9
+ at_least.nil? && at_most.nil?
10
+
11
+ version = Gem.loaded_specs[gem_name].version
12
+
13
+ (at_least.nil? || Gem::Version.new(at_least) <= version) &&
14
+ (at_most.nil? || Gem::Version.new(at_most) >= version)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TestProf
4
+ module Utils
5
+ # Ordered set with capacity
6
+ class SizedOrderedSet
7
+ include Enumerable
8
+
9
+ def initialize(max_size, sort_by: nil)
10
+ @max_size = max_size
11
+ @comparator =
12
+ if block_given?
13
+ Proc.new
14
+ elsif !sort_by.nil?
15
+ ->(x, y) { x[sort_by] >= y[sort_by] }
16
+ else
17
+ ->(x, y) { x >= y }
18
+ end
19
+ @data = []
20
+ end
21
+
22
+ def <<(item)
23
+ return if data.size == max_size &&
24
+ comparator.call(data.last, item)
25
+
26
+ # Find an index of a smaller element
27
+ index = data.bsearch_index { |x| !comparator.call(x, item) }
28
+
29
+ if index.nil?
30
+ data << item
31
+ else
32
+ data.insert(index, item)
33
+ end
34
+
35
+ data.pop if data.size > max_size
36
+ data.size
37
+ end
38
+
39
+ def each
40
+ data.each
41
+ end
42
+
43
+ def size
44
+ data.size
45
+ end
46
+
47
+ def to_a
48
+ data
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :max_size, :data, :comparator
54
+ end
55
+ end
56
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestProf
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-23 00:00:00.000000000 Z
11
+ date: 2017-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -141,6 +141,7 @@ files:
141
141
  - lib/test_prof/event_prof/minitest.rb
142
142
  - lib/test_prof/event_prof/rspec.rb
143
143
  - lib/test_prof/ext/float_duration.rb
144
+ - lib/test_prof/ext/string_truncate.rb
144
145
  - lib/test_prof/factory_default.rb
145
146
  - lib/test_prof/factory_default/factory_girl_patch.rb
146
147
  - lib/test_prof/factory_doctor.rb
@@ -167,6 +168,8 @@ files:
167
168
  - lib/test_prof/stack_prof/rspec.rb
168
169
  - lib/test_prof/tag_prof.rb
169
170
  - lib/test_prof/tag_prof/rspec.rb
171
+ - lib/test_prof/utils.rb
172
+ - lib/test_prof/utils/sized_ordered_set.rb
170
173
  - lib/test_prof/version.rb
171
174
  homepage: http://github.com/palkan/test-prof
172
175
  licenses: