rspeed 0.4.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/README.md +10 -7
  4. data/lib/generators/rspeed/install_generator.rb +1 -1
  5. data/lib/rspeed.rb +10 -7
  6. data/lib/rspeed/database.rb +19 -0
  7. data/lib/rspeed/differ.rb +71 -0
  8. data/lib/rspeed/env.rb +39 -0
  9. data/lib/rspeed/extension.rb +3 -2
  10. data/lib/rspeed/logger.rb +13 -0
  11. data/lib/rspeed/observer.rb +19 -7
  12. data/lib/rspeed/redis.rb +78 -0
  13. data/lib/rspeed/reporter.rb +38 -0
  14. data/lib/rspeed/runner.rb +4 -15
  15. data/lib/rspeed/splitter.rb +25 -115
  16. data/lib/rspeed/variable.rb +34 -0
  17. data/lib/rspeed/version.rb +1 -1
  18. data/spec/common_helper.rb +10 -0
  19. data/spec/fixtures/empty.rb +4 -0
  20. data/spec/models/rspeed/database/list_spec.rb +15 -0
  21. data/spec/models/rspeed/database/previous_result_spec.rb +17 -0
  22. data/spec/models/rspeed/database/result_spec.rb +17 -0
  23. data/spec/models/rspeed/differ/actual_data_spec.rb +20 -0
  24. data/spec/models/rspeed/differ/actual_files_spec.rb +20 -0
  25. data/spec/models/rspeed/differ/added_data_spec.rb +19 -0
  26. data/spec/models/rspeed/differ/diff_spec.rb +77 -0
  27. data/spec/models/rspeed/differ/final_diff_spec.rb +46 -0
  28. data/spec/models/rspeed/differ/removed_data_spec.rb +20 -0
  29. data/spec/models/rspeed/differ/sum_time_spec.rb +19 -0
  30. data/spec/models/rspeed/env/app_spec.rb +17 -0
  31. data/spec/models/rspeed/env/db_spec.rb +17 -0
  32. data/spec/models/rspeed/env/host_spec.rb +17 -0
  33. data/spec/models/rspeed/env/pipe_spec.rb +19 -0
  34. data/spec/models/rspeed/env/pipes_spec.rb +19 -0
  35. data/spec/models/rspeed/env/port_spec.rb +17 -0
  36. data/spec/models/rspeed/env/rspeed_spec.rb +43 -0
  37. data/spec/models/rspeed/env/spec_path_spec.rb +19 -0
  38. data/spec/models/rspeed/observer/after_spec.rb +5 -5
  39. data/spec/models/rspeed/observer/after_suite_spec.rb +43 -0
  40. data/spec/models/rspeed/observer/before_spec.rb +0 -2
  41. data/spec/models/rspeed/observer/before_suite_spec.rb +18 -6
  42. data/spec/models/rspeed/redis/clean_spec.rb +20 -0
  43. data/spec/models/rspeed/redis/client_spec.rb +7 -0
  44. data/spec/models/rspeed/redis/destroy_spec.rb +21 -0
  45. data/spec/models/rspeed/redis/get_spec.rb +11 -0
  46. data/spec/models/rspeed/redis/keys_spec.rb +13 -0
  47. data/spec/models/rspeed/redis/list_spec.rb +19 -0
  48. data/spec/models/rspeed/redis/profiles_content_spec.rb +19 -0
  49. data/spec/models/rspeed/redis/result_spec.rb +13 -0
  50. data/spec/models/rspeed/redis/set_spec.rb +11 -0
  51. data/spec/models/rspeed/redis/specs_finished_spec.rb +19 -0
  52. data/spec/models/rspeed/redis/specs_initiated_spec.rb +13 -0
  53. data/spec/models/rspeed/redis/version_the_result_spec.rb +21 -0
  54. data/spec/models/rspeed/reporter/call_spec.rb +42 -0
  55. data/spec/models/rspeed/reporter/print_files_spec.rb +27 -0
  56. data/spec/models/rspeed/reporter/print_table_spec.rb +29 -0
  57. data/spec/models/rspeed/runner/run_spec.rb +73 -0
  58. data/spec/models/rspeed/splitter/append_spec.rb +8 -28
  59. data/spec/models/rspeed/splitter/consolidate_spec.rb +23 -0
  60. data/spec/models/rspeed/splitter/first_pipe_spec.rb +4 -8
  61. data/spec/models/rspeed/splitter/need_warm_question_spec.rb +35 -0
  62. data/spec/models/rspeed/splitter/pipe_files_spec.rb +30 -0
  63. data/spec/models/rspeed/splitter/split_spec.rb +85 -45
  64. data/spec/models/rspeed/variable/append_app_name_spec.rb +33 -0
  65. data/spec/models/rspeed/variable/key_spec.rb +15 -0
  66. data/spec/models/rspeed/variable/pipe_spec.rb +23 -0
  67. data/spec/models/rspeed/variable/pipes_pattern_spec.rb +5 -0
  68. data/spec/models/rspeed/variable/previous_result_spec.rb +19 -0
  69. data/spec/models/rspeed/variable/profile_pattern_spec.rb +5 -0
  70. data/spec/models/rspeed/variable/profile_spec.rb +23 -0
  71. data/spec/models/rspeed/variable/result_spec.rb +19 -0
  72. data/spec/spec_helper.rb +27 -0
  73. data/spec/support/common.rb +13 -0
  74. data/spec/support/coverage.rb +14 -0
  75. data/spec/support/env_mock.rb +3 -0
  76. data/spec/support/fakeredis.rb +3 -0
  77. metadata +187 -30
  78. data/spec/fixtures/new_spec.rb.csv +0 -1
  79. data/spec/models/rspeed/splitter/actual_examples_spec.rb +0 -22
  80. data/spec/models/rspeed/splitter/destroy_spec.rb +0 -33
  81. data/spec/models/rspeed/splitter/diff_spec.rb +0 -32
  82. data/spec/models/rspeed/splitter/get_spec.rb +0 -76
  83. data/spec/models/rspeed/splitter/keys_spec.rb +0 -33
  84. data/spec/models/rspeed/splitter/last_pipe_spec.rb +0 -21
  85. data/spec/models/rspeed/splitter/pipe_spec.rb +0 -21
  86. data/spec/models/rspeed/splitter/pipes_spec.rb +0 -27
  87. data/spec/models/rspeed/splitter/rename_spec.rb +0 -18
  88. data/spec/models/rspeed/splitter/result_spec.rb +0 -19
  89. data/spec/models/rspeed/splitter/save_spec.rb +0 -57
  90. data/spec/rails_helper.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f8fbbef694a5ee56e51580e9969e9e8372d4d93d0e5562f4efbad08fb8df854
4
- data.tar.gz: b9cefcd95a86536bcd139ef8df7f47674ad0f4205ecfb0c7bc7dd2b5c33b4efd
3
+ metadata.gz: 121d5558331de345c2147e1b1ee8b6679c09ac8cb83b33af4ad5673d3e534806
4
+ data.tar.gz: b739938586f9ce82c94c9fe74f79583153ad268e5443c54602f32650482595dd
5
5
  SHA512:
6
- metadata.gz: 66a0fba65b3130c9454abad42a8a0e4554fd49711194a74cf7d5d77d37274469500e29f0d6210c53d92f33aa529799d416281c5556f193b9a9c0a96d3b7babbd
7
- data.tar.gz: 59399ef9100cc2353a7dc93b53a152289b79aaac9a5c2ace44925a50c517a94196193ebe25ae5a4148861ace0317dfdd2def59b332ab9c717b6d073dad5df0c0
6
+ metadata.gz: 4109a7ca7ccc74e43c09eafd0aabf5fba559f9dbc5350a8439cbfc47cd400c03de3d862405059e60adb6ee11b83592985a89b877982c3094bcecbf3f69c363df
7
+ data.tar.gz: 6f706fe116da661fe858fc85979e5ee718ec4fe4da19cb13cd06ee6bbabad4688e6182f8504db93215a549fa9efe18991314faf97d8ca8e0f55125771b2de772
data/CHANGELOG.md CHANGED
@@ -1,3 +1,57 @@
1
+ ## master
2
+
3
+ - None;
4
+
5
+ ## v0.7.0
6
+
7
+ #### News
8
+
9
+ - Prints pipe info into a table on the console;
10
+ - The previous result is keeped alive for further checks;
11
+ - Adds final report show actual, added and removed;
12
+
13
+ ## v0.6.0
14
+
15
+ #### Break Change
16
+
17
+ - Drops `RSPEED_RESULT_KEY` key in favor of `RSPEED_NAME`;
18
+ - Renames env `RSPEED_NAME` to `RSPEED_APP`;
19
+
20
+ #### News
21
+
22
+ - Adds env `RSPEED_SPEC_PATH` to indicate the spec folders path;
23
+ - Saves pipes and profiles with a zero at the beginning;
24
+ - Makes sure examples is unique;
25
+
26
+ ## v0.5.2
27
+
28
+ #### Fix
29
+
30
+ - Avoid duplicate entries in the consolidated result;
31
+
32
+ #### Update
33
+
34
+ - CSV dependency dropped;
35
+ - Drops tmp key in favor of profile keys fetch;
36
+
37
+ ## v0.5.1
38
+
39
+ #### Fix
40
+
41
+ - Only pipe number 1 will warm up avoiding duplicated spec entries;
42
+
43
+ ## v0.5.0
44
+
45
+ #### Fix
46
+
47
+ - Add env `RSPEED_NAME` to specify the application name and avoid result conflicts between multiple runs;
48
+ - No more depends on pipe sequence to generate ou aggregate the resul;
49
+ - rake `rspeed:install`;
50
+
51
+ #### Update
52
+
53
+ - The result of the pipes are no more saved on Redis. It's now calculated based on result key `rspeed`;
54
+
1
55
  ## v0.4.0
2
56
 
3
57
  - Now we make diff to discover removed and added examples;
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # RSpeed
2
2
 
3
- [![Build Status](https://github.com/wbotelhos/rspeed/workflows/CI/badge.svg)](https://github.com/wbotelhos/rspeed/actions)
3
+ [![CI](https://github.com/wbotelhos/rspeed/workflows/CI/badge.svg)](https://github.com/wbotelhos/rspeed/actions)
4
4
  [![Gem Version](https://badge.fury.io/rb/rspeed.svg)](https://badge.fury.io/rb/rspeed)
5
- [![Maintainability](https://api.codeclimate.com/v1/badges/cc5efe8b06bc1d5e9e8a/maintainability)](https://codeclimate.com/github/wbotelhos/rspeed/maintainability)
6
- [![Patreon](https://img.shields.io/badge/donate-%3C3-brightgreen.svg)](https://www.patreon.com/wbotelhos)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/f312587b4f126bb13e85/maintainability)](https://codeclimate.com/github/wbotelhos/rspeed/maintainability)
6
+ [![Coverage](https://codecov.io/gh/wbotelhos/rspeed/branch/main/graph/badge.svg)](https://codecov.io/gh/wbotelhos/rspeed)
7
+ [![Sponsor](https://img.shields.io/badge/sponsor-%3C3-green)](https://www.patreon.com/wbotelhos)
7
8
 
8
9
  RSpeed splits your specs to you run parallels tests.
9
10
 
@@ -25,19 +26,21 @@ rake rspeed:install
25
26
 
26
27
  ## Usage
27
28
 
28
- - `RSPEED`: Enables RSpeed
29
- - `RSPEED_PIPES`: Quantity of pipes
29
+ - `RSPEED_APP`: You app name to avoid data override
30
30
  - `RSPEED_PIPE`: Current pipe
31
+ - `RSPEED_PIPES`: Quantity of pipes
32
+ - `RSPEED_SPEC_PATH`: The specs folders path
33
+ - `RSPEED`: Enables RSpeed
31
34
 
32
35
  ```sh
33
- RSPEED=true RSPEED_PIPES=3 RSPEED_PIPE=1 bundle exec rake rspeed:run
36
+ RSPEED=true RSPEED_APP=blog RSPEED_PIPE=1 RSPEED_PIPES=3 bundle exec rake rspeed:run
34
37
  ```
35
38
 
36
39
  ## How it Works
37
40
 
38
41
  ### First run
39
42
 
40
- 1. Since we has no statistics on the first time, we run all specs and collect it;
43
+ 1. Since we have no statistics on the first time, we run all specs and collect it;
41
44
 
42
45
  ```json
43
46
  { "file": "./spec/models/1_spec.rb", "time": 0.01 }
@@ -6,7 +6,7 @@ module RSpeed
6
6
 
7
7
  desc 'Creates RSpeed task'
8
8
 
9
- def copy_initializer
9
+ def create_initializer
10
10
  copy_file 'lib/tasks/rspeed.rake', 'lib/tasks/rspeed.rake'
11
11
  end
12
12
  end
data/lib/rspeed.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSpeed
4
- require 'csv'
5
- require 'redis'
4
+ require 'rspeed/database'
5
+ require 'rspeed/env'
6
+ require 'rspeed/extension'
7
+ require 'rspeed/logger'
8
+ require 'rspeed/observer'
9
+ require 'rspeed/redis'
10
+ require 'rspeed/reporter'
11
+ require 'rspeed/runner'
12
+ require 'rspeed/splitter'
13
+ require 'rspeed/variable'
6
14
  end
7
-
8
- require 'rspeed/extension'
9
- require 'rspeed/observer'
10
- require 'rspeed/runner'
11
- require 'rspeed/splitter'
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpeed
4
+ module Database
5
+ module_function
6
+
7
+ def previous_result
8
+ list(RSpeed::Variable.previous_result)
9
+ end
10
+
11
+ def result
12
+ list(RSpeed::Variable.result)
13
+ end
14
+
15
+ def list(key)
16
+ RSpeed::Redis.list(key).map { |item| JSON.parse(item, symbolize_names: true) }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpeed
4
+ module Differ
5
+ module_function
6
+
7
+ def actual_files(spec_path: RSpeed::Env.spec_path)
8
+ [].tap do |data|
9
+ Dir[spec_path].sort.each do |file|
10
+ lines = File.open(file).read.split("\n")
11
+
12
+ lines&.each&.with_index do |item, index|
13
+ data << "#{file}:#{index + 1}" if /^it/.match?(item.gsub(/\s+/, ''))
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ def actual_data(files:, result:)
20
+ result.select { |item| files.include?(item[:file]) }
21
+ end
22
+
23
+ def added_data(files:, result:)
24
+ (files - result.map { |item| item[:file] }).map { |file| { file: file, time: nil } }
25
+ end
26
+
27
+ def diff(from: actual_files, to: RSpeed::Database.result)
28
+ to = to.uniq { |item| item[:file] }
29
+ added = added_data(files: from, result: to)
30
+ actual = actual_data(files: from, result: to) + added_data(files: from, result: to)
31
+ removed = removed_data(files: from, result: to)
32
+
33
+ {
34
+ actual_files: actual,
35
+ actual_time: sum_time(data: actual),
36
+ added_files: added,
37
+ added_time: sum_time(data: added),
38
+ removed_files: removed,
39
+ removed_time: sum_time(data: removed),
40
+ }
41
+ end
42
+
43
+ def final_diff(from: RSpeed::Database.previous_result, to: RSpeed::Database.result)
44
+ from = from.uniq { |item| item[:file] }
45
+ to = to.uniq { |item| item[:file] }
46
+ previous_files = from.map { |item| item[:file] }
47
+ actual_files = to.map { |item| item[:file] }
48
+ added = to.reject { |item| previous_files.include?(item[:file]) }
49
+ removed = from.reject { |item| actual_files.include?(item[:file]) }
50
+
51
+ {
52
+ actual_files: to,
53
+ actual_time: sum_time(data: to),
54
+ added_files: added,
55
+ added_time: sum_time(data: added),
56
+ removed_files: removed,
57
+ removed_time: sum_time(data: removed),
58
+ }
59
+ end
60
+
61
+ def removed_data(files:, result:)
62
+ result.reject { |item| files.include?(item[:file]) }
63
+ end
64
+
65
+ def sum_time(data:)
66
+ return '?' if data.all? { |item| item[:time].nil? }
67
+
68
+ data.sum { |item| item[:time].to_f }
69
+ end
70
+ end
71
+ end
data/lib/rspeed/env.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpeed
4
+ module Env
5
+ module_function
6
+
7
+ def app
8
+ ENV['RSPEED_APP']
9
+ end
10
+
11
+ def db
12
+ ENV['RSPEED_DB']&.to_i
13
+ end
14
+
15
+ def host
16
+ ENV['RSPEED_HOST']
17
+ end
18
+
19
+ def pipe
20
+ ENV.fetch('RSPEED_PIPE', 1).to_i
21
+ end
22
+
23
+ def pipes
24
+ ENV.fetch('RSPEED_PIPES', 1).to_i
25
+ end
26
+
27
+ def port
28
+ ENV['RSPEED_PORT']&.to_i
29
+ end
30
+
31
+ def rspeed
32
+ ENV['RSPEED'] == 'true'
33
+ end
34
+
35
+ def spec_path
36
+ ENV.fetch('RSPEED_SPEC_PATH', './spec/**/*spec.rb')
37
+ end
38
+ end
39
+ end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if ENV['RSPEED'] == 'true'
4
- require 'rspec/rails'
3
+ if RSpeed::Env.rspeed
4
+ require 'rspec'
5
5
 
6
6
  RSpec.configure do |config|
7
7
  config.before(:suite) { RSpeed::Observer.before_suite }
8
8
  config.before { |example| RSpeed::Observer.before(example) }
9
9
  config.after { |example| RSpeed::Observer.after(example) }
10
+ config.after(:suite) { RSpeed::Observer.after_suite }
10
11
  end
11
12
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpeed
4
+ module Logger
5
+ module_function
6
+
7
+ def log(context, method, message)
8
+ clazz = context.ancestors.join('::')
9
+
10
+ puts("[#{clazz}##{method}.#{RSpeed::Env.pipe}] #{message}")
11
+ end
12
+ end
13
+ end
@@ -9,9 +9,22 @@ module RSpeed
9
9
  line_number = example.metadata[:line_number]
10
10
  spent_time = example.clock.now - example.metadata[:start_at]
11
11
 
12
- File.open('rspeed.csv', 'a') do |file|
13
- file.write "#{spent_time},#{file_path}:#{line_number}\n"
14
- end
12
+ json = { file: "#{file_path}:#{line_number}", time: spent_time }.to_json
13
+
14
+ RSpeed::Redis.client.rpush(RSpeed::Variable.profile, json)
15
+ end
16
+
17
+ def after_suite
18
+ RSpeed::Redis.set(RSpeed::Variable.pipe, true)
19
+
20
+ return unless RSpeed::Redis.specs_finished?
21
+
22
+ RSpeed::Redis.version_the_result if RSpeed::Redis.result?
23
+ RSpeed::Splitter.consolidate
24
+ RSpeed::Reporter.call
25
+ RSpeed::Redis.clean
26
+
27
+ RSpeed::Logger.log(self, __method__, 'RSpeed finished.')
15
28
  end
16
29
 
17
30
  def before(example)
@@ -19,11 +32,10 @@ module RSpeed
19
32
  end
20
33
 
21
34
  def before_suite
22
- truncate_csv_file
23
- end
35
+ RSpeed::Logger.log(self, __method__, 'Cleanning current flag and profile.')
24
36
 
25
- def truncate_csv_file
26
- File.open('rspeed.csv', 'w') { |file| file.truncate(0) }
37
+ RSpeed::Redis.destroy(pattern: RSpeed::Variable.pipe)
38
+ RSpeed::Redis.destroy(pattern: RSpeed::Variable.profile)
27
39
  end
28
40
  end
29
41
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpeed
4
+ module Redis
5
+ require 'redis'
6
+
7
+ module_function
8
+
9
+ def clean
10
+ RSpeed::Logger.log(self, __method__, 'Cleaning pipes and profiles.')
11
+
12
+ destroy(pattern: RSpeed::Variable::PIPES_PATTERN)
13
+ destroy(pattern: RSpeed::Variable::PROFILE_PATTERN)
14
+ end
15
+
16
+ def client
17
+ @client ||= ::Redis.new(db: RSpeed::Env.db, host: RSpeed::Env.host, port: RSpeed::Env.port)
18
+ end
19
+
20
+ def destroy(pattern:)
21
+ RSpeed::Logger.log(self, __method__, %(Destroying pattern "#{pattern}".))
22
+
23
+ keys(pattern: pattern).each { |key| client.del(key) }
24
+ end
25
+
26
+ def get(key)
27
+ client.get(key)
28
+ end
29
+
30
+ def keys(pattern:)
31
+ cursor = 0
32
+ result = []
33
+
34
+ loop do
35
+ cursor, results = client.scan(cursor, match: pattern)
36
+ result += results
37
+
38
+ break if cursor.to_i.zero?
39
+ end
40
+
41
+ result
42
+ end
43
+
44
+ def list(key)
45
+ client.lrange(key, 0, -1)
46
+ end
47
+
48
+ def profiles_content(pattern: 'rspeed:profile_*')
49
+ client.keys(pattern).map { |key| list(key) }.flatten
50
+ end
51
+
52
+ def result?
53
+ keys(pattern: RSpeed::Variable.result).any?
54
+ end
55
+
56
+ def set(key, value)
57
+ client.set(key, value)
58
+ end
59
+
60
+ def specs_finished?
61
+ (RSpeed::Redis.keys(pattern: RSpeed::Variable::PIPES_PATTERN).size == RSpeed::Env.pipes).tap do |boo|
62
+ RSpeed::Logger.log(self, __method__, "Specs #{boo ? 'finished.' : 'not fineshed yet.'}")
63
+ end
64
+ end
65
+
66
+ def specs_initiated?
67
+ RSpeed::Redis.keys(pattern: RSpeed::Variable::PIPES_PATTERN).any?.tap do |boo|
68
+ RSpeed::Logger.log(self, __method__, "Specs #{boo ? 'initialized.' : 'not initialized yet.'}")
69
+ end
70
+ end
71
+
72
+ def version_the_result
73
+ RSpeed::Logger.log(self, __method__, 'Versioning the result.')
74
+
75
+ client.rename(RSpeed::Variable.result, RSpeed::Variable.previous_result)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpeed
4
+ module Reporter
5
+ module_function
6
+
7
+ require 'terminal-table'
8
+
9
+ def call
10
+ diff = RSpeed::Differ.final_diff
11
+
12
+ print_table(
13
+ headings: %w[Global Value],
14
+
15
+ rows: [
16
+ ['Actual Time', diff[:actual_time]],
17
+ ['Removed Time', diff[:removed_time]],
18
+ ['Added Time', diff[:added_time]],
19
+ ]
20
+ )
21
+ end
22
+
23
+ def print_files(items)
24
+ total_specs = items.size
25
+ headings = ["#{total_specs} specs", "Pipe #{RSpeed::Env.pipe}/#{RSpeed::Env.pipes}", 'Last Time']
26
+
27
+ rows = items.map.with_index do |item, index|
28
+ [format('%02d', index + 1), item[:file], item[:time].to_s]
29
+ end
30
+
31
+ print_table(headings: headings, rows: rows)
32
+ end
33
+
34
+ def print_table(headings:, rows:)
35
+ puts(Terminal::Table.new(headings: headings, rows: rows, title: 'RSpeed'))
36
+ end
37
+ end
38
+ end