Class: UnitTestHelper

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

Instance Method Summary collapse

Constructor Details

#initialize(project_dir, component_path_list) ⇒ UnitTestHelper

构造器方法



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/uth/uth.rb', line 6

def initialize(project_dir, component_path_list)
  # 主工程路径
  @project_dir = project_dir

  # 组件路径列表
  @component_path_list = component_path_list

  # 组件的 test target
  @component_test_target_map = {}

  # 组件 test group 路径
  @component_test_group_map = {}

  # 组件对应的 xcodeproj
  @component_project_map = {}


  puts "project: #{project_dir}"
  puts "component: #{component_path_list}"

  open_main_xcodeproj()

  process_all_components()

end

Instance Method Details

#add_file_ref(dir, current_group, target) ⇒ Object

添加组件测试用例文件引用到主工程 test target



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/uth/uth.rb', line 249

def add_file_ref(dir, current_group, target)
  unless  dir and target and current_group
      puts "add_file_ref params error!"
      return
  end

  Dir.glob(dir) do |item|
      next if item == '.' or item == '.DS_Store'

      if File.directory?(item)
          new_folder = File.basename(item)

          # 创建 group
          created_group = current_group.new_group(new_folder)

          # 设置实际路径
          created_group.set_path(item)

          add_file_ref("#{item}/*", created_group, target)
      else 
          # if item.end_with? ".m"
              ref = current_group.new_reference(item)
              target.add_file_references([ref])
          # end
      end
  end
end

#clearObject

清理环境



404
405
406
# File 'lib/uth/uth.rb', line 404

def clear()
   rm_all_test_group_ref()
end

#find_xcodeproj(proDir) ⇒ Object

找到.xcodeproj后缀文件,返回其路径



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/uth/uth.rb', line 33

def find_xcodeproj(proDir)
  if !File.exist?(proDir)
    puts "#{proDir} does not exist"
    return
  end

  path_name = Pathname.new(proDir)
  project_path = '' # xcodeproj文件路径

  path_name.children.collect do |child|
    if File.extname(child).end_with?('.xcodeproj')
      project_path = child.to_s
      break
    end
  end

  return project_path
end

#get_component_name(component_path) ⇒ Object

根据路径获取组件名



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/uth/uth.rb', line 387

def get_component_name(component_path)
  unless component_path
      return nil
  end

   # 获取组件名
  if component_path.end_with?('/')
      component_path = component_path.slice(0, component_path.length - 1)
  end

  list = component_path.split("/")
  component_name = list[list.length - 1]

  return component_name
end

#open_main_xcodeprojObject

打开主工程



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/uth/uth.rb', line 65

def open_main_xcodeproj()

  @main_project = open_xcodeproj(@project_dir)
  if @main_project.nil?
    puts "main_project is nil"
    return
  end

  # 找到 test target
  @main_project.targets.each do |target|
      if target.test_target_type?
          @main_test_target = target
          @main_test_path = @project_dir + "/#{target.name}"
          break
      end
  end
end

#open_xcodeproj(project_path) ⇒ Object

打开工程



53
54
55
56
57
58
59
60
61
62
# File 'lib/uth/uth.rb', line 53

def open_xcodeproj(project_path)

xcodeproj_path = find_xcodeproj(project_path)

if xcodeproj_path != nil and File.exist?(xcodeproj_path)
  project = Xcodeproj::Project.open(xcodeproj_path)
  return project
else
  return nil
end  end

#process_all_componentsObject

处理所有组件



84
85
86
87
88
89
90
91
92
# File 'lib/uth/uth.rb', line 84

def process_all_components()
  unless @component_path_list
      return
  end

  @component_path_list.each do |component_path|
      process_component(component_path)
  end
end

#process_component(component_path) ⇒ Object

处理组件



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
169
170
171
172
173
174
# File 'lib/uth/uth.rb', line 95

def process_component(component_path)
  unless component_path
      return
  end

  if (!File.exist?(component_path))
      puts "#{component_path} does not exits!"
      return
  end

  # 找到 tests target
  component_example_path = component_path + "/Example"
  component_project = open_xcodeproj(component_example_path)

  unless component_project
      return
  end

  # 获取组件名
  component_name = get_component_name(component_path)

  # 保存组件 project
  if !@component_project_map.include?(component_name)
      @component_project_map[component_name] = component_project
  end
 
  component_project.targets.each do |target|
      if target.test_target_type?
          component_test_group = component_example_path + "/#{target.name}"
          
          # 保存组件 test 文件夹路径
          if !@component_test_group_map.include?(component_name)
              @component_test_group_map[component_name] = component_test_group
          end

          # 保存组件 test target
          if !@component_test_target_map.include?(component_name)
              @component_test_target_map[component_name] = target
          end

          # 旧工程的文件夹是 Tests,重命名 test target 的名字,防止同步到主工程冲突
          if !File.exist?(component_test_group)

            old_component_test_group = component_example_path + "/Tests"

            if File.exist?(old_component_test_group)
              
              puts "rename #{old_component_test_group} to #{component_test_group}"

              # 重命名
              File.rename(old_component_test_group, component_test_group)

              old_tests_group = component_project["Tests"]
              rm_group_ref(old_tests_group)
          
              # 文件夹重命名后,修改 test target 中 build setting 的 GCC_PREFIX_HEADER 和 INFOPLIST_FILE 路径
              target.build_configurations.each do |config|
                config.build_settings['GCC_PREFIX_HEADER'] = "#{target.name}/Tests-Prefix.pch"
                config.build_settings['INFOPLIST_FILE'] = "#{target.name}/Tests-Info.plist"
              end
            end

             # 如果有 Tests.m 文件,也重命名
            old_component_test_file = File.join(component_test_group, 'Tests.m')

            component_test_file = File.join(component_test_group, "#{target.name}.m")

            if File.exist?(old_component_test_file) and !File.exist?(component_test_file)
                puts "rename #{old_component_test_file} to #{component_test_file}"
                File.rename(old_component_test_file, component_test_file)
            end

            # 改名后,添加引用
            sync_component_back(component_name)
          end

          break
      end
  end
end

#rm_all_test_group_refObject



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/uth/uth.rb', line 180

def rm_all_test_group_ref()
  unless @main_project
    return
  end

  puts "\n======== begin clear main project env... ========\n"

  groups = @main_project["DYZBTests"].groups
  groups.each do |group|
    if group.name.end_with?("Tests")
      rm_test_group_ref(group.name)
    end
  end

  save_main()

  puts "\n======== clear main project env done... ========\n"
end

#rm_group_ref(group_ref) ⇒ Object

删除 group 引用



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/uth/uth.rb', line 223

def rm_group_ref(group_ref)
  unless group_ref
      return
  end

  group_ref.groups.each do | group|
      # 递归删除
      rm_group_ref(group)

      # 移除引用
      group.remove_from_project
  end
  
  group_ref.files.each do | file|
      # 删除 build phase 中的文件
      @main_test_target.source_build_phase.remove_file_reference(file)

      # 移除引用
      file.remove_from_project
  end
  
  # 移除引用
  group_ref.remove_from_project
end

#rm_test_group_ref(component_target_name) ⇒ Object

移除组件在主工程的 group 引用



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/uth/uth.rb', line 200

def rm_test_group_ref(component_target_name)
  unless component_target_name
      return
  end

  unless @main_project
    return
  end

  # 组件在主工程所在的 group
  component_test_group = @main_project["DYZBTests"][component_target_name]

  unless component_test_group
    return
  end

  puts "rm group ref:#{component_test_group}"

  # 删除 group 引用
  rm_group_ref(component_test_group)
end

#save_mainObject

保存



409
410
411
412
413
414
415
# File 'lib/uth/uth.rb', line 409

def save_main()
  unless @main_project
      return
  end

  @main_project.save()
end

#sync_all_components_backObject

写回所有组件



330
331
332
333
334
335
336
337
338
339
# File 'lib/uth/uth.rb', line 330

def sync_all_components_back()
  unless @component_path_list
      return
  end

  @component_path_list.each do |component_path|
      component_name = get_component_name(component_path)
      sync_component_back(component_name)
  end
end

#sync_all_components_to_mainObject

同步所有组件 test 文件到主工程



278
279
280
281
282
283
284
285
286
287
# File 'lib/uth/uth.rb', line 278

def sync_all_components_to_main()
  unless @component_path_list and @component_path_list.length > 0
      return
  end

  @component_path_list.each do |component_path|
      component_name = get_component_name(component_path)
      sync_component_to_main(component_name)
  end
end

#sync_component_back(component_name) ⇒ Object

在组件中,同步组件用例文件引用



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/uth/uth.rb', line 342

def sync_component_back(component_name)
  unless component_name
      return
  end

  puts "\n========  sync #{component_name} unit tests  back... ========\n"

  # 将组件 xxTests 文件下的文件添加引用
  component_test_target = @component_test_target_map[component_name]
  unless component_test_target
      puts "#{component_name} target is nil"
      return
  end

  component_test_group_path = @component_test_group_map[component_name]
  unless component_test_group_path
      puts "#{component_name} test group path is nil"
      return
  end
  
  component_project = @component_project_map[component_name]
  unless component_project
      puts "#{component_name} project is nil"
      return
  end

  # 移除组件的 test group
  orig_component_test_group = component_project[component_test_target.name]
  if (!orig_component_test_group.nil?) 
      puts "remove orig_component_test_group #{orig_component_test_group}"
      orig_component_test_group.remove_from_project
  end

  # 组件的 test group
  component_test_group = component_project.main_group

  # 重新添加组件单测文件引用
  add_file_ref(component_test_group_path, component_test_group, component_test_target)

  component_project.save()

  puts "\n======== sync #{component_name} unit tests back done... ========\n"
end

#sync_component_to_main(component_name) ⇒ Object

同步组件用例文件到主工程



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/uth/uth.rb', line 290

def sync_component_to_main(component_name)
  unless component_name
    return
  end

  unless @main_project
    puts "main_project is nil"
    return
  end

  component_test_target = @component_test_target_map[component_name]
  unless component_test_target
      puts "#{component_name} target is nil"
      return
  end

  component_test_group_path = @component_test_group_map[component_name]
  unless component_test_group_path
      puts "#{component_name} test group path is nil"
      return
  end

  puts "\n======== begin sync #{component_name} unit tests to main... ========\n"

  main_test_group = @main_project.main_group.find_subpath("DYZBTests", true)  

  # 将组件的 Tests 文件下的用例文件,添加引用到主工程 test_group
  # 先移除存在的 group ref
  rm_test_group_ref(component_test_target.name)

  # tests 文件下的文件,添加引用到主工程
  add_file_ref(component_test_group_path, main_test_group, @main_test_target)

  # 保存工程文件
  save_main()

  puts "\n======== sync #{component_name} unit tests to main done... ========\n"
end

#update_component(component_name) ⇒ Object

改名后,更新引用



177
178
# File 'lib/uth/uth.rb', line 177

def update_component(component_name)
end