Class: TestSuiteSplitter::RspecHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/test_suite_splitter/rspec_helper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(groups:, group_number:, **options) ⇒ RspecHelper

Returns a new instance of RspecHelper.



4
5
6
7
8
9
10
11
12
# File 'lib/test_suite_splitter/rspec_helper.rb', line 4

def initialize(groups:, group_number:, **options)
  @exclude_path_prefixes = options[:exclude_path_prefixes]
  @exclude_types = options[:exclude_types]
  @groups = groups
  @group_number = group_number
  @example_data_exists = File.exist?("spec/examples.txt")
  @only_types = options[:only_types]
  @tags = options[:tags]
end

Instance Attribute Details

#exclude_path_prefixesObject (readonly)

Returns the value of attribute exclude_path_prefixes.



2
3
4
# File 'lib/test_suite_splitter/rspec_helper.rb', line 2

def exclude_path_prefixes
  @exclude_path_prefixes
end

#exclude_typesObject (readonly)

Returns the value of attribute exclude_types.



2
3
4
# File 'lib/test_suite_splitter/rspec_helper.rb', line 2

def exclude_types
  @exclude_types
end

#only_typesObject (readonly)

Returns the value of attribute only_types.



2
3
4
# File 'lib/test_suite_splitter/rspec_helper.rb', line 2

def only_types
  @only_types
end

#tagsObject (readonly)

Returns the value of attribute tags.



2
3
4
# File 'lib/test_suite_splitter/rspec_helper.rb', line 2

def tags
  @tags
end

Instance Method Details

#example_dataObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/test_suite_splitter/rspec_helper.rb', line 18

def example_data
  @example_data ||= begin
    raw_data = File.read("spec/examples.txt")

    result = []
    raw_data.scan(/^\.\/(.+)\[(.+?)\]\s+\|\s+(.+?)\s+\|\s+((.+?) seconds|)\s+\|$/) do |match|
      file_path = match[0]
      spec_result = match[1]
      seconds = match[4]&.to_f

      spec_data = {
        file_path: file_path,
        spec_result: spec_result,
        seconds: seconds
      }

      result << spec_data
    end

    result
  end
end

#example_data_exists?Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/test_suite_splitter/rspec_helper.rb', line 14

def example_data_exists?
  @example_data_exists
end

#example_file(path) ⇒ Object



57
58
59
# File 'lib/test_suite_splitter/rspec_helper.rb', line 57

def example_file(path)
  example_files[path]
end

#example_filesObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/test_suite_splitter/rspec_helper.rb', line 41

def example_files
  @example_files ||= begin
    files = {}
    example_data.each do |spec_data|
      file_path = spec_data.fetch(:file_path)
      seconds = spec_data.fetch(:seconds)

      files[file_path] ||= {examples: 0, seconds: 0.0}
      files[file_path][:examples] += 1
      files[file_path][:seconds] += seconds if seconds
    end

    files
  end
end

#group_filesObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/test_suite_splitter/rspec_helper.rb', line 61

def group_files
  return @group_files if @group_files

  sorted_files.each do |file|
    file_path = file.fetch(:path)
    file_data = example_file(file_path) if example_data_exists?

    if file_data
      examples = file_data.fetch(:examples)
      seconds = file_data.fetch(:seconds)
    else
      examples = file.fetch(:examples)
    end

    group = group_with_least
    group[:examples] += examples
    group[:files] << file
    group[:seconds] += seconds if seconds
    group[:weight] += file_weight(file, file_data)
  end

  @group_files = group_orders[@group_number - 1].fetch(:files)
end

#group_ordersObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/test_suite_splitter/rspec_helper.rb', line 85

def group_orders
  @group_orders ||= begin
    group_orders = []
    @groups.times do
      group_orders << {
        examples: 0,
        files: [],
        seconds: 0.0,
        weight: 0.0
      }
    end
    group_orders
  end
end

#group_with_leastObject



100
101
102
# File 'lib/test_suite_splitter/rspec_helper.rb', line 100

def group_with_least
  group_orders.min_by { |group| group.fetch(:weight) }
end

#sorted_filesObject

Sort them so that they are sorted by file path in three groups so each group have an equal amount of controller specs, features specs and so on



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/test_suite_splitter/rspec_helper.rb', line 105

def sorted_files
  files.values.sort do |file1, file2|
    file1_path = file1.fetch(:path)
    file2_path = file2.fetch(:path)

    file1_data = example_file(file1_path) if example_data_exists?
    file2_data = example_file(file2_path) if example_data_exists?

    value1 = file_weight(file1, file1_data)
    value2 = file_weight(file2, file2_data)

    if value1 == value2
      value2 = file1_path
      value1 = file2_path
    end

    value2 <=> value1
  end
end