Class: TestBuildPlanner

Inherits:
Object show all
Includes:
TestInvokerTypes
Defined in:
lib/ceedling/test_invoker/test_build_planner.rb

Instance Method Summary collapse

Instance Method Details

#assemble_partials_config(filepath:) ⇒ Object


Helper methods



185
186
187
188
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 185

def assemble_partials_config(filepath:)
  configs = @test_context_extractor.lookup_partials_config( filepath )
  return @partializer.populate_filepaths( configs )
end

#collect_test_framework_sources(mocks) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 190

def collect_test_framework_sources(mocks)
  sources = []
  sources << File.join( PROJECT_BUILD_VENDOR_UNITY_PATH, UNITY_C_FILE )
  sources << File.join( PROJECT_BUILD_VENDOR_CMOCK_PATH, CMOCK_C_FILE )       if @configurator.project_use_mocks and mocks
  sources << File.join( PROJECT_BUILD_VENDOR_CEXCEPTION_PATH, CEXCEPTION_C_FILE ) if @configurator.project_use_exceptions

  if @configurator.project_use_mocks
    @configurator.cmock_unity_helper_path.each do |helper|
      if @file_wrapper.exist?( helper.ext( EXTENSION_SOURCE ) )
        sources << helper
      end
    end
  end

  return sources
end

#extract_sources(context, test_filepath, partials) ⇒ Object



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 207

def extract_sources(context, test_filepath, partials)
  sources = []

  _sources = @test_context_extractor.lookup_build_directive_sources_list( test_filepath )
  _sources.each do |source|
    sources << @file_finder.find_build_input_file( filepath: source, complain: :ignore, context: context )
  end

  _support_headers = COLLECTION_ALL_SUPPORT.map { |filepath| File.basename( filepath ).ext( EXTENSION_HEADER ) }

  includes = @test_context_extractor.lookup_all_header_includes_list( test_filepath )
  includes.each do |include|
    _basename = include.filename
    next if _basename == UNITY_H_FILE
    next if _basename.start_with?( CMOCK_MOCK_PREFIX )
    next if _support_headers.include?( _basename )

    sources << @file_finder.find_build_input_file( filepath: include.filename, complain: :ignore, context: context )
  end

  # Add to the source list any testable Partials (no mock Partials)
  partials.tests.each do |_module|
    sources << @file_finder.find_build_input_file( filepath: _module, complain: :ignore, context: context )
  end

  return sources.compact.uniq
end

#fetch_include_search_paths_for_test_file(test_filepath) ⇒ Object



239
240
241
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 239

def fetch_include_search_paths_for_test_file(test_filepath)
  return @test_context_extractor.lookup_include_paths_list( test_filepath )
end

#fetch_shallow_source_includes(test_filepath) ⇒ Object



235
236
237
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 235

def fetch_shallow_source_includes(test_filepath)
  return @test_context_extractor.lookup_source_includes_list( test_filepath )
end

#find_header_input_for_mock(mock) ⇒ Object



243
244
245
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 243

def find_header_input_for_mock(mock)
  return @file_finder.find_header_input_for_mock( mock.filename )
end

#form_partials_filenames(partials) ⇒ Object



258
259
260
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 258

def form_partials_filenames(partials)
  return partials.map { |partial| @file_path_utils.form_partial_implementation_source_filename( partial ) }
end

#gnerate_header_input_for_mock_partial(mock, test) ⇒ Object



251
252
253
254
255
256
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 251

def gnerate_header_input_for_mock_partial(mock, test)
  return @file_path_utils.form_partial_header_filepath(
    test,
    mock.filename.delete_prefix( @configurator.cmock_mock_prefix )
  )
end

#is_mock_partial?(mock) ⇒ Boolean

Returns:

  • (Boolean)


247
248
249
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 247

def is_mock_partial?(mock)
  return mock.filename.start_with?( @configurator.cmock_mock_prefix + PARTIAL_FILENAME_PREFIX )
end

#remove_mock_original_headers(filelist, mocklist) ⇒ Object



262
263
264
265
266
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 262

def remove_mock_original_headers(filelist, mocklist)
  filelist.delete_if do |filepath|
    mocklist.include?( @configurator.cmock_mock_prefix + File.basename( filepath ).ext( EXTENSION_CORE_HEADER ) )
  end
end

#remove_partials_source_objects(objects, configs) ⇒ Object



268
269
270
271
272
273
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 268

def remove_partials_source_objects(objects, configs)
  modules = configs.keys
  objects.delete_if do |filepath|
    modules.include?( File.basename( filepath ).ext() )
  end
end

#setupObject



28
29
30
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 28

def setup()
  @context_extractor = @test_context_extractor
end

#stage_determine_artifacts(state) ⇒ Object

Stage 14: Determine the full set of objects to compile and link for each test.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 118

def stage_determine_artifacts(state)
  @batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
    filepath  = testable.filepath
    mock_list = @context_extractor.lookup_mock_header_includes_list( filepath )

    test_sources = extract_sources( state.context, filepath, testable.partials )
    test_core    = test_sources +
                   mock_list.map { |mock| mock.filename.ext( EXTENSION_CORE_SOURCE ) }

    remove_mock_original_headers(
      test_core,
      mock_list.map { |mock| mock.filename }
    )

    test_frameworks   = collect_test_framework_sources( !testable.mocks.empty? )
    test_support      = @configurator.collection_all_support

    compilations  = []
    compilations << filepath
    compilations += test_core
    compilations << testable.runner[:output_filepath]
    compilations += test_frameworks
    compilations += test_support
    compilations.uniq!

    test_objects     = @file_path_utils.form_test_build_objects_filelist( testable.paths[:build], compilations )
    test_executable  = @file_path_utils.form_test_executable_filepath( testable.paths[:build], filepath )
    test_pass        = @file_path_utils.form_pass_results_filepath( testable.paths[:results], filepath )
    test_fail        = @file_path_utils.form_fail_results_filepath( testable.paths[:results], filepath )

    test_no_link_objects =
      @file_path_utils.form_test_build_objects_filelist(
        testable.paths[:build],
        fetch_shallow_source_includes( filepath )
      )

    test_objects = (test_objects.uniq - test_no_link_objects)

    state.lock.synchronize do
      testable.sources         = test_sources
      testable.frameworks      = test_frameworks
      testable.core            = test_core
      testable.objects         = test_objects
      testable.executable      = test_executable
      testable.no_link_objects = test_no_link_objects
      testable.results_pass    = test_pass
      testable.results_fail    = test_fail
    end
  end
end

#stage_determine_files(state) ⇒ Object

Stage 5: Determine runners, mocks, and partials for all tests.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 33

def stage_determine_files(state)
  @batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
    test     = testable.name
    filepath = testable.filepath

    runner_filepath = @file_path_utils.form_runner_filepath_from_test( filepath )

    mocks   = {}
    _mocks  = @context_extractor.lookup_mock_header_includes_list( filepath )

    _mocks.each do |include|
      name   = File.basename( include.filename ).ext()
      source = nil
      input  = nil

      if is_mock_partial?( include )
        source = gnerate_header_input_for_mock_partial( include, test )
        input  = source
      else
        source            = find_header_input_for_mock( include )
        preprocessed_input = @file_path_utils.form_preprocessed_file_filepath( source, test )
        input             = (@configurator.project_use_test_preprocessor_mocks ? preprocessed_input : source)
      end

      mocks[name.to_sym] = {
        name:     name,
        filepath: include.filepath,
        path:     include.path,
        source:   source,
        input:    input
      }
    end

    partials_configs = {}
    if @configurator.project_use_partials
      partials_configs = assemble_partials_config( filepath: filepath )
    end

    state.lock.synchronize do
      testable.runner = {
        output_filepath: runner_filepath,
        input_filepath:  filepath
      }
      testable.mocks    = mocks
      testable.partials.configs = partials_configs

      @plugin_manager.pre_test( filepath )
    end
  end
end

#stage_flatten_mocks_list(state) ⇒ Object

Transform T2: Flatten mocks into a parallel-processing-friendly list.



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 104

def stage_flatten_mocks_list(state)
  state.testables.each do |_, testable|
    testable.mocks.each do |name, elems|
      state.mocks_list << {
        name:                     name,
        details:                  elems,
        testable:                 testable,
        directives_only_filepath: nil
      }
    end
  end
end

#stage_flatten_objects_list(state) ⇒ Object

Transform T3: Flatten testable objects into a parallel-processing-friendly list.



170
171
172
173
174
175
176
177
178
179
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 170

def stage_flatten_objects_list(state)
  state.objects_list = state.testables.map do |_, testable|
    testable.objects.map do |obj|
      {
        test: testable.name,
        obj:  obj
      }
    end
  end.flatten
end

#stage_flatten_partials_lists(state) ⇒ Object

Transform T1: Flatten partials into parallel-processing-friendly lists.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 85

def stage_flatten_partials_lists(state)
  state.testables.each do |_, testable|
    testable.partials.configs.each do |_, config|
      state.partials_headers << {
        config:                   config.header,
        testable:                 testable,
        directives_only_filepath: nil
      } if config.header.filepath

      state.partials_sources << {
        config:                   config.source,
        testable:                 testable,
        directives_only_filepath: nil
      } if config.source.filepath
    end
  end
end