what_to_run 0.1.0 → 1.0.2

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,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NWI3ZjRiMTMzYmQ5YzA0NmM4NjJkNTViM2VkOTJkZTI2NDQxNmE4MQ==
5
- data.tar.gz: !binary |-
6
- MmE2Yzc1YWVhMjA3NDliZjk4YTQ5NzdlNjljNTg4NzZjMjBjODM1Mg==
2
+ SHA1:
3
+ metadata.gz: 5628bef322e5ffe04df75062217228f1c462251a
4
+ data.tar.gz: a3a0beabaabfb83223a0b588acb713a0e56a682f
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZmY3Yzk3ZmY1ZmMwMTMzNTc3ZWYyYzRjNjU5NjVhODY0NmNkODI2MTM4YzJi
10
- NGNjYTRhNTg5MjRkMTdhY2NhNWNhYjBhZDE4M2VjYjEwOTI1MTJhNWFiNWRh
11
- NDAxNjFiMjc1NDUyYTI0YTllYzBlNTk0NmQ2MWQ2MWYyM2NiMmQ=
12
- data.tar.gz: !binary |-
13
- ZGZmMzBiYjZkZmUzMzcxNDZhZWU5MjgxZTAwMDQwMjAwOGY0MTQwZTliMDdm
14
- MmNjNjczNTdlN2YzNjg5YWUyZWFlYzkwZTlhMTIwMWY0YWQ1MDk1MjRhNjY0
15
- MmIxYzM3M2NjYWYxYTM3OTM4ZTgzOTNhOGRlOWRkY2JhYjQzNjI=
6
+ metadata.gz: bbb66e545238e59c45d64b927b518a9b1b25bfb6cd7e24c17125ac5e00b32f3ead0bbf2346052cbeb7f5be69b10687e2106153303c5377ad7f73924d3a6a38f8
7
+ data.tar.gz: ff854a098d8f76780a4c7977cdb17ad57d3adfc1a1a1253910e4fca1a3bd2b71b3a2c3864c8145ef4a384830370900cda21ebb8e63b29ff006cc4aace266e702
data/README.md CHANGED
@@ -1,14 +1,30 @@
1
1
  # What To Run
2
2
 
3
+ [![Join the chat at https://gitter.im/DyegoCosta/what_to_run](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DyegoCosta/what_to_run?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+
3
5
  [![Build Status](https://travis-ci.org/DyegoCosta/what_to_run.svg?branch=master)](https://travis-ci.org/DyegoCosta/what_to_run)
4
6
 
5
- What To Run is a lib for regression test selection, use it to predict which tests you should run when you make any modification on your codebase.
7
+ What To Run is a lib for regression test selection for Ruby projects, use it to predict which tests you should run when you make any modification on your codebase.
8
+
9
+ This lib was inspired by [@tenderlove](https://github.com/tenderlove) [blog post](tenderlove-post). Make sure to check it out.
10
+
6
11
 
7
- This lib is based on [@tenderlove](https://github.com/tenderlove) idea and guidance, make sure to read his [blog post](http://tenderlovemaking.com/2015/02/13/predicting-test-failues.html) on the subject.
12
+ From the _[An Empirical Study of Regression Test Selection Techniques](rts-article)_ article:
13
+
14
+ > Regression testing is the process of validating modified software to detect whether new errors
15
+ have been introduced into previously tested code and to provide confidence that modifications
16
+ are correct. Since regression testing is an expensive process, researchers have proposed
17
+ regression test selection techniques as a way to reduce some of this expense. These techniques
18
+ attempt to reduce costs by selecting and running only a subset of the test cases in a program’s
19
+ existing test suite.
20
+
21
+ [rts-article]: https://www.cs.umd.edu/~aporter/Docs/p184-graves.pdf
22
+ [tenderlove-post]: http://tenderlovemaking.com/2015/02/13/predicting-test-failues.html
8
23
 
9
24
  ## Requirements
10
25
 
11
26
  - Project must be inside a Git repository
27
+ - CMake to build the gem
12
28
 
13
29
  ## Installation
14
30
 
@@ -27,12 +43,12 @@ $ bundle
27
43
  Or install it yourself as:
28
44
 
29
45
  ```
30
- gem install what_to_run
46
+ $ gem install what_to_run
31
47
  ```
32
48
 
33
49
  ## Usage
34
50
 
35
- Require the lib with:
51
+ Require it after requiring your test framework and before load your files to be tested and your test suite config:
36
52
 
37
53
  Minitest
38
54
 
@@ -46,29 +62,41 @@ RSpec
46
62
  require 'what_to_run/rspec'
47
63
  ```
48
64
 
49
- Run your tests on a clean git branch
65
+ Run your full tests suite with COLLECT=1 on a **clean git branch**
50
66
 
51
67
  Minitest
52
68
 
53
69
  ```
54
- $ COLLECTION=1 bundle exec rake test
70
+ $ COLLECT=1 bundle exec rake test
55
71
  ```
56
72
 
57
73
  RSpec
58
74
 
59
75
  ```
60
- $ COLLECTION=1 bundle exec rspec
76
+ $ COLLECT=1 bundle exec rspec
61
77
  ```
62
78
 
63
79
  This will create the initial coverage information. Then make your desired modifications on your code.
64
80
 
65
- Now to predict which tests is likely fail, run this:
81
+ Now to run the tests that could reveal faults do the following
82
+
83
+ ```
84
+ $ what_to_run <framework> [options]
85
+ ```
86
+
87
+ Supported frameworks are:
66
88
 
67
89
  ```
68
- $ what_to_run
90
+ rspec
91
+ minitest
69
92
  ```
70
93
 
71
- :warning: A `run_log.json` file will be created in the current directory, you might want to include it in your `.gitignore`.
94
+ Options are:
95
+
96
+ ```
97
+ -e, --exec EXECUTABLE Alternate test runner executable
98
+ -h, --help Prints this help
99
+ ```
72
100
 
73
101
  ## Contributing
74
102
 
@@ -2,4 +2,5 @@
2
2
 
3
3
  require 'what_to_run'
4
4
 
5
- puts WhatToRun.predict
5
+ WhatToRun::CLI.new.run ARGV
6
+
@@ -1,91 +1,63 @@
1
- require 'json'
2
- require 'rugged'
3
1
  require 'set'
2
+ require 'rugged'
3
+
4
+ require_relative 'what_to_run/tracker'
4
5
 
5
6
  module WhatToRun
6
- extend self
7
+ autoload :CLI, 'what_to_run/cli'
8
+ autoload :VERSION, 'what_to_run/version'
7
9
 
8
- def predict
9
- lines_to_run.inject([]) do |tests, (file, line)|
10
- path = File.expand_path(file)
11
- tests += Array cov_map[path][line]
10
+ class << self
11
+ def predict
12
+ lines_to_run.inject(Set.new) do |tests, (file, line)|
13
+ tests += Array cov_map[file][line]
14
+ end
12
15
  end
13
- end
14
-
15
- def lines_to_run
16
- repo = Rugged::Repository.new('.')
17
- lines_to_run = Set.new
18
16
 
19
- repo.index.diff.each_patch do |patch|
20
- file = patch.delta.old_file[:path]
21
-
22
- patch.each_hunk do |hunk|
23
- hunk.each_line do |line|
24
- case line.line_origin
25
- when :addition
26
- lines_to_run << [file, line.new_lineno]
27
- when :deletion
28
- lines_to_run << [file, line.old_lineno]
29
- when :context
30
- # do nothing
17
+ def lines_to_run
18
+ repository = Rugged::Repository.discover('.')
19
+ repository_root = File.expand_path("..", repository.path)
20
+ lines_to_run = Set.new
21
+
22
+ repository.index.diff.each_patch do |patch|
23
+ file = patch.delta.old_file[:path]
24
+ file_path = File.join(repository_root, file)
25
+
26
+ patch.each_hunk do |hunk|
27
+ hunk.each_line do |line|
28
+ case line.line_origin
29
+ when :addition
30
+ lines_to_run << [file_path, line.new_lineno]
31
+ when :deletion
32
+ lines_to_run << [file_path, line.old_lineno]
33
+ when :context
34
+ # do nothing
35
+ end
31
36
  end
32
37
  end
33
38
  end
34
- end
35
-
36
- lines_to_run
37
- end
38
-
39
- def cov_delta(before, after)
40
- after.each_with_object({}) do |(file_name, lines_cov), delta|
41
- before_lines_cov = before[file_name]
42
-
43
- # skip arrays that are exactly the same
44
- next if before_lines_cov == lines_cov
45
39
 
46
- # subtract the old coverage from the new coverage
47
- cov = lines_cov_delta(before_lines_cov, lines_cov)
48
-
49
- # add the "diffed" coverage to the hash
50
- delta[file_name] = cov
40
+ lines_to_run
51
41
  end
52
- end
53
-
54
- def cov_map
55
- cov_map = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
56
42
 
57
- File.open('run_log.json') do |f|
58
- JSON.parse(f.read).each do |cov_info|
59
- before, after = cov_info.last(2)
60
- desc = build_test_desc(cov_info)
43
+ def cov_map
44
+ schema = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
61
45
 
62
- delta = cov_delta(before, after)
63
-
64
- delta.each_pair do |file, lines|
46
+ @cov_map ||= Tracker.read.inject(schema) do |cov_map, (desc, cov_delta)|
47
+ cov_delta.each_pair do |file, lines|
65
48
  file_map = cov_map[file]
66
49
 
67
- lines.each_with_index do |val, i|
68
- file_map[i + 1] << desc if line_executed?(val)
50
+ lines.each_with_index do |line, i|
51
+ file_map[i + 1] << desc if line_executed?(line)
69
52
  end
70
53
  end
54
+
55
+ cov_map
71
56
  end
72
57
  end
73
58
 
74
- cov_map
75
- end
76
-
77
- def build_test_desc(cov_info)
78
- using_minitest = cov_info.length == 4
79
- using_minitest ? cov_info.first(2).join('#') : cov_info.first
80
- end
81
-
82
- def line_executed?(line)
83
- line.to_i > 0
84
- end
85
-
86
- def lines_cov_delta(before_lines_cov, after_lines_cov)
87
- after_lines_cov.zip(before_lines_cov).map do |lines_after, lines_before|
88
- lines_after ? lines_after - lines_before : lines_after
59
+ def line_executed?(line)
60
+ line.to_i > 0
89
61
  end
90
62
  end
91
63
  end
@@ -0,0 +1,52 @@
1
+ require 'optparse'
2
+ require 'shellwords'
3
+
4
+ module WhatToRun
5
+ class CLI
6
+ def run(argv)
7
+ framework = Array(argv)[0]
8
+
9
+ abort 'Must specify a test framework' unless framework
10
+
11
+ options = parse_options!(argv)
12
+
13
+ begin
14
+ runner = load_runner framework.downcase
15
+ runner.new(options).run
16
+ rescue LoadError
17
+ abort "Unsupported test framework: #{framework}"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def parse_options!(argv)
24
+ options = {}
25
+
26
+ parser = OptionParser.new do |opts|
27
+ opts.banner = 'Usage: what_to_run <framework> [options]'
28
+
29
+ opts.on('-e', '--exec EXECUTABLE', 'Alternate test runner executable') do |e|
30
+ options[:exec] = e
31
+ end
32
+
33
+ opts.on('-h', '--help', 'Prints this help') do
34
+ puts opts
35
+ exit
36
+ end
37
+ end
38
+
39
+ parser.parse!(argv)
40
+
41
+ options
42
+ end
43
+
44
+ def load_runner(framework)
45
+ require "what_to_run/#{framework}/runner"
46
+ klass_name = "WhatToRun::#{RUNNERS[framework]}::Runner"
47
+ klass_name.split('::').inject(Object) {|x, y| x.const_get(y.to_sym)}
48
+ end
49
+
50
+ RUNNERS = {'rspec' => 'RSpec', 'minitest' => 'Minitest'}
51
+ end
52
+ end
@@ -0,0 +1,77 @@
1
+ module WhatToRun
2
+ class Differ
3
+ class << self
4
+ ##
5
+ # Gives the delta beteween the coverage result
6
+ # before and after a test run and before starting
7
+ # the test suite
8
+ #
9
+ # Results in the lines that may trigger the test
10
+ # that gave the after result
11
+ def coverage_delta(cov_before, cov_after, cov_before_suite)
12
+ cov_after.each_with_object({}) do |(file_name, lines_cov_after), delta|
13
+ lines_cov_before = cov_before[file_name]
14
+ lines_cov_before_suite = cov_before_suite[file_name]
15
+
16
+ next unless file_covered?(lines_cov_before, lines_cov_after)
17
+
18
+ lines_delta = lines_cov_delta \
19
+ lines_cov_before_suite, lines_cov_before, lines_cov_after
20
+
21
+ delta[file_name] = lines_delta
22
+ end
23
+ end
24
+
25
+ ##
26
+ # It needs to diff the diff of before and after
27
+ # with the coverage before the test suite in order
28
+ # to include the uncovered lines to all tests that
29
+ # touch this file
30
+ def lines_cov_delta(before_suite, before, after)
31
+ delta = diff before_suite, diff(before, after)
32
+ delta.map(&method(:normalize_cov_result))
33
+ end
34
+
35
+ def diff(before, after)
36
+ after = Array(after)
37
+ before = Array(before)
38
+
39
+ after.zip(before).map do |lines_after, lines_before|
40
+ lines_after ? lines_after - lines_before.to_i : lines_after
41
+ end
42
+ end
43
+
44
+ ##
45
+ # The possible param value that this method might receive
46
+ # are the following
47
+ #
48
+ # @param result positive => should run the test
49
+ # @param result negative => should run the test
50
+ # @param result nil => should run the test
51
+ # @param result zero => should not run the test
52
+ #
53
+ # This method will convert negative and nil values to 1,
54
+ # which will make them represent lines that should be run.
55
+ # The positive lines can be kept as they are since this mean
56
+ # they will be run.
57
+ #
58
+ # The only exception case is the 0 result which will be kept
59
+ # as it is so we don't run lines within the not called methods
60
+ #
61
+ # This introduces false positives to avoid missing tests that
62
+ # depends on lines that are evaluated when the file is required
63
+ #
64
+ # @return 1 to represent that this line should trigger the current test
65
+ # @return 0 to represent that this line should not trigger the current test
66
+ def normalize_cov_result(result)
67
+ result.nil? || result.to_i < 0 ? 1 : result
68
+ end
69
+
70
+ def file_covered?(cov_before, cov_after)
71
+ cov_before != cov_after
72
+ end
73
+ end
74
+
75
+ private_class_method :lines_cov_delta, :file_covered?
76
+ end
77
+ end
@@ -1,26 +1,28 @@
1
- require 'json'
2
- require 'coverage'
3
- require 'coverage_peeker'
1
+ configure = -> do
2
+ require 'coverage'
3
+ require 'coverage_peeker'
4
+ require 'what_to_run/tracker'
4
5
 
5
- Coverage.start
6
+ Coverage.start
6
7
 
7
- require 'minitest'
8
+ require 'minitest'
8
9
 
9
- class Minitest::Runnable
10
- LOGS = []
10
+ WhatToRun::Tracker.start
11
11
 
12
- Minitest.after_run {
13
- File.open('run_log.json', 'w') { |f| f.write JSON.dump LOGS }
14
- }
12
+ class Minitest::Runnable
13
+ Minitest.after_run {WhatToRun::Tracker.finish}
15
14
 
16
- class << self
17
- alias :old_run_one_method :run_one_method
15
+ class << self
16
+ alias :old_run_one_method :run_one_method
18
17
 
19
- def run_one_method klass, method_name, reporter
20
- before = CoveragePeeker.peek_result
21
- old_run_one_method klass, method_name, reporter
22
- after = CoveragePeeker.peek_result
23
- LOGS << [ klass.name, method_name.to_s, before, after ]
18
+ def run_one_method(klass, method_name, reporter)
19
+ before = CoveragePeeker.peek_result
20
+ old_run_one_method klass, method_name, reporter
21
+ after = CoveragePeeker.peek_result
22
+ WhatToRun::Tracker.track "#{klass.name}##{method_name}", before, after
23
+ end
24
24
  end
25
25
  end
26
26
  end
27
+
28
+ configure.call if ENV['COLLECT'] && ENV['COLLECT'] != 'false'
@@ -0,0 +1,28 @@
1
+ require 'what_to_run/runner'
2
+ require 'shellwords'
3
+
4
+ module WhatToRun
5
+ module Minitest
6
+ class Runner < WhatToRun::Runner
7
+ DEFAULT_EXECUTABLE = 'bundle exec rake test'.freeze
8
+
9
+ def initialize(opts = {})
10
+ super({exec: DEFAULT_EXECUTABLE}.merge(opts))
11
+ end
12
+
13
+ private
14
+
15
+ def predicted_example_args
16
+ patterns = predicted_examples.flat_map do |example|
17
+ "^#{example}$"
18
+ end
19
+
20
+ examples = patterns.join('|')
21
+
22
+ name_arg = Shellwords.escape("--name=/#{examples}/")
23
+
24
+ "TESTOPTS=\"#{name_arg}\""
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,21 +1,27 @@
1
- require 'json'
2
- require 'rspec'
1
+ configure = -> do
2
+ require 'coverage'
3
+ require 'coverage_peeker'
4
+ require 'what_to_run/tracker'
3
5
 
4
- require 'coverage'
5
- require 'coverage_peeker'
6
+ Coverage.start
6
7
 
7
- LOGS = []
8
- Coverage.start
8
+ RSpec.configuration.before(:suite) do
9
+ WhatToRun::Tracker.start
10
+ end
9
11
 
10
- RSpec.configuration.after(:suite) {
11
- File.open('run_log.json', 'w') { |f| f.write JSON.dump LOGS }
12
- }
12
+ RSpec.configuration.after(:suite) do
13
+ WhatToRun::Tracker.finish
14
+ Coverage.result
15
+ end
13
16
 
14
- RSpec.configuration.around(:example) do |example|
15
- before = CoveragePeeker.peek_result
16
- puts 'before:' + before.object_id.to_s
17
- example.call
18
- after = CoveragePeeker.peek_result
19
- puts 'after:' + after.object_id.to_s
20
- LOGS << [ example.full_description, before, after ]
17
+ RSpec.configuration.around(:each) do |example|
18
+ before = CoveragePeeker.peek_result
19
+ example.call
20
+ after = CoveragePeeker.peek_result
21
+
22
+ WhatToRun::Tracker.track \
23
+ example.metadata[:full_description], before, after
24
+ end
21
25
  end
26
+
27
+ configure.call if ENV['COLLECT'] && ENV['COLLECT'] != 'false'
@@ -0,0 +1,21 @@
1
+ require 'what_to_run/runner'
2
+ require 'shellwords'
3
+
4
+ module WhatToRun
5
+ module RSpec
6
+ class Runner < WhatToRun::Runner
7
+ DEFAULT_EXECUTABLE = 'bundle exec rspec'.freeze
8
+
9
+ def initialize(opts = {})
10
+ super({exec: DEFAULT_EXECUTABLE}.merge(opts))
11
+ end
12
+
13
+ private
14
+
15
+ def predicted_example_args
16
+ args = predicted_examples.flat_map { |example| ['-e', example] }
17
+ Shellwords.join(args)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ require 'what_to_run'
2
+
3
+ module WhatToRun
4
+ ##
5
+ # Abstract base spec runner
6
+ class Runner
7
+ attr_reader :executable, :collect
8
+
9
+ def initialize(opts = {})
10
+ @executable = opts.fetch(:exec)
11
+ end
12
+
13
+ def run
14
+ if predicted_examples.empty?
15
+ exit 0
16
+ else
17
+ Kernel.exec command
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def command
24
+ "#{executable} #{predicted_example_args}"
25
+ end
26
+
27
+ def predicted_example_args
28
+ fail NotImplementedError, 'Subclass must override #predicted_example_args'
29
+ end
30
+
31
+ def predicted_examples
32
+ @predicted_examples ||= WhatToRun.predict
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,74 @@
1
+ require 'sqlite3'
2
+ require 'fileutils'
3
+
4
+ require 'coverage_peeker'
5
+ require_relative 'differ'
6
+
7
+ module WhatToRun
8
+ class Tracker
9
+ FileUtils.mkdir_p('.what_to_run')
10
+
11
+ DB_NAME = 'run_log'.freeze
12
+
13
+ DB = SQLite3::Database.open \
14
+ ".what_to_run/#{DB_NAME}#{ENV['TEST_ENV_NUMBER']}.db"
15
+
16
+ class << self
17
+ def start
18
+ DB.execute 'drop table if exists coverage'
19
+
20
+ DB.execute <<-SQL
21
+ create table if not exists coverage (
22
+ description varchar,
23
+ log blob
24
+ )
25
+ SQL
26
+
27
+ @before_suite = CoveragePeeker.peek_result
28
+ end
29
+
30
+ def track(description, before, after)
31
+ coverage = Marshal.dump \
32
+ Differ.coverage_delta(before, after, @before_suite)
33
+
34
+ DB.execute 'insert into coverage VALUES(?, ?)',
35
+ [description, SQLite3::Blob.new(coverage)]
36
+ end
37
+
38
+ def finish
39
+ DB.close
40
+ end
41
+
42
+ def read
43
+ query = 'select description, log from coverage'
44
+
45
+ unless additional_databases.empty?
46
+ attach_databases!
47
+ query += union_query
48
+ end
49
+
50
+ DB.execute(query).map { |row| [row[0], Marshal.load(row[1])] }
51
+ end
52
+
53
+ def additional_databases
54
+ count = Dir['.what_to_run/*.db'].length
55
+ (2..count).map { |n| "#{DB_NAME}#{n}" }
56
+ end
57
+
58
+ def attach_databases!
59
+ additional_databases.each do |db|
60
+ DB.execute "attach '.what_to_run/#{db}.db' as #{db}"
61
+ end
62
+ end
63
+
64
+ def union_query
65
+ additional_databases.inject('') do |query, db|
66
+ query += " union select description, log from #{db}.coverage"
67
+ end
68
+ end
69
+ end
70
+
71
+ private_class_method :additional_databases,
72
+ :attach_databases!, :union_query
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module WhatToRun
2
+ VERSION = '1.0.2'
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: what_to_run
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -9,48 +9,68 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-30 00:00:00.000000000 Z
12
+ date: 2015-04-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0.9'
21
- - - ! '>='
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
23
  version: 0.9.0
24
24
  type: :development
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ~>
28
+ - - "~>"
29
29
  - !ruby/object:Gem::Version
30
30
  version: '0.9'
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.9.0
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: rugged
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.21'
41
- - - ! '>='
41
+ - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  version: 0.21.0
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - ~>
48
+ - - "~>"
49
49
  - !ruby/object:Gem::Version
50
50
  version: '0.21'
51
- - - ! '>='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: 0.21.0
54
+ - !ruby/object:Gem::Dependency
55
+ name: sqlite3
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.3'
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.3.10
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '1.3'
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 1.3.10
54
74
  description: Predict which tests are likely to fail after you’ve changed the code
55
75
  email: dyego@dyegocosta.com
56
76
  executables:
@@ -66,8 +86,15 @@ files:
66
86
  - ext/coverage_peeker/extconf.rb
67
87
  - lib/coverage_peeker.rb
68
88
  - lib/what_to_run.rb
89
+ - lib/what_to_run/cli.rb
90
+ - lib/what_to_run/differ.rb
69
91
  - lib/what_to_run/minitest.rb
92
+ - lib/what_to_run/minitest/runner.rb
70
93
  - lib/what_to_run/rspec.rb
94
+ - lib/what_to_run/rspec/runner.rb
95
+ - lib/what_to_run/runner.rb
96
+ - lib/what_to_run/tracker.rb
97
+ - lib/what_to_run/version.rb
71
98
  homepage: https://github.com/DyegoCosta/what_to_run
72
99
  licenses:
73
100
  - MIT
@@ -78,12 +105,12 @@ require_paths:
78
105
  - lib
79
106
  required_ruby_version: !ruby/object:Gem::Requirement
80
107
  requirements:
81
- - - ! '>='
108
+ - - ">="
82
109
  - !ruby/object:Gem::Version
83
110
  version: 1.9.3
84
111
  required_rubygems_version: !ruby/object:Gem::Requirement
85
112
  requirements:
86
- - - ! '>='
113
+ - - ">="
87
114
  - !ruby/object:Gem::Version
88
115
  version: '0'
89
116
  requirements: []