crude-mutant 0.5.5 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15e303ad1352ba2818a0f79e470d4991efca505c4714a0f54ea6a0e42a82ddbe
4
- data.tar.gz: 241e688e2dc2740eca82d97c787821311b65b2fb12fea7ca748eee8352823dc0
3
+ metadata.gz: c2de77d0a729f2d9979af69f870ed458ab7bcc0e7b21d06c91a05e34d054a14f
4
+ data.tar.gz: e9eca3bdb377d9d4c1408208f1de5418a91a60f970f3443c45807e00b2c08b7c
5
5
  SHA512:
6
- metadata.gz: 7235f34036f9f7588bc5d9e1f13e793dc0c09f767485fff9ae2b3f0985cf23d6086c1186efda0ac84a9039b3950f9952c4d3a3c6c1251610538750e9da8fc08b
7
- data.tar.gz: 917d0b1b09195c45f1f823aee7ee9563a00a81a8e931de19824a07e6cefe82f6f47989b764faac1b4724e85427154d2c598beef5f737a80b2278b6dfef06e9d3
6
+ metadata.gz: 8b1e55aaff7fdfb50d913e5954c2f36efd3ed49f08bf7404b2bfca723de3a0b888d4af45bb030d269b97a78c3d9a6ff653a85d76b64a0f2cbafe47a72d9a6856
7
+ data.tar.gz: 7e8702f3850647893cda4978c7eeb02a35962a948b44c7254dc734c4fbcd42e3a647b582edd4ca519e30a711b0cab0a9fa85791e98a24cee673f2b6d81706dd6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- crude-mutant (0.5.5)
4
+ crude-mutant (0.6.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/exe/cm CHANGED
@@ -12,7 +12,7 @@ Options = Struct.new(
12
12
  :file_to_mutate,
13
13
  )
14
14
 
15
- args = Options.new(false, 1, 1)
15
+ args = Options.new(false, 0, 1)
16
16
  OptionParser.new do |opts|
17
17
  opts.banner = "Usage: crude-mutant [options]"
18
18
 
data/exe/crude-mutant CHANGED
@@ -12,7 +12,7 @@ Options = Struct.new(
12
12
  :file_to_mutate,
13
13
  )
14
14
 
15
- args = Options.new(false, 1, 1)
15
+ args = Options.new(false, 0, 1)
16
16
  OptionParser.new do |opts|
17
17
  opts.banner = "Usage: crude-mutant [options]"
18
18
 
@@ -9,8 +9,8 @@ module CrudeMutant
9
9
  stream.print(
10
10
  JSON.dump({
11
11
  result.file_path => {
12
- passed_lines: result.run_results.select(&:success?).map(&:line_number),
13
- failed_lines: result.run_results.reject(&:success?).map(&:line_number),
12
+ passed_lines: result.run_results.reject(&:success?).map(&:line_number),
13
+ failed_lines: result.run_results.select(&:success?).map(&:line_number),
14
14
  }
15
15
  }),
16
16
  )
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrudeMutant
4
+ class LinePermuter
5
+ def initialize(file_contents)
6
+ @file_contents = file_contents
7
+ end
8
+
9
+ def number_of_permutations
10
+ @number_of_permutations ||= @file_contents.split("\n").size
11
+ end
12
+
13
+ def take(permutation_number)
14
+ if permutation_number < 0
15
+ raise ArgumentError, 'permutation_number must be 0 or more'
16
+ end
17
+
18
+ if permutation_number > number_of_permutations - 1
19
+ raise ArgumentError, 'permutation_number must be less than number_of_permutations - 1'
20
+ end
21
+
22
+ (contents_as_array.slice(0, permutation_number) +
23
+ contents_as_array.slice(permutation_number + 1, number_of_permutations)).join("\n")
24
+ end
25
+
26
+ def line(line_number)
27
+ contents_as_array.fetch(line_number)
28
+ end
29
+
30
+ private
31
+
32
+ def contents_as_array
33
+ @contents_as_array ||= @file_contents.split("\n")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrudeMutant
4
+ class PermutationSelector
5
+ def self.select(number_of_permutations:, number_of_sections:, section_number:)
6
+ if section_number < 0
7
+ raise ArgumentError, 'section_number must be 0 or greater'
8
+ end
9
+
10
+ if section_number >= number_of_sections
11
+ raise ArgumentError, 'section_number must be less than number_of_sections - 1'
12
+ end
13
+
14
+ if number_of_sections <= 0
15
+ raise ArgumentError, 'number_of_sections must be greater than 0'
16
+ end
17
+
18
+ if number_of_sections > number_of_permutations
19
+ raise ArgumentError, 'number_of_sections must less than number_of_permutations'
20
+ end
21
+
22
+ section_size = (number_of_permutations.to_f / number_of_sections).ceil
23
+ starting_number = section_number * section_size
24
+
25
+ buckets = Array.new(number_of_sections, 0)
26
+
27
+ current_bucket = 0
28
+ i = 0
29
+
30
+ while i < number_of_permutations do
31
+ buckets[current_bucket] += 1
32
+ i += 1
33
+ current_bucket = i % number_of_sections
34
+ end
35
+
36
+ start = buckets.slice(0, section_number).sum
37
+ stop = start + buckets[section_number]
38
+
39
+ buckets[section_number].times.map do |i|
40
+ i + start
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CrudeMutant
4
- VERSION = "0.5.5"
4
+ VERSION = "0.6.0"
5
5
  end
data/lib/crude_mutant.rb CHANGED
@@ -3,12 +3,12 @@
3
3
  require "benchmark"
4
4
 
5
5
  require "crude_mutant/executor"
6
- require "crude_mutant/file_loader"
7
- require "crude_mutant/file_writer"
6
+ require "crude_mutant/json_result_printer"
7
+ require "crude_mutant/line_permuter"
8
+ require "crude_mutant/permutation_selector"
8
9
  require "crude_mutant/progress"
9
10
  require "crude_mutant/result"
10
11
  require "crude_mutant/result_printer"
11
- require "crude_mutant/json_result_printer"
12
12
  require "crude_mutant/run_result"
13
13
  require "crude_mutant/terminal_calculator"
14
14
  require "crude_mutant/version"
@@ -22,11 +22,14 @@ module CrudeMutant
22
22
  printer_klass = result_printer == :json ? JsonResultPrinter : ResultPrinter
23
23
 
24
24
  start_time = Time.now.to_f
25
- file = FileLoader.load(file_path)
26
- num_lines_in_file = file.lines_in_file
27
- section_size = (num_lines_in_file.to_f / total_sections).ceil
28
- starting_line_number = section * section_size - 1
29
- stopping_line_number = starting_line_number + section_size
25
+ original_file_contents = File.read(file_path)
26
+ permuter = LinePermuter.new(original_file_contents)
27
+
28
+ permutations_to_run = PermutationSelector.select(
29
+ number_of_permutations: permuter.number_of_permutations,
30
+ number_of_sections: total_sections,
31
+ section_number: section,
32
+ )
30
33
 
31
34
  initial_success = Executor.call(test_command)
32
35
 
@@ -35,24 +38,25 @@ module CrudeMutant
35
38
  end
36
39
 
37
40
  begin
38
- line_number = starting_line_number
39
- test_runs = file.contents_as_array.reduce([]) do |acc, contents|
40
- line_number += 1
41
-
42
- if (starting_line_number..stopping_line_number).cover?(line_number) && contents.strip.size != 0
43
- result = [perform_run(
44
- file,
45
- test_command,
46
- line_number
47
- )]
48
- else
49
- result = [NullRunResult.new(line_number)]
50
- end
41
+ test_runs = permutations_to_run.reduce([]) do |acc, permutation|
42
+ success, bench = perform_run(
43
+ file_path: file_path,
44
+ file_contents: permuter.take(permutation),
45
+ command: test_command,
46
+ )
47
+
48
+ result = [RunResult.new(
49
+ file_path,
50
+ permutation,
51
+ success,
52
+ permuter.line(permutation),
53
+ bench,
54
+ )]
51
55
 
52
56
  if block_given?
53
57
  block.call(
54
58
  Progress.new(
55
- num_lines_in_file,
59
+ permutations_to_run.size,
56
60
  acc + result
57
61
  )
58
62
  )
@@ -61,7 +65,7 @@ module CrudeMutant
61
65
  acc + result
62
66
  end
63
67
  ensure
64
- FileWriter.write(file_path, file.contents_as_array)
68
+ File.write(file_path, original_file_contents)
65
69
  end
66
70
 
67
71
  stop_time = Time.now.to_f
@@ -73,21 +77,15 @@ module CrudeMutant
73
77
 
74
78
  private
75
79
 
76
- def perform_run(file_loader, test_command, line_number)
80
+ def perform_run(file_path:, file_contents:, command:)
77
81
  success = false
78
82
  bench = Benchmark.measure do
79
- FileWriter.write(file_loader.file_path, file_loader.without_line(line_number))
83
+ File.write(file_path, file_contents)
80
84
 
81
- success = Executor.call(test_command)
85
+ success = Executor.call(command)
82
86
  end
83
87
 
84
- RunResult.new(
85
- file_loader.file_path,
86
- line_number,
87
- success,
88
- file_loader.contents_as_array[line_number],
89
- bench
90
- )
88
+ [success, bench]
91
89
  end
92
90
  end
93
91
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crude-mutant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Sutton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-20 00:00:00.000000000 Z
11
+ date: 2019-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,9 +81,9 @@ files:
81
81
  - lib/crude-mutant.rb
82
82
  - lib/crude_mutant.rb
83
83
  - lib/crude_mutant/executor.rb
84
- - lib/crude_mutant/file_loader.rb
85
- - lib/crude_mutant/file_writer.rb
86
84
  - lib/crude_mutant/json_result_printer.rb
85
+ - lib/crude_mutant/line_permuter.rb
86
+ - lib/crude_mutant/permutation_selector.rb
87
87
  - lib/crude_mutant/progress.rb
88
88
  - lib/crude_mutant/result.rb
89
89
  - lib/crude_mutant/result_printer.rb
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CrudeMutant
4
- class FileLoader
5
- class LoadError < StandardError; end
6
-
7
- def self.load(file_path)
8
- if !file_path.is_a?(String) || !File.exist?(file_path)
9
- raise LoadError, "Could not load file: #{file_path}"
10
- end
11
-
12
- new(file_path, File.readlines(file_path))
13
- end
14
-
15
- attr_reader :file_path
16
-
17
- def initialize(file_path, contents_as_array)
18
- @file_path = file_path
19
- @contents_as_array = contents_as_array
20
- end
21
-
22
- def lines_in_file
23
- @contents_as_array.size
24
- end
25
-
26
- def contents_as_array
27
- @contents_as_array
28
- end
29
-
30
- def without_line(line_number)
31
- (contents_as_array.slice(0, line_number) || []) +
32
- (contents_as_array.slice(line_number + 1, lines_in_file) || [])
33
- end
34
- end
35
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CrudeMutant
4
- class FileWriter
5
- def self.write(file_path, contents_as_array)
6
- File.open(file_path, 'w') do |f|
7
- contents_as_array.each do |line|
8
- f.write(line)
9
- end
10
-
11
- f.flush
12
- end
13
- end
14
- end
15
- end