kintsugi 0.5.4 → 0.6.2

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.
@@ -27,6 +27,13 @@ describe Kintsugi, :apply_change_to_project do
27
27
  end
28
28
  end
29
29
 
30
+ it "not raises when change is nil or doesn't have root object" do
31
+ expect {
32
+ described_class.apply_change_to_project(base_project, nil)
33
+ described_class.apply_change_to_project(base_project, {})
34
+ }.not_to raise_error
35
+ end
36
+
30
37
  it "adds new target" do
31
38
  theirs_project = create_copy_of_project(base_project.path, "theirs")
32
39
  theirs_project.new_target("com.apple.product-type.library.static", "foo", :ios)
@@ -34,7 +41,6 @@ describe Kintsugi, :apply_change_to_project do
34
41
  changes_to_apply = get_diff(theirs_project, base_project)
35
42
 
36
43
  described_class.apply_change_to_project(base_project, changes_to_apply)
37
- base_project.save
38
44
 
39
45
  expect(base_project).to be_equivalent_to_project(theirs_project)
40
46
  end
@@ -46,7 +52,6 @@ describe Kintsugi, :apply_change_to_project do
46
52
  changes_to_apply = get_diff(theirs_project, base_project)
47
53
 
48
54
  described_class.apply_change_to_project(base_project, changes_to_apply)
49
- base_project.save
50
55
 
51
56
  expect(base_project).to be_equivalent_to_project(theirs_project)
52
57
  end
@@ -60,7 +65,6 @@ describe Kintsugi, :apply_change_to_project do
60
65
  changes_to_apply = get_diff(theirs_project, base_project)
61
66
 
62
67
  described_class.apply_change_to_project(base_project, changes_to_apply)
63
- base_project.save
64
68
 
65
69
  expect(base_project).to be_equivalent_to_project(theirs_project)
66
70
  end
@@ -72,29 +76,29 @@ describe Kintsugi, :apply_change_to_project do
72
76
  changes_to_apply = get_diff(theirs_project, base_project)
73
77
 
74
78
  described_class.apply_change_to_project(base_project, changes_to_apply)
75
- base_project.save
76
79
 
77
80
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
78
81
  end
79
82
 
80
- it "adds subproject that already exists" do
81
- theirs_project = create_copy_of_project(base_project.path, "theirs")
83
+ it "removes reference proxy from subproject with the same display name as another reference proxy" do
84
+ framework_filename = "baz"
85
+ subproject = add_new_subproject_to_project(base_project, "subproj", framework_filename)
82
86
 
83
- subproject = add_new_subproject_to_project(theirs_project, "foo", "foo")
84
- theirs_project.save
87
+ subproject.new_target("com.apple.product-type.library.static", framework_filename, :ios)
88
+ base_project.root_object.project_references[0][:product_group] <<
89
+ create_reference_proxy_from_product_reference(base_project,
90
+ base_project.root_object.project_references[0][:project_ref],
91
+ subproject.products_group.files[-1])
92
+ base_project.save
85
93
 
86
- ours_project = create_copy_of_project(base_project.path, "ours")
87
- add_existing_subproject_to_project(ours_project, subproject, "foo")
94
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
95
+ theirs_project.root_object.project_references[0][:product_group].children[-1].remove_from_project
88
96
 
89
97
  changes_to_apply = get_diff(theirs_project, base_project)
90
98
 
91
- described_class.apply_change_to_project(ours_project, changes_to_apply)
92
- ours_project.save
99
+ described_class.apply_change_to_project(base_project, changes_to_apply)
93
100
 
94
- expect(ours_project.root_object.project_references[0][:project_ref].uuid)
95
- .not_to equal(ours_project.root_object.project_references[1][:project_ref].uuid)
96
- expect(ours_project.root_object.project_references[0][:project_ref].proxy_containers).not_to be_empty
97
- expect(ours_project.root_object.project_references[1][:project_ref].proxy_containers).not_to be_empty
101
+ expect(base_project).to be_equivalent_to_project(theirs_project)
98
102
  end
99
103
 
100
104
  # Checks that the order the changes are applied in is correct.
@@ -110,7 +114,6 @@ describe Kintsugi, :apply_change_to_project do
110
114
  changes_to_apply = get_diff(theirs_project, base_project)
111
115
 
112
116
  described_class.apply_change_to_project(base_project, changes_to_apply)
113
- base_project.save
114
117
 
115
118
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
116
119
  end
@@ -152,11 +155,28 @@ describe Kintsugi, :apply_change_to_project do
152
155
  changes_to_apply = get_diff(theirs_project, base_project)
153
156
 
154
157
  described_class.apply_change_to_project(base_project, changes_to_apply)
155
- base_project.save
156
158
 
157
159
  expect(base_project).to be_equivalent_to_project(theirs_project)
158
160
  end
159
161
 
162
+ it "raises when a file is split into two" do
163
+ base_project.main_group.find_subpath("new_group", true)
164
+ base_project.main_group.find_subpath("new_group2", true)
165
+ base_project.save
166
+
167
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
168
+ new_group = theirs_project.main_group.find_subpath("new_group")
169
+ file_reference = theirs_project.main_group.find_file_by_path(filepath)
170
+ file_reference.move(new_group)
171
+ theirs_project.main_group.find_subpath("new_group2").new_reference(filepath)
172
+
173
+ changes_to_apply = get_diff(theirs_project, base_project)
174
+
175
+ expect {
176
+ described_class.apply_change_to_project(base_project, changes_to_apply)
177
+ }.to raise_error(Kintsugi::MergeError)
178
+ end
179
+
160
180
  it "adds file to new group" do
161
181
  theirs_project = create_copy_of_project(base_project.path, "theirs")
162
182
 
@@ -165,8 +185,70 @@ describe Kintsugi, :apply_change_to_project do
165
185
  changes_to_apply = get_diff(theirs_project, base_project)
166
186
 
167
187
  described_class.apply_change_to_project(base_project, changes_to_apply)
188
+
189
+ expect(base_project).to be_equivalent_to_project(theirs_project)
190
+ end
191
+
192
+ it "removes group" do
193
+ base_project.main_group.find_subpath("new_group", true)
168
194
  base_project.save
169
195
 
196
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
197
+ theirs_project["new_group"].remove_from_project
198
+
199
+ changes_to_apply = get_diff(theirs_project, base_project)
200
+
201
+ described_class.apply_change_to_project(base_project, changes_to_apply)
202
+
203
+ expect(base_project).to be_equivalent_to_project(theirs_project)
204
+ end
205
+
206
+ it "moves a group with files in it" do
207
+ new_group = base_project.main_group.find_subpath("new_group", true)
208
+ new_group.new_reference("new_file")
209
+ base_project.save
210
+
211
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
212
+ new_group2 = theirs_project.main_group.find_subpath("new_group2", true)
213
+ theirs_project["new_group"].move(new_group2)
214
+
215
+ changes_to_apply = get_diff(theirs_project, base_project)
216
+
217
+ described_class.apply_change_to_project(base_project, changes_to_apply)
218
+
219
+ expect(base_project).to be_equivalent_to_project(theirs_project)
220
+ end
221
+
222
+ it "moves a group with a group in it" do
223
+ new_group = base_project.main_group.find_subpath("new_group", true)
224
+ new_group.find_subpath("sub_group", true)
225
+ base_project.save
226
+
227
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
228
+ new_group2 = theirs_project.main_group.find_subpath("new_group2", true)
229
+ theirs_project["new_group"].move(new_group2)
230
+
231
+ changes_to_apply = get_diff(theirs_project, base_project)
232
+
233
+ described_class.apply_change_to_project(base_project, changes_to_apply)
234
+
235
+ expect(base_project).to be_equivalent_to_project(theirs_project)
236
+ end
237
+
238
+ it "moves a group with a group with a file in it" do
239
+ new_group = base_project.main_group.find_subpath("new_group", true)
240
+ sub_group = new_group.find_subpath("sub_group", true)
241
+ sub_group.new_reference("new_file")
242
+ base_project.save
243
+
244
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
245
+ new_group2 = theirs_project.main_group.find_subpath("new_group2", true)
246
+ theirs_project["new_group"].move(new_group2)
247
+
248
+ changes_to_apply = get_diff(theirs_project, base_project)
249
+
250
+ described_class.apply_change_to_project(base_project, changes_to_apply)
251
+
170
252
  expect(base_project).to be_equivalent_to_project(theirs_project)
171
253
  end
172
254
 
@@ -179,7 +261,6 @@ describe Kintsugi, :apply_change_to_project do
179
261
  changes_to_apply = get_diff(theirs_project, base_project)
180
262
 
181
263
  described_class.apply_change_to_project(base_project, changes_to_apply)
182
- base_project.save
183
264
 
184
265
  expect(base_project).to be_equivalent_to_project(theirs_project)
185
266
  end
@@ -203,7 +284,6 @@ describe Kintsugi, :apply_change_to_project do
203
284
  changes_to_apply = get_diff(theirs_project, base_project)
204
285
 
205
286
  described_class.apply_change_to_project(base_project, changes_to_apply)
206
- base_project.save
207
287
 
208
288
  expect(base_project).to be_equivalent_to_project(theirs_project)
209
289
  end
@@ -225,6 +305,22 @@ describe Kintsugi, :apply_change_to_project do
225
305
  expect(base_project).to be_equivalent_to_project(theirs_project)
226
306
  end
227
307
 
308
+ it "ignores removal of a non-existent group" do
309
+ base_project.main_group.find_subpath("new_group", true)
310
+ base_project.save
311
+
312
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
313
+ theirs_project.main_group.children.delete_at(-1)
314
+
315
+ changes_to_apply = get_diff(theirs_project, base_project)
316
+
317
+ base_project.main_group.children.delete_at(-1)
318
+
319
+ described_class.apply_change_to_project(base_project, changes_to_apply)
320
+
321
+ expect(base_project).to be_equivalent_to_project(theirs_project)
322
+ end
323
+
228
324
  it "removes build files of a removed file" do
229
325
  target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
230
326
  target.source_build_phase.add_file_reference(
@@ -244,7 +340,6 @@ describe Kintsugi, :apply_change_to_project do
244
340
  changes_to_apply = get_diff(theirs_project, base_project)
245
341
 
246
342
  described_class.apply_change_to_project(base_project, changes_to_apply)
247
- base_project.save
248
343
 
249
344
  expect(base_project).to be_equivalent_to_project(theirs_project)
250
345
  end
@@ -260,7 +355,6 @@ describe Kintsugi, :apply_change_to_project do
260
355
  changes_to_apply = get_diff(theirs_project, base_project)
261
356
 
262
357
  described_class.apply_change_to_project(base_project, changes_to_apply)
263
- base_project.save
264
358
 
265
359
  expect(base_project).to be_equivalent_to_project(theirs_project)
266
360
  end
@@ -275,25 +369,21 @@ describe Kintsugi, :apply_change_to_project do
275
369
  changes_to_apply = get_diff(theirs_project, base_project)
276
370
 
277
371
  described_class.apply_change_to_project(base_project, changes_to_apply)
278
- base_project.save
279
372
 
280
373
  expect(base_project).to be_equivalent_to_project(theirs_project)
281
374
  end
282
375
 
283
376
  it "handles moved file to an existing group with a different path on filesystem" do
284
377
  base_project.main_group.find_subpath("new_group", true).path = "some_path"
285
-
286
378
  base_project.save
287
- theirs_project = create_copy_of_project(base_project.path, "theirs")
288
379
 
380
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
289
381
  new_group = theirs_project.main_group.find_subpath("new_group")
290
-
291
382
  theirs_project.main_group.find_file_by_path(filepath).move(new_group)
292
383
 
293
384
  changes_to_apply = get_diff(theirs_project, base_project)
294
385
 
295
386
  described_class.apply_change_to_project(base_project, changes_to_apply)
296
- base_project.save
297
387
 
298
388
  expect(base_project).to be_equivalent_to_project(theirs_project)
299
389
  end
@@ -312,7 +402,6 @@ describe Kintsugi, :apply_change_to_project do
312
402
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
313
403
 
314
404
  described_class.apply_change_to_project(ours_project, changes_to_apply)
315
- ours_project.save
316
405
 
317
406
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
318
407
  end
@@ -330,7 +419,6 @@ describe Kintsugi, :apply_change_to_project do
330
419
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
331
420
 
332
421
  described_class.apply_change_to_project(ours_project, changes_to_apply)
333
- ours_project.save
334
422
 
335
423
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
336
424
  end
@@ -348,7 +436,6 @@ describe Kintsugi, :apply_change_to_project do
348
436
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
349
437
 
350
438
  described_class.apply_change_to_project(ours_project, changes_to_apply)
351
- ours_project.save
352
439
 
353
440
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
354
441
  end
@@ -363,7 +450,6 @@ describe Kintsugi, :apply_change_to_project do
363
450
  changes_to_apply = get_diff(theirs_project, base_project)
364
451
 
365
452
  described_class.apply_change_to_project(ours_project, changes_to_apply)
366
- ours_project.save
367
453
 
368
454
  expect(ours_project).to be_equivalent_to_project(theirs_project)
369
455
  end
@@ -377,6 +463,54 @@ describe Kintsugi, :apply_change_to_project do
377
463
  base_project.save
378
464
  end
379
465
 
466
+ it "moves file that is referenced by a target from main group to a new group" do
467
+ file_reference = base_project.main_group.new_reference("bar")
468
+ base_project.targets[0].source_build_phase.add_file_reference(file_reference)
469
+ base_project.save
470
+
471
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
472
+ new_group = theirs_project.main_group.find_subpath("new_group", true)
473
+ file_reference = theirs_project.main_group.find_file_by_path("bar")
474
+ file_reference.move(new_group)
475
+ changes_to_apply = get_diff(theirs_project, base_project)
476
+
477
+ described_class.apply_change_to_project(base_project, changes_to_apply)
478
+
479
+ expect(base_project).to be_equivalent_to_project(theirs_project)
480
+ end
481
+
482
+ it "moves file that is referenced by a target from a group to the main group" do
483
+ file_reference = base_project.main_group.find_subpath("new_group", true).new_reference("bar")
484
+ base_project.targets[0].source_build_phase.add_file_reference(file_reference)
485
+ base_project.save
486
+
487
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
488
+ file_reference = theirs_project["new_group/bar"]
489
+ file_reference.move(theirs_project.main_group)
490
+ changes_to_apply = get_diff(theirs_project, base_project)
491
+
492
+ described_class.apply_change_to_project(base_project, changes_to_apply)
493
+
494
+ expect(base_project).to be_equivalent_to_project(theirs_project)
495
+ end
496
+
497
+ it "moves file that is referenced by a target and has a different file encoding" do
498
+ file_reference = base_project.main_group.find_subpath("new_group", true).new_reference("bar")
499
+ target.frameworks_build_phase.add_file_reference(file_reference)
500
+ base_project.save
501
+
502
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
503
+ file_reference = theirs_project["new_group/bar"]
504
+ file_reference.move(theirs_project.main_group)
505
+ file_reference.fileEncoding = "4"
506
+
507
+ changes_to_apply = get_diff(theirs_project, base_project)
508
+
509
+ described_class.apply_change_to_project(base_project, changes_to_apply)
510
+
511
+ expect(base_project).to be_equivalent_to_project(theirs_project)
512
+ end
513
+
380
514
  it "changes framework from file reference to reference proxy" do
381
515
  framework_filename = "baz"
382
516
 
@@ -389,7 +523,7 @@ describe Kintsugi, :apply_change_to_project do
389
523
  theirs_project = create_copy_of_project(base_project.path, "theirs")
390
524
 
391
525
  build_phase = theirs_project.targets[0].frameworks_build_phase
392
- build_phase.files[0].remove_from_project
526
+ build_phase.files.find { |build_file| build_file.display_name == "baz" }.remove_from_project
393
527
  build_phase.add_file_reference(
394
528
  theirs_project.root_object.project_references[0][:product_group].children[0]
395
529
  )
@@ -397,7 +531,6 @@ describe Kintsugi, :apply_change_to_project do
397
531
  changes_to_apply = get_diff(theirs_project, base_project)
398
532
 
399
533
  described_class.apply_change_to_project(base_project, changes_to_apply)
400
- base_project.save
401
534
 
402
535
  expect(base_project).to be_equivalent_to_project(theirs_project)
403
536
  end
@@ -410,7 +543,6 @@ describe Kintsugi, :apply_change_to_project do
410
543
  changes_to_apply = get_diff(theirs_project, base_project)
411
544
 
412
545
  described_class.apply_change_to_project(base_project, changes_to_apply)
413
- base_project.save
414
546
 
415
547
  expect(base_project).to be_equivalent_to_project(theirs_project)
416
548
  end
@@ -440,7 +572,6 @@ describe Kintsugi, :apply_change_to_project do
440
572
  # hierarchy.
441
573
  base_project.files[-1].name = "foo"
442
574
  theirs_project.files[-1].name = "foo"
443
- base_project.save
444
575
 
445
576
  expect(base_project).to be_equivalent_to_project(theirs_project)
446
577
  end
@@ -467,7 +598,6 @@ describe Kintsugi, :apply_change_to_project do
467
598
  changes_to_apply["rootObject"].delete("projectReferences")
468
599
 
469
600
  described_class.apply_change_to_project(base_project, changes_to_apply)
470
- base_project.save
471
601
 
472
602
  expect(base_project).to be_equivalent_to_project(theirs_project)
473
603
  end
@@ -494,7 +624,6 @@ describe Kintsugi, :apply_change_to_project do
494
624
  changes_to_apply = get_diff(theirs_project, base_project)
495
625
 
496
626
  described_class.apply_change_to_project(base_project, changes_to_apply)
497
- base_project.save
498
627
 
499
628
  expect(base_project).to be_equivalent_to_project(theirs_project)
500
629
  end
@@ -511,11 +640,26 @@ describe Kintsugi, :apply_change_to_project do
511
640
  changes_to_apply = get_diff(theirs_project, base_project)
512
641
 
513
642
  described_class.apply_change_to_project(base_project, changes_to_apply)
514
- base_project.save
515
643
 
516
644
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
517
645
  end
518
646
 
647
+ it "adds build when there is a build file without file ref" do
648
+ target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
649
+ target.frameworks_build_phase.add_file_reference(nil)
650
+ base_project.save
651
+
652
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
653
+ file_reference = theirs_project.main_group.new_reference("bar")
654
+ theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
655
+
656
+ changes_to_apply = get_diff(theirs_project, base_project)
657
+ other_project = create_copy_of_project(base_project.path, "theirs")
658
+ described_class.apply_change_to_project(other_project, changes_to_apply)
659
+
660
+ expect(other_project).to be_equivalent_to_project(theirs_project)
661
+ end
662
+
519
663
  it "adds product ref to build file" do
520
664
  base_project.main_group.new_reference("bar")
521
665
  base_project.save
@@ -531,16 +675,13 @@ describe Kintsugi, :apply_change_to_project do
531
675
  changes_to_apply = get_diff(theirs_project, base_project)
532
676
 
533
677
  described_class.apply_change_to_project(base_project, changes_to_apply)
534
- base_project.save
535
678
 
536
679
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
537
680
  end
538
681
 
539
682
  it "adds build file to a file reference that already exists" do
540
683
  base_project.main_group.new_reference("bar")
541
-
542
684
  base_project.main_group.new_reference("bar")
543
-
544
685
  base_project.save
545
686
 
546
687
  theirs_project = create_copy_of_project(base_project.path, "theirs")
@@ -554,17 +695,14 @@ describe Kintsugi, :apply_change_to_project do
554
695
  changes_to_apply = get_diff(theirs_project, base_project)
555
696
 
556
697
  described_class.apply_change_to_project(base_project, changes_to_apply)
557
- base_project.save
558
698
 
559
699
  expect(base_project).to be_equivalent_to_project(theirs_project)
560
700
  end
561
701
 
562
702
  it "adds file reference to build file" do
563
703
  file_reference = base_project.main_group.new_reference("bar")
564
-
565
704
  build_file = base_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
566
705
  build_file.file_ref = nil
567
-
568
706
  base_project.save
569
707
 
570
708
  theirs_project = create_copy_of_project(base_project.path, "theirs")
@@ -575,7 +713,6 @@ describe Kintsugi, :apply_change_to_project do
575
713
  changes_to_apply = get_diff(theirs_project, base_project)
576
714
 
577
715
  described_class.apply_change_to_project(base_project, changes_to_apply)
578
- base_project.save
579
716
 
580
717
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
581
718
  end
@@ -585,7 +722,6 @@ describe Kintsugi, :apply_change_to_project do
585
722
  base_project.save
586
723
 
587
724
  theirs_project = create_copy_of_project(base_project.path, "theirs")
588
-
589
725
  file_reference = theirs_project.main_group.files.find { |file| file.display_name == "bar" }
590
726
  build_file =
591
727
  theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
@@ -595,7 +731,6 @@ describe Kintsugi, :apply_change_to_project do
595
731
 
596
732
  other_project = create_copy_of_project(base_project.path, "other")
597
733
  described_class.apply_change_to_project(other_project, changes_to_apply)
598
- other_project.save
599
734
 
600
735
  expect(other_project).to be_equivalent_to_project(base_project)
601
736
  end
@@ -621,7 +756,6 @@ describe Kintsugi, :apply_change_to_project do
621
756
  changes_to_apply = get_diff(theirs_project, base_project)
622
757
 
623
758
  described_class.apply_change_to_project(base_project, changes_to_apply)
624
- base_project.save
625
759
 
626
760
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
627
761
  end
@@ -637,7 +771,6 @@ describe Kintsugi, :apply_change_to_project do
637
771
  changes_to_apply = get_diff(theirs_project, base_project)
638
772
 
639
773
  described_class.apply_change_to_project(base_project, changes_to_apply)
640
- base_project.save
641
774
 
642
775
  expect(base_project).to be_equivalent_to_project(theirs_project)
643
776
  end
@@ -646,7 +779,6 @@ describe Kintsugi, :apply_change_to_project do
646
779
  base_project.targets[0].build_configurations.each do |configuration|
647
780
  configuration.build_settings = {}
648
781
  end
649
-
650
782
  theirs_project = create_copy_of_project(base_project.path, "theirs")
651
783
 
652
784
  theirs_project.targets[0].build_configurations.each do |configuration|
@@ -659,7 +791,6 @@ describe Kintsugi, :apply_change_to_project do
659
791
  changes_to_apply = get_diff(theirs_project, base_project)
660
792
 
661
793
  described_class.apply_change_to_project(base_project, changes_to_apply)
662
- base_project.save
663
794
 
664
795
  expect(base_project).to be_equivalent_to_project(theirs_project)
665
796
  end
@@ -677,7 +808,6 @@ describe Kintsugi, :apply_change_to_project do
677
808
  changes_to_apply = get_diff(theirs_project, base_project)
678
809
 
679
810
  described_class.apply_change_to_project(base_project, changes_to_apply)
680
- base_project.save
681
811
 
682
812
  expect(base_project).to be_equivalent_to_project(theirs_project)
683
813
  end
@@ -701,7 +831,6 @@ describe Kintsugi, :apply_change_to_project do
701
831
  changes_to_apply = get_diff(theirs_project, base_project)
702
832
 
703
833
  described_class.apply_change_to_project(base_project, changes_to_apply)
704
- base_project.save
705
834
 
706
835
  expect(base_project).to be_equivalent_to_project(theirs_project)
707
836
  end
@@ -718,10 +847,8 @@ describe Kintsugi, :apply_change_to_project do
718
847
  ours_project.targets[0].build_configurations.each do |configuration|
719
848
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
720
849
  end
721
- ours_project.save
722
850
 
723
851
  described_class.apply_change_to_project(ours_project, changes_to_apply)
724
- ours_project.save
725
852
 
726
853
  expected_project = create_copy_of_project(base_project.path, "expected")
727
854
  expected_project.targets[0].build_configurations.each do |configuration|
@@ -742,10 +869,8 @@ describe Kintsugi, :apply_change_to_project do
742
869
  ours_project.targets[0].build_configurations.each do |configuration|
743
870
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
744
871
  end
745
- ours_project.save
746
872
 
747
873
  described_class.apply_change_to_project(ours_project, changes_to_apply)
748
- ours_project.save
749
874
 
750
875
  expected_project = create_copy_of_project(base_project.path, "expected")
751
876
  expected_project.targets[0].build_configurations.each do |configuration|
@@ -761,10 +886,9 @@ describe Kintsugi, :apply_change_to_project do
761
886
  "$(SRCROOT)/../Bar"
762
887
  ]
763
888
  end
764
-
765
889
  base_project.save
766
- theirs_project = create_copy_of_project(base_project.path, "theirs")
767
890
 
891
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
768
892
  theirs_project.targets[0].build_configurations.each do |configuration|
769
893
  configuration.build_settings["HEADER_SEARCH_PATHS"] = nil
770
894
  end
@@ -772,7 +896,6 @@ describe Kintsugi, :apply_change_to_project do
772
896
  changes_to_apply = get_diff(theirs_project, base_project)
773
897
 
774
898
  described_class.apply_change_to_project(base_project, changes_to_apply)
775
- base_project.save
776
899
 
777
900
  expect(base_project).to be_equivalent_to_project(theirs_project)
778
901
  end
@@ -781,10 +904,9 @@ describe Kintsugi, :apply_change_to_project do
781
904
  base_project.targets[0].build_configurations.each do |configuration|
782
905
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
783
906
  end
784
-
785
907
  base_project.save
786
- theirs_project = create_copy_of_project(base_project.path, "theirs")
787
908
 
909
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
788
910
  theirs_project.targets[0].build_configurations.each do |configuration|
789
911
  configuration.build_settings =
790
912
  configuration.build_settings.reject { |key, _| key == "HEADER_SEARCH_PATHS" }
@@ -793,7 +915,6 @@ describe Kintsugi, :apply_change_to_project do
793
915
  changes_to_apply = get_diff(theirs_project, base_project)
794
916
 
795
917
  described_class.apply_change_to_project(base_project, changes_to_apply)
796
- base_project.save
797
918
 
798
919
  expect(base_project).to be_equivalent_to_project(theirs_project)
799
920
  end
@@ -802,8 +923,8 @@ describe Kintsugi, :apply_change_to_project do
802
923
  base_project.targets[0].build_configurations.each do |configuration|
803
924
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
804
925
  end
805
-
806
926
  base_project.save
927
+
807
928
  theirs_project = create_copy_of_project(base_project.path, "theirs")
808
929
  theirs_project.targets[0].build_configurations.each do |configuration|
809
930
  configuration.build_settings = nil
@@ -812,7 +933,6 @@ describe Kintsugi, :apply_change_to_project do
812
933
  changes_to_apply = get_diff(theirs_project, base_project)
813
934
 
814
935
  described_class.apply_change_to_project(base_project, changes_to_apply)
815
- base_project.save
816
936
 
817
937
  expect(base_project).to be_equivalent_to_project(theirs_project)
818
938
  end
@@ -822,8 +942,8 @@ describe Kintsugi, :apply_change_to_project do
822
942
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
823
943
  configuration.build_settings["foo"] = "baz"
824
944
  end
825
-
826
945
  base_project.save
946
+
827
947
  theirs_project = create_copy_of_project(base_project.path, "theirs")
828
948
  theirs_project.targets[0].build_configurations.each do |configuration|
829
949
  configuration.build_settings = nil
@@ -837,7 +957,6 @@ describe Kintsugi, :apply_change_to_project do
837
957
  changes_to_apply = get_diff(theirs_project, base_project)
838
958
 
839
959
  described_class.apply_change_to_project(base_project, changes_to_apply)
840
- base_project.save
841
960
 
842
961
  expect(base_project).to be_equivalent_to_project(theirs_project)
843
962
  end
@@ -858,7 +977,6 @@ describe Kintsugi, :apply_change_to_project do
858
977
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
859
978
 
860
979
  described_class.apply_change_to_project(base_project, changes_to_apply)
861
- base_project.save
862
980
 
863
981
  expect(base_project).to be_equivalent_to_project(theirs_project)
864
982
  end
@@ -879,7 +997,6 @@ describe Kintsugi, :apply_change_to_project do
879
997
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
880
998
 
881
999
  described_class.apply_change_to_project(base_project, changes_to_apply)
882
- base_project.save
883
1000
 
884
1001
  expect(base_project).to be_equivalent_to_project(theirs_project)
885
1002
  end
@@ -940,10 +1057,9 @@ describe Kintsugi, :apply_change_to_project do
940
1057
  base_project.targets[0].build_configurations.each do |configuration|
941
1058
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
942
1059
  end
943
-
944
1060
  base_project.save
945
- theirs_project = create_copy_of_project(base_project.path, "theirs")
946
1061
 
1062
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
947
1063
  theirs_project.targets[0].build_configurations.each do |configuration|
948
1064
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
949
1065
  end
@@ -951,7 +1067,6 @@ describe Kintsugi, :apply_change_to_project do
951
1067
  changes_to_apply = get_diff(theirs_project, base_project)
952
1068
 
953
1069
  described_class.apply_change_to_project(base_project, changes_to_apply)
954
- base_project.save
955
1070
 
956
1071
  expect(base_project).to be_equivalent_to_project(theirs_project)
957
1072
  end
@@ -960,10 +1075,9 @@ describe Kintsugi, :apply_change_to_project do
960
1075
  base_project.targets[0].build_configurations.each do |configuration|
961
1076
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
962
1077
  end
963
-
964
1078
  base_project.save
965
- theirs_project = create_copy_of_project(base_project.path, "theirs")
966
1079
 
1080
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
967
1081
  theirs_project.targets[0].build_configurations.each do |configuration|
968
1082
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[baz foo]
969
1083
  end
@@ -971,7 +1085,6 @@ describe Kintsugi, :apply_change_to_project do
971
1085
  changes_to_apply = get_diff(theirs_project, base_project)
972
1086
 
973
1087
  described_class.apply_change_to_project(base_project, changes_to_apply)
974
- base_project.save
975
1088
 
976
1089
  expect(base_project).to be_equivalent_to_project(theirs_project)
977
1090
  end
@@ -998,7 +1111,6 @@ describe Kintsugi, :apply_change_to_project do
998
1111
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
999
1112
 
1000
1113
  described_class.apply_change_to_project(base_project, changes_to_apply)
1001
- base_project.save
1002
1114
 
1003
1115
  expect(base_project).to be_equivalent_to_project(expected_project)
1004
1116
  end
@@ -1062,37 +1174,32 @@ describe Kintsugi, :apply_change_to_project do
1062
1174
  changes_to_apply = get_diff(theirs_project, base_project)
1063
1175
 
1064
1176
  described_class.apply_change_to_project(base_project, changes_to_apply)
1065
- base_project.save
1066
1177
 
1067
1178
  expect(base_project).to be_equivalent_to_project(theirs_project)
1068
1179
  end
1069
1180
 
1070
1181
  it "adds build phase with a simple attribute value that has non nil default" do
1071
1182
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1072
-
1073
1183
  theirs_project.targets[0].new_shell_script_build_phase("bar")
1074
1184
  theirs_project.targets[0].build_phases.last.shell_script = "Other value"
1075
1185
 
1076
1186
  changes_to_apply = get_diff(theirs_project, base_project)
1077
1187
 
1078
1188
  described_class.apply_change_to_project(base_project, changes_to_apply)
1079
- base_project.save
1080
1189
 
1081
1190
  expect(base_project).to be_equivalent_to_project(theirs_project)
1082
1191
  end
1083
1192
 
1084
1193
  it "removes build phase" do
1085
1194
  base_project.targets[0].new_shell_script_build_phase("bar")
1086
-
1087
1195
  base_project.save
1088
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1089
1196
 
1197
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1090
1198
  theirs_project.targets[0].shell_script_build_phases[0].remove_from_project
1091
1199
 
1092
1200
  changes_to_apply = get_diff(theirs_project, base_project)
1093
1201
 
1094
1202
  described_class.apply_change_to_project(base_project, changes_to_apply)
1095
- base_project.save
1096
1203
 
1097
1204
  expect(base_project).to be_equivalent_to_project(theirs_project)
1098
1205
  end
@@ -1102,33 +1209,29 @@ describe Kintsugi, :apply_change_to_project do
1102
1209
  file = variant_group.new_reference("Base")
1103
1210
  file.last_known_file_type = "text.plist.strings"
1104
1211
  target.resources_build_phase.add_file_reference(variant_group)
1105
-
1106
1212
  base_project.save
1107
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1108
1213
 
1214
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1109
1215
  theirs_variant_group = theirs_project.main_group.find_subpath("foo.strings")
1110
1216
  theirs_variant_group.new_reference("en")
1111
1217
 
1112
1218
  changes_to_apply = get_diff(theirs_project, base_project)
1113
1219
 
1114
1220
  described_class.apply_change_to_project(base_project, changes_to_apply)
1115
- base_project.save
1116
1221
 
1117
1222
  expect(base_project).to be_equivalent_to_project(theirs_project)
1118
1223
  end
1119
1224
 
1120
1225
  it "adds target dependency" do
1121
1226
  base_project.new_target("com.apple.product-type.library.static", "bar", :ios)
1122
-
1123
1227
  base_project.save
1124
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1125
1228
 
1229
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1126
1230
  theirs_project.targets[1].add_dependency(theirs_project.targets[0])
1127
1231
 
1128
1232
  changes_to_apply = get_diff(theirs_project, base_project)
1129
1233
 
1130
1234
  described_class.apply_change_to_project(base_project, changes_to_apply)
1131
- base_project.save
1132
1235
 
1133
1236
  expect(base_project).to be_equivalent_to_project(theirs_project)
1134
1237
  end
@@ -1137,10 +1240,9 @@ describe Kintsugi, :apply_change_to_project do
1137
1240
  base_project.targets[0].build_configurations.each do |configuration|
1138
1241
  configuration.build_settings["GCC_PREFIX_HEADER"] = "foo"
1139
1242
  end
1140
-
1141
1243
  base_project.save
1142
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1143
1244
 
1245
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1144
1246
  theirs_project.targets[0].build_configurations.each do |configuration|
1145
1247
  configuration.build_settings["GCC_PREFIX_HEADER"] = "bar"
1146
1248
  end
@@ -1148,16 +1250,13 @@ describe Kintsugi, :apply_change_to_project do
1148
1250
  changes_to_apply = get_diff(theirs_project, base_project)
1149
1251
 
1150
1252
  described_class.apply_change_to_project(base_project, changes_to_apply)
1151
- base_project.save
1152
1253
 
1153
1254
  expect(base_project).to be_equivalent_to_project(theirs_project)
1154
1255
  end
1155
1256
 
1156
1257
  it "adds build settings to new target" do
1157
1258
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1158
-
1159
1259
  theirs_project.new_target("com.apple.product-type.library.static", "bar", :ios)
1160
-
1161
1260
  theirs_project.targets[1].build_configurations.each do |configuration|
1162
1261
  configuration.build_settings["GCC_PREFIX_HEADER"] = "baz"
1163
1262
  end
@@ -1165,7 +1264,6 @@ describe Kintsugi, :apply_change_to_project do
1165
1264
  changes_to_apply = get_diff(theirs_project, base_project)
1166
1265
 
1167
1266
  described_class.apply_change_to_project(base_project, changes_to_apply)
1168
- base_project.save
1169
1267
 
1170
1268
  expect(base_project).to be_equivalent_to_project(theirs_project)
1171
1269
  end
@@ -1174,7 +1272,6 @@ describe Kintsugi, :apply_change_to_project do
1174
1272
  base_project.main_group.new_reference("baz")
1175
1273
 
1176
1274
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1177
-
1178
1275
  configuration_reference = theirs_project.main_group.find_subpath("baz")
1179
1276
  theirs_project.targets[0].build_configurations.each do |configuration|
1180
1277
  configuration.base_configuration_reference = configuration_reference
@@ -1183,35 +1280,29 @@ describe Kintsugi, :apply_change_to_project do
1183
1280
  changes_to_apply = get_diff(theirs_project, base_project)
1184
1281
 
1185
1282
  described_class.apply_change_to_project(base_project, changes_to_apply)
1186
- base_project.save
1187
1283
 
1188
1284
  expect(base_project).to be_equivalent_to_project(theirs_project)
1189
1285
  end
1190
1286
  end
1191
1287
 
1192
1288
  it "adds known regions" do
1193
- base_project.save
1194
1289
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1195
-
1196
1290
  theirs_project.root_object.known_regions += ["fr"]
1197
1291
 
1198
1292
  changes_to_apply = get_diff(theirs_project, base_project)
1199
1293
 
1200
1294
  described_class.apply_change_to_project(base_project, changes_to_apply)
1201
- base_project.save
1202
1295
 
1203
1296
  expect(base_project).to be_equivalent_to_project(theirs_project)
1204
1297
  end
1205
1298
 
1206
1299
  it "removes known regions" do
1207
1300
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1208
-
1209
1301
  theirs_project.root_object.known_regions = nil
1210
1302
 
1211
1303
  changes_to_apply = get_diff(theirs_project, base_project)
1212
1304
 
1213
1305
  described_class.apply_change_to_project(base_project, changes_to_apply)
1214
- base_project.save
1215
1306
 
1216
1307
  expect(base_project).to be_equivalent_to_project(theirs_project)
1217
1308
  end
@@ -1225,7 +1316,6 @@ describe Kintsugi, :apply_change_to_project do
1225
1316
  changes_to_apply = get_diff(theirs_project, base_project)
1226
1317
 
1227
1318
  described_class.apply_change_to_project(base_project, changes_to_apply)
1228
- base_project.save
1229
1319
 
1230
1320
  expect(base_project).to be_equivalent_to_project(theirs_project)
1231
1321
  end
@@ -1235,14 +1325,12 @@ describe Kintsugi, :apply_change_to_project do
1235
1325
  base_project.save
1236
1326
 
1237
1327
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1238
-
1239
1328
  theirs_project.root_object.attributes["TargetAttributes"] =
1240
1329
  {"foo" => {"LastSwiftMigration" => "1140"}}
1241
1330
 
1242
1331
  changes_to_apply = get_diff(theirs_project, base_project)
1243
1332
 
1244
1333
  described_class.apply_change_to_project(base_project, changes_to_apply)
1245
- base_project.save
1246
1334
 
1247
1335
  expect(base_project).to be_equivalent_to_project(theirs_project)
1248
1336
  end
@@ -1252,14 +1340,12 @@ describe Kintsugi, :apply_change_to_project do
1252
1340
  base_project.save
1253
1341
 
1254
1342
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1255
-
1256
1343
  theirs_project.root_object.attributes["TargetAttributes"] =
1257
1344
  {"foo" => {"LastSwiftMigration" => "1140"}}
1258
1345
 
1259
1346
  changes_to_apply = get_diff(theirs_project, base_project)
1260
1347
 
1261
1348
  described_class.apply_change_to_project(base_project, changes_to_apply)
1262
- base_project.save
1263
1349
 
1264
1350
  expect(base_project).to be_equivalent_to_project(theirs_project)
1265
1351
  end
@@ -1270,13 +1356,11 @@ describe Kintsugi, :apply_change_to_project do
1270
1356
  base_project.save
1271
1357
 
1272
1358
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1273
-
1274
1359
  theirs_project.root_object.attributes["TargetAttributes"]["foo"] = {}
1275
1360
 
1276
1361
  changes_to_apply = get_diff(theirs_project, base_project)
1277
1362
 
1278
1363
  described_class.apply_change_to_project(base_project, changes_to_apply)
1279
- base_project.save
1280
1364
 
1281
1365
  expect(base_project).to be_equivalent_to_project(theirs_project)
1282
1366
  end
@@ -1295,7 +1379,6 @@ describe Kintsugi, :apply_change_to_project do
1295
1379
  changes_to_apply = get_diff(theirs_project, base_project)
1296
1380
 
1297
1381
  described_class.apply_change_to_project(ours_project, changes_to_apply)
1298
- ours_project.save
1299
1382
 
1300
1383
  expect(ours_project).to be_equivalent_to_project(theirs_project)
1301
1384
  end
@@ -1313,7 +1396,6 @@ describe Kintsugi, :apply_change_to_project do
1313
1396
  changes_to_apply = get_diff(theirs_project, base_project)
1314
1397
 
1315
1398
  described_class.apply_change_to_project(ours_project, changes_to_apply)
1316
- ours_project.save
1317
1399
 
1318
1400
  expect(ours_project).to be_equivalent_to_project(theirs_project)
1319
1401
  end
@@ -1341,7 +1423,6 @@ describe Kintsugi, :apply_change_to_project do
1341
1423
  changes_to_apply = get_diff(ours_project, theirs_project)
1342
1424
 
1343
1425
  described_class.apply_change_to_project(base_project, changes_to_apply)
1344
- base_project.save
1345
1426
 
1346
1427
  expect(base_project).to be_equivalent_to_project(ours_project, ignore_keys: ["containerPortal"])
1347
1428
  end
@@ -1365,6 +1446,30 @@ describe Kintsugi, :apply_change_to_project do
1365
1446
  expect(base_project).to be_equivalent_to_project(theirs_project)
1366
1447
  end
1367
1448
 
1449
+ it "adds build configuration list" do
1450
+ base_project.root_object.build_configuration_list = nil
1451
+ base_project.save
1452
+
1453
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1454
+ theirs_project.root_object.build_configuration_list =
1455
+ theirs_project.new(Xcodeproj::Project::XCConfigurationList)
1456
+
1457
+ changes_to_apply = get_diff(theirs_project, base_project)
1458
+
1459
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1460
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1461
+ end
1462
+
1463
+ it "removes build configuration list" do
1464
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1465
+ theirs_project.build_configuration_list.remove_from_project
1466
+
1467
+ changes_to_apply = get_diff(theirs_project, base_project)
1468
+
1469
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1470
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1471
+ end
1472
+
1368
1473
  it "adds group to product group" do
1369
1474
  base_project_path = make_temp_directory("base", ".xcodeproj")
1370
1475
  base_project = Xcodeproj::Project.new(base_project_path)
@@ -1400,6 +1505,154 @@ describe Kintsugi, :apply_change_to_project do
1400
1505
  expect(base_project).to be_equivalent_to_project(theirs_project)
1401
1506
  end
1402
1507
 
1508
+ describe "avoiding duplicate references to the same component" do
1509
+ it "avoids adding file reference that already exists" do
1510
+ base_project.main_group.new_reference("bar")
1511
+ base_project.save
1512
+
1513
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1514
+ theirs_project.main_group.new_reference("bar")
1515
+
1516
+ changes_to_apply = get_diff(theirs_project, base_project)
1517
+ other_project = create_copy_of_project(base_project.path, "theirs")
1518
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1519
+
1520
+ expect(other_project).to be_equivalent_to_project(base_project)
1521
+ end
1522
+
1523
+ it "avoids adding group that already exists" do
1524
+ base_project.main_group.new_group("bar")
1525
+ base_project.save
1526
+
1527
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1528
+ theirs_project.main_group.new_group("bar")
1529
+
1530
+ changes_to_apply = get_diff(theirs_project, base_project)
1531
+ other_project = create_copy_of_project(base_project.path, "theirs")
1532
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1533
+
1534
+ expect(other_project).to be_equivalent_to_project(base_project)
1535
+ end
1536
+
1537
+ it "avoids adding variant group that already exists" do
1538
+ base_project.main_group.new_variant_group("bar")
1539
+ base_project.save
1540
+
1541
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1542
+ theirs_project.main_group.new_variant_group("bar")
1543
+
1544
+ changes_to_apply = get_diff(theirs_project, base_project)
1545
+ other_project = create_copy_of_project(base_project.path, "theirs")
1546
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1547
+
1548
+ expect(other_project).to be_equivalent_to_project(base_project)
1549
+ end
1550
+
1551
+ it "avoids adding subproject that already exists" do
1552
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1553
+
1554
+ subproject = add_new_subproject_to_project(theirs_project, "foo", "foo")
1555
+
1556
+ ours_project = create_copy_of_project(base_project.path, "ours")
1557
+ add_existing_subproject_to_project(ours_project, subproject, "foo")
1558
+
1559
+ changes_to_apply = get_diff(theirs_project, base_project)
1560
+
1561
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
1562
+
1563
+ expect(ours_project.root_object.project_references.count).to equal(1)
1564
+ end
1565
+
1566
+ it "avoids adding build file that already exists" do
1567
+ file_reference = base_project.main_group.new_reference("bar")
1568
+ target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1569
+ target.frameworks_build_phase.add_file_reference(file_reference)
1570
+ base_project.save
1571
+
1572
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1573
+ file_reference = theirs_project.main_group.new_reference("bar")
1574
+ theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
1575
+
1576
+ changes_to_apply = get_diff(theirs_project, base_project)
1577
+ other_project = create_copy_of_project(base_project.path, "theirs")
1578
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1579
+
1580
+ expect(other_project).to be_equivalent_to_project(base_project)
1581
+ end
1582
+
1583
+ it "avoids adding reference proxy that already exists" do
1584
+ framework_filename = "baz"
1585
+ subproject = add_new_subproject_to_project(base_project, "subproj", framework_filename)
1586
+ base_project.save
1587
+
1588
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1589
+
1590
+ theirs_project.root_object.project_references[0][:product_group] <<
1591
+ create_reference_proxy_from_product_reference(theirs_project,
1592
+ theirs_project.root_object.project_references[0][:project_ref],
1593
+ subproject.products_group.files[-1])
1594
+
1595
+
1596
+ changes_to_apply = get_diff(theirs_project, base_project)
1597
+
1598
+ other_project = create_copy_of_project(base_project.path, "theirs")
1599
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1600
+
1601
+ expect(other_project).to be_equivalent_to_project(base_project)
1602
+ end
1603
+
1604
+ it "keeps array if adding string value that already exists in array" do
1605
+ base_project.new_target("com.apple.product-type.library.static", "bar", :ios)
1606
+ base_project.save
1607
+
1608
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1609
+ theirs_project.targets[0].build_configurations.each do |configuration|
1610
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
1611
+ end
1612
+ changes_to_apply = get_diff(theirs_project, base_project)
1613
+
1614
+ ours_project = create_copy_of_project(base_project.path, "ours")
1615
+ ours_project.targets[0].build_configurations.each do |configuration|
1616
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
1617
+ end
1618
+ ours_project.save
1619
+
1620
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1621
+
1622
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
1623
+
1624
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1625
+ end
1626
+ end
1627
+
1628
+ describe "allowing adding reference to the same component" do
1629
+ before do
1630
+ Kintsugi::Settings.allow_duplicates = true
1631
+ end
1632
+
1633
+ after do
1634
+ Kintsugi::Settings.allow_duplicates = false
1635
+ end
1636
+
1637
+ it "adds subproject that already exists" do
1638
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1639
+
1640
+ subproject = add_new_subproject_to_project(theirs_project, "foo", "foo")
1641
+
1642
+ ours_project = create_copy_of_project(base_project.path, "ours")
1643
+ add_existing_subproject_to_project(ours_project, subproject, "foo")
1644
+
1645
+ changes_to_apply = get_diff(theirs_project, base_project)
1646
+
1647
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
1648
+
1649
+ expect(ours_project.root_object.project_references[0][:project_ref].uuid)
1650
+ .not_to equal(ours_project.root_object.project_references[1][:project_ref].uuid)
1651
+ expect(ours_project.root_object.project_references[0][:project_ref].proxy_containers).not_to be_empty
1652
+ expect(ours_project.root_object.project_references[1][:project_ref].proxy_containers).not_to be_empty
1653
+ end
1654
+ end
1655
+
1403
1656
  def create_copy_of_project(project_path, new_project_prefix)
1404
1657
  copied_project_path = make_temp_directory(new_project_prefix, ".xcodeproj")
1405
1658
  FileUtils.cp(File.join(project_path, "project.pbxproj"), copied_project_path)