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



187
188
189
190
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 187

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



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

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



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
234
235
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 209

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



241
242
243
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 241

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



237
238
239
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 237

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



245
246
247
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 245

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

#form_partials_filenames(partials) ⇒ Object



260
261
262
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 260

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



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

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)


249
250
251
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 249

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



264
265
266
267
268
# File 'lib/ceedling/test_invoker/test_build_planner.rb', line 264

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



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

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
168
# 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
      testable.tool            = TOOLS_TEST_COMPILER
    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.



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

def stage_flatten_objects_list(state)
  state.objects_list = state.testables.map do |_, testable|
    testable.objects.map do |obj|
      {
        tool: testable.tool,
        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