rspeed 0.0.1 → 0.5.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.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +32 -0
 - data/LICENSE +1 -1
 - data/README.md +88 -5
 - data/lib/generators/rspeed/install_generator.rb +13 -0
 - data/lib/generators/rspeed/templates/lib/tasks/rspeed.rb +9 -0
 - data/lib/rspeed.rb +9 -0
 - data/lib/rspeed/env.rb +43 -0
 - data/lib/rspeed/extension.rb +12 -0
 - data/lib/rspeed/observer.rb +43 -0
 - data/lib/rspeed/redis.rb +55 -0
 - data/lib/rspeed/runner.rb +13 -0
 - data/lib/rspeed/splitter.rb +130 -0
 - data/lib/rspeed/variable.rb +31 -0
 - data/lib/rspeed/version.rb +1 -1
 - data/spec/common_helper.rb +10 -0
 - data/spec/fixtures/1_spec.rb +9 -0
 - data/spec/fixtures/2_spec.rb +5 -0
 - data/spec/fixtures/empty.rb +4 -0
 - data/spec/fixtures/new_spec.rb.csv +1 -0
 - data/spec/models/rspeed/env/db_spec.rb +17 -0
 - data/spec/models/rspeed/env/host_spec.rb +17 -0
 - data/spec/models/rspeed/env/name_spec.rb +17 -0
 - data/spec/models/rspeed/env/pipe_spec.rb +19 -0
 - data/spec/models/rspeed/env/pipes_spec.rb +41 -0
 - data/spec/models/rspeed/env/port_spec.rb +17 -0
 - data/spec/models/rspeed/env/result_key_spec.rb +19 -0
 - data/spec/models/rspeed/env/rspeed_spec.rb +43 -0
 - data/spec/models/rspeed/env/tmp_spec.rb +19 -0
 - data/spec/models/rspeed/observer/after_spec.rb +16 -0
 - data/spec/models/rspeed/observer/after_suite_spec.rb +46 -0
 - data/spec/models/rspeed/observer/before_spec.rb +15 -0
 - data/spec/models/rspeed/observer/before_suite_spec.rb +37 -0
 - data/spec/models/rspeed/redis/clean_pipes_flag_spec.rb +14 -0
 - data/spec/models/rspeed/redis/client_spec.rb +7 -0
 - data/spec/models/rspeed/redis/destroy_spec.rb +29 -0
 - data/spec/models/rspeed/redis/get_spec.rb +9 -0
 - data/spec/models/rspeed/redis/keys_spec.rb +29 -0
 - data/spec/models/rspeed/redis/result_spec.rb +13 -0
 - data/spec/models/rspeed/redis/set_spec.rb +9 -0
 - data/spec/models/rspeed/redis/specs_finished_spec.rb +19 -0
 - data/spec/models/rspeed/redis/specs_initiated_spec.rb +13 -0
 - data/spec/models/rspeed/runner/run_spec.rb +30 -0
 - data/spec/models/rspeed/splitter/actual_examples_spec.rb +26 -0
 - data/spec/models/rspeed/splitter/append_spec.rb +35 -0
 - data/spec/models/rspeed/splitter/diff_spec.rb +30 -0
 - data/spec/models/rspeed/splitter/first_pipe_spec.rb +17 -0
 - data/spec/models/rspeed/splitter/get_spec.rb +74 -0
 - data/spec/models/rspeed/splitter/pipe_files_spec.rb +26 -0
 - data/spec/models/rspeed/splitter/redundant_run_spec.rb +45 -0
 - data/spec/models/rspeed/splitter/rename_spec.rb +16 -0
 - data/spec/models/rspeed/splitter/split_spec.rb +89 -0
 - data/spec/models/rspeed/variable/append_name_spec.rb +19 -0
 - data/spec/models/rspeed/variable/csv_spec.rb +5 -0
 - data/spec/models/rspeed/variable/default_partner_spec.rb +5 -0
 - data/spec/models/rspeed/variable/key_spec.rb +15 -0
 - data/spec/models/rspeed/variable/pipe_name_spec.rb +15 -0
 - data/spec/models/rspeed/variable/pipes_pattern_spec.rb +5 -0
 - data/spec/models/rspeed/variable/result_spec.rb +19 -0
 - data/spec/models/rspeed/variable/tmp_spec.rb +15 -0
 - data/spec/spec_helper.rb +27 -0
 - data/spec/support/common.rb +5 -3
 - data/spec/support/coverage.rb +14 -0
 - data/spec/support/env_mock.rb +3 -0
 - data/spec/support/fakeredis.rb +3 -0
 - metadata +180 -23
 - data/spec/rails_helper.rb +0 -9
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: c2d2d14366ee70f0cf449f6fbf6bc6c7cedd57edc8497b646721afa4b098720a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 0ac5789e67ba474055620780a0311525bbe29c801b2c09344218888b33de55ac
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 00adb24277015b707cfbd1d5ea0f2cd9b220701344654a107471ab6683ea4876830a34cb34262a42b425078a5dab85efaee16cb2252da1027b807a3409eb22ac
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: aa4932a206cd9a5ab93e4b4217099ebad1a110b8ee9d48c6c0dd9addaf9073d561249480cfe1f74137f484c27a649b05afc4720fde679abb825ef43ba59feb4a
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ## master
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            - None;
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## v0.5.0
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            #### Fix
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            - Add env `RSPEED_NAME` to specify the application name and avoid result conflicts between multiple runs;
         
     | 
| 
      
 10 
     | 
    
         
            +
            - No more depends on pipe sequence to generate ou aggregate the resul;
         
     | 
| 
      
 11 
     | 
    
         
            +
            - rake `rspeed:install`;
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            #### Update
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            - The result of the pipes are no more saved on Redis. It's now calculated based on result key `rspeed`;
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ## v0.4.0
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            - Now we make diff to discover removed and added examples;
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ## v0.3.0
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            - Removed and added files now is considered on run;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            ## v0.2.0
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            - Splits specs by examples over files;
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ## v0.1.0
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            - First release;
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       1 
33 
     | 
    
         
             
            ## v0.0.1
         
     | 
| 
       2 
34 
     | 
    
         | 
| 
       3 
35 
     | 
    
         
             
            - RubyGems namespace reservation.
         
     | 
    
        data/LICENSE
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            The MIT License (MIT)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            Copyright (c)  
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (c) 2017-2020 Washington Botelho
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
       6 
6 
     | 
    
         
             
            of this software and associated documentation files (the "Software"), to deal
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,11 +1,94 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # RSpeed
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            [](https://github.com/wbotelhos/rspeed/actions)
         
     | 
| 
      
 4 
     | 
    
         
            +
            [](https://badge.fury.io/rb/rspeed)
         
     | 
| 
      
 5 
     | 
    
         
            +
            [](https://codeclimate.com/github/wbotelhos/rspeed/maintainability)
         
     | 
| 
      
 6 
     | 
    
         
            +
            [](https://codecov.io/gh/wbotelhos/rspeed)
         
     | 
| 
      
 7 
     | 
    
         
            +
            [](https://www.patreon.com/wbotelhos)
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
            RSpeed splits your specs to you run parallels tests.
         
     | 
| 
       7 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
            ## Install
         
     | 
| 
       8 
12 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
            Add the following code on your `Gemfile` and run `bundle install`:
         
     | 
| 
       10 
14 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 16 
     | 
    
         
            +
            gem 'rspeed'
         
     | 
| 
      
 17 
     | 
    
         
            +
            ```
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ## Setup
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            We need to extract the rake that executes the split via `rspeed:run`.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 24 
     | 
    
         
            +
            rake rspeed:install
         
     | 
| 
      
 25 
     | 
    
         
            +
            ```
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            - `RSPEED_NAME`: You app name to avoid data override
         
     | 
| 
      
 30 
     | 
    
         
            +
            - `RSPEED_PIPE`: Current pipe
         
     | 
| 
      
 31 
     | 
    
         
            +
            - `RSPEED_PIPES`: Quantity of pipes
         
     | 
| 
      
 32 
     | 
    
         
            +
            - `RSPEED_RESULT_KEY`: The key that keeps the final result of all pipes
         
     | 
| 
      
 33 
     | 
    
         
            +
            - `RSPEED_TMP_KEY`: The temporary key that keeps the partial result of the pipes
         
     | 
| 
      
 34 
     | 
    
         
            +
            - `RSPEED`: Enables RSpeed
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 37 
     | 
    
         
            +
            RSPEED=true RSPEED_NAME=authorizy RSPEED_PIPE=1 RSPEED_PIPES=3 bundle exec rake rspeed:run
         
     | 
| 
      
 38 
     | 
    
         
            +
            ```
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            ## How it Works
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            ### First run
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            1. Since we have no statistics on the first time, we run all specs and collect it;
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 47 
     | 
    
         
            +
            { "file": "./spec/models/1_spec.rb", "time": 0.01 }
         
     | 
| 
      
 48 
     | 
    
         
            +
            { "file": "./spec/models/2_spec.rb", "time": 0.02 }
         
     | 
| 
      
 49 
     | 
    
         
            +
            { "file": "./spec/models/3_spec.rb", "time": 0.001 }
         
     | 
| 
      
 50 
     | 
    
         
            +
            { "file": "./spec/models/4_spec.rb", "time": 1 }
         
     | 
| 
      
 51 
     | 
    
         
            +
            ```
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            ### Second and next runs
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            1. Previous statistics is balanced by times and distributed between pipes:
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 58 
     | 
    
         
            +
            { "file": "./spec/models/4_spec.rb", "time": 1 }
         
     | 
| 
      
 59 
     | 
    
         
            +
            ```
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 62 
     | 
    
         
            +
            { "file": "./spec/models/2_spec.rb", "time": 0.02 }
         
     | 
| 
      
 63 
     | 
    
         
            +
            ```
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 66 
     | 
    
         
            +
            { "file": "./spec/models/3_spec.rb", "time": 0.001 }
         
     | 
| 
      
 67 
     | 
    
         
            +
            { "file": "./spec/models/1_spec.rb", "time": 0.01 }
         
     | 
| 
      
 68 
     | 
    
         
            +
            ```
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            2. Run the current pipe `1`:
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 73 
     | 
    
         
            +
            { "file": "./spec/models/4_spec.rb", "time": 1 }
         
     | 
| 
      
 74 
     | 
    
         
            +
            ```
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            - Collects statistics and temporary save it;
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            4. Run the current pipe `2`:
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 81 
     | 
    
         
            +
            { "file": "./spec/models/2_spec.rb", "time": 0.02 }
         
     | 
| 
      
 82 
     | 
    
         
            +
            ```
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            - Collects statistics and temporary save it;
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            5. Run the current pipe `3`:
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 89 
     | 
    
         
            +
            { "file": "./spec/models/3_spec.rb", "time": 0.001 }
         
     | 
| 
      
 90 
     | 
    
         
            +
            { "file": "./spec/models/1_spec.rb", "time": 0.01 }
         
     | 
| 
      
 91 
     | 
    
         
            +
            ```
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            - Collects statistics and temporary save it;
         
     | 
| 
      
 94 
     | 
    
         
            +
            - Sum all the last statistics and save it for the next run;
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              class InstallGenerator < Rails::Generators::Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                source_root File.expand_path('templates', __dir__)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                desc 'Creates RSpeed task'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def create_initializer
         
     | 
| 
      
 10 
     | 
    
         
            +
                  copy_file 'lib/tasks/rspeed.rake', 'lib/tasks/rspeed.rake'
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rspeed.rb
    CHANGED
    
    | 
         @@ -1,4 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              require 'csv'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              require 'rspeed/env'
         
     | 
| 
      
 7 
     | 
    
         
            +
              require 'rspeed/extension'
         
     | 
| 
      
 8 
     | 
    
         
            +
              require 'rspeed/observer'
         
     | 
| 
      
 9 
     | 
    
         
            +
              require 'rspeed/redis'
         
     | 
| 
      
 10 
     | 
    
         
            +
              require 'rspeed/runner'
         
     | 
| 
      
 11 
     | 
    
         
            +
              require 'rspeed/splitter'
         
     | 
| 
      
 12 
     | 
    
         
            +
              require 'rspeed/variable'
         
     | 
| 
       4 
13 
     | 
    
         
             
            end
         
     | 
    
        data/lib/rspeed/env.rb
    ADDED
    
    | 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Env
         
     | 
| 
      
 5 
     | 
    
         
            +
                module_function
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def db
         
     | 
| 
      
 8 
     | 
    
         
            +
                  ENV['RSPEED_DB']&.to_i
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def host
         
     | 
| 
      
 12 
     | 
    
         
            +
                  ENV['RSPEED_HOST']
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def name
         
     | 
| 
      
 16 
     | 
    
         
            +
                  ENV['RSPEED_NAME']
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def pipe
         
     | 
| 
      
 20 
     | 
    
         
            +
                  ENV.fetch('RSPEED_PIPE', 1).to_i
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def pipes
         
     | 
| 
      
 24 
     | 
    
         
            +
                  RSpeed::Redis.result? ? ENV.fetch('RSPEED_PIPES', 1).to_i : 1
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def port
         
     | 
| 
      
 28 
     | 
    
         
            +
                  ENV['RSPEED_PORT']&.to_i
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def result_key
         
     | 
| 
      
 32 
     | 
    
         
            +
                  ENV.fetch('RESPEED_RESULT_KEY', RSpeed::Variable.result)
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def rspeed
         
     | 
| 
      
 36 
     | 
    
         
            +
                  ENV['RSPEED'] == 'true'
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def tmp_key
         
     | 
| 
      
 40 
     | 
    
         
            +
                  ENV.fetch('RESPEED_TMP_KEY', RSpeed::Variable.tmp)
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            if RSpeed::Env.rspeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              require 'rspec'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              RSpec.configure do |config|
         
     | 
| 
      
 7 
     | 
    
         
            +
                config.before(:suite) { RSpeed::Observer.before_suite }
         
     | 
| 
      
 8 
     | 
    
         
            +
                config.before { |example| RSpeed::Observer.before(example) }
         
     | 
| 
      
 9 
     | 
    
         
            +
                config.after { |example| RSpeed::Observer.after(example) }
         
     | 
| 
      
 10 
     | 
    
         
            +
                config.after(:suite) { RSpeed::Observer.after_suite }
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Observer
         
     | 
| 
      
 5 
     | 
    
         
            +
                module_function
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def after(example)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  file_path   = example.metadata[:file_path]
         
     | 
| 
      
 9 
     | 
    
         
            +
                  line_number = example.metadata[:line_number]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  spent_time  = example.clock.now - example.metadata[:start_at]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  File.open(RSpeed::Variable::CSV, 'a') do |file|
         
     | 
| 
      
 13 
     | 
    
         
            +
                    file.write("#{spent_time},#{file_path}:#{line_number}\n")
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def after_suite(splitter = ::RSpeed::Splitter.new)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  RSpeed::Redis.set(RSpeed::Variable.pipe_name, true)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  splitter.append
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  return unless RSpeed::Redis.specs_finished?
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  splitter.rename
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  RSpeed::Redis.clean_pipes_flag
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def before(example)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  example.update_inherited_metadata(start_at: example.clock.now)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def before_suite
         
     | 
| 
      
 34 
     | 
    
         
            +
                  truncate_csv_file
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  RSpeed::Redis.destroy(RSpeed::Variable.tmp) unless RSpeed::Redis.specs_initiated?
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def truncate_csv_file
         
     | 
| 
      
 40 
     | 
    
         
            +
                  File.open(RSpeed::Variable::CSV, 'w') { |file| file.truncate(0) }
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rspeed/redis.rb
    ADDED
    
    | 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 5 
     | 
    
         
            +
                require 'redis'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                module_function
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def clean_pipes_flag
         
     | 
| 
      
 10 
     | 
    
         
            +
                  destroy(RSpeed::Variable::PIPES_PATTERN)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def client
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @client ||= ::Redis.new(db: RSpeed::Env.db, host: RSpeed::Env.host, port: RSpeed::Env.port)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def destroy(pattern = RSpeed::Variable::DEFAULT_PATTERN)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  keys(pattern).each { |key| client.del(key) }
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def get(key)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  client.get(key)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def keys(pattern = RSpeed::Variable::DEFAULT_PATTERN)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  cursor = 0
         
     | 
| 
      
 27 
     | 
    
         
            +
                  result = []
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 30 
     | 
    
         
            +
                    cursor, results = client.scan(cursor, match: pattern)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    result += results
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    break if cursor.to_i.zero?
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  result
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def result?
         
     | 
| 
      
 40 
     | 
    
         
            +
                  keys(RSpeed::Env.result_key).any?
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def set(key, value)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  client.set(key, value)
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def specs_finished?
         
     | 
| 
      
 48 
     | 
    
         
            +
                  RSpeed::Redis.keys(RSpeed::Variable::PIPES_PATTERN).size == RSpeed::Env.pipes
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def specs_initiated?
         
     | 
| 
      
 52 
     | 
    
         
            +
                  RSpeed::Redis.keys(RSpeed::Variable::PIPES_PATTERN).any?
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Runner
         
     | 
| 
      
 5 
     | 
    
         
            +
                module_function
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def run(shell, splitter: ::RSpeed::Splitter.new)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  return if splitter.redundant_run?
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  shell.call(['bundle exec rspec', splitter.pipe_files].compact.join(' '))
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,130 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpeed
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Splitter
         
     | 
| 
      
 5 
     | 
    
         
            +
                require 'json'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(specs_path: './spec/**/*_spec.rb')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @specs_path = specs_path
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def actual_examples
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @actual_examples ||= begin
         
     | 
| 
      
 13 
     | 
    
         
            +
                    [].tap do |examples|
         
     | 
| 
      
 14 
     | 
    
         
            +
                      Dir[@specs_path].sort.each do |file|
         
     | 
| 
      
 15 
     | 
    
         
            +
                        data     = File.open(file).read
         
     | 
| 
      
 16 
     | 
    
         
            +
                        lines    = data.split("\n")
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                        lines&.each&.with_index do |item, index|
         
     | 
| 
      
 19 
     | 
    
         
            +
                          examples << "#{file}:#{index + 1}" if /^it/.match?(item.gsub(/\s+/, ''))
         
     | 
| 
      
 20 
     | 
    
         
            +
                        end
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      stream(:actual_examples, examples)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def append(files = CSV.read(RSpeed::Variable::CSV))
         
     | 
| 
      
 29 
     | 
    
         
            +
                  files.each do |time, file|
         
     | 
| 
      
 30 
     | 
    
         
            +
                    redis.lpush(RSpeed::Env.tmp_key, { file: file, time: time.to_f }.to_json)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def diff
         
     | 
| 
      
 35 
     | 
    
         
            +
                  actual_data = rspeed_data.select { |item| actual_examples.include?(item[:file]) }
         
     | 
| 
      
 36 
     | 
    
         
            +
                  added_data  = added_examples.map { |item| { file: item, time: 0 } }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  removed_examples # called just for stream for now
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  actual_data + added_data
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def first_pipe?
         
     | 
| 
      
 44 
     | 
    
         
            +
                  RSpeed::Env.pipe == 1
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def get(pattern)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @get ||= begin
         
     | 
| 
      
 49 
     | 
    
         
            +
                    return redis.lrange(pattern, 0, -1) if [RSpeed::Variable.result, RSpeed::Variable.tmp].include?(pattern)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    RSpeed::Redis.keys(pattern).map { |key| ::JSON.parse(redis.get(key)) }
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def pipe_files
         
     | 
| 
      
 56 
     | 
    
         
            +
                  return unless RSpeed::Redis.result?
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  split[RSpeed::Variable.key(RSpeed::Env.pipe)][:files].map { |item| item[:file] }.join(' ')
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def redundant_run?
         
     | 
| 
      
 62 
     | 
    
         
            +
                  !first_pipe? && !exists?(RSpeed::Env.result_key)
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                def rename
         
     | 
| 
      
 66 
     | 
    
         
            +
                  redis.rename(RSpeed::Env.tmp_key, RSpeed::Env.result_key)
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                def split(data = diff)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  json = {}
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  RSpeed::Env.pipes.times do |index|
         
     | 
| 
      
 73 
     | 
    
         
            +
                    json[RSpeed::Variable.key(index + 1)] ||= []
         
     | 
| 
      
 74 
     | 
    
         
            +
                    json[RSpeed::Variable.key(index + 1)] = { total: 0, files: [], number: index + 1 }
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  sorted_data = data.sort_by { |item| item[:time] }.reverse
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  sorted_data.each do |record|
         
     | 
| 
      
 80 
     | 
    
         
            +
                    selected_pipe_data = json.min_by { |pipe| pipe[1][:total] }
         
     | 
| 
      
 81 
     | 
    
         
            +
                    selected_pipe      = json[RSpeed::Variable.key(selected_pipe_data[1][:number])]
         
     | 
| 
      
 82 
     | 
    
         
            +
                    time               = record[:time].to_f
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    selected_pipe[:total] += time
         
     | 
| 
      
 85 
     | 
    
         
            +
                    selected_pipe[:files] << { file: record[:file], time: time }
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  json
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                private
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                def added_examples
         
     | 
| 
      
 94 
     | 
    
         
            +
                  @added_examples ||= begin
         
     | 
| 
      
 95 
     | 
    
         
            +
                    (actual_examples - rspeed_examples).tap { |examples| stream(:added_examples, examples) }
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                # TODO: exists? does not work: undefined method `>' for false:FalseClass
         
     | 
| 
      
 100 
     | 
    
         
            +
                def exists?(key)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  redis.keys.include?(key)
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                def redis
         
     | 
| 
      
 105 
     | 
    
         
            +
                  @redis ||= ::RSpeed::Redis.client
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                def removed_examples
         
     | 
| 
      
 109 
     | 
    
         
            +
                  @removed_examples ||= begin
         
     | 
| 
      
 110 
     | 
    
         
            +
                    (rspeed_examples - actual_examples).tap { |examples| stream(:removed_examples, examples) }
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                def removed_time
         
     | 
| 
      
 115 
     | 
    
         
            +
                  removed_examples.sum { |item| item[0].to_f }
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                def rspeed_data
         
     | 
| 
      
 119 
     | 
    
         
            +
                  @rspeed_data ||= get(RSpeed::Env.result_key).map { |item| JSON.parse(item, symbolize_names: true) }
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                def rspeed_examples
         
     | 
| 
      
 123 
     | 
    
         
            +
                  rspeed_data.map { |item| item[:file] }
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                def stream(type, data)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  puts "PIPE: #{RSpeed::Env.pipe} with #{type}: #{data}"
         
     | 
| 
      
 128 
     | 
    
         
            +
                end
         
     | 
| 
      
 129 
     | 
    
         
            +
              end
         
     | 
| 
      
 130 
     | 
    
         
            +
            end
         
     |